5

I need to override the enter key functionality on a JTable. At present the default behaviour is to move the row selection down one row when the user presses the 'Enter' key. I want to disable this and get it to do something different based on their selection. The problem is that it seems to move down before it goes into my keylistener which takes in the row selection - this therefore opens another window with the wrong row selected.

This is my code so far...:

public class MyJTable extends JTable {


   public MyJTable(){
        setRowSelectionAllowed(true);
        addListeners()
    }

    public void addListeners(){

         addKeyListener(new KeyListener() {
                @Override
                public void keyTyped(KeyEvent e) {}

                @Override
                public void keyPressed(KeyEvent e) {}

                @Override
                public void keyReleased(KeyEvent e) {
                    int key = e.getKeyCode();
                    if (key == KeyEvent.VK_ENTER) {

                        openChannel();
                    }
                }
           });
    }

    public void openChannel(){
            for (int selectedRow : getSelectedRows()){
                //Code to open channel based on row selected
            }
        }
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
maloney
  • 1,633
  • 3
  • 26
  • 49
  • 1
    `KeyListener` is not the way to go, Swing components use `KeyBinding`s. Thus there is a remove method, remove `KeyBinding`s from `JTable`, and add your own. – David Kroukamp Nov 22 '12 at 16:33
  • unrelated: the JSomething are meant to be _used_ - don't subclass if you can reach the same by configuration. – kleopatra Nov 22 '12 at 16:42
  • Thanks for your answers, that works great. @Kleopatra, I understand that, but this JTable needs to be extended, the example was only some test code so you can see what the problem was. But il bear that in mind for the future. – maloney Nov 22 '12 at 16:50

2 Answers2

21

+1 to @Robin's answer

Adding to my comment...

Swing uses KeyBindings simply replace exisitng functionality by adding a new KeyBinding to JTable (the beauty happens because of JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT):

private void createKeybindings(JTable table) {
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "Enter");
    table.getActionMap().put("Enter", new AbstractAction() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            //do something on JTable enter pressed
        }
    });
}

simply call this method and pass JTable instance to override standard functionality of JTable ENTER

David Kroukamp
  • 36,155
  • 13
  • 81
  • 138
5

This is implemented using key bindings, which is preferred over key listeners. I strongly suggest you do the same: replace your key listener by a key binding.

The solution is replace the entry in the InputMap to point to your own Action (which you insert in the action map), or to just replace the appropriate entry in the action map.

The key bindings tutorial contains more info

Robin
  • 36,233
  • 5
  • 47
  • 99