DURANTE EL TIEMPO QUE EXISTE UN APPLET, responde a una serie de eventos que le van llegando desde el exterior. Un applet no tiene un «programa main» y no puede realizar acciones, ya que no posee iniciativa (.Como veremos mas adelante, sin embargo un applet puede crear hebras independientes que pueden correr por separado, de una forma muy semejante a un programa). Entonces, el ciclo de vida de un applet esta determinado por los eventos que recibe y la forma en que responde a ellos. El sistema envía eventos al applet por medio de llamadas que realiza a los métodos del mismo.

En esta sección, veremos algunos de estos eventos y los métodos que se utilizan para responder. Todos estos métodos están definidos en la clase Applet aunque en la versión de esa clase, no hacen nada. Para definir la respuesta de un applet a un evento, debe sobregrabar en su subclase  el método correspondiente.


Inicialización y borrado inicial

Una clase applet para su inicialización, normalmente no emplea un constructor. En lugar de eso, justamente después de que se cree el objeto applet, el sistema llama al método init() del objeto, con el siguiente formato:

public void init() { . . . }

Este método realiza las tareas normalmente encargadas al constructor, esto es, inicializar las instancias de las variables del applet.El método init()es también el encargado de colocar en su lugar otros componentes como botones, que se le quieran añadir al applet. Es el complementario del método destroy() que es llamado por el sistema justamente antes de que se destruya el objeto applet. El formato de llamada es

public void destroy() { . . . }

Este método se llama para darle al applet la posibilidad de limpiar todas sus variables antes de dejar de existir. Dado que Java realiza una limpieza y reorganización automática de los restos de memoria, la mayor parte de la limpieza se puede hacer automáticamente. Sin embargo hay algunos casos donde puede ser útil el empleo de destroy(). Por ejemplo es posible que el applet haya creado en la pantalla una ventana independiente, entonces puede utilizar el método destroy() para cerrar esta ventana antes de que finalice el applet.

Un applet también tiene unos métodos start() y stop() que tienen roles semejantes a los de init() y destroy(). La diferencia esta en que mientras que init() y destroy() son llamados únicamente una vez durante el ciclo de vida, start() y stop() pueden ser llamados muchas veces.

El método start() es llamado una vez cuando el objeto es creado por primera vez, y justo a continuación de la llamada al método init(). El sistema puede decidir parar el applet con una llamada al método stop(), y volver a ponerlo en marcha mas tarde por medio de una llamada al método start().

Por ejemplo, normalmente un navegador detiene el applet cuando el usuario abandona la pagina en la que esta displayado el applet y lo vuelve a arrancar en caso de que el usuario vuelva a esa pagina. El método stop() será llamado como mínimo una vez, justamente antes de destruir el applet, y un applet que reciba la orden de parada, deberá quedar detenido ignorando cualquier evento hasta que no reciba una orden de continuar. Los métodos start() y stop() toman la forma

public void start() { . . . }

y

public void stop() { . . . }

No siempre será correcto que la limpieza y la carga inicial se deba realizar en el init() y no durante el start().Las cosas que solo se deban realizar una vez, lo lógico es que se encuentren en el init().

Sin embargo, si el applet emplea una gran cantidad de recursos del ordenador como por ejemplo memoria, puede que sea razonable el asignar esos recurso en el método start() y liberarlos en el método stop(), a fin de que el applet no este bloqueando los recurso mientras que no este funcionando.

Por otra parte, hay veces que es eso es imposible porque el applet necesita retener los recursos durante todo su ciclo de vida. Veremos algunos ejemplos del uso de start() y stop() en el siguiente capítulo.


Eventos de ratón

El usuario puede interactuar con el applet moviendo el ratón, pulsando los botones del ratón y pulsando teclas en el teclado. El applet recibe noticias de una gran cantidad de los eventos relacionados con las acciones del usuario hasta el punto que para el movimiento del ratón, el sistema llama a los siguientes métodos:

      public boolean mouseEnter(Event evt, int x, int y) {
         . . . // respuesta cuando el ratón entra en el rectangulo
         return true;
      }
      public boolean mouseExit(Event evt, int x, int y) {
         . . . //respuesta si el ratón sale del rectangulo
         return true;
      }
      public boolean mouseDown(Event evt, int x, int y) {
         . . . // respuesta si el usuario ha pulsado un boton
         return true;
      }
      public boolean mouseUp(Event evt, int x, int y) {
         . . . // respuesta si el usuario ha soltado el boton
         return true;
      }
      public boolean mouseDrag(Event evt, int x, int y) {
         . . . // respuesta si el raton se ha movido mientras
               //   el usuario mantenia pulsado el boton
         return true;
      }
      public boolean mouseMove(Event evt, int x, int y) {
         . . . // respuesta si el ratón se ha movido mientras
               //   el usuario NO tenia pulsado el boton
         return true;
      }

Como puede ver, si simplemente mueve el ratón a través del applet, el sistema llama a mouseEnter() tan pronto como el ratón entre en el applet, Si el ratón se mueve, el sistema llamara a mouseMove() una y otra vez.

Exactamente tan a menudo como el sistema pueda comprobar la posición del ratón para ver si se ha movido dependiendo de la implementacion de Java que tenga y de lo ocupado que este el sistema haciendo otras cosas, por lo que no puede estar seguro de cuantas veces se llamará a mouseMove(). (En particular, puede estar bastante seguro que no se llamara una vez por cada pixel que recorra).

Si el usuario pulsa un botón del ratón en alguna parte del rectángulo ocupado por el applet, el sistema primero llamara al método mouseDown() cuando el usuario pulse el botón, y llamara al método mouseUp()cuando el usuario lo suelte. Si el usuario mueve el ratón mientras el botón estaba presionado, entonces el sistema llamara al método mouseDrag()una y otra vez mientras se este moviendo el ratón.

En todos estos métodos, el parámetro x y el parámetro y definen la posición horizontal y vertical del ratón en las coordenadas apropiadas del applet. El parámetro x mide la distancia horizontal, en pixeles, desde el borde izquierdo del applet, mientras que el y mide la distancia vertical desde el borde superior. Puede usar esa información para saber donde ha pulsado el usuario y seguir el movimiento del ratón.

El parámetro evt aporta toda la información acerca del evento que ha provocado la llamada al método.(Incluso contiene copias de x y de y, aunque se han dejado separadas para su mayor comodidad.) Por ejemplo, hay una instancia de una variable publica llamada clickcount que puede emplear en el método mouseDown() para comprobar el doble clic. Exactamente comprobando si (evt.clickcount == 2).

También puede comprobar si el usuario tenia pulsada la tecla shift o la tecla control mientras se producía el evento. La clase Event incluye una instancia del método llamado shiftDown() y otro método llamado controlDown() que se pueden emplear para comprobar esas teclas. Estos métodos devuelven valores boleanos por lo que solo debe comprobar if (evt.shifDown()) o if (evt.controlDown()).

La tecla META (en Macintosh, la tecla de comando) trabaja de la misma forma. Puede emplear evt.metaDown() para comprobar si el usuario ha mantenido pulsada la tecla META.

Sin embargo, en ordenadores en los que el ratón  tiene dos o tres botones, el evt.metaDown() puede emplearse para diferenciar entre el botón derecho y el izquierdo del ratón en los métodos mouseDown(), mouseUp y mouseDrag().

El botón derecho genera un evento en el que metaDown() es true tanto si el usuario esta pulsando la tecla META como si no. Estas cosas son las que permiten que que un mismo programa pueda funcionar en distintas plataformas con diferentes tipos de ratones. (El botón central del ratón se simula usando la tecla ALT, pero por algunas razones, no existe un método altDown(). Para comprobar si la tecla ALT esta pulsada, tiene que decir «if ((evt.modifiers & Event.ALT_MASK) != 0)" )

A continuación les presento un applet muy sencillo que presenta las coordenadas del ratón mientras lo vaya moviendo dentro del applet.

import java.awt.*;
import java.applet.*;

public class SimpleTrackMouse extends Applet {

   int mouse_x, mouse_y;  // coordenadas del ratón
   String modifierKeys = "";  // teclas especiales que pueden 
                 // estar pulsadas
   Color displayColor = Color.black;

   public void init() {   // quiero el fondo blanco
      setBackground(Color.white);
   }

   public void paint(Graphics g) {
      int w = size().width;  // Tomo la anchura del applet
      int h = size().height; // tomo la altura del applet
      g.setColor(Color.blue);
      g.drawRect(0,0,w-1,h-1);  // dibujo un cuadro alrededor
      g.setColor(Color.black);
      g.drawString(modifierKeys, 4, 20);
      g.setColor(displayColor);
      g.drawString("(" + mouse_x + "," + mouse_y + ")",
           mouse_x, mouse_y);
   }  // fin de paint()

   void setInfo(Event evt, int x, int y) {
         // establezco la información a presentar
      mouse_x = x;
      mouse_y = y;
      modifierKeys = "";
      if (evt.shiftDown())
         modifierKeys += "Shift ";
      if (evt.controlDown())
         modifierKeys += "Control ";
      if (evt.metaDown())
         modifierKeys += "META ";
      if ((evt.modifiers & Event.ALT_MASK) != 0)
         modifierKeys += "ALT ";
   }

   public boolean mouseMove(Event evt, int x, int y) {
      setInfo(evt, x, y);
      displayColor = Color.black;
      repaint();
      return true;
   }

   public boolean mouseDrag(Event evt, int x, int y) {
      setInfo(evt, x, y);
      displayColor = Color.red;  //rojo si el ratón esta pulsado
      repaint();
      return true;
   }

}  //fin de la clase SimpleMouseTracker

Este applet presenta las coordenadas de la posición del ratón. Indica con un cambio de color cuando se mueve el ratón o se arrastra. Si el usuario pulsa una tecla especial, el hecho se informa en la esquina superior izquierda del applet. Pruebe de mover el ratón sobre el applet

Lo siento pero su navegador
dno soporta Java


Eventos de teclado

Cada vez que el usuario pulsa una tecla del teclado, se generan dos eventos: uno cuando el usuario pulsa la tecla, otro cuando el usuario la libera. Un applet puede ser programado para responder a cada uno de esos eventos sobregrabando los métodos keyDown() y keyUp(). Sobregrabe el método keyDown() si quiere que el applet responda cuando el usuario teclee algo. Probablemente nunca necesitara sobregrabar el método keyUp()(Descubrirá de inmediato que controlar los eventos de teclado en un applet es extremadamente raro, dado que el control del teclado se realiza automáticamente en los componentes predefinidos como las cajas de texto).

Los manejadores de eventos para el teclado son los siguientes:

       public void keyDown(Event evt, int key) {
          . . . // respuesta cuando se pulsa una tecla
          return true;
       }
       public void keyUp(Event evt, int key) {
          . . . // respuesta cuando se libera una tecla
          return true;
       }

En estos métodos, el parámetro key indica que tecla ha pulsado el usuario. Puede que se sorprenderá al descubrir que este parámetro es del tipo int en vez de ser del tipo char. Esto es porque no son caracteres lo único que el usuario puede teclear. El usuario también puede pulsar teclas de acción como las flechas o las teclas de función F1, F2, …

SI el usuario teclea realmente un carácter, entonces el parámetro key contiene realmente el carácter tecleado. Dado que key es de tipo int deberá convertir el tipo para descubrir que carácter se ha pulsado:

char typedChar = (char)key;

Si el usuario pulsa una de las teclas de acción, entonces el valor del parámetro key será el de unas constantes que especifican que tecla se ha pulsado. El valor puede ser uno de los siguientes, predefinidos por constantes:Event.UP, Event.DOWN, Event.LEFT, Event.RIGHT, Event.HOME, Event.END, Event.PGUP, Event.PGDN, o Event.F1Event.F12. Las primeras cuatro, que son las que probablemente usara mas, corresponden a flecha arriba, abajo, a izquierda y a derecha.

Hay aun otro problema mas cuando trabajamos con eventos de teclado: Está la pregunta de quien debe procesar los eventos cuando están ocurriendo. Puede que en la misma pagina de navegador Web haya mas de un applet, por ejemplo. Cuando el usuario teclee, solo uno de los applet puede recibir los eventos de teclado ( y de hecho, los eventos de teclado también pueden ir dirigidos a la misma pagina Web). Decimos entonces, que el sistema enviará los eventos de teclado al objeto que tenga en ese momento el foco. Java proporciona tres métodos para trabajar con el control del foco. Un applet puede llamar al método requestFocus() si quiere conseguir tener el foco.(Esto no significa que lo consiga, el sistema puede rechazar la solicitud). El sistema puede llamar a los métodos del applet gotFocus() y lostFocus() para permitir que el applet conozca cuando esta y cuando pierde el foco, y pueda responder a estas situaciones.


Eventos de acción y otros eventos

Además de los eventos del teclado y del ratón, hay otros eventos que se generan cuando el usuario interactua con los componentes del interface gráfico como botones, menús y cajas de texto. (El usuario realmente provoca estos otros eventos con el teclado o con el ratón, sin embargo, el sistema los traslada a elementos mas comprensibles). Para muchos de estos eventos, el sistema llama al método action() con el siguiente formato

       public boolean action(Event evt, Object arg) {
          . . . // responder a la acción del evento
          return true;  // o responder falso si la acción no se maneja
       }

Este método se llama cuando el usuario pulsa un botón, marca un checkbox, realiza una doble pulsación en un elemento de una lista, pulsa la tecla «Retorno» mientras esta tecleando un texto en un campo de entrada, o selecciona un elemento de un menú o de un menú  pop-up (Botones, checkbox, y todo lo demás, son componentes de la interface gráfica del usuario y que son realmente objetos que pertenecen a las clases Button, Checkbox, List, TextField, Menú, o Choice.)

Hay algunas cosas mas que decir acerca de los eventos de acción y que veremos en el siguiente capítulo cuando hablemos de varios componentes GUI.

A pesar de eso, aun quedan mas eventos, y hay aun otro método que deberá sobregrabar si quiere tratarlos. Es el manejador de eventos mas general llamado handleEvent() y tiene la forma:

        public boolean handleEvent(Event evt) {
           . . . // tratar el evento
           return true;  // o devolver super.handleEvent(Evt), 
                         //       si el evento no se trata
        }

Tengo que ser honesto y decirle que cuando en esta sección  digo que el sistema llama a métodos como mouseDown() y action() estoy mintiendo. De hecho el sistema únicamente llama  a handleEvent() y es él el que va llamando al método apropiado  de entre los  métodos manejadores de eventos especializados según el evento ocurrido. Algunos eventos, como los que se relacionan con algunos componentes GUI, no tienen un manejador de eventos especializado. Si quiere responder a todos los eventos, deberá sobregrabar el método handleEvent() mismo. En el siguiente capitulo, presento algunos eventos de este tipo.

Un comentario sobre “Java para programadores (5.2).El ciclo de vida de un applet”

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.