10

In SWT you can give any button a shortcut key simply by adding & in front of the letter in the button label. For example, if my button label is &Play, I can activate the button by hitting letter p on the keyboard.

In Swing, you can add a shortcut key using the mnemonic property. However, you need to hit alt+p to activate the button. This is really most appropriate for menu shortcuts. I want to activate the button with a letter press and no alt modifier.

I've seen this post on how to do it, but it seems absurdly complicated. Is there an easier way to do this?

http://linuxjavaprogrammer.blogspot.com/2008/01/java-swing-jbutton-keyboard-shortcuts.html

Update: After @camickr suggestion, I ended up using this code. I couldn't find any clear and simple example online, so hopefully this will help people out.

// play is a jButton but can be any component in the window
play.getInputMap(play.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_P, 0), "play");
play.getActionMap().put("play", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
  playActionPerformed(e);  // some function
}
});
Rich C
  • 3,164
  • 6
  • 26
  • 37

3 Answers3

5

Yes, Swing was designed to use Key Bindings. So instead of adding an ActionListener to the button you add an Action. Then that Action can be shared by the button or a menu item. You can also assign any number of KeyStrokes to invoke the Action by using the KeyBindings. The tutorial also has a section on Actions which explains why using an Action is beneficial.

JComponent has a registerKeyboardAction(...) method which basically does the InputMap/ActionMap bindings for you, but it also has to wrap the ActionListener in a wrapper Action so its preferrable for you to do you own bindings.

camickr
  • 321,443
  • 19
  • 166
  • 288
2

Further to camickr's answer, I am now using a little utility function like this:

public static void clickOnKey(
    final AbstractButton button, String actionName, int key )
{
    button.getInputMap( JButton.WHEN_IN_FOCUSED_WINDOW )
        .put( KeyStroke.getKeyStroke( key, 0 ), actionName );

    button.getActionMap().put( actionName, new AbstractAction()
    {
        @Override
        public void actionPerformed( ActionEvent e )
        {
            button.doClick();
        }
    } );
}

Now to set the keyboard shortcut for a button I just do:

clickOnKey( playButton, "play", KeyEvent.VK_P );
Andy Balaam
  • 6,423
  • 6
  • 34
  • 37
0

I had a similar problem with a dynamically constructed (based on data input) form and just ended up attaching a keyListener action to the buttons. On form construction I parse the Component tree for the buttons and attach the listener. The listener than also parses the tree and matches the keypress with the appropriate button (via the text in the button), since I have no idea which one will have focus at any given time, and fires the button doClick... It's ugly, feels hackish, and has got to be a bit processor intensive, but it allows the flexibility I need for this particular dynamic form...

Brian Knoblauch
  • 20,639
  • 15
  • 57
  • 92