JDK-6809490 : Removing a Table Column causes wrong selected column
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 6u12
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2009-02-24
  • Updated: 2011-01-19
  • Resolved: 2009-03-04
Related Reports
Duplicate :  
Description
J2SE Version (please include all output from java -version flag):
java version "1.6.0_12"
Java(TM) SE Runtime Environment (build 1.6.0_12-b04)
Java HotSpot(TM) Client VM (build 11.2-b01, mixed mode, sharing)

Does this problem occur on J2SE 5.0.x or 6.0?  Yes / No (pick one)
Yes

Operating System Configuration Information (be specific):
Client: Microsoft Windows XP [Version 5.1.2600]

Bug Description:
Removing a Table Column causes wrong selected column

When removing a column from a table, DefaultTableColumnModel is adjusting the selection (implying that a column that is not selected is selected) then removing the column.

Run Code and press the remove column button
Expected: Label to say 'Selected Column: column 2'
Actual: Label says 'Selected Column: column 1'

import static java.awt.BorderLayout.*;
import static javax.swing.JFrame.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class Test {
  private static JLabel label;
  private static JTable table;

  public static void main(String[] args) {
    label = new JLabel();
    table = new JTable(new Object[][] {{"", ""}, {"", ""}}, new Object[] {"column 1", "column 2"});
    table.setRowSelectionAllowed(false);
    table.setColumnSelectionAllowed(true);
    table.getColumnModel().getSelectionModel().addListSelectionListener(new ListSelectionListener() {
      public void valueChanged(ListSelectionEvent anEvent) {
        int selectedIndex = table.getSelectedColumn();
        label.setText(selectedIndex == -1 ? "No Column is Selected" :
            ("Selected Column: " + table.getColumnName(selectedIndex)));
      }
    });
    table.setColumnSelectionInterval(1, 1);
    JFrame frame = new JFrame();
    frame.add(label, NORTH);
    frame.add(new JScrollPane(table));
    frame.add(new JButton(new AbstractAction("Remove First Column") {
      @Override
      public void actionPerformed(ActionEvent e) {
        table.removeColumn(table.getColumnModel().getColumn(0));
        if (table.getColumnCount() == 0) {
          setEnabled(false);
        }
      }
    }), SOUTH);
    frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
  }
}

Comments
WORK AROUND you should ask the updated selection after all listeners are notified. This is usually done by using SwingUtilities.invokeLater() in the listener's body: table.getColumnModel().getSelectionModel().addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent anEvent) { SwingUtilities.invokeLater(new Runnable() { public void run() { // Now you'll get the correct data: int selectedIndex = table.getSelectedColumn(); label.setText(selectedIndex == -1 ? "No Column is Selected" : ("Selected Column: " + table.getColumnName(selectedIndex))); } }); } });
04-03-2009

EVALUATION This is problem is caused by the general design of Swing and AWT - the order of listeners' notification is not specified. User's listeners are notified together with Swing ones and in this case it is happens that the user's code is notified before the Swing code that updates the selection The workaround is simple - you should ask the updated selection after all listeners are notified. This is usually done by using SwingUtilities.invokeLater() in the listener's body: table.getColumnModel().getSelectionModel().addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent anEvent) { SwingUtilities.invokeLater(new Runnable() { public void run() { // Now you'll get the correct data: int selectedIndex = table.getSelectedColumn(); label.setText(selectedIndex == -1 ? "No Column is Selected" : ("Selected Column: " + table.getColumnName(selectedIndex))); } }); } }); closed as duplicate of 4178930
04-03-2009