3.6 Responding to Keyboard Input
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
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
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.
|