Tutorial de Java

Control del Foco

Anterior | Siguiente
En este apartado se entra un poco más a fondo sobre el control del Foco en el nuevo modelo de eventos del JDK, de forma que para demostrar sus posibilidades, en el programa de ejemplo, java1107.java, que se utilizará para ilustrar el control del Foco, se forzará a que un objeto que normalmente no recibe el foco en los programas, como es una Etiqueta (Label), no solamente gane el foco, sino que también responda a eventos del teclado; para mostrar de esta forma el poder, consistencia y flexibilidad de este nuevo modelo de eventos.

En realidad, se utiliza una combinación de eventos de bajo nivel de foco, de ratón y de teclado, para permitir que los cuatro objetos del interfaz: un Frame, un Label, un Button y un TextField, puedan capturar el foco y responder a eventos del teclado. La imagen inicial al arrancar la aplicación del interfaz, es la que muestra la figura siguiente.

Probablemente, el que una Etiqueta responda a un evento de teclado puede no resultar útil a nadie, si se sigue la convencionalidad al uso para programas basados en entornos de ventanas, pero permite hacer una cuantas locuras. El programa es bastante largo, pero muy repetitivo. El hecho de que sea repetitivo habla en favor del nuevo Modelo de Delegación de Eventos, ya que el código necesario para manejar un tipo de evento sobre un tipo de objeto es muy similar al que se necesita para manejar otros tipos de eventos sobre el mismo o diferentes objetos. Una vez que se ha comprendido la sintaxis y entendido el mecanismo, el programador se puede considerar capacitado para escribir programas que probablemente estarán libres de errores. Así de fácil lo ha puesto Sun.

Sobre el objeto Frame se coloca un Botón, un Campo de Texto y una Etiqueta. El borde de la etiqueta no puede verse porque se pinta con el color de fondo.

En el código fuente del ejemplo los comentarios previos a la definición de cada una de las clases indican las acciones que realiza.

A continuación se entra en detalles en cada uno de los diferentes tipos de eventos que se tratan en el ejemplo, teniendo en cuenta que lo especial del ejemplo es la posibilidad que se ha incorporado al objeto Label de que pueda generar eventos de foco.

Eventos del Foco

Se instancia y registra un objeto receptor del foco, FocusListener, para recibir los eventos focusGained() y focusLost() sobre el Frame y el objeto Label. Cuando se producen estos eventos, el receptor del foco hace que el Frame cambie a color azul, o cuando lo tiene el objeto Label, hace que el texto se vuelva rojo.

Una de las ventajas del modelo de Delegación de Eventos es la posibilidad de filtrar eventos, con lo que se consigue que el controlador y manejador de eventos sólo trate en su código aquellos eventos que resulten interesantes. En este ejemplo concreto, los objetos TextField y Button también generan eventos de foco; sin embargo, no hay razón alguna para procesarlos, así que lo que se hace es simplemente no registrar al receptor del foco sobre ellos, para que no sea notificado cuando se producen este tipo de eventos sobre esos objetos. Además, estos dos objetos proporcionan indicación visual de que han ganado el foco sin intervención del programador, es el propio sistema el que lo hace.

Eventos del Ratón

Sobre el objeto Frame y sobre el objeto Label, también se registra e instancia un objeto MouseListener para recibir los eventos mousePressed(). Las cuestiones de filtrado de los eventos del foco se pueden aplicar también a este caso.

Cuando se produce un evento de este tipo, el objeto MouseListener invoca al método requestFocus() sobre el componente visual que ha generado el evento. Esto hace que los objetos Frame o Label reciban el foco en el momento en que se pulse el ratón sobre ellos; aunque en el caso del objeto Label, su comportamiento no sea nada usual.

También en este caso, el botón y el campo de texto reciben automáticamente el foco cuando se pulsa sobre ellos, sin necesidad de que el programador haga nada.

Eventos del Teclado

Un objeto KeyListener es instanciado y registrado para recibir los eventos del teclado keyPressed() sobre los objetos Frame, Label, Button y TextField. Cuando se pulsa una tecla, el objeto que tenga el foco en ese momento generará un evento keyPressed(), e incluso la Etiqueta responde al teclado (en este caso). El objeto KeyListener determina el componente visual que ha generado el evento y presenta un mensaje en pantalla.

Eventos de la Ventana

Finalmente, se instancia y registra un objeto WindowListener para poder terminar la ejecución del programa cuando el usuario cierre el objeto Frame.

Asignación Automática de Nombres

Siempre que se instancia un objeto de la clase Component, el sistema le proporciona automáticamente un nombre. A este nombre se puede acceder utilizando el método getName() de la clase Component, y se puede utilizar el método setName() de la misma clase para asignarle un nombre específico a un objeto. En este ejemplo se utiliza el nombre del Componente para determinar qué objeto ha generado un evento.

En el ejemplo anterior se establecían los nombres de varios Componentes utilizando el método setName(). Sin embargo, el JDK no fuerza a que los nombres sean únicos cuando se fijan por parte desde el código, lo cual puede ocasionar problemas al programador si no se tiene cuidado en asignar nombres únicos a los Componentes. En el ejemplo actual, se asume que los nombres de los componentes visuales que componen el interfaz gráfico son únicos y asignados automáticamente por el sistema, y en vez de asignar nombres y compararlos, lo que se hace es recuperar los nombres que asigna el sistema a cada Componente para distinguir posteriormente entre los Componentes que han generado un evento.

Navegador

Home | Anterior | Siguiente | Indice | Correo