How to Use Key Bindings
5 stars based on
This document provides a review of the existing key binding facilities in Swing and defines a new set of APIs that unify what we have today and satisfy the requirements listed in the next section.
Requirements for the Keyboard Binding Infrastructure This is a list of all of the requirements we've tried to satisfy, roughly in priority order.
Unify the existing keybinding facilities. Disconnect bindings from UI specific actions. Make tables of bindings easier to read. Expose the complete list of actions a component supports. Developers should be able to extend this list easily.
It should be easy to find the binding for control-shift-A in the source code, even if there are bindings defined by the ComponentUI class. This implies that a table of bindings shouldn't be tangled up with boilerplate. Each ComponentUI subclass should provide a table of the actions it defines. This list could also be exposed by JComponent.
All actions should have a name, and a short description. The AbstractAction class allows for this. The name can be used when defining a key binding.
This documents the action for the sake of future Swing developers, for generating javadoc, and for IDE users. If we provide access to java key bindings without focus list of actions and the list of bindings, building a customizer or whatever java key bindings without focus allows one to change the bindings or add new ones would be straightforward.
If we're going to allow developers to easily customize the keyboard bindings we should ensure that it's easy to restore the default bindings for a component. It should be straightforward to generated a tidy Java key bindings without focus table that shows the mapping from keys to actions. Ideally one should be able to do this without creating an instance of the component whose bindings you'd like to java key bindings without focus.
For example a subclass of JList should be able to create a set of generic actions that would be visible in builders in the same way that the actions provided by the ListUI class are. Both approaches use KeyStroke and Action objects to characterize a binding. On the whole they're more the same than they are different. Here's a quick review of each one. The JComponent class supports managing keyboard bindings with a set of public methods that add and remove entries in a private table:.
The registerKeyboardAction methods add an entry to the table that means: The actionPerformed method is passed an ActionEvent whose java key bindings without focus is the component and whose actionCommand is the specified command string. The shorter version of registerKeyboardAction just uses null for command. The condition allows one to specify when the binding is valid:. The unregisterKeyboardAction and resetKeyboardActions methods support removing one binding or all of them. In addition to the methods for managing the binding table, there are a few public JComponent methods for reading the table:.
Keystroke processing is driven by JComponent. All of the ComponentUI subclasses use registerKeyboardAction to enable keyboard navigation, except for the text classes. The code that does this is largely boilerplate and can be difficult to read in large doses.
JTextComponent, the superclass for the Swing text components, uses an ordered list java key bindings without focus named Keymaps to define key bindings. Each text component has a default keymap that contains generic key bindings. The TextUI classes insert look and feel specific Keymaps in front of the java key bindings without focus one. The default keymap, which is the tail of the keymaps list, is the value of the JTextComponent "keymap" property:.
The following JTextComponent static utility methods support managing Keymap lists. The addKeymap method inserts an empty keymap named name before parentremoveKeymap removes a keymap from the list, and getKeymap looks one up by name. The Keymap class provides a nice set of methods for managing bindings, e. If the bindings Action is enabled, it's actionPerformed method is applied to an ActionEvent whose actionCommand property is the string value of the key character that matched the binding.
KeyMaps also have a defaultAction java key bindings without focus that's used for KeyEvent. The text components also support a read-only property called "actions" whose value is a complete list of the actions supported by the Component. Both the generic actions and the look and feel specific actions are combined to form this list.
The result is relatively easy to read. There are two serious incompatabilities between the JComponent registerKeyboardAction machinery and the Keymap based system in the text package:.
The text package doesn't explicitly allow for creating bindings that apply when a descendant has the focus or when the components ancestor window has the focus. Most of the non text Swing components use an informational name for the command.
Dependencies on these names have started to creep in, e. The text components rely java key bindings without focus the ActionEvents "actionCommand" java key bindings without focus being string version of the KeyEvents keyChar property.
Keymaps don't allow one to specify a overriding value to use for actionCommand. We can work around this incompatibility by allowing Action objects to provide the command string, and then using the keyChar string when the Actions command string is null.