Java Tips Weblog

  • Blog Stats

    • 1,845,415 hits
  • Categories

  • Archives

Action Map Action

Posted by Rob Camick on December 6, 2008

The ActionMap contains predefined Actions for a given Swing component. Many, but not all, of these Actions are mapped to a KeyStroke so they can be invoked by the user. Regardless of whether an Action is mapped to a KeyStroke or not, there may be times when you want to use a button or a menu item to invoke one of these existing actions. These components support the setAction() method, so all we need to do is retrieve the Action from the ActionMap.

Well, actually its not quite that easy. Sure we can easily retrieve the Action and add it to a button, but the problem is that the source of the ActionEvent will now be the button, not the component we want to perform the Action on. This may, or may not, be a problem depending on the Action.

The ActionMapAction class will act as a simple wrapper class. You specify the action name identifier used in the ActionMap and it will find the related Action. Whenever it is invoked it will create an new ActionEvent using the specifed Component as the source Component and then invoke the Action from the ActionMap.

For example, creating a button that invokes an Action on a text field is as simple as:

JTextField textField = new JTextField();
Action nextWord = new ActionMapAction(
    "Select Next Word", textField, "selection-next-word");
nextWord.putValue(AbstractAction.MNEMONIC_KEY, KeyEvent.VK_N);
JButton nextButton = new JButton(nextWord);

Clicking on the button would result in…

action-map-action

Check out the Key Bindings entry below for a list of all the currently defined Actions for each component. Now you can easily invoke existing Actions with the keyboard or the mouse.

Get The Code

ActionMapAction.java

See Also

Key Bindings

Advertisements

2 Responses to “Action Map Action”

  1. Kleopatra said

    Hi Rob,

    neat trick :-)

    Just the other day I had do something similar – only differing in looking up the action at the time of the actionPerformed instead of at the time of instantiation (this way delegating to a potentially replaced original action).

    One little glitch, though: the example is not so good, IMO – TextActions don’t care about the sender but always act on the focused textComponent. That is, the example only works if the textfield is focusOwner and the buttons are not focusable.

    Keep up the good work!
    Jeanette

    • Rob Camick said

      > only differing in looking up the action at the time of the actionPerformed

      Maybe a better solution would be to have a property to specify a dynamic or static lookup of the Action.

      > the example only works if the textfield is focusOwner and the buttons are not focusable

      Yes, that is the way the example works. Its difficult to show a “dynamic Action” in a static image. I was thinking of using a menu item, but then again you can’t show the clicking of the menu item, so this was my compromise.

      Thanks for the feedback.

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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 )

Google+ photo

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

Connecting to %s

 
%d bloggers like this: