Calling a routine when up or down is pressed in a JTable

1.9k Views Asked by At

This code calls a routine when enter is pressed in a JTable (called gametable). It works well, but I would like the same Action to be called when moving up or down in the JTable without the need for pressing enter; I can't get it to work. I tried substituting VK_ENTER with VK_UP, but I am unable to move up and down the table?

KeyStroke enter = KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ENTER, 0);

gameTable.getJTable().unregisterKeyboardAction(enter);
gameTable.getJTable().registerKeyboardAction(new ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent e) {
            synchronized (this) {
                gotoGame(gameTable.getSelectedIndex());
            }
        }
    }, enter, JComponent.WHEN_FOCUSED);

I can't figure it out. Can someone help me?

2

There are 2 best solutions below

3
On

You need to add a keylistener to your JTable. Then in your key listener you can check for any button pressed including Enter and take the same action.

I have a program with similar code. Here I just display different values in one textarea if the arrow key choose a different cell, but I think it may give you an idea of how to set it up.

import java.awt.event.KeyEvent;

import javax.swing.JTable;

public class MyClass {
    static JTable table = new JTable();

    public static void main(String[] args) {
        table.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(final java.awt.event.KeyEvent evt) {
                tableKeyReleased(evt);
            }
        });
    }

    private static void tableKeyReleased(final java.awt.event.KeyEvent evt) {
        final int key = evt.getKeyCode();
        if (key == KeyEvent.VK_UP || key == KeyEvent.VK_DOWN
                || key == KeyEvent.VK_LEFT || key == KeyEvent.VK_RIGHT) {
            final int row = table.getSelectedRow();
            final int column = table.getSelectedColumn();

            final Object cellValue = table.getValueAt(row, column);

            if (cellValue == null) {
                return;
            }

        }
    }
}
1
On

You'll have to separate the steps:

  1. First put two KeyStroke instances in the InputMap so they target the same actionMapKey:

    KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
    KeyStroke up = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0);
    String actionMapKey = "anActionMapKey";
    gameTable.getInputMap().put(enter, actionMapKey);
    gameTable.getInputMap().put(up, actionMapKey);
    
  2. Then associate that actionMapKey with your Action:

    gameTable.getActionMap().put(actionMapKey, new AbstractAction(actionMapKey) {
        ...
    });
    

See How to Use Actions and Key Bindings for details.

I am wary of your use of synchronized (this) in this context; you should be constructing your GUI on the event dispatch thread.