|
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);
}
}