JTable tips

Here are 2 common requirements when working with Swing’s JTable:

  • validating the editing of a cell without having to hit the “enter” key
  • preventing a JTable to intercept the “enter key” (so that the default button of your dialog is correctly activated)
Here is a little code sample that illustrates these 2 points:
public class TestTable extends JDialog {
  private JTable table;

  public TestTable() {
  super((Frame) null, "The dialog", true);
  setupUI();
  }

  private void setupUI() {
  table = new JTable();
  DefaultTableModel model = (DefaultTableModel) table.getModel();
  model.setColumnIdentifiers(new Object[]{"myColumn"});
  model.addRow(new String[]{"Row 1 (edit me)"});
  model.addRow(new String[]{"Row 2"});
  getContentPane().add(new JScrollPane(table), BorderLayout.CENTER);
  JButton defaultButton = new JButton("default button");
  defaultButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
    JOptionPane.showMessageDialog(TestTable.this, table.getValueAt(0, 0));
    }
  });
  getRootPane().setDefaultButton(defaultButton);
  getContentPane().add(defaultButton, BorderLayout.SOUTH);
  }

  public static void main(String[] args) {
    TestTable dialog = new TestTable();
    dialog.pack();
    dialog.setVisible(true);
    System.exit(0);
  }
}

Here is the output:


Now if you click on the first row and if you hit the “enter” key, the focus switches to the next row in the JTable (although you defined the “default button” button to be the default button of your dialog):



Now if you start editing the first cell (replacing “edit me” by “edit ME”) and click on the button, this is what happens:



Damn… why does the message box display the old value ? Well, this is because to validate the edition of a cell in a JTable, you are supposed to hit the “enter” key on your keyboard.
Both problems can be solved by calling this method inside the constructor:
private void changeTableProperties() {
  // now hitting "enter" will trigger the "default button" action:
  // (see source code of JTable.CellEditorRemover.propertyChange() method for more information)
  table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
       .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "none");
  // now you can click on the button without having to hit "enter" to finish editing the row:
  // see http://download.oracle.com/javase/tutorial/uiswing/misc/keybinding.html for more information
  table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
  }


From there, hitting the “enter” key will correctly trigger the default button action:



And when editing the cell, you’ll be able to directly click on the button to have your input taken into account (without the need to hit the “enter” key:


Laurent KUBASKI
Advertisements

About lkubaski
www.kubaski.com

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: