Keyboard event processing

 

Overview

Any application or applet can detect and process keyboard events by using built-in features of the java.awt and java.awt.event packages.

 

The KeyEvent class

To receive and process a KeyEvent, a component must register a KeyListener. For example, if myCanvas is a Canvas object, the statement

myCanvas.addKeyListener(this);

will register a listener for all keyboard events that may be fired by the myCanvas component. All that remains is to implement the interface and its required methods. This will be covered shortly.

Method

Usage

getKeyChar()

Returns the Unicode character associated with the key in this event

getKeyCode()

Returns the the virtual key code associated with the key in this event

 

The KeyListener interface

x.addKeyListener(this);

When a keyboard event occurs within component x, a KeyEvent object will be automatically fired to the relevant method within the listener object.

Method

Usage

keyPressed()

Invoked when any key has been pressed on a component.

This is a low-level event handler that is automatically called regardless of whether the key generates a character or not (such as the Alt key). The virtual key code of the key can be obtained by calling the getKeyCode() method of the KeyEvent object.

keyReleased()

Invoked when any key has been released on a component.

This is a low-level event handler that is automatically called regardless of whether the key generates a character or not (such as the Alt key). The virtual key code of the key can be obtained by calling the getKeyCode() method of the KeyEvent object.

keyTyped()

Invoked only when one or more key events generate a Unicode character on a component.

This is a high-level event handler that is automatically called only if a Unicode character (such as the letter 'x') is generated. The value of the character can be obtained by calling the getKeyChar() method of the KeyEvent object. 

The calling sequence for key events can be confusing. For example, if the user presses the 'Shift-a' key combination to enter an upper case 'A', the order in which the methods are called is as follows:

keyPressed() - for the Shift key

keyPressed() - for the 'a' key

keyReleased() - for the 'a' key
keyTyped() - for the 'a' key
keyReleased() - for the Shift key

If the user presses and releases a key for which no character is generated, the keyTyped() method will not be called. For example, if the user presses and releases the Ctrl key, the calling sequence is:

keyPressed() - for the Ctrl key

keyReleased() - for the Ctrl key

For most simple needs, the high-level keyTyped() method is sufficient unless the program must know about key presses and releases that don't generate a character. Consult the Java API for more details.

 

The KeyAdapter class

Rather than implement the KeyListener interface, a class may choose to extend the KeyAdapter class. It contains definitions for all required interface methods so that only the method or methods of interest must be coded to override those that are inherited.

The technique is most often used when registering and defining an inner listener. For example, if x is the reference of some component, you may register and define its listener for handling key events by coding:

x.addKeyListener(
  new KeyAdapter() {
    public void keyTyped(KeyEvent e) {
     
custom code goes here...
    }
  }
);

When a key is typed within component x, a KeyEvent object will be automatically fired to the custom code defined within this inner listener.

 

A sample applet that uses keyboard events

This applet detects an individual keystroke and displays the character in a very large font size:

import java.awt.*;
import java.awt.event.*;
import java.applet.*;

public class App extends Applet implements KeyListener {

  Canvas canvas = new Canvas();
  Label help = new Label("Press any key");

  public void init() {
    resize(200, 200);
    setLayout(new BorderLayout());
    canvas.setForeground(Color.blue);
    canvas.setFont(new Font("SanSerif", Font.PLAIN, 100));
    canvas.addKeyListener(this);
    add(canvas);
    help.setBackground(Color.lightGray);
    help.setAlignment(Label.CENTER);
    add(help, BorderLayout.SOUTH);
    canvas.requestFocus();
  }

  // Methods required by the KeyListener interface.

  public void keyTyped(KeyEvent e) {
    Graphics g = canvas.getGraphics();
    g.clearRect(0,0,canvas.getWidth(),canvas.getHeight());
    g.drawString(new Character(e.getKeyChar()).toString(), 70, 120);
  }
  public void keyPressed(KeyEvent e) {}
  public void keyReleased(KeyEvent e) {}
}

Notes:

  1. In order to handle keyboard events, the applet implements the KeyListener interface.

  2. The applet has a Canvas component (canvas) for displaying the character the user types and a Label component (help) for displaying some help information.

  3. In order to be notified of key events, canvas registers a KeyListener. As a result, whenever a key is typed with canvas as the active component, a KeyEvent object will be fired to the keyTyped() method.

  4. The last statement of the init() method requests focus for canvas making it the active component in this multi-component container. By default, the last component added to a container has focus and only one component can have focus at a time. It is good practice to request focus so the user doesn't have to click on or TAB to the component they are most likely to use.

  5. The keyTyped() method gets the graphics context for canvas, erases its previous contents, and displays the character that the user just typed.

 

Lab exercise for Ferris students

E-mail your answers to this assignment no later than the due date listed in the class schedule.

 

Review questions

  1. Which of the following statements are true of what will happen when the user enters a keystroke in a component having focus?  (choose two)

  1. a KeyEvent object will be fired

  1. a KeystrokeEvent object will be fired

  2. if the component has registered a KeystrokeListener, its keyEntered() method will be called

  3. if the component has registered a KeyListener, its keyEntered() method will be called

  4. if the component has registered a KeyListener, its keyTyped() method will be called

  1. Assuming a program has registered the correct listener for detecting keystrokes within a component, which of the following methods of the listener could be used to perform special processing when the user presses the Shift key in the component?  (choose two)

  1. keyEntered()

  1. keyTyped()

  2. keyPressed()

  3. keyReleased()

  4. keyActivated()

  1. If a component has a registered listener for key events, which of the following represents the correct order in which the listener's methods would be called when the user types a lower case 'd'?

    1. keyPressed()
      keyTyped()
      keyReleased()

    1. keyPressed()
      keyReleased()
      keyTyped()

    2. keyEntered()
      keyExited()
      keyTyped()

    3. keyActivated()
      keyEntered()
      keyDeactivated()

    4. keyActivated()
      keyDecativated()
      keyEntered()

  1. Assuming it is placed in the appropriate method of a registered listener and that e references the KeyEvent object, which of the following statements could be used to determine the character value of a key when it has been pressed but not yet released?

  1. char x = e.getKeyChar();

  2. char x = e.getKeyCode();

  3. char x = e.getChar();

  4. char x = e.getCode();

  5. the character value of a key is not available until the key has been released ("typed")