I think that the JTable component should do a better job of filtering the keys that would start editing. I mean, with the current implementation, if you type DEL, Ctrl+Shift+DEL, F5, F7, for example, in an editable cell, the cell editor will appear. In my opinion, start a cell editor with keys like these is very non-intuitive for the end user.
Also, there's another problem: JTable isn't aware of the other possible key bindings defined in the form. If you have a key binding Ctrl+Shift+C defined for a button on your form, if you type this key combination in your JTable, the table will start editing and them your button key binding action will be called next. I think that there should be an easy way to prevent this instead of disabling all those already defined key bindings in your table key binding mapping.
Is there some third party component that already solved, at least partly, some of these issues, specially the one to start editing with a reasonable key? I wouldn't like to do all the tedious filtering myself.
Any help would be appreciated. Thank you.
Marcos
UPDATE
For the time being I'm using this highly imperfect "solution", that at least makes things less worse for the moment. Improvements, comments and suggestions are appreciated.
@Override
public boolean isCellEditable(EventObject e)
{
if (e instanceof MouseEvent)
{
return ((MouseEvent) e).getClickCount() >=
_delegate.getMouseClickCountToStartEditing();
}
else if (e instanceof KeyEvent)
{
KeyEvent event = (KeyEvent) e;
int key = event.getKeyCode();
if ((key >= KeyEvent.VK_F1 && key <= KeyEvent.VK_F12) &&
KeyStroke.getKeyStrokeForEvent(event) != _startEditingKey)
{
return false;
}
int ctrlAlt = KeyEvent.CTRL_DOWN_MASK | KeyEvent.ALT_DOWN_MASK;
if ((event.getModifiersEx() & ctrlAlt) == ctrlAlt)
{
return true;
}
if ((event.getModifiersEx() & ctrlAlt) != 0)
{
return false;
}
return true;
}
else
{
// Is this else really needed? Are there other events types
// other than mouse and key events?
return true;
}
}
// _startEditingKey is obtained with this method
private KeyStroke getStartEditingKey()
{
InputMap bindings = TheTable.this.getInputMap(
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
for (KeyStroke key : bindings.allKeys())
{
Object binding = bindings.get(key);
if ("startEditing".equals(binding))
{
return KeyStroke.getKeyStroke(
key.getKeyCode(), key.getModifiers(), true);
}
}
return null;
}
You can implement a custom editor which reports not being editable if the keyEvent has modifiers you want to ignore:
DefaultCellEditor editor = new DefaultCellEditor(new JTextField()) {
@Override
public boolean isCellEditable(EventObject e) {
if (e instanceof KeyEvent) {
return startWithKeyEvent((KeyEvent) e);
}
return super.isCellEditable(e);
}
private boolean startWithKeyEvent(KeyEvent e) {
// check modifiers as needed, this here is just a quick example ;-)
if ((e.getModifiersEx() & KeyEvent.CTRL_DOWN_MASK) != 0) {
return false;
}
// check for a list of function key strokes
if (excludes.contains(KeyStroke.getKeyStrokeForEvent(e)) {
return false;
}
return true;
}
};
JTable table = new JTable(new AncientSwingTeam());
table.setDefaultEditor(Object.class, editor);
Edit: for a more reliable filtering which can handle the ctrl-alt combinations correctly, you might have a look into DefaultEditorKit.DefaultKeyTypedAction: while basically delegating to a hidden method in the SunToolkit and handling keyTyped (vs. keyPressed needed for filtering the events that are probable candidates for a valid printable character after having started the edit) it might still give you an idea of how to do it (source of the suntoolkit are most probably available in openjdk, didn't search there, though)
You can bind any desired key to the table's startEditing
action, as shown here and here. You can disable undesired keys, as shown here. Some additional nuances are shown here and the article cited here by @camickr.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With