Making a JTable cell editable - but *not* by double clicking
-
13-09-2019 - |
Question
I am trying to add a column to a JTable
with the following behaviour (similar to Windows Explorer and similar shells):
- The cell can be clicked once to select it, as usual.
- The cell can be double-clicked to perform a separate action (launching an external program.)
- The cell value (a string) can still be edited, by single-clicking a second time (after a pause) or by pressing F2 when the cell is highlighted.
Double-clicking must not trigger editing of the cell, but I would like to leave any other default editing triggers operational if possible.
I have tried adding a MouseListener
to the table, and consuming all MouseEvent
s, but this does not work - if I return true
from isCellEditable()
then my listener never receives any click events but if I return false
then F2 no longer works.
Can this be achieved using only event listeners? I would prefer not to mess with the PLAF functions if I can avoid it.
Solution
You will have to make your own cellEditor and ovveride
public boolean isCellEditable( EventObject e )
You can distinguish between single and double click with the clickCount on the eventObject
If its a single Click and its on a selected cell you can return true otherwise return false;
retrieve row and column with
int row = ( (JTable) e.getSource() ).rowAtPoint(e.getPoint());
int column = ( (JTable) e.getSource() ).columnAtPoint(e.getPoint());
to enable F2 you can add custom inputMap en actionMap entries
similar too
table.getInputMap().put(KeyStroke.getKeyStroke("DOWN"), "doMyArrowDown");
table.getTable().getActionMap().put("doMyArrowDown", new ArrowDownAction());
and from your action you can then fire the cellediting yourself
table.editCellAt(row, column );
OTHER TIPS
The DefaultCellEditor has a setClickCountToStart() method to control mouse clicks for editing. The default is 2. Changing this will have no effect on F2 functionality.
Therefore you can set editing to be a triple click.
Not sure exactly how to handle two single clicks to start editing but I guess you would use a Timer to keep track of the first click and then do the editing if the second single click is within you time interval.
I have solved this by wrapping the existing CellEditor
with a Proxy
and intercepting calls to isCellEditable
, returning false for all mouse events and delegating all other calls to the original CellEditor
.
This is slightly more complex than camickr's solution but works for all editors (I have 4 in all.)