Escribir un Oyente de Teclas

Los eventos de Tecla te dicen cuando el usuario ha pulsado el teclado. Específicamente, los eventos de tecla son generados por los componentes que tienen el foco del teclado cuando el usuario pulsa o libera una tecla. (Para más información sobre el foco, puedes ver la página: Escribir un oyente de Foco.)

Se pueden notificar dos tipos básicos de eventos: el tecleo de un cáracter Unicode, y la pulsación o liberación de una tecla del teclado. El primer tipo de evento es llamado un evento de tecla tecleada. El segundo tipo son los eventos tecla pulsada y tecla liberada.

En general, deberías intentar utilizar los eventos de tecla tecleada, a menos que necesites conocer cuando el usuario pulsa una tecla que no corresponde con los caracteres. Por ejemplo, si quieres saber cuando el usuario teclea algún carácter Unicode -- incluso aquellos que son el resultado de la pulsación de varias teclas por parte del usuario -- debes escuchar por los eventos de tecla tecleada. De otra forma, si quieres saber cuando el usuario pulsa el carácter F1, necesitarás escuchar los eventos de tecla pulsada/liberada.

Si necesitas detectar los eventos de tecla disparados por un componente de cliente, aseguráte de que el componente pide el foco del teclado. De otra forma, nunca obtendrá el foco y nuca disparará eventos de teclas.

Métodos de eventos de Tecla

El interface KeyListener y su correspondiente clase adaptador, KeyAdapter, contienen tres métodos:
void keyTyped(KeyEvent)
Llamado por el AWT justo después de que el usuario teclee un carácter Unicode dentro del componente escuchado.
void keyPressed(KeyEvent)
Llamado por el AWT justo después de que el usuario pulse una tecla del teclado.
void keyReleased(KeyEvent)
Llamado por el AWT justo después de que el usuario libero una tecla del teclado.

Ejemplos de Manejo de Eventos de Tecla

El siguiente applet demuestra los eventos de tecla. Consiste en un campo de texto donde puedes teclear, seguido por un área de texto que muestra un mensaje cada vez que el campo de texto dispara un evento de tecla. Un botón en la parte inferior del applet te permite limpiar el campo y el área de texto.


Intenta esto:
  1. Pulsa el campo de texto del applet para obtener el foco del teclado.
  2. Pulsa y libera la tecla A en el teclado.
    El campo de texto dispara tres eventos: un evento de tecla pulsada, un evento de tecla tecleada y un evento de tecla liberada. Observa que el evento de tecla tecleada no tiene información sobre el código de tecla, tampoco tiene información sobre los modificadores. Si sólo te importan los carácteres que el usuario ha pulsado, deberías manejar los eventos de tecla tecleada. Si te importan las teclas que ha pulsado/liberado el usuario deberías manejar los eventos de tecla pulsada/liberada.
  3. Pulsa el botón Clear.
    Porías querer hacer esto después de cada uno de los siguientes pasos
  4. Pulsa y libera la tecla Shift.
    El campo de texto dispara dos eventos: uno de tecla pulsada y otro de tecla liberada. El campo de texto no genera un evento de tecla tecleada porque Shift, pos sí misma, no corresponde a ningún caracter.
  5. Pulsa una A mayúscula pulsando las teclas Shift y A.
    Verás los siguientes eventos, aunque quizas no en este orden: tecla pulsada (Shift), tecla pulsada (A), tecla tecleada ('A'), tecla liberada (A) y tecla liberada (Shift).
  6. Teclea una A mayúsculas pulsando y liberando la tecla Caps Lock, y pulsando la tecla A.
    Deberías ver los siguientes eventos: tecla pulsada (Caps Lock), tecla pulsada (A), tecla tecleada ('A'), tecla liberada (A). Observa que la tecla Caps Lock no genera un evento de tecla liberada hasta que la pulses y la sueltes otra vez. Esto es igual para otras teclas de estado como Scroll Lock o Num Lock.
  7. Pulsa y manten la tecla A.
    ¿Se repite automáticamente? Si es así, verás los mismos eventos que si pulsaras y liberaras la tecla A repetidamente.

Puedes encontar el código completo del Applet en KeyDemo.java. Aquí tienes el código de manejo de eventos del applet:

public class KeyDemo ...  implements KeyListener ... {
    ...//Donde ocurra la inicialización:
	typingArea = new TextField(20);
	typingArea.addKeyListener(this);
    ...
    /** Maneja el evento de tecla tecleada del campo de texto. */
    public void keyTyped(KeyEvent e) {
	displayInfo(e, "KEY TYPED: ");
    }

    /** Maneja el evento de tecla pulsada del campo de texto. */
    public void keyPressed(KeyEvent e) {
	displayInfo(e, "KEY PRESSED: ");
    }

    /** Maneja el evento de tecla liberada del campo de texto. */
    public void keyReleased(KeyEvent e) {
	displayInfo(e, "KEY RELEASED: ");
    }
    ...
    protected void displayInfo(KeyEvent e, String s){
	...
	char c = e.getKeyChar();
	int keyCode = e.getKeyCode();
	int modifiers = e.getModifiers();
	...
	tmpString = KeyEvent.getKeyModifiersText(modifiers);

	...//mustra información sobre el evento...
    }
}

La clase KeyEvent

Cada método de evento de tecla tiene un sólo parámetro: un objetoKeyEvent. La clase KeyEvent define los siguientes métodos:

int getKeyChar()
void setKeyChar(char)
Obtiene o selecciona el carácter de tecla asociado con el evento de tecla tecleada. El carácter es un carácter Unicode.

int getKeyCode()
void setKeyCode(int)
Obtiene o selecciona el códido de tecla asociado con este evento. El código de tecla identifica una tecla particular del teclado que el usuario ha pulsado o liberado. La clase KeyEvent define muchas constantes para códigos de tecla. Por ejemplo, VK_A especifica la tecla etiquetada A, y VK_ESCAPE especifica la tecla ESCAPE.

void setModifiers(int)
Selecciona el estado de las teclas modificadoras para este evento. También puedes ver los métodos getModifiers de inputEvent.
Otros métodos potencialmente útiles de KeyEvent incluyen métodos que generan descripciones de texto localizables de códigos de teclas y teclas modificadoras.

La clase KeyEvent desciende de InputEvent, que a su vez desciende de ComponentEvent. ComponentEvent proporciona el método getComponent. InputEvent proporciona los siguientes métodos:

int getWhen()
Devuelve el momento en el que ocurrió este este evento. Cuanto más alto sea el tiempo, más recientemente ha ocurrido el evento.

boolean isAltDown()
boolean isControlDown()
boolean isMetaDown()
boolean isShiftDown()
Estos métodos ofrecen el estado de las teclas modificadoras cuando el evento fue generado.

int getModifiers()
Devuelve una bandera que indica el estado de todas las banderas cuando el evento fue generado.


Ozito