June
June

Reputation: 1014

JComboBox setSelectedItem does not work

I am trying to set the setSelectedItem of the JComboBox in the constructor of my JPanel class just after populating the combobox.

I am set the value for textbox, but I can't figure out why setSelectedItem does not seem to work. Any ideas?

public StudentProfilePanel(StudentInfo si) {

        yesButton.setBounds(50, 346, 69, 40);
        noButton.setBounds(121, 346, 56, 40);
        this.add(yesButton);
        this.add(noButton);
        setLayout(null);
        comboBoxYear.setModel(new DefaultComboBoxModel(years()));
        comboBoxYear.setBounds(202, 365, 62, 23);
        if(si.birthdate!=null){
            //System.out.println("year value : ["+dateofbirth(si.birthdate)[2]+"]");
            comboBoxYear.setSelectedItem(dateofbirth(si.birthdate)[2]);

        }

        add(comboBoxYear);
        comboBoxMonth.setModel(new DefaultComboBoxModel(new String[]{"01","02","03","04","05","06","07","08","09","10","11","12"}));
        comboBoxMonth.setBounds(285, 365, 56, 23);

        //set month value
        if(si.birthdate!=null){
            //comboBoxMonth.setSelectedItem(dateofbirth(si.birthdate)[1]);
            comboBoxMonth.setSelectedItem("04");
            System.out.println("month value : ["+dateofbirth(si.birthdate)[1]+"]");
        }
        add(comboBoxMonth);
        comboBoxDay.setModel(new DefaultComboBoxModel(days()));
        comboBoxDay.setBounds(351, 365, 54, 23);
        if(si.birthdate!=null){
            //comboBoxDay.setSelectedItem(dateofbirth(si.birthdate)[0]);
            comboBoxDay.setSelectedItem(dateofbirth(si.birthdate)[0]);
        }
        add(comboBoxDay);

        textFieldFirstName = new JTextField();
        textFieldFirstName.setBounds(21, 321, 171, 21);
        add(textFieldFirstName);
        textFieldFirstName.setColumns(10);
        // set the value of first name
        textFieldFirstName.setText(si.firstName);

        textFieldLastName = new JTextField();
        textFieldLastName.setBounds(242, 321, 163, 21);
        add(textFieldLastName);
        textFieldLastName.setColumns(10);
        //set the value of the last name
        textFieldLastName.setText(si.lastName);

        JPanel panelPersonPhoto = new ImagePanel(
                "C:\\Users\\MDJef\\Pictures\\Wallpaper\\General\\11.jpg");
        panelPersonPhoto.setBorder(new TitledBorder(null, "",
                TitledBorder.LEADING, TitledBorder.TOP, null, null));
        panelPersonPhoto.setBounds(21, 20, 384, 291);
        add(panelPersonPhoto);
    }

Thanks very much.

helper methods that I used

    // jf : helper method
    public String[] years() {
        String[] results = new String[90];
        for (int i = 0; i < 90; i++) {
            results[i] = Integer.toString(1900 + i);
        }
        return results;
    }

    // jf : helper method
    public String[] months() {
        String[] results = new String[12];
        for (int i = 0; i < 12; i++) {
            results[i] = Integer.toString(i + 1);
        }
        return results;
    }

    // jf : helper method
    public String[] days() {
        String[] results = new String[31];
        for (int i = 0; i < 31; i++) {
            results[i] = Integer.toString(i + 1);
        }
        return results;
    }

    // jf : helper method
    public String[] dateofbirth(String dob) {
        String[] tokens = dob.split("-");
        return tokens;
    }

Upvotes: 3

Views: 15846

Answers (6)

BabaNew
BabaNew

Reputation: 976

The item you wish to set as selected must share the class of the objects stored in the JComboBox.

public static void main(String[] args) {
    String[] items = {"1", "2", "3"};
    JComboBox jcb = new JComboBox(items);
    jcb.setSelectedItem(3);
    System.out.println(jcb.getSelectedItem());
    jcb.setSelectedItem(3+"");
    System.out.println(jcb.getSelectedItem());
}

Output of the above code:

1
3

Upvotes: 0

Pramod
Pramod

Reputation: 7

Use the following: comboBoxMonth.setSelectedItem(index of the array);

Upvotes: 0

asdf
asdf

Reputation: 246

For other developer with the same issue: A closer look into the implementation of setSelectedItem(Object anObject) from JComboBox might help:

public void setSelectedItem(Object anObject) {
    Object oldSelection = selectedItemReminder;
    Object objectToSelect = anObject;
    if (oldSelection == null || !oldSelection.equals(anObject)) {

        if (anObject != null && !isEditable()) {
            // For non editable combo boxes, an invalid selection
            // will be rejected.
            boolean found = false;
            for (int i = 0; i < dataModel.getSize(); i++) {
                E element = dataModel.getElementAt(i);
                if (anObject.equals(element)) {
                    found = true;
                    objectToSelect = element;
                    break;
                }
            }
            if (!found) {
                return;
            }
        }

...

In the loop your object is compared with an object of the dataModel with the specific type E. In the implementation of equals() from String you can see a verification of class/interface, length and each character one after another. That means, our object must have same type and all characters must be the same!

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

And this is the most annoying part if (anObject.equals(element)) in setSelectedItem! You cant override equals method from your element. For example StudentInfo and compare other types like strings or integers to it. Simple example. You implement combobox like this JComboBox<StudentInfo> and you want to select the student with int id = 2;. So it compares now Integer with StudentInfo. Here you have to override equals from Integer...

My proposal is to swap it. Create own class, add boolean selectingItem and override setSelectedItem(Object anObject) and contentsChanged(ListDataEvent e)(this method one-to-one). Nevertheless, I had side effects in one project...

Upvotes: 0

MadProgrammer
MadProgrammer

Reputation: 347184

The values assigned to the combo box are not the same values you are trying set.

For example, the years are Strings from 1900 - 1990, but if I supply a value 72, there is no matching value in the combo box to match to.

Equally, your days and months methods are only returning values that are not padded (ie 01), where as, in your code, you're trying to set the value using a padded value (ie 04), meaning there is no matching value...

You have a number of options...

You could...

Convert all the values to an int, meaning that the values in the combo box are simply ints. You would then need to convert the date values to ints as well.

This would make your helper code look more like...

public int[] years() {
    int[] results = new String[90];
    for (int i = 0; i < 90; i++) {
        results[i] = 1900 + i;
    }
    return results;
}

public int[] months() {
    int[] results = new String[12];
    for (int i = 0; i < 12; i++) {
        results[i] = i + 1;
    }
    return results;
}

public int[] days() {
    int[] results = new String[31];
    for (int i = 0; i < 31; i++) {
        results[i] = i + 1;
    }
    return results;
}

public int[] dateofbirth(String dob) {
    int[] tokens = dob.split("-");
    int[] values = new int[tokens.length];
    for (int index = 0; index < tokens.length; index++) {
      values[index] = Integer.parse(tokens[index]);
    }
    return index;
}

A better solution

Would be to use a JSpinner, which would take care of date rolling issues and validation automatically.

Check out Using Standard Spinner Models and Editors

Upvotes: 2

Daniel Lerps
Daniel Lerps

Reputation: 5375

When you call comboBoxMonth.setSelectedItem("04"); you try to select a newly created String which is not equal to the one which is in your JComboBox. Ergo it does not get selected.

You can try something like this instead:

String[] months = new String[] {"01","02","03","04","05","06","07","08","09","10","11","12"};
comboBoxMonth.setModel(new DefaultComboBoxModel(months));

comboBoxMonth.setSelectedItem(months[3]);

Edit: Try this. It uses the index of the item instead. Just make sure you add the months in order to the array.

String[] months = new String[] {"01","02","03","04","05","06","07","08","09","10","11","12"};
comboBoxMonth.setModel(new DefaultComboBoxModel(months));

if(si.birthdate!=null)
{
    comboBoxMonth.setSelectedIndex(Integer.parseInteger(dateofbirth(si.birthdate)[1]) - 1);
}

Upvotes: 1

camickr
camickr

Reputation: 324098

Not related to your problem, but:

yesButton.setBounds(50, 346, 69, 40);
noButton.setBounds(121, 346, 56, 40);
setLayout(null);

Don't use a null layout and setBounds(...). Swing was designed to be used with Layout Manager. In the long run you will save time.

if(si.birthdate!=null){

Don't access variables in your class directly. Create a getter method to access the properties of your class.

//System.out.println("year value : ["+dateofbirth(si.birthdate)[2]+"]");
comboBoxYear.setSelectedItem(dateofbirth(si.birthdate)[2]);

Don't always try to force you code into a single statement. Instead do something like:

String birthdate = dateofbirth(si.birthdate[2]);
System.out.println("year value : [" + birthdate +"]");
comboBoxYear.setSelectedItem(birthdate);

This helps with your debugging because now you know that the variable you display is the same variable that you are trying to use in the setSelectedItem() method. It saves typing the statement twice and avoids typing mistakes.

Upvotes: 1

Related Questions