Key Bindings
An Introduction with Examples in Java |
Prof. David Bernstein |
Computer Science Department |
bernstdh@jmu.edu |
JComponent
objects to respond
to the keyboardAbstractButton
,
JLabel
, and JTabbedPane
)JMenutItem
)Action
objects)
so are more maintainableJComponent
to have the
focusJComponent
ObjectsActionMap
Object:
Action
to
a String
that has been mapped/bound to
a KeyStroke
)InputMap
Objects:
JComponent
has the focusJComponent
contains (or is)
the component that has the focusJComponent
is in the window
that has the focusInputMap
objects is searched
for a matching bindingActionMap
is searched for
a matching Action
Action
is enabled
it's actionPerformed()
method is called
(and the process is terminated), otherwise the search
continuesInputMap
Search Order:
WHEN_FOCUSED
mapWHEN_ANCESTOR_OF_FOCUSED_COMPONENT
mapWHEN_ANCESTOR_OF_FOCUSED_COMPONENT
maps
of enabled containers (in order)WHEN_IN_FOCUSED_WINDOW
maps (in no
particular order)
ArrowPad
import java.awt.*; import java.awt.event.*; import javax.swing.*; /** * A virtual arrow pad that responds to wasd key presses. * * @author Prof. David Bernstein, James Madison University * @version 1.0 */ public class ArrowPad extends JPanel { JButton down, left, right, up; /** * Default Constructor. */ public ArrowPad() { super(); ArrowAction action; down = new JButton("\u2193"); left = new JButton("\u2190"); right = new JButton("\u2192"); up = new JButton("\u2191"); down.setActionCommand("DOWN"); left.setActionCommand("LEFT"); right.setActionCommand("RIGHT"); up.setActionCommand("UP"); // The same Action is used here for all of the JButton // objects. One could, instead, have a different Action for // each. action = new ArrowAction(); down.addActionListener(action); left.addActionListener(action); right.addActionListener(action); up.addActionListener(action); setupKeyBindings(); performLayout(); } /** * Perform the necessary steps to layout this ArrowPad. */ private void performLayout() { Box bottom, main, top; setLayout(new FlowLayout(FlowLayout.CENTER)); main = Box.createVerticalBox(); bottom = Box.createHorizontalBox(); top = Box.createHorizontalBox(); top.add(up); bottom.add(left); bottom.add(down); bottom.add(right); main.add(top); main.add(bottom); add(main); } /** * Setup the key bindings to use. * * In this implementation, the wasd keys correspond to the virtual * up, left, down, and right buttons. One could, alternatively or * additionally, use the arrow keys and/or the arrow keys on the * numeric keypad. */ private void setupKeyBindings() { ActionMap actionMap; InputMap inputMap; actionMap = this.getActionMap(); inputMap = this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "w"); actionMap.put("w", new ClickAction(up)); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), "a"); actionMap.put("a", new ClickAction(left)); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0), "s"); actionMap.put("s", new ClickAction(down)); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "d"); actionMap.put("d", new ClickAction(right)); } }
Action
for the JButton
Objectsimport java.awt.event.*; import javax.swing.*; /** * A placeholder for an Action associated with arrow buttons. * * @author Prof. David Bernstein, James Madison University * @version 1.0 */ public class ArrowAction extends AbstractAction { /** * Handle an actionPerformed() message (required by AbstractAction). * Specifically, output the action command on the console. * * @param evt The ActionEvent that generated the message. */ public void actionPerformed(ActionEvent evt) { System.out.println(evt.getActionCommand()); } }
Action
for the ActionMap
import java.awt.event.*; import javax.swing.*; /** * A ClickAction object can be used to programmatically * generate a button click. * * @author Prof. David Bernstein, James Madison University * @version 1.0 */ public class ClickAction extends AbstractAction { private static final int DELAY = 50; // millis private AbstractButton button; /** * Explicit Value Constructor. * * @param button The button to click */ public ClickAction(AbstractButton button) { super(); this.button = button; } /** * Handle an actionPerformed() message (required by AbstractAction). * Specifically, give the focus to and click the button. * * @param evt The ActionEvent that generated the message. */ public void actionPerformed(ActionEvent evt) { button.grabFocus(); // Programmatically perform a "click". This does the same // thing as if the user had pressed and released the button. //The button stays visually "pressed" for DELAY milliseconds. button.doClick(DELAY); } }