Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6185553

JComboBox.setSelectedItem displays parameter rather than item it contains

XMLWordPrintable

    • b34
    • generic
    • generic

      FULL PRODUCT VERSION :
      java version "1.5.0"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-b64)
      Java HotSpot(TM) Client VM (build 1.5.0-b64, mixed mode, sharing)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows 2000 [Version 5.00.2195]

      A DESCRIPTION OF THE PROBLEM :
      JComboBox setSelectedItem displays the passed paramenter to the method rather the the item contained in its model.

      The language spec does not require two object that test equal to display the same value for toString. Since this is the case it is INVALID to display the parameter's value.

      I've provided original source with the line containing the bug indicated as will as a complete fix that requires simply replacing the bug ridden method with the fix.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run any app that has a combo box where the items contained in the model test equal to the parameter but whose toString() method returns a differing String.

      Since the language spec does not require that two object that test true using the 'equals' method return the same value for 'toString' the logic in the combo box method is invalid. Source below
      java.swing.JComboBox source ************

      <pre>
          public void setSelectedItem(Object anObject) {
      Object oldSelection = selectedItemReminder;
      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++) {
      if (anObject.equals(dataModel.getElementAt(i))) {
      found = true;
      break;
      }
      }
      if (!found) {
      return;
      }
      }

      // Must toggle the state of this flag since this method
      // call may result in ListDataEvents being fired.
      selectingItem = true;
      <b><i>// bug in line below </i></b>
      dataModel.setSelectedItem(anObject);
      selectingItem = false;

      if (selectedItemReminder != dataModel.getSelectedItem()) {
      // in case a users implementation of ComboBoxModel
      // doesn't fire a ListDataEvent when the selection
      // changes.
      selectedItemChanged();
      }
      }
      fireActionEvent();
          }
      </pre>

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Display the item contained in the ComboBox's model rather than the parameter passed as an argument to this method.
      ACTUAL -
      The parameter passed in is what is displayed not the item found in the combox's model.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
        Fixed source code.
      Paste this as a replacement for the method in JComboBox and
      the bug will be fixed.


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

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

      // Must toggle the state of this flag since this method
      // call may result in ListDataEvents being fired.
      selectingItem = true;
      dataModel.setSelectedItem(found);
      selectingItem = false;

      if (selectedItemReminder != dataModel.getSelectedItem()) {
      // in case a users implementation of ComboBoxModel
      // doesn't fire a ListDataEvent when the selection
      // changes.
      selectedItemChanged();
      }
      }
      fireActionEvent();
          }
      </pre>
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Extend JComboBox and override the
      getSelectedItem method with the code below.

      <pre>
          public void setSelectedItem(Object anObject) {
              Object oldSelection = selectedItemReminder;
              if (oldSelection == null || !oldSelection.equals(anObject)) {
                  if (anObject != null) {
                      for (int i = 0; i < dataModel.getSize(); i++) {
                          if (anObject.equals(dataModel.getElementAt(i))) {
                              super.setSelectedItem(dataModel.getElementAt(i));
                              break;
                          }
                      }
                  }
              }
          }
      </pre>
      ###@###.### 10/27/04 22:17 GMT

            draskinsunw Daniel Raskin (Inactive)
            gmanwanisunw Girish Manwani (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: