Sunteți pe pagina 1din 358

CURSO DE JAVA

Introduccin a Java

En cuanto sali Java fue acogido con gran entusiasmo por la comunidad mundial
de los diseadores de program as y de los proveedores de servicios internet. Esto
porque Java perm ita a los usuarios de Internet utilizar aplicaciones seg uras e
independientes de la plataform a, y que se pueden encontrar en cualquier punto
de la red.
Java naci pues como lenguaje para la red, para sostener el Hyper Text Markup
Language (HTML), que no es un lenguaje de program acin propiam ente dicho, y
para darle la seguridad que el HTML no tiene. Desde que apareci Java en la red
se ha empezado a hablar de nmeros de tarjetas de crdito y de inform aciones
seguras, lo cual ha entusiasm ado a las m ayores sociedades m undiales que han
transform ado la vieja Internet, prerrogativa de las universidades y centros de
investigacin, en el m edio actual de comunicacin abierto a todos.
El lenguaje de program acin Java se cre a m ediados de los noventa, es el m s
reciente entre sus sem ejantes, y por eso se encuentra en fase de evolucin,
hasta el punto que todos los aos sale una nueva versin.
Creado como lenguaje exclusivam ente para la red se ha convertido en un
autntico lenguaje de programacin paragonable, desde el punto de vista de la
funcionalidad, al famoso C++.

Java y la m ayor parte de los otros lenguajes pueden compararse slo desde el
punto de vista funcional; y esto porque son fundam entalmente diferentes, ya
que Java recopila las fuentes de sus programas en un cdigo llam ado Bytecode
distinto del aparato en el que se ha compilado, mientras que lenguajes como
C++ recopilan las fuentes de los program as en un cdigo que es a su vez cdigo
del aparato (como aparato se entiende ordenador + sistem a operativo) en el que
se ha realizado. Por lo tanto, para poner en m archa un program a Java es
necesario contar con un instrum ento llam ado Java Virtual Machine que interpreta
el bytcode generado por el recopilador Java y lo ejecuta en el aparato en el que
se ha instalado. Gracias al Java Virtual, Java es independiente de la plataforma,
es decir, que el program a recopilado Java est unido a la JVM y no al sistem a
operativo, por eso ser posible poner en marcha el mismo program a Java,
recopilado una sola vez en un aparato cualquiera con un recopilador Java versin
X, en una plataforma Windows y en una plataform a Linux, sin embargo para
hacer eso se necesita que Windows y Linux instalen un aparato Java Virtual que
apoye la versin X de Java. Las dos JVM, instaladas en las dos plataformas
distintas, son el mismo program a recopilado una vez por Windows y otra vez por
Linux, como ocurra con los program as escritos en lenguajes como el C/C++.
Un aparato Java Virtual est instalado tambin en los distintos Browser (como
Netscape y Explorer) para poder poner en m archa los program as Java que se
encuentran en la red, los apliques.
Pero esto, debido a que Java sigue evolucionando, provoca obvios problem as de
compatibilidad, siempre ocurre que el Browser m s moderno contiene una
versin precedente de Java con respecto a la ltima versin de la Sun
Microsystem. Adem s, hay que tener en cuenta que no todos los usuarios de
Internet navegan usando la ltima versin de Netscape o de Explorer. Por eso,
cuando queremos crear un aplique e insertarlo en un documento HTML, hay que
tener en cuenta estos problem as e intentar disear un program a que sea
compatible con la m ayor parte de los JVM implem entados en los distintos
browser.
Otro problem a al que hay que enfrentarse es el de la eleccin del recopilador
Java a utilizar, ya que existen varios ambientes integrados para editar, recopilar,

depurar y ejecutar program as Java, como los de la Broland, de la Microsoft, de la


Sym antec. Todos estos am bientes ofrecen unas herram ientas de desarrollo
excelentes, como editores grficos de ventanas, depuradores m uy interesantes,
pero presentan dos problem as, el primero que valen mucho dinero, el segundo
es el de la compatibilidad, ya que muy a m enudo se encuentran tras la relase de
la Sun y, adem s, aaden unas clases que los JVM en los browser no tienen.
Mi consejo es usar los JDK ( Java Developm ent Kit ) de la Sun, que comprenden
tanto el compilador como el aparato Java Virtual Machine, para poner en m archa
los program as que recopilamos, adem s son freeware (no cuestan nada) y se
pueden bajar de la red y los browser se ajustan a esta versin de Java.
Si queris escribir apliques para los viejos browser tenis que bajar la versin
1.1 de Java, pero esta versin no os sirve m ucho porque existe otra m s
cotizada, es decir la 1.2.2 ( se llam a, por alguna razn que desconozco Java 2,
se puede bajar en la
direccinhttp://java.sun.com/products/jdk/1.2/index.html ), a la que mencionar
yo tambin en este curso y por la que Netscape version 4.0x y Explorer 5
im plem entaron el Java Virtual Machine (casi todo, yo tuve problem as con las
Swing, que son libreras estndar de Java 2).
Si queris bajar Java 2 os aconsejo que lo hagis entre las nueve y las once de
la m aana porque el sitio est muy a m enudo colapsado, adem s el documento
que hay que bajar es de unos veinte megas. Si queris podis bajar tambin la
documentacin pues es muy til, sin embargo, sta tam bin pesa otros veinte
m egas.
Yo acabo de bajar e instalar la prxima versin, la Relase Candidate del Java 2
Software Developm ent Kit versin 1.3 Relase Candidate 1, y os aseguro que si la
1.2.2 era extraordinaria sta es increble. He descubierto tambin que ha salido
la Relase Candidate 2 del JDK 1.3 y que a finales de Abril saldr por fin la relase
(yo la espero, no tengo ganas de pasarm e otra noche en blanco para bajarme
algo que ser sustituido por la relase dentro de m enos de un m es).
Para bajaros el producto tendris que registraros, hacedlo, la registracin es
gratuita.
Un ltimo problem a que tiene Java es la lentitud, ya que, como ya hemos

sealado, el Java tiene que ser interpretado, as las instrucciones Java antes de
ser ejecutadas por el aparato tienen que ser interpretadas por la JVM; es decir,
que para ejecutar cada instruccin el ordenador realizar un nm ero de
instrucciones que es el doble de las instrucciones que realizara si la mism a
instruccin estuviera escrita en C. Por lo tanto, necesitaris ordenadores rpidos
para ejecutar cmodam ente los program as Java, y de esto os habris percatad o
seguramente navegando por la red. Tam bin la m emoria es importante, se
compila y se ejecuta tambin slo con 32MB de RAM, pero para hacer las cosas
con rapidez son necesarios al menos 64, tened en cuenta que el ltimo ambiente
integrado de la Borland, el Jbuilder 3, tiene como requisito m nimo de RAM 96
Megabyte.
Para acabar vuelvo al Java Developm ent Kit de la Sun Microsystem, con ste es
posible producir todo el software que se quiera sin tener que pagar los derechos
de uso del producto, como sucede con el Borland Jbuilder, el Sym antec Cafe, y el
Microsoft Visual Java. Os aconsejo que leais la licencia de uso que encontraris al
bajar el JDK antes de empezar a producir el software.
Llegados a este punto podemos empezar.

La program acin Java

La principal diferencia entre Java y los dem s lenguajes de


program acin por objetos es que con estos ltimos es
posible program ar por objetos, mientras que con Java se
tiene absolutam ente que program ar por objetos. Por eso es
necesario explicar qu quiere decir program ar por objetos.
En concreto la program acin se desarrolla de la m ism a

form a que los lenguajes "norm ales", pero tanto los datos
como las funciones que los trabajan se organizan en
estructuras llam adas clases.
Las clases son prototipos de objetos, es decir, son
estructuras abstractas (no dem asiado, como veremos) que
se pueden instalar y, por eso, crear un objeto (pero tam bin
m s de uno).
La clase define todas las propiedades de los objetos que
pertenecen a aquella clase, llam adas atributos, y las
funciones que se usarn para actuar sobre ellos, llamados
m todos. Por ejemplo es posible definir una clase de las
personas como sigue:
Inicio clase personas
Atributo aodenacimiento
Mtodo calculaedad (aocorriente)
Fin clase personas
La clase de las personas establecida de esta forma tiene un
atributo que es aodenacimiento, que es seguram ente un
nm ero entero, y un mtodo que, basndose en el ao
corriente que le pongamos, calcula la edad de la persona.
Usando el formalismo de Java, para definir la clase personas
tendremos que escribir:
clase personas
{
public ent aodenacimiento;
public ent calcula edad ( ent aocorriente )
{
enva ( aocorriente - aodenacimiento );
}

}
Como acabamos de ver explicamos tanto el mtodo cuanto
el atributo como public. Veremos ahora lo que significa y
veremos tambin la clase em pieza por { y acaba por }, lo
mismo pasa con los m todos. Esto nos recuerda m ucho al C,
y hay que decir que la sintaxis de Java es m uy sim ilar, casi
igual, a la de C, mientras que para los que no conocen el C,
los corchetes representan el empezar y el terminar del
lenguaje pascal. La clase tendr un llam ado constructor (uno
o m s) que es un mtodo peculiar que norm almente se
utiliza para inicializar los atributos cuando se establece la
clase de un objeto. Es una funcin que no tiene ningn tipo
de return y tiene el mismo nombre que la clase. Decimos
que puede haber ms de un constructor, sin embargo, el
nombre del constructor tiene que ser el m ismo que el de la
clase. A los que estn acostumbrados a program ar con
lenguajes no orientados a los objetos, todo esto les puede
resultar algo raro, sin em bargo es posible porque Java
realiza el llam ado overloading de funciones, es decir
funciones con el mismo nombre que tienen parm etros
diferentes (en el lenguaje inform tico se llam an parm etros
form ales) son distintas, y a la hora de establecerlas se elige
la funcin basndose en el parm etro (llam ado parm etro
actual).
Esto vale para todos los m todos, no slo para los
constructores.
clase personas
{
public ent aodenacimiento;
public String Apellidos=new String();

// Constructores
public personas(ent aodenacimiento)
{
this("No s");
this.aodenacimiento=aodenacimiento;
}
public personas(String Apellidos)
{
this(0);
this.Apellidos=Apellidos;
}
public personas(ent aodenacimiento , String Apellidos)
{
aodenacimiento=aodenacimiento;
this.Apellidos=Apellidos;
}
// Funcin que calcula la edad del sujeto;
public int calculaedad ( ent aocorriente )
{
return ( aocorriente - aodenacim iento );
}
}

Las lneas que empiezan por // son comentarios, el


ordenador los ignora, pero hay otros dos tipos de
comentarios, los que se ponen entre /* y / que perm iten
definir com entarios sobre m s de una lnea. Se llam an
comentarios de documentacin y se tienen que encontrar

antes de la declaracin de las clases, de los miembros de las


clases (atributos o m todos) o de los constructores, y hay
que inclurlos en la posible documentacin del cdigo que se
genera autom ticam ente.
En el ejemplo vemos que hay tres constructores, distintos
por parm etros formales, que tienen el mismo nombre.
Adem s vemos un nuevo atributo que son los Apellidos, sa
es una cadena, que se define como public String
Apellidos=new String(); la parte que est delante del signo
igual resulta clara, la parte que se encuentra a la derecha
del m ismo signo un poco m enos, ese new String() crea un
nuevo objeto de la clase String y llam a a su vez al
constructor que no tiene parm etros. Esto es el
procedim iento tipo que usa Java para crear los objetos de
una clase. No hay que sorprenderse de que el tipo de dato
cadena sea una clase, porque con Java es posible usar
objetos que representen todos los tipos de datos del
lenguaje, insertadoos para completar el lenguaje, y llam ados
confecciones que a veces resultan muy tiles. Si em bargo,
es posible usar tambin los valores.
As, por ejemplo, trabajaremos tanto con enteros como con
objetos que representan enteros. Por ltimo, resulta
bastante evidente en el ejemplo que los constructores tienen
voluntariam ente unos parm etros que tienen a su vez el
mismo nombre de los atributos. Esto tambin es posible en
Java y quiere decir que cuando hay un valor a la izquierda
del signo igual tiene que encontrase el atributo, y a la
derecha el parm etro. De todos modos si no queremos
confundirnos podemos usar la referencia this; escribiendo,
por ejemplo, this.aodenacimiento, esto quiere decir
atributo. This se refiere al objeto, y en el ejemplo anterior lo

encontramos tambin como llam ada a la funcin this(0), en


este caso se refiere a un constructor del objeto y se llam ar
constructor personas (ent aodenacim iento), con el valor 0.
Es por tanto posible en un constructor llam ar a un
constructor distinto de la m isma clase, con tal que la llam ada
sea la prim era instruccin del constructor y que el
constructor sea diferente del actual.
Llegados a este punto, estamos listos para crear objetos que
pertenezcan a la clase que acabamos de definir. Tenemos
tres formas de hacerlo porque hemos creado tres
constructores que son:
personas Pietro=nuevas personas(1974);
o
personas Pietro=nuevas personas("Castellucci");
o
personas Pietro=nuevas personas(1974,"Castellucci");
ahora queremos crear otro objeto de la clase personas
personas Lina=nuevas personas(1975);
o
personas Lina=nuevas personas("Marucci");
o

personas Lina=nuevas personas(1975,"Marucci");


a este punto he creado dos objetos de la clase personas que
tienen que ver con la llamada clase inst_of, los objetos se
llam an uno Pietro y el otro Lina. Tambin es posible copiar
las referencias de los objetos, por ejemplo es posible
escribir:
personas Pietro2=Pietro;
Construidos los objetos puedo crear los mtodos, indicando
Objeto.Mtodo. Por ejemplo es posible crear los m todos:
Pietro.calculaedad(2000);
Pietro2.calculaedad(2000);
Lina.calculaedad(2000);
Ahora introduzcamos unos atributos y unos m todos
particulares, los llamados miem bros estticos. Por como
hem os definido los miem bros de la clase, no nos resulta
posible hacer una referencia directa de la clase atributo s y
m todos ( personas.aodenacimiento es un error), y esto
porque estos trabajan sobre una instancia de la clase, es
decir sobre un objeto, pero a veces puede ser til escribir
m todos y atributos que se puedan crear sin tener que
llam ar al objeto, y que puedan ser llam ados directam ente
desde la clase. Para hacer esto necesitamos declararlos
estticos, por ejemplo:
clase TtulosEmpresaEquis
{
public static int TipodeInters=3;

public String Propietario=new String();


public static float InteresesDevengados (int Perodo)
{
return((Perodo * TipodeInters )/100)
}
TtulosEmpresaExis(String nombre)
{
Propietario=nombre;
}
}
Entonces podremos decidir, por ejemplo, llam ar a un objeto
de la clase TtulosEmpresaExis slo si nos conviene, por
ejem plo haciendo:
if (TtulosEmpresaEquis.InteresesDevengados(12)>1000)
CompraAcciones(10000);
Donde CompraAcciones (int X) es una funcin que llam a X
TtulosEmpresaEquis.
Introduzcamos ahora la relacin is_a entre clases.
Establecida una clase, es posible crear una nueva clase
partiendo de sta haciendo, como se dice en nuestra jerga,
una especializacin de la prim era clase. La nueva clase que
creamos est relacionada is_a con la prim era. Creada una
clase estudiante de la clase (llam ada superclase) personas,
la nueva clase hereda de la prim era todos los mtodos y los
atributos, con la posibilidad de definir unos atributos y unos
m todos nuevos o de volver a definir otros. En Java, la
estensin de una clase se m anifiesta con la palabra clave
extends.

clase estudiante extends personas


{
ent inscripcin;
// Constructores
public estudiante(ent aodenacimiento)
{
super(aodenacimiento,"No Conocido");
}
public estudiante (String Apellidos)
{
super(0,Apellidos);
}
public estudiante(int aodenacimiento , String Apellidos)
{
super(aodenacimiento,Apellidos);
}
}
Como vemos en el ejemplo, la clase estudiante hereda todos
los m todos y los atributos de la clase personas, define un
nuevo atributo inscripcin, y en sus constructores llam a a los
constructores de la clase personas con el nombre de
super.().
Super() puede ser, como this(), una llam ada de otro
constructor (entre parntesis van los parm etros posibles) o
una referencia a la clase (a la superclase en este caso).
Entonces, super.aodenacimiento representa el atributo
aodenacimiento de la superclase personas. Las relaciones

is_a y inst_of son las dos relaciones ms importantes de los


modelos por objetos. Ahora, en conclusin, ponemos un
ejem plo que comentaremos a continuacin para explicar el
significado del public que introducimos anteriorm ente, y del
private y protected (los atributos y los m todos pueden
llam arse public, private y protected).
clase A
{
public int a;
private int b;
protected int c;
// Sus m todos, atributos y constructores
}
clase B extends A
{
public float a;
private float b;
protected float c;
// Sus m todos, atributos y constructores
}
clase C
{
// Sus m todos, atributos y constructores
}
Hemos definido tres clases, A,B y C, B se define partiendo de
A volviendo a definir los tres atributos, de enteros a reales.
En A, en sus constructores y en sus m todos, tenemos aceso
a los mismos atributos de tipo entero, sin limitaciones, es

decir, podemos escribirlos y leerlos a nuestro antojo.


En B y C pasa lo mismo con los propios atributos, pero
vamos a ver lo que sucede para los de las dem s clases.
Por ejemplo, en B (en uno de sus m todos) si escribimos
expresiones con a,b y c, escribiremos unas expresiones pera
unos float (en Java es m uy importante el tipo de las
expresiones). Sin embargo, para referirnos a los atributos
homnimos de A de la que se ha heredado, tenemos que
escribir, como sabemos, super.a, super.b y super.c (que son
unos enteros).
Nuestro compilador Java no dar problem as para las
prim eras dos, pero nos dar error para el tercero. Esto
porque el c de A est protegido (protected) que quiere decir
que es posible leer y escribir aquel atributo slo
internamente a la calse a la que pertenece, pero no es
posible leerlo y escribirlo de clases ajenas o de subclases.
Llegados a este punto metmonos en un mtodo de C,
establezcamos un objeto de la clase B (lo llam amos b) y
escribamos las expresiones b.a, b.b y b.c. Nuestro simptico
compilador nos dar slo la prim era porque la tercera est
protegida y, por eso, slo es visible en la clase a la que
pertenece. La segunda es privada (private) y esto significa
que es visible slo para la clase a la que pertenece y para
sus subclases, y C no es una subclase de B.
Anteriormente hicimos una trampa, es decir, hablamos de
atributos de clases y de objetos como si fueran la mism a
cosa, pero realm ente lo son. Slo hay una pequea
diferencia. Si entramos en un atributo de una clase (
NOBRECLASE.NOMBREATRIBUTO ) este ser seguram ente
esttico, y podemos entrar slo para leer, es prcticamente
una constante. Cuando estabezcamos la clase en un objeto
(NOMBRECLASE NOMBREOBJETO= new NOMBRECLASE

(parm etros); ), entrando en el m ismo atributo del objeto (


NOMBREOBJETO.NOMBREATRIBUTO ) entramos en el mismo
valor de antes y no podemos modificarlo (es static). En
cambio, si intentamos entrar en un atributo no esttico de
una clase, tendremos un error. Realm ente este atributo se
crear en el mismo momento de la creacin del objeto de la
clase, y la m ayora de las veces ser inicializado por el
constructor del objeto.
Espero haber tratado el argum ento con claridad, pero hay
que decir que los modelos por objetos son bastantes
complicados y es imposible explicarlos en detalle en un solo
prrafo, se necesitara un entero curso. Obviam ente lo que
acabamos de decir no es todo sobre los modelos por objetos.
Simplem ente introducimos unos conceptos que nos valdrn
para hacer nuestros program as en Java. Los puntos
im portantes que hemos olvidado tratar en este apartado,
sern introducidos m s adelante cuando se presente la
ocasin.
Al lector que quiera profundizar el argumento no le puedo
aconsejar ningn libro en concreto porque hay varios sobre
este tem a y todos son buenos. Sin embargo, si os
conform is con una introduccin al tem a, podis mirar los
captulos iniciales de cada buen m anual de program acin
para principiantes de Lenguajes por objetos (C++ o Java),
como, por ejemplo, Java: Didctica y Program acin de
K.Arnold e J.Gosling (Ed. Addison-Wesley) Captulos 2,3 y 4.
Os pido sobre todo que sea un m anual para principiantes
porque en los libros de program acin avanzada el tem a se
da por descontado.

Qu son los paquetes inform ticos de Java

Los paquetes inform ticos son colecciones de clases, contenidas


en una coleccin que las une. Prcticam ente son bibliotecas a
las que el usuario puede acceder y que ofrecen varias funciones.
Los usuarios pueden tambin crear paquetes inform ticos, por
ejem plo, haciendo que contengan todas las clases que ha
definido para poner en marcha algunas funciones que luego
usar en varios programas. Sin embargo, esto no nos interesa
porque lo que queremos es ver los paquetes inform ticos ms
interesantes en Java.
Esta es la autntica potencia de Java, el nmero de clases ya
establecidas que realizan las m s variadas tareas, y es tambin
la parte que sigue creciendo m s y m s, y que sigue poniendose
al da con las nuevas versiones de Java (JDK 1.3 bien contiene
18Mb). Los paquetes inform ticos de Java son tantos que slo
describir algunos por encima en un captulo entero (el captulo
3) del curso. Veremos de form a detallada ms o m enos dos, es
decir, los que nos sirven para definir interfaces grficas y
apliques. Obviam ente todos los paquetes inform ticos del
lenguaje estn descritos en la m astodntica gua en lnea del
JDK que se puede bajar junto al paquete del compilador (La JDK
Documentation 1.3 beta es de 105 Megabyte, comprimida es de
unos treinta Megas). sta tambien es gratuita y, si os apetece
pasar un par de horas bajndola, os aconsejo que la cojis junto
al compilador. De todas form as est a vuestra disposicin en
lnea (tenis el enlace en la
pginawww.javasoft.com o www.java.sun.com , es
prcticam ente igual, son primos hermanos).

El ncleo del lenguaje Java contiene slo las palabras claves


para la construccin de las clases, los comentarios, las
construcciones normales en if, switch, while, do-while, for,
etiquetas, break, continue e return (falta el goto), que veremos
en detalle en el prximo captulo. Todo lo dem s est
contenidos en los paquetes inform ticos del lenguaje, incluidas
las norm ales primitivas de Entrada y de Salida. En este prrafo
veremos la lista de los paquetes inform ticos de Java y veremos
uno en particular, el que nos interesa para escribir nuestra
prim era aplicacin Java an antes de haber visto las
construcciones, es decir, en las que podemos encontrar las
instrucciones de entrada y salida.
La lista completa de los paquetes inform ticos de Java 1.2.1 en
orden alfabtico es el siguiente:
com.sun.im age.codec.jpeg,
com.sun.java.swing.plaf.windows,com .sun.java.swing.plaf.motif
, java.applet, java.awt, java.awt.color, java.awt.datatransfer,
java.awt.dnd, java.awt.event, java.awt.font, java.awt.geom,
java.awt.im , java.awt.im age, java.awt.im age.renderable,
java.awt.print, java.beans, java.beans.beancontext, java.io,
java.lang, java.lang.ref, java.lang.reflect, java.m ath, java.net,
java.rmi, java.rm i.activation, java.rm i.dgc, java.rm i.registry,
java.rmi.server, java.security, java.security.acl,
java.security.cert, java.security.interfaces, java.security.spec,
java.sql, java.text, java.util, java.util.jar, java.util.zip,
javax.accessibility, javax.swing, javax.swing.border,
javax.swing.colorchooser, javax.swing.event,
javax.swing.filechooser, javax.swing.plaf,
javax.swing.plaf.basic, javax.swing.plaf.m etal,
javax.swing.plaf.multi, javax.swing.table, javax.swing.text,

javax.swing.text.html, javax.swing.text.htm l.parser,


javax.swing.text.rtf, javax.swing.tree, javax.swing.undo,
org.omg.CORBA, org.omg.CORBA.DynAnyPackage,
org.omg.CORBA.ORBPackage, org.omg.CORBA.portable,
org.omg.CORBA.TypeCodePackage, org.omg.CosNaming,
org.omg.CosNam ing.Nam ingContextPackage,
sun.tools.ttydebug, sunw.io, sunw.util.
Realm ente parecen pocos, parece que haya dicho una tontera
cuando me refera a la potencia de Java, sin embargo si pensis
que slo el paquete informtico Java.io comprende 50 clases y
10 interfaces, comprenderis que los de antes son una coleccin
de clases consistente.
Llegados a este punto nos gustara hacer la entrada y la salida
de consolle y para hacerlo debemos usar el paquete inform tico
java.lang .
para usar un paquete inform tico en una de nuestras clases,
antes de definir la clase, tenemos que introducir la instruccin
im port. Por ejem plo, si queremos usar el paquete inform tico
java.awt tenemos que introducir al comienzo de nuestro
archivo:
im port java.awt.*;
El * indica que queremos usar todas las clases, en cam bio si
queremos usar slo una clase lo podemos especificar, por
ejem plo, import java.awt.Fram e; podremos usar la clase Fram e
del awt. En nuestro caso, en el que queremos hacer una
operacin de entrada, tendremos que declarar al empezar
im port java.lang.*;
o, sabiendo que la clase del paquete informtico java.lang que
contiene los m todos para hacerlo es System, podremos escribir

im port java.lang.System ;
La clase System , a su vez, contendr en su interior una import
java.io (que es el paquete inform tico para la entrada y la
salida) para acceder a las clases de la entrada y de la salida, y
las usar para m andar lo que queramos en la pantalla.
Vimos un ejemplo de paquete inform tico que en su interior
llam a a otro paquete inform tico para que lleve a cabo unas
tareas. En estas bibliotecas Java ocurre eso a m enudo y es
precisam ente este fenmeno que hace de Java un lenguaje
incomprensible para la mayora. Sin embargo, superado este
inconveniente que se refiere a este aspecto del lenguaje, la
program acin se hace fcil e inm ediata.
He introducido el paquete inform tico java.lang. Ahora os digo
tam bin que este es el m s importante de Java, en ste estn
contenidos las clases fundamentales del lenguaje, hasta el
punto de que no hace falta declarara el import, porque Java lo
introduce autom ticam ente.
Adem s me gustara detenerm e en un aspecto fundam ental de
la introduccin de los paquetes inform ticos. Si importo en mi
archivo el paquete inform tico java.lang, ste importar a su
vez el paquete inform tico java.io, y yo desde mi archivo no
podr usar las clases de java.io; para hacerlo tengo que
im portarlo explcitam ente. Esto sucede aunque programe una
aplicacin en m s de un archivo (con m s clases), en cada
archivo tengo que importar los paquetes inform ticos que
necesito para la clase que estoy estableciendo, no basta con
im portarlos en una sola. Veamos pues las clases que contiene
este paquete inform tico java.lang tan importante para el
lenguaje:

Boolean
hem os dicho que los tipos de datos se pueden representar
tam bin con objetos dichos;
contenedores
es una clase que genera los contenedores para los tipos de
datos boolean (verdadero, falso).
Byte
es la clase que genera los contenedores para los tipos de datos
enteros cortos (de un byte).
Character
es una clase que genera los contenedores para los tipos de
datos caracteres.
Character.Subset
es la clase que genera los contenedores para los tipos de datos
caracteres con codificacin unicode.
Character.UnicodeBlock
es la clase que genera los contenedores para los tipos de
caracteres con codificacin unicode 2.0.
Class
representa las clases y las interfaces a runtime (en ejecucin),
en Java es posible, en tiempo de ejecucin, crear, ejecutar y
compilar clases. El compilador y el ejecutor se m ezclan de una
form a rara, sin embargo a nosostros no nos sirven estas clases
"especiales" porque escribiremos unas aplicaciones fciles.
ClassLoader

cargador de clases a tiempo de ejecucin.


Compiler
compilador de clases a tiempo de ejecucin.
Double
es la clase que genera los contenedores para los tipos de datos
reales en coma mvil de 64 bit.
Float
es la clase que genera los contenedores para los tipos de datos
reales de 32 bit en com a mvil.
Integer
es la clase que genera los contenedores para los tipos de datos
enteros.
Long
es la clase que genera los contenedores para los tipos de datos
enteros dobles.
Math
contiene m todos que simulan funciones matem ticas.
Num ber
clase de objetos contenedores de nm eros genricos.
Object
es la clase de la que derivan todas las clases del lenguaje Java,
es decir, cada clase es subclase (no necesariam ente directa) de
sta.

Package
contiene m todos para extrapolar inform aciones en los paquetes
informticos de Java.
Process
Java es un lenguaje que permite gestionar Thread, es decir
pequeos program as que corren en paralelo. Esta clase se
ocupa de ellos, como las dem s clases de java.lang: Runtim e,
Runtim ePermission, Thread, ThreadGroup, ThreadLocal,
Throwable
SecurityManager
para la seguridad
Short
es la clase que genera los contenedores para los tipos de datos
enteros cortos.
String
es la clase que genera los contenedores para los tipos de datos
cadenas de caracteres.
StringBuffer
es la clase que genera los contenedores para los tipos de datos
cadenas de caracteres modificables.
System
es la clase que interacta con el sistem a y contiene muchos
m todos tiles, y unas referencias a otras clases (llam adas class
field), es la que usaremos, por ejemplo, para crear una salida
sobre la pantalla a caracteres.

Void
es la clase que genera los contenedores para los tipos de datos
void, es decir, sin tipo. ste parece un tipo de dato intil, sin
embargo veremos que no lo es en absoluto, adem s es
utilsimo. En realidad, es til cuando queremos definir un
m todo-procedimiento (un m todo que no tiene valor de
vuelta), en Java existen slo dos funciones que obligan a
devolver un valor del tipo que declaran. Declarando un m todo
como void, se simula el procedimiento, es decir, no se necesita
la vuelta.

Escritura de apliques "a consola"

Me doy cuenta de que toda la parte descriptiva hasta ahora


pudo resultar un poco aburrida y estoy de acuerdo con
vosotros pero, estoy seguro de que m e vis a disculpar
porque los conceptos introducidos son FUNDAMENTALES
para el apartado m enos aburrido que est a punto de
empezar, es decir, la program acin.
Sin em bargo, antes de empezar tengo que decir una ltim a
cosa: con los actuales lenguajes de program acin es posible
hacer dos tipos de program as, excluidas las bibliotecas
dinmicas (.DLL) o estticas (.LIB) y varias, es decir, las
aplicaciones a consola y las aplicaciones a ventanas. Las
prim eras son las m s simples de construir porque no tienen
grfica y no tienen interfaz de caracteres: son las que se

parecen a las viejas aplicaciones DOS, o javac.exe m ismo (


el compilador Java ). Las segundas son las Windows o XWindows, con todos los botones, m ens, etc., m s
complicadas de hacer, pero extrem adam ente ms
agradabledes de ver. Con Java es posible hacer, adem s de
stas dos, una tercera aplicacin, la que trabaja en Red, es
decir el aplique. Al principio Java naci slo como un
lenguaje para la Red, pero sucesivam ente se vi que era un
lenguaje completo con el que era fcil escribir tam bin
aplicaciones a consola y a ventanas. Yo tam bin estoy
preparando mi tesis de licenciatura en inform tica usando
Java y es una aplicacin a ventanas. Las primeras
aplicaciones que vamos a ver son, por cierto, las ms
sim ples, aunque las menos sorprendentes, es decir, las
aplicaciones a consola.
Una aplicacin puede estar compuesta por una o ms clases,
todas incluidas en homnimos archivos, simplem ente por
una cuestin de simplicidad de bsqueda, aunque es posible
definir ms de una en un archivo y llam ar los archivos con
nombres distintos de las clases que se encuentran en ellos.
Pero, si escribimos una aplicacin a consola o una a
ventanas, hay una clase especial que un archivo del mismo
nombre tiene que contener. Esta clase que llam ar, por
ejem plo, hola tendr un m todo, que se llam a main,
que representa el punto de entrada del program a, es decir,
es el punto desde el que se iniciar la ejecucin del
program a.
Cuando un program a en Java se redacta, dar uno o m s
archivos .class, entre ellos, en nuestro caso, estar tambin
nuestro hola.class. Para poner en m archa el program a
tendremos que teclear:

java hola [ENVO]


Hay que notar que los viables Java no son .EXE, sino .class,
esto porque para que se pongan en m archa necesitan la ya
citada Java Virtual Machine que es, precisam ente, el
program a java.exe. Pongamos un ejemplo:
class hola
{
public static void m ain(String[] args)
{
// Com entario, este program a no hace nada.
}
}
Vemos que main se declara static void, static porque se
acude a l al principio de la JVM, antes de que hola se
ponga autom ticam ente en un objeto, void porque no
devuelve nada. Esta clase la escribir en un archivo que
llam amos hola.java y la redactar escribiendo javac
ciao.java NB: Es absolutam ente obligatorio llam ar a los
archivos fuentes de Java con la extensin .java, sino el
compilador no los reconoce. Adems si cre hola.java
TENGO que teclear javac hola.java y no javac hola para
compilarlo.
Como parm etro el m todo m ain tiene una cadena que se
llam a args que representa los parm etros con los que se
pone en m archa el program a, por ejemplo, si escribo,
despus de redactarlo, hola en hola.class
java hola Pietro Castellucci
args[0] ser igual a Pietro

args[1] ser igual a Castellucci


Esto cuando se pone en marcha. Hay que notar tambin que
la JVM java.exe pone en m archa hola.class especificando
sim plemente java ciao. A diferencia del compilador
javac.exe, si tecleamos java hola.class nos da error, si
queris podis intentarlo.

Nuestro prim er program a en Java

Lo que estamos a punto de hacer, no es realm ente nuestro


prim er program a en Java: algunos los hicimos precedentemente
y ste es el prim er program a que Java puede trabajar.
Vamos a usar lo que vimos en el precedente prrafo para crear
una aplicacin a consola y las del prrafo anterior para escribir
algo en la pantalla.
Em pezamos por editar un archivo que llam aremos
HolaMundo.java: cuidado con las m aysculas y las minsculas
porque en Java son muy importantes, no slo para el program a,
sino tambin para los archivos. Adem s espero que tengis un
editor que apoye Java porque, si editis con el edit de DOS, no
tendris ninguna ayuda a la hora de escribir los program as. En
cambio, con el editor especializado tendris las indentificaciones
hechas ad hoc, distintos colores para las palabras claves, para los
comentarios, etc.
Podis bajar gratuittam ente unos editores creados precisam ente

para Java o adaptados a Java en red. Podis buscar en el


sitio http://om ega.di.unipi.it de la facultad de Inform tica de
Pisa, en Resources - ftp, o en los varios sitios de la tucows
( www.tucows.com ), en el que encontraris el bluette (una
versin demo) que tiene un buen editor. Simplem ente os
recomiendo que tengis cuidado porque en ste caso el bluette es
un compilador Java, pero no s si es totalmente compatible con
el Java de la SDK que estoy tratando yo. En nuestro archivo
HolaMundo.java escribiremos:
class HolaMundo
{
public static void m ain(String[] args)
{
System .out.print ("Hola mundo, soy el primer program a en
Java");
System .out.println ("di "+args[0]+" "+args[1]);
}
}
Redactamos el program a escribiendo, como siempre, java
HolaMundo.java y ahora podemos ponerlo en marcha.
Escribiremos:
java HolaMundo TUNOMBRE TUSAPELLIDOS
y veremos una salida parecida a sta:

Hola m undo, soy el primer program a en Java de TUNOMBRE TUS


APELLIDOS
Si no ponemos el nombre y los apellidos, el program a dar una
excepcin, que es parecido a un error a runtim e, debido a que en
el m ain se citan arg[0] y arg[1] que no aparecen. estas
excepciones s son errores a runtim e, pero se pueden prever y
gestionar precisam ente porque Java es un lenguaje "seguro" y,
m s que interrumpirse y dar el norm al RUNTIME ERROR que dan
los dem s lenguajes, da una excepcin que, si prevista por el
program ador, no interrumpe el program a. En el siguiente captulo
veremos como gestionar posibles excepciones y, tam bin, como
utilizarlas para nuestros fines. Pensem os, por ejemplo, en un
program a que lee de los archivos y que no encuentra este
archivo: Java dar su excepcin, nosotros la leem os y haremos
que lea otro archivo. La versin sin riesgos de excepciones y m s
espectacular es la siguiente:
class HolaMundo2
{
public static void m ain(String[] args)
{
System .out.println
("*************************************************")
;
System .out.println ("** Hola mundo, soy el primer program a
en Java **");
System .out.println

("*************************************************")
;
System .out.println (" |||||");
System .out.println ("0/ x x \\0");
System .out.println (" | o |");
System .out.println (" |\\___/|");
System .out.println (" |_____|");
}
}
Llegados a este punto, slo m e queda felicitaros: acabis de
escribir vuestro prim er programa en Java. Si os parece poco, no
os procupis: a partir del capttulo sucesivo veremos las
construcciones y entonces nos desahogaremos escribiendo todos
los program as que queramos.

Tipos prim itivos de Java y valores

Llam amos tipos prim itivos de un lenguaje cuando hablamos de


tipos de datos ya definidos en el lenguaje y de los que se
puede partir para la construccin de expresiones o tipos de
compuestos.
Los tipos son muy importantes en todos estos lenguajes de
program acin y son fundam entales en Java que es un lenguaje
que se basa m ucho en los tipos. El concepto de tipo es muy

natural: si veo un nm ero, por ejemplo, 15.4 puedo decir en


seguida el conjunto de nmeros al que pertenece, en este caso
al conjunto de los nmeros reales.
Si veo una operacin 4 / 5 puedo decir:
4 es de entero entero 5 es de tipo entero y / es una funcin de
dos enteros y que me devuelve un nmero real. Se escribe as:
/ : ent x ent float
Entonces, puedo decir que toda la expresin 4/5 es de tipo
entero.
Lo que acabamos de hacer es, m s o m enos, una inferencia de
tipos que es una prctica muy utilizada en inform tica. Para
explicarla toda se necesitara, como con los modelos por
objetos, un curso entero.
Los problem as no surgen con estas expresiones, que se llam an
cerradas, que no tienen variables, sino con las que tienen
variables. Cada lenguaje emplea una tcnica suya: algunas
usan los tipos para las expresiones, otras establecen el tipo
partiendo del contexto de la expresin y da un tipo en
secuencia incluso por cada una de las expresiones, y los que,
como Java, obligan a declarar todos los tipos de todas las
variables desde el principio. Los tipos primitivos de Java son los
mismos de los dem s lenguajes de program acin, slo que
difieren un poco en los valores y son.
boolean
es decir, valores que pueden ser verdaderos o falsos
char los caracteres son de 16 bit y estn codificados en

Unicode 1.1.5; en los dem s lenguajes son ASCII solam ente de


8 bit.
byte
enteros de 8 bit con signo, es decir, nmero entre menos (dos
a la sptim a) y dos a la octava.
short
enteros de 16 bit con signo.
int
enteros de 32 bit con signo.
long
enteros de 64 bit con signo.
float
reales de 32 bit con coma mvil (IEEE 754-1985).
double
reales de 32 bit con coma mvil (IEEE 754-1985).
Obviam ente, a partir de stos es posible definir nuevos tipos de
datos que se llam an compuestos. Por ejemplo, una cadena es
un vector de caracteres y es un tipo compuesto.
Como vimos el la leccin precedente, en el paquete java.lang
estn los contenedores para estos tipos de base, es decir, que
si escribo ent, me refiero a un nmero entero, mientras que si
escribo Enteger m e refiero a las clases enteros.
Si uso las clases, tendr tambin una serie de atributos y
m todos tiles para trabajar con ellos. Por ejemplo, en alguans

se definen las constantes MIN_VALUE y MAX_VALUE (Mnimo y


m ximo valor), en las clases Float y Double encontraremos las
constantes NEGATIVE_INFINITY y POSITIVE_INFINITY, NaN
para indicar un valor que no es vlido y el m todo isNan() para
controlar si un valor es vlido. Por ejemplo, se puede utilizar
despus de una divisin para controlar que no se haya hecho
una divisin por cero que resultara catastrfica. Todo esto no
existe en los dem s lenguajes de program acin.
Ahora vam os a ver los literales de cada tipo de Java, es decir
los valores constantes que cada tipo puede tener.
El nico literal para referirnos a los objetos es null, se puede
utilizar cada vez que nos esperamos una referencia a un
objeto, null es un objeto que no se ha creado y no es vlido:
no es de ningn tipo.
Los literales booleani son verdaderos y falsos e indican,
respectivam ente, el valor cero y el valor falso.
Los literales enteros son cadenas de cifras octales, decim ales o
exadecim ales. El inicio de la constante sirve para escribir la
base del nmero: un cero inicial indica base ocho, 0x o 0X
indica base 16 y nada indica los decimales. Por ejemplo, el
nm ero 15 en base diez puede representarse como:
15 como decim al
017 como octal
0xf o 0XF como esadecim al.
Las constantes enteras que terminan por l o L se consideran
long. Es mejor que terminen por L porque l se confunde
fcilmente con la unidad (no se equivoca el compilador, pero s

nosostros que leem os los program as) y si no acaban por una


letra se consideran como ent. Si un leteral ent se escribe como
un short o como un byte, ste se porta como si lo fuera.
Los literales con coma mvil se escriben como nmeros
decimales, con un punto opcional seguido, posiblem ente, por
un exponente que empieza por e, segn la prctica corriente
para indicar mantisa-exponente. El nmero puede llevar detrs
una f (F) o una d (D) para indicar que es, con precisin, simple
o doble, para default es doble.
35, 35. , 3.5y1, .35y2 representan el mismo nmero.
El cero puede ser positivo o negativo, si los comparamos
obtenemos la equivalencia. Sin embargo, es til en los
clculos, pensemos en 1d/0d y 1d/-0d.
No es posible conceder una constante doble a una float aunque
est en la serie. Si queremos hacer esta operacin, hay que
hacer un cam bio que se llama casting que analizarem os a
continuacin.
Los caracteres se ponen entre comilla como, por ejemplo, '2', y
los caracteres especiales estn representados por unas
secuencias, llam adas secuencias de escape. Son:
\n newline, a parte
\t tab
\b backspace, borra a la izquierda
\r return, representa el carcter especial ENVIO

\f form feed
\\ es el carcter backslash
\' comilla
\" comillas
\ddd es un char que emplea el valor octal (d son cifras octales,
por ejemplo \329, tienen que ser de tres o m enos cifras y
m enores de \377), se puede dar tambin la representacin
exadecim al, siem pre de cuatro cifras. Aqu ponemos en orden
los caracteres citados antes con su nmero exadecimal:
\u000A, \u0009, \u0008, \u000D, \u000C, \u005C, \u0027 y
\u0022.
Las cadenas se escriben entre com illas, como por ejemplo
"Pietro" y todas las secuencias de escape vlidas se pueden
introducir en una larga cadena, creando cosas interesantes
como, por ejemplo:
System .out.println("\tNombre:\tPietro\n\tApellido:\tCastellucci
" );
dar este resultado:
Nom bre: Pietro
Apellido: Castellucci

Variables

Las variables son valores modificables, es decir, son nombres que representan un
valor de cierto tipo y el valor asociado al nombre se puede variar. Por ejemplo, si
digo que X es una variable de tipo entero y despus digo que tiene valor 10,
escribiendo la expresin 5 + X es como si escribiera la expresin 5 + 10. De todas
form as creo que todos vosotros tenis familiaridad con las variables porque son lo
principal de cada lenguaje de program acin. Dicho esto, vamos a ver como Java
trata las variables.
En prim er lugar, antes de utilizarla, una variable se tiene que escribir. En Java la
escritura de una variable est compuesta por tres partes: modificadores, tipo e
indentificadores.
Los modificadores son una opcin y son los que establecen el acceso a las
variables, es decir, a los public particulares y protegidos que vimos en el captulo
anterior. stos se llam an modificadores de acceso y los hay estticos, sincronizados
y finales. No es importante ponerlos en rden, aunque s es importante utilizar
siempre el mismo rden para que sea legible el cdigo. Esttic tambin lo vimos:
nos permite escribir atributos y mtodos constantes que se pueden invocar incluso
antes de que un objeto se escriba. Final, en cambio, quiere decir que, cuando se
utiliza un valor, ste se puede unir slo una vez a un campo porque es tambin una
constante. El modificador sincronizado lo dejaremos de lado: basta con indicar que
sirve para decir que a un mtodo, en el caso de una multiprogram acin (con los
thread), se puede acceder a travs de una exclusin mltiple, es decir, un thread a
la vez.
Los identificadores pueden ser uno o m s, estn separados por una com a y son
nombres que tienen variables. Por ejemplo, la escritura de X en el ejemplo anterior
se convertir en:

ent X;
pero, tambin puedo escribir m s de uno. Por ejem plo, la siguiente escritura se
considera vlida:
ent X,Y,Z;
doble W=3.12;
Como son atributos de las clases tienen que escribirse dentro de los m ismos;
escribirlos fuera de ellos se considera un error.
Como se puede ver en el ejemplo, tambin es posible inicializar una variable en el
momento en el que la creamos: sm plem ente hay que aadir, despus del nombre,
el signo igual y el valor que tom a.
Despus de la escritura de la variable y su inicializacin, el identificador de la
variable, en cualquier lugar que se haya escrito, se entiende como su valor actual,
excepto si le damos un nuevo valor. Por ejemplo, si escribo X = 10 m e refiero a la
variable X y no a su valor, y con el signo igual 10 m e refiero a que el nuevo valor
de la variable es 10.
Si despus escribo:
X = X+1;
con la X a la izquierda del signo igual m e refiero a que la variable se llam a X,
mientras que con la X a la derecha me refiero al valor actual de la variable X. La
expresin X+1, entonces, en este caso ser
10 + 1 y entonces 11, es decir por X = X + 1, he dicho X = 11;
Provad este pequeo program a que hace unos calculos:
class p

{
ent X,Y,Z;
double W = 3.12;
public double A = 15;
static int B = 101;
private final int C = 2;
protected static boolean D = true;
public p()
{
X= 10 ;
Y= X ;
Z= X + Y ;
System .out.println ("Al\'principio tengo: X="+X+", Y="+Y+", Z="+Z);
X= X + 1 ;
Y= Z - X;
System .out.println ("Hago las operaciones: \nX= X + 1 ;\nY= Z - X;\ned
resultado:");

System .out.println ("X="+X+", Y="+Y+", Z="+Z);


}
}
class decl
{
public static void m ain(String[] a)
{
p Prueba=new p();
}
}
Como sabis, visto que decl es la clase que incluye el main, tendris que editar el
program a en un archivo que se llam a decl.java; despus, ponedlo en m archa y a
ver lo que ocurre. Hay tambin otros atributos para mostrar el uso de los
modificadores.
En el ejemplo vemos que yo cre una clase p y le puse el objeto Prueba, llam ando
al constructor. Hice esto porque las variables son atributos y, por eso, si no son
estticos, son atributos de un objeto. Tuve que crear un objeto para poder trabajar
con sus variables. Hay que acostumbrarse a program ar desde esta perspectiva
porque los program as Java son todos as. Como el m ain del programa TIENE que
declararse static (y tiene que tener una cadena como parm etro), ste se pone en
m archa en ausencia del objeto y, por eso, algunas variables no son estticas. Si
hubiera querido crear solo una clase, hubiese tenido que escribir algo parecido a:
class decl2

{
int X,Y,Z;
// Main
public static void m ain(String [] a)
{
decl2 Prueba=new decl2();
}
// Constructor
public decl2()
{
X= 10 ;
Y= X ;
Z= X + Y ;
System .out.println ("Al\'inicio tengo: X="+X+", Y="+Y+", Z="+Z);
X= X + 1 ;
Y= Z - X;
System .out.println ("Hago las operaciones: \nX= X + 1 ;\nY= Z - X;\ned
resultado:");
System .out.println ("X="+X+", Y="+Y+", Z="+Z);

}
}
En este segundo ejemplo, editado y redactado en decl2.java, no se entiende bien
cundo vemos decl2 como clase y cundo como objeto. Realm ente el main est en
la clase y en l se crea el objeto. Por tanto se invoca el constructor y dentro de l
razonamos en trminos de objeto creado. De todas form as, es posible y veris que
el program a funciona tam bin en este caso. Algn da, cuando tengis m s
fam iliaridad con el lenguaje, podris hacerlo vosostros tam bin. De momento no os
lo aconsejo porque es fundam ental, llegados a este punto, distinguir bien entre
clases y objeto, y esto se consigue fcilm ente con mucha experiencia.
Los identificadores Java tienen que empezar por una letra (o con _ o $) seguida por
una secuencia larga de caracteres y cifras elegidas a vuestro antojo. Las cifras,
codificadas en Unicode, son mucho m s num erosas que las letras y que las cifras
ASCII utilizadas por otros lenguajes. Lo siento, pero no tengo un m apa completo de
los caracteres unicode que dejaros, pero puedo deciros que estn incluidos los
caracteres griegos, cirlicos, rabes, etc.
Ahora vam os a ver cmo escribir e inicializar un array. La escritura se hace
ponindo un par de corchetes despus del tipo:
ent [] vectorDeEnteros;
Los array en Java son casi objetos, slo que no pueden extenderse para aadirles
nuevos m todos. Lo que acabamos de citar es una referencia a un array que, sin
embargo, rl lenguaje no ha asignado. Si quiero inicializar el array elem ento por
elem ento, como se hace con los dem s lenguajes, tengo que escribir las
dim ensiones:

ent [] vectorDeEnteros = nuevo ent[100];


A partir de ahora puedo empezar a poner los elem entos en el vector, en las
posiciones de 0 a 99. Si salgo de estos nmeros, el aparato nos dar unm ensaje de
excepcin del tipo out of range.
Cuando creo, puedo adem s inicializar un array, basta con escribir:
ent [] vectorDeEnteros = { 1,2,3,10,100,555,0, .otros valores};
Adem s puedo crear unos vectores cuyos elementos son ellos mismos vectores,
etc. Esto se consigue de esta form a:
double[] [] m atrizIdentidadDerden3 = { { 1.0 , 0.0 , 0.0 } ,
{ 0.0 , 1.0 , 0.0 } ,
{ 0.0 , 0.0 , 1.0 } };
El siguiente program a utiliza los array y lo editarem os en un archivo que se llama
vect.java:
clase vect
{
static ent NOMBRE = 0;
static ent APELLIDOS = 1;
static ent PATODNALD=0;
static ent GILBERTO=1;
static ent JORGITO=2;

static ent JAIMITO=3;


static ent JUANITO=4;
static ent GUS=5;
static ent COMISARIO=6;
static ent RATN=7;
static ent SUPER PATO=8;
static ent PLUTO=9;
static ent ABUELA=10;
static ent GILITO=11;
static Cadena personajes[][] = {
{"Paolino","Pato Donald"},
{"Pietro","Gilberto"},
{"Jorgito","No especificado"},
{"Jaimito","No especificado"},
{"Juanito","No especificado"},
{"Ciccio","De Abuela Donald"},
{"No especificado","Comisario"},
{"No especificado","Ratn Micky"},
{"Tribiln","No especificado"},
{"Pluto","No especificado"},
{"No especificado","Daisy"},
{"No especificado","Gilito"},
};

public static void m ain(String [] a)


{
ent PersonajeTmp;
ent Nm ero=1;
System .out.println ("Unos personajes de Walt Disney");
PersonajeTmp=PATODNALD;
System .out.println("Nm ero:"+Nm ero+"\tNombre:"+personajes[PersonajeTmp][N
OMBRE]+" Apellidos:"+personajes[PersonajeTmp][APELLIDOS]);
Nm ero=Nm ero+1;
PersonajeTmp=GILBERTO;
System .out.println("Nm ero:"+Nm ero+"\tNombre:"+personajes[PersonajeTmp][N
OMBRE]+" Apellidos:"+personajes[PersonajeTmp][APELLIDOS]);
Nm ero=Nm ero+1;
PersonajeTmp=JORGITO;
System .out.println("Nm ero:"+Nm ero+"\tNombre:"+personajes[PersonajeTmp][N
OMBRE]+" Apellidos:"+personajes[PersonajeTmp][APELLIDOS]);
Nm ero=Nm ero+1;
PersonajeTmp=JAIMITO;

System .out.println("Nm ero:"+Nm ero+"\tNombre:"+personajes[PersonajeTmp][N


OMBRE]+" Apellidos:"+personajes[PersonajeTmp][APELLIDOS]);
Nm ero=Nm ero+1;
PersonajeTmp=JUANITO;
System .out.println("Nm ero:"+Nm ero+"\tNombre:"+personajes[PersonajeTmp][N
OMBRE]+" Apellidos:"+personajes[PersonajeTmp][APELLIDOS]);
Nm ero=Nm ero+1;
PersonajeTmp=GUS;
System .out.println("Nm ero:"+Nm ero+"\tNombre:"+personajes[PersonajeTmp][N
OMBRE]+" Apellidos:"+personajes[PersonajeTmp][APELLIDOS]);
Nm ero=Nm ero+1;
PersonajeTmp=COMISARIO;
System .out.println("Nm ero:"+Nm ero+"\tNombre:"+personajes[PersonajeTmp][N
OMBRE]+" Apellidos:"+personajes[PersonajeTmp][APELLIDOS]);
Nm ero=Nm ero+1;
PersonajeTmp=PLUTO;
System .out.println("Nm ero:"+Nm ero+"\tNombre:"+personajes[PersonajeTmp][N
OMBRE]+" Apellidos:"+personajes[PersonajeTmp][APELLIDOS]);

Nm ero=Nm ero+1;
PersonajeTmp=TRIBILN;
System .out.println("Nm ero:"+Nm ero+"\tNombre:"+personajes[PersonajeTmp][N
OMBRE]+" Apellidos:"+personajes[PersonajeTmp][APELLIDOS]);
Nm ero=Nm ero+1;
PersonajeTmp=GILITO;
System .out.println("Nm ero:"+Nm ero+"\tNombre:"+personajes[PersonajeTmp][N
OMBRE]+" Apellidos:"+personajes[PersonajeTmp][APELLIDOS]);
Nm ero=Nm ero+1;
PersonajeTmp=RATN;
System .out.println("Nm ero:"+Nm ero+"\tNombre:"+personajes[PersonajeTmp][N
OMBRE]+" Apellidos:"+personajes[PersonajeTmp][APELLIDOS]);
System .out.println("HiCe los clculos "+Nm ero+" personajes, y eran muchos
m s");
// ste s es un program a realmente intil. El autor.
}
}
Un pequeo com entario sobre el program a. Os habis dado cuanta de que en el
m ain se establecen unas variables (es posible hacerlo): norm almente se usan sin
redactarlas como static porque las variables del m ain, o de una funcin, por lo

general, no son atributos y, por eso, no estn relacionados con el objeto o con la
clase, sino slam ente con la funcin en la que se escriben. En estas definiciones no
estn incluidos los modificadores porque estos se asocian a las clases.
Llegados a este punto nos queda por ver los tipos compuestos que se pueden
fcilmente identificar ahora con las clases. Por ejemplo, si queris definir el tipo
compuesto Complejos, escribiremos:
clase Complejos
{
private double ParteReal;
private double ParteImaginaria;
Complejos (double Re, double Im)
{
ParteReal=Re;
ParteImaginaria=Im;
}
// ahora estableceremos todos nuestros obvios m todos en el nuevo tipo
double dmeParteReal()
{
return ParteReal;
};
double dmeParteIm aginaria()
{
return ParteIm aginaria;
};

double calculaMdulo()
{
return (java.lang.Math.sqrt((ParteImaginaria*ParteIm aginaria)+
(ParteReal*ParteReal)));
};
}
Para probar, podis escribir los siguiente(pruebaComplejos.java):
clase pruebaComplejos
{
public static void m ain (Cadena[] arg)
{
Complejos N=nuevo Complejos(3.0,1.1);
double Re=N.dm eParteReal();
double Im=N.dm eParteImaginaria();
double mod=N.calculaMdulo();
System .out.println("Nm ero complejo:"+Re+"+i"+Im +" tiene "+mod);
}
}

Operadores

Los operadores del enguaje Java son los mismos que los de
los dem s lenguajes, adem s cada nuevo tipo tendr su
proprio m todo que incluyen nuevos operadores, como
vim os en el ejemplo de la clse Complejos.
Analizamos los operadores de acceso a las clases y a los
objetos, es decir, simplem ente el punto. Si queremos entrar
en el campo X del objeto x, simplem ente tendremos que
escribir x.X, aunque x tenga un mtodo Y(ent valor),
nosostros entramos o, mejor en este caso, lo solicitamos
escribiendo x.Y(39); Tenemos los operadores aritmticos de
siempre: +,-,*,/ y %.
Hay que tener en cuenta tam bin las operaciones son
tipadas, es decir, si sumo dos enteros el resultado es un
valor entero y as para todas las operaciones, de form a que
si tenemos una expresin siempre es posible establecer el
tipo de resultado.
Java ejerce un fuerte control sobre los tipos. De hecho, no es
posible asignar un carcter e un entero, lo que es posible en
el lenguaje C, y adem s es imposible asignar un double a un
float sin un casting explcito. El casting obliga a un valor de
un tipo a tener un tipo distinto. Si escribo 5, m e refiero a un
entero, mientras que si hago un cast a float me refiero a la
versin de 5 real y para hacerlo tendr que escribir(float) 5.
De esta form a puedo asignar los enteros a reales y de reales
double a relaes float. Pensemos, por ejemplo en:
double v1=10.0;

float v2;
ent v3=5;
y pensemos en las siguientes asignaciones equivocadas:
v2=v1;
v1=v3;
Si hacemos unos cast, se convierten en exactas tambin
para Java:
v2=(float) v1;
v1=(double) v3;
Hay que notar la divisin de los enteros que en otros
lenguajes da un entero. Por lo tanto, si queremos el nm ero
real que resulta de la divisin de los dos nm eros enteros x
e y, antes hay que transform arlos en nm eros reales:
float resultado= (float ) x / (float) y;
Para las cadenas hay un operador de encadenamiento:
cadena a="Pietro " ;
Cadena b= a + "Castellu";
Cadena b+="cci"
El resultado ser Pietro Castellucci. El operador es el signo
+. En un momento dado, utilizamos una asignacin
particular, es decir, += que es una abreviacin. Si tengo que
escribir a=a+1; puedo abreviar y escribir a+=1, que es lo
mismo. Lo mismo vale para cada operador binario. El

operador + cuelga de una cadena tambin caracteres y


nm eros, pensemos en las salidas de los ejemplos anteriores
en los que escribamos, por ejemplo:
System .out.println("Nm ero complejo:"+Re+"+i"+Im +"
tiene mdulo "+mod);
esto os puede parecer raro, sobre todo si consideramos que
dijimos que las expresiones Java estn bien caracterizadas
por los tipos, a diferencia del C. Esto ocurre, sin embargo,
porque el sistem a hace unas conversiones implcitas de tipos
primitivos y objetos en cadenas. Por ejemplo, si
establecemos cualquier objeto y lo hacemos con un m todo
toString(), el sistem a tendr que trabajar con cadenas y con
este objeto solicitar automticamente el m todo toString().
Adem s Java ofrece otros cuatro operadores que son unas
abreviaciones: dos son de incremento de variables y dos de
incremento. Si X es una variable puedo escribir:
X++
++X
X---X
Esto quiere decir: prim ero evalua X y luego increm enta X,
prim ero increm enta X y luego evalua X, primero evalua X y
luego disminuye X y , por ltimo, primero disminuye X y
luego evala X. Esto quiere decir que la expresin X++ es
un m ando de asignacin, pero tambin una expresin que
devuelve un resultado que, en este caso, es X antes de que
se incremente.

Por ejemplo:
X=10;
Y=X++;
dar como resultado X=11 e Y=10. Intendad editar y poner
en m archa lo siguiente clase incdec
{
public static void m ain(Cadena [] a)
{
ent X,Y,Z,W,V;
X=10;
System .out.println("X="+X);
Y=X++;
System .out.println("Y=X++: tengo X="+X+",Y="+Y);
Z=++Y;
System .out.println("Z=++Y: tengo Z="+Z+",Y="+Y);
W=Z--;
System .out.println("W=Z--: tengo W="+W+",Z="+Z);

V=--W;
System .out.println("V=--W: tengo V="+V+",W="+W);
}
}
Otros operadores son los de comparacin, es decir:
> m ayor de, x>y nos da verdadero si x es m ayor que y, en
caso contrario, nos da falso
>= m ayor o igual a, x>=y nos da verdadero si x es m ayor o
igual a y, en caso contrario nos da falso
< m enor de, x<y nos da verdadero si x es menor de y, en
caso contrario, nos da falso
<= m enor o igual a, x<=y nos da verdadero si x es menor o
igual a y, en caso contrario, nos da falso
== igual a, x==y nos da verdadero si x es igual a y, en caso
contrario, nos da falso
!= diferente, x!=y nos da verdadero si x es diferente de y,
en caso contrario, nos da falso
Tenemos tambin los operadores lgicos &&, || y !, que
representan la conjuncin y, la disjuntiva o y el no:
Establecidos los valores booleanos x e y , x && y ser
verdadera si x e y lo son tambin; ser falsa si no lo son (si
las dos son falsas o si una es verdadera y la otra falsa).

x || y sar vedadera si x o y o los dos son verdaderas (ser


falsa slo si los dos son falsos). !x ser verdadera si x es
falsa, mientras ser falsa si x es verdadera.
Tenemos los operadores binarios orientados hacia los bit :
&, AND bit a bit
| , OR bit a bit
^, OR EXCLUSIVO, bit a bit
y los shift, >>, <<, >>>.
Estas operaciones binarias son muy tiles para construir las
m atrices.
El ltimo operador es el condicional que nos permite definir
expresiones con dos diferentes resultados segn un valor
booleano.
Pongamos el siguiente ejemplo:
ent ValorAbsoluto = ( a<0 ? -a : a );
ValorAbsoluto tendr el valor -a si a es negativo o si a es
positivo o nulo.
Llegados a este punto, podemos escribir todas las
expresiones que queramos en lenguaje Java.

Instrucciones

Estamos preparados para ver los constructores principales


del lenguaje Java. Ya vimos los comentarios, que no se
pueden ocultar, es decir, que el siguiente comentario no es
posible: /* +ste es seguram ente un com entario /* ste
tam bin lo es */ */ Sin embargo, se pueden introducir
comentarios de una lnea en los com entarios de m s de una
lnea porque son distintos. Por ejemplo, es posible escribir lo
siguiente: /* ste es seguram ente un com entario // ste
tam bin lo es */ aunque realm ente resulte bastante intil.
Las prim eras instrucciones de Java que vamos a ver son las
instrucciones de declaracin, que son las declaraciones de
variables locales. Se utilizan para declarar variables y darles
un posible valor inicial. Estas instrucciones ya las vimos y se
parecen a las declaraciones de los atributos, excepto por la
falta de los modificadores. Las variables locales, antes de ser
utilizadas, se tienen que inicializar.
Las variables locales se pueden declarar en un punto
cualquiera de un bloque y no necesariam ente al inicio,
adem s existen slo en los bloques en los que se declaran.
Un bloque es como una instruccin, lo nico es que empieza
por { y acaba por }, y en l puede tener muchas
instrucciones, incluso posiblemente de otros bloques.
{
instruccin 1;
instruccin 2;
.
instruccin j-1;
{
subinstruccin1;

subinstruccin2;
..
subinstruccin;
}; // es la instruccin j
instruccin j+1;
.
instruccin n;
}// Este bloque puede ser el cuerpo de un mtodo o un
bloque
Pensad en el m todo:
void tribiln()
{
ent j=0;
{
ent k=0;
k++; // instruccin A
};
j++; // instruccin B
k++; // instruccin C
}
La instruccin A no da problem as porque usa una variable
local que est inicialidada, declarada en su mismo bloque.
Con la instruccin B ocurre lo mismo, mientras la instruccin
C est equivocada porque la variable que utiliza se ha
declarado en un bloque entero y no se puede ver
externam ente. Si en el bloque interno hubiera escrito j++;
no tendra ningn problema porque la variable j se habra
declarado en un bloque externo. (Dentro se ve lo que hay
fuera, pero fuera no se puede ver lo que hay dentro, lo cual
ocurre en todos los lenguajes de program acin por bloques).
Acabamos de ver en el ejem plo que tambin j++ es tanto

una instruccin como una expresin, como su otra form a e


++j, y es su im agen especular de dism inucin. Hay otras
operaciones que se pueden tener en cuenta a la hora de
analizar las instrucciones. Se trata tanto de la
im plem entacin de los m todos que pueden devolver o no
un valor, como de las instrucciones de creacin de objetos,
las que llevan new. Por ejemplo, new Object(), es una
instruccin correcta.
Otra instruccin muy parecida a una expresin es la
instruccin de asignacin, la del tipo:
Nom breVariable = expresin;
Por lo tanto, hasta ahora hemos visto las seis instrucciones:

Declaracin de una variable local;

Bloque;

Formas de increm ento y disminucin de las variables,


prefijas y postfijas;

Creacin de los objetos;

Solicitud de los mtodos;

Asignacin de las variables;


Todas las instrucciones terminan por ;

Las dem s instrucciones se llam an constructos y son muy


parecidas a las de los dem s lenguajes de program acin. Las
vamos a ver detalladam ente.
Instruccin condicional
if (EXPBOOL) IST
Esta instruccin pone en m archa la instruccin llam ada IST
que puede ser una cualquier instruccin del lenguaje slo si
la expresin booleana EXPBOOL es verdadera, de lo
contrario se salta. Una variedad es la en que pone en
m archa otra instruccin si EXPBOOL es falsa, es:
if (EXPBOOL) IST
else
IST2
Fijaos que IST y IST2 son instrucciones generales, por lo
tanto tam bin los bloques o las dem s instrucciones
condicionales. En este ltimo caso hablamos de if ocultos.
Instruccin switch
Switch (EXP)
{
case CST11: . :case CST1n: IST1
case CST21: . : case CST2n: IST2
.
case CSTm1: . : case CSTmn: ISTm
default ISTm +1;
};

Si EXP es una expresin, CSTij son unas constantes del


mismo tipo que la expresin. EXP y ISTi son unas
instrucciones.
La instruccin evala EXP, y compara el resultado con las
constantes de los case; si encuentra otro igual, pone en
m archa la instruccin correspondiente. Si, en cambio, no
encuentra ninguna constante igual, pone en marcha la
instruccin despus del default, lo que es una opcin. En el
caso de que est ausente y ningn case tenga la c onstante
igual al valor de EXP, se salta el switch.
Analizamos, por ejemplo, el siguente m ando:
switch (5+1)
{
case 6 : System .out.println ("Muy bien");
default : System.out.println ("Burrp, es seis");
};
Instruccin for for (exp de inicializacin; exb booleana; exp
de increm ento) ISTR
pone en m archa la instruccin ISTR que es un nm ero de
veces igual a los valores contenidos en un intervalo.
Norm almente la instruccin de inicializacin pone en m archa
una variable en un valor; la variable se increm enta (o
dism inuye) a partir de la instruccin de increm ento y en la
expresin booleana se controla que la variable tenga los
valores que queremos. En efecto, si la expresin booleana es
falsa, enseguida se sale del ciclo for.
Voy a poner un ejem plo: quiero inicializar los valores de un
vector de 100 enteros todos a cero. En lugar de escribir 100
asignaciones, escribir:

ent v = new ent[100];


for (ent e = 0 ; e<100; e++) v[e] = 0 ;
Como acabamos de ver la variable tambin se puede
declarar en la instruccin de inicializacin. De esta form a,
slo se puede ver en el for.
Instruccin while
while (EXPBOOL) IST
Pone en m archa IST simulando que EXPBOOL es verdadera,
por ejemplo, la inicializacin del ejemplo anterior se puede
llevar a cabo con el while de la siguiente form a:
ent v = nuevo ent[100];
ent e=0;
while (e<100) {
v[e]=0;
e+=1;
};
o de forma comprim ida, aprovechando el increm ento de
form a comprimida:
ent v = nuevo ent[100];
ent e=0;
while (e<100) v[e++]=0;
Instruccin do-while do IST while (EXPBOOL);
ES como el while, slo que antes ejecuta la instruccin y
luego controla el EXPBOOL, de nuevo la inicializacin
precedente se convierte en:

ent v = nuevo ent[100];


ent e=0;
do {
v[e]=0;
e+=1;
} while (e<100);
o tambin de form a todava m s comprimida:
ent v = nuevo ent[100];
ent e=0;
do v[e++] = 0 while (e<100);
Etiquetas
Es posible poner etiquetas a las instrucciones, como ocurre
con el cdigo assembler. Esto resulta m uy til en
combinacin con las instrucciones de break y de continue:
etiqueta: instruccin;
instruccin de break
La instruccin de break se utiliza para salir de un bloque o
de un switch; cuando se encuentra un break se sale del
bloque m s interno, m ientras que si se pone una etiqueta,
se sale hasta donde la etiqueta se ha declarado.
Ejem plo:
{
while ( COND )
{
while (COND2)

{
if (ALGO) break;
}
}
}
En este caso se sale del while interior, mientras:
{
tribiln: while ( COND )
{
while (COND2)
{
if (ALGO) break tribiln;
}
}
}
se sale de los dos while.
Instruccin de continue
En un ciclo se salta todas las instrucciones que le siguen y
evala directam ente la expresin booleana, por ejemplo:
while (Condicin)
{
instrucciones;
if (GolpeDeEfecto) continue;
otras instrucciones;
};
Se entra en el ciclo, se ponen en marcha las instrucciones. Si
GolpeDeEfecto es verdadero, salta otras instrucciones y llega
a evaluar Condicin. Si sta tambin es verdadera, contina

el ciclo poniendo en marcha las instrucciones, etc..


Instruccin de return
Produce la conclusin de la ejecucin del m todo en el que
se encuentra y el retorno a la llam ada. Si el m todo es void
basta con escribir return, si no tiene que contener una
expresin del mismo tipo del m todo, por ejemplo
ent tribiln()
{
return 10;
}
con la instruccin return es posible tambin bloquear la
puesta en marcha de un constructor o de un m todo static.
Con esto acabamos nuestro exam en de las instrucciones.
Ahora estamos preparados para construir cualquier
aplicacin a consola.
Pongamos un par de ejemplos: em pecemos escribiendo un
pequeo program a que imprima los prim eros nmeros, los
m enores de 500 de la famosa serie de Fibonacci. Para los
que no la conozcan, la serie de Fibonacci es una secuencia
infinita de nm eros cuyos dos prim eros elem entos son: 1, 1,
y los dems elem entos se calculan como la sum a del e-1
simo nm ero y del e-2 simo, formalm ente, reconociendo
Fibo com e una funcin:
Fibo ( e ) = Fibo ( e - 1 ) + Fibo ( e - 2 );
El program a que hay que escribir en Fibo.java es el
siguiente:

class Fibo
{
public static void m ain (Cadena[] args)
{
ent bajo=1, alto=1;
// ent alto=1;
System .out.println (bajo);
while (alto<500)
{
System .out.println(alto);
alto+=bajo;
bajo = alto - bajo;
};
}
}
Para que os entrengis, podis intentar hacer un program a
que calcula 10 ! , sabiendo que 1! = 1 y que establecido n
entero, n! = n * ((n-1)!). La solucin se encuentra en el

archivo Fatt.java.
Ahora, intentamos escribir nuetra criba de Eratstenes hecho
en casa, es decir, una forma para calcular todos los nmeros
primos hasta un nm ero establecido, digamos 100;
El algoritmo procede as,
1 es un nm ero primo.
2 es un nm ero primo, le quito sus mltiplos
3 es un nm ero primo, le quito sus mltiplos
etctera hasta encontrar mi mximo.
clase Eratstenes
{
static ent MX=1000;
ent [] nmeros = nuevo ent[MX];
boolean [] primos = nuevo boolean[MX];
public Eratstenes()
{
ent e;
for (e=0;i<MAX;e++)
{
nm eros[e]=e+1;
primos[e]=verdaderos;
};

}
void elMul(ent a)
{
for (ent j=2;j*a<=MX;j++)
primos[(j*a)-1]=falso;
}
ent siguiente(ent n)
{
ent tmp=n;
while (!primos[tmp]) {
tmp++;
if (tmp>=MX) break;
}
return tmp+1;
}
void calculaPrimos()
{
ent nm=2;
while (nm <=MX)
{
elMl(nm);
nm =siguiente(nm );

};
}
void escribaPrimos()
{
System .out.println("Los nmeros primos hasta "+MX+"
son:");
for (ent e=0; e < MX ; e++)
if (primos[e]) System .out.print(nmeros[e]+" ");
}
public static void m ain(Cadena[] args)
{
Eratstenes e = nuevo Eratstenes();
e.calculaPrimos();
e.escribaPrimos();
}
}

Indicaciones sobre las excepciones y sobre los thread

Las excepciones son una form a clara para controlar los


errores sin confundir el cdigo con muchas instrucciones de
control del error. Cuando se verifica un error se pone en
m archa una excepcin que, si se recibe enseguida, nos
perm ite gestionar un error. De lo contrario, el soporte lleva a
cabo como ejecucin de Java, un ter de default.
En Java hay una clase que se llam a Exception, y las
excepciones son objetos que pertenecen a esta clase. Por
eso, se pueden trabajar como verdaderos componentes del
lenguaje.
Vamos a ver cmo es posible crear una excepcin.
Hay que crear una clase que ampla Throwable, o m ejor
Exception , que es una extensin de Throwable.
Supongamos que queremos crear una excepcin para decir
que utilizamos una cadena vaca: tendremos que escribir:
public clase ErrorCadenaVaca ampla Exception
{
ErrorCadenaVaca()
{
super("Cuidado, ests utilizando una cadena que no ha sido
inicializada");
}
}
Esta clase tiene que estar en un archivo que se llam a como
la clase, es decir, ErrorCadenaVaca.java Despus de haberla

creado, necesitaremos una form a para hacerla trabajar, es


decir, para evidenciar la situacin de error que, ya que
estam os, espero que alguien recoja. Las excepciones
trabajan con la instruccin throw que tiene que estar en un
m todo que, a su vez, se tiene que declarar con un clusola
throws. Por ejemplo, en nuestro caso, si quiero crear un
m todo para imprimir la cadena que controla incluso el
error, escribir en mi clase:
public void Imprim ir (Cadena a)
throws ErrorCadenaVaca /* Esto quiere decir que esta
funcin puede poner en m archa una excepcin del tipo
ErrorCadenaVaca*/
{
if (a==null) throw nuevo ErrorCadenaVaca();
else System .out.println(a);
}
Entonces, llegados a este punto, el mtodo Imprim ir enviar
a la pantalla la cadena transform ada en parm etro y dar un
excepcin de tipo ErrorCadenaVaca si el puntero era nulo.
La excepcin que damos nosotros se llama excepcin
controlada y tiene que ser obligatoriamente gestionada,
mientras las que da Java no necesariam ente tienen que ser
recogidas y gestionadas.
Ahora vam os a ver como recoger las excepciones, por
ejem plo, nuestra ExcepcinCadenaVaca.
Las excepcines se recogen cuando se solicitan los m todos
que se declaran con la clusula throws. Para recogerlas hay
que implem entar el m todo en bloques try que tienen la
siguiente sintaxis:

try
BLOQUE // ste es un bloque peligros porque puede poner
en m archa unas excepciones. catch (Tipo de Excepcin que
hay que coger)
BLOQUE // ste es un bloque de restablecimiento. catch
(Tipo de Excepcin que hay que coger)
BLOQUE // ste es un bloque de restablecimiento.
.
finally
BLOQUE
El corpus de esta instruccin se ejecuta hasta el final o hasta
que aparezca una excepcin. En caso de excepcin, se
analizan las clusulas catch para ver si existe un
adm inistrador para esa excepcin o para una de sus
superclases. Si ninguna clusula catch recoge esa excepcin,
sta vuelve a lanzarse en el m todo que la ha provocado
(que la ha ejecutado).
Si en el try hay una clusula finally, su cdigo se pone en
m archa despus de que se hayan completado todas las
dem s operaciones del try, independientem ente de que sta
haya ejcutado una excepcin o no. Por ejemplo, nuestro
m todo Imprim ir se puede invocar as:
Si X es la cadena que hay que imprimir:
try {Imprim ir(X);}
catch (ErrorCadenaVaca e)
{System .out.println ("Lo siento");}
En este caso, si X es nulo, se pondr en m archa la excepcin
y se recoger; despus se imprimir la cadena Lo siento, si

no X. Si escribiera Imprimir(X) fuera de la try, saldra error


porque las excepciones que yo he causado tienen que ser
recogidas. Esto obliga al program ador a escribir cdigo
"bueno". Las excepciones de Java, en cambio, se pueden
coger o no.
El ejemplo siguiente recoge el HolaMundo del primer captulo
que, si invocado sin parm etros, daba una excepcin de
ArrayIndexOutOfBoundsException, que, este vez, se
gestiona;
clase HolaMundo
{
public static void m ain(Cadena[] args)
{
System .out.print ("Hola Mundo, soy el primer program a en
Java");
Cadena Nombre;
Cadena Apellidos;
try {Nombre=args[0];}
catch (ArrayIndexOutOfBoundsException e)
{Nombre="No has introducido tu Nombre";}
;
try {Apellidos=args[1];}
catch (ArrayIndexOutOfBoundsException e)
{Apellidos="No has intruducido tus Apellidos";}
;

System .out.println ("de "+Nombre+" "+Apellidos);


}
}
Intenten ponerlo en m archa de las siguientes form as:
java HolaMundo Nombre Apellidos
java HolaMundo Nombre
java HolaMundo
y a ver lo que pasa. Hagan lo mismo con el HolaMundo del
prim er captulo.

El paquete java.lang

El Paquete lang
Este paquete lo vimo antes. Ahora, sin embargo,
analizaremos algunas funciones que antes no vimos. En
prim er lugar, hay que decir que ste es uno de los paquetes
m s importantes de la API Java. Abarca muchsim as clases e
interfaces fundam entales para la program acin Java, tanto
que este paquete se incluye atom ticam ente en nuestros
program as. Su contenido es::

Intefaces
Cloneable
Comparable
Runnable
Clases
Boolean
Byte
Character
Character.Subset
Character.UnicodeBlock
Class
ClassLoader
Compiler
Double
Float
InheritableThreadLocal
Integer
Long
Math
Num ber
Object
Package
Process
Runtim e
Runtim ePermission
SecurityManager
Short
String
StringBuffer
System
Thread

ThreadGroup
ThreadLocal
Throwable
Void
Excepciones
Arithm eticException
ArrayIndexOutOfBoundsException
ArrayStoreException
ClassCastException
ClassNotFoundException
CloneNotSupportedException
Exception
IllegalAccessException
IllegalArgumentException
IllegalMonitorStateException
IllegalStateException
IllegalThreadStateException
IndexOutOfBoundsException
InstantiationException
InterruptedException
NegativeArraySizeException
NoSuchFieldException
NoSuchMethodException
NullPointerException
Num berForm atException
Runtim eException
SecurityException
StringIndexOutOfBoundsException
UnsupportedOperationException
Errores

AbstractMethodError
ClassCircularityError
ClassForm atError
Error
ExceptionInInitializerError
IllegalAccessError
IncompatibleClassChangeError
InstantiationError
InternalError
LinkageError
NoClassDefFoundError
NoSuchFieldError
NoSuchMethodError
OutOfMemoryError
StackOverflowError
ThreadDeath
UnknownError
UnsatisfiedLinkError
UnsupportedClassVersionError
VerifyError
VirtualMachineError
En el prim er captulo vimos las clases que incluyen los tipos
primitivos incluidos en este paquete. En este apartado
analizaremos unas clases que hacen cosas m s complejas.
La prim era clase que analizaremos es la clase System , que
relacciona nuestro program a Java con el sistema en el que
se pone en marcha. En prim er lugar, la clase System incluye
tres atributos estticos que son:
static PrintStream err static InputStream in static
PrintStream out

Estos program as representan respectivam ente el error


estndar, el input estndar y el output estndar (que ya
utilizam os). Son atributos particulares porque son de tipo
clase, por eso se pueden utilizar como referencia para
capturar los m todos de las clases, por ejemplo, en la
escritura:
System .out.println("Hola");
Se invoca el m todo println(String) de la classe PrintStream ,
porque out es de tipo PrintStream . En nuestros ejemplos,
utilizam os indiferentemente las expresiones:
System .out.println("Hola");
System .out.println(verdadero);
System .out.println(10);
System .out.println('C');
En general, en Java esto no es posible porque un mtodo se
invoca a travs de un parmetro form al. Esto no es una
excepcin. De hecho, invocar el m todo println con todos
estos tipos de datos distintos es posible porque PrintStream
incluye todos los m todos println utilizados con el parm etro
form al adecuado. As sta incluye:
void println()
void println(boolean x)
void println(char x)
void println(char[] x)
void println(double x)
void println(float x)

void println(int x)
void println(long x)
void println(Object x)
void println(String x)
los mismos m todos print, y por supuesto, otros.
Lo mismo vale para err, que es tam bin parecido a un out
del tipo PrintStream . ste se usa para evidenciar los errores
de program a. Es bastante fcil encontrar expresiones como
las siguientes en los programas:
try {System .out.println(cadena+" vs "+otracadena+" = "
+cadena.compareTo(otracadena));}
catch (nullPointerException e)
{System .err.println("ERROR: La segunda cadena es
nula");};
En cam bio, el atributo in es del tipo InputStream , y
representa, como dijimos antes, el estndar input.
Los m todos para actuar sobre l sern, entonces, unos
read:
abstract int read()
int read(byte[] b)
int read(byte[] b, int off, int len)
Como es del tipo InputStream , lee unos byte. Si queremos
que lea otras cosas tenemos que especializarlo en esta otra
cosa. En el siguiente ejemplo, que teclearemos en un archivo
que se llam a StandardIO.java, le haremos leer enteras
lneas.

im port java.io.*;
class StandardIO
{
public static void m ain(String[] tem as)
{
System .out.println("Incluye tus input, teclea end [ENVO]
para salir");
InputStreamReader a=new InputStreamReader(System .in);
BufferedReader IN=new BufferedReader(a);
String s=new String();
while(s.compareTo("end")!=0)
{
try {s=IN.readLine();}
catch (IOException e)
{s="ERROR DE LECTURA";};
System .out.println("Ledo: "+s);
}
}
}
Vamos a ver algunos mtodos de la clase System :
static long currentTim eMillis(), este mtodo nos devuelve el

tiempo en milisegundos
static void exit(int status), este m todo determ ina como salir
de Java Virtual Machine, con un
cdigo .
static void gc(), Java coloca tantos objetos, y los descoloca,
cuando ya no se usan y se necesita nueva
m emoria. Para hacerlo, utiliza un Garbage Collector , y este
m todo pone en m archa el garbage collector en cualquier
momento para liberar la m emoria precedentem ente
establecida por el program a que todava no se ha utilizado.
Puede resultar muy til en aplicaciones muy grandes.
static String getenv(String nam e), nos devuelve una cadena
que incluye inform acciones con respecto al
sistem a con el que se pone en m archa el program a. El
m todo declarado es deprecated en las ltim as
Documentaciones on line del Java Development Kit porque el
m todo pronto desaparecer. Es una de las primeras
versiones del lenguaje y todava aparece porque es
compatible con el viejo software.
static Properties getProperties() , es el nuevo m todo para
obtener informaciones sobre la propriedad del
sistem a.
static String getProperty(String key), como antes, lo nico
es que recoge inform aciones
especficas con respeto a key
static String getProperty(String key, String def)
static void load(String filenam e) , carga en la m emoria el
cdigo incluido en filenam e, que es una
biblioteca dinmica.
static void loadLibrary(String libnam e), carga la biblioteca de
sistem a m encionada por libnam e
static String mapLibraryNam e(String libname), hace un

m apa de una biblioteca en una cadena que la representa.


Hay m todos para volver a asignar los estndars input,
output y err, en otros flujos, por ejemplo un archivo.
static void setErr(PrintStream err)
static void setIn(InputStream in)
static void setOut(PrintStream out)
Los siguientes m todos reparan las propiedades del sistem a.
static void setProperties(Properties props)
static String setProperty(String key, String value)
Utilizamos unos objetos de tipo Properties y ahora veremos
cmo estn hechos. Se trata de unas especializaciones de
cuadros hash de java y son, en sustancia, unos cuadros que
incluyen una serie de parejas Clave - Valor. (En realidad, no
son precisam ente esto, sino que son unas estructuras muy
utilizadas en inform tica para contener los datos. Pero a
nosotros nos interesa verlas as de mom ento). En particular,
las Properties del sistem a son:

Clave

java.version

java.vendor

Descripcin del valor asociado

Versin del ambiente de Java


Runtim e

Distribuidor del ambiente de

Java Runtime

java.vendor.url

java.hom e

URL del destribuidor de Java

Directory donde est


instalado Java

Versin de las
java.vm .specification.version especificaciones de Java
Virtual Machine

Distribuidor de las
java.vm .specification.vendor especificaciones de Java
Virtual Machine

Nom bre de las


especificaciones de Java
Virtual Machine

java.vm .version

Versin de la implem entacin


de Java Virtual Machine

Distribuidor de la
java.vm .vendor

im plem entacin de Java


Virtual Machine

java.vm .name

java.specification.version

java.specification.vendor

java.specification.nam e

java.class.version

java.class.path

os.nam e

os.arch

os.version

Nom bre de la implem entacin


de Java Virtual Machine

Versin del ambiente de Java


Runtim e

Distribuidor del ambiente de


Java Runtime Java Runtim e

Nom bre del ambiente de Java


Runtim e

Versin de las clases de Java

Pathnam e de las clases de


Java

Nom bre del Sistema


Operativo

Arquitectura del Sistem a


Operativo

Versin del sistem a Operativo

file.separator

path.separator

line.separator

Separador del Archivo ("/" en


UNIX, "\" en Windows)

Separador de Path (":" en


UNIX, ";"en Windows)

New Line ("\n" en UNIX y


Windows)

user.nam e

Account nam e del usuario

user.hom e

Home directorio del usuario

user.dir

Working directorio del usuario

Para eso, podemos escribir un pequeo program a que nos


informe sobre el sistem a como el siguiente que hay que
editar en un archivo que se llam a Sistem a.java
im port java.io.*;
public class Sistem a
{
public static void m ain(String[] arg)

{
// Cambio el estndar output, uso el archivo Sistem a.txt
File outFile=new File("Sistem a.txt");
FileOutputStream fw;
try {fw=new FileOutputStream (outFile) ;}
catch (IOException e)
{fw=null;};

PrintStream Output=new PrintStream (fw);


System .setOut(Output);

// Escribo en el nuevo estndar output:


// Tiem po:
long tiem po=System .currentTim eMillis();
System .out.println("Tiempo en milisegundos: "+tiempo);
long t1=tiempo/1000;
System .out.println("Tiempo en segundos: "+t1);
long sec=t1%60;
long t3=t1/60;

long min=t3%60;
long t4=t3/60;
System .out.println("Tiempo en horas h"+t4+" m "+m in+"
s"+sec);
System .out.println("\nEs el tiempo pasado del 1/1/1970
hasta ahora.\n");
// Propiedad del sistem a:
System .out.println("\nPropiedad del sistema:\n");
String tmp;
System .out.println("\n\tJAVA\n");
tmp=System .getProperty("java.version ");
System .out.println("Versin del ambiente de Java Runtime:
"+tm p);
tmp=System .getProperty("java.vendor");
System .out.println("Distribuidor del ambiente di Java
Runtim e: "+tmp);
tmp=System .getProperty("java.vendor.url");
System .out.println("URL del distribuidor de Java: "+tm p);
tmp=System .getProperty("java.hom e");
System .out.println("Directorio donde est instalado Java:
"+tm p);

tmp=System .getProperty("java.vm .specification.version");


System .out.println("Versin de las especificaciones de Java
Virtual Machine: "+tmp);
tmp=System .getProperty("java.vm .specification.vendor");
System .out.println("Distribuidor de las especificaciones de
Java Virtual Machine: "+tmp);
tmp=System .getProperty("java.vm .specification.nam e");
System .out.println("Nombre de las especificaciones de Java
Virtual Machine: "+tmp);
tmp=System .getProperty("java.vm .version");
System .out.println("Versin de la implementacin de Java
Virtual Machine: "+tmp);
tmp=System .getProperty("java.vm .vendor" );
System .out.println("Distribuidor de la implementacin de
Java Virtual Machine: "+tmp);
tmp=System .getProperty("java.vm .nam e");
System .out.println("Nombre de la implem entacin de Java
Virtual Machine: "+tmp);
tmp=System .getProperty("java.specification.version");
System .out.println("Versin del ambiente de Java Runtime:
"+tm p);
tmp=System .getProperty("java.specification.vendor");
System .out.println("Distribuidor del ambiente de Java
Runtim e Java Runtim e: "+tmp);

tmp=System .getProperty("java.specification.nam e" );


System .out.println("Nombre del am biente de Java Runtim e:
"+tm p);
System .out.println("\n\tCLASES\n");
tmp=System .getProperty("java.class.version");
System .out.println("Versin de las clases de Java: "+tmp);

tmp=System .getProperty("java.class.path");
System .out.println("Pathnam e de las clases de Java:
"+tm p);
System .out.println("\n\tSISTEMA OPERATIVO\n");

tmp=System .getProperty("os.nam e");


System .out.println("Nombre del Sistem a Operativo: "+tmp);

tmp=System .getProperty("os.arch");
System .out.println("Arquitectura del Sistem a Operativo:
"+tm p);

tmp=System .getProperty("os.version");
System .out.println("Versin del sistema Operativo: "+tmp);
tmp=System .getProperty("file.separator");
System .out.println("Separador del Archivo: "+tmp);

tmp=System .getProperty("path.separator");
System .out.println("Separador del Pathnam e: "+tmp);

tmp=System .getProperty("line.separator");
System .out.println("New Line: "+tmp);
System .out.println("\n\tUSUARIO\n");
tmp=System .getProperty("user.nam e");
System .out.println("Account nam e del usuario: "+tmp);
tmp=System .getProperty("user.home");
System .out.println("Hom e directory del usuario: "+tmp);
tmp=System .getProperty("user.dir");
System .out.println("Working directory del usuario: "+tmp);

}
}
Puesto en marcha en mi sistem a, el output fue
(Sistem a.txt):
Tiempo en milisegundos: 956241233430
Tiempo en segundos: 956241233
Tiempo en horas h265622 m 33 s53
Es el tiempo transcurrido del 1/1/1970 hasta ahora.

Propiedad del sistem a:


JAVA

Versin del ambiente de Java Runtim e: null

Distribuidor del ambiente de Java Runtim e: Sun


Microsystems Inc.

URL del distribuidor de Java: http://java.sun.com/

Directorio donde est instalado Java:


C:\PROGRAMAS\JAVASOFT\JRE\1.3

Versin de las especificaciones de Java Virtual Machine: 1.0

Distribuidor de las especificaciones de Java Virtual Machine:


Sun Microsystem s Inc.

Nom bre de las especificaciones de Java Virtual Machine:


Java Virtual Machine Specification

Versin de la implem entacin de Java Virtual Machine:


1.3.0rc1-S

Distribuidor de la implem entacin de Java Virtual Machine:

Sun Microsystem s Inc.

Nom bre de la implem entacin de Java Virtual Machine: Java


HotSpot(TM) Client VM

Versin del ambiente de Java Runtim e: 1.3

Distribuidor del ambiente de Java Runtim e Java Runtime:


Sun Microsystem s Inc.

Nom bre del ambiente de Java Runtime: Java Platform API


Specification

CLASSI

Versin de las clases de Java: 47.0

Pathnam e de las clases de Java: .

SISTEMA OPERATIVO

Nom bre del Sistema Operativo: Windows 95

Arquitectura del Sistem a Operativo: x86

Versin del sistem a Operativo: 4.0

Separador del Archivo: \

Separador del Pathnam e: ;

New Line:

USUARIO

Account nam e del usuario: pietro

Home directory del usuario: C:\WINDOWS\Profiles\Pietr000

Working directory del usuario:


D:\Lavoro\HTMLpoint\corso\esem pi\cap3\lez6

Otra clase m uy importante del paquete java.lang di Java es


la clase Object. sta es la clase desde la que se crean todas
las dem s clases de Java, es decir, cualquier otra clase de
Java es una extensin de la clase java.lang.Object. La class
Object no incluye ninguna variable, sino que incluye 11
m todos que se heredan de todas las dem s clases de java y
pueden ser utilizadas en cualquier objeto fijado en Java,
entre las que:
clone(), que crea una copia del objeto idntica a la de la que
invoca el m todo. En este caso hay que fijarse en que el
mismo program a Java es un Objeto, por eso, se pueden
crear un nmero arbitrario de program as todos idnticos.

Para que se pueda invocar el m todo clone() de un objeto,


este tiene que implementar la interfaz Cloneable .
getClass(), devuelve un Objeto de tipo Class que representa
la clase a la que pertenece el objeto cuyo m todo fue
solicitado.
toString(), transform a el objeto en una cadena. Este m todo
tiene que ser escrito otra vez en los objetos creados por el
usuario, pero es m uy til.
Pensemos en la escritura Cadena sum a="Sum ando"+10+" y
"+11+" tengo "+(10+11);
Cream os una cadena usando unas cadenas y unos int. De
form a autom tica, en este caso Java invoca el m todo
toString() de la clase correspondiente que lo contiene. Esto
ocurre en cada expresin que abarca cadenas y objetos
como "Cadena"+Objeto.
La otra clase del paquete a la que nos referimos antes es
Class y representa las clases del lenguaje. Es muy
im portante porque tiene m s de treinta mtodos que sirven
para gestionar las clases a runtim e, lo que es
im prenscindible en los dem s lenguajes de program acin.
Objetos de este tipo, llam ados descriptores de clase, aunque
sean ellos mismos descriptores de interfaces, se crean y se
asocian autom ticam ente a los objetos a los que se refieren.
Objetos de tipo Class, Object y otros tipos, son muy
im portantes si son a runtim e porque perm iten gestionar el
program a que se est poniendo en m archa como si fuera
una coleccin de datos sobre los que es posible trabajar.
Java es un lenguaje de potencialidad impresionante. Si
pensam os en java.lang, hay una clase que se llam a Compiler
que incluye m todos para redactar fuentes Java. Hay otras

clases como ClassLoader, Runtim e... que permiten cargar


nuevas clases a runtim e, ponerlas en m archa, y modificar el
program a mismo mientras est trabajando. Potencialm ente,
es posible escribir en Java partiendo del cdigo que se
automodifica (que evoluciona).
Llegados a este punto para terminar la explicacin de
java.lang, entre otras cosas porque verlo de form a detallada
es dem asiado complicado y sin duda est fuera de los fines
de nuestro curso, nos basta con saber que existe y que hace
cosas que para los otros lenguajes de program acin es pura
fantasa o, como mnimo, es imposible o dificilsimo trabajar
a niveles altos.
Antes de acabar descrivo brevem ente la clase
java.lang.Match (diferente de la clase java.m ath).
Esta clase sirve para hacer clculos matem ticos y tiene dos
atributos:
static double E , es la e de Eulero
static double PI, es la PI griega
Los m todos son obviam ente todas las funciones
m atem ticas calculables, entre las que:

Los valores absolutos de valores double, float, int e long:

static double abs(double a)

static float abs(float a)

static int abs(int a)

static long abs(long a)

Las funciones trigonom tricas

static double acos(double a) - arcocoseno

static double asin(double a) - arcoseno

static double atan(double a) - arcotangente

static double cos(double a) - coseno

static double sin(double a) - seno

static double tan(double a) - tangente

Transformaciones de ngulos

static double toDegrees(double angrad) - convierte radiantes


en grados

static double toRadians(double angdeg) - convierte grados


en radiantes

static double atan2(double a, double b) - convierte

coordinadas cartesianas (b,a) en coordinadas polares


(r,theta)

Funciones exponenciales y logartm icas

static double exp(double a) - y elevado a la a.

static double log(double a) - logaritmo en base y de a

Mximos y m nimos entre valores double, float, int e long

static double m ax(double a, double b)

static float m ax(float a, float b)

static int max(int a, int b)

static long m ax(long a, long b)

static double min(double a, double b)

static float m in(float a, float b)

static int min(int a, int b)

static long min(long a, long b)

Potencias y races

static double pow(double a, double b) - calcula a elevado a


la b, notar que si b es <1, esta es

una raz(1/b)-esim a de a

static double sqrt(double a) - calcula la raz cuadrada de a.

Nm eros pseudocasuales

static double random() - da un numero casual entre 0 y 1

Redondeos

static double rint(double a) - parte entera baja de a, es un


entero

static long round(double a) - a redondeado, es un long

static int round(float a) - a redondeado, es un entero

Visto que hemos nombrado el paquete java.m ath, digamos


que ste contiene dos clases, BigInteger e BigDecimal. La
prim era clase sirve para tratar nm eros enteros de tam ao
arbitrario, pongamos por ejemplo el clculo factorial de un

nm ero muy grande, este ser un nmero exageradam ente


grande. BigDecim al hace lo mismo con los nm eros
particulares.

Il package java.util

Antes de empezar esta leccin tengo que hacer una pequea advertencia.
Hemos visto como hay que program ar usando Java, pero m e he dado cuenta de
que los teclados italianos no tienen tienen llaves, en cambio en los teclados que
uso yo s que aparecen. Por lo tanto os tengo que decir cmo podis hacer
aparecer estas llaves en vuestras pantallas.
Para que aparezca { hay que pulsar el teclado ALT, y m antenindolo pulsado hay
que teclear en el pequeo teclado numrico que est a la derec ha el nm ero 123
(ALT+123).
Para que aparezca } hay que teclear en cambio ALT+125.
Para los otros smbolos tiles en Java:
ALT Gr + es el de [ y ALT Gr + + de ]. Las teclas estn subrayadas para no
confundirlas con el signo + que indica che indica "pulsar a la vez". ALT Gr es el
ALT que se encuentra a la derecha de la tecla ESPACIO, m ientras que ALT se
encuentra a la izquierda (mirando al teclado).
Este paquete es muy til porque pone a disposicin 34 clases y 13 interfaces que
im plem entan algunas de las estructuras de datos m s comunes. Algunas
operaciones sobre fechas y sobre el calendario, y otras cosas.
Adem s el paquete java.util incluye otros subpaquetes que son: java.util.m ime,
java.util.zip y java.util.jar que sirven respectivam ente para tratar archivos de

tipo MIME, de tipo ZIP y de tipo Java Archive (JAR), que veremos en seguida en
este captulo. Como estructura de datos, en inform atica, se llam a a la estructura
lgica lista para contenerun cierto nmero de datos en la que es posible insertar
un datos, quitarlos, buscarlos, como m ucho ordenarlos. Una simple estructura de
daots que ya hemos visto es la array. Esta contiene un nm ero cero de datos
que pueden ser cualquier cosa, desde byte a objetos complejos, y sobre la
mism a se pueden incluir otros datos, hacer bsquedas o borrar, incluso un array
se puede ordenar.
Para ve si en un array grande N est presente un dato X, yo tengo que visitar
todo el array y hacer comparaciones con cada elemento del array, por lo que
esta es una operacin bastante compleja. Existen estructuras de datos que esta
bsqueda la hacen empleando un solo acceso a la estructura, estas son, por
ejem plo las citadas tablas hash. La eleccin de las estructuras de datos para
usar en un program a es bastante complicada, por ello se elige una estructura en
lugar de otra dependiendo del uso que se vaya hacer en el program a. Por
ejem plo es difcil que en un database m uy grande en el que se hacen muchas
bsquedas se use un array como estructura de datos, porque empleaream os
mucho tiempo para cada bsqueda (el ordenador es rpido, pero tiene sus
lm ites si pensamos que ste emplea tanto tiempo para visitar completam ente
un database de mil millones de elementos), en este caso lo m ejor tal vez sea
emplear una tabla hash de cierta grandeza.
Java, por tanto, pone a disposcin del usuario toda una gam a de estructuras de
datos, las gestiona, y a nosotros no nos queda m s que usarlas. Para la eleccin
de las estructuras de datos ms acorde con nuestras intenciones, usarem os
nuestro buen hacer porque, para elegirla de form a rigurosa son necesarios
conocim ientos especficos, entre otros los detalles que se realizan en las
estructuras, estudiadas en cursos universitarios, como los algoritmos y
Estructuras de Datos, y Fundam entos de Complejidad.
Cuando describa las clases de Java que se ocupan de la implem entacin de estas
estructuras, las indicar y tratar los tiempos de insercin, las bsquedas,
etctera, pero siempre inform alm ente.
Vamos a ver qu incluye el paquete java.util

Interfaces
Collection
Comparator
Enum eration
EventListener
Iterator
List
ListIterator
Map
Map.Entry
Observer
Set
SortedMap
SortedSet
Estas interfaces establecen algunas propiedades de nuestras estructuras de
datos. Se implementan en algunas de las siguientes clases.
Clases
AbstractCollection
AbstractList
AbstractMap
AbstractSequentialList
AbstractSet
ArrayList
Arrays
BitSet
Calendar
Collections

Date
Dictionary
EventObject
GregorianCalendar
HashMap
HashSet
Hashtable
LinkedList
ListResourceBundle
Locale
Observable
Properties
PropertyPermission
PropertyResourceBundle
Random
ResourceBundle
SimpleTim eZone
Stack
StringTokenizer
Tim er
Tim erTask
Tim eZone
TreeMap
TreeSet
Vector
WeakHashMap
Excepciones
ConcurrentModificationException
Em ptyStackException
MissingResourceException

NoSuchElem entException
TooManyListenersException
Em pezamos viendo algunas estructuras: BitSet, o en espaol Conjunto de Bit.
Esta clase ofrece una forma para crear y gestionar conjuntos bit (1,0) o mejor
dicho, valores verdadero, falso.
El conjunto es desde luego un vector de bit pero que crece dinm icam ente. Al
principio los bit tienen un valor falso, y el vector mide 2^32-1 ((dos elevado a la
treinta y dos) m enos uno).
La clase tiene dos constructores: BitSet(), para crear un BitSet de dim ensiones
estndar, y BitSet(int nbits), para crear un BitSet que contiene nbits bit.
Las operaciones que se pueden hacer son:
void and(BitSet set), devuelve el and entre el BitSet y el otro BitSet localizados
por set.
void andNot(BitSet set), borra todos los bit de la BitSet que tienen el
correspondiente bit ajustado en la BitSet set.
void or(BitSet set), devuelve el or exclusivo entre el BitSet y el otro BitSet
localizados por set.
void xor(BitSet set) , devuelve el or exclusivo entre el BitSet y el otro BitSet
localizados por set.
void clear(int bitIndex), ajusta el bit especificado en falso.
void set(int bitIndex), ajusta el bit especificado en verdadero.
Object clone(), BitSet se declara Cloneable. Este m todo crea una copia igual.
boolean equals(Object obj), compara el objeto con otro objeto.
boolean get(int bitIndex), da el valor del bit nm ero bitIndex.
int hashCode(), da un cdigo hash para ste bitset.
int length(), da la grandeza lgica del bitset, es decir el bit ms alto ajustado en
verdadero ms uno.
int size(), da el nm ero de bit en el momento de la bitset. Es el bit m s alto que
se puede asignar a uno sin ampliar el bit set.
String toString(), transforma el bitset en una cadena

Probamos el bit set con el siguiente program a CaracteresUtilizados, que hay que
editar en un archivo llam ado CaracteresUtilizados.java, que coge una cadena en
entrada y lee los caracteres que han sido utilizados.
im port java.util.BitSet;
public class CaracteresUtilizados
{
public static void m ain (String[] a)
{
String tmp;
try {tmp=a[0];}
catch (ArrayIndexOutOfBoundsException e)
{errore();}
elabora(a[0]);
}
public static void error()
{
System .out.println("ERROR, necesito una cadena:");
System .out.println("\tTeclear:");
System .out.println("\t\tjava CaracteresUtilizados CADENA.");
System .exit(0);
}

public static void elabora (String a)


{
String tmp = a;
BitSet utilizados= new BitSet();
for (ent e = 0; e < tmp.length() ; e++)
utilizados.set(tmp.charAt(i));
String out="[";
ent dim =utilizados.size();
for (ent e = 0; e < dim; e++)
{
if (utilizados.get(i))
out+=(char )i;
};
out+="]";
System .out.println(out);
System .out.println("Para redactar he utilizado un bit set de "+utilizados.size()+"
bit");
System .out.println ("\t\t\tPietro ");
}
}

Analizamos otra clase di java.util, la clase Vector. Esta clase implem enta unos
array de Object. Lo interesante de los array del lenguaje, es que se puede
modificar la largura del vector cuando se realiza la puesta en marcha.
En Vector, adem s de los constructores, tenemos tres tipos de mtodos, los que
sirven para modificar el vector, los que sirven para obtener los valores includos
en el vector, y los que sirven para gestionar el crecimiento del vector.
Hay cuatro constructores:
Vector(), construye un vector de tam ao 10, y que tiene la posibilidad de
aum ento igual a cero.
Vector(Collection c), construye un vector que incluye los elem entos de la
coleccin especificada, en el mismo orden en el que aparecen en la coleccin.
Vector(int initialCapacity), construye un vector tan grande como initialCapacity,
con posibilidad de aumento igual a cero.
Vector(int initialCapacity, int capacityIncrem ent), construye un vector grande
initialCapacity, con la posibilida de aum ento igual a capacityIncrem ent.
Algunos m todos de la clase son:
void add(int index, Object elem ent), aade un elem ento al vector en la posicin
indicada.
boolean add(Object o), aade un elem ento al final del vector.
boolean addAll(Collection c), aade al final del vector los elem entos de la
coleccin especificada, en el mismo rden en el que aparecen en la coleccin.
boolean addAll(int index, Collection c), aade los elementos de la coleccin en el
vector empezando por el cdigo especificado.
Estos tres m todos se convierten en verdaderos si los elem entos han sido
aadididos.Se convierten en falsos si no tienen nada que ver.
void addElement(Object obj), aade el elemento al vector y aum enta la
capacidad de uno. int capacity(), da la capacidad actual del vector.

void clear(), elimina todos los elementos que estn en el vector.


Object clone(), m todo utilizado generalm ente para clonar el objeto Vector, que
es supuestam ente cloneable.
boolean contains(Object elem ), controla si el elem ento especificado est en el
vector.
boolean containsAll(Collection c), controla si toda la coleccin especificada est
en el vector.
void copyInto(Object[] anArray), copia el contenido del objeto de tipo Vector en
un array de objetos del lenguaje.
Object elementAt(int index), devuelve el elem ento del vector que se encuentra
en la m ism a posicin especificada.
boolean equals(Object o), controla la identidad entre el vector y el objeto
especificado.
Object firstElem ent(), da el prim er elem ento del vector en posicin 0.
Object get(int index), da el elemento del vector que se encuentra en la posicin
especificada y lo borra del vector.
int hashCode(), da el cdigo hash del vector.
int indexOf(Object elem ), busca el prim er dato elemento en el vector, y devuelve
el ndice. Con prim er dato m e refiero supuestam ente al del ndice ms bajo.
int indexOf(Object elem, int index), busca el prim er dato elemento en el vector
empezando por el ndice especificado y devuelve el ndice.
void insertElem entAt(Object obj, int index), incluye el objeto especificado en la
posicin que queramos del vector.
boolean isEmpty(), controla si el vector est vaco.
Object lastElem ent(), da el ltimo componente del vector.
int lastIndexOf(Object elem ), da el ndice del ltimo elem ento del objeto
especificado en el vector.
int lastIndexOf(Object elem , int index), como antes em pezando por el ndice
especificado y movindose hacia detrs.
Object remove(int index), borra el elem ento que se encuentra en la posicin
indicada en el vector.
boolean remove(Object o), borra el prim er dato en el vector del objeto

especificado.
boolean removeAll(Collection c), borra del vector todos los elem entos incluidos
en la coleccin especificada void removeAllElem ents(), borra todos los elem entos
del vector.
boolean removeElement(Object obj), borra el primer dato del objeto especificado
en el vector.
void removeElem entAt(int index), borra el elem ento en la posicin especificada.
boolean retainAll(Collection c), borra todos los elem entos del vector que estn
incluidos en la coleccin especificada.
Object set(int index, Object elem ent), sustituye los elem entos en la posicin
especificada del vector con el elem ento que se le da como parm etro (pone el
elem ent en la direccin index).
void setElem entAt(Object obj, int index), pone el objeto especificado en la
posicin que queremos.
void setSize(int newSize), ajusta el nuevo tam ao del vector.
int size(), da el nm ero de posiciones en el vector.
List subList(int fromIndex, int toIndex), crea un listado con los elementos del
vector que se encuentran en la posicin especificada come inicio o como final.
List es otra estructura de datos muy importante que Java lleva ya implem entada.
Object[] toArray() e Object[] toArray(Object[] a), crean un array del lenguaje
con los elem entos incluidos en el vector.
toString(), da una representacin bajo form a de cadena del vector que incluye
las representaciones como cadena de todos los elem entos incluidos en el vector.
Prcticam ente invoca el toString de todos los objetos.
Los que estn acostumbrados a program ar con otros lenguajes de program acin
podrn apreciar la funcionalidad que a m enudo el program ador tiene que
im plem entar l mismo de forma superficial. Lo que yo aprecio personalm ente,
como program ador, es, adem s de la dinam icidad de la estructura de Vector,
que siempre ha sido por definicn esttica, la posibilidad de crear vectores con
elem entos heterogneos. En realidad, stos son vectores de objetos, y sabemos
que los objetos de java pueden ser cualesquiera incluso program as. Por ejemplo,

es posible crear un vector que incluya nmeros enteros, valores booleanos y


cadenas, lo que no se puede hacer con los dem s array del lenguaje.
Para que quede ms claro voy a poner un ejemplo.
Fijaos en este vector:
tribiln = { true , 10 , "Hola"};
De qu tipo ser Tribiln? ent[]? boolean[]? O String[]? Ninguno de los tres. En
Java es im posible crear un array hecho de esta form a, utilizando las famosas
clases envoltorios, que, hasta ahora, nos haban parecido bastantes intiles.
Podemos crear un array y escribiremos.
Object[] tribiln={new Boolean(true),
new Integer(10),
new String("Hola")
};
Adem s, si utilizamos la clase Vector, tendremos muchos mtodos para
gestionar este vector de elem entos heterogneos.
Pongamos un pequeo ejemplo que usa los vectores. Definimos un espacio
geom trico tridim ensional de puntos, lneas y caras, que se definen as:
class punto
{
String nombre;
ent x,y,z;
public punto(String n, ent X,ent Y,ent Z)
{
x=X;
y=Y;

x=Z;
nombre=n;
}
public String toString()
{
return "\n"+nombre+"="+x+","+y+","+z+"\n";
}
}

class lnea
{
String nombre;
punto inicio;
punto fin;
public lnea(String n, punto i,punto f)
{
inicio=i;
fin=f;
nombre=n;
}
public String toString()

{
return "\n"+nombre+"=("+inicio.toString()+","+fin.toString()+")\n";
}
}

class cara
{
String nombre;
punto x1;
punto x2;
punto x3;
lnea l1;
lnea l2;
lnea l3;
public cara(String n, punto X1,punto X2,punto X3)
{
x1=X1;
x2=X2;
x3=X3;
l1=new lnea(n+"-lnea1",x1,x2);
l2=new lnea(n+"-lnea2",x3,x2);
l3=new lnea(n+"-lnea3",x1,x3);
nom e=n;
}
public String toString()
{

return "\n"+nombre+"={"
+l1.toString()+
","
+l2.toString()+
","
+l3.toString()+"}\n";
}
}
Las clases incluyen unos m todos toString(), que sobrescriben los m todos
estndar para crear el outpu en el archivo del program a.
Las clases las pondremos en un archivo llam ado Geometra.java, donde
pondremos tam bin los import necesarios al program a y las clases Geometra
que incluye el m ain que definimos a continuacin:
im port java.util.*;
im port java.io.*;
// Definicicn de la clase punto
// Definicicn de la clase lnea
// Definicicn de la clase cara
public class Geom etra
{
public static ent NMERO = 3000;
public static void m ain(String[] arg)
{
Vector espacio=new Vector(1,1);

System .out.println("Geometra en el espacio:");


ent pti = NMERO;
System .out.println();
System .out.println("Gnero "+pti+" objetos a caso por cada especie");
System .out.println("Cambiar la constante NMERO en Geometra para generar
un nmero diferente.");
ent lin=NMERO;
ent car;
car=NMERO;

System .out.println();
ent d1=espscio.capacity();
System .out.println ("Capacidad del vector:"+espacio.capacity());
System .out.println("Redacto los puntos...");
ent e=0;
for ( e = 0 ; e
{
float a=(float ) Math.random ();

float b=(float ) Math.random();


float c=(float ) Math.random ();
ent x=Math.round(a*1000);
ent y=Math.round(b*1000);
ent z=Math.round(c*1000);
String nome="Punto"+(e+1);
punto tmpP=new punto(nombre,x,y,z);
espacio.addElem ent(tmpP);
};
System .out.println ("Capacidad del vector:"+espacio.capacity());
ent d2=espacio.capacity();
System .out.println("Redacto las lneas...");
for ( e = 0 ; e
{
float a=(float ) Math.random ();
float b=(float ) Math.random();

float c=(float ) Math.random ();


float d=(float ) Math.random();
float e=(float ) Math.random ();
float f=(float ) Math.random ();

ent x=Math.round(a*1000);
ent y=Math.round(b*1000);
ent z=Math.round(c*1000);
ent x1=Math.round(d*1000);
ent y1=Math.round(e*1000);
ent z1=Math.round(f*1000);
String nombre="Lnea"+(i+1);
punto P1=new punto ("Punto 1 del "+nombre,x,y,z);
punto P2=new punto ("Punto 2 del "+nombre,x1,y1,z1);
linea tmpL=new linea(nombre,P1,P2);
espacio.addElem ent(tmpL);
};

System .out.println ("Capacidad del vector:"+espacio.capacity());


ent d3=espacio.capacity();
System .out.println("redacto las caras...");
for ( e = 0 ; e
{
float a=(float ) Math.random ();
float b=(float ) Math.random();
float c=(float ) Math.random ();
float d=(float ) Math.random();
float e=(float ) Math.random ();
float f=(float ) Math.random ();
float g=(float ) Math.random();
float h=(float ) Math.random ();
float j=(float ) Math.random ();
ent x=Math.round(a*1000);
ent y=Math.round(b*1000);

ent z=Math.round(c*1000);
ent x1=Math.round(d*1000);
ent y1=Math.round(e*1000);
ent z1=Math.round(d*1000);
ent x2=Math.round(g*1000);
ent y2=Math.round(h*1000);
ent z2=Math.round(j*1000);
String nome="Cara"+(e+1);
punto P1=new punto ("Punto 1 del "+nombre,x,y,z);
punto P2=new punto ("Punto 2 del "+nombre,x1,y1,z1);
punto P3=new punto ("Punto 1 del "+nombre,x2,y2,z2);
cara tmpF=new cara(nombre,P1,P2,P3);
espacio.addElem ent(tmpF);
};
System .out.println ("Capacidad final del vector:"+espacio.capacity());
ent d4=espacio.capacity();

File FileOut=new File("Geometra.txt");


FileWriter Output;
try {Output=new FileWriter(FileOut);}
catch (IOException e) {Output=null;};
try {
Output.write("Geometra.txt\nnm ero objetos="+3*NMERO+"\n");
Output.write("Tam ao del Vector:\al principio:"+d1+"\n despus de la inclusin
de los nm eros:"+d2);
Output.write("\ndespus de la inclusin de las lneas:"+d3+"\ndespus de la
inclusin de las caras:"+d4);
Output.write("\n\nContenido:\n");
Output.write(espacio.toString());
Output.write("\n\n\n\t\tPietro Castellucci");
Output.flush();
} catch (IOException e) {};
System .out.println("\nLee el archivo Geom etra.txt.\n");
};
}

Si ponemos en m archa el program a verem os que el Vector espacio aum enta


dinmicamente con los objetos heterogneos punto, lnea y cara.
Finalm ente tendremos un archivo llam ado Geom etra.txt que inc luye la
descripcin del vector. El archivo con 5 elem entos por cada especie es algo
como:
Geom etra.txt
nm ero objetos=15
Tam ao del Vector:
al principio:1
despus de la inclusin de los puntos:5
despus de la inclusin de las lneas:10
despus de la inclusin de las caras:15
Contenido:
[
Punto1=653,932,0
,
Punto2=100,273,0
,
Punto3=855,210,0
,
Punto4=351,702,0
,
Punto5=188,996,0
,
Lnea1=(
Punto 1 de la Lnea1=680,454,0
,

Punto 2 de la Lnea1=69,16,0
)
,
Lnea2=(
Punto 1 de la Lnea2=116,651,0
,
Punto 2 de la Lnea2=371,15,0
)
,
Linea3=(
Punto 1 de la Lnea3=947,335,0
,
Punto 2 de la Lnea3=477,214,0
)
,
Lnea4=(
Punto 1 de la Lnea4=391,671,0
,
Punto 2 de la Lnea4=692,725,0
)
,
Lnea5=(
Punto 1 de la Lnea5=762,283,0
,
Punto 2 de la Lnea5=582,192,0
)
,
Cara1={
Cara1-lnea1=(
Punto 1 de la Cara1=826,235,0
,
Punto 2 de la Cara1=13,378,0

)
,
Cara1-lnea2=(
Punto 1 de la Cara1=12,950,0
,
Punto 2 de la Cara1=13,378,0
)
,
Cara1-lnea3=(
Punto 1 de la Cara1=826,235,0
,
Punto 1 de la Cara1=12,950,0
)
}
,
Cara2={
Cara2-lnea1=(
Punto 1 de la Cara2=382,30,0
,
Punto 2 de la Cara2=224,597,0
)
,
Cara2-lnea2=(
Punto 1 de la Cara2=277,361,0
,
Punto 2 de la Cara2=224,597,0
)
,
Cara2-lnea3=(
Punto 1 de la Cara2=382,30,0
,
Punto 1 de la Cara2=277,361,0

)
}
,
Cara3={
Cara3-lnea1=(
Punto 1 de la Cara3=139,802,0
,
Punto 2 de la Cara3=880,935,0
)
,
Cara3-lnea2=(
Punto 1 de la Cara3=643,921,0
,
Punto 2 de la Cara3=880,935,0
)
,
Cara3-lnea3=(
Punto 1 de la Cara3=139,802,0
,
Punto 1 de la Cara3=643,921,0
)
}
,
Cara4={
Cara4-linea1=(
Punto 1 de la Cara4=516,614,0
,
Punto 2 de la Cara4=429,210,0
)
,
Cara4-lnea2=(
Punto 1 de la Cara4=979,860,0

,
Punto 2 de la Cara4=429,210,0
)
,
Cara4-lnea3=(
Punto 1 de la Cara4=516,614,0
,
Punto 1 de la Cara4=979,860,0
)
}
,
Cara5={
Cara5-lnea1=(
Punto 1 de la Cara5=152,663,0
,
Punto 2 de la Cara5=828,101,0
)
,
Cara5-linea2=(
Punto 1 de la Cara5=651,761,0
,
Punto 2 de la Cara5=828,101,0
)
,
Cara5-lnea3=(
Punto 1 de la Cara5=152,663,0
,
Punto 1 de la Cara5=651,761,0
)
}
]

Pietro Castellucci
Intentad fijar la constante NMERO a 4000 y poned en m archa el program a.
Como habis visto hay m uchas estrucuturas de datos en java.util, y describirlas
todas sera dem asiado trabajo.
Lo que nos interesa es que todas tienen m todos para introducir, quitar,
recuperar y m todos para gestionar la estructura mism a.
Las estructuras de datos implem entadas son tablas hash, listas, pile, code,
rboles etc Segn vuestras exigencias podes utilizar una u otra. Para tener
m s detalles, sin embargo, os aconsejo ojear la docum entacin del Java
Development Kit, donde stn escritas todas estas clases.
Por ahora os sirve con saber que las tablas hash son muy rpidas buscando un
objeto. Por lo general, basta con un solo acceso a las estructuras de datos para
encontrar el objeto que buscis.
Los listados son como los vectores. Los objetos estn relaccionados entre s, y
desde un obbjeto es posible alcanzar el siguiente o el anterior o los dos, segn la
realizacin del listado .
Los Pile son listados particulares, en los que se introducen objetos siempre al
comienzo de la estructura y, de aqu, se pueden tom ar. Por lo tanto en pila el
ltimo objeto que ha entrado es el prim ero que sale. Pensad en los objetos como
si fueran unos documentos que hay despachar desde una oficina. Se ponen en
rden en la m esa del encargado segn sus llegadas, uno encima del otro. El
encargado de despachar los documentos empieza siempre por el que est
encima de la pila. sta puede parecer una estructura de datos tonta, pero os
aseguro que es la m s mportante de todas. Las utilizan todos los lenguajes de
program acin para invocar las funciones y los procedimientos. (Incluso Java la
usa para invocar los mtodos), para transladar los parm etros y recuperar los
resultados. Sin esta estructura sera imposible program ar de form a recursiva,
que es una form a de program ar muy potente.
Las colas funcionan al revs. Se pueden comparar con las colas de los bancos.
Los objetos son las personas que estn en la cola delante de la ventanilla. Llegan

y se ponen al final de la cola. Mientras tanto el empleado atiende a las personas


que estn delante. Tambim esta estructura es muy importante porque algunas
variantes (las colas de prioridad, en las que los objetos tienen prioridad, se
atienden segn esta caracterstica, es decir, se cuelan). Se utilizan mucho en los
sistem as operativos como Windows, Linux, Unix, etc. para gestionar las
necesidades de imprenta de una sola impresora por parte de todos los usuarios
del sistem a.
Antes de pasar al siguiente paquete, quiero mostraros una pequea comparacin
sobre la bsqueda de un objeto entre muchos que estn incluidos en distintas
estructuras. Particularm ente, en las estructuras de tipo vector y de tipo tabla
hash.
Veremos como los resultados de la bsqueda cambian de form a evidente
aum entando el tamao de las estructuras. Imaginemos unos objetos de este
tipo:
class O
{
String nombre=new String();
ent valor;
public O(String a, ent v)
{
nombre=a;
valor=v;
}
}
Cream os un vector de 100000 de estos elem entos. Buscamos uno y vemos el
tiempo que tardamos:
im port java.util.*;
class O

{
String nombre=new String();
ent valor;
public O(String a, ent v)
{
nombre=a;
valor=v;
}
}

public class Rvector


{
public static ent NMERO = 100000;
public static void m ain (String[] s)
{
Vector V = new Vector(NUMERO);
ent numnombre=128756;
O O_30000=null;
System .out.println("Redacto el vector, introduzco "+NMERO+" objetos de tipo
O con valores que no tienen relacin con el ndice.");

System .out.print("Inicio: O_"+numnombre);


for (ent e=0; i< NMERO;i++)
{
O tmp = new O("O_"+numnombre,numnombre);
if (numnombre==30000) O_30000 = tmp;
numnombre--;
V.add(e,tmp);
};
System .out.println(" Fin: O_"+numnombre);
System .out.println("Inicio la bsqueda de O_30000");
long Inicio=System .currentTimeMillis();
ent index=V.indexOf(O_30000);
O tmp=(O ) V.get(index);
long Fine=System .currentTimeMillis();
System .out.println("Oggetto O_30000 trovato in "+(Fin-Inicio)+" millisec. al
ndice "+index);
System .out.println("Vale:\nNombre:"+tmp.nombre+"\nValor:"+tmp.valor+"\n")
;

}
}
El program a buscar el objeto O_30000. El output del programm a es:
Redacto el vector, introduzco 100000 objetos de tipo O con valores
independientes del ndice.
Inicio: O_128756 Fin: O_28756
Em piezo la bsqueda de O_30000
Objeto O_30000 encontrado en 50 m illisec. ..
Ahora hago lo mismo usando una estructura como la tabla hash:
im port java.util.*;
class O
{
String nombre=new String();
ent valor;
public O(String a, ent v)
{
nombre=a;
valor=v;
}
}

public class Rhash


{
public static ent NMERO = 100000;
public static void m ain (String[] s)
{
Hashtable H = new Hashtable(NUMERO+1);
ent numnombre=128756;
O O_30000=null;
System .out.println("Redacto el cuadro, introduzco "+NMERO+" objetos de tipo
O.");
System .out.print("Inicio: O_"+numnombre);
for (ent e=0; i< NMERO;e++)
{
O tmp = new O("O_"+numnombre,numnombre);
if (numnombre==30000) O_30000 = tmp;
numnombre--;
H.put(tmp,tmp);
};

System .out.println(" Fin O_"+numnombre);


System .out.println("Inicio la bsqueda de O_30000");
long Inizio=System .currentTimeMillis();
O tmp=(O ) H.get(O_30000);
long Fine=System .currentTimeMillis();
System .out.println("Obbjeto O_30000 encontrado en "+(Fin-Inicio)+" m illisec.
");
System .out.println("Vale:\nNombre:"+tmp.nombre+"\nValor:"+tmp.valor+"\n")
;

}
}
Otra vez el programa buscar el objeto O_30000. El output del programm a es:
Redacto el vector, introduzco 100000 objetos de tipo O.
Inicio: O_128756 Fin: O_28756
Em piezo la bsqueda de O_30000
Objeto O_30000 encontrado en 0 millisec. ..
El paquete java.util no incluye slo estas utilsim as estructuras de datos, sino
tam bin clases que simplifican la gestin de fechas y horarios, para la
internacionalizacin, y otras clases de utilidad como el string tokenizer. Coge de
una cadena todas las palabras y unos generadores de nm eros casuales.

El paquete java.util

En esta leccin veremos la parte de java.util que trata de los


utilsimos archivos .zip e i .jar
Em pezamos viendo java.util.zip
Los archivos .zip son archivos que contienen unos archivos
comprimidos y varios program as. Se utilizan sobre todo para
cambiar datos en internet porque reducen notablem ente los
tam aos.
Hay varios tipos de archivos comprimidos y varios
program as para comprimir y ampliar los datos, pensemos en
los archivos RAR, en los CAB de Windows, en los ARJ. Este
paquete nos da la posibilidad de tratar datos comprim idos
segn los estndars ZIP y GZIP, que utilizan el algoritmo de
compresin llam ado DEFLATE. este paquete incluye tambin
utility que controlan los cdigos checksum CRC-32 y Adler32 de un flujo arbitrario de entrada.
Para qu usar este paquete? Las razones son muchas. En
prim er lugar, los program as Java que incluyen im genes,
anim aciones y sonidos, pueden ser realm ente grandes y es
posible crear un archivo .ZIP con todos los archivos
necesarios para que funcione. De esta form a se dism inuye el
tam ao del mismo. Pero, para que se puedan utilizar por el
program a, prim ero tienen que descomprimirse y este
paquete nos ofrece esta posibilidad. Otra razn para usar

este paquete es que la compresin de datos en informtica


es un problema bastante complejo. En esta operacin se
utilizan unos algoritmos que se basan en el lgebra de los
nm eros, tema no muy conocido fuera de las facultades de
Ciencias. Por esta razn, son unos algoritmos bastantes
incomprensibles para los que no tienen prctica en el asunto.
Este paquete ofrece la posibilidad a todo el mundo de
comprimir y ampliar estos datos.
Veam os, entonces, lo que incluye el paquete java.util.zip
Interfaces
Checksum, es un interfaz que representa el cdigo checksum
de los datos.
Clases
CheckedInputStream , es un flujo de entrada que trata
tam bin el checksum de los datos de entrada.
CheckedOutputStream , es un flujo de salida que trata
tam bin el checksum de los datos en salida.
CRC32, clase usada para calcular el cdigo checksum de tipo
CRC-32 de un flujo de datos.
Deflater, clase que se ocupa de las compresiones de los
datos utilizando la compresin segn la biblioteca
ZLIB.
DeflaterOutputStream , flujo de salida que comprime los
datos utilizando el algoritmo Deflate.
GZIPInputStream , filtro para el stream de ingreso para leer
datos comprimidos segn el formato
GZIP.
GZIPOutputStream , filtro para el flujo de salida para escibir

datos con el cdigo zip utilizando GZIP.


Inflater, soporte para la compresin de tipo ZLIB.
InflaterInputStream , filtro para el flujo de entrada, para
ampliar datos comprim idos segn
el algoritmo Deflate.
ZipEntry, utilizada para representar un archivo de entrada de
tipo ZIP.
ZipFile, utilizada para leer el contenido de un archivo ZIP.
ZipInputStream, utilizada para leer los archivos contenidos
en un archivo ZIP.
ZipOutputStream , utilizada para escibir datos comprimidos
de formato ZIP.
Excepciones
DataFormatException, error de form ato de los datos.
ZipException
Cada una de estas clases tendr sus mtodos. Para
conocerlos todos os remito a la docum entacin del JDK
porque slo analizarem os algunos con un pequeo ejemplo.
El siguiente program a abre el directorio en el que se
encuentra y busca todos los archivos .zip, por cada archivo
que encuentra y mira el contenido.
im port java.util.*;
im port java.util.zip.*;
im port java.io.*;

public class ReadZip


{

public static void m ain(String [] a)


{
File dir=new File(".");
System .out.println("Abro el directorio
"+dir.getAbsolutePath());
File[] cont=dir.listFiles();
ent MAX=cont.length;
for (ent e = 0; i
{
String tmp=cont[i].getNam e();
if ((tmp.endsWith(".zip"))||(tmp.endsWith(".ZIP")))
{
// es un archivo .zip
System .out.println("He encontrado "+tmp);
controlaZip(cont[i]);
};
}

}
public static void controlaZip(File f)
{

System .out.println("Contenido del archivo "+f.getNam e());


ZipFile Zf;
try {Zf=new ZipFile(f);}
catch (ZipException e){Zf=null;}
catch (IOException e1){Zf=null;}
;
Enum eration files=Zf.entries();
while(files.hasMoreElem ents())
System .out.println(files.nextElem ent());

}
Adem s podemos ampliar estos archivos. El siguiente
program a recoge todos los .zip del directorio donde se pone
en m archa y los amplia.
im port java.util.*;
im port java.util.zip.*;
im port java.io.*;

public class Decomp


{

public static void m ain(String [] a)


{
File dir=new File(".");
System .out.println("Abro el directorio
"+dir.getAbsolutePath());
File[] cont=dir.listFiles();
ent MAX=cont.length;
for (ent e = 0; i<MAX; e++)
{
String tmp=cont[i].getNam e();
if ((tmp.endsWith(".zip"))||(tmp.endsWith(".ZIP")))
{
// es un archivo .zip
System .out.println("He encontrado "+tmp);
try {controlaZip(cont[i]);}
catch (IOException e){};
};
}

}
public static void controlaZip(File f) throws IOException
{

System .out.println("Ampliacin del archivo


"+f.getNam e()+":");
ZipFile Zf;
try {Zf=new ZipFile(f);}
catch (ZipException e){Zf=null;}
catch (IOException e1){Zf=null;}
;
Enum eration files=Zf.entries();
while(files.hasMoreElem ents())
{
ZipEntry tmpFile=(ZipEntry ) files.nextElem ent();
System .out.println("am plio el archivo "+tmpFile.getNam e());
System .out.println("tam ao comprimido "+
tmpFile.getCompressedSize()+" tam ao no comprimido "+
tmpFile.getSize()+" CRC "+tmpFile.getCrc());
System .out.println("modificado "+tmpFile.getTim e());
InputStream in= Zf.getInputStream (tmpFile);
FileOutputStream out= new
FileOutputStream (tmpFile.getNam e());

for (ent ch=in.read();ch!=-1;ch=in.read()) out.write(ch);

out.close();
in.close();
}
}

}
El paquete java.util.jar se pone a disposicin del
program ador de las clases y de los interfaces para tratar los
archivos de tipo Java Archive (JAR), sobre todo es posible
leerlos y escribirlos. Los archivos JAR se basan en el
estndar ZIP, con un archivo opcional llam ado m anifest .
El contenido del paquete es el siguiente:
Clases
Attributes
Attributes.Nam e
JarEntry
JarFile
JarInputStream
JarOutputStream
Manifest
Excepciones
JarException
Os rem ito a la docum entacin del JDK para m s informacin.

El paquete java.net

El Paquete java.net
Java, como ya dijimos anteriorm ente, naci como lenguaje
para la red y slo sucesivam ente se convirti en un
verdadero lenguaje de programacin.
Su papel de lder para la programacin no se pone en duda
y, por eso, pone a disposicin del programador diferentes
paquetes para llevar a cabo esta program acin.
Como el objetivo final del curso es program ar Applet,
tenemos que verlo aunque sea de modo superficial. El
paquete es muy amplio y su contenido es el siguiente:
Interfaces
ContentHandlerFactory
FileNam eMap
SocketImplFactory
SocketOptions
URLStreamHandlerFactory
Clases
Authenticator
ContentHandler
Datagram Packet

Datagram Socket
Datagram SocketImpl
HttpURLConnection
InetAddress
JarURLConnection
MulticastSocket
NetPermission
PasswordAuthentication
ServerSocket
Socket
SocketImpl
SocketPermission
URL
URLClassLoader
URLConnection
URLDecoder
URLEncoder
URLStreamHandler
Excepciones
BindException
ConnectException
MalformedURLException
NoRouteToHostException
ProtocolException
SocketException
UnknownHostException
UnknownServiceException
De todo esto nosotros veremos slo algo. Para empezar
vamos aver qu pasa en la red.
Los ordenadores en Internet comunican intercambiando

paquetes de datos, llam ados paquetes IP (Internet Protocol).


Estos paquetes salen de un ordenador, pasan por varios
nudos de la red (Servidor de la red) y llegan a su destino.
Para establecer el recorrido intermedio entre los dos
ordenadores que quieren comunicare se pone en m archa un
algoritmo de routing (hay varios tipos segn las exigencias y
segn el tipo de red).
Para establecer el remite de una comunicacin, los
destinatarios, los nudos internet, se necesita que cada
ordenador conectado a la red tenga un nombre que lo
identifique unvocam ente. Este nombre es un nm ero y se
llam a direccin IP.
La direccin IP es un nmero de 32 bit, que se puede
escribir con varios formatos, sin embargo, el m s utilizado
es el form ato decim al separado por puntos. Por ejemplo, una
direccin IP es 594. 24.114.462 (Se ha elgido un nm ero
cualquiera).
Como los ordenadores recuerdan muy bien los nm eros,
pero nosotros los humanos no, se inventaron los DNS
(Dom ain Nam e System ) que asocian unos nombres a estas
direcciones IP.
La prim era clase del paquete que analizaremos es la
InetAddres, que gestiona estas direcciones IP.
La clase tiene varios mtodos, entre los que hay uno que
devuelve las direcciones Ip del ordenador en el que se est
trabajando, otro que, fijado un nombre de dominio, devuelve
la direccin IP.
El siguiente ejemplo nos muestra el uso.
im port java.net.*;
public class DireccionesIP
{

public static void m ain(String [] a)


{
String dom ="developer.java.sun.com";
try {
InetAddress loc=InetAddress.getByNam e(dom );
System .out.println("IP de "+dom +" :
"+loc.getHostAddress());
}
catch (UnknownHostException e)
{System .out.println("No existe el dominio "+dom );};

try {
InetAddress loc=InetAddress.getLocalHost();
System .out.println("IP local: "+loc.getHostAddress());
System .out.println("Nombre local"+loc.getHostNam e());
}
catch (UnknownHostException e)
{};
}
}
Como ejercicio, coged como nombre de dominio el prim er
tem a del program a, por ejemplo,java DireccionesIP
HTMLpoint
El paquete dota de clases tiles para tratar los socket
fundam entales basados en TCP y en UDP, que son protocoles

utilizados en la m ayor parte de las aplicaciones Internet.


Nosotros no los analizaremos, sino que pasaremos
directam ente a las clases que gestionan aplicaciones Web de
nivel m s alto.
Veam os la clase URL.
Qu es un URL? Un URL, o Uniform Resource Locator, es un
puntero a un recurso web.
Un recurso web puede ser cualquier cosa, un directorio, un
archivo, un objeto en red como, por ejemplo, una interfaz
para hacer unas query a un database remoto, o para un
motor de bsqueda.
Los URL son muchos, cada uno con un protocolo distinto, sin
embargo los m s utilizados son los que utilizan protocolos
HTTP (HyperText Transfer Protocol) y FTP (File Transfer
Protocol).
La clase URL se conecta con objetos web accediendo a stos
a travs sus direcciones URL.
Vosotros que sois usuarios de HTMLpoint no necesitis m s
explicaciones sobre el formato de las direcciones URL
comohttp://www.cli.di.unipi.it/~castellu/index.html y que el
index.htm l es opcional, es decir que la direccin
URL http://www.cli.di.unipi.it/~castellu es igual a la anterior,
que ~castellu es un directorio que se encuentra en el
servidor, y que la direccin del servidor se identifica
como http://www.cli.di.unipi.it . Sin embargo, os digo que, a
diferencia de los web browser, l'http:// delante de la
direccin es indispensable porque distingue el protocolo del
URL, protocolo que el Navigator y el Explorer intuyen aunque
se om itan. Cuando program emos los apliques utilizaremos
slo los URL para acceder tambin a los archivos locales,
vindolos como recursos de la red. Lo haremos porque en
los apliques no se pueden utilizar los archivos, por razones

de seguridad, entonces para leer un archivo hay que verlo


como un recurso de la red.
Las ltimas versiones de Java estn eliminando esta
lim itacin del lenguaje, utilizando unas firm as que perm iten
leer y escribir un archivo de form a controlada incluso en la
red. Por eso en futuro ser posible utilizar incluso los
archivos en los archivos, siempre que se asum an algunas
responsabilidades.
Veam os unos constructores de objetos URL:
URL(String spec) , crea un objeto URL segn la
representacin a cadena, por ejemplo "HTMLpoint"
URL(String protocol, String host, int port, String file), crea
un objeto URL, especificndolo todo, incluso la puerta.
URL(String protocol, String host, int port, String file,
URLStreamHandler handler), como el anterior, lo nico que
especifica tam bin la URLStreamHandler, que es la
superclase comn a todos los protocolos(HTTP,FTP,Gopher).
URL(String protocol, String host, String file), crea un objeto
URL especificando el protocolo, el host y el Archivo en el
servidor host, por ejemplo:
URL("http","www.cli.di.unipi.it","~castellu/index.html").
Analizamos ahora unos m todos de la clase
boolean equals(Object obj), compara dos objetos URL.
Object getContent(), da el contenido del objeto URL.
String getFile(), da el nobre del archivo del URL.
String getHost(), el host
int getPort(), el nm ero de la puerta
String getProtocol(), el nombre del protocolo.
String getRef(), da el puntero a la URL.

int hashCode(), da el cdigo hash del objeto.


URLConnection openConnection(), abre una conexin con el
objeto remoto indicado por la URL.
InputStream openStream (), abre una conexin con el objeto
web indicado por la url en form a de flujo de lectura.
String toExternalForm (), da una cadena que representa la
URL.
String toString(), da una representacin del objeto URL.
A continuacin damos un pequeo ejemplo de cmo se
utiliza la clase URL.
im port java.net.*;
im port java.io.*;
public class getPage
{
public static void m ain(String[] arg)
{
String un;
try {un=arg[0];}
catch (ArrayIndexOutOfBoundsException e)
{
un="http://www.htm lpoint.com /index.asp";
System .out.println("Ninguna URL definida, cojo "+un);
};
System .out.println("URL:"+un);
URL url;

boolean tribiln=false;
try {url= new URL(un);}
catch (Malform edURLException e)
{
System .out.println("URL equivocado, cojo
http://www.htm lpoint.com /index.asp ");
url = null;
tribiln=true;
};
if (tribiln) try {url = new URL
("http://www.htmlpoint.com/index.asp ");}
catch (Malform edURLException e){};
BufferedReader stream ;
try {stream = new BufferedReader (new InputStream Reader
(url.openStream ()));}
catch (IOException e){
System .out.println("Error de apertura del archivo");
stream =null;
System .exit(0);
};
File out=new File(".\\"+url.getFile());
FileWriter Output;

try {Output=new FileWriter(out);}


catch (IOException e) {Output=null;};
String l;
try
{
while ((l=stream .readLine())!=null)
{

Output.write(l);
};
Output.flush();
Output.close();
}
catch (IOException e){System .out.println("Error de
lectura.");};
}
}
El program a coge una url de los parm etros de entrada; si
ste no es vlido o no hay parm etros, abre por default la
url http://HTMLpoint/index.asp. Entonces recoge la pgina
que ha ledo y la guarda en el disco.
Como se puede ver, esto se parece a un web browser,
utilizando un poco de grfica se podra visualizar incluso la

pgina. Intentad poner en m archa el programa poniendo las


siguientes direcciones:
java getPage http://www.cli.di.unipi.it/~castellu/index.htm
java getPage http://www.cli.di.unipi.it/~castellu/pietro1.htm
java getPage
http://www.cli.di.unipi.it/~castellu/quinsoy.htm
y sim plemente java getPage, y veris los resultados.

Conclusiones sobre los paquetes

En este apartado hemos visto unos paquetes que contienen


los API del lenguaje Java, pero hay m s:
java.applet , que analizaremos en el prximo captulo, sirve
para crear unos program as que trabajan
en los web browsers, llam ados applet.
java.awt , este paquete y sus subpaquetes implem entan las
clases para, a su vez, implem entar los controles
GUI, para implementar interfaces grficas, adem s de
instrumentos para el dibujo, manipulacin de las im genes,
im prim ir y otras funciones. Lo veremos en el prximo
captulo
java.beans, paquete que permite definir los componentes
Java y utilizarlos en otros program as.

java.rmi, paquete para la invocacin de m todos remotos, es


decir, de m todos de objetos que se encuentran en cualquier
lugar en la red, para construir unas aplicaciones
distribuidas.
java.security, hay clases que implem entan las funciones de
seguridad como, por ejemplo, las clases utilizadas para
criptografar docum entos antes de enviarlos a la red.
java.sql, interfaz entre el lenguaje Java y el lenguaje para
base de datos SQL.
java.text, clases m uy tiles para la interaccin.
javax.accessibility, clases que apoyan las tecnologas que
facilitan a los usuarios no aptos.
javax.swing, es una extensin de java.awt para construir
apliques y aplicaciones grficas: es prodigioso.
org.omg.CORBA, permite relacionar el lenguaje Java con el
lenguaje CORBA.
Otra vez os animo, para saber m s, a controlar la
documentacin del JDK, disponible On line, tanto para
descargarla como para consultarla, en el sito de la Sun
Microsystem www.sun.com .
Estos son los paquetes estndar del lenguaje Java. A estos
se sum an las extensiones estndar del lenguaje. Las
extensiones estndar son paquetes que, en las prximas
versiones de Java, se convertirn en paquetes estndar y
que, hasta ahora, son versiones beta. Swing fue la extensin
hasta que sali Java2. Ahora, de hecho, se utilizan m s las
viejas awt.
API Servlet, est destinada a la program acin de
aplicaciones del servidor en Java. API est formada por

paquetes javax.servlet y javax.servlet.http.


Java 3D, gestiona el dibujo tridimensional y es parecida a la
versin Java de OpenGL (JavaGL), la famossima biblioteca
de la SGI (alguien la conocen como Glide, es decir, como la
biblioteca OpenGL por las 3Dfx) y DirectX de Microsoft.
Se puede bajar del sito: http://java.sun.com /products/javam edia/3D/index.htm l
Java Media Fram ework, gestiona, en los program as Java,
varios form atos audio, video y multim edial. Los archivos que
los ayudan son los siguientes:
.m ov, .avi, .viv, .au, .aiff, .wav, .m idi, .rmf, .gsm , .mpg,
.m p2, .rtp.
Si no toda, por lo menos una parte se convertir en estndar
con Java 1.3 que est a punto de salir al m ercado (finales de
abril). Se baja del sito:
http://www.javasoft.com /products/javam edia/jfm /index.html
Speech, funciones de reconocimiento vocal, no slo para las
rdenes, sino que es posible tambin editar archivos
enteros. Este paquete hace tam bin el output vocal.
Se puede bajar del sito: http://java.sun.com /products/javam edia/speech/index.html
Telephony, funciones de telefona y fax.
JavaMail, clases para gestionar el correo electrnico.
Java Nam ing and Directory Services, para acceder a los
servicios de nombres y directorio utilizando protocoles como

LDAP.
este paquete se ha convertido en estndar en JDK 1.3
Java Managem ent, para la gestin de redes locales.
JavaSpaces, m s clases para la creaccin de aplicaciones
distribuidas.
JavaComm erce, para el com ercio electrnico.
Personalm ente no veo la hora de que se conviertan en
estndar las API Java 3D, Java Media Fram ework,
JavaSpeech y Java Telephony, porque las funciones que
prometen estas API son realm ente excepcionales. Utilizarlas
ahora es posible, pero con cierto riesgo. Realm ente son
todava versiones beta y, por eso, llenas de errores. Adem s
si se quieren escribir apliques utilizando estas nuevas
funciones, esto es posible, pero para ponerlos en m archa se
necesita el apliqueviewer del JDK, porque seguramente el
Java implem entado en los web browser todava no las tiene.
Hay que pensar que Swing se ha convertido en un paquete
estndar del lenguaje, pero existen todava unos browser
que no lo tienen.

Interfaces grficas y sucesos

Por fin llegamos a la program acin de interfaces grficas, es


decir, a la creaccin de apliques y de aplicaciones a
ventanas. En prim er lugar, intentamos establecer qu es un
interfaz y qu quiere decir hacerla grfica.
Cada program a, como ya dijimos, se puede ver como un
objeto que calcula una funcin, es decir, que coge unos
datos del exterior y devuelve unos resultados. Por ejemplo,
pensem os en un simple program a que calcula la sum a de
dos nm eros. Este programa coger como input dos
nm eros y devolver como output un solo nmero que
representa la sum a de los prim eros dos.
Lo que acabamos de decir es vlido en general para todas
las aplicaciones y no es un caso especfico del ejemplo
anterior. Pensem os en un videojuego: el input lo dar la
palanca de control, y el output sar la grfica que aparece
en la pantalla. Por esta razn, conceptualm ente tanto el
videojuego como el program a sum a, como cualquier
program a que un program ador pueda inventarse, son
funciones calculadas sobre unos datos de entrada que
devuelven resultados.
La interfaz del program a hacia el usuario que la utiliza es la
m anera en que el programa coge los datos del usuario y le
devuelve los resultados.
Hasta ahora vimos unas interfaces de texto, el caso de la
sum a de los nm eros en las que los datos se cogan del
input estndar con una System.in.read() y los resultados se
im prim an en el output estndar con una System.out.print().
Las System .in y out representan una interfaz del program a
hacia el exterior, en este caso, hacia el usuario.

Otras interfeces con el exterior que ya hemos analizado, son


los archivos que representan interfeces de entrada o de
salida hacia usuarios u otros program as.
Estableciendo una pequea comparacin, no tan imposible,
entre un program a y el hombre, podemos decir que la
interfaz en entrada del cerebro est representada por la
vista, el tacto, el gusto, el odo y el olfato, mientras la
interfaz de salida est representada por la palabra y el
movimiento de los msculos.
Notar que esto no es algo muy raro porque los robots,
aunque no tienen los mismos canales de entrada que los
hombres (tienen la vista, una especie de tacto, algo que
indica la proximidad) y de salida (a m enudo hablan, en lugar
de los msculos tienen motores elctricos conectados a
brazos m ecnicos, pinzas, etc...), tienen el mismo
funcionam iento del hombre. Realizan acciones (dan un
ouput) consecuentemente a unos estmulos (seas de input),
aunque por supuesto el hombre es m ucho ms complejo
gracias a su capacidad de pensam iento que todava la
inteligencia artificial no consigue alcanzar totalmente.
Realm ente un robot no puede decidir nada al conocer s lo
informaciones parciales sobre un problema, en cambio el
hombre puede hacerlo porque es capaz de formular
hiptesis, etc.).
Por tanto, la interfaz est compuesta por todos los canales
de los que un program a recoge informaciones y hacia las
que devuelve unos resultados.
Algunos datos de entrada sirven para que cambie slo el
estado del program a, otros, en cambio, dan inm ediatamente
un output. Nosotros los consideramos todos datos en los que
se calculan funciones. Realm ente una funcin se calcula

tam bin teniendo en cuenta el estado del program a y,


tam bin, el estado y, por consiguiente, el input que le ha
cusado es un input de la funcin.
Aclaro este tem a con un ejemplo. Pensemos en un program a
que calcula dos funciones, una de sum a y otra de
sustraccin entre dos nm eros, y pensemos en un input que
toma un nmero para elegir un estado (1 o 2), y despus
dos nm eros. A estos dos nmeros se les aplica la funcin
sum a o la funcin sustraccin segn el estado del program a.
Poe ejem plo:
INPUT: <1,10,10> OUTPUT: 20
INPUT:<2,10,10> OUTPUT: 0
En el ejemplo, el input sobre el estado se usa para calcular
el output.
Lo que nos interesa es la interfaz del usuario. Vimos como
los program as pueden relaccionarse con otros program as o
con perifricas (enviando, por ejemplo, rdenes a una
im presora), pero esto no nos interesa. Nos interesa en
cambio ver todo lo que le sirve al program a para dialogar
con el usuario, es decir, la llam ada interfaz del usuario.
En este caso nos interesa ver la interfaz grfica del
program a, es decir, la interfaz que hace mucho m s
agradable el program a al usuario, en lugar de la gris interfaz
de caracteres que vimos antes.
La interfaz grfica del program a est compuesta por los
llam ados componentes GUI (Graphics User Interface), que
son componentes que sirven para el input o el output y
tienen un aspecto grfico. Son, por ejem plo, unos

componentes GUI de un program a, todos los mens, los


pulsadores, las etiquetas, etc.
Todas estas GUI estrn, obviam ente, conectadas a una
estructura que las incluye. Las dos estructuras que
analizaremos, ya que son las m s importantes, son los
apliques y las ventanas.
Cada GUI es, entonces, un trocito de interfaz grfica, reciben
los sucesos y, de acuerdo con stos, dan unos resultados.
Pensemos en un pulsador: se puede clicar o dejar de clicar.
Cuando un usuario program a una interfaz grfica que incluye
un pulsador tendr que gestionar incluso los sucesos
asociados a ste, es decir, tendr que decir qu ocurre
cuando se clica el pulsador, cuando se deja de clicar, cuando
le pasam os el ratn encima, etc.
Cada GUI tendr un tipo de suceso asociado, algunos los
gestionan automticamente las clases que se am plian para
incluir el GUI en la ventana (por ejemplo, la modificacin
grfica del pulsador clicado que se pone en evidencia); otros
los puede definir el usuario (como el clic de un pulsador, si
no hay gestor no ocurre nada) y otros los tiene que definir el
usuario (como todos los sucesos del teclado cuando
queremos escuchar por lo menos uno de stos, por ejemplo,
nos interesa program ar cmo se pulsa una tecla, tenemos
que gestionar incluso la presin, etc.).
Cada tipo de suceso, para cada tipo de componente GUI,
tiene que ser declarado como escucha del suceso. Es un
program a que espera que el suceso ocurra sobre el
componente y cuando esto ocurre, lo gestiona.
La program acin de interfaces grficas es, por esta razn,
diferente de la norm al program acin porque se dibujan las
interfaces y luego se gestionan los suceos que llegan,

mientras que en las normales aplicaciones haba un main


que representaba todo el program a. La gestin de los
sucesos en Java ha cambiado de la versin 1 a Java 2 (JDK
1.2 para arriba). Nosostros analizarem os la nueva gestin de
los sucesos, la de Java 2 porque la primera fue cambiada
porque no se entenda a que componente se asocia el
suceso.
En nuestra explicacin de los componentes GUI analizaremos
cmo definirlos, cmo inicializarlos, cmo introducirlos en
una ventana o en un aplique y, finalm ente, cmo gestionar
los sucesos.
Como ya dijimos, Java 2 tiene dos colecciones de paquetes
para las interfaces grficas, java.awt, que ya exista en Java
1, y javax.swing, que sali con Java 2, construida sobre las
AWT, que aumenta muchsimo las posibilidades para las
interfaces grficas.

Qu es una aplicacin a ventanas?

La aplicacin a ventanas es el tipo de aplicacin que m s a


m enudo utilizamos cuando trabajamos con el ordenador. Es
una aplicacin que se pone en m archa de form a local, que
utiliza como interfaz del usuario las tecnologas de las
ventanas tpica de los sistemas operativos Mac OS (en la que
naci), Windows (todas sus variantes, Windows 3.1,

Windows 95, 95-OSR2, 98, NT, 2000 y Millenium),


XWindows (el servidor grfico para Linux y Unix).
Casi todos los program as que se utilizan actualm ente son
aplicaciones a ventanas. Lo son, por ejemplo, Word,
Netscape, Explorer, Jbuilder, Visual Studio, WinZip, Paint,
XV, etc (Todos pertenecen a los correspondientes
productores).
Por lo tanto veremos cmo se crea una Ventana usando el
paquete AWT.
Como siem pre creamos una aplicacin con el main, como
hicimos anteriormente. Sin embargo, la clase que creamos
ahora ampliar la clase java.awt.Fram e, que representa la
ventana completa, incluye el ttulo, los pulsantes de
reduccin a icono, maximizar y cerrar.
La clase Fram e tiene varios m todos y constructores que
veremos dentro de poco. Ahora vamos a crear nuestra
prim era ventana con el ttulo Prim era Ventana y que no
incluye nada. La editamos en Ventana.java.
im port java.awt.*;
public class Ventana extends Fram e
{
public Ventana()
{
super("Prim era Ventana");
setLocation(100,100);
setSize(200,100);

show();
}

public static void m ain(String[] arg)


{
new Ventana();
System .out.println("he creado la ventana");
}
}
Al principio, como para cada aplicacin, se invoca el m ain
que crea un nuevo objeto de tipo Ventana. (El m ain y la
ventana podran estar en dos archivos separados, uno que
gestiona el m ain, y el otro que gestiona la ventana).
En el constructor del objeto ventana se invoca al constructor
de la superclase, es decir, del fram e, con la cadena "Prim era
Ventana" (es el ttulo). Luego se invoca el m todo
setLocation que declara la posicin del ngulo derecho en la
parte que est arriba de la ventana en el desktop, en este
caso <100, 100> (Son la x y la y respectivam ente. La x se
mide partiendo del lado izquierdo de la pantalla y aum enta a
m edida que se va hacia la derecha. La y se mide partiendo
de la parte superior de la pantalla y aum enta a m edida que
se va hacia abajo).
Despus se invoca el mtodo setSize que permite especificar
anchura y altura. En nuestro caso, tiene una anchura de 200

y una altura de 100. Finalmente se invoca el mtodo show()


y a continuacin aparece la ventana en la pantalla.

Las coordinadas de la pantalla no son las coorinadas


cartesianas. realm ente la y es precisam ente opuesta porque
aum enta a medida de que se baja y desminuye a medida de
que se sube. ste es un problem a que tiene no slo Java,
sino que todos los lenguajes de program acin y todas las
bibliotecas para la grfica Raster. Se debe a razones
histricas, supongo, debidas a la forma de dibujar los pixel
en pantalla a nivel de hardware. Hay que acostumbrarse,
pero las prim eras veces puede provocar problem as de
razonam iento.
Intentad redactar y poner en m archa el program a y cuando
veis vuestra prim era ventana os anim aris. Sucesivam ente
elim inad, por turnos, los m todos setLocation, setSize y
show, colocad tambin las ventanas en distintas posiciones y
evaluad los cambios. En el ejemplo, se ven sucesos que el

sistem a gestiona autom ticam ente. Son Ir Resize de la


Ventana y la presin de los pulsadores reduce a iconos y
m aximiza (minimiza), los cuales se gestionan en la clase
Fram e.
En cam bio, no se gestiona el suceso cerrar ventana (el
pulsador de la x). Si se teclea no ocurre nada y para acabar
la puesta en marcha del program a hay que ir al prompt del
DOS desde el que empez la aplicacin y teclear CTRL+C (el
exit para todos los program as DOS).
Por ltimo, creo que queda claro, la aplicacin no funcio na
en am bientes que no son grficos, es decir, en DOS y en
Linux. Se necesita Windows (y el DOS cargado en una
ventana, es decir, prompt de MS-DOS) o Xwindows con una
shell abierta.
Adem s no es verdad que a una aplicacin se puede asociar
a una solo ventana. Java es un lenguaje que perm ite la
multiprogram acin. Cada ventana es un programa
independiente que trabaja contem poraneam ente con otros.
Por eso puedo crear, para la mism a aplicacin, m s
ventanas FRam e, como en el ejemplo que ofrecemos a
continuacin.
im port java.awt.*;
public class Ventanas extends Frame
{
public Ventanas(String Nombre, ent x, ent y)
{
super(Nombre);

setLocation(x,y);
setSize(200,100);
show();
}

public static void m ain(String[] arg)


{
System .out.println("Creo 4 ventanas solapadas");
for (ent e1;i<5;i++) new Ventanas("Ventana "e,10+(e*10),
10+(e*10));
System .out.println("Creo 4 ventanas a cuadros");
for (ent e=5;e<9;e++) new Ventanas("Ventana "+e,(e5)*200, 100+(e-5));

System .out.println("He creado las ocho ventanas");


}
}
Las m ism as cosas se podan hacer extendiendo la clase
JFram e del paquete javax.swing.

im port javax.swing.*;
public class VentanaSwing extends JFram e
{
public VentanaSwing()
{
super("Prim era Ventana");
setLocation(100,100);
setSize(200,100);
show();
}

public static void m ain(String[] arg)


{
new VentanaSwing();
System .out.println("He creado la ventana");
}
}
Este program a es como Ventana.java. lo nico que am pla

JFram e de swing. Las nicas diferencias son el contenido de


la ventana, que esta vez es gris y antes era blanco, y el
pulsador cerrar, que esta vez cierra la ventana (slo la
ventana y no toda la aplicacin). Realm ente la utilizacin de
swing y de awt es muy parecida. Sin embargo, swing es m s
complejo y pone a disposicin muchas m s clases, y ofrece
la posibilidad de cambiar el aspecto de las ventanas a
runtim e, etc.
Desgraciadam ente, no todos los web browser las pueden
utilizar. Por eso, nosotros veremos las awt, y despus
hablaremos de las swing, dejando claro que los que quieran
hacer un aplique para su propria pgina html hasta ahora
TIENEN que utilizar las awt. Dentro de poco, cuando el XML
se convierta en estndar y se tengan que cambiar los
browser, se podr utilizar con toda tranquilidad swing incluso
para los apliques.
Por lo tanto, vemos qu incluye la clase Fram e. En prim er
lugar, los constructores son dos:
Fram e() , que crea un Fram e sin ningn ttulo, al principio
invisible.
Fram e(String T), que crea un Frame con ttulo T, tambin
inicialm ente invisible.
Los atributos de la clase son:
static int ICONIFIED
static int NORMAL
para indicar el estado de las ventanas y
static int CROSSHAIR_CURSOR
static int DEFAULT_CURSOR

static int E_RESIZE_CURSOR


static int HAND_CURSOR
static int MOVE_CURSOR
static int N_RESIZE_CURSOR
static int NE_RESIZE_CURSOR
static int NW_RESIZE_CURSOR
static int S_RESIZE_CURSOR
static int SE_RESIZE_CURSOR
static int SW_RESIZE_CURSOR
static int TEXT_CURSOR
static int W_RESIZE_CURSOR
static int WAIT_CURSOR
Todos se declaran como deprecated, para los cursores,
rem plazados por la clase Cursor. Hereda la alineacin de los
componentes de Component.
Los m todos son:
void addNotify(), conecta el fram e a un recurso de la
pantalla y lo convierte en visible.
int getCursorType(), declarado Deprecated. Es de la versin
1.1 de las JDK
static Fram e[] getFram es(), da un array que incluye todos
los Fram es creados por la aplicacin.
Image getIconIm age(), da el icono del Fram e. Es un objeto
de tipo Icon, que analizarem os a continuacin.
MenuBar getMenuBar(), devuelve la barra de los mens del
fram e. Es un objeto de tipo MenuBar, que analizaremos a
continuacin.
int getState(), da el estado del fram e.
String getTitle(), da el ttulo del fram e

boolean isResizable(), da verdadero si el fram e se puede


agrandar y reducir con el ratn.
protected String param String() , da la cadena que incluye los
parm etros del Fram e.
void remove(MenuComponent m ), quita el MenuBar
especificado por el fram e.
void removeNotify(), quita la conexin entre el fram e y el
recurso que representa la pantalla, convirtindolo en algo
que no se puede visualizar.
void setCursor(int cursorType), controla el cursor en JDK1.1.
Se declara deprecated.
void setIconIm age(Image image), averigua el icono del
Fram e.
void setMenuBar(MenuBar mb), asigna una MenuBar al
fram e.
void setResizable(boolean resizable), averigua el Frame que
puede cambiar dim ensiones o no. Por default lo es.
void setState(int state), averigua el estado del fram e
void setTitle(String title), averigua el ttulo del fram e.
Fram e es una clase que ampla java.awt.Window y, por eso,
hereda los mtodos y los atributos.
Realm ente Fram e es una Window que aade un borde y un
MenuBar. Los mtodos heredados de windows son:
addWindowListener, applyResourceBundle,
applyResourceBundle, dispose, getFocusOwner,
getInputContext, getLocale, getOwnedWindows, getOwner,
getToolkit, getWarningString, isShowing, pack, postEvent,
processEvent, processWindowEvent, removeWindowListener,
show, toBack, toFront.

Window ampla java.awt.Container, es un contenedor de


objetos AWT. Es un componente que puede incluir otros
componentes. Por lo tanto, por la propiedad de la
transitividad, Fram e hereda los mtodos y los atributos. Los
m todos son:
add, add, add, add, add, addContainerListener, addImpl,
countComponents, deliverEvent, doLayout,
findComponentAt, findComponentAt, getAlignmentX,
getAlignm entY, getComponent, getComponentAt,
getComponentAt, getComponentCount, getComponents,
getInsets, getLayout, getMaximum Size, getMinimum Size,
getPreferredSize, insets, invalidate, isAncestorOf, layout, list,
list, locate, minimumSize, paint, paintComponents,
preferredSize, print, printComponents,
processContainerEvent, remove, remove, removeAll,
rem oveContainerListener, setFont, setLayout, update,
validate, validateTree
Container ampla java.awt.Component. Un Component es un
objeto que tiene una representacin grfica, por ejemplo un
cursor ser una extensin de esta clase que am pla, a su
vez, java.lang.Object
Los atributos heredados por Component son:
BOTTOM_ALIGNMENT, CENTER_ALIGNMENT,
LEFT_ALIGNMENT, RIGHT_ALIGNMENT, TOP_ALIGNMENT
mientras los mtodos heredados por Component son:
action, add, addComponentListener, addFocusListener,
addInputMethodListener, addKeyListener, addMouseListener,

addMouseMotionListener, addPropertyChangeListener,
addPropertyChangeListener, bounds, checkImage,
checkIm age, coalesceEvents, contains, contains,
createIm age, createIm age, disable, disableEvents,
dispatchEvent, enable, enable, enableEvents,
enableInputMethods, firePropertyChange, getBackground,
getBounds, getBounds, getColorModel,
getComponentOrientation, getCursor, getDropTarget,
getFont, getFontMetrics, getForeground, getGraphics,
getHeight, getInputMethodRequests, getLocation,
getLocation, getLocationOnScreen, getNam e, getParent,
getPeer, getSize, getSize, getTreeLock, getWidth, getX,
getY, gotFocus, handleEvent, hasFocus, hide, im ageUpdate,
inside, isDisplayable, isDoubleBuffered, isEnabled,
isFocusTraversable, isLightweight, isOpaque, isValid,
isVisible, keyDown, keyUp, list, list, list, location, lostFocus,
mouseDown, mouseDrag, mouseEnter, mouseExit,
mouseMove, mouseUp, move, nextFocus, paintAll,
prepareIm age, prepareImage, printAll,
processComponentEvent, processFocusEvent,
processInputMethodEvent, processKeyEvent,
processMouseEvent, processMouseMotionEvent,
rem oveComponentListener, removeFocusListener,
rem oveInputMethodListener, removeKeyListener,
rem oveMouseListener, removeMouseMotionListener,
rem ovePropertyChangeListener,
rem ovePropertyChangeListener, repaint, repaint, repaint,
repaint, requestFocus, reshape, resize, resize,
setBackground, setBounds, setBounds,
setComponentOrientation, setCursor, setDropTarget,
setEnabled, setForeground, setLocale, setLocation,
setLocation, setNam e, setSize, setSize, setVisible, show,

size, toString, transferFocus


Mientras que de Object se heredan los mismos m todos:
clone, equals, finalize, getClass, hashCode, notify, notifyAll,
wait, wait, wait
Algunos los analizarem os, mientras que para los dem s os
aconsejo consultar la documentacin del JDK, en la que
estn descritas todas detalladam ente.
El diagram a de las extensiones de Fram e es el siguiente:

Llegados a este punto, se entiende por qu es importante la


extensin de las clases en Java. Realm ente en Fram e se
pueden invocar todos los mtodos que analizamos antes.
En cam bio, el m todo de JFram e de swing es:

Por lo tanto Jfram e hereda todos lo m todos de Fram e


porque deriva de ste y, adem s, crea otros.

Qu es un aplique?

Un aplique no es m s que una aplicacin Java que se


encuentra en web. El aplique presenta unas diferencias con
las aplicaciones porque no tienen ningn main, y son clases
que tienen el mismo nombre que el del archivo que las
incluye, que amplan la clase Applet del paquete java.applet.
Incluso para los apliques existe la versin JApplet de swing,
que se utiliza para introducir componentes Swing en lugar de
componentes AWT. Un aplique necesita un archivo html que
lo invoque. Por ejem plo, PrimoApplet.java, el aplique que
queremos poner en m archa, lo redactamos y el compilador
genera PrimoApplet.class. Para ponerlo en m archa
necesitamos un archivo html que incluya el TAG en su
interior:

<applet code="PrimoApplet.class" ></applet>


Si este archivo se llam a tribiln.html, llegados a este punto
tenemos dos posibilidades para poner en m archa el aplique.
La prim era, en fase debug, es utilizar el program a
appletviewer de JDK y, para esto, tendremos que escribir
partiendo del prompt de dos:
appletviewer tribiln.html
La segunda es utilizar un web browser, como Explorer o
Netscape invocando el archivo tribiln.html.
Como se puede ver, se pone en m archa siempre el archivo
html, y no el archivo .class como ocurra para las
aplicaciones. Es el archivo html el que invoca la aplicacin
.java.
Para m s informaciones sobre las pginas html os aconsejo
visitar el sito HTMLpoint donde se encuentran apartados que
tratan este tem a. Nosostros prepararemos unas pginas
sencillas que sirven slo para cargar nuestros apliques. por
ejem plo, para el aplique PrimoApplet.class de antes, el
archivo tribiln.html ser algo parecido a:
<htm l>
<head>
<title>Applet PrimoApplet
</head>
<body>
El siguiente es el aplique PrimoApplet.class

<applet code="PrimoApplet.class" width=100


height=100>Tu browser es viejo, tienes que
cambiarlo!</APPLET>
</body>
</htm l>
Hasta ahora hemos visto cmo poner en m archa el aplique,
ahora lo tenemos que crear. En prim er lugar tenemos que
crear una clase llam ada PrimoApplet, que ampla la clase
java.applet.Applet, y tenemos que definir unos mtodos que
el sistem a (appletviewer o el browser) invocar
automticam ente. Uno de estos m todos se llam a
paint(Graphics O), y Graphics es un objeto que representa la
pantalla del aplique. Nosostros lo volveremos a definir de
form a que salga en pantalla lo que queramos.
Utilizaremos el mtodo drawString de la clase Graphics para
im prim ir una cadena en la pantalla.
El program a PrimoApplet.java es
im port java.applet.*;
im port java.awt.*;
public class PrimoApplet extends Applet
{
public void paint (Graphics g)
{
g.drawString("Hola, yo soy el prim er aplique.",0,50);
}
}

El paquete aplique contiene tres interfaces y una clase:


Interfaces
AppletContext, esta interfaz corresponde al ambiente del
aplique, es decir al documento que lo incluye y a los dem s
apliques que estn el en mismo documento.
AppletStub, se refiere al ambiente de puesta en m archa del
aplique, tanto el browser como el appletviewer. AudioClip, la
interfaz es una simple abstraccin para que toquen unos
audios.
Clase
Aplique
Analizamos la clase Applet m s detalladamente.
El constructor es nico, sin argumentos.
Aplique()
Hay unos m todos invocados del browser o de appletviewer
automticam ente, que son: void init(), este mtodo se
invoca nada ms cargar completam ente en el sistem a el
aplique.
Se utiliza principalmente para inicializar el aplique.
void start(), invocado cuando el sistem a pone en m archa el
aplique y le avisa del suceso.
void stop(), invocado cuando el sistem a bloquea la puesta en
m archa del aplique y le avisa del suceso, invocado cuando se
teclea STOP del appletviewer y cambia la pgina en el
browser.
void destroy(), invocado cuando el aplique se destruye, es
decir, cuando cambiamos, sale del browser o del

appletviewer
Por lo tanto el ciclo vital de un aplique es:

Se carga y, sucesivam ente, se le da el nombre de init();

Se pone en marcha, se teclea start(). Invoca el mtodo


paint() de la superclase Container;

Se para tecleando stop del browser o, cuando la ventana que


lo incluye no est en primer plano, se teclea stop(). Cuando
vuelve en primer plano se teclea start();

Finalm ente, se destruye cuando se sale del browser que lo


puso en m archa. En prim er lugar se invoca stop y,
sucesivam ente, el destroy();

En el ejemplo que ponemos a continuacin, se visualizan las


fases precedentes para ver los resultados con un browser,
visto que el output son System.out.print(). Seleccionar en
herram ientas (tool), show java consola (o parecidos), con el
appletviewer, en cambio, el output se escribe en la ventana
de la que se invoca el html que invoca el aplique.
Lo editamos en el archivo Etapas.java:
im port java.applet.*;
public class Etapas extends Applet
{
public Etaps()

{
System .out.println("Invocado el constructor de Etapas");
}
public void init()
{
super.init();
System .out.println("Puesto en m archa public void init()");
}
public void start()
{
super.start();
System .out.println("Puesto en m archa public void start()");
}
public void stop()
{
super.stop();
System .out.println("Puesto en m archa public void stop()");
}
public void destroy()
{

super.destroy();
System .out.println("Puesto en m archa public void
destroy()");
}
}
Lo redactamos con: javac Etapas.java
Para cargarlo vam os a crear el archivo Etapas.html que
incluye:
<htm l>
<head>
<title>Etapas.html carga Etapas.class</title>
</head>
<body>
El siguiente es el aplique Etapas, que nos muestra las etapas
por las que pasa el aplique.
<BR>
<applet code="Etapas.class" width=200 height=100>Tu
browser es viejo, tienes que cambiarlo!</APPLET>
</body>
</htm l>
Pra ponerlo en marcha teclearemos: appleviewer
Etapas.htm l, o abriremos el archivo Etapas.html con nuestro
browser preferido.
Los dems m todos de la clase Applet son:
AppletContext getAppletContext(), da el AppletContext

asociado al aplique, es decir, el docum ento que lo puso en


m archa y los dem s invocados por ste.
String getAppletInfo(), da informaciones sobre el aplique,
tiene que ser sobrescrita, la normal da nulo.
AudioClip getAudioClip(URL url), da el objeto de tipo
AudioClip asociado al URL introducido. Os recuerdo que la
URL es un recuso del web.
AudioClip getAudioClip(URL url, String nam e), da el objeto
de tipo AudioClip asociado a la URL y al nombre .
URL getCodeBase(), da la url asociado al aplique.
URL getDocum entBase(), da la url del documento html que
ha invocado el aplique.
Image getIm age(URL url), da el objeto de tipo Image
asociada a la url introducida y se puede imprimir en la
pantalla.
Image getIm age(URL url, String nam e), da el objeto de tipo
Image asociado a la url y al nombre.
Locale getLocale(), da el objeto de tipo Local asociado al
aplique y se ocupa de la internacionalizacin. Se encuentra
en el paquete java.util.
String getParam eter(String nam e), da el valor del parm etro
llam ado nam e tom ado de la pgina html que invoca el
aplique. El aplique, por lo tanto, se puede invocar con
valores de entrada, como el args del m ain. Este m todo los
recoge.
Por ejemplo, si invoco el aplique Clock.class de esta forma:
<applet code="Clock" width=50 height=50>
<param nam e=Color value="blue">
</applet>

Si en cdigo del aplique escribo getParam eter("Color") el


resultado ser "blue".
String[][] getParam eterInfo(), da un array que incluye
informaciones sobre los parm etros del aplique. boolean
isActive(), nos dice si el aplique est activo.
static AudioClip newAudioClip(URL url), coge un AudioClip de
un dato url.
void play(URL url), toca el audio clip tom ado de la url
absoluto.
void play(URL url, String nam e), toca el Clip que nos da la
url y el nobmre especificado.
void resize(Dimension d) o void resize(int width, int height),
pide al plique que modifique sus dimensiones. Dim ension es
un objeto awt que es una dimensin, es decir, un valor de
anchura y altura.
void setStub(AppletStub stub), ajusta el AppletStub del
aplique al nuevo stub.
void showStatus(String m sg), pide al aplique que la cadena
se im prima en la ventana de estado del aplique.
Un aplique es una extensin de Panel, que es un simple
contenedor. De ste hereda el m todo: addNotify
Panel ampla Container del que hereda y hace heredar a
Applet, los mtodos: add, add, add, add, add,
addContainerListener, addImpl, countComponents,
deliverEvent, doLayout, findComponentAt, findComponentAt,
getAlignm entX, getAlignmentY, getComponent,
getComponentAt, getComponentAt, getComponentCount,
getComponents, getInsets, getLayout, getMaximum Size,
getMinimum Size, getPreferredSize, insets, invalidate,
isAncestorOf, layout, list, list, locate, minimum Size, paint,

paintComponents, param String, preferredSize, print,


printComponents, processContainerEvent, processEvent,
rem ove, remove, removeAll, removeContainerListener,
rem oveNotify, setFont, setLayout, update, validate,
validateTree
A su vez Container ampla Component, y, por lo tanto, estn
los atributos
BOTTOM_ALIGNMENT, CENTER_ALIGNMENT,
LEFT_ALIGNMENT, RIGHT_ALIGNMENT, TOP_ALIGNMENT
y los m todos:
action, add, addComponentListener, addFocusListener,
addInputMethodListener, addKeyListener, addMouseListener,
addMouseMotionListener, addPropertyChangeListener,
addPropertyChangeListener, bounds, checkImage,
checkIm age, coalesceEvents, contains, contains,
createIm age, createIm age, disable, disableEvents,
dispatchEvent, enable, enable, enableEvents,
enableInputMethods, firePropertyChange, getBackground,
getBounds, getBounds, getColorModel,
getComponentOrientation, getCursor, getDropTarget,
getFont, getFontMetrics, getForeground, getGraphics,
getHeight, getInputMethodRequests, getLocation,
getLocation, getLocationOnScreen, getNam e, getParent,
getPeer, getSize, getSize, getTreeLock, getWidth, getX,
getY, gotFocus, handleEvent, hasFocus, hide, im ageUpdate,
inside, isDisplayable, isDoubleBuffered, isEnabled,
isFocusTraversable, isLightweight, isOpaque, isValid,
isVisible, keyDown, keyUp, list, list, list, location, lostFocus,

mouseDown, mouseDrag, mouseEnter, mouseExit,


mouseMove, mouseUp, move, nextFocus, paintAll,
prepareIm age, prepareImage, printAll,
processComponentEvent, processFocusEvent,
processInputMethodEvent, processKeyEvent,
processMouseEvent, processMouseMotionEvent,
rem oveComponentListener, removeFocusListener,
rem oveInputMethodListener, removeKeyListener,
rem oveMouseListener, removeMouseMotionListener,
rem ovePropertyChangeListener,
rem ovePropertyChangeListener, repaint, repaint, repaint,
repaint, requestFocus, reshape, resize, resize,
setBackground, setBounds, setBounds,
setComponentOrientation, setCursor, setDropTarget,
setEnabled, setForeground, setLocale, setLocation,
setLocation, setNam e, setSize, setSize, setVisible, show,
size, toString, transferFocus
Y, por lo tanto, los de Object:
clone, equals, finalize, getClass, hashCode, notify, notifyAll,
wait, wait, wait
La jerarqua es:

Preparamos otro pequeo aplique llam ado Info.java

im port java.applet.*;
im port java.awt.*;
im port java.awt.im age.*;
public class Info extends Applet implements ImageObserver
{

public Info()
{
}
public void init()
{
super.init();
setBackground(Color.yellow);
resize(400,200);
}

public void start()


{
super.start();
}
public void stop()
{
super.stop();
}

public void destroy()


{
super.destroy();
}

public void paint (Graphics g)


{
g.setColor(Color.darkGray);
String p=getAppletInfo();
if (p!=null) g.drawString(p,10,10);
g.drawString("CODE:"+getCodeBase().toString(),10,20);
g.drawString("DOC:"+getDocum entBase().toString(),10,30);
Image io=getImage(getCodeBase(),"m e.JPG");
// Para visualizar esta im gen necesito que Info implem ente
la interfaz ImageObserver.
// g.drawImage(Im age,x,y,Im ageObserver);
g.drawIm age(io,10,40,this);
g.drawString("ste soy yo",80,80);
String nome=getParam eter("pm etro3");
String cognome=getParam eter("parm etro2");

String eta=getParam eter("parm etro1");


g.drawString("Pone en marcha el programm a",10,150);
g.drawString(nombre,10,160);
g.drawString(apellidos,10,170);
g.drawString("de "+edad+" aos",10,180);
}
public String getAppletInfo()
{
return "Applet de Pietro Castellucci";
}
public String[][] getParam eterInfo()
{
String[][] r={
{"parm etro1","entero","Tu edad"},
{"parm etro2","Cadena", "Tus Apellidos"},
{"parm etro3","Cadena","Tu Nombre"}
};
return r;
}
}
Para cargar el aplique vamos a crear un archivo llam ado
Info.html, que incluye:

<htm l>
<head>
<title>Info.html carga Info.class</title>
</head>
<body>
ste es el aplique Info.
<BR>
<applet code="Info.class" width=400 height=200>
<param nam e=parm etro1 value=" EDAD DEL QUE PONE
EN MARCHA EL PROGRAMA ">
<param nam e=parm etro2 value=" APELLIDOS DEL QUE
PONE EN MARCHA EL PROGRAMA ">
<param nam e=parm etro3 value=" NOMBRE DEL QUE PONE
EN MARCHA EL PROGRAMA ">
Tu browser es viejo, hay que cambiarlo!
</APPLET>
</body>
</htm l>
Cuidado con especificar los parm etros parm etro1,
parm etro2 y parm etro3 porque en el aplique no se hace
ningn control de sus definiciones. Por lo tanto, el aplique
hace una excepcin no capturada, adem s en el directorio
donde ponis el aplique, tiene que haber un archivo llam ado
m e.JPG, que es una im gen 67x88 pixel.

Aplicaciones mixtas

Llegados a este punto, despus de haber visto qu son los


Fram e y los Applet, se nos ocurre una pregunta. Es posible
combinar las dos tcnicas, para invocarlas de alguna form a,
para crear unas aplicaciones m ixtas?
La respuesta, obviam ente, es s. Podemos hacer program as
que son mixtos, una combinacin de las aplicaciones y los
apliques. Realm ente, debido a la modularidad del lenguaje,
podemos crear unas aplicaciones Java que utilizan otras
aplicaciones, lo que no ocurre en los normales lenguajes de
program acin, donde es simplem ente posible invocar
program as de otro program a.
Supongamos, por ejemplo, que creamos un program a Java
llam ado Calculadora.java, con su main y sus m todos, entre
los que hay uno que coge dos enteros y devuelve la sum a.
Supongamos entonces, que lo redactamos en
Calculadora.class y que lo inclumos ya puesto en m archa.
Por ltimo hacemos otro program a de cualquier tipo en el
que podemos utilizar el program a Calculadora.class, es decir
la clase Calculadora y todas sus funciones pblicas, entre
ellas la de sum a.
Volviendo al tem a de los apliques que llam an de los fram e,
fijaos en este ejem plo:
im port java.awt.*;
im port java.applet.*;

public class Mixta extends Applet


{
Fram e F;
public void init()
{
F = new Fram e("Hola, ste es un Fram e");
F.setSize(100,50);
F.show();
}
public void paint(Graphics g)
{
g.drawString("Yo soy un aplique",10,20);
new p();
}

public void destroy()


{
String [] param ={""};
Ventana.m ain(param );

class p extends Fram e


{
p()
{
setTitle("Otro Fram e puesto en marcha por el aplique");
setSize(250,100);
setLocation(200,300);
show();
new Dialog(this,"sta es una dialog");
}
public void paint(Graphics g)
{
g.drawString("Podra ser un banner publicitario",10,40);

}
Lo ponis en un archivo llam ado Mixta.java, y lo pondris en
m archa creando un archivo Mixta.html que incluye:
<htm l>
<head>
<title>mixta</title>
</head>
<body>
Lo siguiente es un aplique:<BR>
<applet code="Mixta.class" width=200 height=100>Tu
browser es viejo, tienes que cambiarlo!</APPLET>
</body>
</htm l>
Ponedlo en marcha y a ver lo que ocurre. Siem pre el aplique
pasa en segundo plano, es decir, coloca otra ventana
encima, y despes vuelve al primer plano.

Interfaces grficas: GUI e AWT

Antes de empezar ste que es uno de los captulos m s

interesantes del curso, introducimos el paquete awt y


explicamos qu es un componente GUI.
Veremos tambin unos componentes que son contenedores
para otros componentes.
El paquete Abstract Window Toolkit pone a disposicin del
program ador una serie de clases e interfaces grficas.
El paquete java.awt incluye tambin unos subpaquetes que
son:
java.awt.color
java.awt.datatransfer
java.awt.dnd
java.awt.event
java.awt.font
java.awt.geom
java.awt.im
java.awt.im age
java.awt.im age.renderable
java.awt.print
Analizaremos algunas funciones. Las clases del paquete
swing han sido construidas sobre las clases awt. Swuing es
actualmente el paquete ms utilizado para construir
interfaces grficas y las veremos enseguida.
Awt incluye:
Interfaces ActiveEvent, interfaces para sucesos que saben
cmo se han activado.
Adjustable, interfaces para objetos que tienen un valor
num rico entre una serie de valores.
Composite, interfaz que sirve para redactar las prim itivas
grficas de awt.

CompositeContext, am biente optimizado para las


operaciones de composicin de prim itivas.
Item Selectable, interfaz para objetos que incluyen un
conjunto de item de los que pueden ser
seleccionados cero o m s de uno. (Generalmente se pueden
seleccionar por lo m enos y al m ximo un item . Esta interfaz
elim ina esta limitacin).
LayoutManager, interfaz para las clases que incluirn unos
gestores de ajuste de pgina.
LayoutManager2, como arriba.
MenuContainer, superclase de todos los m ens.
Paint, esta interfaz define los colores que hay que utilizar
para las operaciones grficas usando Graphics2D.
PaintContext, ambiente optimizado para las operaciones de
redaccin de primitivas grficas usando
Graphics2D.
PrintGraphics, define el contexto para imprimir.
Shape, definicciones para construir una form a geomtrica.
Stroke, m s decoraciones para las form as.
Transparency, define los tipos m s comunes de
transparencia.
Clases
AlphaComposite, clase que implem enta las composiciones
del factor alfa de los colores utilizando el blending y la
transparecia de grfica y las im genes.
AWTEvent, root de los sucesos de AWT.
AWTEventMulticaster, dispatcher para suceos AWT, eficaz y
multiprogram able. Hace el multicast de sucesos a varios
componentes.
AWTPerm ission, para los perm isos AWT.
BasicStroke, atributos para las lneas externas de las

primitivas grficas.
BorderLayout, es el primer gestor de ajuste de lnea. Estos
gestores, que analizaremos dentro de muy poco, sirven apra
disponer los elem entos (los componentes) en los
contenedores. ste divide el contenedor en 5 partes: norte,
sur, este, oeste y centro.
Button, clase de los botones.
Canvas, rea en la que se puede dibujar una aplicacin.
CardLayout, otro gestor de layout.
Checkbox, CheckboxGroup, CheckboxMenuItem gestionan
los botones de tipo booleano (apretado o no apretado)
Choice, presenta un m en a cortina para elegir.
Color, colores en RGB o en otros espacios arbitrarios de
colores.
Component, Clase de la que derivan todos los componentes
GUI (pulsadores, etiquetas,)
ComponentOrientation, orientacin de los componentes.
Container, contenedor de los componentes.
Cursor, cursores.
Dialog, ventanas de dilogo en las que se indican errores y
no slo eso.
Dim ension, cajas que gestionan el tam ao de los
componentes, la altura y la anchura.
Event, clase que gestiona los sucesos segn el viejo modelo
de gestin de los sucesos (Java 1.0). Se ha dejado para que
se puedan trabajar las viejas aplicaciones y apliques Java y
se declara deprecated. En efecto, este modelo se ha
cambiado porque, en situaciones complejas, es decir, con
muchos componentes puestos unos encim a de otros, no se
entenda qu componente reciba el suceso.
EventQueue, cola de sucesos.
FileDialog, dialog especial que gestiona el input y el output

del archivo. Es muy cmoda.


FlowLayout, otro gestor del ajuste de lnea.
Font, fonts para el texto.
FontMetrics, atributos para las font.
Fram e, clase ya analizada que implementa las ventanas con
ttulo y m arco.
GradientPaint, rellena las figuras con colores lineares.
Graphics, contexto grfico en el que se puede dibujar.
Graphics2D, nuevo contexto grfico, incluido con Java 2, que
da otras sofisticadas posibilidades al dibujo.
GraphicsConfiguration, describe las caractersticas del
destino de la grfica que puede ser el monitor o la
im presora.
GraphicsConfigTem plate, utilizada para obtener una
GraphicsConfiguration vlida.
GraphicsEnvironm ent, describe los am bientes grficos y los
font que se pueden utilizar para cada especfica plataform a
de Java.
GraphicsDevice, describe el GraphicDevice que se puede
utilizar en un cierto ambiente.
GridBagConstraints, GridBagLayout, GridLayout, gestores del
ajuste de lnea.
Image, superclase para todas las clases que representan una
im gen grfica.
Insets, representa el borde de un contenedor.
Label, etiqueta.
List, listado
MediaTracker, clase de utilidad para gestionar objetos
multim ediales.
Menu, m en de tipo pull-down (a descenso).
MenuBar, barra de los m ens.
MenuComponent, superclase de todos los componentes de

los m ens.
MenuItem , Voz de m en.
MenuShortcut, sirve para representar el acelerador para una
voz de m en.
Panel, contenedor.
Point, punto en las coordenadas x,y.
Polygon, polgono.
PopupMenu, m en de tipo invisible.
PrintJob, sirve para inicializar y para imprimir.
Rectangle, rectngulo.
RenderingHints, incluye ayudas para el rendering utilizadas
por Graphics2D.
RenderingHints.Key, define las teclas utilizadas para
controlar los diferentes aspectos del rendering.
Scrollbar, barra de desplazam iento.
ScrollPane, panel con dos barras de desplazamiento.
SystemColor, representa los colores simblicos de un objeto
GUI en un sistem a.
TextComponent, superclase de todos los componentes que
incluyen el texto.
TextArea, rea de testo.
TextField, simple lnea de texto.
TexturePaint, cmo rellenar una figura con una texture.
Toolkit, superclase del Abstract Window Toolkit.
Window, ventana (sin borde y barra de men).
Excepciones
AWTException
IllegalComponentStateException
Errores
AWTError

Visto este recorrido panorm ico por el paquete informtico,


intentaremos comprender para qu sirven estas clases.
Entre todas las clases distinguimos algunas segn lo que
hacen.
En prim er lugar, hemos visto unas clases Fram e, Dialog e
Windows, que representan unas ventanas. Estas ventanas
incluyen unos mens (las prim eras dos) y unos componentes
GUI y para incluirlos hay que tener unos contenedores.
Pertenecen a este tipo Container y Panel. Cada Contenedor
puede incluir un Layout Manager que gestiona la colocacin
de varios componentes en el m ismo contenedor y puede
incluir incluso otros contenedores, que pueden crear
estructuras complejas.
Finalm ente hemos visto los verdaderos componentes GUI
que se aaden a los contenedores, por ejem plo, Label. En el
ejem plo que ponemos a continuacin aadimos una label al
contenedor del Fram e.
im port java.awt.*; public class Etiqueta extends Fram e
{
Label et=new Label();
public Etiqueta(String etiqueta)
{

et.setText(etiqueta);
setTitle("Etiqueta "+etiqueta);
add(et);
pack();

show();
}
public static void m ain (String[] a)
{
try
{new Etiqueta(a[0]);}
catch (ArrayIndexOutOfBoundsException e)
{System .out.println("ERROR: teclear java Etiqueta
CADENA");};
}
}
Como ya hemos dicho, los GUI van tanto en los Fram e como
en Applet, por lo tanto se puede pensar en la versin applet
del programa anterior.
im port java.applet.*;
im port java.awt.*;
public class ApplEtiqueta extends Applet
{
Label et=new Label();
public void init ()
{

et.setText("Hola");
add(et);

}
Se pondr en un archivo llam ado ApplEtiqueta.java y se
invocar desde un archivo html que incluye:
<htm l>
<head>
<title>
</title>
</head>
<body>
<APPLET code="ApplEtiqueta.class" width=200
height=100>
</APPLET>
</body>
</htm l>
En el paquete swing todo es muy parecido, aunque la
gestin de los contenedores es un poco diferente.

Las etiquetas y los botones

Em pezamos este recorrido panorm ico sobre los GUI. Para


utilizar varios componentes en la m ism a ventana
necesitamos uno o m s contenedores. stos los
analizaremos sucesivam ente, sin embargo tendr que
utilizarlos de vez en cuando en este apartado sin haberlos
explicado.
Estoy seguro de que no tendris problem as para comprender
los program as porque usar tanto los Layout como los
Container de form a muy simple. Sin embargo os pido perdn
si este procedimiento os puede causar algn inconveniente.
En particular, utilizar los Panel o utilizar unas constantes
de la clase BorderLayout, que separa el Container, en este
caso el Panel, en cinco zonas, NORTH, SOUTH, WEST, EAST
e CENTER.
En esta leccin analizaremos dos componentes, los m s
sim ples, las Label y los Botones. Las primeras no tienen
ningn suceso asociado, mientras los segundos, segn el
tipo de botn, tienen dos tipos de sucesos asociados..
Etiquetas
Em pezamos nuestra panormica sobre los componentes
analizando el primer elem ento simple, la etiqueta, que, entre
otras cosas, ya hem os utilizado. La etiqueta es un
contenedor para un texto. Esta hace aparecer en la pantalla
una simple lnea de texto que el usuario no puede editar, y
que, sin embargo, la aplicacin puede cam biar.
La etiqueta, invocada en Java Label, se encuentra en el

paquete java.awt. Por lo tanto para ser utilizada, nuestro


program a tendr que empezar una import java.awt.Label
(para incluir slo la clase Label del paquete), o import
java.awt.* (para incluir todas las clases del paquete)
internamente al program a que quiere utilizarla, por lo tanto,
tendr que declarar un objeto de tipo Label de la siguiente
form a:
Label etiqueta = new Label();
o, si no ha sido importado el paquete java.awt:
java.awt.Label etiqueta = new Label();
La Label tiene tres constructores:
Label() , que construye una etiqueta vaca. Label(String
text), que construye una etiqueta con texto Text, justificada
a la izquierda. Label(String text, int alignment) , que
construye una etiqueta con texto Texto, justificada con
alignm ent. Los valores de alignment son: Label.LEFT,
Label.RIGHT, y Label.CENTER.
Algunos m todos del objeto son:
int getAlignm ent(), da la justificacin actual del objeto.
String getText() , da el texto incluido en el label.
void setAlignment(int alignm ent), cambia la justificacin de
la Label con alignm ent.
void setText(String text), ajusta el texto de la Label.
Adem s existe el m todo AccessibleContext

getAccessibleContext(), que veremos cuando analicemos los


contenedores. Realm ente la Label es un contenedor de
texto.
Label viene de la siguiente jerarqua:

Por lo tanto hereda los m todos de Object y los de


java.awt.Component. Todos los componentes GUI se
heredan de Component, por lo tanto, al final de la
panormica de los GUI hablaremos de Component que
incluye m todos muy tiles para sus gestin. Por ejemplo,
m todos para ajustar y obtener informaciones sobre
tam ao, colores del fondo, colores del texto, bordes, etc
del componente.
A parte los m todos de Component, estamos listos para
utilizar las Label en nuestos program as. Por ahora no pongo
ningn ejemplo sobre el uso de las Label porque las veremos
en el siguiente prrafo cuando hablemos de los botones.
El paquete swing pone a disposicin una clase parecida
llam ada JLabel que es una extensin de Label, y que, a su
vez, pone a disposicin una amplia gam a de funciones
aadidas. Por ejemplo, es posible crear JLabel que tengan
tanto un texto como una im agen.
Botones
Otro componente muy utilizado, y de simple realizacin es el
botn. Es un poco m s complicado de la Label porque puede
recibir unos sucesos (Click el botn).

Los botones son de tres tipos: los norm ales, les Checkbox y
los radiobutton. Empezamos con los prim eros.
La clase que define los botones es Button java.awt y pone a
disposicin todos los m todos para gestionar el aspecto del
botn. Los constructores de la clase son dos:
Button(), costruye un botn sin etiqueta;
Button(String txt), costruye un botn con etiqueta txt.
Algunos m todos de la clase son:
void addActionListener(ActionListener l), aade el botn a un
objeto invocado.
ActionListener, que escucha los sucesos. Cuando se clique el
botn, el suceso ser gestionado por ActionListener.
AccessibleContext getAccessibleContext(), como para las
Label, los botones son tam bin unos contenedores.
String getActionCommand(), a cada botn se asocia una
rden que devuelve el actual.
String getLabel(), devuelve la etiqueta asociada al botn.
EventListener[] getListeners(Class listenerType), da un array
que incluye a todos los que escuchan sucesos establecidos
por este botn.
addXXXListener(), aade un oyente de sucesos de tipo tipo
XXX. En Java hay varios tipos de sucesos, los analizaremos
dentro de poco. Uno de stos es el suceso de tipo action y,
en este caso, el m todo es addActionListener( )
void removeActionListener(ActionListener l), elimina el
oyente de sucesos 1 precedentemente asociado al botn.
void setActionCommand(String comm and), ajusta la rden
asociada al botn. Al principio la rden es la etiqueta.
void setLabel(String label), ajusta la etiqueta del botn.

Ahora podemos definir nuestro primer botn. Slo tenemos


que conseguir entender cmo capturar el suceso que resulta
de la presin del mismo. Como ya dicho anteriormente,
tratar de la gestin de los suceos segn Java 2 porque el
viejo modelo de gestion de los eventos de Java 1 es obsoleto
y no funciona.
Segn Java2, definido un botn, como el suceso principal del
botn es el click, que pertenece a la fam ilia de los sucesos
Action, hay que asociar un ActionListener al mismo botn
utilizando el m todo addActionListaner(ActionListener l); Lo
que tenemos que hacer es crear un ActionListener
especializado para nuestro botn (o para nuestros botones).
ActionListener se define en el paquete java.awt.event (que
hay que incluirlo en el program a). Es una interfaz y, por lo
tanto, tiene que ser implem entada en la clase en la que se
ha definido.
Por ejemplo, estoy haciendo un Fram e llam ado Tribiln que
incluye un botn del que quiero escuchar el click y quiero
escucharlo con un ActionListener especializado por m
llam ado EscuchaTribiln. Tendr que escribir algo parecido a:
im port java.awt.*;
im port java.awt.event.*;
public class Tribiln extends Fram e
{
Button botn=new Button("Hola");
m todos de Tribiln, entre los que est el constructor, que
incluye un botn.addActionListener(new EscuchaTribiln());
public class EscuchaTribilin implements ActionListener()
{

// Gestin del suceso


} // Fin clase EscuchaTribiln dentro de Tribiln
}//Fin clase Tribiln
En EscuchaTribiln tendr que especializar todos los mtodos
de la interfaz que estoy extendiendo. ActionListener tiene
slo un mtodo:
void actionPerformed(ActionEvent e), por lo tanto, en
EscuchaTribiln tendr que definir el m todo public void
actionPerform ed(ActionEvent e). ste es el mtodo que se
invocar cuando clique el botn.
La ActionEvent que llega al m todo como parm etro, incluye
todas las inform aciones sobre el suceso, incluso la rden.
EscuchaTribiln se puede asociar incluso a ms botones. Su
actionPerform ed se invocar al click de cada uno de estos
botones. Aclaremos en seguida este concepto que, a lo
m ejor, es un poco m s difcil de las dem s cosas que hemos
hecho con el anterior ejemplo. Sin embargo, os aseguro que
una vez asim ilado el concepto, la gestin de los sucesos de
Java resultar m uy simple.
Cream os un Frame que tenga un botn y una Label: cada
vez que se clica el botn, la etiqueta da un m ensaje.
im port java.awt.*;
im port java.awt.event.*;
public class Botn extends Fram e
{
// Constructor clase Botn
Button clcam e=new Button("Clcame");

Label clicado=new Label("No m e has clicado ni siquiera una


vez");
public Botn()
{
clcam e.addActionListener(new Oyente());
// setup comando
clcam e.setActionCommand("CLIC");
// Aado un botn y la etiqueta al Frame.
// No hagis caso a las siguientes instrucciones,
// la add sirve para aadir un componente ad
// un contenedor y el segundo parm etro
// add, es decir BorderLayout, es un gestor de Layout,
// que sirve para establecer la form a en la que los objetos
// GUI se colocan en el contenedor.
add(clcame,BorderLayout.NORTH);
add(clicado,BorderLayout.SOUTH);

// m todos de Fram e
pack();
show();
}
// m ain
public static void m ain (String [] arg)
{
new Botn();

}
// Oyente de suceso Action
int Volte=2;
public class Oyente implements ActionListener
{
public void actionPerform ed (ActionEvent e)
{
String rden=e.getActionCommand();
if (rden.compareTo("CLIC")==0)
{
clicado.setText("Me has clicado");
clcam e.setLabel("Vuelve a clicarme");
clcam e.setActionCommand("RECLIC");
};
if (rden.compareTo("RECLIC")==0)
clicado.setText("Me has clicado "+(Veces++)+" veces.");
}
}// Fin Oyente

}// Fin Botn

El resultado es la siguiente ventana:

Como se ve en Oyente se gestionan dos rdenes diferentes


asociados al mismo botn y ste, cuando se clica por
prim era vez, cambia la rden asociado al suceso clic.
Intentad cambiarlo modificando la orden para estalblecer con
certeza las prim eras diez veces que se clica e imprimiendo
en la etiqueta "Has clicado nueve veces el botn" (la novena
vez).
Resum iendo, en una interfaz grfica, en prim er lugar se
program a el aspecto grfico, es decir, se incluyen los
botones, los mens, etc. Despus se crean y se aaden los
oyentes de los sucesos que, segn el suceso, invocan uno u
otro mtodo de gestin del program a (pone al da la interfaz,
calcula las funciones del program a de la que es la interfaz

grfica).
ste es un principio general de la program acin de
Interfaces Grficas, es decir, de la program acin de los
sucesos. Cada program a que utilizis funciona de esta form a
y cada program a que escribss tam bin.
El tipo de program acin es un poco diferente al que un
program ador sobre plataform a no grficas (tipo Dos, Linux
senza X-Win) est acostumbrado y al principio puede
resultar no muy simple. Sin em bargo hay que
acostumbrarse, despus es todo igual.
El segundo tipo de botones que analizamos son las
Checkbox, es decir, los botones de tipo booleano, que
retienen el estado. Se utilizan para hacer opciones no
exclusivas o exclusivas entre ellas (en este ltimo caso son
unos radiobutton). Por ejemplo, si hay que elegir entre unos
hobbies preferidos, estos botones, una vez clicados, se
quedan as y hay que volver a clicarlos para que vuelvan a la
situacin inicial.
Pra crear una Checkbox hay que crear un objeto que
pertenece a la clase Checkbox de java.awt. Los
constructores son:
Checkbox(), crea una Checkbox sin etiqueta.
Checkbox(String label), crea una Checkbox con etiqueta
label.
Checkbox(String label, boolean state), crea una Checkbox
con etiqueta label, y hay que clicarla o no segn el valor
booleano state.
En cam bio para los radiobutton:

Checkbox(String label, boolean state, CheckboxGroup


group), crea una Checkbox con etiqueta label introducida en
una particular
CheckboxGroup, que es un contenedor de Checkbox.
Checkbox(String label, CheckboxGroup group, boolean
state) crea una Checkbox con etiqueta label introducida en
una particular
CheckboxGroup, y ajustada segn el valor de state.
Prcticam ente, entre todos los botones introducidos en el
CheckboxGroup, slo uno puede ser clicado, los dem s no se
tienen que clicar. Las Checkbox del prim er tipo, como he
dicho, se utilizan para hacer unas opciones no exclusivas
como, por ejemplo, la opcin de los intereses entre una lista
de los intereses posibles. Mientras las Checkbox del segundo
tipo, es decir, los radiobuttons sirven para hacer opciones
exclusivas como, por ejemplo, la opcin de la renta de una
persona en las diferentes fases.
Entre los mtodos de la clase Checkbox los ms interesantes
son:
void addItemListener(ItemListener l) , asocia un
ItemListener a la Checkbox, el ItemListener gestiona los
sucesos de los Checkbox y no slo eso. Son un segundo tipo
de sucesos que aprenderemos a utilizar. De todas formas, se
parecen a los ActionListener, lo nico es que se asocian a los
objetos que tienen un estado.
CheckboxGroup getCheckboxGroup(), da el posible grupo en
el que se intruduce la Checkbox.
Las ya conocidas String getLabel() e EventListener[]
getListeners(Class listenerType) boolean getState(), este

m todo dice que la Checkbox se ha clicado o no.


void removeItemListener(ItemListener l), quita el actual
oyente de sucesos Item .
void setCheckboxGroup(CheckboxGroup g), ajusta un
gruppo para la Checkbox.
void setLabel(String label), ajusta la etiqueta
void setState(boolean state), ajusta el estado.
Vamos a ver ahora lo que contiene un CheckboxGroup. El
constructor no tiene parm etros y los m todos no declarados
Deprecated son tres:
Checkbox getSelectedCheckbox(), da la Checkbox
seleccionada en el grupo .
void setSelectedCheckbox(Checkbox box), ajusta la
Checkbox del grupo indicado.
String toString(), da una cadena que representa el objeto.
Ahora vam os a poner un pequeo ejemplo que usa tanto
Checkbox como RadioButton.
im port java.awt.*;
im port java.awt.event.*;
public class Check extends Fram e
{
// Constructot clase Botn
Label r=new Label("Renta anual");
Label i=new Label("Intereses");
Button sale=new Button("saledela aplicacin");

CheckboxGroup renta=new CheckboxGroup();


Checkbox r1=new Checkbox("De 0 a 10");
Checkbox r2=new Checkbox("De 11 a 30");
Checkbox r3=new Checkbox("De 31 a 70");
Checkbox r4=new Checkbox("De 71 a 100");
Checkbox r5=new Checkbox("De 101 a 200");
Checkbox r6=new Checkbox("De 201 a 500");
Checkbox r7=new Checkbox("Soy un ricachn");
Checkbox i1=new Checkbox("Esport");
Checkbox i2=new Checkbox("Inform tica");
Checkbox i3=new Checkbox("Lectura");
Checkbox i4=new Checkbox("Cine");
Checkbox i5=new Checkbox("Animales");
Checkbox i6=new Checkbox("Teveos");
Checkbox i7=new Checkbox("Loteras");
Checkbox i8=new Checkbox("Mujeres");
Checkbox i9=new Checkbox("Hombres");

public Check()
{
sale.addActionListener(new Oyente());

Panel p1=new Panel();


Panel p2=new Panel();

p1.add(r);
p1.add(r1);
p1.add(r2);
p1.add(r3);
p1.add(r4);
p1.add(r5);
p1.add(r6);
p1.add(r7);
r1.setCheckboxGroup(renta);
r2.setCheckboxGroup(renta);
r3.setCheckboxGroup(renta);
r4.setCheckboxGroup(renta);
r5.setCheckboxGroup(renta);
r6.setCheckboxGroup(renta);
r7.setCheckboxGroup(renta);

add(p1,BorderLayout.NORTH);

p2.add(i);
p2.add(i1);
p2.add(i2);
p2.add(i3);
p2.add(i4);
p2.add(i5);
p2.add(i6);
p2.add(i7);
p2.add(i8);
p2.add(i9);

add(p2,BorderLayout.CENTER);
add(sale,BorderLayout.SOUTH);
// m todos de Fram e
pack();
show();
}
// m ain
public static void m ain (String [] arg)
{
new Check2();
}

// Oyentes de sucesos Action


public class Oyente implements ActionListener
{
public void actionPerform ed (ActionEvent e)
{

System .out.println("afiliacin al sito XXXXXXX.it");


System .out.print("ganancia anual ");
if (r1.getState()) System .out.println(r1.getLabel());
else if (r2.getState()) System .out.println(r2.getLabel());
else if (r3.getState()) System .out.println(r3.getLabel());
else if (r4.getState()) System .out.println(r4.getLabel());
else if (r5.getState()) System .out.println(r5.getLabel());
else if (r6.getState()) System .out.println(r6.getLabel());
else if (r7.getState()) System .out.println(r7.getLabel()+"
(Qu suerte!)");
else System .out.println("NO DECLARADO");
System .out.println("Intereses declarados:");
if (i1.getState()) System.out.println("\t"+i1.getLabel());
if (i2.getState()) System.out.println("\t"+i2.getLabel());
if (i3.getState()) System.out.println("\t"+i3.getLabel());
if (i4.getState()) System.out.println("\t"+i4.getLabel());
if (i5.getState()) System.out.println("\t"+i5.getLabel());
if (i6.getState()) System.out.println("\t"+i6.getLabel());
if (i7.getState()) System.out.println("\t"+i7.getLabel());
if (i8.getState()) System.out.println("\t"+i8.getLabel());
if (i9.getState()) System.out.println("\t"+i9.getLabel());
System .exit(0);
}
}// Fin Oyente
}// Fin Botn
Fig 4: Ventana del program a

He tenido que usar otra vez los layout y tam bin los Panel.
Lo siento porque todava no los hemos tratado, sin embargo,
es la nica forma para introducir ms GUI en la m isma
ventana. Por ejemplo, intentad quitar los Panel y,
sucesivam ente, aadid todo directam ente a las ventanas, sin
utilizar los Layout. Vis a ver lo que ocurre.
En la aplicacin hay un botn que sirve para cerrar la
ventana porque todava no sabemos gestionar los sucesos de
la ventana, como el close, que en este caso no funciona.
Dentro de poco podremos gestionar incluso stos.
En la aplicacin no he gestionado los sucesos de las
Checkbox porque no lo he necesitado. Hay situaciones en las
que se tienen que gestionar, en las que, adems del estado
del botn cambia algo, por ejemplo, el estado de algn GUI.
Lo vemos en este ejemplo.
im port java.awt.*;
im port java.awt.event.*;
public class Check2 extends Fram e
{
// Constructot clase Botn

Button cierra=new Button("Sale de la aplicacin");


Checkbox i1=new Checkbox("primeros 3");
Checkbox i2=new Checkbox("segundos 4");
Checkbox ii1=new Checkbox("uno");

Checkbox ii2=new Checkbox("dos");


Checkbox ii3=new Checkbox("tres");
Checkbox ii4=new Checkbox("cuatro");
Checkbox ii5=new Checkbox("cinco");
Checkbox ii6=new Checkbox("seis");
Checkbox ii7=new Checkbox("siete");

public Check2()
{
cierra.addActionListener(new Oyente());

Panel p1=new Panel();


Panel p2=new Panel();
p1.add(ii1);
p1.add(ii2);
p1.add(ii3);
p1.add(ii4);
p1.add(ii5);
p1.add(ii6);
p1.add(ii7);

ii1.addItemListener(new AItem 1());


ii2.addItemListener(new AItem 1());
ii3.addItemListener(new AItem 1());
ii4.addItemListener(new AItem 1());
ii5.addItemListener(new AItem 1());

ii6.addItemListener(new AItem 1());


ii7.addItemListener(new AItem 1());

i1.addItemListener(new AItem 2());


i2.addItemListener(new AItem 2());
add(p1,BorderLayout.NORTH);
p2.add(i1);
p2.add(i2);

add(p2,BorderLayout.CENTER);
add(cierra,BorderLayout.SOUTH);
// m todos de Fram e
pack();
show();
}
// m ain
public static void m ain (String [] arg)
{
new Check();

// Oyente de sucesos Action


public class Oyente implements ActionListener
{
public void actionPerform ed (ActionEvent e)
{System .exit(0);}
}// Fin Oyente
// Oyente de sucesos Item
public class AItem 1 implem ents ItemListener
{
public void item StateChanged(Item Event e)
{
i1.setState(ii1.getState()&&
ii2.getState()&&
ii3.getState());
i2.setState(ii4.getState()&&
ii5.getState()&&
ii6.getState()&&
ii7.getState());
}
}//Fin AItem1

public class AItem 2 implem ents ItemListener


{
public void item StateChanged(Item Event e)
{
ii1.setState(i1.getState());
ii2.setState(i1.getState());
ii3.setState(i1.getState());
ii4.setState(i2.getState());
ii5.setState(i2.getState());
ii6.setState(i2.getState());
ii7.setState(i2.getState());
}
}//Fin AItem2

}// Fin Botn

Contenedores y Gestin de los Layout

En la leccin anterior hemos visto como introducir en


nuestras aplicaciones y en nuestros apliques unas etiquetas
y unos botones. Para hacerlo hemos utilizado unos
contenedores y unos layout sin saber cmo funcionaban. En
este leccin analizeremos sus funcionamientos y cmo
aprovecharlos para m ejorar nuestras interfaces.

Em pezamos con describir la clase Container del paquete


java.awt. Es una extensin de la clase Component de la que
proceden todos los componentes GUI y, en realidad, ste
mismo es un componente GUI.

Un Container es un contenedor para los objetos GUI y, por lo


tanto, tam bin para los dems container. Se utiliza junto a
un Layout Manager y perm ite que abarquen m s de un GUI
(y Contenedores), permitiendo que aparezcan varios objetos
en nuestras interfaces. Vemos qu contiene la clase.
Container() , es el nico constructor de la clase.
Unos m todos: Component add(Component comp), aade el
componente al final del contenedor.
Component add(Component comp, int index), aade el
componente en la posicin indicada por el contenedor.
void add(Component comp, Object constraints) e void
add(Component comp, Object constraints, int index) , como
antes, lo nico es que especifica unas constantes para el
componente que se ha introducido.
Component add(String nam e, Component comp), aade al
contenedor el componente y le da un nombre.
void addContainerListener(ContainerListener l), ajusta el
ContainerListener que escuchar los sucesos que han

ocurrido en el contenedor.
void doLayout(), provoca la disposicin de los componentes
en el contenedor.
Component findComponentAt(int x, int y), devuelve el
componente que se encuentra en la posicin especificada del
contenedor (posicin grfica).
Component findComponentAt(Point p) , devuelve el
componente que se encuentra en la posicin especificada del
contenedor (posicin grfica).
float getAlignmentX(), devuelve el ajuste de lneas a lo largo
del eje X del contenedor.
float getAlignmentY(), devuelve el ajuste de lneas a lo largo
del eje Y del contenedor.
Component getComponent(int n), devuelve el ensimo
componente introducido en el contenedor.
Component getComponentAt(int x, int y), devuelve el
componente que se encuentra en la posicin especificada del
contenedor (posicin grfica).
Component getComponentAt(Point p), devuelve el
componente que se encuentra en la posicin especificada del
contenedor (posicin grfica).
int getComponentCount() , da el nmero de componentes
introducidos en el contenedor.
Component[] getComponents(), da todos los componentes
introducidos en el contenedor.
Insets getInsets(), da un objeto Insets para el contenedor.
Este objeto representa el tam ao (grfico= del contenedor.
LayoutManager getLayout(), devuelve el LayuotManager
asociado al contenedor.
EventListener[] getListeners(Class listenerType), devuelve
todos los oyentes de sucesos al contenedor.

Dim ension getMaximum Size(), devuelve el tamao m ximo


que puede tener el contenedor.
Dim ension getMinimum Size(), devuelve el tam ao m nimo
que puede tener el contenedor.
Dim ension getPreferredSize(), devuelve el tam ao preferido
por el contenedor.
void list(PrintStream out, int indent), imprim e el listado de
los componentes introducidos en el contenedor, sobre un
stream de output.
void list(PrintWriter out, int indent), imprim e en una
im presora los componentes introducidos en el contenedor.
void paint(Graphics g), dibuja el contenedor. La paint es una
funcin muy importante. Veremos cmo definirla para
dibujar en una ventana.
void paintComponents(Graphics g). dibuja todos los
componentes del contenedor.
void print(Graphics g), imprim e el contenedor (el aspecto
grfico).
void printComponents(Graphics g), imprime todos los
componentes introducidos en el contenedor (sus aspectos
grficos).
void remove(Component comp), elimina el componente
especificado por el contenedor.
void remove(int index), aparta el componente que se
encuentra en la posicin especificada en el contenedor.
void removeAll(), aparta todos los componentes introducidos
en el contenedor.
void removeContainerListener(ContainerListener l), elimina
el oyente de sucesos para containers de este container.
void setFont(Font f), ajusta las Font utilizadas por el texto en
el contenedor.
void setLayout(LayoutManager mgr), asocia al contenedor

un gestor de layout.
void update(Graphics g), vuelve a dibujar el contenedor.
void validate(), anula el contenedor y sus componentes.
Introduciendo componentes en el contenedor, como en el
ejem plo sucesivo, nos damos cuenta de que slo el ltimo
ser visualizado. Esto ocurre porque no hemos dado gestor
de Layout. En el caso de applet, en cambio, el
LayoutManager de default es el FlowLayout.
im port java.awt.*;
public class Contenedor extends Fram e
{
Label l1=new Label("Etiqueta1");
Label l2=new Label("Etiqueta2");
Label l3=new Label("Etiqueta3");
Label l4=new Label("Etiqueta4");
Label l5=new Label("Etiqueta5");
public Contenedor()
{
// uso add, porque el Fram e es una extensin de Window,
que a su
// vez am pla Container.
add(l1);
add(l2);
add(l3);
add(l4);
add(l5);

doLayout();
pack();
show();
}
public static void m ain(String [] arg)
{
new Contenedor();
}
}
Por lo tanto, vemos cmo introducir un gestor de Layout en
el contenedor. El m todo de la clase container que lo
perm ite es void setLayout(LayoutManager mgr). No nos
queda que ver cmo es el objeto de tipo LayoutManager.
LayoutManager es una interfaz. De las clases que la
im plem entan analizaremos GridLayout, FlowLayout.
Hay otra interfaz llam ada LayoutManager2, que ampla sta
y que tiene otras clases que la implem entan. De stas
veremos: CardLayout, BorderLayout, GridBagLayout,
BoxLayout, OverlayLayout.
Por lo tanto, en el mtodo setLayout () podemos utilizar
como parm etro un objeto de estas clases.
Llegados a este punto, tenemos que comprender qu
diferencia hay entre los layout manager.
El FlowLayout deja colocar los componentes de un
contenedor de la izquierda hacia la derecha en una sla
lnea.

Para utilizar el LayoutManager FlowLayout del ejemplo


precedente basta con invocar el m todo setLayout con
parm etro new FlowLayout(), y despus los componentes se
introducen autom ticam ente, de la add de la derecha hacia
la izquierda en la mism a lnea.
im port java.awt.*;
public class ContEFL extends Fram e
{
Label l1=new Label("Etiqueta1");
Label l2=new Label("Etiqueta2");
Label l3=new Label("Etiqueta3");
Label l4=new Label("Etiqueta4");
Label l5=new Label("Etiqueta5");
public ContEFL()
{
// uso add, porque el Fram e es una extensin de Window,
que a su

// vez am pla Container.


setLayout(new FlowLayout());
add(l1);
add(l2);
add(l3);
add(l4);
add(l5);
pack();
show();
}
public static void m ain(String [] arg)
{
new ContEFL();
}
}
La ventana que sale es:

El GridLayout permite colocar los componentes en un


contenedor como si se dispusieran en una plantilla.

Todos los componentes tendrn el mismo tam ao. La clase


tiene tres constructores, uno sin parm etros que crea una
planilla con 1 lnea, prcticam ente un FlowLayout, y otros
dos que permiten especificar el tam ao de la planilla.
El ejemplo anterior cambia de esta form a:
im port java.awt.*;
public class ContEGL extends Frame
{
Label l1=new Label("Etiqueta1");
Label l2=new Label("Etiqueta2");
Label l3=new Label("Etiqueta3");
Label l4=new Label("Etiqueta4");

Label l5=new Label("Etiqueta5");


public ContEGL()
{
// uso add, poruqe el Fram e es una extensin de Window,
que a su
// vez am pla Container.
setLayout(new GridLayout(2,3));
add(l1);
add(l2);
add(l3);
add(l4);
add(l5);
pack();
show();
}
public static void m ain(String [] arg)
{
new ContEGL();
}
}
La ventana es la siguiente:

El LayoutManager CardLayout permite visualizar los


componentes diferentes en plazos de tiem po diferentes, es
decir, que visualiza slo un componente a la vez. Sin
embargo el componete visualizado se puede cambiar.
Hay aqu un ejemplo del uso de CardLayout
im port java.awt.*;
im port java.awt.event.*;
public class ContECL extends Frame
{
Label l1=new Label("Etiqueta1");
Label l2=new Label("Etiqueta2");
Label l3=new Label("Etiqueta3");
Label l4=new Label("Etiqueta4");
Label l5=new Label("Etiqueta5");
Panel p=new Panel(new GridLayout(2,1));
CardLayout CL=new CardLayout(14,14);
Panel p1=new Panel(CL);
Panel NPB=new Panel(new FlowLayout());

public ContECL()
{

p.add(NPB);
p.add(p1);
Button N=new Button("Prximo");
Button P=new Button("Anterior");
NPB.add(P);
NPB.add(N);
P.addActionListener(new ActionListener()
{
public void actionPerform ed(ActionEvent e)
{
CL.previous(p1);
}
}
);
N.addActionListener(new ActionListener()
{
public void actionPerform ed(ActionEvent e)
{
CL.next(p1);
}
}
);

p1.add("uno",l1);
p1.add("dos",l2);
p1.add("tres",l3);
p1.add("cuatro",l4);
p1.add("cinco",l5);
add(p);
pack();
show();
}
public static void m ain(String [] arg)
{
new ContECL();
}
}
El resultado de los ejemplos son las siguientes ventanas:

Muestran como las cinco etiquetas aparecen en la mism a


posicin en plazos de tiempo diferentes.
Notad que en el ejem plo no se han utilizado los dem s
gestores de Layout para que se puedan introducir los
botones Prximo y Anterior.
BorderLayout es uno de los gestores de Layout ms
utilizados. Permite introducir en un contenedor cinco
componentes, uno al Norte, uno al Sur, uno al Este, uno al

Oeste y otro al Centro.


El tam ao del contenedor lo establecer el componente
central. Las cinco posiciones estn indicadas por los
contenedores de la clase:
BorderLayout.NORTH
BorderLayout.SOUTH
BorderLayout.EAST
BorderLayout.WEST
BorderLayout.CENTER
hay aqu un ejemplo del uso de BorderLayout. He cam biado
los colores de fondo de las etiquetas para que se vea el
componente entero.
im port java.awt.*;
public class ContEBL extends Fram e
{
Label l1=new Label("Etiqueta al Norte",Label.CENTER);
Label l2=new Label("Etiqueta al Sur",Label.CENTER);
Label l3=new Label("Etiqueta al Este",Label.CENTER);
Label l4=new Label("Etiqueta al Oeste",Label.CENTER);
Label l5=new Label("Etiqueta al Centro",Label.CENTER);
public ContEBL()
{
// uso add porque el Fram e es una extensin de Window,
que a su
// vez am pla Container.

l1.setBackground(Color.pink);
l2.setBackground(Color.lightGray);
l3.setBackground(Color.green);
l4.setBackground(Color.yellow);
l5.setBackground(Color.orange);

setLayout(new BorderLayout());
add(l1,BorderLayout.NORTH);
add(l2,BorderLayout.SOUTH);
add(l3,BorderLayout.EAST);
add(l4,BorderLayout.WEST);
add(l5,BorderLayout.CENTER);
pack();
show();
}
public static void m ain(String [] arg)
{
new ContEBL();
}
}
El resultado es:

Hay tambin otros gestores de Layout, que no analizaremos,


y que, sin embargo, podis estudiar junto a stos en la
documentacin oficial de las Java Developm ent Kit.

Mens

Un m en en una aplicacin no es m s que un MenuBar en el


que hay varios mens.
Pensemos en un program a cualquiera con las voces de men
File Edit y Help. Estas tres voces en Java son unos objetos
de la clase Men y se tienen que aadir a un objeto de la
clase MenuBar que se une a la ventana. Cada men tiene
varias voces. por ejemplo, el men File tendr las voces:
Abrir, Cerrar, Guarda y Salir. stos en Java son unos objetos
de la clase MenuItem (o tam bin Men si incluyen otros
subm ens).

Por lo tanto, si a una aplicacin le quisieramos aadir un


m en tendramos hacer las siguientes cosas siguiendo un
rden cualquiera:

Crear los objetos MenuItem

Crear los objetos men y pegarles los MenuItem

Crear una MenuBar y pegarles los Mens


Adem s, como siempre, tenemos que escribir unos gestores
para los sucesos de los m ens y asociarlos a los m ens.
Veam os, en prctica, cmo se construye un menu,
empezando por los MenuItem .
Los sucesos de los MenuItem son los que tenemos que
gestionar nosotros a diferencia de los sucesos de los mens
que los gestiona el sistem a. Mientras los segundos sirven
para que aparezcan y desaparezcan las voces del men, los

prim eros son los clics sobre la orden correspondiente al


Item .
Por lo tanto, para stos tendremos que escribir unos
ActionListener, como para los botones. Realmente no son
otra cosa que unos botones especiales. Los constructores
son tres:
MenuItem () , que construye un MenuItem sin etiqueta.
MenuItem (String label), que construye MenuItem con
etiqueta label.
MenuItem (String label, MenuShortcut s), que construye un
MenuItem con etiqueta label y acelerador (tecla de opcin
rpida) definido en MenuShortcut s.
Algunos m todos son:
addActionListener(ActionListener l), asocia un ActionListener
al MenuItem para escuchar los sucesos de tipo ActionEvent
(el clic).
void deleteShortcut(), borra la tecla de opcin rpida para el
m enuitem .
String getActionCommand(), da la accin asociada al
MenuItem . La accin es la que pasa al actionListener del
botn para identificar el botn mismo. As varios item
pueden tener el mismo gestor de sucesos que podr
distinguir el botn clicado basndose en la rden que le
llega.
String getLabel(), devuelve la etiqueta del MenuItem
EventListener[]getListeners(Class listenerType) , devuelve
todos los oyentes de sucesos asociados al MenuItem , del
tipo listenerType.
MenuShortcut getShortcut(), devuelve la definicin del

acelerador para el MenuItem .


boolean isEnabled(), dice si el m en esta disponible o no. Si
no lo est se visualizar en gris.
void removeActionListener(ActionListener l), elimina el
oyente asociado.
void setActionCommand(String comm and), ajusta la orden
asociada al MenuItem. Si no est especificado, la rden es la
etiqueta del MenuItem .
void setEnabled(boolean b), habilita y deshabilita el
MenuItem .
void setLabel(String label), ajusta la etiqueta para el
MenuItem .
void setShortcut(MenuShortcut s), define el acelerador para
el m en.
Por lo tanto, para crear los Item del m en File descrito antes
tendremos que escribir:
MenuItem abrir=new MenuItem ("Abrir");
MenuItem cerrar=new MenuItem("Cerrar");
MenuItem guardar=new MenuItem ("Guardar");
MenuItem salir=new MenuItem ("Salir");
Por tanto cream os el objeto Menu para pegar los MenuItem .
Dos constructores del objeto son:
Menu(), construye un Men sin etiqueta
Menu(String label), construye un m en con etiqueta label.
Entre los mtodos hay:
MenuItem add(MenuItem mi), aade un MenuItem al Men.

void add(String label), aade una etiqueta al Men (tipo


separador).
void addSeparator(), aade un verdadero separador al
m en, es decir, una lnea.
Aadiendo objetos a un m en de esta forma, se colocarn
en el m ismo rden en el que se aaden. Para especificar, en
cambio, la posicin en que si quieren introducir hay que usar
los m todos:
void insert(MenuItem menuitem , int index)
void insert(String label, int index)
void insertSeparator(int index)
Los m todos MenuItem getItem (int index) e int
getItem Count() sirven para coger un item establecido en
una posicin y para conocer el nmero de MenuItem
incluidos en un men.
Para eliminar los Item del m en, en cambio, se utilizan los
m todos:
void remove(int index)
void remove(MenuComponent item ) e
void removeAll()
Por lo tanto, para crear nuestro m en File tendremos que
escribir:
Menu file= new Menu("File");
file.add(abrir);
file.add(guardar);
file.add(cerrar);
file.addSeparator();

file.add(salir);
Llegados e este punto, suponiendo haber creado tambin
Edit y Help, tenemos que aadirle el MenuBar que se crea
utilizando el constructor MenuBar().
En esta barra estan los m todos remove y removeAll como
para los mens, y est la add:
Menu add(Menu m);
Por lo tanto nuestro MenuBar se tendr que crear de la
siguiente form a:
MenuBar barra=new MenuBar();
barra.add(file);
barra.add(edit);
barra. setHelpMenu(help);
Este ltimo mtodo es especial para aadir un m en de
ayuda.
Finalm ente, no nos queda que asociar la barra de m en a
nuestra ventana. Esto es muy simple porque nuestra
ventana ser una extensin de Fram e y en fram e est el
m todo:
setMenuBar(MenuBar mb);
En nuestro caso ser setMenuBar (barra);
CUIDADO: con awt no es posible introducir men en Dialog y
en Applet (los que se ven son falsos mens, es decir, se
program an dibujando unos m ens o no son slo awt),

mientras con swing s.


A continuacin mostramos el listado de una aplicacin que
define un m en y escucha los sucesos:
im port java.awt.*;
im port java.awt.event.*;
public class Ventanam en extends Fram e
{
MenuItem abrir=new MenuItem ("Abrir");
MenuItem cerrar=new MenuItem("Cerrar");
MenuItem salvar=new MenuItem ("Guardar");
MenuItem salir=new MenuItem ("Salir");
MenuItem cortar=new MenuItem ("Cortar");
MenuItem copiar=new MenuItem ("Copiar");
MenuItem pegar=new MenuItem ("Pegar");
MenuItem eliminar=new MenuItem ("Elim inar");
MenuItem buscar=new MenuItem ("Buscar");
MenuItem sustituir=new MenuItem ("Sustituir");
MenuItem ayuda=new MenuItem ("ndice");

Menu file= new Menu("File");


Menu edit= new Menu("Edit");
Menu help= new Menu("Help");
MenuBar barra = new MenuBar();

Label resultado=new Label("Ninguna voz de men clicada");


public Ventanam en()
{
setupSucesos();
file.add(abrir);
file.add(guardar);
file.add(cerrar);
file.addSeparator();
file.add("Men Salir");
file.addSeparator();
file.add(salir);
edit.add(cortar);
edit.add(copiar);
edit.add(pegar);
edit.add(eliminar);
edit.addSeparator();
edit.add(buscar);
edit.add(sustituir);
help.add(ayuda);
barra.add(file);
barra.add(edit);
barra.setHelpMenu(help);
setMenuBar(barra);
add(resultado);

pack();
show();
addWindowListener(new Ventanam enWindowListener());
}
void setupSucesos()
{
abrir.addActionListener(new OyenteMen());
salvar.addActionListener(new OyenteMen());
cerrar.addActionListener(new OyenteMen());
salir.addActionListener(new OyenteMen());
cortar.addActionListener(new OyenteMen());
copiar.addActionListener(new OyenteMen());
pegar.addActionListener(new OyenteMen());
elim inar.addActionListener(new OyenteMen());
buscar.addActionListener(new OyenteMen());
sustituir.addActionListener(new OyenteMen());
ayuda.addActionListener(new OyenteMen());

public static void m ain(String[] arg)


{
new Ventanamen();

}
class OyenteMen implem ents ActionListener
{
public void actionPerform ed (ActionEvent e)
{
resultado.setText(" Clicado "+e.getActionComm and());
if (e.getActionCommand().compareTo("Salir")==0)
System .exit(0);
}
}
class Ventanam enWindowListener implem ents
WindowListener
{
public void windowActivated(WindowEvent e)
{
System .out.println("Escuchado un Window Activated");
}
public void windowClosed(WindowEvent e)
{
System .out.println("Escuchado un Window Closed");
}
public void windowClosing(WindowEvent e)
{
System .out.println("Escuchado un Window Closing");

System .exit(0);
}
public void windowDeactivated(WindowEvent e)
{
System .out.println("Escuchado un Window Deactivaded");
}
public void windowDeiconified(WindowEvent e)
{
System .out.println("Escuchado un Window Deiconified");
}
public void windowIconified(WindowEvent e)
{
System .out.println("Escuchado un Window Iconified");
}
public void windowOpened(WindowEvent e)
{
System .out.println("Escuchado un Window Opened");
}
}
}
Como acabamos de ver en el ejemplo, hay otro oyente de
sucesos. Escucha los sucesos de tipo WindowEvent y sirve
para escuchar sucesos de la ventana.
Para asociarlo a la ventana se utiliza el m todo
addWindowListener(WindowListener l); en el que

WindowListener es el oyente de los sucesos. Para definir un


oyente de sucesos hay, por lo tanto, que implem entar la
interfaz WindowListener y volver a definir todos los mtodos:
class MOYENTE implem ents WindowListener
Los m todos para definir son:
public void windowActivated(WindowEvent e)
public void windowClosed(WindowEvent e)
public void windowClosing(WindowEvent e)
public void windowDeactivated(WindowEvent e)
public void windowDeiconified(WindowEvent e)
public void windowIconified(WindowEvent e)
public void windowOpened(WindowEvent e)
Hay que volver a definirlos todos.
Si ponemos en m archa el ejem plo vemos, gracias a las
System .out.println colocadas en los m todos redefinidos, a
qu tipo de suceso de la ventana estn asociados los
distintos m todos, como, por ejemplo, windowClosed se
invoca cuando se pulsa la X de la ventana.
Como ejercicio intentad escribir unos WindowListener para
escuchar el suceso cerrar Ventana para todos los Frame
definidos en los ejemplos de este captulo (los dej a posta
sin definicin).
Los m ens analizados no son los nicos que se pueden
im plem entar en Java. Otro tipo de men es el de tipo Popup,
es decir, el m en que se asocia a un componente o a una
posicin. Un ejemplo de men popup es el que sale en el

desktop del sistem a operativo Windows cuando se aprieta el


botn derecho del ratn (vase Dibujo).

Para crear un m en popup hay que crear un objeto que


pertenezca a la clase PopupMenu, utilizando uno de los
constructores: PopupMenu(), PopupMenu(String label), que
crean, respectivam ente, un men sin o con etiqueta.
PopupMenu es una extensin de Men, por lo tanto hereda
los m todos incluso los que sirven para aadir y eliminar
unos MenuItem . En cambio, entre sus m todos hay uno para
visualizar el m en en una posicin establecida de la pantalla
con respecto a un determ inado componente:
show(Component origin, int x, int y)

Listas y selecciones

A m enudo en las interfaces de nuestro Apliques nos sucede


que el usuario tiene que hacer una o ms selecciones entre
varias posibilidades. Para esto tenemos que hacer una lista
de las posibilidades y despus leer la opcin.
Para hacerlo podemos utilizar las listas, que representan una
serie de objetos y dan la posibilidad de elegir. Pensemos, por
ejem plo, en un aplique que gestiona las reservas de visitas
guiadas de algunas localidades y que nos obligue a elegir
una.
Adem s de las form conocidas para el Nombre, Apellidos,
etc.. tendremos la lista de las localidades. Analicemos cmo
podemos implem entarla. Para construir la lista utilizaremos
uno de los tres constructores:
List() , crear una nueva lista
List(int rows), crea una nueva lista con rows lneas
List(int rows, boolean m ultipleMode), crea una nueva lista
con rows lneas, y se le dice que, segn el valor booleano
multipleMode, se podrn elegir uno o m s elem entos de la
lista.
En nuestro caso utilizaremos la tercera forma de constructor.
List lista=new List(0,true);
Algunos m todos que podemos utilizar en las listas son:
void add(String item ) e void add(String item, int index),
para colgar, al final de la lista o en cierta posicin, un nuevo
componente.

void addActionListener(ActionListener l), para asociar un


ActionListener a la lista.
void addItemListener(ItemListener l), para asociar un
ItemListener a la lista.
String getItem (int index), para tener el elemento en posicin
indicada.
int getItemCount() , para obtener el nmero de los
elem entos.
String[] getItem s(), para obtener todos los elem entos.
EventListener[] getListeners(Class listenerType) , para
obtener los oyentes asociados a la lista del tipo que
queremos.
Dim ension getMinimum Size(), da el tam ao m nimo de la
lista.
Dim ension getPreferredSize(), da el tam ao preferido para la
lista.
int getRows() , dice el nm ero de lneas al momento visibles
en la lista.
Int getSelectedIndex(), da el ndice del elem ento
seleccionado.
int[] getSelectedIndexes(), da los ndices de los elem entos
seleccionados.
String getSelectedItem (), da el objeto seleccionado.
String[]getSelectedItem s(), da los objetos seleccionados.
Object[] getSelectedObjects(), da la lista de los elem entos
seleccionados en un vector de objetos.
boolean isIndexSelected(int index), dice si el ndice est
seleccionado.
boolean isMultipleMode(), dice si, en la lista, se pueden
seleccionar m s elem entos.
void makeVisible(int index), visualiza el item en la posicin

indicada.
void remove(int position), void remove(String item), elimina
los elem entos indicados por el ndice o la etiqueta.
void removeAll(), elimina todos los elem entos de la lista.
void removeActionListener(ActionListener l) e void
rem oveItem Listener(Item Listener l), eliminan los oyentes de
sucesos definidos para la lista.
void replaceItem (String newValue, int index), modifica el
elem ento especificado.
void select(int index), selecciona el elem ento indicado en la
lista.
void setMultipleMode(boolean b), dice a la lista si es posible
seleccionar slo un elem ento o m s de uno.
Veam os el ejemplo sobre el uso de las listas.
im port java.awt.*;
im port java.awt.event.*;
public class listas extends Fram e
{
List lista=new List(0,true);
Label text=new Label("Maravillas que se pueden visitar en la
localidad elegida");
public listas()
{
super("Elegir itinerario");
lista.add("Bienvenido");
lista.add("Foiano de Val Fortore");

lista.add("Baselice");
lista.add("San Bartolom eo en Galdo");
lista.add("San Marco de los Cavoti");
lista.add("Montefalcone en Val Fortore");
lista.add("Pesco Sannita");
lista.add("Colle Sannita");
lista.add("Castelvetere en Val Fortore");
lista.add("Castelfranco en Miscano");
lista.add("Ginestra de los Schiavoni");
lista.add("San Giorgio la Molara");
lista.add("Molinara");
lista.add("Pietrelcina");
lista.add("Fragneto Monforte");
lista.add("Circello");
lista.add("Campolattaro");
add(lista,BorderLayout.CENTER);
add(text,BorderLayout.SOUTH);
addWindowListener(new listeWindowListener());
lista.addItemListener(new escuchaLista());
setSize(350,100);
setResizable(false);
show();
}

public static void m ain(String [] arg)

{
new listas();
}

class listeWindowListener implem ents WindowListener


{
public void windowActivated(WindowEvent e)
{}
public void windowClosed(WindowEvent e)
{}
public void windowClosing(WindowEvent e)
{

String[] s=lista.getSelectedItem s();


int i=0;
System .out.println("Itinerario seleccionado");
try
{
while (true)
{
System .out.println(s[i++]);
}

}
catch (ArrayIndexOutOfBoundsException er)
{System .out.println("Qu lo pases bien...");}
System .exit(0);
}
public void windowDeactivated(WindowEvent e)
{}
public void windowDeiconified(WindowEvent e)
{}
public void windowIconified(WindowEvent e)
{}
public void windowOpened(WindowEvent e)
{}
}

class escuchaLista implem ents Item Listener


{
public void item StateChanged(Item Event e)
{
int ndice=((Integer) e.getItem ()).intValue();
if (ndice==0) text.setText("Rocca de los Rettori, arco de
Trajano, anfiteatro Rom ano, ciudad espectculo");
if (ndice==1) text.setText("localidad San Giovanni,

Cam panario, via Roma, lago, fiesta S.Giovanni, fiesta del


emigrante");
if (ndice==2) text.setText("asis ds San Leonardo");
if (indice==3) text.setText("casco histrico");
if (ndice==4) text.setText("casco histrico");
if (ndice==5) text.setText("casco histrico");
if (ndice==6) text.setText("casco histrico");
if (ndice==7) text.setText("casco histrico");
if (ndice==8) text.setText("casco histrico");
if (ndice==9) text.setText("Bosque");
if (ndice==10) text.setText("casco histrico");
if (ndice==11) text.setText("Lago de San Giorgio");
if (ndice==12) text.setText("casco histrico");
if (ndice==13) text.setText("Piana Romana, casco histrico,
casas de Padre Po");
if (ndice==14) text.setText("Encuentro internacional de
globos, Palacio Ducal");
if (ndice==15) text.setText("casco histrico");
if (ndice==16) text.setText("Dique de Cam polattaro");
}
}
}
Por lo tanto, las listas son unos buenos GUI para que el
usuario ponga en marcha una opcin entre las m uchas
posibilidades.
Hay otro GUI que sirve para esto, que prcticam ente es una
lista que aparece y desaparece, en el sentido de que se
puede ver slo el objeto seleccionado y que los dem s se

ven slo cuando hay que hacer la seleccin, tipo m en,


mientras en las listas se pueden ver siempre.
El GUI del que estoy hablando es el Choice (seleccin), cuyo
funcionam iento es parecido al de las listas.
El constructor es uno sin parm etros, mientras los m todos
son:
void add(String item ), aade una posibilidad al final de las
selecciones posibles.
void addItem (String item ), como la add
void addItemListener(ItemListener l), asocia un oyente de
sucesos para la Choice.
String getItem (int index), devuelve la eleccin posible que
se encuentra en el ndice .
int getItemCount(), da el nmero de posibilidades para la
Choice.
EventListener[] getListeners(Class listenerType), da todos
los oyentes asociados a la Choice.
int getSelectedIndex(), devuelve el ndice de la lista
seleccionada en la Choice.
String getSelectedItem (), devuelve la opcin seleccionada en
la Choice.
Object[] getSelectedObjects(), da todos los item
seleccionados.
void insert(String item, int index), introduce una seleccim
en la posicin indicada de la Choice.
void remove(int position), void remove(String item), void
rem oveAll() , para eliminar las selecciones posibles de la
lista.
void removeItemListener(ItemListener l), elimina el oyente

de sucesos de tipo ItemListener asociado a la Choice.


void select(int pos), void select(String str), para seleccionar
una opcin.
Escribamos un pequeo program a que utilice las Choice.
Pero, como hasta ahora hemos creado unas aplicaciones a
ventana, creemos un aplique, y visto que es GUI, se pueden
utilizar en los dos tipos de program as.
Hablando de aplique, como no lo hemos hacho hasta ahora,
creemos un aplique que lee los parm etros que le pasan los
archivos htm l que lo invoca. Es lo que hacen prcticam ente
la m ayor parte de los apliques del sito HTMLpoint.
En el aplique, como ejemplo, he puesto un pequeo control
sobre el campo autor. Esto m e sirve para ensearos cmo se
puede hacer. Puede resultar til si se crea un aplique y lo
distribuimos de form a que sea obligatorio el parm etro del
autor y su valor. Tambin sirve para evitar que otros puedan
hacerse creadores del aplique y, por lo tanto, pretender los
derechos de la creacin del aplique.
El control no es complicado, un hacker lo evitara fcilmente.
Sin em bargo un hacker no tiene ningn inters en destruir
un program a free, slo para eliminar los derechos de autor.
En cam bio, para un usuario norm al es imposible poner en
m archa el program a sin especificar el nombre del autor. El
nombre puede incluso ser un nm ero de serie si queremos
vender un program a.
El archivo htm l, se llam ar Choice.html, y su contenido es:
<htm l>

<head>
<title>
Ejem plo de uso de la java.awt.Choice y del cambio de los
parm etros a un aplique
</title>
</head>
<body>
<APPLET code="Selecciones.class" width=350 height=100>
<param nam e=loc1 value="Bienvenido">
<param nam e=loc2 value="Foiano de Val Fortore">
<param nam e=loc3 value="Baselice">
<param nam e=loc4 value="San Bartolom eo en Galdo">
<param nam e=loc5 value="San Marco de los Cavoti">
<param nam e=loc6 value="Montefalcone in Val Fortore">
<param nam e=loc7 value="Pesco Sannita">
<param nam e=loc8 value="Colle Sannita">
<param nam e=loc9 value="Castelvetere en Val Fortore">
<param nam e=loc10 value="Castelfranco en Miscano">
<param nam e=loc11 value="Ginestra de los Schiavoni">
<param nam e=loc12 value="San Giorgio la Molara">
<param nam e=loc13 value="Molinara">
<param nam e=loc14 value="Fragneto Monforte">
<param nam e=loc15 value="Circello">
<param nam e=loc16 value="Campolattaro">
<param nam e=autore value="Pietro Castellucci">
</APPLET>
</body>
</htm l>
Mientras que el cdigo del aplique, editado en el archivo
llam ado Selecciones.java, es:

im port java.awt.*;
im port java.awt.event.*;
im port java.applet.*;
public class Selecciones extends Applet
{

Label text=new Label("Maravillas que se pueden visitar en la


localidad seleccionada");
Choice scelte=new Choice();
public void init()
{
// Control de los derechos de autor:
String autor=getParam eter("autor");
if (autor==null) System.exit(0);
if (autor.compareTo("Pietro Castellucci")!=0)
{
System .out.println("Parm etro autor no valido, introducir
como valor Pietro Castellucci");
System .exit(0);
}

String p=getParam eter("loc1");


if (p==null) p="Localidad 1 no definida";
scelte.add(p);
p=getParam eter("loc2");
if (p==null) p="Localidad 2 no definida";

scelte.add(p);
p=getParam eter("loc3");
if (p==null) p="Localidad 3 no definida";
scelte.add(p);
scelte.add(p);
p=getParam eter("loc4");
if (p==null) p="Localidad 4 no definida";
scelte.add(p);
p=getParam eter("loc5");
if (p==null) p="Localidad 5 no definida";
scelte.add(p);
p=getParam eter("loc6");
if (p==null) p="Localidad 6 no definida";
scelte.add(p);
p=getParam eter("loc7");
if (p==null) p="Localidad 7 no definida";
scelte.add(p);
p=getParam eter("loc8");
if (p==null) p="Localidad 8 no definida";
scelte.add(p);
p=getParam eter("loc9");
if (p==null) p="Localidad 9 no definida";
scelte.add(p);

p=getParam eter("loc10");
if (p==null) p="Localidad 10 no definida";
scelte.add(p);
p=getParam eter("loc11");
if (p==null) p="Localidad 11 no definida";
scelte.add(p);
p=getParam eter("loc12");
if (p==null) p="Localidad 12 no definida";
scelte.add(p);
p=getParam eter("loc13");
if (p==null) p="Localidad 13 no definida";
scelte.add(p);
p=getParam eter("loc14");
if (p==null) p="Localidad 14 no definida";
scelte.add(p);
p=getParam eter("loc15");
if (p==null) p="Localidad 15 no definida";
scelte.add(p);
p=getParam eter("loc16");
if (p==null) p="Localidad 16 no definida";
scelte.add(p);
p=getParam eter("loc17");
if (p==null) p="Localidad 17 no definida";
scelte.add(p);

scelte.addItem Listener(new escuchaChoice());

// Visualizzo la Choice
add(selecciones, BorderLayout.CENTER);
add(text, BorderLayout.SOUTH);
}
class escuchaChoice implem ents ItemListener
{
public void item StateChanged(Item Event e)
{
int indice=scelte.getSelectedIndex();
if (indice==0) text.setText("Rocca dei Rettori, arco de
Trajano, anfiteatro Rom ano");
if (indice==1) text.setText("localidad San Giovanni,
Cam panario, via Roma, lago");
if (ndice==2) text.setText("asi de San Leonardo");
if (ndice==3) text.setText("casco histrico");
if (ndice==4) text.setText("casco histrico");
if (ndice==5) text.setText("");
if (ndice==6) text.setText("");
if (ndice==7) text.setText("");
if (ndice==8) text.setText("");
if (ndice==9) text.setText("Bosque");
if (ndice==10) text.setText("");
if (ndice==11) text.setText("Lago de San Giorgio");

if (ndice==12) text.setText("");
if (ndice==13) text.setText("Piana Romana, casco histrico,
casas de Padre Po");
if (ndice==14) text.setText("Encuentro internacional de
globos, palcio Ducale");
if (ndice==15) text.setText("");
if (ndice==16) text.setText("Dique de Cam polattaro");
}
}
}
El ltimo componente GUI que veremos en esta leccin es el
ScrollPane, es decir, un panel en el que es posible introducir
un componente tan grande como queramos, y que tiene que
ser visualizado a trozos.
El ScrollPane usa dos Scrollbar, una horizontal y otra
vertical, para seleccionar la parte del GUI que queremos ver.
Fijaos que la Scrollbar es un objeto tam bin, por lo tanto, se
puede introducir y gestionar en las proprias aplicaciones. En
el ScrollPane se puede elegir si visualizar las Scrollbar
siempre, nunca o slo cuando sea necesario.
Un ScrollPane tpico es el que utilizamos para visualizar un
archivo de texto.
Hay dos tipos de constructores para el objeto:
ScrollPane(int sbp), crea un ScrollPane que pueda visualizar
las Scrollbar definidas por spb.
Los valores posibles son :
ScrollPane.SCROLLBARS_ALWAYS siem pre a la vista
ScrollPane.SCROLLBARS_AS_NEEDED a la vista slo si lo
necesitamos

ScrollPane.SCROLLBARS_NEVER nunca a la vista


ScrollPane(), crea un ScrollPane que pueda visualizar
ScrollPane.SCROLLBARS_AS_NEEDED.
Entre los mtodos, adem s de los que sirven para gestionar
el ScrollPane, encontramos los de Container y de
Component. En efecto, ScrollPane es una extensin de
Container, por lo tanto, si lo vemos como un contenedor, se
puede ver como un componente.

El Texto, los sucesos, Dialog

Nos queda por ver un componente fundam ental para una


interfaz, es decir, el texto.
Los abstract window Toolkit de Java ponen a disposicin dos
clases para el texto: TextArea y TextField, las dos amplan la
clase TextComponent.

En TextComponent encontramos una serie de m todos tiles


para la gestin del texto, tanto en TextArea como en
TextField, entre ellos:
Color getBackground() e setBackground(Color c), para
capturar y verificar el color de Background del texto.
String getSelectedText(), captura el texto seleccionado.
int getSelectionEnd(), da la posicin del final de la seleccin
del texto.
Int getSelectionStart(), da la posicin del inicio de la
seleccin del texto.
String getText(), da el texto del TextComponent
boolean isEditable(), dice si el texto del componente se
puede editar.
void select(int selectionStart, int selectionEnd), selecciona el
texto de selectionStart a selectionEnd.
void selectAll(), selecciona todo el texto.
void setEditable(boolean b), verifica si el texto se puede
editar o no.
void setSelectionEnd(int selectionEnd), verifica el final de la
seleccin del texto.
void setSelectionStart(int selectionStart), verifica el inicio de
la seleccin.
void setText(String t), verifica el contenido del componente
del texto con valor t.

Adem s en TextComponent se pueden utilizar todos los


m todos de Component, es decir:
action, add, addComponentListener, addFocusListener,
addHierarchyBoundsListener, addHierarchyListener,
addInputMethodListener, addKeyListener, addMouseListener,
addMouseMotionListener, addNotify,
addPropertyChangeListener, addPropertyChangeListener,
bounds, checkIm age, checkIm age, coalesceEvents, contains,
contains, createIm age, createIm age, deliverEvent, disable,
disableEvents, dispatchEvent, doLayout, enable, enable,
enableEvents, enableInputMethods, firePropertyChange,
getAlignm entX, getAlignmentY, getBounds, getBounds,
getColorModel, getComponentAt, getComponentAt,
getComponentOrientation, getCursor, getDropTarget,
getFont, getFontMetrics, getForeground, getGraphics,
getGraphicsConfiguration, getHeight, getInputContext,
getInputMethodRequests, getLocale, getLocation,
getLocation, getLocationOnScreen, getMaximum Size,
getMinimum Size, getNam e, getParent, getPeer,
getPreferredSize, getSize, getSize, getToolkit, getTreeLock,
getWidth, getX, getY, gotFocus, handleEvent, hasFocus,
hide, imageUpdate, inside, invalidate, isDisplayable,
isDoubleBuffered, isEnabled, isFocusTraversable,
isLightweight, isOpaque, isShowing, isValid, isVisible,
keyDown, keyUp, layout, list, list, list, list, list, locate,
location, lostFocus, m inimum Size, mouseDown, mouseDrag,
mouseEnter, mouseExit, mouseMove, mouseUp, move,
nextFocus, paint, paintAll, postEvent, preferredSize,
prepareIm age, prepareImage, print, printAll,
processComponentEvent, processFocusEvent,

processHierarchyBoundsEvent, processHierarchyEvent,
processInputMethodEvent, processKeyEvent,
processMouseEvent, processMouseMotionEvent, remove,
rem oveComponentListener, removeFocusListener,
rem oveHierarchyBoundsListener, removeHierarchyListener,
rem oveInputMethodListener, removeKeyListener,
rem oveMouseListener, removeMouseMotionListener,
rem ovePropertyChangeListener,
rem ovePropertyChangeListener, repaint, repaint, repaint,
repaint, requestFocus, reshape, resize, resize, setBounds,
setBounds, setComponentOrientation, setCursor,
setDropTarget, setEnabled, setFont, setForeground,
setLocale, setLocation, setLocation, setNam e, setSize,
setSize, setVisible, show, show, size, toString, transferFocus,
update, validate
Ahora, veam os los TextField. Prcticam ente un TextField es
una nica lnea de texto que se puede editar, con aspecto
grfico. Es uno de los campos que estamos acostumbrados a
ver en las Form que se encuentran en internet para
introducir nombres, apellidos, etc.
Hay cuatro posibles constructores:
TextField(), crea un TextField vaco.
TextField(int c), crea un TextField vaco de c columnas, es
decir, una lnea de c caracteres.
TextField(String t), crea un TextField inicializado con t.
TextField(String t, int c), crea un TextField inicializado con t,
de c caracteres.
De los varios m todos, los m s interesantes para nuestros

fines son:
boolean echoCharIsSet(), dice si el TextField realiza el
"echo" de los caracteres introducidos.
int getColumns(), da el nmero de columnas de los
TextField.
char getEchoChar(), da el carcter utilizado para el "echo".
void setColumns(int columns), verifica el nm ero de las
columnas de los TextField.
void setEchoChar(char c), verifica el carcter de "echo" para
el TextField.
void setText(String t), para verificar el texto introducido.
Para el tam ao:
Dim ension getMinimum Size()
Dim ensin getMinimum Size(int c)
Dim ensin getPreferredSize()
Dim ensin getPreferredSize(int c)
La TextArea, en cam bio, es un verdadero texto, no slo una
lnea, sino muchas. Incluye tambin las dos barras para
navegar en el texto si ste es m s grande de la ventana en
la que est visualizado.
Los constructores son:
TextArea(), construye una nueva TextArea.
TextArea(int r, int c) , construye una nueva TextArea, de r
lneas y c columnas.
TextArea(String text), construye una nueva TextArea
inicializada con el texto pasado.

TextArea(String text, int rows, int columns) , construye una


nueva TextArea inicializada con el texto pasado, de r lneas y
c columnas.
TextArea(String text, int rows, int columns, int scrollbars),
como el anterior, slo que perm ite especificar la
visualizacin de las barras de texto.
Vamos a ver algunos mtodos:
void append(String str), cuelga el texto pasado a la
TextArea. (En la viejas versiones de Java es
appendText(String str)).
int getColumns(), int getRows() para tener inform acin
sobre el nm ero de columnas o lneas.
void insert(String str, int pos), introduce el texto pasado en
la posicin pasada. (En las viejas versiones de Java es
insertText(String str)).
void replaceRange(String str, int start, int end), sustituye el
texto de start a end con la cadena pasada.
void setColumns(int columns) e void setRows(int rows) para
verificar el nmero de columnas o de lneas de la TextArea.
Para el tam ao del objeto GUI:
Dim ensin getMinimum Size()
Dim ensin getMinimum Size(int rows, int columns)
Dim ensin getPreferredSize()
Dim ensin getPreferredSize(int rows, int columns)
Hemos visto todos los componentes de texto. Llegados a
este punto podemos poner un ejem plo que los utiliza las
dos.

Cream os un aplique, por lo tanto el launcher es:


<htm l>
<head>
<title>
Ejem plo de uso de los componentes de texto.
</title>
</head>
<body>
<APPLET code="Texto.class" width=500 height=200>
<param nam e=testo value="Texto inicial para la
TextArea.Introducir m s caracteres.">
</APPLET>
</body>
</htm l>
El cdigo que hay que editar en Texto.java, es el siguiente:
im port java.awt.event.KeyListener;
im port java.awt.event.KeyEvent;
im port java.awt.TextField;
im port java.awt.TextArea;
im port java.awt.BorderLayout;
im port java.applet.*;

public class Texto extends Applet


{
TextField TF=new TextField(20);
TextArea TA=new TextArea();
public void init()
{
add(TA,BorderLayout.CENTER);
add(TF,BorderLayout.SOUTH);
String t=getParam eter("texto");
if (t!=null) TA.setText(t);
TF.setEditable(false);
TA.addKeyListener(new MyKeyListener());
}

public class MyKeyListener implements KeyListener


{
public void keyPressed(KeyEvent e)
{
}

public void keyReleased(KeyEvent e)


{
int valor=e.getKeyCode();
if (valor!=10) TF.setText("Introducido carcter
"+e.getKeyChar());
else TF.setText("Introducido carcter ENVIAR");
}
public void keyTyped(KeyEvent e)
{
}
}
}

La gestin de los sucesos en Java2

Hemos visto casi todos los componentes GUI de awt. Para


construir una interfaz basta con combinarlos y escuchar los
sucesos.
Por cada GUI analizada, hemos visto cmo gestionar unos
sucesos. Ahora vamos a ver qu sucesos se pueden

escuchar.
En prim er lugar hemos escuchado unos sucesos de tipo
ActionEvent, es decir, sucesos que actan sobre las GUI
gracias al usuario como, por ejemplo, pulsar un botn.
Para esto, os recuerdo que hemos implem entado la interfaz
ActionListener, y hemos vuelto a definir el nico suceso
actionPerform ed (ActionEvent e), que se invoca cuando se
pone en m archa una accin sobre el componente GUI (o
sobre los componentes) a los que est asociado.
Para asociar al GUI el oyente de los sucesos que hemos
definido, hemos utilizado el mtodo addActionListener
(ActionListener oyente) del GUI.
Para usarlos hay que incluir en el program a:
im port java.awt.event.ActionListener;
im port java.awt.event.ActionEvent;
o
im pore java.awt.event.*;
Oyentes de sucesos de tipo ActionListener se pueden asociar
a los objetos GUI de awt:
Button
List (cuando seleccionamos o no seleccionamos un
elem ento)
MenuItem
TextField
Hemos visto tam bin cmo implementar un ItemListener,
para escuchar sucesos de la GUI que tienen un estado de

on/off, cuando modifican su propiio estado.


Para asociarlo a una GUI hemos utilizado
addItemListener(ItemListener oyente) de la GUI. Cuando el
suceso es generado por GUI, se invoca el m todo
item StateChanged(Item Event e) del oyente asociado.
Hay que incluir:
im port java.awt.event.*;
o
im port java.awt.event.Item Listener;
im port java.awt.event.Item Event;
Los GUI awt para que pueda ser escuchado, son:
Checkbox
CheckboxMenuItem (no lo hemos visto. Es como un
MenuItem , lo nico es que funciona como una Checkbox, es
decir, se puede clicar o no. Si se asocia a un
CheckboxGroup, se convierte otra vez en un radiobutton,
slo que en un men).
Choice
List
Adem s hemos visto los oyentes de los sucesos de las
ventanas, es decir, los de tipo WindowListener.
Se asocian a las ventanas usando el m todo de stas
addWindowListener(WindowListener WL), y para definirlas
hay que implementar la interfaz WindowListener y volver a
definir los mtodos:

void windowActivated(WindowEvent e), invocado cuando la


ventana est activa, es decir, cuando aparece en primer
plano en el desktop.
void windowClosed(WindowEvent e), invocado cuando la
ventana se cierra.
void windowClosing(WindowEvent e), invocado cuando se
aprieta el botn cerrarVentana (X).
void windowDeactivated(WindowEvent e), invocado cuando
la ventana pasa a un segundo plano.
void windowDeiconified(WindowEvent e), invocado cuando la
ventana se convierte de icono a activa.
void windowIconified(WindowEvent e), cuando se transforma
en icono.
void windowOpened(WindowEvent e), cuando se abre.
Para escuchar los sucesos de la ventana hay que incluir:
im port java.awt.event.WindowListener;
im port java.awt.event.WindowEvent;
o
im port java.awt.event.*;
Los sucesos de las ventanas se m anifiestan casi siempre por
parejas. Por ejemplo, cuando pulsamos la tecla X en la parte
de arriba a la derecha de la ventana, primero se invoca
windowClosing y despus windowClosed, o cuando una
ventana se transform a de icono a activa, prim ero escucha
windowDeiconified y luego WindowActivated, etc.

Es posible escuchar sucesos de tipo ventana para los


elem entos:
Window
Fram e
Dialog
Por lo que se refiere a los Dialog abro un parntesis.
Son Fram e sin icono. Reducir a icono y m aximizar son muy
parecidos para hacer precisam ente unos dilogos rpidos
con el usuario. Son, por ejemplo, unos dialog las ventanas
que aparecen en las aplicaciones y dicen: ests seguro de
que quieres salir?
Un Dialog puede ser modal o no modal. El primero es un
Dialog que bloquea completam ente la aplicacin y que, por
tanto, ya no oye los sucesos, el segundo en cambio va en
paralelo a sta.
Los dialog de awt no pueden incluir mens, mientras que s
los incluyen los de swing (javax.swing.JDialog) si.
Vamos a ver qu sucesos pueden escuchar los objetos de
tipo TextComponent, es decir, objetos de tipo TextField y
TextArea. Podemos escuchar sucesos de tipo TextEvent,
im plem entando la interfaz TextListener, y volviendo a definir
el m todo textValueChanged(TextEvent e), invocado cada
vez que el texto se modifica.
La interfaz y el suceso se encuentran en java.awt.event
Los objetos de tipo container, es decir, Panel, ScrollPane,
Window (y, por lo tanto, Dialog y Frame), pueden escuchar
los sucesos en el contenedor, utilizando el mtodo
addContainerListener(ContainerListener l). Hay que

im plem entar la interfaz ContainerListener y volver a definir


los m todos.
void componentAdded(ContainerEvent e)
void componentRemoved(ContainerEvent e)
stos se invocan autom ticam ente cuando se aaden o se
quitan elem entos al contenedor.
Hay que incluir java.awt.event.ContainerListener y
java.awt.event.ContainerEvent.
Llegados a este punto vamos a ver qu sucesos se pueden
escuchar en objetos de tipo Component, es decir, en TODOS
los componentes awt, incluidos los contenedores y las
ventanas.
En Component estn los m todos:
addComponentListener(ComponentListener l)
addFocusListener(FocusListener l)
addHierarchyBoundsListener(HierarchyBoundsListener l)
addHierarchyListener(HierarchyListener l)
addInputMethodListener(InputMethodListener l)
addKeyListener(KeyListener l)
addMouseListener(MouseListener l)
addMouseMotionListener(MouseMotionListener l)
addPropertyChangeListener(PropertyChangeListener
listener)
addPropertyChangeListener(String propertyNam e,
PropertyChangeListener listener)
Los ComponentListener escuchan sucesos en el componente

y hay que volver a definir los m todos.


void componentHidden(ComponentEvent e)
void componentMoved(ComponentEvent e)
void componentResized(ComponentEvent e)
void componentShown(ComponentEvent e)
stos se invocan cuando el componente se oculta, se mueve,
cambia su tam ao y se visualiza.
FocusListener escucha los sucesos de focus del teclado en el
componente, es decir, si se selecciona o no el componente
del teclado.
Hay que volver a definir los mtodos:
focusGained(FocusEvent e), invocado cuando se selecciona
el componente.
focusLost(FocusEvent e), invocado por el componente
cuando pierde la seleccin del teclado.
Pensemos, por ejemplo, en la navegacin de las varias form
de una interfaz, pulsando la tecla TAB.
HierarchyBoundsListener, escucha los sucesos de remocin
de los antepasados del componente, por ejemplo, un botn
en una ventana. Se implementa esta interfaz, escucha si la
ventana se m ueve.
Hay que volver a definir los mtodos:
void ancestorMoved(HierarchyEvent e), invocada cuando el
antepasado se remueve.
void ancestorResized(HierarchyEvent e) , invocada cuando

se cam bia de tam ao el antepasado.


HierarchyListener escucha los cambios de los antepasados
del componente. Hay que volver a definir el mtodo
hierarchyChanged(HierarchyEvent e). Ser HierarchyEvent el
que incluye el cambio.
KeyListener ya lo hemos visto: escucha los sucesos del
teclado. Hay que volver a definir los m todos.
void keyPressed(KeyEvent e), invocado cuando se tecla una
tecla.
void keyReleased(KeyEvent e), invocado cuando se deja de
teclear una tecla.
void keyTyped(KeyEvent e), invocado cuando se sigue
pulsando una tecla.
En resum en, cuando se teclea una tecla se oyen los sucesos
en ste orden: keyPressed, keyTyped y keyReleased.
MouseListener escucha los sucesos del ratn. Hay que volver
a definir los mtodos.
void mouseClicked(MouseEvent e), invocado cundo se clica
un botn del ratn en el componente.
void mouseEntered(MouseEvent e), invocado cuando el ratn
entra sobre el componente.
void mouseExited(MouseEvent e), invocado cuando el ratn
sale del componente.
void mousePressed(MouseEvent e), invocado cuando se
sigue teniendo pulsado el ratn sobre el componente.
void mouseReleased(MouseEvent e), invocado cuando se
deja de pulsar el ratn.
MouseMotionListener, otros sucesos del ratn sobre el

componente:
mouseDragged(MouseEvent e), invocado cuando se aprieta y
se mueve el ratn sobre el componente.
void mouseMoved(MouseEvent e), invocado cuando el ratn
se mueve sobre el componente, con o sin pulsar botones.
La ltim a interfaz para los sucesos del ratn es
MouseInputListener, que implem enta las dos interfaces
anteriores. Por lo tanto escucha todos los sucesos anteriores
del ratn.
En el ejemplo a continuacin se escuchan varios sucesos y
se utiliza tam bin un Dialog.
im port java.awt.event.*;
im port java.awt.*;
class escuchar extends Fram e
{
Button b1=new Button("Botn1");
Button b2=new Button("Visualiza Dialog");
Button b3=new Button("salir");
Button b4=new Button("Cerrar Dialog");
Choice l1=new Choice();
TextField TF1=new TextField(15);

Dialog D;
AscoltaActionListener aal;
AscoltaItemListener ail;
AscoltaWindowListener awl;
AscoltaWindowListenerDialog awld;
AscoltaMouseListener am l;
AscoltaKeyListener akl;
public Ascolta()
{
setTitle("Fram e, ejemplo oyentes suscesos");
setLocation(100,100);
setLayout(new GridLayout(5,1));
add(b1);
add(b2);
add(b3);
add(l1);
add(TF1);
D=new Dialog(this,true);
D.setSize(200,100);
D.setLocation(200,100);
D.add(b4,BorderLayout.SOUTH);
D.setTitle("Dialog - modale");
preparaD(false);
l1.add("Seleccin 1");
l1.add("Seleccin 2");
l1.add("Seleccin 3");

// Inicializar los oyentes de los sucesos.


aal=new AscoltaActionListener();
ail=new AscoltaItemListener();
awl=new AscoltaWindowListener();
awld=new AscoltaWindowListenerDialog();
aml=new AscoltaMouseListener();
akl=new AscoltaKeyListener();
b1.addActionListener(aal);
b2.addActionListener(aal);
b3.addActionListener(aal);
TF1.addActionListener(aal);
l1.addItemListener(ail);
addWindowListener(awl);
addMouseListener(am l);
b1.addMouseListener(aml);
b2.addMouseListener(aml);
b3.addMouseListener(aml);
b4.addMouseListener(aml);
l1.addMouseListener(am l);
TF1.addMouseListener(am l);
TF1.addTextListener(new TextListener()
{
public void textValueChanged(TextEvent e)
{
System .out.println("TextListener: cambiar el valor de la
TextField");
}
}
);
D.addMouseListener(am l);
addKeyListener(akl);
b1.addKeyListener(akl);

b2.addKeyListener(akl);
b3.addKeyListener(akl);
b4.addKeyListener(akl);
l1.addKeyListener(akl);
TF1.addKeyListener(akl);
D.addKeyListener(akl);
pack();
show();
}
void prepararD(boolean m)
{
D.setModal(m );
}
public static void m ain (String [] s)
{
System .out.println("Escuchar los sucesos.");
new Escuchar();
}
// ActionListener
class EscucharActionListener implem ents ActionListener
{
public void actionPerform ed(ActionEvent e)
{
String c=e.getActionCommand();
if (c.compareTo("Botn1")==0)
System .out.println("ActionListener: Pulsar Botn1");

else
if (c.compareTo("Salir")==0)
{
System .out.println("ActionListener: Pulsar Salir");
System .exit(9); // es un nmero cualquiera, se llam a exit
code.
} else
if (c.compareTo("Visualizar Dialog")==0)
{
System .out.println("ActionListener: Pulsar Visualizar
Dialog");
D.show();
b4.addActionListener(aal);
b2.removeActionListener(aal);
D.addWindowListener(awld);
} else
if (c.compareTo("Cerrar Dialog")==0)
{
System .out.println("ActionListener: Pulsar Visualizar
Dialog");
D.hide();
b4.removeActionListener(aal);
b2.addActionListener(aal);
D.removeWindowListener(awld);
} else
{
System .out.println("ActionListener: Pulsar Enviar en la
TextField, letto:"+TF1.getText());
TF1.setText("");
}
}

}
// ItemListener
class EscucharItem Listener implem ents ItemListener
{
public void item StateChanged(Item Event e)
{
String val=l1.getSelectedItem ();
System .out.println("ItemListener: Seleccionado "+val);
}
}
// WindowListener
public class EscucharWindowListener implem ents
WindowListener
{
public void windowActivated(WindowEvent e)
{
System .out.println("WindowListener: Ventana activada");
}
public void windowClosed(WindowEvent e)
{
System .out.println("WindowListener: Ventana cerrada");
}
public void windowClosing(WindowEvent e)
{
System .out.println("WindowListener: Pulsar cerrar

ventana");
System .exit(0);
}
public void windowDeactivated(WindowEvent e)
{
System .out.println("WindowListener: Ventana no activada");
}
public void windowDeiconified(WindowEvent e)
{
System .out.println("WindowListener: Ventana sin icono");
}
public void windowIconified(WindowEvent e)
{
System .out.println("WindowListener: Ventana reducir a
icono");
}
public void windowOpened(WindowEvent e)
{
System .out.println("WindowListener: Ventana abierta");
}
}

public class EscucharWindowListenerDialog implem ents


WindowListener
{
public void windowActivated(WindowEvent e)
{

System .out.println("WindowListener: Dialog activado");


}
public void windowClosed(WindowEvent e)
{
System .out.println("WindowListener: Dialog cerrado");
}
public void windowClosing(WindowEvent e)
{
System .out.println("WindowListener: Pulsar cerrar Dialog");
D.hide();
b4.removeActionListener(aal);
b2.addActionListener(aal);
D.removeWindowListener(awld);
}
public void windowDeactivated(WindowEvent e)
{
System .out.println("WindowListener: Ventana no activada");
}
public void windowDeiconified(WindowEvent e)
{
System .out.println("WindowListener: Dialog sin icono");
}
public void windowIconified(WindowEvent e)
{
System .out.println("WindowListener: Dialog reducir a
icono");
}

public void windowOpened(WindowEvent e)


{
System .out.println("WindowListener: Dialog abierto");
}
}
// Mouse Listener:
class EscucharMouseListener implem ents MouseListener
{
public void mouseClicked(MouseEvent e)
{
Component a=e.getComponent();
String n=a.getNam e();
System .out.println("MouseListener: Mouse clicado sobre el
componente "+n);
}
public void mouseEntered(MouseEvent e)
{
Component a=e.getComponent();
String n=a.getNam e();
System .out.println("MouseListener: Mouse entrado en el
componente "+n);
}
public void mouseExited(MouseEvent e)
{
Component a=e.getComponent();
String n=a.getNam e();
System .out.println("MouseListener: Mouse salido del
componente "+n);
}

public void mousePressed(MouseEvent e)


{
Component a=e.getComponent();
String n=a.getNam e();
System .out.println("MouseListener: el botn est pulsado
sobre el componente"+n);
}
public void mouseReleased(MouseEvent e)
{
Component a=e.getComponent();
String n=a.getNam e();
System .out.println("MouseListener: Mouse no est pulsado
en el componente "+n);
}
}
// Teclado
class AscoltaKeyListener implem ents KeyListener
{
public void keyPressed(KeyEvent e)
{
System .out.println("KeyListener: Pulsar tecla
"+e.getKeyChar()+
" codice "+
e.getKeyCode());
}
public void keyReleased(KeyEvent e)
{
System .out.println("KeyListener: Dejar de pulsar tecla
"+e.getKeyChar()+
" codice "+
e.getKeyCode());

}
public void keyTyped(KeyEvent e)
{
System .out.println("KeyListener: Ests pulsando la tecla
"+e.getKeyChar()+
" codice "+
e.getKeyCode());
}
}
}

Introduccin a swing

Adem s del paquete java.awt, Java pone a disposicin del


program ador el paquete javax.swing para crear unas interfaces
grficas. En este captulo veremos para qu la Sun Microsystem
ha creado otro paquete y qu diferencias hay con awt.
Para presentar el paquete hablar del program a que estoy
preparando para mi tesina en la Facultad de Informtica de la
Universidad de Pisa. Para informaciones con respecto a Orespics
podis poneros en contacto conmigo o con las profesoras Lagan
y Ricci del Departam ento de Informtica de Pisa (Corso Italia,
40).
El nombre del program a es Orespics Programming Language y, en
prctica, es un ambiente integrado en el que es posible
program ar agentes paralelos que comunicam entre ellos,

intercambiando mensajes. El ambiente permite definir y poner en


m archa estos agentes. Se propone como instrum ento de soporte
didctico al aprendizaje de las modalidades de program acin
paralela, program acin que puede resultar muy difcil.
Precisam ente por ser un instrum ento didctico, tiene una interfaz
usuario User Friendly. La interfaz ha sido escrita utilizando el
paquete Swing de Java.
Swing ha sido totalm ente escrito en Java utilizando el paquete
awt, y pone a disposicin del usuario muchas clases que estn
tam bin en awt, pero m ucho mejores y m s potentes. Adems
introduce muchas ms clases que no estn en awt.
Por lo tanto, veam os cules son las clases y las interfaces
incluidas en el paquete:
Interfaces
Action
BoundedRangeModel
ButtonModel
CellEditor
ComboBoxEditor
ComboBoxModel
DesktopManager
Icon
JComboBox.KeySelectionManager
ListCellRenderer
ListModel
ListSelectionModel
MenuElement
MutableComboBoxModel
Renderer
RootPaneContainer
Scrollable

ScrollPaneConstants
SingleSelectionModel
SwingConstants
UIDefaults.ActiveValue
UIDefaults.LazyValue
WindowConstants
Clases
AbstractAction
AbstractButton
AbstractCellEditor
AbstractListModel
ActionMap
BorderFactory
Box
Box.Filler
BoxLayout
ButtonGroup
CellRendererPane
ComponentInputMap
DebugGraphics
DefaultBoundedRangeModel
DefaultButtonModel
DefaultCellEditor
DefaultComboBoxModel
DefaultDesktopManager
DefaultFocusManager
DefaultListCellRenderer
DefaultListCellRenderer.UIResource
DefaultListModel
DefaultListSelectionModel
DefaultSingleSelectionModel

FocusManager
GrayFilter
ImageIcon
InputMap
InputVerifier
JApplet
JButton
JCheckBox
JCheckBoxMenuItem
JColorChooser
JComboBox
JComponent
JDesktopPane
JDialog
JEditorPane
JFileChooser
JFram e
JInternalFram e
JInternalFram e.JDesktopIcon
JLabel
JLayeredPane
JList
JMenu
JMenuBar
JMenuItem
JOptionPane
JPanel
JPasswordField
JPopupMenu
JPopupMenu.Separator
JProgressBar
JRadioButton

JRadioButtonMenuItem
JRootPane
JScrollBar
JScrollPane
JSeparator
JSlider
JSplitPane
JTabbedPane
JTable
JTextArea
JTextField
JTextPane
JToggleButton
JToggleButton.ToggleButtonModel
JToolBar
JToolBar.Separator
JToolTip
JTree
JTree.Dynam icUtilTreeNode
JTree.Em ptySelectionModel
JViewport
JWindow
KeyStroke
LookAndFeel
MenuSelectionManager
OverlayLayout
ProgressMonitor
ProgressMonitorInputStream
RepaintManager
ScrollPaneLayout
ScrollPaneLayout.UIResource
SizeRequirem ents

SizeSequence
SwingUtilities
Tim er
ToolTipManager
UIDefaults
UIDefaults.LazyInputMap
UIDefaults.ProxyLazyValue
UIManager
UIManager.LookAndFeelInfo
ViewportLayout
Excepciones
UnsupportedLookAndFeelException
Est claro que hay muchas m s clases de las de swing. Adems
hay m uchas que tienen el mismo nombre de algunas clases de
awt, excepto una J inicial, como, por ejemplo, JFram e, JDialog,
etc. Estas clases funcionan igual que las de awt, pero contienen
muchos m todos ms tiles.
Presentam os algunas de ests cosas que estn en swing m s que
en awt.
En swing estn las Toolbar, es decir, unas pequeas barras sobre
las que hay unos botones. Se pueden mover dentro de las
ventanas que las incluyen.
Los botones de swing, como casi todos los dem s JComponent,
pueden tener tanto una etiqueta como una im agen, imagen que
puede cambiar segn el estado del botn.
Adem s en swing se pueden utilizar los Tooltip, es decir, aquellas
sugerenias que salen autom ticam ente en un componente cuando
el ratn se detiene en l durante un rato.
Vamos a ver ahora el efecto de estos componentes swing en
Orespics.

En el Dibujo podemos notar la Toolbar (en la que he ocultado los


bordes) de otras 8 Toolbar, una por cada categora de botones.
Se ven los botones que incluyen las im genes, unas activas y
otras no.

En el Dibujo se puede ver un Tooltip en uno de los botones.

Adem s podemos notar que incluso en los m ens se pueden


introducir unas im genes y esto las convierte en imgenes muy
agradables para el usuario.

Las toolbar se pueden ocultar fcilm ente y se pueden visualizar


en la pantalla.

En el dibijo notamos el cambio de la im agen del botn con el


pingino, que se hace ms grande con swing. Como ya hemos
dicho, es posible cambiar el icono segn el estado del botn.
Otros dos componentes muy interesantes
de Swing son los TabbedPane y los rboles.
Los prim eros son los controles a tarjetas
tpicos de las interfaces de Windows, muy
agradables. Los segundos m uestran las
estructuras a rbol como las que se ven
cuando se navega en los discos duros
utilizando explorer de Windows.
Con swing se puede incluso cambiar el
llam ado Look and Feel de la ventana, es
decir, su aspecto, convirtindola en algo
parecido a una interfaz tpica de Java, de
Windows, de Macintosh (si est en un
aparato Mac) y de Linux (X-Windows - Motif).

Con Swing cambia completam ente la gestin del texto. Se pueden


crear texto de colores, con distintos tipos de caracteres.
Muchas m s son las posibilidades de Swing, por ejemplo, unos
Dialog para navegar en los archivos con unas preview y unos
dialog para elegir los colores. Estas opciones ya vienen
im plem entadas en el paquete.
A m m e resulta muy interesante saber que el dialog de seleccin
de los colores del Dibujo 16 se crea y se utiliza con una sola
orden, es decir, que basta con invocar el mtodo:
static JDialog
createDialog(Component c, String title,
boolean modal, JColorChooser chooserPane,
ActionListener okListener,
ActionListener cancelListener)
de la clase JColorChooser.
De todas form as creo que os han quedado claras las
potencialidades del paquete que, sin em bargo, todava no est
incluido en las versiones de Java de los navegadores y que, por lo
tanto, todava no es posible crear unos apliques swing sin cargar
plugins en los navegadores.

En los textos de swing es posible introducir incluso im genes y,


adem s, se pueden leer y decodificar directam ente los archivos
de html, rtf (Un primo de .doc).
En Swing est la clase Jdialog, parecida a la Applet de
java.applet. Es una extensin y presenta, adems de los m todos
de la clase Applet (de la que es una extensin), otros m todos
muy interesantes, entre ellos el m todo void
setJMenuBar(JMenuBar menuBar).
Obviam ente, como hay muchos GUI m s en swing, es necesario
gestionar los sucesos. Para esto est el paquete de
java.awt.event que gestiona dichos sucesos.

Fundam entos para el dibujo con Java

En el captulo anterior hemos visto cmo utilizar los


componentes GUI de Abstract Window Toolkit para construir
unas interfaces grficas para el usuario de nuestros
program as, y hemos dicho que un componente GUI es, en
sum a, un objeto con unas cualidades grficas. El
componente GUI es de nivel alto en el paquete awt, y se
construye utilizando los componentes de nivel bajo del
paquete, es decir, las primitivas grficas y los sucesos.
Pensemos, por ejemplo, en un botn. ste, grficam ente, no

es otra cosa que una caja con dentro un texto, que cambia
aspecto cuando se aprieta, es decir, cuando escucha su
suceso ActionEvent.
Utilizando las caractersticas de bajo nivel podemos construir
nuestros GUI personalizados o modificar los que ya existen
segn nuestras necesidades. No solam ente podemos
extender un componente particular, un componente lienzo,
en el que podemos dibujar lo que queramos y ponerlo en
nuestras interfaces como cualquier otro GUI.
Si utilizam os los apliques m s que las aplicaciones, podemos
evitar utilizar el lienzo porque el aplique trae implcitam ente
un lienzo. De todas form as, empecemos a ver en concreto
cmo se puede dibujar en un componente cualquiera o en un
aplique. Primero hablaremos de los apliques y luego
pasaremos a los componentes en general.

Las funciones paint, repaint y update...

En el lenguaje Java es posible dibujar en un aplique


sim plemente volviendo a definir el mtodo paint. Este mtodo se
invoca autom ticam ente por el sistem a cuando la ventana que
incluye el aplique pasa a un prim er plano. Por lo tanto cada
orden grfica al aplique se dar en el m todo paint del aplique.
void paint (Graphics g)
{

// Dibujo
}
Cuando el aplique haya dibujado y se quiera visualizar posibles
cambios, es posible invocar el mtodo repaint() o el mtodo
update(Graphics g) que borra el rea en el que el aplique ha
dibujado y vuelve a invocar la paint.
El m todo paint(Graphics g) no se puede invocar directam ente.
El aplique no slo tiene el m todo paint que se puede volver a
definir, sino tambin los objetos de tipo Component, es decir,
todos los GUI. Por lo tanto, para cam biar el aspecto grfico de
cualquier componente grfico, basta con volver a definir el
m todo paint.
Entre todos los componentes est el ya citado lienzo sobre el
que es posible dibujar. Es un objeto de la clase Canvas. Los que
estn acostumbrados a program ar con otros lenguajes esperan
que en la paint haya un inicializador del device en el que se va a
dibujar y, despus, una serie de instrucciones de tipo drawLine,
drawBox etc., sin embargo, os tengo que decir que esto no
siempre es verdad, es decir, que en los componentes y en los
apliques no hay ningn mtodo grfico.
Llegados a este punto, queda claro incluso que el parm etro g
de tipo Graphics de la paint incluye los mtodos grficos que
Java puede utilizar y representar, por decirlo de alguna form a, el
rea en el que se dibujarn las primitivas.
Graphics es una clase que no se puede incluir, sino que es
recibida por la paint como parm etro. Por lo tanto se puede
utilizar slo en ella y sus m todos son:
abstract void clearRect(int x, int y, int width, int height)
abstract void clipRect(int x, int y, int width, int height)
abstract void copyArea(int x, int y, int width, int height, int dx,

int dy)
abstract Graphics create()
Graphics create(int x, int y, int width, int height)
abstract void dispose()
void draw3DRect(int x, int y, int width, int height,boolean
raised)
abstract void drawArc(int x, int y, int width, int height, int
startAngle, int arcAngle)
void drawBytes(byte[] data, int offset, int length, int x, int y)
void drawChars(char[] data, int offset, int length, int x, int y)
abstract boolean drawImage() Ne esistono varie versioni
abstract void drawLine(int x1, int y1, int x2, int y2)
abstract void drawOval(int x, int y, int width, int height)
abstract void drawPolygon(int[] xPoints, int[] yPoints, int
nPoints)
void drawPolygon(Polygon p)
abstract void drawPolyline(int[] xPoints, int[] yPoints, int
nPoints)
void drawRect(int x, int y, int width, int height)
abstract void drawRoundRect(int x, int y, int width, int height,
int arcWidth, int arcHeight)
abstract void drawString(AttributedCharacterIterator iterator, int
x, int y)
abstract void drawString(String str, int x, int y)
void fill3DRect(int x, int y, int width, int height, boolean raised)
abstract void fillArc(int x, int y, int width, int height, int
startAngle, int arcAngle)
abstract void fillOval(int x, int y, int width, int height)
abstract void fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
void fillPolygon(Polygon p)
abstract void fillRect(int x, int y, int width, int height)
abstract void fillRoundRect(int x, int y, int width, int height, int

arcWidth, int arcHeight)


void finalize()
abstract Shape getClip()
abstract Rectangle getClipBounds()
Rectangle getClipBounds(Rectangle r)
abstract Color getColor()
abstract Font getFont()
FontMetrics getFontMetrics()
abstract FontMetrics getFontMetrics(Font f)
boolean hitClip(int x, int y, int width, int height)
abstract void setClip(int x, int y, int width, int height)
abstract void setClip(Shape clip)
abstract void setColor(Color c)
abstract void setFont(Font font)
abstract void setPaintMode()
abstract void setXORMode(Color c1)
String toString()
abstract void translate(int x, int y)
Dentro de poco veremos con detalle todos estos mtodos.
En Java2 la clase Graphics ha sido potenciada aadiendo la clase
Graphics2D, que la am pla aadiendo m uchas posibilidades a la
grfica de Java.
Para tener una pequea muestra de las potencialidades de Java
podis ver la Demo que est junto a las JDK. Si, por ejemplo,
habis bajado las JDK1.3 y las habis instalado en c:\jdk1.3, la
demo est en:
c:\jdk1.3\demo\jfc\Java2D
y para ponerla en m archa hay que escribir del prompt:

java -jar Java2Demo.jar

Visualizacin de las im genes

Em pezamos viendo los mtodos drawImage de la clase


Graphics con los que es posible visualizar unas im genes
guardadas con form ato gif o jpg.
En la clase Graphics hay varios mtodos drawImage que

son:
abstract boolean drawImage(Im age img, int x, int y, Color
bgcolor, Im ageObserver observer) abstract boolean
drawImage(Im age img, int x, int y, Im ageObserver
observer)
abstract boolean drawImage(Im age img, int x, int y, int
width, int height, Color bgcolor, ImageObserver observer)
abstract boolean drawImage(Im age img, int x, int y, int
width, int height, Im ageObserver observer)
abstract boolean drawImage(Im age img, int dx1, int dy1, int
dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor,
ImageObserver observer)
abstract boolean drawImage(Im age img, int dx1, int dy1, int
dx2, int dy2, int sx1, int sy1, int sx2, int sy2,
ImageObserver observer)
Todos los mtodos requieren dos parm etros Image y
ImageObserver.
Image rapresenta la im agen que hay que visualizar. Es una
clase abstracta que perm ite un acceso independiente del
form ato de imgenes grficas. Los objetos de esta clase se
crean utilizando los mtodos de otras clases que crean
im genes, segn el contexto en el que se quieran utilizar.
Por ejemplo, si quiero dibujar una im agen en un componente
Gui, puedo usar el mtodo createImage() de la clase
Component.
En cam bio, si quiero dibujar una im agen en un aplique, es
posible usar el mtodo getIm age() de la clase Applet.
La clase Toolkit tiene tanto createIm age() como getImage().
El otro parm etro que necesitan las drawImage() es un
objeto que implem enta la interfaz Im ageObserver, y en la

prctica representa el objeto grfico sobre el que se


visualizar la im agen.
Component implementa la interfaz Im ageObserver y,
consecuentem ente, la implem entan todas sus extensiones:

Todos los GUI

Los Apliques

Todas las ventanas (incluso los Fram es)


Los dems parm etros son:

la posicin x en la que se visualizar la imagen en el


componente

la posicin y en la que se visualizar la imagen en el


componente el color del fondo
Vamos a poner un ejemplo de visualizacin de una imagen.
En prim er lugar creamos una im agen como la siguiente:

y la guardamos en formato gif usando un editor cualquiera


de im genes llam ndola, por ejemplo, pietro.jpg.
Ahora cream os el siguiente aplique:
im port java.awt.*; // Para la clase Graphics
im port java.applet.*; // Para la clase Applet
im port java.net.*; // Para las URL
/*
Como hemos tenido ya la ocasin de decir, los archivos para
los apliques no son otra cosa que unas URL
*/
public class VisualizaImagen extends Applet
{
Image ImagenPietro;
public void init()
{
setBackground(Color.white);
ImagenPietro=getIm age(getDocum entBase(),"pietro.jpg");
}
public void paint(Graphics g)
{
g.drawIm age(ImagenPietro,0,0,this);
getAppletContext().showStatus("Visualizo la imagen
pietro.jpg, Applet creada por Pietro Castellucci");

}
}
La ponemos en un archivo llam ado VisualizaImagen.java y la
invocamos usando el docum ento html siguiente
(Im agen.html):
<htm l>
<head>
<title>
Applet VisualizaImagen, visualiza la im agen pietro.jpg
</title>
</head>
<body>
<APPLET code="VisualizaImagen.class" width=385
height=100>
</APPLET>
<BR>
La de arriba es un aplique, sin embargo la de abajo no lo es.
<BR>
<IMG SRC="pietro.jpg">
</body>
</htm l>
Si ponemos en m archa el aplique nos damos cuenta de que
no hay ninguna diferencia entre la im agen cargada en el
aplique y la que hemos cargado usando el tag IMG SRC del
html, sino el mensaje que aparece cuando pasamos por
encima el ratn. Os podra parecer incluso un trabajo intil
para vuestras pginas html.
Esto es absolutam ente falso porque la imagen cargada en el

aplique pertenece a un programa que puede hacer incluso


cosas complejas. Por ejemplo, es posible aadir otros
componentes GUI al aplique, o elaborar las imgenes
mism as, como se ve en el ejemplo sucesivo
(VisualizaIm agen2.java):
im port java.awt.*; // Para la clase Graphics
im port java.applet.*; // Para la clase Applet
im port java.net.*; // Para las URL
im port java.awt.event.*; // Para los sucesos
/*
Como ya hemos dicho, los archivos para los apliques no son
otra cosa que unas URL
*/
public class VisualizaImagen2 extends Applet
{
Image ImagenPietro;
CheckboxGroup gruppo=new CheckboxGroup();
Checkbox b1=new Checkbox("Parar",grupo,true);
Checkbox b2=new Checkbox("Anim ada",grupo,false);
Panel p=new Panel(new GridLayout(1,3));
public void init()
{
setBackground(Color.white);

setLayout(new BorderLayout());
ImagenPietro=getIm age(getDocum entBase(),"pietro.jpg");
p.add(new Label());
p.add(b1);
p.add(b2);
b1.addItemListener(new IL());
b2.addItemListener(new IL());
add(p,BorderLayout.SOUTH);
}
boolean MOVIMIENTO=false;
ent nmero=0;
ent inc=1;
public void paint(Graphics g)
{
if (!MOVIMIENTO)
{
g.drawIm age(ImagenPietro,0,0,this);
getAppletContext().showStatus("Visualizo la imagen
pietro.jpg, Imagen inmvil, Applet creada Pietro
Castellucci");
nm ero=0;

}
else
{
g.setPaintMode();
g.drawIm age(Elabora(ImagenPietro,nm ero),0,0,this);
for (int k=0;k<=99;k++)
getAppletContext().showStatus("Visualizo la imagen
pietro.jpg, Frame "+nm ero+", Applet creada por Pietro
Castellucci");
getAppletContext().showStatus("Visualizo la imagen
pietro.jpg, Frame "+nm ero+", Applet creada por Pietro
Castellucci");
if (nm ero>=10) inc=-1;
if (nm ero<=0) inc=1;
nm ero+=inc;
}
repaint();
}

Image Elabora (Image img, int frm)


{

return img.getScaledInstance(324-(frm*20), 85(frm *4),img.SCALE_FAST);


}

public class IL implements ItemListener


{
public void item StateChanged(Item Event e)
{
if (b1.getState()) MOVIMIENTO=false;
else MOVIMIENTO=true;
repaint();
}
}
}
Cargada por el archivo html siguiente:
<htm l>
<head>
<title>
Applet VisualizaImagen, visualiza la im agen pietro.jpg
</title>
</head>
<body>
<APPLET code="VisualizaImagen2.class" width=385
height=100>
</APPLET>

<BR>
La de arriba es un aplique, sin embargo la de abajo no lo es
<BR>
<IMG SRC="pietro.jpg">
</body>
</htm l>
La nueva clase Graphics2D pone a disposicin otros m todos
drawImage, entre los que hay algunos que tienen un
parm etro de tipo AffineTransform que, como dice el
nombre, es una transform acin parecida a la de la im agen,
una rotacin o una translacin, o una combinacin de todas.
Para tener una versin sin revoloteo basta con aadir la
funcin:
public void update(Graphics g)
{
paint(g);
}

Dibujo

Entendido el funcionamiento de la paint() podemos dibujar


cualquier cosa en un aplique o en un componente en
general.

La cosa m s simple que se puede dibujar es la lnea. Para


hacerlo, utilizamos el mtodo drawLine() de Graphics:
drawLine(Iniciox, Inicioy, Finx, Finy)
ste dibuja una lnea que parte de un punto (Iniciox, Inicioy)
y llega a otro punto (Finx, Finy).
Antes de utilizar la drawLine() tenemos que comprender
cmo se pueden cambiar los colores de las cosas que
dibujamos.
Los colores se cambian utilizando el m todo setColor(Color
c) de la clase Graphics.
Color es otra clase de awt que permite definir un color.
Algunos de sus constructores son:
Color(float r, float g, float b), crea un color especificando los
valores RGB (Red - Green - Blue, es decir, Rojo - Verde Azul) con unos valores entre 0 y 1.
Color(float r, float g, float b, float a), como el anterior, slo
que permite definir incluso el valor alfa
Color(int r, int g, int b) , crea un color especificando los
valores RGB (Red - Green - Blue, es decir, Rojo - Verde Azul) con valores entre 0 y 255.
Color(int r, int g, int b, int a), como el anterior, slo que
perm ite definir incluso el valor alfa
Algunos colores simples se dan a travs de unas constantes
en la clase color:

Color.black
Color.blue
Color.cyan
Color.darkGray
Color.gray
Color.green
Color.lightGray
Color.m agenta
Color.orange
Color.pink
Color.red
Color.white
Color.yellow
En el siguiente aplique se dibujan unas lneas de colores.
im port java.awt.Graphics;
im port java.awt.Color;
im port java.awt.Button;
im port java.awt.BorderLayout;
im port java.awt.GridLayout;
im port java.awt.Panel;
im port java.awt.event.ActionEvent;
im port java.awt.event.ActionListener;

im port java.applet.*;
public class lneas extends Applet
{
final ent SI=14;
final ent NO=0;
Button R=new Button("Rojo");
Button G=new Button("Verde");
Button B=new Button("Azul");
ent r_=0;
ent g_=0;
ent b_=0;
ent ir=0;
ent ig=0;
ent ib=0;
public void init()
{
setLayout(new BorderLayout());

Panel np=new Panel(new GridLayout(1,3));


np.add(R);
np.add(G);
np.add(B);
R.addActionListener(new ActionListener()
{
public void actionPerform ed(ActionEvent e)
{
ir=S;
ig=NO;
ib=NO;
repaint();
}
}
);

G.addActionListener(new ActionListener()
{
public void actionPerform ed(ActionEvent e)
{
ir=NO;
ig=S;

ib=NO;
repaint();
}
}
);

B.addActionListener(new ActionListener()
{
public void actionPerform ed(ActionEvent e)
{
ir=NO;
ig=NO;
ib=S;
repaint();
}
}
);

add(np,BorderLayout.SOUTH);
}
public void paint(Graphics g)
{

for (ent e=0;e<200;e+=10)


{
g.setColor(new Color(r_,g_,b_));
r_=r_+ir;
g_=g_+ig;
b_=b_+ib;
g.drawLine(0,i,i,200);
}
g.setColor(Color.black);
g.drawLine(0,0,0,200);
g.drawLine(0,200,200,200);
r_=0;
g_=0;
b_=0;
}
}
El archivo lo llam amos lneas.java y lo cargamos con el
archivo html siguiente (lneas.html):
<htm l>
<head>
<title>

Applet Lneas (lneas.class)


</title>
</head>
<body>
<APPLET code="lineas.class" width=200 height=300>
</APPLET>
</body>
</htm l>

Figuras geom tricas y texto

RECTNGULOS
Graphics permite dibujar unos rectngulos especificando dos
aristas opuestas usando el mtodo:
drawRect(Iniciox,Inicioy,Finx,Finy);
Este m todo es igual a:
drawLine(Iniciox,Inicioy,Finx,Inicioy);
drawLine(Iniciox,Inicioy,Iniciox,Finy);
drawLine(Finx,Inicioy,Finx,Finy);
drawLine(Iniciox,Finy,Finx,Finy);
Es posible incluso construir rectngulos que den un efecto

levantado o ahuecado usando el m todo draw3DRect(ent


x,ent y,int anchura,ent altura,boolean levantado) y
rectngulos con las aristas redondeadas con el m todo
drawRoundRect(ent x, ent y, ent anchura, ent altura, ent
anchuraArco, ent alturaArco).
Adem s es posible colorear en todas las figuras cerradas
usando los mtodos fill. Por ejemplo, para colorear un
RoundRect hay que utilizar fillRoundRect, que tiene los
mismos parm etros que la correspondiente draw.
CRCULOS Y ELIPSIS
Se puede dibujar una elipsis usando la drawOval (ent x, ent
y, ent anchura,ent altura) y colorearla usando la fillOval(ent
x, ent y, ent anchura,ent altura).
Si la altura y la anchura son iguales se dibuja un crculo.
POLGONOS
Usando la drawPolygon se dibuja un polgono genrico. Hay
dos tipos de drawPolygon:
drawPoligon( ent[] PUNTOSx, ent PUNTOSy, ent
NUMEROSPUNTOS);
e
drawPolygon (Polygon p)
La segunda usa un objeto de la clase Polygon que define un
polgono. Estn las correspondientes fillPolygon.

TEXTO
Para dibujar una cadena se puede utilizar el m todo
drawString (String TEXTO, ent x, ent y);
Un texto se puede dibujar con distintas Font. Para cam biar
las Font Graphics pone a disposicin el mtodo setFont(Font
font), en el que font es el objeto que define el tipo de
carcter.
Font es la clase que define los caracteres y es posible
invocarla creando un Font especfico, usando Font(String
nam e, ent style, ent size).
Font es una clase bastante complicada, sin embargo es fcil
encontrar y usar los Fonts del sistem a mientras se pone en
m archa programma java: En las viejas versiones de java
basta con escribir:
String []
NOMBRES=Toolkit.getDefaultToolkit().getFontList();
Mientras en las nuevas versiones de Java (de JDK 1.2 )
String [] NOMBRES=GraphicsEnvironm ent.
getLocalGraphicsEnvironment().
getAvailableFontFamilyNam es();
Adem s es fcil escribir objetos sabiendo los nombres.
ARCOS
Puedo dibujar unos arcos usando drawArc(ent x, ent y, ent
anchura, ent altura, ent nguloInicial, ent nguloArco)

El uso de todos estos mtodos se explica en el ejemplo que


ponemos a continuacin.
El archivo que lo pone en m archa es:
<htm l>
<head>
<title>
Applet grafDemo (grafDemo.class)
</title>
</head>
<body>
<APPLET code="grafDemo.class" width=500 height=400>
</APPLET>
</body>
</htm l>

Archivo grafDemo.java

El ejemplo, editado en el archivo grafDemo.java, es:


im port java.awt.Graphics;
im port java.awt.Color;
im port java.awt.Button;

im port java.awt.BorderLayout;
im port java.awt.GridLayout;
im port java.awt.FlowLayout;
im port java.awt.Panel;
im port java.awt.Label;
im port java.awt.Choice;
im port java.awt.Font;
im port java.awt.Toolkit;
im port java.awt.Checkbox;
im port java.awt.Scrollbar;
im port java.awt.GraphicsEnvironment;
im port java.awt.event.Item Event;
im port java.awt.event.Item Listener;
im port java.awt.event.Adjustm entListener;
im port java.awt.event.Adjustm entEvent;
im port java.applet.*;

public class grafDemo extends Applet


{
Scrollbar R=new Scrollbar(Scrollbar.VERTICAL, 0, 1, 0, 255);
Scrollbar G=new Scrollbar(Scrollbar.VERTICAL, 0, 1, 0,
255);
Scrollbar B=new Scrollbar(Scrollbar.VERTICAL, 0, 1, 0, 255);
Choice FN=new Choice();
Choice GR=new Choice();
Checkbox F=new Checkbox("Figuras cerradas llenas",false);
ent [] puntosX={1,100,200,300,399,300,200,100};
ent [] puntosY={200,150,50,150,200,100,250,130};
ent puntos=8;
public void init()
{
// Calculo los Font del sistem a:
// String[] NOMBRES=GraphicsEnvironment.
// getLocalGraphicsEnvironm ent().
// getAvailableFontFamilyNam es();
/*

Para Java presentes en los browser


String []
NOMBRES=Toolkit.getDefaultToolkit().getFontList();
*/
String []
NOMBRES=Toolkit.getDefaultToolkit().getFontList();
try
{
ent ndice=0;
while (true)
{
FN.addItem (NOMBRES[ndice++]);
}
}
catch (ArrayIndexOutOfBoundsException e)
{};
setLayout(new BorderLayout());
Panel np=new Panel(new GridLayout(1,3));

Panel rojo=new Panel(new FlowLayout());


rojo.add(new Label("Rojo"));
rojo.add(R);
np.add(rojo);

Panel verde=new Panel(new FlowLayout());


verde.add(new Label("Verde"));
verde.add(G);
np.add(verde);
Panel azul=new Panel(new FlowLayout());
azul.add(new Label("Azul"));
azul.add(B);
np.add(azul);
R.setUnitIncrem ent(10);
R.setValue(255);
G.setUnitIncrem ent(10);
G.setValue(255);
B.setUnitIncrement(10);
B.setValue(255);
add(np,BorderLayout.SOUTH);
GR.addItem ("Lnea");
GR.addItem ("Rectngulo");
GR.addItem ("Rectngulo 3D");
GR.addItem ("Rectngulo Redondeado");
GR.addItem ("Crculo");

GR.addItem ("Elpses");
GR.addItem ("Polgono genrico");
GR.addItem ("Texto");
GR.addItem ("Arco");
Panel up=new Panel(new GridLayout(1,3));
up.add(GR);
up.add(FN);
up.add(F);
add(up,BorderLayout.NORTH);
R.addAdjustmentListener(new AL());
G.addAdjustm entListener(new AL());
B.addAdjustmentListener(new AL());
GR.addItemListener(new IL());
FN.addItemListener(new IL());
F.addItemListener(new IL());
}

public void paint(Graphics g)


{
g.setColor(new Color(255-R.getValue(),
255-G.getValue(),
255-B.getValue()
));
g.setFont(new Font(FN.getSelectedItem (),0,40));
boolean filled=F.getState();
int pg=GR.getSelectedIndex();
g.drawString(GR.getSelectedItem (),1,300);
if (pg==0)
{
g.drawLine(1,100,399,300);
return;
}
if (pg==1)
{
g.drawRect(50,100,250,100);
if (filled) g.fillRect(50,100,250,100);
return;
}
if (pg==2)
{

g.draw3DRect(50,100,250,100,true);
return;
}
if (pg==3)
{
g.drawRoundRect(50,100,300,100,20,20);
if (filled) g.fillRoundRect(50,100,300,100,20,20);
return;
}
if (pg==4)
{
g.drawOval(100,100,200,200);
if (filled) g.fillOval(100,100,200,200);
return;
}
if (pg==5)
{
g.drawOval(100,100,200,100);
if (filled) g.fillOval(100,100,200,100);
return;
}
if (pg==6)
{
g.drawPolygon(puntosX,puntosY,puntos);
if (filled) g.fillPolygon(puntosX,puntosY,puntos);
return;
}

if (pg==7)
{
g.drawString("sta es una cadena",1,200);
return;
}
if (pg==8)
{
g.drawArc(1,50,398,200,10,270);
if (filled) g.fillArc(1,50,398,200,10,270);
return;
}

}
public class IL implements ItemListener
{
public void item StateChanged(Item Event e)
{
repaint();
}
}
public class AL implem ents Adjustm entListener
{
public void adjustmentValueChanged(AdjustmentEvent e)
{

repaint();
}
}

Notas para redactar el programa

Visto que el program a ha sido creado para un navegador


(que tiene las versiones de Java) se ha tenido que utilizar
String []
NOMBRES=Toolkit.getDefaultToolkit().getFontList(); para
obtener los caracteres, si se redacta con JDK 1.2 o 1.3 se
tiene que escribir:
javac grafDemo.java -deprecation
Esto dar un aviso para decir que se usa un mtodo
deprecated.
Si, en cambio, utilizis el appletviewer para visualizar el
aplique, podis cambiar
String []
NOMBRES=Toolkit.getDefaultToolkit().getFontList();

con
String [] NOMBRES=GraphicsEnvironm ent.
getLocalGraphicsEnvironment().
getAvailableFontFamilyNam es();
y apreciar la gran cantidad de Font que hay.
En el ejemplo, he utilizado los colores de scrollbar, entre
ellos los GUI que no hemos visto. Para crear el objeto
scrollbar he utilizado el constructor:
Scrollbar R=new Scrollbar(Scrollbar.VERTICAL, 0, 1, 0, 255);
que crea una barra (scrollbar) vertical con valores entre 0 y
255 con valor inicial 0.
Despus he averiguado el valor de la barra con
R.setValue(255); he dicho que el increm ento por cada clic
tiene que ser 10 con R.setUnitIncrement(10);
Para escuchar los cambios, utilizo un objeto que implem enta
la clase Adjustm entListener que, a su vez, escucha los
sucesos de tipo Adjustm entEvent. Para asociar el oyente al
objeto scrollbar se utiliza el mtodo addAdjustm entListener.

El sonido de Java 1.1.x y 1.2.x

Hasta ahora hemos intentado crear program as compatibles


entre las viejas y las nuevas versiones de Java. Esto para
crear unos apliques generales que puedan trabajar en todos
los browser (que tienen actualm ente Java 1.1.x come motor
para los apliques).
En el apartado que estamos a punto de tratar,
desgraciadam ente esto no es posible. Con las viejas
versiones de Java se pueden crear unos apliques que leen y
tocan archivos de tipo .au, usando los m todos play de

applet y la interfaz AudioClip.


Todo esto es posible todava con Java2, versin 1.3, sin
embargo se han incluido unos paquetes para gestionar los
sonidos que ofrecen potencialidades excepc ionales.

El sonido en jdk1.3: javax.swing.sam pled

Los paquetes que se han aadido al lenguaje son 4:

javax.sound.midi

javax.sound.midi.spi

javax.sound.sampled

javax.sound.sampled.spi

Las partes que acaban por spi sirven para leer archivos
sonoros, convertirlos o leer los archivos de instrum entos en
el caso de midi. Nosotros no vamos a ver ests partes, sin
embargo veremos javax.sound.sampled y javax.sound.midi.
El paquete javax.swing.sampled permite grabar, tocar y
modificar datos sonoros.

El contenido del paquete es:


Interfaces

Clip

DataLine

Line

LineListener

Mixer

Port

SourceDataLine

TargetDataLine

Clases

AudioFileFormat

AudioFileFormat.Type

AudioForm at

AudioForm at.Encoding

AudioInputStream

AudioPermission

AudioSystem

BooleanControl

BooleanControl.Type

CompoundControl

CompoundControl.Type

Control

Control.Type

DataLine.Info

EnumControl

EnumControl.Type

FloatControl

FloatControl.Type

Line.Info

LineEvent

LineEvent.Type

Mixer.Info

Port.Info

ReverbType

Excepciones

LineUnavailableException

UnsupportedAudioFileException

Vamos a ver cmo utilizar este paquete slo para tocar un


archivo sonoro, por ejemplo, el archivo llam ado italian.wav.
En prim er lugar, tenemos que buscar el archivo y esto lo
hacemos, como siempre, introduciendo un objeto de la clase
File (de java.io)
File sf=new File("italian.wav");
Llegados a este punto, empezamos una try{} catch, en la
que incluimos todo lo que tiene que ver con el sonido.
Despus capturaremos las excepciones:
catch(UnsupportedAudioFileException ee){}
catch(IOException ea){}
catch(LineUnavailableException LUE){};
Para usar el motor sonoro de Java tenemos que empezar por
la clase AudioSystem y de sta obtendremos dos objetos de
tipo AudioFileForm at y AudioInputStream
AudioFileFormat aff=AudioSystem .getAudioFileFormat(sf);
AudioInputStream
ais=AudioSystem .getAudioInputStream (sf);
que representan el contenido del archivo italian.wav
tenemos que crear un objeto AudioForm at de

AudioFileFormat para que se pueda tocar


AudioForm at af=aff.getForm at();
Nuestro objetivo es crear un objeto que implem ente la
interfaz Clip, que incluye los m todos play. Para hacer esto
escribiremos:
DataLine.Info info = new DataLine.Info(
Clip.class,
ais.getForm at(),
((int) ais.getFrameLength() *
af.getFram eSize()));
Clip ol = (Clip) AudioSystem .getLine(info); De ol, que es el
tipo Clip, podemos tocar y esto se consigue abriendo una
lnea e invocando los m todos para tocar:
ol.open(ais); <-(ABRIR l'input stream , es decir, el archivo
italian.wav)
y, por lo tanto
ol.loop(NMERO);
en el que NMERO indica el nm ero de repeticiones del
archivo, en nuestro caso, Clip. LOOP_CONTINUOUSLY para
indicar que se tiene que repetir infinitas veces.
El ejemplo completo, editado en sonido.java es:
im port javax.swing.*;

im port javax.sound.sam pled.*;


im port java.io.*;
public class sonido extends JFram e
{

public sonido()
{
File sf=new File("italian.wav");
AudioFileFormat aff;
AudioInputStream ais;

try
{
aff=AudioSystem .getAudioFileForm at(sf);
ais=AudioSystem .getAudioInputStream (sf);

AudioForm at af=aff.getForm at();

DataLine.Info info = new DataLine.Info(


Clip.class,
ais.getForm at(),
((int) ais.getFrameLength() *
af.getFram eSize()));
Clip ol = (Clip) AudioSystem .getLine(info);

ol.open(ais);
ol.loop(Clip.LOOP_CONTINUOUSLY);
System .out.println("reproducin em pezada, apretar CTRL-C
para interrumpir");
}
catch(UnsupportedAudioFileException ee){}
catch(IOException ea){}
catch(LineUnavailableException LUE){};
}
public static void m ain(String[] ar)
{
new sonido();
}
}
Parece un poco trabajoso, sin embargo, siguiendo estos
pasos es posible leer y tocar cada archivo wav. Para hacer
otras operaciones, el paquete es bastante complejo y
actualmente no hay m anuales que expliquen el
funcionam iento (excepto la documentacin del JDK que,
como habis tenido la oportunidad de ver, no explica cmo
utilizar las cosas, sino que las describe y punto).

El paquete javax.suond.midi

Vamos a ver cmo leer y tocar un archivo midi. Para hacerlo


necesitamos el paquete javax.suond.midi que incluye:
Interfaces

ControllerEventListener

MetaEventListener

MidiChannel

MidiDevice

Receiver

Sequencer

Soundbank

Synthesizer

Transm itter

Clases

Instrument

MetaMessage

MidiDevice.Info

MidiEvent

MidiFileForm at

MidiMessage

MidiSystem

Patch

Sequence

Sequencer.SyncMode

ShortMessage

SoundbankResource

SysexMessage

Track

VoiceStatus

Excepciones

InvalidMidiDataException

MidiUnavailableException

La tcnica para tocar un archivo midi es parecida a la que se


usa para el archivo wav, lo nico diferente es que se parte
de MidiSystem .
En el ejemplo que ponemos a continuacin, se toca el
archivo sorpresa.m id, que es un archivo midi que m e gusta
mucho y, creo, le va a gustar a todos mis coetneos.
Hay que editarlo en el archivo m idifiles.java

im port javax.swing.*;
im port javax.sound.midi.*;
im port java.io.*;
public class m idifiles extends JFram e
{
public m idifiles()
{
try
{
File f2=new File("sorpresa.m id");
MidiFileForm at m ff2=MidiSystem .getMidiFileForm at(f2);
Sequence S=MidiSystem .getSequence(f2);
Sequencer seq=MidiSystem.getSequencer();
seq.open();
seq.setSequence(S);
seq.start();
System .out.println("Sorpresa para todos m is coetneos");
System .out.println("Apretar CTRL-C para interrumpir");

}
catch(MidiUnavailableException ecc){}
catch(InvalidMidiDataException ecc2){}
catch(IOException ecc3){}
;
}

public static void m ain(String[] ar)


{
new m idifiles();
}
}

Sintetizar los sonidos

Como ya he dicho, es posible sintetizar los sonidos. Esto es lo que hace el


prximo program a que hay que editar en el archivo sintetizador.java
im port javax.swing.*;
im port java.awt.*;
im port java.awt.event.*;
im port javax.swing.border.*;
im port java.yo.*;

im port java.util.*;
im port javax.sound.sam pled.*;
im port javax.sound.midi.*;
public class sintetizador extends JFram e
{
ent TIEMPO=50;
ent CANAL=0;
ent UNS=-1;
ent INSTRUMENTO=0;
Sintetizador SINTETIZADOR=new Sintetizador();
// GUI
JLabel teclado1=new JLabel(new Im ageIcon("teclado1.gif"));
JLabel teclado2=new JLabel(new Im ageIcon("teclado2.gif"));
JButton OkB=new JButton("Ok");

JComboBox Instrumentos=new JComboBox();


JComboBox Canales=new JComboBox();
JLabel uns=new JLabel("ltima nota tocada");
JTextField msg=new JTextField(
"Ninguna nota"
);
JSlider SL=new JSlider();
public sintetizador()

{
setTitle("Sintetizador sonoro de Pietro Castellucci");
setupAspecto();
setupValores();
setupSucesos();
SINTETIZADOR.setInstrum ento(
Instrumentos.getSelectedIndex(),CANAL);
setResizable(false);
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
pack();
Toolkit t = Toolkit.getDefaultToolkit();
Dim ension d=t.getScreenSize();
Dim ension win=getSize();
win=getSize();
setLocation(d.width/2-(win.width/2)-1,d.height/2-(win.height/2)-1);
show();
}

void setupAspecto()
{
teclado1.setCursor(new Cursor(Cursor.HAND_CURSOR));
teclado2.setCursor(new Cursor(Cursor.HAND_CURSOR));
OkB.setCursor(new Cursor(Cursor.HAND_CURSOR));
tastiera1.setToolTipText(
"Clcame para tocar"
);
tastiera2.setToolTipText(
"Clcame para tocar"
);
OkB.setToolTipText(
"Salir del program a"
);

JPanel P=new JPanel(new BorderLayout());


JPanel Panel=new JPanel(new GridLayout(2,1));
Panel.add(teclado1);
Panel.add(teclado2);
P.add(Panel,BorderLayout.CENTER);
JPanel SP=new JPanel(new FlowLayout());
Instrumentos.setBorder(
BorderFactory.createTitledBorder(

"Instrum entos"
)
);
Canales.setBorder(
BorderFactory.createTitledBorder(
"Canales"
)
);
SP.add(Instrum entos);
// SP.add(Canales);
SP.add(uns);
m sg.setEditable(false);
m sg.setBackground(P.getBackground());
SP.add(m sg);
SP.add(OkB);
P.add(SP,BorderLayout.SOUTH);
SL.setBorder(BorderFactory.createTitledBorder(
"Presin "
));
SL.setOrientation(JSlider.VERTICAL);
SL.setMajorTickSpacing(25);
SL.setMaxim um(100);
SL.setMinimum(0);
SL.setMinorTickSpacing(1);

SL.setPaintLabels(true);
SL.setPaintTicks(true);
SL.setPaintTrack(true);
SL.setSnapToTicks(true);
SL.setValue(TIEMPO);
P.add(SL,BorderLayout.EAST);

setContentPane(P);
}

void setupValores()
{
try
{
ent e=0;
while (true)
{
String nombre= SINTETIZADOR.Instrum entos[i++].getNam e();
Instrumentos.addItem (nombre);
}
}
catch (ArrayIndexOutOfBoundsException e)
{};

try
{
int i=0;
while (true)
{
String nombre="Canales"+" "+(i+1);
SINTETIZADOR.CANALES[i++].allNotesOff();
Canales.addItem(nombre);
}
}
catch (ArrayIndexOutOfBoundsException e)
{};
if (Instrum entos.getItemCount()>0)
Instrumentos.setSelectedIndex(INSTRUMENTO);
}

void setupSucesos()
{
teclado1.addMouseListener(new Teclado1Listener());
teclado2.addMouseListener(new Teclado2Listener());

Instrumentos.addItem Listener(new Item Listener()


{
public void item StateChanged(Item Event e)

{
SINTETIZADOR.setInstrum ento(
Instrumentos.getSelectedIndex(),CANALES);
}
}
);

Canales.addItemListener(new ItemListener()
{
public void item StateChanged(Item Event e)
{
CANALES=Canales.getSelectedIndex();
SINTETIZADOR.cambiaCanal(CANAL);
}
});

OkB.addActionListener(new ActionListener()
{
public void actionPerform ed(ActionEvent e)
{
System .out.println("Gracias por haber tocado conmigo!");
System .exit(0);
}
}
);

}
// Sucesos

public class Teclado1Listener implements MouseListener


{
public void mouseClicked(MouseEvent e)
{}
public void mouseEntered(MouseEvent e)
{}
public void mouseExited(MouseEvent e)
{}
public void mousePressed(MouseEvent e)
{
// System .out.println("Teclado 1 Punto:
(x="+e.getX()+",y="+e.getY()+")");
UNS=getNota(e.getX());
// System .out.println("Nota="+nota);
TIEMPO=SL.getValue();
SINTETIZADOR.tocar(UNS,TIEMPO,CANAL);
m sg.setText(""+(UNS+1));
}
public void mouseReleased(MouseEvent e)

{}
}

public class Teclado2Listener implements MouseListener


{
public void mouseClicked(MouseEvent e)
{}
public void mouseEntered(MouseEvent e)
{}
public void mouseExited(MouseEvent e)
{}
public void mousePressed(MouseEvent e)
{
// System .out.println("Teclado 2 Punto:
(x="+e.getX()+",y="+e.getY()+")");
UNS=64+getNota(e.getX());
// System .out.println("Nota="+nota);
TIEMPO=SL.getValue();
SINTETIZADOR.suona(UNS,TIEMPO,CANAL);
m sg.setText(""+(UNS+1));
}
public void mouseReleased(MouseEvent e)
{}
}

// Utility fun
int getNota (int pos)
{
int nota;
nota=(pos/12);
return nota;
}

public static void m ain(String[] arg)


{
new sintetizador();
}

//*****************************************
// SOUND MANAGER
//*****************************************
//**********************************************************
*
// Sintetizador:
//**********************************************************

*
public class Sintetizador
{
private Synthesizer SYNT;
private Sequencer sequencer;
private Sequence seq;
private Soundbank BANK;
public Instrum ent[] Instrumentos;
public MidiChannel[] CANALES;
public Sintetizador()
{
setupSintetizador();
}
void setupSintetizador()
{
try
{
SYNT=MidiSystem.getSynthesizer();
sequencer=MidiSystem.getSequencer();
seq= new Sequence(Sequence.PPQ, 10);
SYNT.open();
BANK = SYNT.getDefaultSoundbank();
if (BANK != null)
Instrumentos = SYNT.getDefaultSoundbank().getInstruments();
else
Instrumentos = SYNT.getAvailableInstrum ents();
CANALES=SYNT.getChannels();
}
catch(MidiUnavailableException ecc){todonull();}

catch(InvalidMidiDataException ecc2){todonull();}
;
}
void todonull()
{
SYNT=null;
sequencer=null;
seq=null;
BANK=null;
Instrumentos=null;
}
public void setInstrum ento(int str,int can)
{
SA=str;
int prog=Instrum entos[str].getPatch().getProgram ();
CANALES[can].programChange(prog);
}
private int SA=0;
public void cambiaCanal(int can)
{
int prog=Instrum entos[SA].getPatch().getProgram ();
CANALES[can].programChange(prog);
}
public void tocar(ent nota,ent tiempo, ent canal)
{

CANALES[canal].allNotesOff();
CANALES[canal].noteOn(nota,tiem po);
}
public void tocar(ent nota,ent tiempo)
{
tocar(nota,tiempo,0);
}
public void callar()
{
CANALES[0].allNotesOff();
}

} // End of Sintetizador
}
Os habis dado cuenta de que es un program a consistente, sin embargo no
tenis que espantaros porque la m ayor parte del cdigo sirve para la
grfica y para escuchar los sucesos. La parte interesante para sintetizar los
sonidos la he puesto en la subclase Sintetizador, es decir, en
sintetizador.Sintetizador
es decir, la siguiente:
//**********************************************************
*
// Sintetizador:
//**********************************************************
*

public class Sintetizador


{
private Synthesizer SYNT;
private Sequencer sequencer;
private Sequence seq;
private Soundbank BANK;
public Instrum ent[] Instrumentos;
public MidiChannel[] CANALES;
public Sintetizador()
{
setupSintetizador();
}
void setupSintetizador()
{
try
{
SYNT=MidiSystem.getSynthesizer();
sequencer=MidiSystem.getSequencer();
seq= new Sequence(Sequence.PPQ, 10);
SYNT.open();
BANK = SYNT.getDefaultSoundbank();
if (BANK != null)
Instrumentos = SYNT.getDefaultSoundbank().getInstruments();
else
Instrumentos = SYNT.getAvailableInstrum ents();
CANALES=SYNT.getChannels();
}
catch(MidiUnavailableException ecc){todonull();}
catch(InvalidMidiDataException ecc2){todonull();}
;
}

void todonull()
{
SYNT=null;
sequencer=null;
seq=null;
BANK=null;
Instrumentos=null;
}
public void set nstrum ento(ent str,ent can)
{
SA=str;
ent prog=Instrum entos[str].getPatch().getProgram ();
CANALES[can].programChange(prog);
}
private ent SA=0;
public void cambiaCanal(ent can)
{
ent prog=Instrum entos[SA].getPatch().getProgram ();
CANALES[can].programChange(prog);
}
public void tocar(ent nota,ent tiempo, ent canal)
{
CANALES[canal].allNotesOff();
CANALES[canal].noteOn(nota,tiem po);
}
public void tocar(ent nota,ent tiempo)
{
tocar(nota,tiempo,0);
}

public void callar()


{
CANALES[0].allNotesOff();
}
} // End of Sintetizador
El aspecto del program a es:

Conclusiones y bibliografa

Hemos hecho un resum en de algunas partes del famoso


lenguaje Java, m uy utilizado para escribir los program as que
trabajan en internet y no slo para eso; empezando por las
bases hasta llegar a las interfaces grficas y, finalmente, al
sonido. stos son todos aspectos m s avanzados de la

program acin.
Quiero disculparm e con mis lectores menos expertos por si
han tenido problem as para entender algunas partes de la
gua y, al mismo tiempo, quiero hacerlo con los m s
expertos si han encontrado algo dem asiado aburrido o
sim ple. Los que han asistido a todo el curso tendran que ser
capaces de escribir unos apliques simples y unas
aplicaciones por su cuenta. No creo que hayis conseguido
todava gestionar grandes aplicaciones complejas, aunque,
con un poco de prctica y con los simples conceptos del
curso, os vis a convertir en excelentes program adores.
Yo estar siem pre disponible a posibles preguntas sobre el
curso o a m s explicaciones, pero os pido que no m e
escribis para los Javascript o para la configuracin de los
apliques bajados de la red.
Para los que quieran profundizar los tem as tratados o ver
nuevos, os dejo la bibliografa completa en la que me he
basado para preparar este curso.
Un saludo a todos.

Pietro Castellucci
Foiano di Val Fortore (Benevento)

Bibliografa

Documentacin oficial de la Sun Microsystem s de Java


Development Kit Versioni 1.3, 1.3 Relase Candidate 1, 1.3
Relase Candidate 2, 1.3 Relase Candidate 3, 1.3 Beta, 1.2.2

, 1.2.1. Disponible en la red en el sito oficial de


Java: http://java.sun.com

Java Didctica y Program acin, K.Arnold e J. Gosling,


Addison-Wesley Prim era edicin, (en italiano) Marzo de 1997

Manual QUE - Special Edition Using Java, 2nd Edition,


versin encontrada en internet (en ingls).

Java2 Todo&Ms, J. Jaworski, SAMS Publishing - APOGEO


(en ingls)

Javatm 2D Graphics, J. Knudsen, O'REILLY (en ingls)

Ambiente para explorar los micromundos en competicin,


Pietro Castellucci, Tesina en Inform tica. (en italiano)

S-ar putea să vă placă și