I don't know if this is the "proper" way to handle having multiple keystrokes for one action, but until I find a better approach I thought I'd share this here.
For my Java text editor application, on Mac OS X I want the user to be able to use any of the following keystrokes to increase the font size by one unit:
- [Apple][=]
- [Apple][Shift][=]
- [Apple][+]
Each of those keystrokes might be interpreted by a user as being equivalent to [Apple][+], so I want to be sure I support all three of them.
To tackle this problem, I've defined these three keystrokes as follows:
// handle [meta][equals], [meta][equals][shift], and [meta][plus] private KeyStroke largerFontSizeKeystroke1 = KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS, Event.META_MASK); private KeyStroke largerFontSizeKeystroke2 = KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS, Event.META_MASK + Event.SHIFT_MASK); private KeyStroke largerFontSizeKeystroke3 = KeyStroke.getKeyStroke(KeyEvent.VK_PLUS, Event.META_MASK);
Hopefully you can read that code, and see that each keystroke corresponds to my bulleted items above.
Add KeyStroke objects to ActionMap and InputMap
Next, I add each of these KeyStroke definitions to the InputMap and ActionMap for my text editing area, which is technically a JTextPane like this:
largerFontSizeAction = new LargerFontSizeAction(mainFrameController, this, "Increase Font Size", largerFontSizeKeystroke1.getKeyCode()); // add largerFontSizeKeystroke1 getEditorPane().getInputMap().put(largerFontSizeKeystroke1, "largerFontSizeKeystroke"); getEditorPane().getActionMap().put("largerFontSizeKeystroke", largerFontSizeAction); // add largerFontSizeKeystroke2 getEditorPane().getInputMap().put(largerFontSizeKeystroke2, "largerFontSizeKeystroke2"); getEditorPane().getActionMap().put("largerFontSizeKeystroke2", largerFontSizeAction); // add largerFontSizeKeystroke3 getEditorPane().getInputMap().put(largerFontSizeKeystroke3, "largerFontSizeKeystroke3"); getEditorPane().getActionMap().put("largerFontSizeKeystroke3", largerFontSizeAction);
As mentioned, I don't know if there is a better way to handle this particular Java KeyStroke need, but I can confirm that this approach does work.
I suspect that I can cut down on half of those lines by using the same "actionMapKey" for all three keystrokes (see the Java InputMap class), but as I'm writing this I'm just a wee bit tired, so I'll try to come back to this later.
Javadoc links
Before I leave, here are links to the Java classes referenced in this tutorial: