Wie kann man Tastatureingaben abfragen?

Wahlfreie Tastaturereignisse sind in Java an Komponenten, d.h. Elemente der verschiedenen grafischen API (AWT, Swing, etc.) gebunden. Sie können bei der Betätigung einer Tastaturtaste Ereignisse der Klasse KeyEvent erzeugen. Die Komponente muss dazu jedoch den Focus besitzen und vorher bei einem KeyListener, der die Aktion bei Auftreten registriert, angemeldet worden sein. Diese Aktion, das sog. KeyEvent, kann dann einige Eigenschaften der gedrückten Taste liefern. Sie können durch geeignete Methoden zurückgegeben werden.

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. Gelegentlich 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, die Shift- und die Buchstabentaste, 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 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-Zeichens 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;
import javax.swing.SwingUtilities;

public class KeyEventClass implements KeyListener {
    
    public KeyEventClass(){
        init();
    }
    
    private void init() {
        JTextField field = new JTextField();
        field.addKeyListener(this);
        JFrame frame = new JFrame("Key-Event");
        frame.setLayout(new BorderLayout());
        frame.add(field, BorderLayout.CENTER);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.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) {
        SwingUtilities.invokeLater(() -> 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().

Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.