JDK-8144765 : DefaultCellEditor doesn't save edited JComboBox value on focus lost
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 8u60
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_8
  • CPU: x86
  • Submitted: 2015-10-19
  • Updated: 2020-11-10
  • Resolved: 2015-12-07
Related Reports
Duplicate :  
Description
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.


Comments
duplicates JDK-8072767 which need to be backported to 8.
07-12-2015

Has a test case
04-12-2015