JTables
Using combo-box cell editor
If you use a combo-box cell editor, you must call:
table.setSurrendersFocusOnKeystroke (true);
in order to use the keyboard to choose a value in the combo-box.
Checking input
Checking user input to table cells has to deal with the following behaviour of JTables:
- When the user starts editing a table cell, the JTable calls the
getTableCellEditorComponent method of the cell editor. Initially, while
the cell is being edited, the JTable has focus. The cell editor does
NOT have focus.
- If the user attempts to move to another cell in the table (using
the mouse or keyboard), the JTable calls editor.stopCellEditing.
- If stopCellEditing returns true, the JTable calls
model.setValueAt to store the value, and the move succeeds (and the
JTable still has the focus). The default cell editor also fires an
event before returning true, which causes the JTable to switch to using
the renderer to display the cell instead of the editor.
- If stopCellEditing returns false, the move fails, the JTable loses focus and the editor gains focus!
- It is also possible for the cell editor to gain focus if the
user triple-clicks on the cell, or if the user clicks on the cell when
it is already being edited.
- If the user attempts to move to a component outside the table
(using keyboard or mouse), the move succeeds and the JTable or the cell
editor (whichever has focus) loses focus. No editor method is called,
and the editor is left displaying the cell.
- It is possible to change the loss-of-focus behaviour by calling:
table.putClientProperty ("terminateEditOnFocusLost", Boolean.TRUE);
If the user now attempts to move to a component outside the table, the
JTable calls editor.stopCellEditing. If stopCellEditing returns true,
model.setValueAt is called and editing is stopped. If stopCellEditing returns
false, editor.cancelCellEditing is called and editing is stopped. In
both cases, the move succeeds and focus is transferred outside the
table. This behaviour appears not to depend on whether it was the
JTable or the editor that initially had focus.
- It is possible to ensure that the cell editor always has focus when editing, by calling:
table.setSurrendersFocusOnKeystroke (true);
If the user now attempts to move outside the table, it will always be the editor that loses focus.
Given the above behaviour, the following steps seem to be the simplest way to do input verification:
- Call table.setSurrendersFocusOnKeystroke (true) to simplify the focus cases.
- Provide your own cell editor (i.e. call table.getColumnModel ().getColumn (col).setCellEditor (editor)):
- The editor should extend DefaultCellEditor.
- The editor should use a JTextField for editing.
- Set up an InputVerifier on the text field to check user input -
this will prevent focus moving out of the table if the input is invalid.
- Override the editor stopCellEditing method to also check user input - this will prevent moves within the table if the input is invalid. Remember to call super.stopCellEditing to fire the event that tells the JTable that editing has stopped.
- Call table.putClientProperty ("terminateEditOnFocusLost", Boolean.TRUE) - this will cause valid input to be stored when focus moves out of the table.