Wie kann man Tastatureingaben abfragen?

Komponenten können bei der Betätigung einer Tastaturtaste sog. KeyEvents erzeugen. Die Komponente muss dazu bei einem KeyListener angemeldet sein. Das KeyEvent kann dann einige Eigenschaften der gedrückten Taste liefern, die durch geeignete Methoden zurückgegeben werden können.

Java unterscheidet drei Varianten von KeyEvents, die auch durch statische int-Variablen in der Klasse KeyEvent repräsentiert werden: Wird eine Tastaturtaste betätigt, so wird als erstes ein KEY_PRESSED-Event erzeugt. Beim Lösen der Taste wird dann ein KEY_RELEASED-Event erzeugt. Gehört die gedrückte Taste zu einem Unicode-Charakter, so wird zusätzlich ein KEY_TYPED-Event generiert. Nur in wenigen Ausnahmefällen ist hierzu auch noch ein KEY_RELEASED-Event notwendig. Das Aktivieren einer Taste, die keinem Unicode-Character zuzuordnen ist, erzeugt zwar KEY_PRESSED- und KEY_RELEASED-Events, jedoch kein KEY_TYPED-Event.

Der Sinn hinter diesem Verhalten besteht darin, dass etliche Eingaben die Aktivierung mehrerer Tasten benötigen. Wird eine Tastenkombination gedrückt, z.B. im Laufe der Eingabe eines Großbuchstabens, so wird für jede Taste je ein KEY_PRESSED- und ein KEY_RELEASED-Event erzeugt. Beide KEY_PRESSED-Events werden dann auf ein KEY_TYPED-Event ├╝bertragen, sodass dies für ein Zeichen nur einmal gesendet wird.
Für die Eingabe des Großbuchstabens 'A' sieht die Ausgabe des u.a. Programms z.B. wie folgt aus:

Taste: ´┐┐, Code: 16
Tastenposition: 2
---
Taste: A, Code: 65
Tastenposition: 1
---
KeyTyped: 
A gedrückt!
---
KeyReleased: 
Taste: A, Code: 65
---
KeyReleased: 
Taste: ´┐┐, Code: 16
---

Für die Eingabe des Kleinbuchstabens 'a' sieht sie hingegen so aus:

Taste: a, Code: 65
Tastenposition: 1
---
KeyTyped: 
a gedrückt!
---
KeyReleased: 
Taste: a, Code: 65
---

Zur genauen Identifizierung einer Taste wird im Hintergrund ein virtueller KeyCode erzeugt, der mit der Methode getKeyCode() abgefragt werden kann. Auf diese Weise können z.B. linke und rechte Shift-Taste unterschieden werden.

Es zeigt sich, dass in beiden o.a. Fällen für die a-Taste der KeyCode 65 gesendet wird, nach Betätigen der Umschalt-Taste jedoch der Großbuchstabe durch getKeyChar() zurückgegeben wird. Die Methode getKeyTyped() liefert dabei in jedem Fall das korrekte erzeugte Zeichen.

Die geeignete Methode zur Ermittlung eines eingegebenen Buchstabens ist somit getKeyChar() in Verbindung mit dem KEY_TYPED-Event.
KEY_PRESSED- und KEY_RELEASED-Ereignisse sind nicht zwingend an die Eingabe eines Unicode-Charakters gebunden, sodass sie die bevorzugten Ereignisse zur Erfassung von Modifizierern (z.B. Shift, Strg, Ctrl, Alt, etc.) darstellen.

KEY_TYPED-Ereignisse sind zudem unabhängig von der Plattform und vom Tastatur-Layout.

import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.JTextField;

public class KeyEventClass extends JFrame implements KeyListener {
    
    public KeyEventClass(){
        this.setLayout(new BorderLayout());
        JTextField field = new JTextField();
        field.addKeyListener(this);
        this.add(field, BorderLayout.CENTER);
        this.pack();
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }

    public void keyTyped(KeyEvent e) {
        System.out.println("KeyTyped: ");
        if(e.getKeyChar() == KeyEvent.CHAR_UNDEFINED){
            System.out.println("Kein Unicode-Character gedr\u00FCckt!");
        }else{
            System.out.println(e.getKeyChar() + " gedr\u00FCckt!");
        }
        System.out.println("---");
    }
    public void keyPressed(KeyEvent e) {
        System.out.println("Taste: " + e.getKeyChar() + ", Code: " + e.getKeyCode());
        System.out.println("Tastenposition: " + e.getKeyLocation());
        System.out.println("---");
    }

    public void keyReleased(KeyEvent e) {
        System.out.println("KeyReleased: ");
        if(e.getKeyCode() == KeyEvent.VK_SPACE){
            System.out.println("Programmabbruch!");
            System.exit(0);
        }    
        System.out.println("Taste: " + e.getKeyChar() + ", Code: " + e.getKeyCode());
        System.out.println("---");
    }
    
    public static void main(String[] args) {
        new KeyEventClass();
    }
}

Das Programmbeispiel zeigt einen kleinen JFrame mit einem JTextField, bei dem ein KeyListener angemeldet wird. Die Methoden des Listeners zum Abfangen der drei Ereignisvarianten zeigen das Verhalten bei der Tastatureingabe von Zeichen auf.
keyPressed() gibt zusätzlich den Ort der gedrückten Taste aus. Dies ist ein Integer-Wert, dessen Abfrage z.B. benutzt werden kann, um zu ermitteln, ob eine Zifferntaste von der Standard-Tastatur oder vom Nummernblock aus betätigt wurde. Hierzu stehen die Konstanten KEY_LOCATION_LEFT, KEY_LOCATION_RIGHT, KEY_LOCATION_NUMPAD und KEY_LOCATION_STANDARD in der Klasse KeyEvent bereit.
In der Methode keyReleased() wird zusätzlich abgefragt, ob die Leertaste betätigt wurde. Ist dies der Fall, so wird das Programm beendet.

Der KeyCode ist für jede Taste als Integer-Wert in einer Konstanten der Klasse KeyEvent festgelegt. Beispiele für deren Nutzung finden sich in den if-Abfragen der Methoden keyReleased() und keyTyped().