JMU
Key Bindings
An Introduction with Examples in Java


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu


Getting Started
Key Bindings vs. Key Listeners
Supporting Classes
Attribute of JComponent Objects
The Process
An Example

An ArrowPad

javaexamples/keybindings/ArrowPad.java
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));
    }
}
        
An Example

The Action for the JButton Objects

javaexamples/keybindings/ArrowAction.java
import 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());
    }
}
        
An Example

The Action for the ActionMap

javaexamples/keybindings/ClickAction.java
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);
    }
}