Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Start editing in a JTable cell only with reasonable keys

Tags:

java

swing

jtable

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;
    }
like image 440
Marcos Avatar asked Apr 20 '13 14:04

Marcos


2 Answers

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)

like image 108
kleopatra Avatar answered Oct 12 '22 11:10

kleopatra


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.

like image 20
trashgod Avatar answered Oct 12 '22 10:10

trashgod