>>
Lección 10


Eventos.


Cuando el usuario de un programa o applet mueve el ratón, o hace un clic o usa el teclado, genera un Evento. En Java los eventos, como cualquier otra cosa, se representan como instancias u objetos de alguna clase. Para programar una interfaz gráfica es necesario aprender a utilizar los eventos.

Nota: El JDK 1.0 tenía un modelo de eventos que cambió radicalmente en el JDK 1.1. Aquel modelo está "deprecated", es decir se sugiere dejar de usarlo. Por lo tanto no lo presentaremos, sólo estudiaremos el modelo introducido en el JDK 1.1 que tiene trazas de ser permanente.

Cuando el usuario interactúa sobre los diversos componentes del awt, estos componentes generan eventos. La siguiente tabla muestra los eventos que cada tipo de componente puede generar y cuándo los genera.

Tipo de Componente Eventos generados Hechos que los generan
Button ActionEvent El usuario hace un clic sobre el botón.
Checkbox ItemEvent El usuario selecciona o deselecciona el interruptor (Checkbox)
CheckboxMenuItem ItemEvent El usuario selecciona o deselecciona el interruptor (Checkbox)
Choice ItemEvent El usuario selecciona o deselecciona un elemento de la lista
Component






ComponentEvent
El componente se mueve, cambia de tamaño, se esconde o se exhibe
FocusEvent El componente gana o pierde el foco
KeyEvent El usuario pulsa o suelta una tecla
MouseEvent El usuario pulsa o suelta un botón del ratón, el cursor del ratón entra o sale o el usuario mueve o arrastra el ratón
Container ContainerEvent Se agrega o se quita un componente al contenedor
List

 

ActionEvent El usuario hace doble clic en un elemento de la lista
ItemEvent El usuario selecciona o deselecciona un elemento de la lista
MenuItem ActionEvent El usuario selecciona un elemento del menú
Scrollbar AdjustmentEvent El usuario mueve la barra de desplazamiento
TextComponent TextEvent El usuario hace un cambio en el texto
TextField ActionEvent El usuario termina de editar el texto (hace un intro)
Window
WindowEvent
La ventana se abre, se cierra, se minimiza, se reestablece o se cierra.

Todos los eventos mencionados en la tabla están en el paquete java.awt.event.

Nota: En Java hay otros eventos aparte de los mencionados en la tabla. Los eventos en general se representan como objetos de subclases de la clase java.util.EventObject. Hay muchas subclases de java.util.EventObject conocidas hoy en día que el alumno puede consultar en la documentación, pero las que usaremos en el curso son sólo las que aparecen en la tabla anterior y todas ellas son subclases (derivadas directa o indirectamente) de java.awt.AWTEvent y pertenecen al paquete java.awt.event.

Para facilitar la tarea del programador se han creado una serie de interfaces que deben implementarse cuando se quieren procesar algunos de estos eventos. La siguiente tabla presenta estas interfaces con sus métodos.

Interfaz Métodos
ActionListener actionPerformed(ActionEvent)
AdjustmentListener adjustmentValueChanged(AdjustementEvent)
ComponentListener

componentHidden(ComponentEvent)
componentMoved(ComponentEvent)
componentResized(ComponentEvent)
componentShown(ComponentEvent)
ContainerListener
componentAdded(ContainerEvent)
componentRemoved(ContainerEvent)
FocusListener
focusGained(FocusEvent)
focusLost(FocusEvent)
ItemListener itemStateChanged(ItemEvent)
KeyListener

keyPressed(KeyEvent)
keyReleased(KeyEvent)
keyTyped(KeyEvent)
MouseListener


mouseClicked(MouseEvent)
mouseEntered(MouseEvent)
mouseExited(MouseEvent)
mousePressed(MouseEvent)
mouseReleased(MouseEvent)
MouseMotionListener
mouseDragged(MouseEvent)
mouseMoved(MouseEvent)
TextListener textValueChanged(TextEvent)
WindowListener




windowActivated(WindowEvent)
windowClosed(WindowEvent)
windowClosing(WindowEvent)
windowDeactivated(WindowEvent)
windowDeiconified(WindowEvent)
windowIconified(WindowEvent)
windowOpened(WindowEvent)

¿Cómo se utilizan estas interfaces para programar una interfaz gráfica?

Supongamos que deseamos que en un Componente que estamos desarrollando (típicamante un Applet, Marco, Diálogo, Ventana o Panel) responda a los eventos generados por el usuario sobre el mismo componente o sobre algunos otros (típicamente contenidos en él). Para ello convertimos a este componente en "escucha" (Listener) de ciertos eventos generados por él o por los otros componentes. Convertir a un componente en escucha de un tipo de eventos consiste en declarar que implementa la interfaz correspondiente, implementar los métodos de la interfaz y agregarlo a la lista de escuchas del o de los componentes que originan ese tipo de eventos. Por ejemplo, si queremos que un Applet responda a los movimientos del ratón sobre el applet y a los clics sobre un botón b colocado en el applet, será necesario declarar en su línea definitoria que implementa MouseMotionListener y ActionListener, luego habrá que implementar los métodos de ambas interfaces y también habrá que agregar el applet a la lista de escuchas de eventos del ratón del propio applet y a la lista de escuchas de ActionEvent del botón. En otras palabras hay que escribir algo así:

public class miApplet extends Applet implements
        MouseMotionListener, ActionListener {

    public void init() {
        ...
        this.addMouseMotionListener(this);
        b.addActionListener(this);
        ...
    }

    /* -- MouseMotionListener methods --*/
    public void mouseDragged(MouseEvent e) {
        ...
    }

    public void mouseMoved(MouseEvent e) {
        ...
    }

    /* -- ActionListener method --*/
    public void actionPerformed(ActionEvent e) {
        ...
    }

}

Los ejemplos que se presentan a continuación ilustran este procedimiento y muestran cómo extraer información concreta de los eventos para responder a ellos adecuadamente.


ItemEvent y ActionEvent


El siguiente applet ilustra cómo se usan los eventos ItemEvent y ActionEvent. Los dos campos de texto de la parte superior informan cuál es el origen (source) del evento y el tipo de evento de que se trata con su valor descriptivo, respectivamente.

Pruebe a realizar selecciones en todas las componentes, escribir en el campo de texto y dar un intro (o return). Observe que se produce un ActionEvent al hacer clic sobre el botón, al hacer un doble clic en uno de los elementos de la lista, al dar intro en el campo de texto. Observe que un clic sencillo en la lista, una selección en el selector y un clic en el interruptor produce un ItemEvent.

Estudie detenidamente el código de este sencillo applet.

El siguiente applet presenta un conocido juego de bolsillo que en mi tierra y en mi época (México D.F., años 50) se le llamaba "imposible". Su objetivo es comenzar con un marco con los cuadritos en desorden y ordenarlos moviendo cada vez alguno de los cuadros adyacentes al espacio vacío. A veces contábamos el tiempo que tardábamos en ordenarlo y hacíamos competencias. El nombre "imposible" venía de que si uno malintencionadamente sacaba los cuadros de lugar y los ponía en orden pero haciendo una única permutación del 1 con el 2, resultaba imposible ordenarlo sin volver a sacar los cuadros del marco. La forma aparentemente complicada en que se programó la acción de desordenar los cuadros es para simular un desordenamiento que deje los cuadros con una solución posible. Se hizo precisamente desordenando como si se hiciera manualmente.

Juegue un poco con el applet, para mover un cuadro basta hacer clic sobre él, se moverá al cuadro vacío si está adyacente a él. Convénzase de que la solución siempre es posible. Después estudie el código del applet y en especial cómo se utilizan los ActionEvents generados por el ratón.


MouseEvent


Aquí presentamos un applet que sirve para hacer dibujos sencillos y para ello implementa las interfaces MouseEvent y MouseMotionEvent, además de ActionEvent e ItemEvent. 

Estudie detenidamente el código de este applet, prestando particular atención a la implementación de los métodos que responden al ratón, es decir los métodos mousePressed, mouseDragged, etc... Con ello aprenderá la técnica que se suele emplear en los programas que responden a lo que el usuario hace con el ratón, es decir aprenderá a programar interfaces gráficas que usan el  ratón.


Las otras interfaces de eventos que no se han ilustrado funcionan igual que estas, aunque por supuesto cada una de ellas tiene sus peculiaridades y detalles que hay que conocer. Dos de las más importantes son WindowListener y KeyListener. Los ejercicios 5.6 y 5.7 piden al alumno estudiar y aplicar estas interfaces.

Esta lección tiene poco texto, pero el contenido de los ejemplos es muy denso e importante y conviene estudiarlos todos detenidamante.


Índice

Ejercicios de la Lección 10.


José Luis Abreu y Marta Oliveró