sábado, 30 de junio de 2012

Los Menus de Java

Los Menus de Java
Los Menus de Java no descienden de Component, sino de MenuComponent, pero tienen un comportamiento similar, pues aceptan Events. La Figura  muestra la jerarquía de clases de los Menus de Java 1.1.
Para crear un Menú se debe crear primero una MenuBar; después se crean los Menus y los MenuItem. Los MenuItems se añaden al Menu correspondiente; los Menus se añaden a la MenuBar y la MenuBar se añade a un Frame.
Una MenuBar se añade a un Frame con el método setMenuBar(), de la clase Frame. También puede añadirse un Menu a otro Menu para crear un sub-menú, del modo que es habitual en Windows. La clase Menu es sub-clase de MenuItem. Esto es así precisamente para permitir que un Menu sea añadido a otro Menu.
Jerarquía de clases para los menús.

Clase MenuShortcut

La clase java.awt.MenuShortcut (derivada de Object) representa las teclas aceleradoras que pueden utilizarse para activar los menús desde teclado, sin ayuda del ratón. Se establece un Shortcut creando un objeto de esta clase con el constructor MenuShortcut(int vk_key), y pasándoselo al constructor adecuado de MenuItem. Para más información, consúltese la adocumentación on-line de Java. La Tabla muestra algunos métodos de esta clase. Los MenuShortcut de Java están restringidos al uso la tecla control (CTRL). Al definir el MenuShortcut no hace falta incluir dicha tecla.
Métodos de la clase MenuShortcut.

Clase MenuBar

La Tabla  muestra algunos métodos de la clase MenuBar. A una MenuBar sólo se pueden añadir objetos Menu.
Métodos de la clase MenuBar.

Clase Menu

El objeto Menu define las opciones que aparecen al seleccionar uno de los menús de la barra de menús. En un Menu se pueden introducir objetos MenuItem, otros objetos Menu (para crear submenús), objetos CheckboxMenuItem, y separadores. La Tabla muestra algunos métodos de la clase Menu. Obsérvese que como Menu desciende de MenuItem, el método add(MenuItem) permite añadir objetos Menu a otro Menu.
Métodos de la clase Menu.

Clase MenuItem

Los objetos de la clase MenuItem representan las distintas opciones de un menú. Al seleccionar, en la ejecución del programa, un objeto MenuItem se generan eventos del tipo ActionEvents. Para cada item de un Menu se puede definir un ActionListener, que define el método actionPerformed(). La Tabla muestra algunos métodos de la clase MenuItem.
Métodos de la clase MenuItem.
El método getActionCommand(), asociado al getSource() del evento correspondiente, no permite identificar correctamente al item cuando éste se ha activado mediante el MenuShortcut (en ese caso devuelve null).

Clase CheckboxMenuItem

Son items de un Menu que pueden estar activados o no activados. La clase CheckboxMenuItem no genera un ActionEvent, sino un ItemEvent, de modo similar a la clase Checkbox. En este caso hará registrar un ItemListener. La Tabla muestra algunos métodos de esta clase.
Métodos de la clase CheckboxMenuItem.

Menús pop-up

Los menús pop-up son menús que aparecen en cualquier parte de la pantalla al clicar con el botón derecho del ratón (pop-up trigger) sobre un componente determinado (parent Component). El menú pop-up se muestra en unas coordenadas relativas al parent Component, que debe estar visible.
Métodos de la clase PopupMenu.
Además, se pueden utilizar los métodos de la clase Menu, de la que deriva PopupMenu. Para hacer que aparezca el PopupMenu habrá que registrar el MouseListener y definir el método mouseClicked().

Gráficos, Texto e Imágenes en Java


En esta parte final del AWT se van a describir, también muy sucintamente, algunas clases y métodos para realizar dibujos y añadir texto e imágenes a la interface gráfica de usuario.

Capacidades gráficas del AWT: Métodos paint(), repaint() y update()

La clase Component tiene tres métodos muy importantes relacionados con gráficos: paint(), repaint() y update(). Cuando el usuario llama al método repaint() de un componente, el AWT llama al método update() de ese componente, que por defecto llama al método paint().

Método paint(Graphics g)

El método paint() está definido en la clase Component, pero ese método no hace nada y hay que redefinirlo en una de sus clases derivadas. El programador no tiene que preocuparse de llamar a este método: el sistema operativo lo llama al dibujar por primera vez una ventana, y luego lo vuelve a llamar cada vez que entiende que la ventana o una parte de la ventana debe ser re-dibujada (por ejemplo, por haber estado tapada por otra ventana y quedar de nuevo a la vista).

Método update(Graphics g)

El método update() hace dos cosas: primero re-dibuja la ventana con el color de fondo y luego llama al método paint(). Este método también es llamado por el AWT, y también puede ser llamado por el programador, quizás porque ha realizado algún cambio en la ventana y necesita que se dibuje de nuevo.
La propia estructura de este método -el comenzar pintando de nuevo con el color de fondo hace que se produzca parpadeo (flicker) en las animaciones. Una de las formas de evitar este efecto es redefinir este método de una forma diferente, cambiando de una imagen a otra sólo lo que haya que cambiar, en vez de re-dibujar todo otra vez desde el principio. Este método no siempre proporciona los resultados buscados y hay que recurrrir al método del doble buffer.

Método repaint()

Este es el método que con más frecuencia es llamado por el programador. El método repaint() llama “lo antes posible” al método update() del componente. Se puede también especificar un número de milisegundos para que el método update() se llame transcurrido ese tiempo. El método repaint() tiene las cuatro formas siguientes:
repaint( )
repaint(long time)
repaint(int x, int y, int w, int h)
repaint(long time, int x, int y, int w, int h)
Las formas tercera y cuarta permiten definir una zona rectangular de la ventana a la que aplicar el método.

Clase Graphics

El único argumento de los métodos update() y paint() es un objeto de esta clase. La clase Graphics dispone de métodos para soportar dos tipos de gráficos:
  1. Dibujo de primitivas gráficas (texto, líneas, círculos, rectángulos, polígonos, …).
  2.  Presentación de imágenes en formatos *.gif y *.jpeg.
Además, la clase Graphics mantiene un contexto gráfico: un área de dibujo actual, un color de dibujo del background y otro del foreground, un font con todas sus propiedades, etc. La Figura muestra el sistema de coordenadas utilizado en Java. Como es habitual en Informática, los ejes están situados en la esquina superior izquierda, con la orientación indicada en la Figura (eje de ordenadas descendente). Las coordenadas se miden siempre en pixels.
Coordenadas de los gráficos de Java.

Primitivas gráficas

Java dispone de métodos para realizar dibujos sencillos, llamados a veces “primitivas” gráficas. Como se ha dicho, las coordenadas se miden en pixels, empezando a contar desde cero. La clase Graphics dispone de los métodos para primitivas gráficas reseñados en la Tabla. Excepto los polígonos y las líneas, todas las formas geométricas se determinan por el rectángulo que las comprende, cuyas dimensiones son w y h. Los polígonos admiten un argumento de la clase java.awt.Polygon.
Métodos de la clase Graphics para dibujo de primitivas gráficas.
Los métodos draw3DRect()fill3DRect()drawOval()fillOval()drawArc() y fillArc() dibujan objetos cuyo tamaño total es (w+1, h+1) pixels.

Clases Graphics y Font

La clase Graphics permite “dibujar” texto, como alternativa al texto mostrado en los componentes Label, TextField y TextArea. Los métodos de esta clase para dibujar texto son los siguientes:
drawBytes(byte data[ ], int offset, int length, int x, int y);
drawChars(char data[ ], int offset, int length, int x, int y);
drawString(String str, int x, int y);
En estos métodos, los argumentos x e y representan las coordenadas de la línea base. El argumento offset indica el elemento del array que se empieza a imprimir.
Cada tipo de letra está representado por un objeto de la clase Font. Las clases Component y Graphics disponen de métodos setFont() y getFont(). El constructor de Font tiene la forma:
Font(String name, int style, int size)
donde el style se puede definir con las constantes Font.PLAINFont.BOLD y Font.ITALIC. Estas constantes se pueden combinar en la forma: Font.BOLD | Font.ITALIC.
La clase Font tiene tres variables protected, llamadas name, style y size. Además tiene tres constantes enteras: PLAINBOLD e ITALIC. Esta clase dispone de los métodos String getName()int getStyle()int getSize()boolean isPlain()boolean isBold() y boolean isItalic(), cuyo significado es inmediato.
Para mayor portabilidad se recomienda utilizar nombres lógicos de fonts, tales como Serif (Times New Roman), SansSerif (Arial) y Monospaced (Courier).
Líneas importantes en un tipo de letra.

Clase FontMetrics

La clase FontMetrics permite obtener información sobre una font y sobre el espacio que ocupa un char o un String utilizando esa font. Esto es muy útil cuando se pretende rotular algo de modo que quede siempre centrado y bien dimensionado.
La clase FontMetrics es una clase abstract. Esto quiere decir que no se pueden crear directamente objetos de esta clase ni llamar a su constuctor. La forma habitual de soslayar esta dificultad es creando una subclase. En la práctica Java resuelve esta dificultad para el usuario, ya que la clase FontMetrics tiene como variable miembro un objeto de la clase Font. Por ello, un objeto de la clase FontMetrics contiene información sobre la font que se le ha pasado como argumento al constructor. De todas formas, el camino más habitual para obtener esa información es a partir de un objeto de la clase Graphics que ya tiene un font definido. A partir de un objeto g de la clase Graphics se puede obtener una referencia FontMetrics en la forma:
FontMetrics miFontMet = g.getFontMetrics();
donde está claro que se está utilizando una referencia de la clase abstract FontMetrics para refererirse a un objeto de una clase derivada creada dentro del API de Java. Con una referencia de tipo FontMetrics se pueden utilizar todos los métodos propios de dicha clase.
Métodos de la clase FontMetrics.

Clase Color

La clase java.awt.Color encapsula colores utilizando el formato RGB (Red, Green, Blue). Las componentes de cada color primario en el color resultante se expresan con números enteros entre 0 y 255, siendo 0 la intensidad mínima de ese color, y 255 la máxima.
En la clase Color existen constantes para colores predeterminados de uso frecuente: black, white, green, blue, red, yellow, magenta, cyan, orange, pink, gray, darkGray, lightGray. La Tabla muestra algunos métodos de la clase Color.
Métodos de la clase Color.

Imágenes

Java permite incorporar imágenes de tipo GIF y JPEG definidas en ficheros. Se dispone para ello de la clase java.awt.Image. Para cargar una imagen hay que indicar la localización del fichero (URL) y cargarlo mediante los métodos Image getImage(String) o Image getImage(URL, String). Estos métodos existen en las clases java.awt.Toolkit y java.applet.Applet. El argumento de tipo String representa una variable conteniendo el nombre del fichero.
Cuando estas imágenes se cargan en applets, para obtener el URL pueden ser útiles las funciones getDocumentBase() y getCodeBase(), que devuelven el URL del fichero HTML que llama al applet, y el directorio que contiene el applet (en forma de String).
Para cargar una imagen hay que comenzar creando un objeto Image, y llamar al método getImage(), pasándole como argumento el URL. Por ejemplo:
Image miImagen = getImage(getCodeBase(), "imagen.gif")
Una vez cargada la imagen, hay que representarla, para lo cual se redefine el método paint() para llamar al método drawImage() de la clase Graphics. Dicho método admite varias formas, aunque casi siempre hay que incluir el nombre del objeto imagen creado, las dimensiones de dicha imagen y un objeto ImageObserver.
ImageObserver es una interface que declara métodos para observar el estado de la carga y visualización de la imagen. Si se está programando un applet, basta con poner como ImageObserver la referencia this, ya que en la mayoría de los casos, la implementación de esta interface en la clase Applet proporciona el comportamiento deseado. Para más información sobre dicho método dirigirse a la referencia de la API.
La clase Image define ciertas constantes para controlar los algoritmos de cambio de escala:
SCALE_DEFAULT, SCALE_FAST, SCALE_SMOOTH,
SCALE_REPLICATE, SCALE_AVERAGE.
Métodos de la clase Image.


Animaciones en Java


Las animaciones tienen un gran interés desde diversos puntos de vista. Una imagen vale más quemil palabras y una imagen en movimiento es todavía mucho más útil. Para presentar o describir ciertos conceptos el movimiento animado es fundamental. Además, las animaciones o mejor dicho, la forma de hacer animaciones en Java ilustran mucho la forma en que dicho lenguaje realiza los gráficos. En estos apartados se va a seguir el esquema del Tutorial de Sun sobre el AWT.
Se pueden hacer animaciones de una forma muy sencilla: se define el método paint() de forma que cada vez que sea llamado dibuje algo diferente de lo que ha dibujado la vez anterior. De todas formas, recuérdese que el programador no llama directamente a este método. El programador llama al método repaint(), quizás dentro de un bucle while que incluya una llamada al método sleep() de la clase Thread , para esperar un cierto número de milisegundos entre dibujo y dibujo (entre frame y frame, utilizando la terminología de las animaciones). Recuérdese que repaint() llama a update() lo antes posible, y que update() borra todo redibujando con el color de fondo y llama a paint().
La forma de proceder descrita da buenos resultados para animaciones muy sencillas, pero produce parpadeo o flicker cuando los gráficos son un poco más complicados. La razón está en el propio proceso descrito anteriormente, combinado con la velocidad de refresco del monitor. La velocidad de refresco vertical de un monitor suele estar entre 60 y 75 herzios. Eso quiere decir que la imagen se actualiza unas 60 ó 75 veces por segundo. Cuando el refresco se realiza después de haber borrado la imagen anterior pintando con el color de fondo y antes de que se termine de dibujar de nuevo toda la imagen, se obtiene una imagen incompleta, que sólo aparecerá terminada en uno de los siguientes pasos de refresco del monitor. Ésta es la causa del flicker. A continuación se verán dos formas de reducirlo o eliminarlo.

Eliminación del parpadeo o flicker redefiniendo el método update()

El problema del flicker se localiza en la llamada al método update(), que borra todo pintando con el color de fondo y después llama a paint(). Una forma de resolver esta dificultad es re-definir el método update(), de forma que se adapte mejor al problema que se trata de resolver.
Una posibilidad es no re-pintar todo con el color de fondo, no llamar a paint() e introducir en update() el código encargado de realizar los dibujos, cambiando sólo aquello que haya que cambiar.
A pesar de esto, es necesario re-definir paint() pues es el método que se llama de forma automática cuando la ventana de Java es tapada por otra que luego se retira. Una posible solución es hacer que paint() llame a update(), terminando por establecer un orden de llamadas opuesto al de defecto. Hay que tener en cuenta que, al no borrar todo pintando con el color de fondo, el programador tiene que preocuparse de borrar de forma selectiva entre frame y frame lo que sea necesario. Los métodos setClip() y clipRect() de la clase Graphics permiten hacer que las operaciones gráficas no surtan efecto fuera de un área rectangular previamente determinada. Al ser dependiente del tipo de gráficos concretos de que se trate, este método no siempre proporciona soluciones adecuadas.

Técnica del doble buffer

La técnica del doble buffer proporciona la mejor solución para el problema de las animaciones, aunque requiere una programación algo más complicada. La idea básica del doble buffer es realizar los dibujos en una imagen invisible, distinta de la que se está viendo en la pantalla, y hacerla visible cuando se ha terminado de dibujar, de forma que aparezca instantáneamente.
Para crear el segundo buffer o imagen invisible hay que crear un objeto de la clase Image del mismo tamaño que la imagen que se está viendo y crear un contexto gráfico u objeto de la clase Graphics que permita dibujar sobre la imagen invisible. Esto se hace con las sentencias,
Image imgInv;
Graphics graphInv;
Dimension dimInv;
Dimension d = size();    // se obtiene la dimensión del panel
en la clase que controle el dibujo (por ejemplo en una clase que derive de Panel). En el método update() se modifica el código de modo que primero se dibuje en la imagen invisible y luego ésta se haga visible:
Los gráficos y las animaciones son particularmente útiles en las applets. El Tutorial de Sun tiene un ejemplo (un applet) completamente explicado y desarrollado sobre las animaciones y los distintos métodos de eliminar el flicker o parpadeo.

Applets, Que es un Applets, Características y Métodos

¿Que es un Applets?
Un applet es una mini-aplicación, escrita en Java, que se ejecuta en un browser (Netscape Navigator, Microsoft Internet Explorer, …) al cargar una página HTML que incluye información sobre el applet a ejecutar por medio de las tags <APPLET>... </APPLET>.
A continuación se detallan algunas características de las applets:
  • Los ficheros de Java compilados (*.class) se descargan a través de la red desde un servidor de Web o servidor HTTP hasta el browser en cuya Java Virtual Machine se ejecutan. Pueden incluir también ficheros de imágenes y sonido.
  • Las applets no tienen ventana propia: se ejecutan en la ventana del browser (en un “panel”).
  • Por la propia naturaleza “abierta” de Internet, las applets tienen importantes restricciones de seguridad, que se comprueban al llegar al browser: sólo pueden leer y escribir ficheros en el servidor del que han venido, sólo pueden acceder a una limitada información sobre el ordenador en el que se están ejecutando, etc. Con ciertas condiciones, las applets “de confianza” (trusted applets) pueden pasar por encima de estas restricciones.
Aunque su entorno de ejecución es un browser, las applets se pueden probar sin necesidad de
browser con la aplicación appletviewer del JDK de Sun.

Algunas características de las applets

Las características de las applets se pueden considerar desde el punto de vista del programador y desde el del usuario. En este manual lo más importante es el punto de vista del programador:
  • Las applets no tienen un método main() con el que comience la ejecución. El papel central de su ejecución lo asumen otros métodos que se verán posteriormente.
  • Todas las applets derivan de la clase java.applet.Applet. LaFigura muestra la jerarquía de clases de la que deriva la clase Applet. Las applets deben redefinir ciertos métodos heredados de Applet que controlan su ejecución: init(), start(), stop(), destroy().
  • Se heredan otros muchos métodos de las super-clases de Applet que tienen que ver con la generación de interfaces gráficas de usuario (AWT). Así, los métodos gráficos se heredan de Component, mientras que la capacidad de añadir componentes de interface de usuario se hereda de Container y de Panel.
  • Las applets también suelen redefinir ciertos métodos gráficos: los más importantes son paint() y update(), heredados de Component y de Container; y repaint() heredado de Component.
  • Las applets disponen de métodos relacionados con la obtención de información, como por ejemplo: getAppletInfo(), getAppletContext(), getParameterInfo(), getParameter(), getCodeBase(),  etDocumentBase(), e isActive().
El método showStatus() se utiliza para mostrar información en la barra de estado del browser.
Existen otros métodos relacionados con imágenes y sonido: getImage(), getAudioClip(), play(), etc.
Jerarquía de clases de Applet.

 Métodos que controlan la ejecución de un applet

Los métodos que se estudian en este Apartado controlan la ejecución de las applets. De ordinario el programador tiene que redefinir uno o más de estos métodos, pero no tiene que preocuparse de llamarlos: el browser se encarga de hacerlo.
  • Método init()
Se llama automáticamente al método init() en cuanto el browser o visualizador carga el applet. Este método se ocupa de todas las tareas de inicialización, realizando las funciones del constructor (al que el browser no llama).
En Netscape Navigator se puede reinicializar un applet con Shift+Reload.
  • Método start()
El método start() se llama automáticamente en cuanto el applet se hace visible, después de haber sido inicializada. Se llama también cada vez que el applet se hace de nuevo visible después de haber estado oculta (por dejar de estar activa esa página del browser, al cambiar el tamaño de la ventana del browser, al hacer reload, etc.).
Es habitual crear threads en este método para aquellas tareas que, por el tiempo que requieren, dejarían sin recursos al applet o incluso al browser. Las animaciones y ciertas tareas a través de Internet son ejemplos de este tipo de tareas.
  • Método stop()
El método stop() se llama de forma automática al ocultar el applet (por haber haber dejado de estar activa la página del browser, por hacer reload o resize, etc.).
Con objeto de no consumir recursos inútilmente, en este método se suelen parar las threads que estén corriendo en el applet, por ejemplo para mostrar animaciones.
  • Método destroy()
Se llama a este método cuando el applet va a ser descargada para liberar los recursos que tenga reservados (excepto la memoria). De ordinario no es necesario redefinir este método, pues el que se hereda cumple bien con esta misión.

Métodos para dibujar el applet

Las applets son aplicaciones gráficas que aparecen en una zona de la ventana del browser. Por ello deben redefinir los métodos gráficos paint() y update(). El método paint() se declara en la forma:
public void paint(Graphics g)
El objeto gráfico g pertenece a la clase java.awt.Graphics, que siempre debe ser importada por el applet. Este objeto define un contexto o estado gráfico para dibujar (métodos gráficos, colores, fonts, etc.) y es creado por el browser.
Todo el trabajo gráfico del applet (dibujo de líneas, formas gráficas, texto, etc.) se debe incluir en el método paint(), porque este método es llamado cuando el applet se dibuja por primera vez y también de forma automática cada vez que el applet se debe redibujar.
En general, el programador crea el método paint() pero no lo suele llamar. Para pedir explícitamente al sistema que vuelva a dibujar el applet (por ejemplo, por haber realizado algún cambio) se utiliza el método repaint(), que es más fácil de usar, pues no requiere argumentos. El método repaint() se encarga de llamar a paint() a través de update().
El método repaint() llama a update(), que borra todo pintando de nuevo con el color de fondo y luego llama a paint(). A veces esto produce parpadeo de pantalla o flickering. Existen dos formas de evitar el flickering:
1. Redefinir update() de forma que no borre toda la ventana sino sólo lo necesario.
2. Redefinir paint() y update() para utilizar doble buffer.

Como Incluir Applets en una pagina HTML

Para llamar a un applet desde una página HTML se utiliza la tag doble <APPLET>…</APPLET>, cuya forma general es (los elementos opcionales aparecen entre corchetes[]):
El atributo NAME permite dar un nombre opcional al applet, con objeto de poder comunicarse con otras applets o con otros elementos que se estén ejecutando en la misma página. El atributo ARCHIVE permite indicar uno o varios ficheros Jar o Zip (separados por comas) donde se deben buscar las clases.
A continuación se señalan otros posibles atributos de <APPLET>:
  • ARCHIVE="file1, file2, file3". Se utiliza para especificar ficheros JAR y ZIP.
  • ALIGN, VSPACE, HSPACE. Tienen el mismo significado que el tag IMG de HTML.

Pasos de parámetros a un Applets

Los tags PARAM permiten pasar diversos parámetros desde el fichero HTML al programa Java del applet, de una forma análoga a la que se utiliza para pasar argumentos a main().
Cada parámetro tiene un nombre y un valor. Ambos se dan en forma de String, aunque el valor sea numérico. El applet recupera estos parámetros y, si es necesario, convierte los Strings en valores numéricos. El valor de los parámetros se obtienen con el siguiente método de la clase Applet:
String getParameter(String name)
La conversión de Strings a los tipos primitivos se puede hacer con los métodos asociados a los wrappers que Java proporciona para dichos tipo fundamentales (Integer.parseInt(String), Double.valueOf(String), …).
En los nombres de los parámetros no se distingue entre mayúsculas y minúsculas, pero sí en los valores, ya que serán interpretados por un programa Java, que sí distingue.
El programador del applet debería prever siempre unos valores por defecto para los parámetros del applet, para el caso de que en la página HTML que llama al applet no se definan.
El método getParameterInfo() devuelve una matriz de Strings (String[ ][ ]) con información sobre cada uno de los parámetros soportados por el applet: nombre, tipo y descripción, cada uno de ellos en un String. Este método debe ser redefinido por el programador del applet y utilizado por la persona que prepara la página HTML que llama al applet. En muchas ocasiones serán personas distintas, y ésta es una forma de que el programador del applet dé información al usuario.

Carga de Applets

  • Localización de ficheros
Por defecto se supone que los ficheros *.class del applet están en el mismo directorio que el fichero HTML. Si el applet pertenece a un package, el browser utiliza el nombre del package para construir un path de directorio relativo al directorio donde está el HTML.
El atributo CODEBASE permite definir un URL para los ficheros que continen el código y demás elementos del applet. Si el directorio definido por el URL de CODEBASE es relativo, se interpreta respecto al directorio donde está el HTML; si es absoluto se interpreta en sentido estricto y puede ser cualquier directorio de la Internet.
  • Archivos JAR (Java Archives)
Si un applet consta de varias clases, cada fichero *.class requiere una conexión con el servidor de Web (servidor de protocolo HTTP), lo cual puede requerir algunos segundos. En este caso es conveniente agrupar todos los ficheros en un archivo único, que se puede comprimir y cargar con una sola conexión HTTP.
Los archivos JAR están basados en los archivos ZIP y pueden crearse con el programa jar que viene con el JDK. Por ejemplo:
jar cvf myFile.jar *.class *.gif
crea un fichero llamado myFile.jar que contiene todos los ficheros *.class y *.gif del directorio actual. Si las clases pertenecieran a un package llamado es.ceit.infor2 se utilizaría el comando:
jar cvf myFile.jar es\ceit\infor2\*.class *.gif

Comunicación de Applets con Browser

La comunicación entre el applet y el browser en el que se está ejecutando se puede controlar mediante la interface AppletContext (package java.applet). AppletContext es una interface implementada por el browser, cuyos métodos pueden ser utilizados por el applet para obtener información y realizar ciertas operaciones, como por ejemplo sacar mensajes breves en la barra de estado del browser. Hay que tener en cuenta que la barra de estado es compartida por el browser y las applets, lo que tiene el peligro de que el mensaje sea rápidamente sobre-escrito por el browser u otras applets y que el usuario no llegue a enterarse del mensaje.
Los mensajes breves a la barra de estado se producen con el método showStatus(), como por ejemplo,
getAppletContext().showStatus("Cargado desde el fichero " + filename);
Los mensajes más importantes se deben dirigir a la salida estándar o a la salida de errores, que en Netscape Navigator es la Java Console (la cual se hace visible desde el menú Options en  Navigator 3.0, desde el menú Communicator en Navigator 4.0* y desde Communicator/Tools en Navigator 4.5). Estos mensajes se pueden enviar con las sentencias:
System.out.print();
System.out.println();
System.error.print();
System.error.println();
Para mostrar documentos HTML en una ventana del browser se pueden utilizar los métodos siguientes:
  • showDocument(URL miUrl, [String target]), que muestra un documento HTML en el frame del browser indicado por target (name, _top, _parent, _blank, _self).
  • showDocument(URL miUrl), que muestra un documento HTML en la ventana actual del browser.
Un applet puede conseguir información de otras applets que están corriendo en la misma página del browser, enviarles mensajes y ejecutar sus métodos. El mensaje se envía invocando los métodos del otro applet con los argumentos apropiados.
Algunos browsers exigen, para que las applets se puedan comunicar, que las applets provengan del mismo browser o incluso del mismo directorio (que tengan el mismo codebase). Por ejemplo, para obtener información de otras applets se pueden utilizar los métodos:
  • getApplet(String name), que devuelve el applet llamada name (o null si no la encuentra). El nombre del applet se pone con el atributo opcional NAME o con el parámetro NAME.
  • getApplets(), que devuelve una enumeración con todas las applets de la página.
Para poder utilizar todos los métodos de un applet que se está ejecutando en la misma página HTML (y no sólo los métodos comunes heredados de Applet), debe hacerse un cast del objeto de la clase Applet que se obtiene como valor de retorno de getApplet() a la clase concreta del applet.
Para que pueda haber respuesta (es decir, comunicación en los dos sentidos), el primer applet que envía un mensaje debe enviar una referencia a sí misma por medio del argumento this.

Sonidos en Applets

La clase Applet y la interface AudioClips permiten utilizar sonidos en applets. La Tabla muestra algunos métodos interesantes al respecto.
Métodos de Applet y de AudioClip relacionados con sonidos.
Respecto a la carga de sonidos, por lo general es mejor cargar los sonidos en un thread distinto (creado en el método init()) que en el propio método init(), que tardaría en devolver el control y permitir al usuario empezar a interaccionar con el applet.
Si el sonido no ha terminado de cargarse (en la thread especial para ello) y el usuario interacciona con el applet para ejecutarlo, el applet puede darle un aviso de que no se ha terminado de cargar.

Imagenes en Applets

Las applets admiten los formatos JPEG y GIF para representar imágenes a partir de ficheros localizados en el servidor. Estas imágenes se pueden cargar con el método getImage() de la clase Applet, que puede tener las formas siguientes:
public Image getImage(URL url)
public Image getImage(URL url, String name)
Estos métodos devuelven el control inmediatamente. Las imágenes de cargan cuando se da la orden de dibujar las imágenes en la pantalla. El dibujo se realiza entonces de forma incremental, a medida que el contenido va llegando.
Para dibujar imágenes se utiliza el método drawImage() de la clase Graphics, que tiene las formas siguientes:
public abstract boolean drawImage(Image img, int x, int y,
Color bgcolor, ImageObserver observer)
public abstract boolean drawImage(Image img, int x, int y, int width, int height,
Color bgcolor, ImageObserver observer)
El primero de ellos dibuja la imagen con su tamaño natural, mientras que el segundo realiza un cambio en la escala de la imagen.
Los métodos drawImage() van dibujando la parte de la imagen que ha llegado, con su tamaño, a partir de las coordenadas (x, y) indicadas, utilizando bgcolor para los pixels transparentes.
Estos métodos devuelven el control inmediatamente, aunque la imagen no esté del todo cargada. En este caso devuelve false. En cuanto se carga una parte adicional de la imagen, el proceso que realiza el dibujo avisa al ImageObserver especificado. ImageObserver es una interface implementada por Applet que permite seguir el proceso de carga de una imagen.

Obtención de las propiedades del Sistema

Un applet puede obtener información del sistema o del entorno en el que se ejecuta. Sólo algunas propiedades del sistema son accesibles. Para acceder a las propiedades del sistema se utiliza un método static de la clase System:
String salida = System.getProperty("file.separator");
Los nombres y significados de las propiedades del sistema accesibles son las siguientes:
"file.separator"                                     Separador de directorios (por ejemplo, "/" o "\")
"java.class.version"                            Número de version de las clases de Java
"java.vendor"                                        Nombre específico del vendedor de Java
"java.vendor.url"                                  URL del vendedor de Java
"java.version"                                       Número de versión Java
"line.separator"                                   Separador de líneas
"os.arch"                                               Arquitectura del sistema operativo
"os.name"                                            Nombre del sistema operativo
"path.separator"                                  Separador en la variable Path (por ejemplo, ":"
No se puede acceder a las siguientes propiedades del sistema: "java.class.path", "java.home", "user.dir", "user.home", "user.name".

Utilización de Threads en Applets

Un applet puede ejecutarse con varias threads, y en muchas ocasiones será necesario o conveniente hacerlo así. Hay que tener en cuenta que un applet se ejecuta siempre en un browser (o en la aplicación appletviewer).
Así, las threads en las que se ejecutan los métodos mayores -init(), start(), stop() y destroy() dependen del browser o del entorno de ejecución. Los métodos gráficos -paint(), update() y repaint() se ejecutan siempre desde una thread especial del AWT.
Algunos browsers dedican un thread para cada applet en una misma página; otros crean un grupo de threads para cada applet (para poderlas matar al mismo tiempo, por ejemplo). En cuelquier caso se garantiza que todas las threads creadas por los métodos mayores pertenecen al mismo grupo.
Se deben introducir threads en applets siempre que haya tareas que consuman mucho tiempo (cargar una imagen o un sonido, hacer una conexión a Internet, …). Si estas tareas pesadas se ponen en el método init() bloquean cualquier actividad del applet o incluso de la página HTML hasta que se completan. Las tareas pesadas pueden ser de dos tipos:
  • Las que sólo se hacen una vez.
  • Las que se repiten muchas veces.
Un ejemplo de tarea que se repite muchas veces puede ser una animación. En este caso, la tarea repetitiva se pone dentro de un bucle while o do…while, dentro del thread. El thread se debería crear dentro del método start() del applet y destruirse en stop(). De este modo, cuando el applet no está visible se dejan de consumir recursos.
Al crear el thread en el método start() se pasa una referencia al applet con la palabra this, que se refiere al applet. El applet deberá implementar la interface Runnable, y por tanto debe definir el método run(), que es el centro del Thread.
Un ejemplo de tarea que se realiza una sola vez es la carga de imágenes *.gif o *.jpeg, que ya se realiza automáticamente en un thread especial.
Sin embargo, los sonidos no se cargan en threads especiales de forma automática; los debe crear el programador para cargarlos en “background”. Este es un caso típico de programa producerconsumer: el thread es el producer y el applet el consumer. Las threads deben estar sincronizadas, para lo que se utilizan los métodos wait() y notifyAll().
A continuación se presenta un ejemplo de thread con tarea repetitiva:
El método run() se detendrá en cuanto se ejecute el método stop(), porque la referencia al thread está a null.

Applets que también son programas

Es muy interesante desarrollar aplicaciones que pueden funcionar también como applets y viceversa. En concreto, para hacer que un applet pueda ejecutarse como aplicación pueden seguirse las siguientes instrucciones:
  1.  Se añade un método main() a la clase MiApplet (que deriva de Applet)
  2. El método main() debe crear un objeto de la clase MiApplet e introducirlo en un Frame.
  3. El método main() debe también ocuparse de hacer lo que haría el browser, es decir, llamar a los métodos init() y start() de la clase MiApplet.
  4. Se puede añadir también una static inner class que derive de WindowAdapter y que
gestione el evento de cerrar la ventana de la aplicación definiendo el método windowClosing(). Este método llama al método System.exit(0). Según como sea el applet, el método windowClosing() previamente deberá también llamar a los métodos MiApplet.stop() y MiApplet.destroy(), cosa que para las applets se encarga de hacer el browser. En este caso conviene que el objeto de MiApplet creado por main() sea static, en lugar de una variable local.
A continuación se presenta un ejemplo:
Fuente: Applets, Que es un Applets, Características y Métodos