EVENTOS

Los eventos permiten al programa interactuar con el usuario. Siempre que se utiliza el ratón o el teclado, se genera un evento que describe de una manera exacta lo que ha ocurrido.

SISTEMA ANTIGUO

En Java podemos distinguir dos clases de eventos:

 
EVÉNTOS ESTÁNDAR PARA TECLADO Y RATÓN
           ID del evento                 Método               Descripción
   KEY_PRESS     keyDown(Event,int)   Pulsar una tecla
   KEY_RELEASE    keyUp(Event,int)   Soltar una tecla
   KEY_ACTION    keyDown(Event,int)   Pulsar una tecla de función
   KEY_ACTION_RELEASE    keyUp(Event,int)   Soltar una tecla de función
   MOUSE_DOWN    mouseDown(Event,int,int)   Pulsar el ratón
   MOUSE_UP    mouseUp(Event,int,int)   Movimiento hacia arriba del 
  ratón
   MOUSE_MOVE    mouseMove(Event,int,int)   Movimiento del ratón
   MOUSE_ENTER    mouseEnter(Event,int,int)   Movimiento de entrada del 
  ratón
   MOUSE_EXIT    mouseExit(Event,int,int)   Movimiento de salida del ratón
   MOUSE_DRAG    mouseDrag(Event,int,int)   Arrastrar el ratón
   
EVENTOS GENERADOS POR COMPONENTES
           Componente             ID del evento              Descripción
   Button   ACTION_EVENT El usuario ha hecho click.
  Check Box   ACTION_EVENT El usuario ha pulsado una casilla 
de activación.
  Choice   ACTION_EVENT El usuario ha seleccionado un 
elemento.
  Component   GOT_FOCUS Obtiene el foco de entrada.
  Component   KEY_ACTION El usuario ha pulsado una tecla 
de función.
  Component   KEY_ACTION_RELEASE El usuario ha soltado una tecla 
de función.
  Component   KEY_PRESS El usuario ha pulsado una tecla.
  Component   KEY_RELEASE El usuario ha soltado una tecla.
  Component   LOST_FOCUS Se ha perdido el foco de entrada.
  Component   MOUSE_ENTER El ratón ha entrado en un 
componente.
  Component   MOUSE_EXIT El ratón ha salido de un 
componente.
  Component   MOUSE_DOWN Se ha pulsado un botón del 
ratón.
  Component   MOUSE_UP Se ha soltado un botón del 
ratón.
  Component   MOUSE_MOVE El usuario ha movido el ratón.
  Component   MOUSE_DRAG Se arrastró el ratón.
  List   ACTION_EVENT El usuario ha hecho doble click 
sobre una lista de elementos.
  List   LIST_SELECT El usuario ha seleccionado un 
elemento de la lista.
  List   LIST_DESELECT El usuario ha anulado la sele- 
cción de un elemento de la lista.
  Menu Item   ACTION_EVENT Se ha seleccionado un elemento 
del menú.
  ScrollBar   SCROLL_LINE_UP El usuario ha solicitado un des- 
plazamiento ascendente de una 
línea.
  ScrollBar   SCROLL_LINE_DOWN El usuario ha solicitado un des- 
plazamiento descendente de una 
línea.
  ScrollBar   SCROLL_PAGE_UP El usuario ha solicitado un des- 
plazamiento ascendente de una 
página.
  ScrollBar   SCROLL_PAGE_DOWN El usuario ha solicitado un des- 
plazamiento descendente de una 
página.
  ScrollBar   SCROLL_ABSOLUTE El usuario ha solicitado un cam- 
bio absoluto.
  TestField   ACTION_EVENT Se ha pulsado la tecla "Return".
  Window   WINDOW_DESTROY La ventana se ha destruido.
  Window   WINDOW_ICONIFY La ventana se ha transformado 
en icono.
  Window   WINDOW_DEICONIFY El icono se ha transformado en 
ventana.
  Window   WINDOW_MOVED Se ha movido la ventana.
 
Ambos tipos de eventos son objetos instanciados a partir de la clase java.awt.Event. A la hora de manejar los eventos, al programador se le presentan 2 opciones:

1. Construir un manejador de eventos.

Cuando se genera un evento UI, el mecanismo de manejo de eventos de AWT lo pasa al nivel anterior en la jerarquía de componentes. La forma de manejar estos eventos es implementar un método handleEvent().
Ejemplo:

public boolean handleEvent (Event e) {
  switch (e,id) {
    case Event.ACTION_EVENT: if (e.target instanceof Button) {
                               .....  // es un evento de botón
                             }
                             return true;
                             if (e.target instanceof MenuItem) {
                               .....  // es un evento de menú
                             }
                             return true;
    case Event.MOUSE_MOVE:  // evento de movimiento de ratón
                    ......
      return true;

      .....
      .....
    default: super.handleEvent(e);  // el evento no se maneja aquí, de
            break;                  // manera que la responsabilidad se le
   }                                // pasa a la superclase
}
2. Pasar los eventos a un método action().

El método action() tendrá el siguiente aspecto:

public boolean action (Event e,Object obj) {
    .....
    .....
}
es decir, los eventos UI se pasan al método action(), junto con un parámetro Object adicional que contiene información sobre el evento. Dicha información depende del elemento UI que genere el evento.
Pero no todos los componentes UI generan eventos action, por lo que si queremos atrapar eventos que no esten en la tabla anterior deberemos construir un método handleEvent(), de propósito general.
No obstante, para aquellos componentes que sí invocan un método action(), es conveniente redefinir dicho método, de modo que consultando el parámetro Object podremos averiguar información concreto acerca del evento.

Ejemplo:

public boolean action (Event e,Object obj) {
  if (e.target instanceof Button) {   // es un evento button
      .....
  }
  if (e.target instanceof MenuItem) {  // es un evento de menú
      .....
  }
  return true;
}
Las variables de instancia que poseen los objetos Event contenidos en java.awt.Event son:

- ID: identificador del evento. (Ver tabla EVENTOS ESTÁNDAR PARA TECLADO Y RATÓN).
- target: es el objetivo de un evento, es decir, de donde proviene el evento. (Por ejemplo, de un área de texto, de una barra de desplazamiento ...etc.).
- when: momento en el que se generó el evento.
- x,y: coordenadas en las que se generó el evento.
- key: tecla pulsada. Es especialmente útil para eventos de teclado.
- arg: argumento de tipo Object, que es el argumento asociado a un evento (como, por ejemplo, el nombre del botón seleccionado).
- modifiers: estado de las teclas modificadoras cuando se genera un evento.

SISTEMA VERSION 1.1

A partir de la versión 1.1 de Java, se introdujo un nuevo sistema de gestión de eventos. El motivo por el cual apareció  este nuevo sistema es que cuando teníamos una interfaz de ususario muy amplia y deseábamos controlar los eventos, debíamos comparar los nombres de los distintos componentes para poder distinguirlos entre sí. Estas comparaciones se realizaban mediante los nombres de los componentes, que no son otra cosa que Strings , lo que disminuía considerablemente el rendimiento de la aplicación.
En la versión 1.1 se establece una clase base llamada EventObject y a partir de ella se establecen una serie de clases descendientes: Existen dos niveles de eventos: eventos de bajo nivel y eventos de alto nivel.

EVENTOS DE BAJO NIVEL

Estos eventos se producen cuando el usuario pulse alguna tecla o efectúe algún movimiento con el ratón, o también cuando se modifique o visualice algún componente en la pantalla.
Las clases asociadas son:

A continuación vamos a ver los métodos para KeyEvent y MouseEvent:
 
 
Métodos de KeyEvent
getKeyChar ( ) Devuelve el carácter asociado con la tecla que produjo el evento
getKeyCode( ) Devuelve el código de la tecla que produjo el evento
getKeyModifiers( ) Devuelve una cadena que indica el modificador de la tecla, por ejemplo "Shift"
getKeyText(int) Devuelve una cadena que indica el tipo de tecla pulsada, por ejemplo F1, indicando que se trata de una tecla de función
isActionKey( ) Devuelve se la tecla es una tecla de "acción"
 
 
 
Métodos de MouseEvent
getClickCount( ) Devuelve el número de clics de ratón asociados con el evento
getX( ) Devuelve la posición x cuando se genera el vento
getY( ) Devuelve la posición y cuando se genera el evento
isPopupTrigger() Devuelve si es o no un evento de tratón del tipo pop-up menú para esta plataforma
translatePoint(int posx,int posy) Traslada la posición de las coordenadas del vento a posx y posy
 

EVENTOS DE ALTO NIVEL

Son aquellos que tienen que ver  con la semántica de los componentes. Así por ejemplo, se generarán cuando se pulse un botón o cuando se se cambie el texto de un campo de texto. Las clases asociadas a este nivel son:

LAS CLASES DE ESCUCHA

Para poder capturar tanto los eventos de bajo nivel, como los de alto, Java proporciona las clases de escucha (Listeners). Estas clases son interfaces. Para cada tipo de evento existe una clase de escucha. Cada clase de escucha contiene la declaración de un conjunto de métodos, a los que se llamarán dependiendo del evento producido.
A continuación vamos a mostrar las clases de escucha  con sus correspondientes métodos abstractos:
 
 
 
Clases Métodos Descripción
ActionListener actionPerformed(ActionEvent e) Ejecuta algún comando
AdjustmentListener adjustamentValueChanged(AdjustamentEvent e) Ajusta algún valor
ComponentListener componentHidden(ComponentEvent e) El componente se oculta
componentMoved(ComponentEvent e) El componente se mueve
componentResized(ComponentEvent e) El componente se redimensiona
componentShown(ComponentEvent e) El componente se visualiza
ContainerListener componentAdded(ContainerEvent e) Se añade un componente el contenedor
componentRemoved(ContainerEvent e) Se elimina un componente del contenedor
FocusListener focusGained(FocusEvent e) El componente obtiene el foco
focusLost(FocusEvent e) El componente pierde el foco
ItemListener ItemStateChanged(ItemEvent e) Se modifica el estado de algún elemento del componente, como puede ser la elección de alguna casilla de verificación
KeyListener keyPressed(KeyEvent e) Se ha pulsado una tecla
keyReleased(KeyEvent e) Se ha soltado la tecla
keyTyped(KeyEvent e) Se ha tecleado un carácter
MouseListener mouseClicked(MouseEvent e) Se ha pulsado el botón del ratón
mouseEntered(MouseEvent e) El puntero del ratón ha entrado en el componente
mouseExited(MouseEvent e) El puntero del ratón ha salido del componente
mousePressed(MouseEvent e) Se ha presionado un botón del ratón
mouseReleased(MouseEvent e) Se ha soltado un botón del ratón
MouseMotionListener mouseDragged(MouseEvent e) Se está desplazando el ratón con el botón pulsado
mouseMoved(MouseEvent e) El puntero del ratón  ha cambiado de posición
TextListener textValueChanged(textEvent e) El contenido del texto del componente ha cambiado
WindowListener windowActivated(WindowEvent e) La ventana ha sido activada
windowClosed(WindowEvent e) Se ha cerrado la ventana
windowClosing(WindowEvent e) Se ha solicitado cerrar la ventana
windowDeactivated(WindowEvent e) La ventana ha sido desactivada
windowDeiconified(WindowEvent e) Cuando se restaura la ventana a su tamaño original o se maximiza
windowIconofied(WindowEvent e) Se ha minimizado la ventana
windowOpened(WindowEvent e) se ha abierto la ventana

Una vez creados los componentes, debemos indicar  qué clase de escucha vamos a implementar a cada componente.Para ello, debemos utilizar la siguiente línea de código:
nombreDelComponente.addClaseDeEscucha( );
donde ClaseDeEscucha es el nombre de la clase de escucha según los nombres reseñados en la tabla anterior.
Además deberemos indicar que la clase en la que se encuentran los componentes implementa la interfaz correspondiente:
class LaQueSea implements ClaseDeEscucha {
             ...
}

Pero uno de los problemas que tienen las interfaces es que debemos definir todos sus métodos abstractos en las clases que las implementan. Así, si una de nuestras clases implementa la interfaz WindowListener, deberá implementar todos los métodos asociados, aún cuando sólo utilicemos uno de ellos. (El resto de los métodos tendrán una implementación vacía). Por esta razón surgen las clases adaptadoras. Estas clases adaptadoras se encargan de implementar todos los métodos del la clase de escucha. Así sólo necesitaremos redefinir aquellos métodos que nos van a ser útiles para gestionar eventos , sin preocuparnos del resto.
Para ello dedemos indicar que nuestra clase es una subclase del adaptador:
class LaQueSea extends Adaptador{
      ...
}

Sólo las clases que poseen más de un método tienen  adaptador , y son los siguientes:

Es conveniente utilizar adaptadores de cara a la vida futura de la aplicación, ya que si algún día Sun (empresa creadora de Java) decidiese añadir un nuevo evento a una clase de escucha y nosotros tenemos implementado en la aplicación la interfaz de escucha, deberemos implementar el nuevo método, ya que si no el compilador nos dará un error.Pero si nuestra aplicación utiliza adptadores, nosotros podremos olvidarnos del nuevo evento ya que Sun será la encargada de proporcionar la nueva sobrecarga vacía para el método asociado al nuevo evento.