JDK-6711682 : JCheckBox in JTable: checkbox doesn't alaways respond to the first mouse click
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 5.0
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2008-06-06
  • Updated: 2017-05-09
  • Resolved: 2010-01-13
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other Other JDK 6 JDK 7
5.0u17-crevFixed 5.0u23Fixed 6u18 b03Fixed 7Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
on all versions >= 1.5.0_08

A DESCRIPTION OF THE PROBLEM :
The cell editor is a JCheckBox and the table stays in edit mode after clicking the JCheckBox.
If you are in editing mode and click on an other row of the same column to select/unselect the JCheckBox, only each second time the value changed.

This bug is due to the bugfix of BUG ID 4368790.

The problem can be easily reproduced by the attached example TableWithCheckbox.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.*;
import java.awt.event.*;
import java.util.EventObject;

import javax.swing.*;
import javax.swing.event.CellEditorListener;
import javax.swing.table.*;

public class TableWithCheckbox {
    public static void main(String[] args) {
        JFrame f = new JFrame("Table with CheckBox");
        Container p = f.getContentPane();
        p.setLayout(new BorderLayout());
        final JTable table = new JTable(new Object[][]{{false},{false},{false}}, new Object[] {"CheckBox"});
        TableCellEditor editor = new TableCellEditor() {
            JCheckBox checkBox = new JCheckBox();
            int editedRow;
            public Component getTableCellEditorComponent(JTable table,
                    Object value, boolean isSelected, int row, int column) {
                this.editedRow = row;
                checkBox.setSelected(Boolean.TRUE.equals(value));
                checkBox.setBackground(UIManager.getColor("Table.selectionBackground"));
                return checkBox;
            }

            public void addCellEditorListener(CellEditorListener l) {
            }

            public void cancelCellEditing() {
            }

            public Object getCellEditorValue() {
                return checkBox.isSelected();
            }

            public boolean isCellEditable(EventObject anEvent) {
                return true;
            }

            public void removeCellEditorListener(CellEditorListener l) {
            }

            public boolean shouldSelectCell(EventObject anEvent) {
                return true;
            }

            public boolean stopCellEditing() {
                table.getModel().setValueAt(checkBox.isSelected(), editedRow, 0);
                return true;
            }
        };
        table.getColumnModel().getColumn(0).setCellEditor(editor);

        TableCellRenderer renderer = new TableCellRenderer() {
            JCheckBox checkBox = new JCheckBox();
            public Component getTableCellRendererComponent(JTable table,
                    Object value, boolean isSelected, boolean hasFocus,
                    int row, int column) {
                checkBox.setBackground(isSelected? UIManager.getColor("Table.selectionBackground") : UIManager.getColor("Table.background"));
                checkBox.setSelected(Boolean.TRUE.equals(value));
                return checkBox;
            }
        };
        table.getColumnModel().getColumn(0).setCellRenderer(renderer);
        
        p.add(table, BorderLayout.CENTER);
        
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        
        f.pack();
        f.setVisible(true);
    }
}

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

Release Regression From : 5.0u8
The above release value was the last known release where this 
bug was not reproducible. Since then there has been a regression.

Comments
EVALUATION Look at JToggleButton.ToggleButtonModel.setPressed() this method calls setSelected() depending on the isArmed() state, that's why methods ordering is important
24-06-2009

EVALUATION This is a regression of 4368790 indeed We should make a better fix for 4368790 without this regression, the logic behind updating button's model is pretty complex and the proposed solution is a bit surprising: Change the line's order in BasicButtonListener.focusLost() instead of model.setPressed(false); model.setArmed(false); do it this way: model.setArmed(false); model.setPressed(false); just like we do in BasicButtonListener.mouseReleased()
24-06-2009

EVALUATION I reproduced this bug, run the provided test and click checkbox cells one after another
09-06-2008