Java Tips Weblog

  • Blog Stats

    • 2,189,652 hits
  • Categories

  • Archives

  • Advertisements

Key Bindings

Posted by Rob Camick on October 10, 2008

All Swing components use Key Bindings, but what are they? Well, have you ever wondered how the “copy” functionality of a text component works? The KeyStroke (Ctrl+C) is used to invoke an Action (copy). So a key binding is simply the mapping of a KeyStroke to an Action.

Swing uses an InputMap (well actually it uses three of them), to contain the KeyStrokes and an ActionMap to contain the Actions. The InputMap and ActionMap are linked together so that when a key on the keyboard is invoked the action is performed. The Swing tutorial on “How to Use Key Bindings” gives a much better description of this process then I can provide here, so I suggest you read it for more detail, as it is important to understand the usage of the three different InputMaps.

After reading the tutorial, hopefully you will realize that key bindings are an easy way to customize the behaviour of a component. A summary of the basic code for different key binding features would be something like:

  • add new functionality by adding a new key binding: 
    Action action = new AbstractAction() {...};
    String keyStrokeAndKey = "control Z";
    KeyStroke keyStroke = KeyStroke.getKeyStroke(keyStrokeAndKey);
    component.getInputMap(...).put(keyStroke, keyStrokeAndKey);
    component.getActionMap().put(keyStrokeAndKey, action);
  • change existing functionality by replacing the Action of an existing binding: 
    Action action = new AbstractAction() {...};
    KeyStroke keyStroke = KeyStroke.getKeyStroke("control Z");
    InputMap im = component.getInputMap(...);
    component.getActionMap().put(im.get(keyStroke), action);
  • share an Action with a different KeyStroke: 
    KeyStroke existingKeyStroke = KeyStroke.getKeyStroke("ENTER");
    KeyStroke addedKeyStroke = KeyStroke.getKeyStroke("control Z");
    InputMap im = component.getInputMap(...);
    im.put(addedKeyStroke, im.get(existingKeyStroke));
  • bind an Action to a KeyStroke:
    KeyStroke addedKeyStroke = KeyStroke.getKeyStroke("control Z");
    InputMap im = component.getInputMap(...);
    im.put(addedKeyStroke, "caret-end-word"); // from the "Action" column below
  • remove a key binding: 
    KeyStroke remove = KeyStroke.getKeyStroke(...);
    InputMap im = component.getInputMap(...);
    im.put(remove, "none");

Note, the above examples are for adding bindings to individual components. To add a binding at the frame or dialog level you need to use the InputMap and ActionMap of the root pane:


So, now that you know that key bindings exist, you are probably wondering what the default key bindings are for each component, right? Well, if you are curious, then the Key Bindings application is a good starting point to find this information.

The above discussion deals with changing the bindings for an individual component. But there may be times when you need to change a binding for all components of a given class. In this case the UIManager can help you out. It has access to the InputMap that is used by all components. So if you modify that InputMap it will be changed for all components. You access this InputMap with code like the following (using a JTextField as an example):

InputMap im = (InputMap)UIManager.get("TextField.focusInputMap");

Remember that there are potentially 3 different InputMaps for any given component so you should use the UIManager Defaults program (link below) to determine the appropriate InputMap to update.

There is also a shared ActionMap that you can access (again using a JTextField as an example):

ActionMap am = (ActionMap)UIManager.get("TextField.actionMap");

You should only try to access these shared maps after an instance of the component has been created.

Try The Demo

Launch – Using Java™ Web Start (JRE 6 required)

Get The Code

See Also

UIManager Defaults

Related Reading

How to Use Key Bindings
How to Use Actions


12 Responses to “Key Bindings”

  1. Torgil Zethson said

    This is an awesome little program! I wish had it (or had the good sense of writing something like it myself…) years ago.

    – Torgil

  2. camickr said

    Thanks. Writing the code helped me better understand how key binding worked and it sure beats looking at the code to find action names.

  3. Torgil Zethson said

    > and it sure beats looking at the code to find action names

    Definitely. It is very useful (in fact, I’ve used it already at work).

  4. Christian Ortiz said

    Hi. i want to put a different keystroke to a JButton. in my case ENTER because default inputmap is space. i am trying but no success. i want to add a actionperformed to a button and when it´s focus i can press enter and the action for button response.

    please help.

    this is the code i am coding.

    KeyStroke existingKeyStroke = KeyStroke.getKeyStroke(“SPACE”);
    KeyStroke addedKeyStroke = KeyStroke.getKeyStroke(“ENTER”);
    InputMap im = jButton1.getInputMap((JComponent.WHEN_FOCUSED));
    im.put(addedKeyStroke, im.get(existingKeyStroke));

    thanks a lot. sorry by my poor english.

  5. Christian Ortiz said

    perfect you got a solution at. exactly what i was looking for. i will try for all buttons the same things thanks a lot

  6. Excellent post. I knew JTable supported copy out of the box, but I didn’t know why. Thanks to your post on Action Map Action, I can easily create a context menu option to copy out of the table as well. Thanks!

  7. Steve Cohen said

    Tremendous! I’ve been beating my head against the wall with this stuff.

  8. Anonymous said

    This is wonderful, as I’ve said before, however, now Java 6 is past end of life and security settings won’t let me launch this. Yet I need to see the information that I know is here. Help!

    • Anonymous said

      No biggy, I just got the source, compiled and ran it. But it might be worthwhile for you to update the page to not require an obsolete version of java.

      • Rob Camick said

        As far as I know it should run on any version of Java from 1.6 and above. I think the security message is the browser. I must admit I don’t really understand the security implications of using Web Start and what is necessary to fix the problem. I have been using JDK1.7.u10 for over a year with no problems (that I can remember). However yesterday I did upgrade to JDK1.7.60 and am now having problems. So, yes, I will try to look into this. All code can be freely downloaded as you did so it is not a big issue. I just though I would include the WebStart apps to demonstrate some of the features of the code without you needing to write you own little test app. Thanks for the feedback.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: