Download Tutorial sobre AWT y applets - dccia

Document related concepts
no text concepts found
Transcript
Tema 6
Programación de Applets
6.1 Fundamentos de los applets
Un applet es un programa Java que se ejecuta en el navegador web, utilizando todos sus
recursos como entorno de trabajo. Por ejemplo, la página en la que se carga el applet hace de
entorno gráfico en el que se van a dibujar los comandos gráficos.
Algunas ventajas de los applets frente a JavaScript son:
‰
‰
‰
Mayor potencia. Uso de funciones gráficas.
Código fuente no visible.
Opciones de seguridad.
Suponemos que tienes un conocimiento inicial del lenguaje de programación Java. A
continuación vamos a explicar las características básicas de los applets, utilizando ejemplos y
demostraciones.
6.1.1 Implementación básica de un applet
Para construir un applet debemos implementar una clase que especialice la clase Java
Applet. La clase Applet permite la definición de pequeñas aplicaciones que van a ser
ejecutadas dentro de un programa, en nuestro caso un navegador. Esta clase proporciona un
conjunto de métodos de utilidad que veremos más adelante, y que nos van a permitir, por
ejemplo, cargar una imagen desde una URL, reproducir un sonido o abrir una nueva página en
el navegador.
Ciclo de vida de un applet
Cuando el navegador carga un applet por primera vez, éste debe realizar ciertas tareas de
inicialización. En otros momentos, el applet desaparecerá de la vista del usuario, bien porque
éste ha cargado otra página, o porque ha minimizado la página actual. En cualquier de estos
casos, el navegador llama a un método del ciclo de vida del applet, para que éste realice las
tareas correspondientes a cada caso. Los métodos son los siguientes:
‰
‰
‰
‰
init(): método al que llama el navegador cuando se carga o recarga el applet. En
este método debe incluirse todo el código de inicialización del mismo.
start(): método al que llama el navegador cuando comienza a ejecutar el applet. Si
un usuario sale de la página en la que se ha cargado el applet y vuelve a ella, el applet
no se reinicia, sino que vuelve a llamarse a este método.
stop(): método al que llama el navegador cuando se detiene el applet. Esto sucede
cuando el usuario abandona la página con el applet, o minimiza la aplicación.
destroy(): método al que llama el navegador justo antes de descargar el applet.
Todos los métodos del ciclo de vida están definidos, por defecto, en la clase Applet. A la hora
de implementar un applet se deberán redefinir únicamente aquellos métodos necesarios. Lo
más usual es definir únicamente init() y dejar que el resto de métodos ejecuten el código de
la clase padre.
Tema 6. Programación de applets
Applets como componentes AWT
El AWT (Abstract Windows Toolkit) es un conjunto de clases de Java que permiten construir y
manejar interfaces de usuario. Estas clases son parte integral del lenguaje y proporcionan, por
lo tanto, una garantía de que la aplicación desarrollada va a poder ejecutarse en cualquier
entorno que soporte el lenguaje Java. En nuestro caso, el entorno de ejecución será un
navegador.
El AWT se basa en dos conceptos fundamentales: componentes y eventos. Los componentes
son los elementos como menús, botones, etiquetas, campos de texto, etc. que forman la
interfaz de usuario. Una interfaz de usuario se construye añadiendo con el método add los
componentes al applet, o añadiéndolos a paneles (objetos de la clase Panel) que después se
añadirán a su vez al applet. En realidad, la clase Applet es una subclase de Panel, y ésta es
subclase de Container (la jerarquía de clases de AWT se muestra en el apartado ...) Un
objeto container es un tipo especial de componente no visible, que permite agrupar los
componentes que se añaden en él y tratar como uno todos ellos cuando se insertan en un
container superior (el applet, por ejemplo).
Por otra parte, los eventos se producen como consecuencia de las acciones del usuario sobre
los componentes y deben ser tratados por el programa. Para ello, el AWT 1.1proporciona los
denominados listeners, objetos que se asocian a componentes y que manejan los eventos
específicos de su clase. Hay distintas clases de listeners, por ejemplo: actionListener, para
acciones semánticas como la pulsación de un botón, mouseListener, para eventos del ratón
como pulsaciones, windowListener, para eventos relacionados con las ventanas, como
cerrar o minimizar ventana, etc. Cada objeto escucha únicamente los eventos del tipo
correspondiente a su clase y que además se han ejecutado sobre el componente al que están
asociados.
NOTA
2
En las distintas versiones de Java se ha ido modificando la librería AWT. En
las primeras versiones (JDK 1.0X) se hablaba del AWT 1.0. Con el
lanzamiento de la versión 1.1 de Java se introduce AWT 1.1 y se modifica
sustancialmente el modelo de eventos de la librería. La introducción Java 2
ha provocado un cambio considerable también en las librerías de interface
de usuario. Aunque se ha mantenido AWT 1.1 sin cambios, se ha introducido
una versión nueva, Swing, que mantiene un modelo muy parecido de
componentes y eventos, pero mejora sustancialmente los componentes.
Existe una variedad mucho mayor de componentes, introduciéndose mejoras
como la posibilidad de imágenes en los botones, las tablas o la posibilidad de
cambiar la apariencia de las componentes (dándoles el aspecto Windows,
Mac, Motif, etc.). En cuanto a la compatibilidad con los navegadores, si
buscamos una compatibilidad absoluta tendremos que utilizar AWT 1.0. La
versión 1.1 de AWT es soportada desde la versión 4 del Internet Explorer y
del Netsape y es un buen compromiso de compatibilidad y funcionalidad. No
existen navegadores compatibles con Swing, aunque es posible implementar
applets que lo utilicen mediante el Java Plug-in de Sun Microsystem (ver
apartado 6.3.3)
Tema 1. Protocolo HTTP y aplicaciones web
Un primer ejemplo de applet
Ejemplo de un sencillo applet que muestra un botón y asocia una acción al evento de pulsar el
botón. En este caso, la acción es ejecutar un beep.
Listado 6.1. Beep.java
Sencillo applet que muestra un botón y ejecuta un beep al pulsarlo
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
public class Beep extends Applet {
Toolkit toolkit;
public void init() {
toolkit = this.getToolkit();
Button botonBeep = new Button("Beep");
botonBeep.addActionListener(new BotonBeepListener());
add(botonBeep);
}
class BotonBeepListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
toolkit.beep();
}
}
}
En el applet se define el componente botonBeep de tipo botón y se le asocia un manejador de
eventos de la clase BotonBeepListener. Esta clase es una clase interna (inner class) de
Beep e implementa la interfaz ActionListener, que escucha el evento 'pulsación del botón'.
Como ya hemos comentado, cuando se produce un evento sobre un componente sólo
escuchan ese evento aquellos manejadores que están asociados al componente y que
implementan métodos relacionados con el evento producido. En este caso, la interfaz
ActionListener sólo tiene un único método, que es actionPerformed(), que se ejecuta
cuando se pulsa el botón al que se ha asociado el manejador.
Para comprobar el funcionamiento del applet, debes primero compilarlo. Para ello, debes tener
instalado algún compilador Java. Supongamos que tienes el JSDK 1.3 de Sun, en el directorio
C:\jdk1.3. Debes inicializar las variables del entorno necesarias para que el compilador y el
intérprete de Java funcionen correctamente:
> set JAVA_HOME = C:\jdk1.3
> set CLASSPATH = %JAVA_HOME%\lib;.
> set PATH = %PATH%:%JAVA_HOME%\bin
Ahora ya puedes compilar el programa
> javac Beep.java
y cargarlo en un navegador. El siguiente fichero HTML se encarga de realizar la carga del
applet:
Listado 6.2. Beep.html
Documento HTML que carga el applet Beep.class en el navegador
<html>
<applet code=Beep.class width=100 height=100>
</applet>
</html>
También es posible comprobar el funcionamiento de un applet utilizando el programa
appletviewer proporcionado en la distribución del JSDK de Sun.
3
Tema 6. Programación de applets
> appletviewer Beep.html
Verás un botón que ejecutará un sonido cuando lo pulses.
6.1.2 El tag APPLET
Ya hemos visto en el ejemplo anterior que la etiqueta que se emplea en la página HTML para
cargar el applet es <APPLET>.
Sintaxis
La sintaxis completa de esta etiqueta es la siguiente:
<APPLET
[CODEBASE = URL]
[CODE = fichero con la clase principal]
WIDTH = anchura
HEIGHT = altura
[ALT = texto alternativo]
[NAME = nombre del applet]
[ALIGN = alineación en la página]
[VSPACE = espacio vertical]
[HSPACE = espacio vertical]
>
[<PARAM NAME = nombre del parámetro 1 VALUE = valor del parámetro 1 >]
[<PARAM NAME = nombre del parámetro 2 VALUE = valor del parámetro 2 >]
...
[Texto HTML alternativo]
</APPLET>
Descripción de los elementos
El significado de cada uno de estos elementos se comenta en la siguiente tabla:
4
Elemento
Descripción
CODEBASE = URL
URL base del applet. Por defecto, el URL del directorio
que contiene la página desde la que se carga el applet.
Si se especifica una dirección relativa, se añade a esta
URL por defecto.
CODE = fichero .class
Nombre del fichero .class que implementa el applet.
La URL completa del fichero se obtiene añadiendo este
nombre al CODEBASE.
WIDTH = pixels
Ancho en pixels de la zona del navegador reservada
para mostrar el applet
HEIGHT = pixels
Alto en pixels de la zona del navegador reservada para
mostrar el applet.
ALT = textoAlternativo
Texto que debe mostrar el navegador si entiende la
etiqueta APPLET, pero es incapaz de cargar el applet.
NAME = nombre
Nombre que identifica el applet. Se usa para que más de
una applet en la misma página puedan comunicarse
entre ellos.
ALIGN = alineación
Elemento idéntico al atributo del tag IMG de HTML.
Define la alineación del applet. Puede tomar los
siguientes valores: left, right, top, texttop, middle,
absmiddle, baseline, bottom, absbottom.
VSPACE = pixels
Elemento idéntico al atributo del tag IMG de HTML.
Espacio vertical en pixels que el navegador debe
reservar entre el texto previo y el applet.
Tema 1. Protocolo HTTP y aplicaciones web
HSPACE = pixels
Elemento idéntico al atributo del tag IMG de HTML.
Espacio horizontal en pixels que el navegador debe
reservar entre el texto previo y el applet.
PARAM = identificador
del parámetro VALUE
= valor
Se utiliza para el paso de parámetros desde la página
HTML hasta el applet. Ya se ha explicado en detalle.
Texto alternativo
Texto que aparecerá en aquellos navegadores que no
entiendan el tag APPLET.
El elemento CODEBASE permite que el applet se encuentre en un directorio (incluso en una
URL) distinto del directorio en el que se encuentra el fichero HTML desde el que se carga. De
esta forma, podemos en el servidor organizar applets (ficheros .class) y ficheros HTML en
directorios distintos.
El atributo CODE debe contener el nombre del fichero principal que implementa el applet, esto
es, el fichero con el nombre de la clase que es subclase de Applet. En el caso de que este
fichero deba importar otras clases adicionales implementadas por nosotros, el navegador las
cargará de forma automática realizando una petición HTTP por cada una de ellas. Esto
introduce un retardo importante en la carga del applet. Para mejorar el rendimiento de estos
casos, la versión 1.1 del JDK de Java introdujo los archivos JAR, basados en el formato ZIP,
que comprimen un conjunto de ficheros CLASS en un único archivo. Con la etiqueta ARCHIVE
se carga el fichero JAR en el navegador. Por ejemplo, para cargar el fichero JAR menu.jar,
que está situado en el directorio applets y tiene una clase menu.class que es subclase de
Applet, se debería escribir:
<APPLET CODEBASE = applets/ CODE = menu.class ARCHIVE = menu
WIDTH = 100 HEGHT = 400>
Parámetros
Otro elemento muy importante son las etiquetas PARAM. Constituyen la forma de pasar
parámetros desde la página HTML hasta el applet. Normalmente los applets "profesionales"
tienen un gran número de parámetros que permiten una gran flexibilidad en su uso, haciendo
posible que el applet funcione en múltiples situaciones sin necesidad de reescribirlo ni
recompilarlo. Todos los valores de los parámetros se pasan como strings y es el applet debe
convertirlos en el tipo adecuado. Cuando escribamos un applet que use parámetros debemos
documentar perfectamente qué parametros acepta y cuál es la sintaxis esperada para cada
uno de los parámetros.
Por ejemplo, revisemos el applet MenuApplet2L. Se trata de uno de los muchísimos applets
"profesionales" de dominio público desarrollados para mostrar menús en páginas HTML.
Hemos escogido éste por su sencillez, y por tener disponible el código fuente. En este caso, el
applet permite dos niveles de profundidad en los menús y opciones de menús con gráficos y/o
texto.
NOTA: Sitios web donde buscar applets (jars, gamelan, tocows) www.jars.com
Para cargar el applet, hay que especificar los valores de todos los parámetros necesarios para
configurarlo, como son el color de fondo, el fuente por defecto del texto o todas las opciones de
menú junto con la URL a la que apuntan.
Listado 6.3: Ejemplo de etiqueta APPLET para configurar el applet MenuApplet2L
<APPLET
CODEBASE = "." CODE = "menuapplet2l.MenuApplet2L.class"
ARCHIVE = "menuapplet2l.jar" NAME = "MenuApplet2L" WIDTH = 200 HEIGHT = 400 >
<PARAM
<PARAM
<PARAM
<PARAM
NAME
NAME
NAME
NAME
=
=
=
=
"Background" VALUE = "FFFFFF">
"BackgroundSubMenu" VALUE = "FFFFFF">
"DefaultFont" VALUE = "Arial,,14">
"TextColor" VALUE = "003366">
5
Tema 6. Programación de applets
<PARAM NAME = "TextColorSubMenu" VALUE = "003366">
<PARAM NAME = "TextColorHighlight" VALUE = "4444FF">
<PARAM NAME = "TextColorPressed" VALUE = "FF4444">
<PARAM NAME = "Choice0" VALUE = "Universidad de Alicante >>">
<PARAM NAME = "Choice0-0" VALUE = "Home page (new frame)">
<PARAM NAME = "Choice0-0-URL" VALUE = "http://www.ua.es">
<PARAM NAME = "Choice0-0-FONT" VALUE = "Arial,,12">
<PARAM NAME = "Choice1" VALUE = "PAW">
<PARAM NAME = "Choice1-URL" VALUE =
"http://www.dccia.ua.es/dccia/inf/asignaturas/PAW">
<PARAM NAME = "Choice2" VALUE = "Departamento DCCIA >>">
<PARAM NAME = "Choice2-0" VALUE = "Componentes">
<PARAM NAME = "Choice2-0-URL" VALUE =
"http://www.dccia.ua.es/dccia/publico/estaticas/cas/componentes.cas">
<PARAM NAME = "Choice2-0-FONT" VALUE = "Arial,,12">
<PARAM NAME = "Choice2-1" VALUE = "Docencia">
<PARAM NAME = "Choice2-1-URL" VALUE =
"http://www.dccia.ua.es/dccia/publico/estaticas/cas/docencia.cas">
<PARAM NAME = "Choice2-1-FONT" VALUE = "Arial,,12">
</APPLET>
6.1.3 Algo más de AWT 1.1
Componentes de AWT 1.1
Ya hemos visto que los componentes son los elementos que forman la interfaz de usuario de
un applet. En AWT 1.1 existen 9 tipos de componentes: Button, Canvas, Checkbox, Choice,
Label, List, Scrollbar, TextComponent (TextField y TextArea), MenuComponent
(MenuItem y MenuBar). Además, existe un tipo especial de componente invisible pero
fundamental para la visualización de todos los demás. Se trata de la clase Container, con
subclases como Panel, Window o ScrollPane, que sirve para almacenar y distribuir
espacialmente los componentes elementales. Como un container es también un componente,
se puede anidar la utilización de unos y otros, por ejemplo añadiendo un panel que contenga
un cierto número de botones en la parte izquierda de un applet, que, como ya hemos visto, es
un tipo especial de panel.
La siguiente figura muestra el aspecto visual de todos los componentes de AWT 1.1.
La estructura de clases de los componentes de AWT 1.1 se muestra en la siguiente figura.
6
Tema 1. Protocolo HTTP y aplicaciones web
Todos los componentes son subclases de la clase Component, y heredan alrededor de 100
métodos de esa clase. Algunos de métodos de esta clase que pueden resultar útiles son
getSize(),
getLocation(),
getBounds(),
setEnabled(boolean),
setVisible(boolean),
setBackground(color),
setForeground(color)
o
setFont(Font). Se puede encontrar más información en la documentación de las clases de
AWT incluida en la distribución del JSDK.
Además de estos componentes existe un componente especial orientado a la construcción de
menús. Se trata de MenuComponent, y se diferencia de los anteriores en que sólo es posible
añadirlo a objetos de la clase Window. Dado que los applets no son objetos de esta clase, sino
de la clase Panel, no es posible añadir directamente un menú en applet.
En la siguiente tabla podemos ver un ejemplo de cada uno de los componentes mencionados.
Componente
Ejemplo
Button
Button comp = new Button("Etiq");
Canvas
class RegionDibujo extends Canvas {
public RegionDibujo() {
setSize(100, 50);
}
public void paint(Graphics g) {
g.drawRect(0, 0, 99, 49); // dibujo el borde
g.drawString("Un Canvas", 20,20);
}
}
RegionDibujo comp = new RegionDibujo();
Checkbox
Checkbox m = comp Checkbox("Etiq", true);
Grupo de checkboxs
(radio buttons)
CheckboxGroup cbg = new CheckboxGroup();
Checkbox comp1 = new Checkbox("Etiq 1", cbg, true);
Checkbox comp2 = new Checkbox("Etiq 2", cbg, false);
Choice
Choice comp = new Choice();
comp.add("Etiq 1");
comp.add("Etiq 2");
comp.add("Etiq 3");
Label
Label comp = new Label("Etiq");
7
Tema 6. Programación de applets
List
List list = new List(3, false); // Visualizo 3
list.add("Etiq 1");
// elementos,
list.add("Etiq 2");
// sin selección
list.add("Etiq 3");
// múltiple
list.add("Etiq 4");
list.add("Label 5");
Scrollbar
Scrollbar comp =
new Scrollbar(Scrollbar.HORIZONTAL,
0, // valor inicial
5, // ancho del slider
-100, 100); // rango
Text comp =
new Text("Etiq",15); // número de columnas
TextField
TextArea
TextArea comp =
new TextArea("Etiq", 10,20); // filas y cols.
Para comprobar el funcionamiento de cualquiera de los componentes de la tabla anterior, no
hay más que insertar el código ejemplo en el método init() del applet y añadir el
componente al applet:
import java.awt.*;
import java.applet.Applet;
public class Test extends Applet {
public void init() {
// Insertar el código ejemplo aquí
add(comp);
}
}
En el caso del Canvas, hay que realizar la definición de la clase RegionDibujo fuera de la
clase Test:
import java.awt.*;
import java.applet.Applet;
public class Test extends Applet {
public void init() {
// Insertar el código ejemplo aquí
add(comp);
}
}
public class RegionDibujo extends Canvas {
// Completar código
}
Contenedores y gestores de disposición
Hemos mencionado que para construir la interfaz de usuario se deben ir añadiendo
componentes en el applet, un objeto de clase Container. El método utilizado para ello es el
método add:
add(comp1);
add(comp2);
...
add(compN)
¿Cómo aparecen ordenados los componentes en el applet? Depende de la gestión de
disposición (layout management) activa en el contenedor. La gestión de la disposición es el
proceso de determinar el tamaño y la posición de los componenentes. Por defecto, cada
contenedor tiene activo un gestor de disposición que es el que realiza esa tarea con los
componentes que se van añadiendo al contenedor. La librería AWT 1.1 proporciona
fundamentalmente cuatro gestores de disposición: BorderLayout, FlowLayout,
GridLayout y GridBagLayout. Siempre que se use el método add para añadir un
componente en un contenedor, tiene que tenerse en cuenta el gestor de disposición. Algunos
8
Tema 1. Protocolo HTTP y aplicaciones web
gestores, como BorderLayout, necesitan un parámetro adicional en el método add indicando
dónde colocar el componente (en el norte, sur, este, oeste o centro). Otros gestores, como
GridBagLayout, requieren un complicado proceso de preparación. Y otros, como
FlowLayout o GridLayout, simplemente van colocando los componentes basándose en el
orden en que son añadidos en el contenedor.
También es posible definir una posición y tamaño absoluta para los componentes. Esto sólo se
debe hacer cuando la aplicación no va a reutilizarse, va a tener siempre el mismo tamaño y
controlamos totalmente aspectos que influyen en el tamaño final de los componentes como es
el tamaño de las fuentes utilizadas.
Manejo de eventos en AWT 1.1
En el modelo de eventos de AWT 1.1 (y también de SWING) los eventos se generan desde
fuentes de eventos (event sources). En concreto, estas fuentes de eventos son los
componentes que constituyen la interfaz de usuario. Uno o más oyentes (listeners) de eventos
pueden registrarse para ser avisados cuando se produce un evento de una determinada clase
ha sido generado por una fuente determinada.
En AWT 1.1 los oyentes de eventos se definen mediante interfaces, lo que permite que
cualquier clase pueda manejar eventos, siempre que implemente la interfaz correspondiente.
Normalmente, cualquier programa que implemente un manejador de eventos hará lo siguiente:
‰
Definir una clase que implemente la interfaz del oyente de eventos deseado. Por
ejemplo:
class MiClase implements ActionListener {
‰
Implementar en esa clase los métodos que van a manejar los eventos que se reciban:
public void actionPerformed (ActionEvent e) {
// código que gestiona el evento recibido
}
‰
Registrar un objeto de esta clase como oyente en uno o más componentes que
actuarán de fuentes de eventos:
componente.addActionListener(instanciadeMiClase);
En la figura siguiente podemos ver un ejemplo de registro de oyentes. En ella se representan
tres objetos del tipo oyente (listener) que se registran en dos componentes. Los objetos
oyente1 y oyente2 se registran en componente1, y oyente2 y oyente3 se registran en
componente2.
Registro
componente1
oyente1
Registro
Registro
oyente2
componente2
Registro
oyente3
9
Tema 6. Programación de applets
Una vez registrados, cualquier evento que se produzca en un determinado componente
(movimiento del ratón, selección de una opción, pulsación del ratón, etc) será enviado a los
oyentes registrados en ese componente para que lo procesen. En la siguiente figura se
muestra este comportamiento.
Eventos
componente1
oyente1
Eventos
Eventos
oyente2
componente2
Eventos
oyente3
Aunque esto es bastante sencillo, la flexiblidad de la librería AWT hace que podamos encontrar
bastantes formas de implementar este modelo. Como ejemplo curioso, veamos dos
implementaciones adicionales del applet Beep del listado 6.1:
‰
En el primer ejemplo se muestra cómo es posible extender la clase Button
incorporando el manejo de los eventos en la propia clase. De esta forma, cualquier
objeto nuevo que creemos de la clase BotonBeep tendrá por defecto asociado la
ejecución de un beep cuando lo pulsemos
public class Beep2 extends Applet {
public void init() {
BotonBeep botonBeep = new BotonBeep("Beep");
add(botonBeep);
}
}
class BotonBeep extends Button implements ActionListener {
public BotonBeep(String str) {
super(str);
addActionListener(this);
}
public void actionPerformed(ActionEvent event) {
Component c = (Component)event.getSource();
c.getToolkit().beep();
}
}
‰
El segundo ejemplo es el preferido por algunos tutoriales que desean ahorrarse unas
cuantas líneas de código. Se basa en crear un objeto in-line que será el encargado de
manejar el evento de pulsación del botón.
public class Beep3 extends Applet {
public void init() {
Button botonBeep = new Button("Beep");
botonBeep.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
Component c = (Component)event.getSource();
c.getToolkit().beep();}});
add(botonBeep);
}
}
10
Tema 1. Protocolo HTTP y aplicaciones web
Para hacer más eficiente el sistema se implementan distintas clases de eventos, que sólo
serán escuchados por los objetos de las clases que implementen el interfaz correspondiente.
Por ejemplo, un evento de clase KeyEvent (pulsación de una tecla) sólo será enviado a
objetos que implementen la interfaz KeyListener. Los nombres de los tipos de evento y de
las interfaces se construyen siempre igual. Las clases de eventos se denominan XXXXEvent y
las interfaces se denominan XXXXListener. La siguiente tabla enumera los tipos de evento,
las interfaces y los métodos.
Evento
Eventos
de bajo
nivel
Eventos
semánticos
Listener
Métodos
componentHidden
componentMoved
ComponentEvent
ComponentListener
componentResized
componentShown
componentAdded
ContainerEvent
ContainerListener
componentRemoved
focusGained
FocusEvent
FocusListener
focusLost
keyPressed
KeyEvent
KeyListener
keyReleased
keyTyped
mouseClicked
mouseEntered
mouseExited
MouseEvent
MouseListener
mousePressed
mouseReleased
mouseDragged
MouseMotionEvent MouseMotionListener
mouseMoved
windowActivated
windowClosed
windowClosing
windowDeactivated
WindowEvent
WindowListener
windowDeiconified
windowIconofied
windowOpened
ActionEvent
ActionListener
actionPerformed
AdjustmentEvent AdjustmentListener adjustmentValueChanged
ItemEvent
ItemListener
itemStateChanged
TextEvent
TextListener
textValueChanged
Cada componente puede generar un determinado tipo de eventos. En la tabla siguiente se
enumeran los tipos de evento que puede generar cada uno de los componentes de AWT. Hay
que hacer notar que cuando una clase de componente genera un tipo de evento, también lo
hacen todas sus subclases.
Componente
Tipo de evento generado
Component
ComponentEvent
FocusEvent
KeyEvent
MouseEvent
MouseMotionEvent
ContainerEvent
WindowEvent
ActionEvent
ActionEvent
ItemEvent
ActionEvent
TextEvent
ItemEvent
ItemEvent
AdjustmentEvent
Eventos
de bajo
nivel
Container
Window
Button
List
TextField
Eventos
semánticos
Choice
Checkbox
Scrollbar
11
Tema 6. Programación de applets
Ejemplos
Para terminar el apartado dedicado a AWT, vamos a presentar un par de ejemplos en los que
se utilizan los conceptos que hemos ido presentando.
En el primer ejemplo, se muestran diversos componentes AWT y se juega con los eventos que
producen.
Listado 6.4 EjemploAWT.java
Applet que muestra diversos componentes AWT
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
public class EjemploAWT extends Applet {
Choice menu;
Checkbox cb1, cb2, cb3;
TextField text;
TextArea output;
public void init() {
menu = new Choice();
menu.add("Opción 1"); menu.add("Opción 2");
menu.add("Opción 3"); menu.add("Opción 4");
MiItemListener il = new MiItemListener();
menu.addItemListener(il);
add(menu);
cb1 = new Checkbox("Checkbox 1"); cb1.addItemListener(il);
cb2 = new Checkbox("Checkbox 2"); cb2.addItemListener(il);
cb3 = new Checkbox("Checkbox 3"); cb3.addItemListener(il);
add(cb1); add(cb2); add(cb3);
text = new TextField("Escribe algo aquí");
add(text);
Button boton = new Button("Escribir");
boton.addActionListener(new BotonListener());
add(boton);
output = new TextArea(10, 40); output.setEditable(false);
add(output);
}
class BotonListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
String str = menu.getSelectedItem();
if (cb1.getState()) str = str + " " + cb1.getLabel();
if (cb2.getState()) str = str + " " + cb2.getLabel();
if (cb3.getState()) str = str + " " + cb3.getLabel();
str = str + " " + text.getText();
output.append(str+"\n");
}
}
class MiItemListener implements ItemListener {
public void itemStateChanged(ItemEvent event) {
Object source = event.getSource();
if (source instanceof Choice)
output.append(((Choice)source).getSelectedItem()+" seleccionada\n");
else if (source instanceof Checkbox)
output.append(((Checkbox)source).getLabel()+" ha cambiado\n");
}
}
}
Podemos ver cómo se definen dos clases que manejan eventos: BotonListener y
MiItemListener. Ambas clases son internas a EjemploAWT y pueden, por tanto, acceder a
variables de esa clase. En este caso ambas clases acceden a los componentes para obtener
su estado e imprimirlo en output. La clase BotonListener implementa un manejador que
describe el estado de menu, cb1, cb2, cb3 y text. Un objeto de esta clase se registra en el
12
Tema 1. Protocolo HTTP y aplicaciones web
componente botón. La clase MiItemListener implementa un manejador que se activa
cuando cambia de estado algún item. Un único objeto de esta clase se registra en todos los
componentes que generan un evento de tipo item.
En el segundo ejemplo mostramos cómo se puede utilizar un Canvas y gestionar los eventos
de ratón para implementar un applet que permite activar y desactivar puntos situados sobre
una rejilla. Este applet podría ser la semilla de una aplicación más ambiciosa que implemente
un juego de "guerra de barcos".
Listado 6.5. DibujaPuntos.java
Applet que permite activar y desactivar puntos en una rejilla
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
public class DibujaPuntos extends Applet {
public void init() {
Dimension d = getSize();
AreaDibujo region = new AreaDibujo(d.width,d.height);
add(region);
}
}
class AreaDibujo extends Canvas implements MouseListener{
boolean puntos[][] = new boolean[10][10];
public AreaDibujo(int ancho, int alto) {
for (int i=0; i<10;i++)
for (int j=0; j<10; j++)
puntos[i][j] = false;
setSize(ancho,alto);
addMouseListener(this); // La propia clase implementa la
// interfaz MouseListener y maneja
// los eventos del raton
}
// Metodo de la interfaz MouseListener
public void mousePressed(MouseEvent e) {
int i = e.getX()/10;
int j = e.getY()/10;
if (puntos[i][j]) puntos[i][j] = false;
else puntos[i][j] = true;
repaint();
}
// Los
public
public
public
public
siguientes metodos están vacíos y completan la interfaz MouseListener
void mouseClicked(MouseEvent e) {}
void mouseEntered(MouseEvent e) {}
void mouseExited(MouseEvent e) {}
void mouseReleased(MouseEvent e) {}
// Reescritura del metodo paint de la clase Canvas
public void paint(Graphics g) {
System.out.println("Paint");
for (int i=0; i<10; i++)
for (int j=0; j<10; j++)
if (puntos[i][j]) {
g.setColor(Color.blue);
g.fillOval(i*10+3, j*10+3,6,6);
g.setColor(Color.red);
g.drawOval(i*10+3, j*10+3,6,6);
}
}
}
13
Tema 6. Programación de applets
Para cargar el applet:
Listado 6.6. DibujaPuntos.html
Documento HTML que carga el applet DibujaPuntos.class en el navegador
<html>
<applet code=DibujaPuntos.class width=100 height=100>
</applet>
</html>
6.2 Métodos del paquete java.applet
El paquete java.applet está constituido por la clase Applet y las interfaces
AppletContext, AppletStub y AudioClip. Las interfaces son implementadas por el propio
navegador y constituyen la forma de pasar información propia del navegador hacia el applet.
Entre las funciones que vamos a poder realizar utilizando estos métodos se encuentran las
siguientes:
‰
‰
‰
‰
‰
‰
Obtener la URL donde se encuentra el documento que ha cargado el applet.
Leer los valores los parámetros de la etiqueta APPLET del documento HTML.
Obtener una imagen desde una determinada URL.
Ejecutar un clip de sonido.
Mostrar información en la línea de status del navegador.
Abrir una página en el navegador.
También se encuentran en la clase Applet un conjunto de métodos invocados desde el
navegador cuando se produce un evento que puede afectar a la ejecución del applet, como es
que el usuario cambie la página actual o que se minimize la ventana en la que se está
ejecutando. Son los métodos init(), start(), stop() y destroy().
6.2.1 Métodos invocados desde el applet
La siguiente tabla enumera todos los métodos que podemos utilizar desde un applet. Son
métodos de la propia clase Applet o de la interfaz AppletContext. Para utilizar un método
de la interfaz AppletContext no tenemos más que obtener el appletContext asociado a un
applet con el método getAppletContext().
Clase Applet
Interface
AppletContext
14
public
public
public
public
public
public
public
public
public
public
public
public
public
URL getDocumentBase()
URL getCodeBase()
String getParameter(String nombre)
AppletContext getAppletContext()
void resize(int ancho, int alto)
void showStatus(String msg)
Image getImage(URL url)
final static AudioClip newAudioClip(URL url)
AudioClip getAudioClip(URL url)
AudioClip getAudioClip(URL url, String nombre)
String getAppletInfo()
void play(URL url)
void play(URL url, String nombre)
AudioClip getAudioClip(URL url)
Image getImage(URL url)
Applet getApplet(String nombre)
Tema 1. Protocolo HTTP y aplicaciones web
Enumeration getApplets()
void showDocument(URL url)
public void showDocument(URL url, String target)
void showStatus(String status)
URL del documento y del código base
Los métodos getDocumentBase() y getCodeBase() devuelven la URL del documento
HTML que ha cargado el applet y la URL base desde la que se ha cargado el applet. Por
ejemplo:
URL base = getDocumentBase();
Image imagen = getImage(base, "image/image1.gif");
En el ejemplo anterior se obtiene la URL donde está instalado el documento HTML desde el
que se ha cargado el applet y a continuación se obtiene la imagen image1.gif situada en el
subdirectorio image de esa URL. De esta forma se evita dar una URL absoluta y se
independiza la implementación del applet de su ubicación en el servidor.
Obtención de parámetros de la etiqueta APPLET
Recordemos que la sintaxis de la etiqueta APPLET para especificar un parámetro para el
applet era:
<PARAM NAME = nombre VALUE = valor>
El método getParameter(string nombre) devuelve el string valor asociado al parámetro
nombre en la etiqueta APPLET que ha cargado el applet. Después de obtenido el string,
normalmente se convertirá en un objeto de otra clase (int, URL, Color, etc.) utilizando algún
constructor de Java. Por ejemplo, supongamos un applet que permite configurar su color de
fondo con una instrucción como:
<PARAM NAME = "COLOR" VALUE = "00FF44"
Para leer el valor de este parámetro en el applet se debe implementar el siguiente código:
String colorStr = getParameter("COLOR");
if (colorStr == NULL)
Color color = new Color(Color.white);
else
Color color = new Color(Integer.ParseInt(colorStr,16));
Mensajes en la línea de estado del navegador
El método showStatus(String msg) permite mostrar un mensaje en la línea de estado del
navegador. Esta línea no tiene posibilidad de scroll, por lo que cada nuevo mensaje borra el
anterior. Por ejemplo:
String link = getLinkCurrentOption();
showStatus(getDocumentBase()+link);
El ejemplo anterior utiliza la línea de estado para mostrar una URL absoluta. En este caso,
suponemos que el applet implementa un sistema de menús y que el método
getLinkCurrentOption() devuelve el link asociado a la opción sobre la que se encuentra
el ratón.
Imágenes desde URLs
Los métodos getImage(URL url) y getImage(URL url, string nombre) sirven para obtener un
objeto de la clase Image que se encuentra en una determinada URL. Normalmente será la
misma URL donde se encuentra el documento HTML que ha cargado el applet, o algún
subdirectorio. La segunda forma de llamar al método suele ser la más usada desde los applets,
utilizando getDocumentBase() para obtener la URL:
15
Tema 6. Programación de applets
Image img = getImage(getDocumentBase(), "images/img1.gif");
El siguiente applet crea un Canvas en el que se dibuja una imagen que se ha cargado del
directorio en el que se encuentra la página HTML:
Listado 6.7 DibujaImagen.java
Applet que carga la imagen "img1.gif" que debe existir en el mismo directorio en que se
encuentra el fichero HTML que lo carga
import java.applet.Applet;
import java.awt.*;
public class DibujaImagen extends Applet {
public void init() {
Image img = getImage(getDocumentBase(),"img1.gif");
Dimension d = getSize();
AreaDibujo region = new AreaDibujo(img, d.width, d.height);
add(region);
}
}
class AreaDibujo extends Canvas {
Image img;
public AreaDibujo(Image img, int ancho, int alto) {
this.img = img;
setSize(ancho,alto);
}
public void paint(Graphics g) {
g.drawImage(img,0,0,this);
}
}
Existen también otras versiones del método drawImage de la clase Graphics en las que, por
ejemplo, es posible escalar la imagen ajustándola al tamaño del canvas. Nosotros hemos
escogido la versión más sencilla, la que coloca la imagen directamente en la posición (0,0) del
canvas. Si la imagen fuera más grande que el tamaño del canvas (que es el mismo que el del
applet) aparecería recortada.
Reproduciendo sonidos
Existen un conjunto de métodos que permiten cargar y reproducir sonidos en los applets. Los
sonidos deben ser de formato ".au", un formato propio de Sun. Es bastante habitual que los
programas de tratamiento y edición de sonidos ofrezcan la opción de convertir los sonidos al
formato ".au".
Existen métodos en el paquete java.applet para cargar sonidos desde una URL y para
reproducirlos. Son los siguientes:
‰
‰
‰
Para cargar un sonido desde una URL se utilizan los métodos getAudioClip(URL url) y
getAudioClip(URL url, String, nombre). Al igual que con las imágenes, es posible pasar
como parámetro una URL absoluta, o una URL base y un nombre de fichero que se
añade a la URL base. Ambos métodos devuelven un objeto de tipo AudioClip.
Para reproducir un sonido desde una URL se utilizan los métodos play(URL url) y
play(URL url, String nombre).
Una vez que se tiene un objeto de tipo AudioClip es posible reproducir el sonido una
vez, reproducirlo de forma continua o detener la reproducción. Para ello se utilizan los
métodos play(), loop() y stop().
El siguiente ejemplo presenta un applet con dos botones, uno para reproducir de forma
continua un sonido cargado y el otro para detenerlo. El sonido se llama "train.au" y debe estar
en el mismo directorio del fichero HTML que carga el applet.
16
Tema 1. Protocolo HTTP y aplicaciones web
Listado 6.8 Sonido.java
Applet que ejecuta un sonido
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
public class Sonido extends Applet {
AudioClip train;
public void init() {
train = getAudioClip(getDocumentBase(),"train.au");
Button botonPlay = new Button("Play");
botonPlay.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
train.loop();}});
add(botonPlay);
Button botonStop = new Button("Stop");
botonStop.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
train.stop();}});
add(botonStop);
}
}
Abriendo páginas nuevas en el navegador
La interface AppletContext proporciona un conjunto de métodos que permiten acceder a
funcionalidades del entorno en el que se está ejecutando el applet. De hecho, las funciones ya
comentadas de los applets para cargar imágenes o sonidos, se implementan obteniendo el
AppletContext asociado al applet y llamando a los métodos proporcionados por esta
interfaz. Dos de los métodos exclusivos de la interfaz, no implementados en la clase Applet,
son showDocument(URL url) y showDocument(URL url, String target). Estos
métodos hacen que el navegador abra una URL. El primer método lo hace en una nueva
página, y el segundo permite especificar el destino del documento mediante los siguientes
valores:
‰
‰
‰
‰
‰
"_blank": muestra el documento en una página nueva sin nombre
"nombre": muestra el documento en una página nueva llamada "nombre"
"_self": muestra el documento en la página y frame que contiene el applet
"_parent": muestra el documento en la ventana del applet, pero en el frame padre del
frame en el que se encuentra el applet. Si el frame en el que se encuentra el applet no
tiene padre, se comporta igual que "_self".
"_top": muestra el documento en la ventana del applet, pero en el frame de nivel
superior. Si el frame en el que se encuentra el applet es el frame de nivel superior, se
comporta igual que "_self".
Como ejemplo listamos a continuación un applet que permite al usuario introducir una URL en
un campo de texto y abre el documento en una nueva página cuando se pulsa ENTER o el
botón.
Listado 6.9 DocumentoNuevo.java
Applet que prueba el funcionamiento del método showDocument
import
import
import
import
java.awt.*;
java.applet.*;
java.awt.event.*;
java.net.*;
public class DocumentoNuevo extends Applet {
TextField textField;
AppletContext appletContext;
17
Tema 6. Programación de applets
public void init() {
appletContext = getAppletContext();
textField = new TextField("Introduce la URL aquí");
AbrirURL listener = new AbrirURL();
textField.addActionListener(listener);
add(textField);
Button botonURL = new Button("Abrir URL");
botonURL.addActionListener(listener);
add(botonURL);
}
class AbrirURL implements ActionListener {
public void actionPerformed(ActionEvent event) {
String urlString = textField.getText();
URL url = null;
try {
url = new URL(urlString);
} catch (MalformedURLException e) {
showStatus("URL incorrecta: " + urlString);
}
if (url != null) appletContext.showDocument(url,"página nueva");
}
}
}
Nótese el modo en que se comprueba que la URL es correcta, capturando la excepción
MalformedURLException. También es interesante hacer notar que se asocia el mismo
oyente del evento ActionEvent tanto al botón como al campo de texto, ya que se debe hacer
lo mismo cuando se pulsa el botón o cuando se pulsa ENTER.
6.2.2 Métodos que se invocan desde el navegador
Un conjunto de métodos de la clase Applet se invocan desde el navegador, respondiendo a
acciones del usuario, como son recargar la página en la que se encuentra el applet o minimizar
su ventana. Tal y como hemos mencionado previamente, estos métodos constituyen lo que se
denomina el ciclo de vida del applet. Son los métodos init(), start(), stop() y
destroy().
Para comprobar el funcionamiento de estos métodos, el siguiente applet los reescribe todos,
haciendo que cuando el navegador llame a cualquiera de ellos se añada en un área de texto
una cadena indicando qué método ha sido llamado. Se ha incluido también el método
paint(), también interesante, aunque es un método heredado de la clase Component.
Listado 6.10 SimpleApplet.java
Applet que comprueba los métodos init, start, stop, destroy y paint
import java.applet.Applet;
import java.awt.*;
public class SimpleApplet extends Applet{
static TextArea text;
public void init() {
if (text == null) {
text = new TextArea(20,20);
text.setEditable(false);
}
add(text);
text.append("Soy un sencillo applet\n");
text.append("init...\n");
}
public void start() {
text.append("start...\n");
}
public void stop() {
text.append("stop...\n");
18
Tema 1. Protocolo HTTP y aplicaciones web
}
public void destroy() {
text.append("destroy...\n");
}
public void paint(Graphics g){
text.append("paint...\n");
}
}
Es interesante comprobar el funcionamiento de este applet en distintos navegadores y en el
appletviewer. Al cargar el applet todos ellos mostrarán:
Soy un sencillo applet... init... start... paint...
Sin embargo, en lo que se refiere a las paradas y recargas del applet podemos comprobar que
en muchos casos el comportamiento es distinto del especificado. Por ejemplo, en el Internet
Explorer 5.0, si pulsamos el botón "reload" o si accedemos a otra página y pulsamos el botón
de "atrás", el applet muestra la secuencia:
... stop... destroy... Soy un sencillo applet... init... start...
Esta secuencia no sigue la especificación original, ya que si salimos de la página y volvemos a
entrar en ella, el applet debería detenerse y volver a comenzar. Esto es:
... stop... start...
Puedes probar también qué sucede si minimizamos la página donde se muestra el applet.
6.3 Seguridad y restricciones de ejecución
6.3.1 Restricciones en la ejecución de los applets
Un appet que ha sido descargado desde una determinada URL no puede hacer ninguna de las
siguientes cosas:
‰
‰
‰
‰
‰
‰
No puede cargar ni definir librerías nativas
No puede leer ni escribir ficheros del computador en el que se encuentra el navegador
que lo está ejecutando
No puede establecer conexiones con otros computadores distintos del que
originalmente ha servido el applet
No puede lanzar ningún programa en el host que lo está ejecutando
No puede leer ciertas propiedades del sistema
Las ventanas que abre un applet deben ser distintas de las que abra una aplicación.
Cada navegador tiene un objeto de la clase SecurityManager que es el encargado de
implementar políticas de seguridad. Cuando un SecurityManager detecta una violación de la
política, envía una excepción del tipo SecurityException.
Por ejemplo, el siguiente listado muestra un applet que intenta escribir un fichero llamado
"writetest". En él se captura la excepción y se muestra un mensaje de error en el que se
reproduce la misma.
19
Tema 6. Programación de applets
Listado 6.11 WriteFile.java
Applet que intenta escribir un fichero en el disco local
import
import
import
import
java.awt.*;
java.io.*;
java.lang.*;
java.applet.*;
public class WriteFile extends Applet {
String myFile = "writetest";
File f = new File(myFile);
DataOutputStream dos;
public void init() {
Label etiq = new Label("");
add(etiq);
String osname = System.getProperty("os.name");
try {
dos = new DataOutputStream(new BufferedOutputStream(
new FileOutputStream(myFile),128));
dos.writeChars("Como mola el curso PAW\n");
dos.flush();
etiq.setText("Escritura correcta del fichero " + myFile);
}
catch (SecurityException e) {
etiq.setText("Excepción de seguridad: "+ e);
}
catch (IOException ioe) {
etiq.setText("Excepción de entrada/salida: " + ioe);
}
}
}
6.3.2 Seguridad en Java 2
En el modelo de seguridad de Java 2 cualquier programa, ya sea local o remoto, está
sometido a una política (policy) de seguridad. Esta política define el conjunto de permisos que
se asocian a lugares (dominios de internet) o firmas digitales, de forma que cualquier código
que se importe de un determinado lugar o venga con una determinada firma digital tiene
asociado los permisos del lugar o la firma. Cada permiso especifica tipos de acceso a un
determinado recurso, como permiso de lectura o escritura para un determinado fichero o
directorio o permiso de acceso a un determinado host. El usuario o el administrador del sistema
puede configurar estos permisos con una variedad de programas que proporciona la
distribución del JSDK.
Aparte de estas funcionalidades relacionadas con permisos, Java 2 proporciona acceso a una
gran variedad de servicios relacionados con criptografía, como son algoritmos de firmas
digitales, algoritmos de generación de claves, servicos de DSA (Digital Signature Algorithm),
etc.
Vamos a ver a continuación cómo configurar el fichero de política de seguridad del sistema
para permitir que el applet anterior escriba el fichero writetest. El objetivo final va a ser
otorgar un permiso de escritura a este nombre de fichero.
Pueden existir varios ficheros de política de seguridad. Todos ellos se definen en el fichero
JAVA_HOME\jre\lib\security\java.security
Todos se especifican con de la siguiente forma:
policy.url.n = URL
Por defecto, existen las dos líneas siguientes:
20
Tema 1. Protocolo HTTP y aplicaciones web
policy.url.1=file:${java.home}/lib/security/java.policy
policy.url.2=file:${user.home}/.java.policy
En estas líneas {java.home} hace referencia al directorio donde está instalado JRE, y
{user.home} hace referencia al directorio home del usuario, que en Windows es el directorio
C:\Windows.
Aunque podríamos añadir tantas líneas como configuraciones de seguridad quisiéramos,
vamos a simplificar el ejemplo y modificar el fichero .java.policy del directorio del sistema
C:\Windows. Para ello debemos ejecutar el programa policytool en el directorio
JAVA_HOME\jre\bin:
> C:\jdk1.3\jre\bin\policytool
Este programa permite editar ficheros de política, añadiendo o modificando permisos a
recursos. Vamos a añadir un permiso de escritura al fichero writetest y vamos a otorgar este
permiso a todo el mundo (es posible restringir el permiso sólo a una URL o a una firma digital).
Para ello debemos seguir los siguientes pasos:
‰
‰
‰
Seleccionar la opción AddPolicyEntry. Dejamos CodeBase y SignedBy en blanco.
El primer campo sirve para otorgar permiso sólo a una URL, y el segundo a una firma
digital.
Seleccionar AddPermission. Rellenar los campos Permission: con la opción
FilePermission, TargetName: con writetest y Actions: con write.
OK, Done y salvar como: .java.policy
Ahora volvemos a ejecutar el appletviewer y veremos que el fichero ya se deja escribir.
6.3.3 Utilización del Java plug-in de Sun
Los navegadores más usados (Internet Explorer y Netscape) implementan una máquina virtual
Java que está bastante anticuada y que no incorpora las nuevas características y
funcionalidades de las nuevas versiones de Java que va desarrollando Sun Microsystems. Para
no tener que depender de las decisiones de las compañías que producen estos navegadores,
Sun ha desarrollado el Java Plug-in, un plug-in que se instala en estos dos navegadores y que
implementa la última máquina virtual Java desarrollada. De esta forma los applets ejecutados
en esta máquina virtual pueden acceder a las últimas funcionalidades de Java, como por
ejemplo el uso de Swing en las interfaces de usuario, o el manejo de la política de seguridad de
Java.
Normalmente, la instalación del Java Plug-in es recomendable en entornos de intranet, donde
podemos tener control de las herramientas que se instalan en los equipos de los clientes, y en
situaciones en las que es obligado usar alguna nueva característica de la última versión de
Java en los applets que hemos desarrollado. Esta instalación es muy sencilla. Las últimas
versiones del Internet Explorer y del Netscape incluso la realizan de forma automática cuando
deben mostrar una página HTML que requiere el Java Plug-in.
En estos momentos la última versión disponible del Java Plug-in es la 1.3. Esta versión es
compatible con la última versión de Java, la Java 2 SDK, v. 1.3.
Algunas de las ventajas de utilizar la versión Java 2 son:
‰
Uso de Swing para las interfaces de usuario de los applets. Este entorno es mucho
más flexible que AWT.
21
Tema 6. Programación de applets
‰
Características de seguridad muy avanzadas. Por ejemplo, la posiblidad de utilizar
certificados RSA para firmar digitalmente los applets.
Conversión de HTML para cargar applets en el Java Plug-in
La etiqueta APPLET hace una llamada a la máquina virtual Java instalada en el navegador. Si
deseamos que un applet sea interpretado por el Java Plug-in es necesario utilizar una nueva
etiqueta. Además esta etiqueta es distinta en el Internet Explorer y en el Netscape Navigator.
En el primero debemos utilizar la etiqueta OBJECT, y en el segundo la etiqueta EMBED.
Una forma muy sencilla de convertir la etiqueta APPLET es utilizando el programa HTML
Converter desarrollado por Sun. Este programa está escrito en Java y transforma las etiquetas
APPLET de los ficheros HTML que le especificamos en etiquetas para que los applets se
ejecuten desde el Java Plug-in.
Para instalar la herramienta debemos descomprimir el fichero htmlconv.zip en algún
directorio, por ejemplo, en C:\programas-java. Después debemos añadir el nuevo directorio
creado que contiene las clases del programa en la variable CLASSPATH:
> CLASSPATH = %CLASSPATH%;C:\programas-java\converter\classes
Ahora ya podemos situarnos en el directorio donde se encuentra el fichero html que deseamos
convertir y llamar al programa HTMLConverter:
> cd C:\applets\WriteFile
> java HTMLConverter WriteFile.html
El programa HTMLConverter guarda entonces el archivo original sonido.html en un nuevo
directorio C:\applets\WriteFile_BAK y lo sustituye por un archivo que contiene las
nuevas etiquetas. También es posible llamar al programa sin especificar ningún parámetro para
que se lance una versión del programa con interfaz de usuario.
Una vez que se ha convertido el fichero HTML, el navegador llamará al Java Plug-in y hará que
éste ejecute el applet. Comprobar cómo ahora el applet WriteFile sí que puede escribir el
fichero writetest.
22