Graphic Java 2: Mastering the Jfc, By Geary, 3Rd Edition, Volume 2: Swing

Swing provides a flexible framework for keyboard-based control, which can be used by any component. The rest of the chapter explains this mechanism.

3.6.1 The InputMap Class

InputMap maps keystrokes to logical action names. When the user types a key combination, it's looked up in the input map of the focused component (and perhaps other components in the active window, as described earlier). If a match is found, the resulting object is used as a key in the corresponding component's ActionMap to look up the concrete Action class to be invoked. The platform-specific L&F implementations provide InputMaps consistent with the key-binding conventions for their platforms.

When looking for values in an InputMap, a java.awt.KeyStroke is always used as the key. KeyStroke is a simple, immutable class that represents a particular keyboard action (including any modifier keys). KeyStrokes are intended to be unique (that is, if two KeyStroke variables represent the same action, they should reference the same KeyStroke instance). To ensure uniqueness, you can't create KeyStrokes directly; you must obtain them through the static getKeyStroke( ) factory methods in the KeyStroke class.

Although the result of looking up a KeyStroke in an InputMap is an arbitrary object, and any object can be used as a key for looking up an action in an ActionMap, in practice the values are Strings. By convention, their content is a descriptive name for the action to be performed (such as copy, print, save, or the like). This allows InputMaps to be largely self-documenting (it's easy to print their contents as a "cheat sheet" showing the keys that invoke particular commands) and also improves the readability of code that requests actions programmatically. The most common way this string is obtained is by calling getName( ) on the Action to be added to the map.

InputMaps can be chained together so that common functionality can be shared in a basic InputMap; specialized components can add custom keystrokes to their own InputMap and delegate the common cases to the shared map via the parent property.

3.6.1.1 Property

The single property defined by InputMap is shown in Table 3-10. The parent property establishes a fallback InputMap that is consulted if a key mapping is not found in the current map, much as the inheritance chain is followed when looking up the members of Java classes. If you create a cycle in the parent chain (for example, by setting two InputMaps to be parents of each other), many of the method calls crash with a StackOverflowError.

Table 3-10. InputMap property

Property

Data type

get

is

set

Default value

parent

InputMap

·

 

·

null

3.6.1.2 Constructor

public InputMap( )

The default constructor is the only constructor available. It creates an empty InputMap with no parent.

3.6.1.3 Methods

public KeyStroke[] allKeys( )

Return an array of all KeyStrokes defined in the InputMap, either directly or anywhere along the parent chain. If there are no mappings, this method returns either an empty array or null, depending on the history of the InputMap(s). Each key appears only once even if it overrides another on the parent chain.

public void clear( )

Remove all keystroke mappings from this InputMap (does not affect any mappings in the parent chain).

public Object get(KeyStroke keyStroke)

Look up the specified keyStroke in the InputMap (and the parent chain), returning a value that represents the logical action that should be taken in response. If no match is found, returns null. The result is generally used immediately to look up an Action in the ActionMap of the component that owns this InputMap. Convention dictates that the values returned are Strings describing the nature of the action to perform.

public KeyStroke[] keys

Return an array of KeyStrokes locally defined in this InputMap. That is to say, it does not follow the parent chain. If there are no mappings, this returns either an empty array or null, depending on the history of the InputMap.

public void put(KeyStroke keyStroke, Object actionMapKey)

Define a new mapping for the specified keyStroke. Future calls to the get( ) method return actionMapKey as the logical action associated with keyStroke. As suggested by the parameter name, actionMapKey is intended to be used to look up an Action in an ActionMap. By convention, it should be a String whose value is descriptive of the action. (Appendix B lists the standard ActionMap keys supported by Swing components; your own classes can use these or define their own as appropriate.) Passing a null actionMapKey has the same effect as calling remove(keyStroke).

public void remove(KeyStroke keyStroke)

Remove the mapping defined for the specified keyStroke from this InputMap. Looking up that keyStroke in the future returns a value that is determined by the parent chain (which is not affected by this method). If you want to "block" a mapping in a shared InputMap that is part of your parent chain, define a mapping for that KeyStroke to the string none. By convention, there is never an Action associated with none in any ActionMap, so its presence in your InputMap causes the parent check to be skipped without allowing any action to take place.

public int size( )

Return the number of mappings defined in this InputMap (not counting any that might be defined in the parent chain). For a new or newly cleared InputMap, this returns 0.

3.6.2 The ActionMap Class

ActionMap is responsible for mapping logical action names to concrete Action instances that carry them out. When the user types a key combination, it's looked up in the InputMap of a component, and the result is looked up as a key in the corresponding ActionMap.

Although any object can be used as a key in an ActionMap, in practice they are Strings. By convention, their content is a descriptive name for the action to be performed (such as copy, print, save, or the like), often obtained by calling getName( ) on the corresponding Action.

ActionMaps can be chained together so that common functionality can be shared in a basic ActionMap; specialized components can add unique actions to their own ActionMap and delegate the common cases to the shared map through the parent property.

A component's ActionMap can also be used to configure auditory cues to be played at appropriate points by the component, as described in Chapter 26.

3.6.2.1 Property

The single property defined by ActionMap is shown in Table 3-11. The parent property establishes a fallback ActionMap that is consulted if an action name is not found in the current map, much as the inheritance chain is followed when looking up the members of Java classes. If you create a cycle in the parent chain (for example, by setting two ActionMaps to be parents of each other), many of the method calls crash with a StackOverflowError.

Table 3-11. ActionMap property

Property

Data type

get

is

set

Default value

parent

ActionMap

·

 

·

null

3.6.2.2 Constructor

public ActionMap( )

The default constructor is the only constructor available. It creates an empty ActionMap with no parent.

3.6.2.3 Methods

public Object[] allKeys( )

Return an array of all logical action names defined in the ActionMap, either directly or anywhere along the parent chain. If there are no mappings, this method returns either an empty array or null, depending on the history of the ActionMap(s). Each key appears only once even if it overrides another on the parent chain.

public void clear( )

Remove all action mappings from the local ActionMap (does not affect any in the parent chain).

public Action get(Object key)

Look up the specified action name in the ActionMap (and the parent chain), returning the corresponding Action to be executed. If no match is found, returns null. The keys are often obtained by looking up a KeyStroke in an InputMap.

public Object[] keys

Return an array of the logical action names locally defined in this ActionMap. That is to say, it does not follow the parent chain. If there are no mappings, this returns either an empty array or null, depending on the history of the ActionMap.

public void put(Object key, Action action)

Define a new mapping for the specified action. Future calls to the get( ) method return it as the Action associated with the logical name key. By convention, key should be a String whose value is descriptive of the action. Appendix B lists the standard ActionMap keys supported by Swing components; your own classes can use these as well, or define their own, as appropriate. Passing a null key has the same effect as calling remove(action).

public void remove(Object Key)

Remove the mapping defined for the specified key from this ActionMap. Looking up that logical action name in the future returns a value determined by the parent chain (which is not affected by this method).

public int size( )

Return the number of mappings defined in this ActionMap (not counting any that might be defined in the parent chain). For a new or newly cleared ActionMap, this method returns 0.

Категории