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

DefaultCellEditor doesn't save edited JComboBox value on focus lost

XMLWordPrintable

      FULL PRODUCT VERSION :
      java version "1.8.0_45"
      Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
      Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      Linux 3.13.0-65-generic #106-Ubuntu SMP Fri Oct 2 22:08:27 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
      Windows 8

      A DESCRIPTION OF THE PROBLEM :
      The text edited in a table cell that has an editable combobox is lost when the mouse is clicked in some empty area within the containing JScrollPane.

      In previous Java versions, the text would have been saved.

      REGRESSION. Last worked in version 7u79

      ADDITIONAL REGRESSION INFORMATION:
      java version "1.7.0_79"
      OpenJDK Runtime Environment (IcedTea 2.5.6) (7u79-2.5.6-0ubuntu1.14.04.1)
      OpenJDK 64-Bit Server VM (build 24.79-b02, mixed mode)


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Run test case. Note how the cell has a "Hello" value.
      2. Edit the table cell text, (type in "World")
      3. Mouse-click in the white area beneath

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The table cell text should have been updated with the edited value ("World").
      ACTUAL -
      The cell text is not changed (it's still "Hello")

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------

      import java.awt.event.ActionEvent;
      import javax.swing.DefaultCellEditor;
      import javax.swing.JComboBox;
      import javax.swing.JFrame;
      import javax.swing.JScrollPane;
      import javax.swing.JTable;
      import javax.swing.table.AbstractTableModel;
      import javax.swing.JComponent;
      import javax.swing.SwingUtilities;

      /**
       * Double-click the table cell, type in "World" then click in the white area
       * beneath; the text will be ignored...
       */
      public class Bug {

          public static JComponent createTable() {
              JTable table = new JTable(new AbstractTableModel() {

                  private String value = "Hello";

                  @Override
                  public int getRowCount() {
                      return 1;
                  }

                  @Override
                  public int getColumnCount() {
                      return 1;
                  }

                  @Override
                  public Object getValueAt(int rowIndex, int columnIndex) {
                      return value;
                  }

                  @Override
                  public boolean isCellEditable(int rowIndex, int columnIndex) {
                      return true;
                  }

                  @Override
                  public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
                      value = String.valueOf(aValue);
                  }
              });
              table.setFillsViewportHeight(true);

              final JComboBox comboBox = new JComboBox();
              comboBox.setEditable(true);

              table.getColumnModel().getColumn(0).setCellEditor(new DefaultCellEditor(comboBox));

              return new JScrollPane(table);
          }

          public static void main(String[] args) {
              SwingUtilities.invokeLater(new Runnable() {

                  @Override
                  public void run() {
                      JFrame frame = new JFrame();
                      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                      frame.setContentPane(createTable());

                      frame.pack();
                      frame.setVisible(true);
                  }
              });
          }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      The bug is in the JComboBox.actionPerformed method which is too strict in verifying the event source.

      It particularly fails for the event sent by the DefaultCellEditor when stopCellEditing is invoked.

      A workaround is to change the event in such a situation:

              final JComboBox comboBox = new JComboBox()
              {

                  @Override
                  public void actionPerformed(ActionEvent e) {
                      Object source = e.getSource();
                      if (source instanceof DefaultCellEditor) {
                          e = new ActionEvent(getEditor(), e.getID(), e.getActionCommand());
                      }
                      super.actionPerformed(e);
                  }

              };

      but the fix should be done in the JComboBox class itself.

            alexsch Alexandr Scherbatiy
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: