Você está na página 1de 236

JAVA

Principales Caractersticas del Lenguaje Java


JAVA es un lenguaje de programacion desarrollado por Sun Microsystems, sus principales caractersticas
son:
Lenguaje multiplataforma (Windows, Macintosh, Unix).
Estructura similar al C++.
Orientado a objeto.
Simple y elegante.
Facilita la labor del programador eliminando dos de los problemas de otros lenguajes:
Gestion de la memoria.
Punteros.
Lenguaje multitarea.
Penetracion en Internet.
Prestaciones multimedia (texto, graficos, sonido, animaciones, etc.).
Facilmente accesible.
Esas caractersticas han hecho de JAVA uno de los lenguajes lderes y de mayor crecimiento en el
mercado.

Direcciones de Inter
es en Internet
http://www.sun.com
Direccion de la empresa Sun Microsystems, desarrolladora de Java.
http://java.sun.com
Lugar oficial de informacion sobre el lenguaje Java.
http://www.javaworld.com
Revista electronica sobre Java.
http://www.engapplets.vt.edu/
Direccion con interesantes applets aplicados a la ingeniera.
http://www.stat.duke.edu/sites/java.html
Direccion con applets relacionados con la estadstica.
http://www.um.es/ psibm/tutorial/
Tutorial de html en castellano.
http://www.wmaestro.com/webmaestro/index.html
Tutorial de html en castellano.

3
http://www.digitaleconomist.com/
Direccion con interesantes applets aplicados a la economa.
http://members.nbci.com/surendranath/
Applets.html
Direccion con interesantes applets aplicados a la fsica.
http://home.planetinternet.be/ poolly/eng/
eng.html
Direccion con interesantes applets aplicados a la fsica.

Tipos de Programas en Java


En el lenguaje Java existen dos tipos de programas:
1. Applets: Programas que se integran en las paginas Web y que se ejecutan a traves de la red.
2. Aplicaciones: Son programas normales que se ejecutan directamente por el sistema operativo
del usuario a traves de un interprete.
Restricciones de los applets
Por razones de seguridad, los applets tienen varias restricciones. Un applet no puede:
1. Cargar libreras o definir metodos nativos.
2. Leer ni escribir ficheros en el sistema anfitrion que esta ejecutandolo.
3. Hacer conexiones de red, excepto al sistema anfitrion del que procede.
4. Ejecutar cualquier programa en el sistema anfitrion que esta ejecutandolo.
5. Leer ciertas propiedades del sistema.


PROGRAMACION
ORIENTADA A OBJETOS

Programaci
on Orientada a Objetos
Java es un Lenguaje Orientado a Objetos que incorpora una gran n
umero de clases predefinidas organizadas en paquetes.
La programacion en Java supone definir clases de forma jerarquica, construir objetos de dichas clases
y realizar acciones con ellos.
Los objetos constituyen el concepto fundamental para entender la tecnologa que se conoce como
tecnologa orientada a objetos.
Objetos del mundo real:

COCHE

MESA

ORDENADOR
TELEVISOR
Todos estos objetos del mundo real tienen:
un estado
un comportamiento

Programaci
on Orientada a Objetos
Un objeto es un conjunto constituido por una o varias variables y, opcionalmente, por metodos.
Todo aquello que el objeto conoce (estado) se expresa por sus variables, y todo lo que puede hacer
(comportamiento) se expresa por sus metodos.

ESTADO

VARIABLES MIEMBRO

OBJETO
COMPORTAMIENTO

MTODOS

MTODO 1

MTODO
3

VARIABLES
MIEMBRO

MTODO
2

MTODO 4

Ejemplo de Objeto

Consideremos un objeto del mundo real: un automovil.


Nuestro objeto contiene:
1. Variables:
(a) modelo
(b) cilindrada
(c) velocidad
(d) marcha
2. Metodos:
(a) acelera
(b) frena
(c) para
(d) cambiaMarcha

Clases
En el mundo real, se encuentran muchos objetos del mismo tipo. Por ejemplo, mi automovil forma
parte del conjunto de todos los automoviles del mundo.

Clase Automovil

Utilizando la terminologa orientada a objetos, mi automovil es un miembro o ejemplar de la clase


de objetos conocidos como automoviles.
Una clase es un prototipo que define las variables y los metodos de todos los objetos con
caractersticas comunes.
Cuando se crea un ejemplar de una clase, las variables declaradas por la clase son almacenadas en
memoria.
Una vez creadas, se pueden utilizar los metodos miembro de la clase para asignar valores a las
variables.
Para definir una clase es necesario dar dos componentes: la declaracion y el cuerpo:
DeclaracionClase{
CuerpoClase
Declaraci
on de una clase
En la declaracion de una clase debe aparecer, como mnimo, la palabra class y el nombre de la
clase que se esta definiendo.
class NombreClase{
...

8
Los nombres de las clases, por convenio, comienzan por may
uscula.
Cuerpo de una clase
El cuerpo de una clase contiene dos secciones:
1. Declaraci
on de sus variables.
2. Definici
on de sus metodos.
DeclaracionClase{
declaracionVariablesMiembro
...
declaracionMetodos
}
Declaraci
on de las variables miembro
Como mnimo, en la declaracion de una variable miembro aparecen dos componentes:
1. El tipo de dato de la variable.
2. Su nombre.
tipo variableNombre;
Declaraci
on de los metodos miembro
La implementacion de un metodo consta de dos partes: la declaracion y el cuerpo del mismo. En la
declaracion del metodo, ademas del nombre, va una cierta informacion, como:
El valor de retorno del metodo (el tipo de valor que devuelve).
El n
umero y tipo de argumentos requeridos por dicho metodo.
tipo metodo(argumentos){
...
}
Si un metodo no devuelve ning
un valor, debe declararse como void, y si devuelve un valor, debe utilizar
la sentencia return para devolverlo.

Clase Automovil
class Automovil{
String
Modelo;
int
Cilindrada;
float
Velocidad;
int
Marcha;
Automovil(String m,int c) {
super();

9
Modelo=m;
Cilindrada=c;
Velocidad=0;
Marcha=0;
}
void Acelera(float v) {
Velocidad=Velocidad+v;
}
void Frena(float v) {
Velocidad=Velocidad-v;
}
void Para() {
Marcha=0;
Velocidad=0;
}
void CambiaMarcha(int m) {
Marcha=m;
}
}

Creaci
on y Utilizaci
on de Objetos
En Java se crea un objeto sin mas que crear un ejemplar de una clase.
Pueden utilizarse clases definidas por el propio programador o las que se encuentran definidas en los
diferentes paquetes que incluye el entorno de desarrollo Java.
As, para crear un nuevo objeto de la clase String definida en el paquete java.lang se usa el comando
m
ultiple:
String str = new String(h,o,l,a);
Con esta declaracion se realizan tres acciones:
1. Declaraci
on: se declara una variable de tipo String cuyo nombre es str
2. Creaci
on del objeto: el operador new crea un nuevo objeto de tipo String
3. Iniciaci
on: String(h,o,l,a) inicia la cadena asignandole el contenido hola".
Constructor de una clase
Los constructores se reconocen porque tienen el mismo nombre que la clase y no tienen tipo de
retorno (o tipo void)
Siempre existe un costructor por defecto que no recibe argumentos.
Una clase puede tener varios constructores, pero todos ellos deben tener el mismo nombre (el de
la clase), y diferente n
umero o tipo de argumentos, para que el compilador pueda distinguirlos.
Los constructores solo pueden ser llamados con el operador new.

10
Por ejemplo, para crear un objeto de la clase Automovil llamado micoche,
Automovil micoche;
micoche= new Automovil(...,...);
Para acceder a las variables de un objeto, se concatenan los nombres del objeto y de la variable con
un punto. Por ejemplo, para acceder a la variable miembro modelo del objeto miCoche
miCoche.modelo
Para llamar a los metodos de un objeto, se concatena el nombre del objeto con el del metodo
mediante un punto, dando los argumentos del metodo entre parentesis, como en:
miChoche.cambiaMarcha(2);
Si el metodo no requiere argumentos, se utilizan los parentesis vacos.
miChoche.para();
Las llamadas a metodos tambien se conocen como mensajes.

Clase Punto
class Punto{
int x,y;
Punto(int x,int y){
this.x=x;
this.y=y;
}
double distancia(int x,int y){
int dx=this.x-x;
int dy=this.y-y;
return Math.sqrt(dx*dx+dy*dy);
}
double distancia(Punto p){
return distancia(p.x,p.y);
}
}
class DistanciaPuntos{
public static void main(String
args[]){
Punto p1=new Punto(0,0);
Punto p2=new Punto(30,40);
System.out.println("p1=("+p1.x+","+
p1.y+")");
System.out.println("p2=("+p2.x+","+
p2.y+")");
System.out.println("Distancia de

11
p1 a p2=",p1.distancia(p2));
System.out.println("Distancia de
p1 a (60,80)=",
p1.distancia(60,80));
}
}

Herencia
En programacion orientada a objetos se pueden definir clases (subclases) en terminos de otras clases
(superclases).
En Java, toda clase tiene una superclase. La superclase por defecto es la clase Object.
Para especificar la superclase se escribe la palabra extends y el nombre de la superclase a continuacion del nombre de la clase:
class SubClase extends SuperClase{...}
Toda subclase hereda el estado (en la forma de declaracion de variables) y los metodos de la superclase. Sin embargo, las subclases no estan limitadas al estado y comportamiento de su superclase, ya
que las subclases pueden:
A
nadir nuevas variables miembro.
nadir nuevos metodos a los heredados de la superclase.
A
Dar implementaciones particulares a los metodos heredados, anulando la definicion original de los
metodos, dada por la superclase, y sustituyendola por otra.

Clase Camion
class Camion extends Automovil {
float
PMA;
float
PesoCarga;
Camion(String m,int c,float p) {
super(m,c);
PesoCarga=p;
}
void Carga(float c) {
PesoCarga= PesoCarga+c;

void Descarga(float c) {
PesoCarga= PesoCarga-c;

void Para(){

12
super.Para();
PesoCarga=0; }
}

Declaraci
on de una Clase
En la declaracion de una clase se puede:
Declarar cual es su superclase.
Listar las interfases que implementa.
Declarar si es p
ublica, abstracta o final.
Implementar interfases
class Nombre extends SuperClase implements
Iterfase1,Interfase2...{...}
Una interfase declara un conjunto de metodos y constantes, sin especificar la implementacion para los
metodos. De forma que la clase que implementa dicha interfase debe implementarlos.
Clase p
ublica
public class Nombre ...{...}
Se pueden crear objetos de esa clase desde cualquier otra clase. Por defecto solo lo pueden hacer las
clases definidas en el mismo paquete.
Clase abstracta
abstract class Nombre ...{...}
No se pueden crear objetos de esas clases. Dentro de esta clase se pueden declarar metodos abstract
sin dar una implementacion de los mismos. Cualquier subclase debe dar una implementacion de dichos
metodos abstractos.
Clase final
final class Nombre ...{...}
No se pueden crear subclases suyas.
Por defecto una clase no es p
ublica, ni abstracta, ni final.
Se puede especificar que otros objetos pueden crear ejemplares de la clase:
private: ninguna clase puede crear objetos de esta.
protected: solo las subclases y las clases del mismo paquete pueden crear objetos de esta clase.
public: cualquier clase puede crear un ejemplar.

13
No especificado: solo clases del mismo paquete.

Ejemplo: Clase final


final class Punto{
int x,y;
Punto(int x,int y){
this.x=x;
this.y=y;
}
double distancia(int x,int y){
int dx=this.x-x;
int dy=this.y-y;
return Math.sqrt(dx*dx+dy*dy);
}
double distancia(Punto p){
return distancia(p.x,p.y);
}
}
final class Rectangulo{
Punto p1,p2;
int diagonal,ancho,alto;
Rectangulo(Punto p1,Punto p2){
this.p1=p1;
this.p2=p2;
}
Rectangulo(int ancho,int alto){
Punto p1Aux=new Punto(0,0);
Punto p2Aux=new Punto(ancho,alto);
this(p1Aux,p2Aux);
}
void calcula(){
Punto p1Aux=new Punto(p1.x,0);
Punto p2Aux=new Punto(p2.x,0);
Punto p3Aux=new Punto(0,p1.y);
Punto p4Aux=new Punto(0,p2.y);
diagonal=p1.distancia(p2);
ancho=p1Aux.distancia(p2Aux);
alto=p3Aux.distancia(p4Aux);
}
}
public class Principal{
public static void
main(String args[]){
Punto p1=new Punto(0,0);
Punto p2=new Punto(30,40);

14
Rectangulo r1;
r1=new Rectangulo(p1,p2);
System.out.println("distancia de
p1 a p2= "+p1.distancia(p2));
r1.calcula();
System.out.println("diagonal
del rectangulo "+ r1.diagonal);
System.out.println("ancho
del rectangulo "+ r1.ancho);
System.out.println("alto
del rectangulo "+ r1.alto);
}
}

Ejemplo: Clase final y privada


private final class Libro{
int paginas;
public Libro(int numPaginas){
paginas=numPaginas;
}
public void mensajePaginas(){
System.out.println("Numero de
paginas="+paginas);
}
}
class Diccionario extends
Libro{ //no permitido
int definiciones;
public Diccionario(int numPaginas,
int numDef){
super(numPaginas);
definiciones=numDef;
}
public void mensajeDef(){
System.out.println("Numero de
definiciones="+definiciones);
System.out.println("Numero de
paginas="+paginas);
}
}
public class PrincipalLibro{
public static void
main(String args[]){
Libro lib1;
lib1=new Libro(50);//no permitido
Diccionario dicc1;
dicc1=new Diccionario(60,1000);

15
lib1.mensajePaginas();
dicc1.mensajeDef();
}
}

Acceso a los Miembros de una Clase


Las clases pueden proteger sus metodos y variables miembro del acceso por otros objetos.
Por ejemplo: Dise
namos una clase que busca informacion en una base de datos que contiene informacion secreta. Cierta informacion, la disponible a traves de los metodos y variables p
ublicos de nuestra
clase, puede ser utilizada por cualquier otro objeto. Otro tipo de informacion puede estar disponible
solamente para uso personal de la clase. Las variables y metodos involucrados deberan estar protegidos.
Los niveles de acceso a las variables y metodos de una clase son:
public, protected, private
Acceso privado
Un miembro con este tipo de acceso es accesible solo en la clase en la cual esta definido.
Ejemplo:
class AClase{
private int privVar;
private void privMetodo(){
privVar=5;//permitido
System.out.println("La variable
privVar toma el valor="+privVar);
}
public void pubMetodo(){
privVar=15;//permitido
privMetodo();//permitido
}
}
class BClase{
void accMetodo(){
AClase a=new AClase();
a.privVar=10;//no permitido
a.privMetodo();//no permitido
a.pubMetodo();//permitido
}
}
Acceso protegido
En este nivel de acceso se permite a la propia clase, a sus subclases y a todas las clases que
esten en el mismo paquete, acceder a los miembros.

16
Ejemplo:
package Ejemplo;
class AClase {
protected int protVar;
protected void protMetodo(){
protVar=1; //permitido
}
}
class BClase{
void accMetodo(){
AClase ap=new AClase();
ap.protVar=2; //permitido
ap.protMetodo(); //permitido
System.out.println("var1="+
ap.protVar); }}
-----------import Ejemplo.*;
package EjemploPrueba;
class CClase extends AClase{
void metodo3(AClase a,
CClase d){
a.protVar=2;
d.protVar=2;
a.metodo1();
d.metodo1();
}
}

//no permitido
//permitido
//no permitido
//permitido

Acceso p
ublico
Cualquier clase en cualquier paquete tiene acceso a las variables y metodos p
ublicos de una
clase.
Ejemplo:
package Ejemplo;
class AClase {
public int protVar;
public void protMetodo(){
protVar=1; //permitido
}}
package EjemploPrueba;
class BClase{
void accMetodo(){
AClase ap=new AClase();
ap.protVar=2; //permitido

17
ap.protMetodo(); //permitido
System.out.println("var1="+
ap.protVar);
}
}
Acceso no especificado
Las clases definidas en el mismo paquete tiene acceso a las variables y metodos de una clase
cuyo acceso es no especificado.
Variables y metodos: final
El valor de una variable es constante si esta se declara final, un metodo no puede ser
redefinido si se declara final.

Miembros de Clase y de Instancia


Al declarar una variable miembro as:
class A{float var;}
tenemos una variable de instancia. Cada vez que se crea una instancia de una clase, el sistema crea
una copia de cada una de las variables de instancia de la clase. Se puede acceder a ellas solo desde un
objeto de la clase.
Las variables de clase se declaran as:
class A {static float var;}
Todos los ejemplares de la clase comparte la misma copia de las variables de clase. Se puede acceder a
ellas a traves de un ejemplar o a traves de la propia clase.
Retomando el ejemplo de los coches, si todos los coches tuvieran la misma cilindrada, definiremos
una variable de clase que contenga dicho valor. Todos los ejemplares comparten esta variable. Si uno
de ellos lo modifica, tambien cambia para los demas objetos de la clase.
Tambien tenemos metodos de instancia y metodos de clase. Los metodos de instancia tienen acceso
a las variables de instancia y de clase. Solo se puede acceder a ellos desde un objeto.
Los metodos de clase solo pueden operar con variables de clase. No pueden acceder a las variables
de instancia declaradas dentro de la clase. Hay que crear un nuevo objeto para acceder a ellas. Pueden
invocarse en la clase. No es necesario un ejemplar para llamarlos.
Ejemplo:
class Entero{
int x;
public int x(){
return x;
}
public void cambiarX(int nuevoX){
x=nuevoX;
}

18
}
class Principal{
public static void main(String
args[]){
Entero x1=new Entero();
Entero x2=new Entero();
x1.cambiarX(1);
x2.x=2;
System.out.println("x1.x="+x1.x());
System.out.println("x2.x="+x2.x());
}}
Salida: x1.x=1, x2.x=2
Ejemplo:
class Entero{
static int x;
public int x(){
return x;// permitido
}
public void cambiarX(int nuevoX){
x=nuevoX;
}
}
class Principal{
public static void main(String
args[]){
Entero x1=new Entero();
Entero x2=new Entero();
x1.cambiarX(1);
x2.x=2;
System.out.println("x1.x="+x1.x());
System.out.println("x2.x="+x2.x());
}
}
Salida: x1.x=2, x2.x=2
Ejemplo:
class Entero{
int x;
static public int x(){
return x;//no permitido
}
public void cambiarX(int nuevoX){
x=nuevoX;
}
}
class Principal{

19
public static void main(String
args[]){
Entero x1=new Entero();
Entero x2=new Entero();
x1.cambiarX(1);
x2.x=2;
System.out.println("x1.x="+x1.x());
System.out.println("x2.x="+x2.x());
}}
Salida: Error!!
Ejemplo:
class Entero{
static int x;
static public int x(){
return x;//permitido
}
public void cambiarX(int nuevoX){
x=nuevoX;
}
}
class Principal{
public static void main(String
args[]){
Entero x1=new Entero();
Entero x2=new Entero();
x1.cambiarX(1);
x2.x=2;
System.out.println("x1.x="+x1.x());
System.out.println("x2.x="+x2.x());
}}
Salida: x1.x=2, x2.x=2
Ejemplo:
class Entero{
static int x;
static public int x(){
return x;
}
static public void
cambiarX(int nuevoX){
x=nuevoX;
}
}
class Principal1{
public static void main(String
args[]){

20
Entero.cambiarX(1);
Entero.x=2;
System.out.println("El valor final
es "+ Entero.x());
}
}
Salida: El valor final es 2

Herencia
Una subclase hereda las variables y los metodos de su superclase y de todas sus antecesoras:
hereda los miembros declarados public o protected.
hereda los miembros declarados sin ning
un acceso si esta en el mismo paquete que su superclase.
no heredan un miembro si lo declaran con el mismo nombre que en la superclase. En este caso se
ocultan variables y se redefinen metodos.
Ejemplo:
class ASuper{
int var1;
void metodo(){
var=1;
}
}
class BSub extends ASuper{
int var;
void metodo(){
var=2;
super.metodo();
System.out.println(var);
System.out.println(super.var);
}
}

Clases y M
etodos Abstractos
Algunas veces necesitamos implementar un concepto abstracto.
Por ejemplo, podemos definir una aplicacion que dibuje crculos, rectangulos, etc. Todos estos objetos comparten un cierto estado (posicion, dimensiones) y un comportamiento (mover, redimensionar,
dibujar). Pero no es lo mismo dibujar un crculo que un rectangulo. Todos los objetos graficos deben
saber como dibujarse, pero difieren en la manera de hacerlo.
Declaramos una clase abstracta con variables y metodos que seran compartidos por todas las subclases. Y con metodos abstractos, que necesitan ser implementados por las subclases, pero de diferentes
maneras.
Ejemplo:

21
abstract class Figura{
int x,y;
.......
void mover(int nuevax,int nuevay){
...
}
abstract void dibujar();
}
class Circulo extends Figura{
void dibujar(){...}
}
class Rectangulo extends Figura{
void dibujar(){...}
}

Paquetes Definidos en Java


Las clases e interfases implementadas en Java estan agrupadas en diferentes paquetes. La Java
API (Java Application Programming Interface) es un conjunto de paquetes que pueden ser utilizados
por todo programa Java.
Paquete java.lang
Contiene clases que constituyen el n
ucleo del lenguaje Java.
Java lo importa automaticamente.
Paquete java.io
Permite la lectura y escritura de datos procedentes de diferentes fuentes.
Paquete java.applet
Permite la construccion de peque
nos programas o applets (clase Applet).
Paquete java.util
Posee clases que:
Tratan estructuras de datos genericas.
Tratamiento de bits.
Permiten el trabajo con fechas en diferentes formatos.
Manipulacion de cadenas de caracteres.
Generacion de n
umeros aleatorios.
Acceso a las propiedades del sistema.
Paquete java.net
til para construir applets que necesitan utilizar
Soporta todo lo relacionado con la red. Es u
los servicios de la red. Contiene la clase URL, sin la cual los applets no podrian cargar nada
de el servidor, lo cual significaria que no se podrian cargar ficheros con imagenes o sonido.

22
Paquete java.awt
Suministra la interfase de comunicacion con el usuario, que se llama (Abstract Window
Toolkit).
Paquete java.awt.event
Suministra las clases necesarias para controlar todos los sucesos que ocurren sobre la ventana
de nuestro applet o aplicacion.
Paquete java.awt.image
Paquete que sirve para tratar los datos de imagenes.
Paquete java.awt.peer
Conecta las componentes a sus correspondientes implementaciones independientes de la
plataforma.
Paquete java.awt.geom
En este paquete se encuentran clases y metodos para trabajar con objetos geometricos en
2D.
Paquete javax.swing
En este paquete se encuentran clases y metodos para crear una interfase de usuario. Este
paquete se puede considerar como una version actualizada del paquete java.awt, pues las
nuevas clases ofrecen mayores posibilidades que las que ofrece el paquete java.awt.
Paquete javax.swing.event
Suministra las clases necesarias para controlar todos los sucesos que ocurren sobre los componentes swing.
Paquete javax.swing.table
Suministra las clases e interfases necesarias para trabajar con objetos javax.swing.JTable.
Paquete javax.swing.text
Suministra las clases e interfases necesarias para trabajar con componentes de texto, editables
y no-editables.
Paquete javax.swing.border
Suministra las clases e interfases necesarias para dibujar bordes alrededor de las componentes
swing.
Como cargar un paquete:
Para importar una clase especfica de un paquete:

23
import paquete.nombreclase
Para importar todas las clases de un paquete:
import paquete.*
Por ejemplo, para cargar todas las clases del paquete java.awt:
import java.awt.*

Clase Lista
import java.io.*; import java.util.*;
public class Lista{
private long dni[];
int numero;
int maxnum;
public Lista(int longitud){
dni=new long[longitud];
maxnum=longitud;
numero=0;
System.out.println("Se crea la lista");
}
public boolean alta(long newdni){
if(numero<maxnum)
{
dni[numero]=newdni;
System.out.println("Se da de alta el DNI"+newdni);
numero++;
return(true);
}
else
return(false);
}

public void imprimir(){


System.out.println("Lista con "+numero+" clientes");
for(int i=0; i<numero; i++)
System.out.print(dni[i]+" ");
System.out.println("\n");
}

24

public boolean baja(long dnibaja){


int num;
if((num=buscar(dnibaja))>0)
{
System.out.println("Se da de baja el DNI "
+dnibaja);
for(int i=num; i<numero-1; i++)
dni[i]=dni[i+1];
dni[numero]=0;
numero--;
}
else
System.out.println("No existe el DNI "+
dnibaja+" en la lista");
return(true);
}
public int buscar(long dnibuscado){
int i=numero-1;
while(dni[i]!=dnibuscado && i>0)
{i--;}
return i;
}
public static void main(String args[]){
Lista L=new Lista(10);
L.alta(44443);
L.alta(34567);
L.alta(42039);
L.alta(20456);
L.imprimir();
L.baja(3333);
L.baja(34567);
L.imprimir();
}
}
/* SALIDA DE MSDOS:
Se crea la lista
Se da de alta el DNI 44443 Se da de alta el DNI 34567 Se da de
alta el DNI 42039 Se da de alta el DNI 20456
Lista con 4 clientes 44443

34567

42039

20456

No existe el DNI 3333 en la lista Se da de baja el DNI 34567

25

Lista con 3 clientes 44443

42039

20456

*/

Clase Complejo
import java.io.*;
import java.lang.*;
public class Complejo extends Object
double preal,pimag;
public Complejo(double partereal,double parteimag){
this.preal=partereal;this.pimag=parteimag;
}
public void opuesto(){
preal=-preal;
pimag=-pimag;
}
public void conjugado(){
pimag=-pimag;
}
public double modulo(){
return Math.pow(preal*preal+pimag*pimag,0.5);
}
public double argumento(){
if(preal==0.0 && pimag==0.0){
return 0.0;
}
else
return Math.atan(pimag/preal);
}
public void imprime(){
System.out.println("("+preal+","+pimag+")");
}
public void suma(Complejo c1,Complejo c2){
preal=c1.preal+c2.preal;pimag=c1.pimag+c2.pimag;
}

26

public void producto(Complejo c1,Complejo c2){


preal=c1.preal*c2.preal-c1.pimag*c2.pimag;
pimag=c1.preal*c2.pimag+c1.pimag*c2.preal;
}
public void cociente(Complejo c1,Complejo c2) throws
ZerodivisorException{ double aux;
if(c2.preal==0.0 && c2.pimag==0.0){
throw new ZerodivisorException("Divide por cero");
}
else{
aux=c2.preal*c2.preal+c2.pimag*c2.pimag;
preal=(c1.preal*c2.preal+c1.pimag*c2.pimag)/aux;
pimag=(c1.pimag*c2.preal-c1.preal*c2.pimag)/aux;
}
}
}
class ZerodivisorException extends Exception{
ZerodivisorException(){super();}
ZerodivisorException(String s){super(s);}
}

Prueba de la Clase Complejo


El modulo del complejo es:
|(preal, pimag)| = (preal2 + pimag 2 )1/2
La suma, el producto y el cociente de complejos son:
(a, b) + (c, d) = (a + c, b + d)
(a, b) (c, d) = (ac bd, ad + bc)

(a, b)/(c, d) = (

ac + bd ad bc
,
).
c2 + d2 c2 + d2

Salida del Programa


(1,2)
(3,4)
(-3,-4)
(-3,4)

(-2,6)
El modulo de la suma es = 6.32456
El argumento de la suma es = -1.24905 radianes
(-14,-22)
El argumento de c2 es = 0 radianes
Al calcular el cociente se ha producido una excepcion
class ZerodivisorException
con el mensaje: Divide por cero

Programa de Prueba
import java.io.*;
import java.applet.*;
//import Complejo;
public class PComplejo extends Applet{
public void init() {
Complejo c1,c2,c3;
c1=new Complejo(1.0,2.0);c2=new Complejo(3.0,4.0);
c3=new Complejo(0.0,0.0);c1.imprime();
c2.imprime();c3=c2;c3.opuesto();c3.imprime();
c3.conjugado();c3.imprime();
c3.suma(c1,c2);c3.imprime();
System.out.println("El modulo de la suma es = "
+ c3.modulo());
System.out.println("El argumento de la suma es = "
+ c3.argumento() + " radianes");
c3.producto(c1,c2);c3.imprime();
c2.preal=0.0;c2.pimag=0.0;
System.out.println("El argumento de c2 es = "
+ c2.argumento() + " radianes");
try{ c3.cociente(c1,c2);
System.out.println("El cociente es: ");
c3.imprime();
}catch (ZerodivisorException e){
System.out.println("Al calcular el cociente se ha
producido una excepcion " + e.getClass()
+ "\ncon el mensaje: " + e.getMessage());
}
}
}

28

ENTORNO JDK

29

Creaci
on de Applets y Aplicaciones

PROGRAM A
JAVA

MiPrograma.java

COMPILA DOR

INTRPR ETE
MiPrograma.class

0010110100

MI
PROGRAMA

Creaci
on de aplicaciones
Las aplicaciones son programas autonomos que no necesitan de un navegador para ejecutarse.
on del codigo fuente
1. Creaci
Debe utilizarse alg
un editor de texto (SimpleText, Edit, Word,...).
Ejemplo 1:
public class MiAplicacion {
public static void main(String argv[]) {
System.out.println("SOY UNA APLICACION");
}
}

30
El formato del fichero fuente debe ser solo texto.
El nombre de dicho fichero debe ser el mismo que el de la clase con el metodo main() pero con la
terminacion .java.
2. Compilaci
on del codigo fuente
La compilacion se puede efectuar directamente con un editor de Java (Kawa, JCreator, etc.),
utilizando la opcion Compile del men
u Build. La compilacion tambien se puede efectuar desde
el DOS, mediante un comando de la forma:
javac MiAplicacion.java
En caso de estar en un directorio diferente al que contiene el codigo fuente debe indicarse el camino
(path) completo para llegar a el.
Esto tambien puede resolverse a
nadiendo a la variable Path, el camino donde se halla el compilador. Para ello basta con escribir en el fichero autoexec.bat,
SET PATH=C:\Archivos de programa\Java\jdk1.5.0_07\bin\;
3 Ejecuci
on de la aplicaci
on La ejecucion se puede hacer con un editor de Java (Kawa, JCreator,
etc.), en particular, utilizando la opcion Run del men
u Build. Tambien se puede hacer desde el
DOS, para ello se utiliza el fichero .class asociado a la clase que tiene el metodo main()
La orden debe darse desde el DOS:
java MiAplicacion
Para poder ejecutar una aplicacion, el directorio actual debe ser el que contiene el codigo objeto
(el fichero MiAplicacion.class).
Aplicaciones que reciben argumentos
Ejemplo 2:
public class MiNombre {
public static void main(String argv[]) {
System.out.println("BIENVENIDO "+ argv[0]);
}
}
Los argumentos se pasan desde la lnea de comandos del DOS, al mismo tiempo que se ordena la
ejecucion de la aplicacion:
java MiNombre "Pepe P
erez"
Creaci
on de applets

31
on del codigo fuente
1. Creaci
Ejemplo:
import java.applet.Applet;
public class MiApplet extends Applet{
public void init() {
System.out.println("SOY UN
APPLET");
}
}
El nombre del fichero con el codigo fuente debe ser el mismo que el de la subclase de la clase
Applet pero con la terminacion .java.
2. Compilaci
on del codigo fuente: Similar al caso de las aplicaciones.
Se generan tantos ficheros .class como clases definidas en el fichero fuente.
on en un documento HTML
3 Integraci
Se utiliza el comando <APPLET> del HTML.
Ejemplo (Fichero "Ejemplo.html"):
<HTML>
Esta p&aacute;gina incluye un applet:
<HR>
<APPLET CODE=MiApplet.class
HEIGHT=50
WIDTH=300>
</APPLET>
<HR>
<A HREF="MiApplet.java">
CODIGO FUENTE
</A>
</HTML>
El parametro CODE toma como valor el fichero generado por el compilador correspondiente a la
subclase de la clase Applet.
4 Ejecuci
on del applet
Existen dos alternativas:
(a) Utilizar un navegador compatible con Java (p.e. Netscape, InternetExplorer).
Abrir con el navegador el documento HTML que integra el applet.

32
(b) Utilizar la herramienta de visualizacion de applets del JDK.
En particular, si se utiliza un editor de Java (Kawa, JCreator, etc.), basta con seleccionar el
fichero.html y llamar al comando Run del men
u Build.
La orden que debe darse desde el DOS:
appletviewer Ejemplo.html

Ejemplo aplicaci
on
PrimeraAplicacion.java

public class PrimeraAplicacion{


public static void main(String args[]){
if(args.length>0)
System.out.println("`
AComo estas, "+args[0]+"?");
else
System.out.println("Hola");
}
}
}

Ejemplo applet
MiPrimerApplet.java

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


public class MiPrimerApplet extends Applet{
public void init(){
repaint();
}
public void paint(Graphics g){
g.drawRect(0,0,200,50);
g.drawRect(5,5,190,40);
g.drawString("Bienvenidos a este curso !",30,30);
}
}

33
MiPrimerApplet.html
<title> Mi primer applet </title>
<hr>
<applet code=MiPrimerApplet.class width=200 height=200>
</applet>
<hr>
<a href="MiPrimerApplet.java"> CODIGO FUENTE.</a>

EJEMPLO
import java.awt.*;
public class EjemploAplicacion
extends Frame{
Button boton;
public EjemploAplicacion(){
boton=new Button("OK");
add("South",boton);
}
public static void main(String[] args){
EjemploAplicacion ejem=
new EjemploAplicacion();
ejem.resize(100,100);
ejem.show();
}
}

EL LENGUAJE JAVA

35

Variables
Las variables son zonas o espacios de memoria en las que se almacena la informacion. Son los pilares
de la programacion y los elementos sobre los que se act
ua. Es necesario especificar su nombre y su tipo.
el nombre sirve para saber a que zona de memoria se esta uno refiriendo.
el tipo sirve para saber el tama
no de la memoria necesario para almacenarla y como debe interpretarse la informacion. La informacion se almacena en binario, es decir, en forma de bits (ceros
y unos), por lo que hay que transformarla tanto para almacenarla como para interpretarla.
Toda variable y toda expresion tienen un tipo. Esto limita los valores que pueden tomar las variables
y producir las expresiones, limita las operaciones que pueden realizarse con las variables y expresiones
y determina el significado de las operaciones que las afectan.
Al declarar una variable, debe especificarse su tipo y su nombre.
int a,b;
String nombre,domicilio;
long d;
boolean f;

Nombre de una Variable


Debe cumplir las condiciones siguientes:
1. Debe comenzar siempre con una letra (may
uscula o min
uscula) o con un signo de subrayado (_).
2. El resto del nombre puede estar formado por combinaciones de letras, n
umeros y signos de subrayado. Por ejemplo miEdad, Edad_1,A1
3. No debe incluir espacios ni caracteres como & y *.
4. Debe ser un identificador legal de Java formado por una serie de caracteres unificados (Unicode).
5. No debe coincidir con una palabra clave ni con true o false.
6. Tampoco debe coincidir con el nombre de otra variable declarada en su mismo campo de accion,
pudiendo hacerlo con variables declaradas en diferente campo.

Tipos de Datos
Hay tres tipos de variables o expresiones:

B
asicas: contienen la informacion propiamente dicha. Estas
pueden ser:
Numericas: a su vez pueden ser:

36
Enteras: byte, short, int, long, que toman valores enteros.
Coma flotante: float (simple precision), double (doble precision), que toman valores
reales.
Booleanas: boolean, que toman los valores logicos true y false.
Tipo caracter: char, que toman solo valores de tipo caracter.
Referenciales: no contienen la informacion, sino donde se encuentra esta, es decir, son referencias
a objetos. Estas pueden ser:
Tipo clase: class, que contienen referencias a clases.
Tipo interfase: interface, que contienen referencias a una interfase.
Tipo matriz: array, que contienen referencias a una matriz.
Tipo nulo: es un tipo especial que no tiene nombre. La referencia nula null es el u
nico valor que
puede tomar una expresion de este tipo.
Tipo
byte
short
int
long
float
double
boolean
char

Tama
no
8 bits
16 bits
32 bits
64 bits
32 bits
64 bits
N/A
16 bits

Mnimo
M
aximo
256
255
32768
32767
2147483648
2147483647
9223372036854775808 922337203685477580
224 E 149
224 E104
253 E 1045
253 E1000
false
true
Caracter Unicode

Table 1: Tipos de datos o variables basicas.


Observaciones:
El tipo double tiene mas precision y puede almacenar mas cifras decimales.
En la mayora de los ordenadores, los enteros se procesan mucho mas rapido que los n
umeros
almacenados en coma flotante.
Los n
umeros en coma flotante pueden almacenar valores mas grandes y mas peque
nos que los
enteros.

Campo de Acci
on de una Variable
Se denomina campo de acci
on de una variable al bloque de codigo en el que dicha variable es accesible.
Ademas, este campo determina cuando la variable se crea y se destruye.
Atendiendo al campo de accion, se pueden clasificar las variables en las clases siguientes:
Variable de clase. Se declara dentro de la definicion de una clase o interfase, usando la palabra
clave static. Estas variables son creadas e iniciadas, a valores determinados o por defecto, al
construirse la clase, dejando de existir cuando desaparece dicha clase y tras completar el proceso
previo a la destruccion del objeto.

37
Variables miembro de una clase. Se declaran en la definicion de una clase sin usar la palabra clave
static. Si a es una variable miembro de una clase A, cada vez que se construye un nuevo objeto
de la clase A o una subclase de A se crea una nueva variable a y se inicia dandole un valor concreto
o por defecto. La variable deja de existir cuando desaparece la clase a la que pertenece y tras
completar el proceso previo a la des truccion del objeto.
Componentes de una matriz. Son variables sin nombre que se crean e inician a valores concretos
o por defecto cuando se crea un objeto nuevo de tipo matriz. Las componentes de la matriz dejan
de existir cuando desaparece la misma.
Variable local. Se declara dentro de un bloque de codigo y solo es accesible dentro del mismo. Las
variables locales no se inician hasta que se ejecuta la sentencia de declaracion correspondiente.
Las variables locales dejan de existir cuando se termina el bloque en el que estan declaradas.
Par
ametro de un metodo o constructor. Es el argumento formal de un metodo o un constructor,
mediante el cual se pasan valores al mismo. Cada vez que se invoca el metodo se crea una variable
con ese nombre y se le asigna el valor que tena la correspondiente variable en el metodo que la
llama. Su campo de accion es el metodo o constructor del cual es argumento.
Par
ametro de un manipulador de excepciones. Es el argumento de un manipulador de excepciones.

Iniciaci
on de Variables
Al declarar las variables locales, las de clase y las que son miembros de clases pueden darse valores
iniciales. Por ejemplo:
int edad=30;
double estatura=1.78;
boolean Terminado=true;
Ademas de reservar espacio en memoria para ellas, se almacenan los valores indicados.
Los parametros de los metodos y los de los manipuladores de excepciones no pueden iniciarse de
este modo. El valor de estos parametros es fijado por el metodo que los llama.
Constantes
Las constantes en Java son como las variables, pero su valor no se altera durante la ejecucion del programa. Se las precede del adjetivo final. Por convenio, las constantes se escriben todas en may
usculas.
Por ejemplo:
final double PI=3.14159265358979;
final double E=2.71728182;

38

Comentarios
Existen tres clases de comentarios:
/* texto */. El texto comprendido entre /* y */ es ignorado por el compilador. Se utiliza para
comentarios de mas de una lnea.
// texto. El texto desde // hasta el final de lnea es ignorado. Se utiliza para comentarios de
una sola lnea.
/** documentaci
on */. El texto comprendido entre /** y */ puede ser procesado por otra
herramienta para preparar documentacion de la siguiente
declaracion de clase, constructor, interfase, metodo o campo.

Operadores
Existen operadores unarios y binarios que requieren uno o dos operandos, respectivamente.
Los operadores unarios pueden aparecer antes o despues del operando, aunque, en ese caso, la accion
que realizan puede ser diferente.
x++;
++y;
Los operadores binarios siempre aparecen entre los dos operandos:
5*6;
a+b;
Todo operador devuelve siempre un valor. Dicho valor y su tipo dependen del operador y del tipo
de los operandos.
Los operadores pueden clasificarse en las siguientes
categoras:
aritmeticos
relacionales y condicionales
bit-a-bit y l
ogicos
de asignacion

Operadores Aritm
eticos
Los operadores aritmeticos binarios, salvo el operador %, que solo act
ua con enteros, manejan indistintamente los tipos enteros y los de coma flotante.
Cuando un operador tiene operandos de diferente tipo, estos se convierten a un tipo com
un siguiendo
las reglas:
la categora de los tipos, de mayor a menor, es la siguiente: double, float, long, int,
short,char.

39

Operador
+
*
/
%

Operadores Binarios
Operaci
on Descripci
on
a + b
Adicion
a - b
Diferencia
a * b
Producto
a / b
Division
a % b
resto de dividir a entre b
Table 2: Operadores Binarios.

en cualquier operacion en la que aparezcan operandos de tipos diferentes, se eleva la categora del
que la tenga menor.
en una sentencia de asignacion, el resultado final se convierte al tipo de la variable a la que son
asignados.

Operador
+y++
--

Operadores Unarios
Operaci
on Descripci
on
Fijan el signo del operando
+a y -a
++x
Suma 1 a x antes de usarla
x++
Suma 1 a x despues de usarla
--x
Resta 1 a x antes de usarla
x-Resta 1 a x despues de usarla
Table 3: Lista de operadores unarios

Ejemplos:
int i=7;
4 * i++;
i+2;
Las dos u
ltimas sentencias dan como resultado 4*7=28 y 8+2=10.
int i=7;
4 * ++i;
i+2;
En este caso los resultados son 4*8=32 y 8+2=10.

Operadores Relacionales y Condicionales


Los operadores relacionales comparan dos valores y determinan la relacion que existe entre ellos.
Los operadores condicionales se utilizan para efectuar operaciones de tipo logico.

40

Operador
>
>=
<
<=
==
!=

Operadores Relacionales
Empleo Descripci
on
true si a es mayor que b,
a > b
false en caso contrario.
true si a es mayor o igual que b,
a >= b
false en caso contrario.
true si a es menor que b,
a < b
false en caso contrario.
true si a es menor o igual que b,
a <= b
false en caso contrario.
true si a y b son iguales,
a == b
false en caso contrario.
true si a y b son diferentes,
a != b
false en caso contrario.

Table 4: Lista de operadores relacionales.

Operadores Condicionales
Operador Empleo Descripci
on
true si a y b son true,
&&
a && b
false en caso contrario.
false si a y b son false,
||
a || b
true en caso contrario.
false si a es true y
!
!a
true si a es false
Table 5: Lista de operadores condicionales.

Operadores de Asignaci
on
El operador = asigna a la variable de la izquierda el valor que toma la expresion de la derecha:
float i = 3.5;
Ademas:
n = n*5;

41
Operadores de Asignaci
on
Operador Empleo Descripci
on
+=
a += b
a = a + b
-=
a -= b
a = a - b
*=
a *= b
a = a * b
/=
a /= b
a = a / b
%=
a %= b
a = a % b
&=
a &= b
a = a & b
|=
a |= b
a = a | b
^=
a ^= b
a = a ^ b
<<=
a <<= b
a = a << b
>>=
a >>= b
a = a >> b
>>>=
a >>>= b a = a >>> b
Table 6: Lista de operadores de asignacion.

es equivalente a:
n *= 5;

El operador cast
A veces se necesita almacenar valores de un tipo en variables de tipo diferente. Como Java no
permite almacenar a cada variable mas que valores de su tipo, es necesario transformarlos previamente.
Para ello, se recurre al operador cast, que transforma un tipo de dato en otro compatible, tal como
se ve en el siguiente ejemplo:
float a;
int b;
b = (int) a;

Matrices
Considerense los 100 primeros m
ultiplos de 2. Estos podran almacenarse as:
int
int
int
...
int

m1 = 2;
m2 = 4;
m3 = 6;
m100 = 200;

Para ello, se dispone de las matrices (arrays), cuya declaracion se hace como sigue:

42
int mult[];
mult = new int[100];
En la primera sentencia se especifica el tipo de los elementos de la matriz (int en este caso) y se
da un nombre a la matriz, seguido de un doble corchete [], el cual indica al compilador que lo que se
declara es una matriz.
Pero la declaracion int mult[]; no asigna memoria para almacenar los elementos de la matriz, de
manera que si se intenta acceder a alguno de ellos o asignarle un valor, el compilador dara un mensaje
de error. Para evitar esto y asignar la memoria necesaria se recurre al operador new.
A partir de ese instante ya se pueden dar valores a todos los elementos de la matriz:
public class Multiplo{
public static void
main(String args[]){
int mult[];
mult=new int[100];
for(int i=0;i<mult.length;i++){
mult[i]=2*(i+1);
System.out.println(mult[i]);
}
}
}
Ejemplo:
public class ArrayExample{
public static void
main(String args[]){
int smallPrimes[]={2,3,5,7,11,13};
int bigInts[]={1001,1002,1003,1004,
1005,1006,1007};
System.arraycopy(smallPrimes,2,
bigInts,3,4);
for(int i=0;i<bigInts.length;i++){
System.out.println(i +" despues
de la copia es "+bigInts[i]);
}
}
}

Cadenas de Caracteres
Se denomina cadena de caracteres a una secuencia o conjunto ordenado de ellos. Toda cadena de
caracteres se implementa mediante la clase String.
String a[] = new String[20];
Otra forma:

43
"Hola"
Tambien se pueden unir dos cadenas de caracteres mediante el operador de concatenacion +. Por
ejemplo:
"La ecuacion tiene " +

n + " soluciones."

Expresiones
Toda expresi
on es una combinacion de variables, operadores y llamadas a metodos, que calculen un
valor.
Las expresiones se utilizan para calcular y asignar valores a variables y para controlar la ejecucion
de un programa. Realizan las operaciones indicadas por sus elementos y devuelven alg
un valor.
Existen dos tipos de expresiones:
Numericas: que toman valores numericos.
Booleanas: que solo toman los valores true o false.
Expresiones Numericas
Cualquier variable que represente un n
umero es una expresion numerica.
int i
i+10
--n;
Toda asignacion es tambien una expresion:
a = 100
b* = 2
Expresiones Booleanas
Solo poseen los valores true o false.
n != m
a < b
En una expresion es importante el orden en que se aplican los operadores. No es lo mismo
5 * 3 + 4
que
5 * (3 + 4)

44
. [] ()
++ -- ! ~ instanceof
new (type)
* / %
+ << >> >>>
< >
== !=
&
^
|
&&
||
? :
= += -= *= /= %= ^=
&= |= <<= >>= >>>=
Table 7: Orden de preferencia de los operadores.

Sentencias y Bloques
Un programa no es mas que un conjunto de sentencias ordenadas. Una sentencia es una instruccion
completa para el compilador, que acaba en un punto y coma.
Una expresion como a = 100 o a < b se convierte en una sentencia cuando va seguida de un punto
y coma:
a = 100;
a < b;
Una sentencia indica una accion. La expresion
2+2;
indica al compilador que realice esa operacion pero no lo que debe hacer con el resultado. Por el
contrario, la sentencia
a = 2+2;
ordena al compilador que almacene el resultado en la variable a.
Veamos cuatro clases de sentencias:
Sentencias de declaraci
on: establecen los nombres y el tipo de variables.
Sentencias de asignacion: asignan valores a las variables.
Sentencias de funcion: llaman a funciones para realizar una determinada tarea.
Sentencias estructuradas o de control de flujo: while, if-else, switch, etc., que se analizan en
la seccion siguiente.

45
Un bloque es un conjunto de dos o mas sentencias agrupadas y encerradas entre llaves, no existiendo
punto y coma tras la llave de cierre. Por ejemplo, el programa que sigue contiene un bloque.
for(i=0;i<100;i++) {
mult[i] = 2*(i+1);
System.out.println("Elemento i"+mult[i]);
}

Control de Flujo
Puede determinarse el orden de ejecucion de las sentencias seg
un convenga. Para ello nos servimos
de las sentencias estructuradas o de control de flujo.
Sentencia if-else
Se define primero la sentencia if, que tiene el formato:
if(expresion)
{sentencias}
Si expresion es true, se ejecuta {sentencias}, si es false, no se ejecuta {sentencias}.
Una alternativa mas potente es la sentencia if-else:
if(expresion)
{sentencias1}
else
{sentencias2}
Si expresion es true, se ejecuta {sentencias1}; en caso contrario, se pasa a ejecutar {sentencias2}.
Ejemplo:
public boolean retirar(double cantidad){
boolean resultado=false;
System.out.println("Retirar de cuenta "+ cuenta);
System.out.println("Cantidad: "+ cantidad);
if(cantidad>saldo)
System.out.println("No hay fondos");
else{
saldo-=cantidad;
System.out.println("Nuevo saldo: "+saldo);
resultado=true;
}
return resultado;
}
Sentencia else-if
La sentencia else-if ampla el n
umero de opciones.

46

Expresin booleana
if( cantidad >saldo )

Bloque then

System.out.println("No hay fondos");


else
{
saldo-=cantidad;
System.out.println("Nuevo saldo: "+saldo);
resultado=true;
}
Bloque else
if(expresion1)
{sentencias1}
else if(expresion2)
{sentencias2}
...
else
{sentenciasN}
Las expresiones se eval
uan en orden; si alguna es cierta, se ejecuta la sentencia o bloque asociado a ella,
y se concluye la ejecucion de la sentencia else-if. Solo se ejecuta el u
ltimo else en el caso de que
todas las expresiones sean falsas.
Pudiera ocurrir que fueran ciertas dos o mas expresiones. En este caso, se ejecutaran solo las
sentencias correspondientes a la primera de ellas y se saldra del bloque else-if.
Ejemplo:
public boolean retirar(double cantidad){
boolean resultado=false;
System.out.println("Retirar de cuenta "+ cuenta);
System.out.println("Cantidad: "+ cantidad);
if(cantidad==0.0)
System.out.println("Introduzca otra cantidad");
else if (cantidad>saldo)
System.out.println("No hay fondos");
else{
saldo-=cantidad;
System.out.println("Nuevo saldo: "+saldo);
resultado=true;
}
return resultado;
}

47
Ejercicio: Escribir un applet o aplicacion que escriba en la salida estandar si un a
no es bisiesto o no
lo es, dado un a
no cualquiera.
Nota: Una a
no es bisiesto si es divisible por 4 pero no por 100. Un a
no que es divisible por 4 y 100
es bisiesto si es tambien divisible por 400.
class Bisiesto{
public static void main(String args[]){
int anio=Integer.parseInt(args[0]);
if((anio%4==0)&&(anio%100!=0))
System.out.println("El anio " + anio+" es bisiesto");
else if((anio%4==0)&&(anio%100==0)&&(anio%400==0))
System.out.println("El anio " + anio+" es bisiesto");
else
System.out.println("El anio " + anio+" no es bisiesto");
}}
Sentencia switch
Se dispone de varias opciones derivadas de la evaluacion de una u
nica expresion. La sintaxis es la
siguiente:
switch(expresion) {
case {expresion1_constante1}:
{sentencias1}
case {expresion2_constante2}:
{sentencias2}
...
case {expresionN_constanteN}:
{sentenciasN}
default {sentencias}
Cada case lleva una o mas constantes enteras o expresiones constantes enteras. Si un case coincide
con el valor de expresion, la ejecucion comienza ah. Todas las expresiones de los case deben ser
diferentes. Si ninguna de ellas coincide con expresion, se ejecutan las sentencias correspondientes a
default. El default es optativo; si no esta y ninguno de los casos coincide, no se ejecuta ninguna
accion.
Ejemplo:
class Califica{
static void calificacion(int nota){
switch (nota){
case 3:
System.out.println("S"); break;
case 5:
System.out.println("A"); break;
case 7:
System.out.println("N"); break;
case 9:

48

Expresin Aritmtica
char, byte, short, int
switch (

nota

){

expresion1_constante1

case 3 :
System.out.println("S"); break;

expresion2_constante2

case 5 :
System.out.println("A"); break;

expresion3_constante3

case 7 :
System.out.println("N"); break;

expresion4_constante4

case 9 :
System.out.println("SB"); break;
default: System.out.println("Ser
calificado posteriormente");
}

System.out.println("SB"); break;
default: System.out.println("Sera
calificado posteriormente");
}
}
public static void
main(String args[]){
calificacion(5);
calificacion(8);
}
}
Ejercicio: Escribir una aplicacion que devuelva el n
umero de das de cada mes en un a
no cualquiera.
public class Calendario{
public static void
main(String args[]){
int mes=1;
int a=2000;
int numDias=0;
switch(mes){
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
numDias=31;

49

Expresin booleana
while ( numero<=100 ) {
sum=sum+numero;
numero=numero+1;
}

Cuerpo del bucle

break;
4:
6:
9:
11:
numDias=30;
break;
case 2:
if(((a%4==0) && !(a%100==0))||
(a%400==0))
numDias=29;
else
numDias=28;
break;
case
case
case
case

}
System.out.println("Numero de
dias= "+numDias);
}
}
Ciclo while
while(expresion)
{sentencias}
Se ejecuta el bloque {sentencias} mientras el valor de la expresion es true. El ciclo se repite hasta
que el valor de expresion toma el valor false. Entonces, el compilador sale del ciclo.
Ejemplo: Supongamos que queremos sumar los primeros 100 n
umeros enteros.
int sum=0; numero=1;
while(numero<=100){
sum=sum+numero;
numero=numero+1;
}
Ejemplo:

50
class Bisiesto1{
public static void
main(String args[]){
char ans;
System.out.println("Quiere
introducir anio?? (y/n)");
ans=SavitchIn.readLineNonwhiteChar();
while((ans==y) || (ans==Y) ){
System.out.println("Introduzca
un anio");
int anio=SavitchIn.readLineInt();
if((anio%4==0)&&(anio%100!=0))
System.out.println("El anio " +
anio+" es bisiesto");
else if((anio%4==0)&&(anio%100==0)
&& (anio%400==0))
System.out.println("El anio " +
anio+" es bisiesto");
else
System.out.println("El anio " +
anio+" no es bisiesto");
Ejercicio: Calcular el producto de los primeros 20 n
umeros impares.
class Pares{
public static void
main(String args[]){
int producto=1, numero=1;
int limite=20, ultimoNumero;
ultimoNumero=2*limite+1;
while(numero<=ultimoNumero){
producto=producto*numero;
numero=numero+2;
}
System.out.println("Resultado="+
producto);
}
}
Ciclo do-while
do{
sentencias
}while({expresion});

51
Mientras en los ciclos while y for, las condiciones de termino se eval
uan al principio de cada iteracion,
en el ciclo do-while se comprueban al final, despues de cada repeticion del ciclo, por lo que el bloque
{sentencias} se ejecuta siempre, al menos una vez.
As, primero se ejecutan las sentencias del bloque sentencias y despues se eval
ua expresion.
Si es verdadera, se vuelve a ejecutar el bloque sentencias, y as sucesivamente.
Cuando expresion toma el valor false se acaba el ciclo.
El bloque while:
int a = 1;
while ( a != 15 ) {
a = a + 1;
}
equivale al bloque con do-while:
int a = 1;
do {
a = a + 1;
} while (a != 14);
Ciclo for
Act
ua hasta un cierto lmite impuesto por el programador. Su sintaxis es la siguiente:
for(iniciacion;limite;incremento)
{sentencias}
El ciclo for es equivalente a:
iniciacion
while(limite) {
{sentencias}
incremento
}
iniciacion e incremento suelen ser asignaciones o llamadas a una funcion, que en el caso de ser
mas de una, se separan por comas, y limite, una expresion relacional.
La expresion iniciacion se ejecuta al comienzo del bucle.
La expresion limite indica cuando se ejecuta el bucle y se eval
ua al comienzo de cada iteracion,
de manera que cuando su valor es true se ejecuta el bloque {sentencia} y si es false, el ciclo
for concluye.
Las sentencias del bloque sentencias se ejecutan en cada ciclo.
Las sentencias del bloque incremento se ejecutan al final de cada iteracion o ciclo.
El ciclo for es frecuente en la iniciacion de los elementos de un matriz:
int mult[];
mult = new int[100];
for(int i=0;i<100;i++) {
mult[i] = 2*(i+1);
}

52

Definiciones Recursivas
Factorial de un n
umero (Forma 1)
public class Factorial {
public static long factorial(long x){
if(x==1) return 1;
else return x*factorial(x-1);
}
public static void
main(String args[]) {
Long argumento=new Long(args[0]);
long n=argumento.longValue();
System.out.println(factorial(n));
}
}
Factorial de un n
umero (Forma 2)
import java.math.*;
public class Factorial1 {
public static BigInteger
factorial(long x){
BigInteger fact;
fact= BigInteger.valueOf(x);
if(fact== BigInteger.valueOf(1))
return BigInteger.valueOf(1);
else
return fact.multiply(factorial(x-1));
}
public static void
main(String args[]) {
Long argumento=new Long(args[0]);
long n=argumento.longValue();
System.out.println(
factorial(n).toString());
}
}

Sentencias de Bifurcaci
on
Permiten alterar el flujo de ejecucion normal del programa. Por ejemplo, la sentencia break en un
ciclo obliga al programa a abandonar el ciclo y continuar con la ejecucion de las sentencias que siguen.
La sentencia continue se usa dentro de un ciclo para iniciar la siguiente iteracion del ciclo que la
contiene. De esta manera se evita ejecutar las sentencias del ciclo siguientes a continue. Por ejemplo,
con las sentencias:

53
for (i = 0; i < n; i++) {
if(a[i] < 0)
continue;
}
se ignoran los valores negativos de la matriz a.
La sentencia return finaliza la ejecucion de la funcion que la contiene y devuelve el control a la
sentencia siguiente de la funcion de llamada. Ademas, puede devolver un valor. En este u
ltimo caso, la
sintaxis es: return expresion;

Algoritmo de la Bisecci
on para la B
usqueda de un N
umero en
una Matriz Ordenada de Enteros
import java.applet.Applet;
public class BusquedaBinaria extends Applet{
public static int Buscar(int x[], int n) {
int e1=0;
int e2=x.length-1;
int centro;
if(x[e1]==n)
return(e1);
else if (x[e2]==n)
return(e2);
while (e1<e2)
{
centro=(e1+e2)/2;
if(centro==e1)
return(-1);
else if(x[centro]==n)
return(centro);
else if (x[centro]<n)
e1=centro;
else
e2=centro;
}
return(-1); }
public void init() {
int datos[]={1,4,6,9,11,16,21,23,29,30};
System.out.println(1+" --> "+
Buscar(datos,1));
System.out.println(16+" --> "+
Buscar(datos,16));
System.out.println(29+" --> "+
Buscar(datos,29));
System.out.println(30+" --> "+

54
Buscar(datos,30));
System.out.println(2+" --> "+
Buscar(datos,2));
System.out.println(18+" --> "+
Buscar(datos,18));
System.out.println(22+" --> "+
Buscar(datos,22));
System.out.println(28+" --> "+
Buscar(datos,28));
}
}

Conjetura de Collatz
public class Collatz {
public static int F(int x) {
if(x%2==1)
return (3*x+1)/2;
else
return x/2;
}
public static void main(String args[]) {
int n, i=1;
Integer argumento=new Integer(args[0]);
n=argumento.intValue();
while(n!=1) {
System.out.println( "Iter. " + i +
":" + n );
i++;
n=F(n);
}
System.out.println("SE ALCANZA EL 1
TRAS "+ i +" ITERACIONES");
}
}
Por ejemplo, haciendo la llamada al metodo main() de la clase Collatz al mismo tiempo que se
pasa el valor inicial n = 56, se obtiene un resultado como el que se muestra a continuacion:
Iter.
Iter.
Iter.
Iter.
Iter.
Iter.

1:56
2:28
3:14
4:7
5:11
6:17

55
Iter. 7:26
Iter. 8:13
Iter. 9:20
Iter. 10:10
Iter. 11:5
Iter. 12:8
Iter. 13:4
Iter. 14:2
SE ALCANZA EL 1 TRAS 15 ITERACIONES

Programa que Reconoce si un N


umero es Primo
public class Primo {
public static void main(String args[]) {
int n, i=2;
long m;
boolean fin=false;
Integer argumento=new Integer(args[0]);
n=argumento.intValue();
m = Math.round(Math.sqrt(n));
while ((i<=m)&&(!fin))
{
if(n%i==0)
fin = true;
else
i++;
}
if (fin)
System.out.println("EL NUMERO " + n +
" NO ES PRIMO");
else
System.out.println("EL NUMERO " + n +
" ES PRIMO");
}
}

Generaci
on de una Pir
amide de N
umeros Mediante Bucles
Anidados
public class Piramide {
public static void main(String args[]) {
int i,j,k,m;

56
1
232
34543
4567654
567898765
67890109876
7890123210987
890123454321098
90123456765432109
0123456789876543210
123456789010987654321
23456789012321098765432
3456789012345432109876543
456789012345676543210987654
56789012345678987654321098765

int altura=12;
if(args.length>=1)
{
Integer argumento=new Integer(args[0]);
altura=argumento.intValue();
}
else
altura=10;
for(i=1,m=1;i<=altura;i++,m+=2)
{
for (j=1;j<=altura-i;j++)
System.out.print(" ");
for (k=i;k<=m;k++)
System.out.print(k%10);
for (j=m-1;j>=i;j--)
System.out.print(j%10);
System.out.println("");
}
}
}

El M
etodo main()
El metodo main() es el metodo de arranque de toda aplicaci
on en lenguaje Java.
Puede ejecutarse una clase cualquiera sin mas que incluir en ella el metodo main(). Cuando se trata
de aplicaciones, bastara implementarlo en una de las clases (la que se arranca).
El metodo main() es la herramienta de que dispone el lenguaje Java para decirle al ordenador que
hacer tras arrancar una aplicacion o clase. Por ello, es llamado automaticamente por el entorno Java
al arrancar la clase o aplicacion, controla el flujo del programa desde su comienzo, asigna los recursos
que se necesiten y se encarga de llamar a cualquier otro metodo que se requiera.
Forma de declarar el metodo main():

57

Arranca el
intrprete de Java
Carga la clase o
aplicacin
Arranca la clase
o aplicacin

No

Existe el
mtodo main?

Enva un mensaje
de error

Si

Arranca el
mtodo main

public static void main(String args[]) {}


public: puede ser llamado por cualquier objeto.
static: es un metodo de clase.
void: no devuelve ning
un valor.
args[]: es una matriz de objetos de la clase String en la que el usuario pasa la informacion a la
clase. Se trata de los argumentos del metodo main().
Deben tenerse en cuenta las siguientes observaciones:
El metodo main() es un metodo de clase, por lo que si se quieren invocar metodos de la clase, se
debe crear un ejemplar de la misma.
Si se dise
na una interfase de usuario en una aplicacion, se debe crear en el metodo main() un
espacio y una ventana donde colocar dicha interfase.
Llamada al metodo main()
Cuando el entorno Java ejecuta la clase o aplicacion, lo primero que hace es llamar al metodo main(),
el cual invoca al resto de metodos necesarios para hacer funcionar la aplicacion.
Si la clase a compilar no tiene implementado un metodo main(), el proceso se detiene y se enva el
mensaje de error:
In class NombreClase:
void main(String args[]) is not defined
Argumentos de la lnea de comandos

58
Los programas pueden necesitar informacion para poder ejecutarse seg
un los deseos del usuario.
Una de las herramientas que lo permiten son los argumentos de la lnea de comandos. Son caracteres o
cadenas de caracteres que el usuario teclea y que permiten modificar el comportamiento de la aplicacion
sin necesidad de recompilarla.
El metodo main() acepta como u
nico argumento una matriz de elementos de la clase String, que
se llaman argumentos de la lnea de comandos, puesto que se les puede dar valores al comienzo de la
ejecucion, mediante un cuadro de dialogo que se muestra al usuario al ejecutar el programa Java o en
el comando de arranque de la aplicacion (entornos UNIX y WINDOWS). Mediante estos argumentos
se puede enviar informacion a la aplicacion.
Por tanto, el programa Java debe ser capaz de leer los argumentos y programarlos. El proceso es
el siguiente: al ejecutar una aplicacion, el sistema pasa los argumentos tecleados por el usuario a su
metodo main(), y los almacena en una matriz de objetos de tipo String. Cada uno de los argumentos
es uno de los elementos de la matriz.

Pr
actica 1
public class Matriz {
public int nfilas, ncolumnas;
public float x[][];
public Matriz(float m[][]) {
nfilas=m.length;
ncolumnas=m[0].length;
x=m;
}
public Matriz(int n, int m) {
nfilas=n;
ncolumnas=m;
x=new float[n][m];
}
public void Mostrar() {
int i,j;
for(i=0;i<nfilas;i++) {
for(j=0;j<ncolumnas;j++)
System.out.print(x[i][j]+"
System.out.println("");
}
}

");

}
import java.applet.Applet; import curso.*;
public class Producto extends Applet{
public Matriz Multiplicar (Matriz A, Matriz B) {
int i,j,k;
float suma;

59
Matriz C= new Matriz (A.nfilas, B.ncolumnas);
for(i=0;i<A.nfilas;i++)
for(j=0;j<B.ncolumnas;j++)
{
suma=0;
for(k=0;k<A.ncolumnas;k++)
suma+=A.x[i][k]*B.x[k][j];
C.x[i][j]=suma;
}
return(C);
}
public void init() {
float x[][]={{2,1,0},{-1,3,2},{4,1,-1}};
float y[][]={{2,3},{5,4},{1,2}};
Matriz A=new Matriz(x);
Matriz B=new Matriz(y);
Matriz C;
System.out.println("Producto:");
C=Multiplicar(A,B);
C.Mostrar();
}
}

60

Pr
actica 2
class Persona{
int edad, telefono;
String nombre;
public Persona(){
nombre="No ha sido dado";
edad=0;
telefono=0;
}
public Persona(String nombre, int edad, int telefono){
this.nombre=nombre;
this.edad=edad;
this.telefono=telefono;
}
}
class Agenda{
Persona[] entradas;
int contador;
public Agenda(int tamano){
contador=0;
entradas=new Persona[tamano];
System.out.println("Se ha creado una matriz de tamano "+tamano);
}
void anadir(Persona nuevaPersona){
if(contador==entradas.length) aumentarTamano();
entradas[contador]=nuevaPersona;
contador++;
}
void aumentarTamano(){
int nuevaLongitud=2*entradas.length;
Persona[] entradasAux=new Persona[nuevaLongitud];
for(int i=0;i<entradas.length;i++){
entradasAux[i]=entradas[i];
}
entradas=entradasAux;
System.out.println("La nueva matriz de tamano "+entradas.length);
}
Persona busqueda(String buscarNombre){
Persona encontrarPersona;
int localizador=0;
while((localizador<contador) &&
!(buscarNombre.equals(entradas[localizador].nombre)))
localizador++;
if(localizador==contador)
encontrarPersona=null;

61
else
encontrarPersona=entradas[localizador];
return encontrarPersona;
}
}
class PrincipalAgenda{
public static void main(String args[]){
Agenda miAgenda;
Persona persona,personaBuscar;
miAgenda=new Agenda(4);
for(int i=0;i<4;i++){
persona=new Persona("X"+i,10+i,677888+i);
System.out.println("La persona anadida es "+persona.nombre);
miAgenda.anadir(persona);
}
persona=new Persona("X5",15,5555788);
miAgenda.anadir(persona);
System.out.println("La persona anadida es "+persona.nombre);
personaBuscar=miAgenda.busqueda("X2");
if(personaBuscar==null)
System.out.println("No se encuentra la persona indicada");
else
System.out.println("La persona indicada se encuentra en la agenda");
}
}

EXCEPCIONES

63

Excepciones
Conceptos b
asicos
Los errores forman parte de todo programa. El lenguaje Java usa las excepciones para su tratamiento
y manipulacion.
Una excepcion es un suceso que ocurre durante la ejecucion del programa, y que rompe el flujo
normal del mismo.
Cuando ocurre uno de estos sucesos, se crea una excepcion y el control del programa pasa desde
el punto donde el error se produjo a otro punto especificado por el programador.
Se dice que la excepcion es lanzada (thrown) desde el punto donde se crea y es recogida
(caught) en el punto donde se transfiere el control
Java hereda la terminologa y la sintaxis del tratamiento de excepciones del lenguaje C++.
Toda excepcion es representada por un objeto de la clase Throwable o cualquier subclase suya.
Para dar respuesta a las excepciones se utilizan los manipuladores de excepciones (exception
handler).
Primer ejemplo de excepciones
Dado el programa en Java:
public class PrimeraExcepcion{
public static void main(){
int a[] = new int[3];
a[0]=5;
a[1]=3;
a[2]=4;
System.out.println(a[1] );
System.out.println(a[4] );
}
}
La consola de Java devuelve el siguiente mensaje:
3
Exception Occurred:
java.lang.ArrayIndexOutOfBoundsException: 4
at PrimeraExcepcion.main(PrimeraExcepcion.java:9)
at com.apple.mrj.JManager.JMStaticMethodDispatcher.
run(JMAWTContextImpl.java)
at java.lang.Thread.run(Thread.java)

64
Throwable

Error

Exception

RuntimeException

Causas de excepciones
En un programa Java las excepciones pueden provocarse por:
1. El propio sistema cuando detecta un error o una condicion de ejecucion anormal. Algunas de
estas causas de excepciones son:
Operacion que provoca una violacion de las normas semanticas del lenguaje. Por ejemplo,
ndice fuera de lmites en una matriz.
Error al cargar una parte del programa.
Exceso en el uso de un cierto recurso. Por ejemplo, agotar la memoria.
Error interno en la maquina virtual.
2. Explcitamente por el programador, utilizando la sentencia throw.
Por que usar excepciones?

Proporcionan robustez al programa.


Permiten separar el codigo especfico de tratamiento de errores del resto del codigo.
Permiten propagar los errores a otros metodos dentro de la lnea de llamadas.
Posibilidad de crear grupos de excepciones y diferenciar unas excepciones de otras.

Tipos de Excepciones
Toda excepci
on es un objeto de la clase Throwable o de alguna de sus subclases
El programador puede crear sus propios tipos de excepciones construyendo subclases de la clase Throwable
que se adapten mejor a sus necesidades particulares. Por convenio, todos los nombres de las clases de
excepciones terminan con la palabra Exception.
La clase Throwable es la superclase de todos los errores y excepciones en el lenguaje java.
La clase Error agrupa todos los errores graves del sistema que conducen a situaciones de difcil
solucion. Es poco probable que dentro de un programa Java se intente hacer un tratamiento de
este tipo de errores.

65
La clase Exception y sus subclases son una forma de la clase Throwable que indica condiciones
que un programa razonable debe querer capturar.

Excepciones de Obligada Respuesta


El compilador de Java comprueba si en el programa existen manipuladores (handlers) para las excepciones que se pudieran originar en la ejecucion de cada metodo.
La b
usqueda comienza en el metodo en el que se produce la excepcion y continua de forma ascendente
por la lnea de llamadas de dicho metodo. En caso de no encontrarlo se produce un error de compilacion
de la forma:
Warning:
Exception xxxException must be caught,
or it must be declared in throws clause
of this method.
Esta exigencia, que parece bastante estricta, es una de las formas de garantizar la robustez del programa.
Quedan exentas de esta imposici
on todas las excepciones de la clase RuntimeException o cualquiera
de sus subclases.
Excepciones de obligada respuesta:
Definidas en el paquete java.lang:
ClassNotFoundException: clase no encontrada por el metodo forName().
CloneNotSupportedException: error al hacer una copia del objeto con el metodo clone() de la
clase Object.
IllegalAccessException: intento fallido de cargar una clase desde un metodo que no tiene
acceso a ella porque no es de tipo public y se encuentra en otro paquete.
InstantationException: intento de crear un ejemplar de una clase de tipo abstract o de una
interfase.
InterruptedException: un proceso ligero interrumpe a otro que se encontraba en situacion de
espera.
Definida en el paquete java.io la clase IOException con las subclases:
java.io.EOFException: alcanzado el fin de fichero.
java.io.FileNotFoundException: no se encuentra el fichero.
java.io.InterruptedIOException: un proceso ligero interrumpe a otro que se encontraba en
situacion de espera para completar una operacion de Input/Output.
java.io.UTFDataFormatException: conversion imposible de realizar cuando se utiliza el metodo
readUTF().

66
Subclases de IOException definidas en el paquete java.net:
java.net.MalformedURLException
java.net.ProtocolException
java.net.SocketException
java.net.UnknownHostException
java.net.UnknownServiceException

Excepciones en Tiempo de Ejecuci


on (runtime)
No es obligatoria la presencia de un manipulador para tratarlas
Definidas en el paquete java.lang:
ArithmeticException: provocada por una operacion aritmetica ilegal. Por ejemplo, la division
por cero.
ArrayStoreException: intento de asignar a uno de los elementos de una matriz un valor con un
tipo no compatible.
ClassCastException: conversion de tipo ilegal.
IllegalArgumentException: llamada a un metodo con un argumento inapropiado. Subclases:
IllegalThreadStateException: se efect
ua una llamada no permitida a un metodo de un
thread.
NumberFormatException: intento de convertir una cadena que no tiene el formato adecuado
a un determinado tipo numerico.
IllegalMonitorException.
IndexOutOfBoundsException: ndice fuera de rango.
NegativeArraySizeException: intento de crear una matriz cuya longitud es negativa.
NullPointerException: uso de una referencia nula donde se requera la referencia a un objeto.
SecurityException: violacion de seguridad detectada.
Definidas en el paquete java.util:
java.util.EmptyStackException: intento de acceder a un elemento de una pila (stack) vaca.
java.util.NoSuchElementException: intento de acceder a un elemento de un vector vaco.

67

La clase Error
La clase Error agrupa todos los errores graves del sistema que conducen a situaciones de difcil
solucion.
Es poco probable que dentro de un programa Java se intente hacer un tratamiento de este tipo de
errores.

Tratamiento de excepciones
Ejemplo:
import java.io.*;
class Division{
public static void main(String args[]){
BufferedReader f;
float x,y;
f=new BufferedReader(
new FileReader("Datos"));
x=new Float(f.readLine()).floatValue();
y=new Float(f.readLine()).floatValue();
System.out.println("Resultado = " + x/y);
}
}
En el programa anterior se producen dos errores de compilacion:
El metodo main() debe tratar una posible excepcion del tipo FileNotFoundException.
Tambien debe tratar las excepciones IOException que se pueden producir al leer los datos.
Existe otro punto que puede provocar una excepcion: al efectuar la division se produce una
ArithmeticException si el divisor es nulo. Sin embargo, no es necesario tratarla, ya que es de tipo
runtime.

68
Un metodo puede responder a una excepcion de dos formas:
1. Incorporando un manipulador de excepciones apropiado al tipo de la misma.
2. Declarandola y dejando que sea alguno de los metodos de los que provino quien se encargue de
responderla.

Construcci
on de un manipulador de excepciones
Las tres componentes basicas de un manipulador de excepciones son:
El bloque try: agrupa todas las sentencias que pueden provocar excepciones.
El bloque o bloques catch: sentencias que se ejecutan cuando se produce la excepcion.
El bloque finally (opcional): sentencias que se ejecutan siempre:
Tras las sentencias del bloque try si no se producen excepciones.
Tras las sentencias del bloque catch si se ha producido alguna excepcion.
El bloque try define el alcance del manipulador de excepciones y debe ir acompa
nado de al menos un
bloque catch o el bloque finally.
try{
...
} catch (...) {
...
} catch (...) {
...
} ...
} finally {
...
}
}
Cuando existen varias sentencias del metodo que potencialmente pueden provocar una excepcion, hay
dos posibilidades:
(a) Agrupar todas las sentencias en un solo bloque try con varios bloques catch para responder a
cada una de las excepciones.
(b) Agrupar cada sentencia individual en un bloque try con su bloque catch correspondiente.
Cada bloque catch requiere un argumento que indica el tipo de excepcion que trata, este argumento
pertenece siempre a una subclase de la clase Throwable. Puede utilizarse el metodo getMessage() de
este argumento para mostrar informacion adicional sobre el error que provoco la excepcion.

69
Funcionamiento del manipulador de excepciones.
Si se produce una excepci
on:
1. Una instruccion dentro de un bloque try provoca una excepcion.
2. Se abandona el flujo de ejecucion normal del programa.
3. El sistema busca el primer bloque catch cuyo tipo de excepcion se ajusta al de la que se ha
producido. La b
usqueda comienza en el mismo metodo en el que se produjo la excepcion y
contin
ua por los metodos de los que provena la llamada.
4. Se ejecutan las sentencias de ese bloque.
5. Si existe bloque finally se ejecutan sus sentencias, en otro caso se da por concluida la ejecucion
del programa.
Si no se produce ninguna excepci
on:
1. Se ejecutan normalmente las sentencias del bloque try.
2. Si existe bloque finally se ejecutan sus sentencias.
Soluciones alternativas al programa del ejemplo
Soluci
on 1:
import java.io.*; class Division{
public static void main(String args[]){
BufferedReader f;
float x,y;
try{
f=new BufferedReader
(new FileReader("Datos"));
x=new Float(f.readLine()).floatValue();
y=new Float(f.readLine()).floatValue();
System.out.println("Resultado = " + x/y);
} catch(FileNotFoundException e){
System.err.
println("No encontrado el fichero");
} catch(IOException e){
System.err.println("Error de lectura");
}
}
}

70
Soluci
on 2:
import java.io.*;
class Division{
public static void main(String args[]){
BufferedReader f;
float x,y;
try{
f=new BufferedReader
(new FileReader("Datos"));
x=new Float(f.readLine()).floatValue();
y=new Float(f.readLine()).floatValue();
System.out.println("Resultado = " + x/y);
} catch(Exception e){
System.err.
println("Error: "+ e.toString());
}
}
}

Declaraci
on de Excepciones
La alternativa a la construccion de un manipulador para una excepcion es dejar que un metodo
anterior en la sucesion de llamadas se encargue de responderla, utilizando para ello el comando throws.
Ejemplo:
public void S(int v[])
throws IndexOutOfBoundsException {
......................
......................
......................
}
Indica que en el metodo S() puede generarse una excepcion IndexOutOfBoundsException, pero en ese
caso, el bloque catch para tratarla debe buscarse no en el metodo S() sino a partir del metodo en el
que se hizo la llamada a el.

La Sentencia throw
La sentencia throw se utiliza para lanzar excepciones, es decir, cuando se detecta una situacion
que provocara un error, debe crearse un objeto de la clase de excepcion correspondiente, e indicar que
la excepcion se ha producido mediante una sentencia de la forma:
throw Objeto;
donde Objeto debe pertenecer a alguna de las subclases de la clase Throwable.

71
La sentencia throw es utilizada implcitamente por el sistema cuando detecta algunos errores
estandar.
El programador puede utilizarla para lanzar sus propias excepciones de forma explcita.

Pr
actica de Excepciones
Terminar de escribir el siguiente programa realizando el tratamiento de las excepciones. (Nota: No
olvidar introducir los argumentos para ejecutar la aplicacion. Hay que introducir los nombres de 2
ficheros.)
import java.io.*;
class LeerEscribir{
public static void main(String argv[]){
File leer=new File(argv[0]);
FileInputStream f1=new FileInputStream(leer);
File escribir=new File(argv[1]);
FileOutputStream f2=
new FileOutputStream(escribir);
int c;
while((c=f1.read()) != -1){
f2.write(c);
}
f1.close();
f2.close();
}
}
Solucion 1
import java.io.*;
class LeerEscribir1{
public static void main(String argv[]){
try{
File leer=new File(argv[0]);
FileInputStream f1=new FileInputStream(leer);
File escribir=new File(argv[1]);
FileOutputStream f2=
new FileOutputStream(escribir);
int c;
while((c=f1.read()) != -1){
f2.write(c);
}
f1.close();

72
f2.close();
}
catch(Exception e){
System.out.println("LeerEscribir: "+e);
}
finally{System.out.println(" Se ha realizado con exito");}
}
}
Solucion 2
import java.io.*;
class LeerEscribir{
public static void main(String argv[])
throws IOException{
File leer=new File(argv[0]);
FileInputStream f1=new FileInputStream(leer);
File escribir=new File(argv[1]);
FileOutputStream f2=
new FileOutputStream(escribir);
int c;
while((c=f1.read()) != -1){
f2.write(c);
}
f1.close();
f2.close();
}
}

CONTROL DE SUCESOS

74

Programa 1

import java.awt.*;
public class Marco1{
public Marco1(){
setTitle("Marco");
setSize(300,300);
}
public static void main(String[] args){
Marco1 m=new Marco1();
m.show();
}
}
Como cerrar la ventana?
Se puede controlar perfectamente como transmitir los sucesos desde las fuentes de sucesos, (botones,
barras de desplazamiento) a los receptores de sucesos. Cualquier objeto puede ser un receptor de sucesos.
Las fuentes de sucesos poseen metodos que permiten registrar receptores de sucesos con ellos. Las
fuentes de sucesos son objetos que tienen la capacidad de detectar sucesos y notificar a los receptores
que se han producido dichos sucesos.
Resumiendo:
un receptor es un ejemplar de una clase que implementa una interfase especial llamada interfase
receptora
una fuente de sucesos es un objeto que puede registrar receptores y enviarles mensajes cuando
ocurren sucesos. Estos mensajes son metodos de la interfase receptora.
C
omo registrar el receptor con la fuente?
eventSourceObject.
addEventListener(eventListenerObject);
Ejemplo:
Button b=new Button("OK");
b.addActionListener(objeto);

75
El objeto es avisado cuando tiene lugar un suceso de acci
on en el boton, (presionar el boton, en este
caso).
Por tanto, la clase a la que pertenece el objeto (el receptor) debe implementar la interfase apropiada:
ActionListener, en este caso.
Para implementar ActionListener, la clase del receptor debe poseer un metodo (actionPerformed)
que recibe un objeto de la clase ActionEvent como parametro.
En el paquete java.awt.Event aparecen once interfases receptoras:

ActionListener
AdjustmentListener
ComponentListener
ContainerListener
FocusListener
ItemListener

KeyListener
MouseListener
MouseMotionListener
TextListener
WindowListener

Volvamos al ejemplo de partida y veamos como cerrar la ventana. Para ello, en primer lugar
redefinimos la clase Marco1. Si queremos cerrar la ventana, el suceso que se va a crear es un objeto de
la clase WindowEvent.
marco.addWindowListener(x);
Quien puede recibir el suceso?
Un objeto de una clase que implemente la interfase
WindowListener. En nuestro caso, la fuente y el receptor son el mismo.
Ejemplo:
import java.awt.*;
import java.awt.event.*;
class Marco extends Frame
implements WindowListener{
public Marco(){
addWindowListener(this);
}
}
Pero implementar una interfase no es suficiente. Se deben implementar los metodos necesarios para
la interfase
WindowListener en la clase Marco. Nuestra clase debe implementar todos los metodos definidos en
la interfase WindowListener. Existen siete metodos. Java los llama como respuestas a siete sucesos
diferentes que pueden ocurrir en una ventana:

76
void
void
void
void
void
void
void

windowClosed(WindowEvent e)
windowIconified(WindowEvent e)
windowOpened(WindowEvent e)
windowClosing(WindowEvent e)
windowDeiconified(WindowEvent e)
windowActivated(WindowEvent e)
windowDeactivated(WindowEvent e)

Ejemplo:
import java.awt.*;
import java.awt.event.*;
public class Marco extends Frame
implements WindowListener{
public Marco(){
setTitle("Marco");
setSize(300,300);
addWindowListener(this);
}
public void windowClosing(WindowEvent e){
System.exit(0);
}
public void windowClosed(WindowEvent e){}
public void windowIconified(WindowEvent e){}
public void windowOpened(WindowEvent e){}
public void windowDeiconified(WindowEvent e){}
public void windowActivated(WindowEvent e){}
public void windowDeactivated(WindowEvent e){}
public static void main(String[] args){
Marco m=new Marco();
m.show();
}
}
Se han implementado seis metodos que no realizan ninguna accion. Simplifiquemos el programa
anterior.
Cada interfase receptora viene acompa
nada de una clase adaptadora que implementa todos los
metodos de la interfase pero no hace nada con ellos. Existe una clase adaptadora para cada una de las
siete interfases receptoras con mas de un metodo:

ComponentAdapter MouseAdapter
ContainerAdapter MouseMotionAdapter
FocusAdapter
WindowAdapter
KeyAdapter

77
Ejemplo:
import java.awt.*;
import java.awt.event.*;
class CerrarVentana extends WindowAdapter{
public void windowClosing(WindowEvent e){
System.exit(0);
}
}
class MarcoSimplificado extends Frame{
public MarcoSimplificado(){
CerrarVentana v = new CerrarVentana();
setTitle("Marco");
setSize(300,300);
addWindowListener(v);
}
public static void main(String[] args){
MarcoSimplificado m=new MarcoSimplificado();
m.show();
}
}
Ejemplo:
import java.awt.*;
import java.awt.event.*;

public class MarcoSimplificadoAltern


extends Frame{
public MarcoSimplificadoAltern(){
setTitle("Marco");
setSize(300,300);
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);}});
}
public static void main(String[] args){
MarcoSimplificadoAltern m=
new MarcoSimplificadoAltern();
m.show();
}
}

78

Sucesos
La superclase que engloba todos los sucesos es la clase EventObject implementada en el paquete
java.util
Event
Object

AW T E v e n t

Action Adjustment
Event Event

Container Focus
Event
Event

Component Item
Event
Event

Input
Paint
Event Event

Key
Event

Te x t
Event

Wi n d o w
Event

Mouse
Event

Cuando una fuente necesita comunicar a un receptor la ocurrencia de un suceso, el AWT


llama al metodo adecuado de la interfase receptora
le pasa un objeto de la clase EventObject
Esto sucede automaticamente una vez que se registra el receptor con la fuente.
A continuacion se muestra una lista con aquellos sucesos que pasan a los receptores:

ActionEvent
FocusEvent MouseEvent
AdjustmentEvent ItemEvent
TextEvent
ComponentEvent
KeyEvent
WindowEvent
ContainerEvent
Describamos brevemente las clases del paquete
java.awt.event
u, activar un campo de texto.
ActionEvent: pulsar un boton, seleccionar un men
AdjustmentEvent: ajustar una barra de desplazamiento.
ItemEvent: seleccionar un boton de marca o un tem de una lista.
TextEvent: modificar el contenido de un area de texto.

79
no de una componente, moverla, mostrarla o esconderla.
ComponentEvent: modificar el tama
KeyEvent: pulsar o soltar una tecla.
MouseEvent: pulsar el boton del raton, soltarlo, mover o arrastrar el raton.
FocusEvent: activar o desactivar una componente.
WindowEvent: activar, desactivar, cerrar la ventana.

80
Interfase

M
etodos

Par
ametro

ActionListener

actionPerformed

ActionEvent
getActionCommand
getModifiers

AdjustmentListener

adjustmentValueChanged

ItemListener

itemStateChanged

TextListener
ComponentListener

textValueChanged
componentMoved
componentHidden
componentResized
componentAdded
componentRemoved

AdjustmentEvent
getAdjustable
getAdjustmentType
getValue
ItemEvent
getItem
getItemSelectable
getStateChange
TextEvent
ComponentEvent
getComponent

ContainerListener

FocusListener
KeyListener

focusGained
focusLost
keyPressed
keyReleased
keyTyped

MouseListener

mousePressed
mouseReleased
mouseEntered
mouseExited
mouseClicked

MouseMotionListener

mouseDragged
mouseMoved
windowClosing
windowOpened
windowIconified
windowDeiconified
windowClosed
windowActivated
windowDeactivated

WindowListener

ContainerEvent
getChild
getContainer
FocusEvent
IsTemporary
KeyEvent
getKeyChar
getKeyCode
getKeyModifiersText
getKeyText
IsActionKey
MouseEvent
getClickCount
getX
getY
getPoint
TranslatePoint
IsPopupTrigger

Sucesos
generados por
Button
List
MenuItem
TextField
Scrollbar

Checkbox
CheckboxMenuItem
Choice
List
TextComponent
Component

Container

Component
Component

Component

Component
WindowEvent
getWindow

Window

81

Ejemplo 1
import java.awt.*;
import java.applet.Applet;
public class Boton extends Applet{
Button a;
public void init(){
a=new Button("OK");
add(a);
}
}

Ejemplo 2
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class Boton extends Applet
implements ActionListener{
Button a;
public void init(){
a=new Button("OK");
add(a);
a.addActionListener(this);
}
public void actionPerformed(ActionEvent evt){
a.setLabel("Cancel");
}
}

Ejemplo 3
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;

82
public class Botones extends Applet
implements ActionListener{
Button a,b;
public void init(){
a=new Button("a");
b=new Button("b");
add(a);
a.addActionListener(this);
add(b);
b.addActionListener(this);
}
public void actionPerformed(ActionEvent evt){
String arg=evt.getActionCommand();
if(arg.equals("a"))
b.setLabel("a");
else if(arg.equals("b"))
a.setLabel("b");
}
}

Ejemplo 4

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

83
import java.awt.event.*;
public class Sucesos extends Applet
implements MouseListener,ItemListener,
ActionListener,MouseMotionListener,
FocusListener{
List mensajes;
Button boton;
Choice colores;
Label etiqueta1,etiqueta2,etiqueta3,etiqueta4;
TextField nombre;
TextArea acciones;
int x,y,w,h;
public void init() {
addMouseMotionListener(this);
setLayout(null);
// Se crea la etiqueta 1
etiqueta1=new Label("BIENVENIDO!",Label.CENTER);
etiqueta1.setBounds(80,10,120,20);
add(etiqueta1);
// Se crea la etiqueta 2
etiqueta2=new Label("Mensajes",Label.CENTER);
etiqueta2.setBounds(10,40,120,20);
add(etiqueta2);
// Se crea la lista de mensajes
mensajes=new List(4,false);
mensajes.add("Hola");
mensajes.add("Cuidado");
mensajes.add("Peligro");
mensajes.add("Adios");
mensajes.setBounds(10,70,120,63);
mensajes.addMouseListener(this);
mensajes.addItemListener(this);
add(mensajes);
// Se crea el boton
boton=new Button("BOTON");
boton.setBounds(150,40,120,20);
boton.addMouseListener(this);
boton.addActionListener(this);
add(boton);
// Se crea el menu flotante
colores=new Choice();
colores.addItem("azul");
colores.addItem("verde");
colores.addItem("rojo");

84
colores.addItem("amarillo");
colores.addItem("negro");
colores.setBounds(150,70,120,80);
colores.addMouseListener(this);
colores.addItemListener(this);
add(colores);
// Se crea la etiqueta 3
etiqueta3=new Label("Acciones",Label.CENTER);
etiqueta3.setBounds(80,140,120,20);
etiqueta3.addMouseListener(this);
add(etiqueta3);
// Se crea la zona de texto no editable
acciones=new TextArea(15,25);
//acciones.setEditable(false);
acciones.setBounds(20,170,240,160);
acciones.addMouseListener(this);
add(acciones);
// Se crea la etiqueta 4
etiqueta4=new Label("Nombre",Label.CENTER);
etiqueta4.setBounds(80,350,120,20);
etiqueta4.addMouseListener(this);
add(etiqueta4);
// Se crea la zona de texto editable
nombre=new TextField(20);
nombre.setBounds(80,380,120,20);
nombre.addMouseListener(this);
nombre.addFocusListener(this);
add(nombre);
}
public void mouseEntered(MouseEvent evt) {
Object componente=evt.getSource();
if(componente.equals(boton)){
acciones.append("Se entra en el boton\n");
}else if(componente.equals(mensajes)){
acciones.append("Se entra en la lista\n");
}else if(componente.equals(acciones)){
acciones.append("Se entra en el campo de
acciones\n");
}else if(componente.equals(nombre)){
acciones.append("Se entra en el campo
nombre\n");
}
}
public void mouseExited(MouseEvent evt) {
Object componente=evt.getSource();

85
if(componente.equals(boton)){
acciones.append("Se sale del boton\n");
}else if(componente.equals(mensajes)){
acciones.append("Se sale de la lista\n");
}else if(componente.equals(acciones)){
acciones.append("Se sale de el campo de
acciones\n");
}else if(componente.equals(nombre)){
acciones.append("Se sale de el campo
nombre\n");
}
}
public void mouseClicked(MouseEvent evt) {
acciones.append("Se ha pulsado el raton\n");
}
public void mousePressed(MouseEvent evt) {
acciones.append("Se ha presionado el raton\n");
}
public void mouseReleased(MouseEvent evt) {
acciones.append("Se ha liberado el raton\n");
}
public void mouseDragged(MouseEvent evt) {
acciones.append("Se ha arrastrado el raton\n");
}
public void mouseMoved(MouseEvent evt) {
acciones.append("Se ha movido el raton\n");
}
public void itemStateChanged(ItemEvent evt) {
Object componente=evt.getSource();
if(componente.equals(mensajes)){
String mensaje=mensajes.getSelectedItem();
acciones.append("Se ha seleccionado "+
mensaje+"\n");
boton.setLabel(mensaje);
}
else if(componente.equals(colores)){
String color=(String)evt.getItem();
acciones.append("Se ha seleccionado el "+
color+"\n");
}
}

86

public void actionPerformed(ActionEvent evt){


if((evt.getSource()).equals(boton)){
String str=evt.getActionCommand();
acciones.append("Se ha presionado sobre
el boton "+str+" \n");
}
}
public void focusGained(FocusEvent evt){
acciones.append("Se ha activado nombre\n");
}
public void focusLost(FocusEvent evt){
acciones.append("Se ha desactivado nombre\n");
etiqueta1.setText(nombre.getText());
} }

INTERFASES DE USUARIO

88

Paquete java.awt
En este paquete se encuentran clases que permiten definir las distintas componentes de una interfase.
La siguiente figura muestra algunas de las componentes disponibles en Java:

Paquete java.awt
Todas las componentes tienen lo siguiente en com
un:
Una posicion en la pantalla y un tama
no
Un color del fondo y un color del primer plano
Estar activadas o desactivadas
Una interfase para manejar los sucesos que ocurran sobre esa componente
Todas las componentes, excepto los men
us, se implementan como subclases de la clase Component y
por tanto, heredan de esta todos los procedimientos, que son los que permiten darles funcionalidad en
un programa.
Cuando se crea una componente, esta se a
nade a un contenedor para lo cual se utiliza el metodo
add() definido en la clase Container.
Este metodo tiene las tres definiciones siguientes:
Component add(Component comp)
Component add(Component comp,int pos)
Component add(Sring name,Component comp)
Algunos de los metodos definidos en la clase Component y que pueden ser utilizados por toda subclase
son:
String getName(): Devuelve el nombre de la componente.
void setName(String name): Asigna el nombre a la componente.
void setEnabled(boolean b): Para activar o desactivar la componente correspondiente.
void setVisible(boolean b): Para mostrar o ocultar la componente correspondiente.
Color getBackground(): Devuelve el color del fondo de dicha componente.
void setBackground(Color c): Asigna el color del fondo de dicha componente.
Font getFont(): Devuelve el tipo de letra de dicha componente.
void setFont(): Asigna el tipo de letra de dicha componente.
Dimension getSize(): Devuelve el tama
no de dicha componente.
void setSize(int width,int height): Modifica el tama
no de dicha componente.

89
void setBounds(int x,int y,int width,int height):
Mueve y modifica el tama
no de dicha componente.
FontMetrics getFontMetrics(Font font):Devuelve el aspecto metrico del tipo de letra.
void paint(Graphics g):Dibuja en esta componente.
void update(Graphics g):Actualiza esta componente.
void repaint():Redibuja esta componente.

Botones
La clase Button
La clase Button proporciona dos constructores para crear botones:
public Button()
public Button(String label)
Entre los metodos que proporciona la clase Button destaca:
void setLabel(String label)
void addActionListener(ActionListener al)
String getLabel()
Ejemplo:
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class Botones extends Applet {
// Se crean cuatro botones con diferentes nombres
Button a, b,c,d;
public void init() {
setLayout(new GridLayout(2,2,10,10));
a = new Button("Boton 1");
a.addActionListener(this);
b = new Button("Boton 2");
b.addActionListener(this);
c = new Button("Boton 3");
c.addActionListener(this);
d = new Button("Boton 4");

90
d.addActionListener(this);
setLayout(new GridLayout(2,2,10,10));
add(a);
add(b);
add(c);
add(d);
}
public void actionPerformed(ActionEvent evt) {
String arg = evt.getActionCommand();
// Al presionar sobre un bot
on, cambia su etiqueta
if (arg.equals("Boton 1"))
a.setLabel("A");
else if (arg.equals("Boton 2"))
b.setLabel("B");
else if (arg.equals("Boton 3"))
c.setLabel("C");
else if (arg.equals("Boton 4"))
d.setLabel("D");
}
}
La clase Checkbox
Para crear estos botones, se dispone de las clases Checkbox y CheckboxGroup.
La clase Checkbox proporciona tres constructores:
public Checkbox()
public Checkbox(String label)
public Checkbox(String label,boolean state)
public Checkbox(String label,CheckboxGroup group,
boolean state)
Entre sus metodos destacan:
void setCheckboxGroup(CheckboxGroup g)
CheckboxGroup getCheckboxGroup()
void setLabel(String label)
String getLabel()
void setState(boolean state)
boolean getState()

91
void addItemListener(ItemListener l)
void removeItemListener(ItemListener l)
La clase CheckboxGroup
El constructor de la clase CheckboxGroup es:
public CheckboxGroup()
Entre sus metodos destaca:
Checkbox getSelectedCheckbox()
void setSelectedCheckbox(Checkbox box)
String toString()
Ejemplo:
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class Botones extends Applet
implements ActionListener,
ItemListener{
Button a, b,c;
Checkbox d, e,f;
public void init() {
setLayout(null);
a = new Button("Boton 1");
a.addActionListener(this);
a.setBounds(10,10,50,20);
b = new Button("Boton 2");
b.setBounds(70,10,50,20);
b.addActionListener(this);
c = new Button("Boton 3");
c.setBounds(130,10,50,20);
c.addActionListener(this);
CheckboxGroup ch=new CheckboxGroup();
d=new Checkbox("Boton 4",ch,true);
d.setBounds(10,40,60,20);
d.addItemListener(this);
e=new Checkbox("Boton 5",ch,false);
e.setBounds(80,40,60,20);
e.addItemListener(this);
f=new Checkbox("Boton 6",ch,false);
f.setBounds(140,40,60,20);

92
f.addItemListener(this);
add(a);
add(b);
add(c);
add(d);
add(e);
add(f);
}
public void actionPerformed(ActionEvent evt) {
String arg = evt.getActionCommand();
if (arg.equals("Boton 1"))
a.setLabel("A");
else if (arg.equals("Boton 2"))
b.setLabel("B");
else if (arg.equals("Boton 3"))
c.setLabel("C");
}
public void itemStateChanged(ItemEvent evt) {
if(evt.getItem().equals("Boton 4")){
d.setLabel("D");
}else if(evt.getItem().equals("Boton 5")){
e.setLabel("E");
}else if(evt.getItem().equals("Boton 6")){
f.setLabel("F");
}
}
}

Canvas
Cuando se empieza a llenar una ventana con muchos elementos de interfase y m
ultiples paneles, lo
mejor es no dibujar directamente sobre la superficie de la ventana puesto que el dibujo puede interferir
con las componentes que se han colocado en la ventana. Un Canvas es un area rectangular en la cual
se puede dibujar.
Ejemplo:
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class Checkboxes extends Applet
implements ItemListener{
NuevoCanvas area;
Checkbox peq, medio, grande;
CheckboxGroup grupo;

93
public void init() {
setLayout(new BorderLayout());
Panel p=new Panel();
area=new NuevoCanvas();
grupo = new CheckboxGroup();
peq = new Checkbox("Peque\~no", grupo, true);
peq.addItemListener(this);
medio = new Checkbox("Medio", grupo, false);
medio.addItemListener(this);
grande = new Checkbox("Grande", grupo, false);
grande.addItemListener(this);
p.add(peq);
p.add(medio);
p.add(grande);
add(p,"South");
add(area,"Center");
}
public void itemStateChanged(ItemEvent evt){
if(evt.getItem().equals("Peque\~no")){
area.setFont(new Font("SansSerif",
Font.PLAIN,8));
area.repaint();}
else if(evt.getItem().equals("Medio")){
area.setFont(new Font("SansSerif",
Font.PLAIN,12));
area.repaint();}
else if(evt.getItem().equals("Grande")){
area.setFont(new Font("SansSerif",
Font.PLAIN,14));
area.repaint();}
}
}
class NuevoCanvas extends Canvas{
public NuevoCanvas(){
setFont(new Font("SansSerif",Font.PLAIN,8));
}
public void paint(Graphics g){
g.drawString("Esto es una prueba",50,50);
}
}

Zonas de Texto
La clase TextComponent es la superclase de las clases
TextArea y TextField, que permiten mostrar y editar texto.
Consta de los siguientes metodos:

94
String getSelectedText()
String getText()
boolean setEditable(boolean t)
void selectAll()
void select(int begin,int end)
void setText(String text)
addTextListener(TextListener tl)
La clase TextArea
Zona con varias lneas que permite mostrar texto.
El metodo setEditable() permite elegir si el area es editable.
La clase TextArea consta de los siguientes constructores:
public TextArea()
public TextArea(int rows, int cols)
public TextArea(String text)
public TextArea(String text,int rows,
int cols)
TextArea(String text,int rows,
int cols,int scroll)
donde scroll puede tomar los valores:
TextArea.SCROLLBARS BOTH
TextArea.SCROLLBARS VERTICAL ONLY
TextArea.SCROLLBARS HORIZONTAL ONLY
TextArea.SCROLLBARS NONE
Algunos de los metodos de esta clase son:
void append(String text)
int getColumns()
int getRows()
void insert(String str,int pos)
void replaceRange(String str,int start,int end)

95
La clase TextField
Un campo de texto es una componente con una u
nica lnea de texto editable.
Los constructores de un campo de texto son:
public TextField()
public TextField(int cols)
public TextField(String text)
public TextField(String text,int cols)
Algunos de los metodos de esta clase son:
void addActionListener(ActionListener al)
Ejemplo
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
public class TextWin extends Applet
implements ActionListener{
TextArea textAr;
TextField textF;
public void init()
{
setLayout(new BorderLayout());
textAr=new TextArea();
textF=new TextField();
textF.addActionListener(this);
add("North",textAr);
add("South",textF);
}
public void actionPerformed(ActionEvent evt)
{
textAr.append(textF.getText()+"\n");
textF.selectAll();
}
}

Etiquetas
La clase Label permite poner texto fijo en un programa.
Se tienen tres constructores en la clase Label:
public Label()

96
public Label(String label)
public Label(String label, int alignment)
Entre sus metodos:
void setAlignment(int alignment)
El parametro alignment puede tomar los valores:
Label.CENTER, Label.LEFT o Label.RIGHT.
void setText(String label)
String getText()
Ejemplo:
import java.awt.*;
public class LabelWin extends Frame {
public LabelWin() {
setLayout(new GridLayout(3,1));
Label l1 = new Label();
l1.setBackground(Color.white);
l1.setText("Blanco");
Label l2 = new Label("Amarillo");
l2.setBackground(Color.yellow);
Label l3 = new Label("Gris");
l3.setBackground(Color.gray);
l3.setAlignment(Label.CENTER);
setTitle("Label");
add(l1);
add(l2);
add(l3);
}

public static void main(String args[]){


LabelWin ld=new LabelWin();
ld.setSize(200,200);
ld.setVisible(true);
}
}

Marcos
La subclase Frame de la clase Window permite crear marcos donde se muestran las aplicaciones y los
applets.
Un objeto de la clase Frame es un marco con borde y barra de ttulo. Puede tener tambien una
barra de men
u. Los objetos de tipo Frame son necesarios en toda aplicacion.
Existen dos constructores de la clase Frame:

97
public Frame()
public Frame(String title)
Con el segundo de estos constructores se le da un ttulo al marco. Algunos de los metodos definidos
en la clase Frame son:
MenuBar getMenuBar()
String getTitle()
void setMenuBar(MenuBar mb)
void setTitle(String title)

Men
us
Existen las siguientes clases que permiten construir men
us y barras de men
us:
MenuItem
Los objetos MenuItem representan las opciones de un men
u.
CheckboxMenuItem
Subclase de MenuItem. Estos objetos hacen referencia a las opciones que act
uan como
botones de marca.
Menu
Subclase de MenuItem. Los men
us se representan mediante los objetos de tipo Menu, que
solo existen en barras de men
u.
MenuBar
Hace referencia al men
u principal. Las barras de men
u estan ligadas u
nicamente a los
contenedores de tipo Frame.
La clase MenuItem
La clase MenuItem consta de los constructores:
public MenuItem()
public MenuItem(String label)
public MenuItem(String label,MenuShortcut ms)
Entre sus metodos:
String getLabel()
void setLabel(String label)

98
boolean isEnabled()
void setEnabled(boolean b)
MenuShorcut getShortcut()
void setShortcut(MenuShortcut s)
void getActionCommand()
void addActionListener(ActionListener al)
La clase Menu
La clase Menu posee los siguientes constructores:
public Menu()
public Menu(String label)
public Menu(MenuBar mb)
public void setTitle(String label,boolean tearoff)
Entre sus metodos:
int getItemCount()
MenuItem getItem(int index)
MenuItem add(MenuItem mi)
void add(String label)
void insert(MenuItem mi,int index)
void insert(String label,int index)
void addSeparator()
void insertSeparator(int index)
void remove(int index)
void removeAll()
La clase MenuBar
La clase MenuBar tiene el constructor:
public MenuBar()
Entre sus metodos:

99
Menu add(Menu m)
void remove(int index)
int getMenuCount()
Menu getMenu(int i)
La clase CheckboxMenuItem
La clase CheckboxMenuItem consta de los constructores:
public CheckboxMenuItem()
public CheckboxMenuItem(String label)
public CheckboxMenuItem(String label,boolean state)
Entre sus metodos:
boolean getState()
void setState(boolean b)
void addItemListener(ItemListener l)
La clase MenuShortcut
La clase MenuShortcut consta de los constructores:
public MenuShortcut(int key)
public MenuShortcut(int key,boolean useShiftModifier)
Entre sus metodos:
int getKey()
boolean useShiftModifier()
Ejemplo:
import java.awt.*;
import java.awt.event.*;
public class Menus extends Frame
implements ActionListener, ItemListener{
MenuBar barra;
Menu m1,m2;
MenuItem mi1,mi2, mi3;
CheckboxMenuItem mi4;

100
public Menus() {
barra = new MenuBar();
setMenuBar(barra);
m1 = new Menu("Menu1");
barra.add(m1);
m2 = new Menu("Menu2");
barra.add(m2);
mi1 = new MenuItem("Salir");
mi1.addActionListener(this);
m1.add(mi1);
mi2 = new MenuItem("MenuItem 1");
mi2.setShortcut(
new MenuShortcut(KeyEvent.VK_5));
mi2.addActionListener(this);
m2.add(mi2);
mi3 = new MenuItem("MenuItem 2");
mi3.addActionListener(this);
m2.add(mi3);
mi4 = new CheckboxMenuItem("MenuItem 3");
mi4.addItemListener(this);
m2.add(mi4);
}
public void actionPerformed(ActionEvent evt){
MenuItem c=(MenuItem) evt.getSource();
String arg=c.getLabel();
if(arg.equals("Salir")){
System.exit(0);
}else if((arg.equals("MenuItem 1")) ||
(arg.equals("MenuItem 2"))){
System.out.println(arg);
}
}
public void itemStateChanged(ItemEvent evt){
CheckboxMenuItem c=
(CheckboxMenuItem) evt.getSource();
String arg=c.getLabel();
if(arg.equals("MenuItem 3")){
System.out.println(arg);
}
}
public static void main(String argv[]) {
Menus menus = new Menus();
menus.setTitle("Barra de Menus");

101
menus.setSize(200,200);
menus.setVisible(true);
}
}

Elecciones
La clase Choice construye men
us de tipo flotante. El constructor de esta clase es:
public Choice()
La primera opcion que se a
nade al men
u se considera como la opcion seleccionada por defecto, hasta
que el usuario elija otra.
Entre los metodos de la clase Choice destacan:
public int getItemCount()
public String getItem(int index)
public void addItem(String item)
public String getSelectedItem()
public void select(int pos)
public void select(String str)
public void addItemListener(ItemListener l)
Ejemplo:
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class Popup extends Applet
implements ItemListener {
Choice choice;
Color color;
public void init() {
color=Color.yellow;
choice = new Choice();
choice.addItem("rojo");
choice.addItem("azul");
choice.addItem("verde");
choice.addItemListener(this);
add(choice);
}

102
public void paint(Graphics g){
setBackground(color);
}
public void itemStateChanged(ItemEvent evt){
String str=(String)evt.getItem();
if(str.equals("rojo"))
color=Color.red;
else if(str.equals("azul"))
color=Color.blue;
else if(str.equals("verde"))
color=Color.green;
repaint();
}
}
Ejercicio:

import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class Opera extends Applet implements ActionListener{
TextField t1,t2;
Choice opcion;
TextArea ta;
Button b1,b2;
public void init() {
setLayout(null);

103
t1=new TextField();
t2=new TextField();
ta=new TextArea();
Label l1=new Label("N\umero");
Label l2=new Label("Operaci\on");
b1=new Button("Calcular");
b1.addActionListener(this);
b2=new Button("Borrar");
b2.addActionListener(this);
opcion=new Choice();
opcion.addItem("|x|");
opcion.addItem("E^x");
opcion.addItem("x^5");
l1.setBounds(10,10,50,30);
t1.setBounds(60,10,100,30);
l2.setBounds(10,80,50,50);
opcion.setBounds(70,80,100,50);
ta.setBounds(10,150,300,100);
b1.setBounds(10,300,80,30);
b2.setBounds(150,300,80,30);
add(l1);
add(t1);
add(l2);
add(t2);
add(ta);
add(b1);
add(b2);
add(opcion);
}
public void actionPerformed(ActionEvent evt){
String str=evt.getActionCommand();
if(str=="Calcular"){
String str1=t1.getText();
String str2=opcion.getSelectedItem();
double d1;
Double aux1=new Double(str1);
d1=aux1.doubleValue();
if(str2=="|x|")
ta.append("|"+d1+"|"+"="+Math.abs(d1)+"\n");
else if(str2=="E^x")
ta.append("E"+"^"+d1+"="+Math.exp(d1)+"\n");
else if(str2=="x^5")
ta.append(d1+"^"+5+"="+Math.pow(d1,5)+"\n");
}
else if(str=="Borrar") ta.setText(" ");
}
}

104

Listas
La clase List permite crear un area desplazable conteniendo opciones que se pueden seleccionar.
Posee los constructores:
public List(int rows)
public List()
public List(int rows, boolean multipleSelections)
Entre sus metodos se encuentran:
void add(String item)
void add(String item, int index)
String getItem(int index)
void select (int index)
String getSelectedItem ()
void setMultipleMode (boolean b)
void addItemListener(ItemListener il)
void addActionListener(ActionListener al)
Ejemplo:
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class ListWin extends Applet implements ItemListener {
Button button;
List list;
public void init() {
setLayout(new BorderLayout());
list = new List(3, true);
list.add("Rojo");
list.add("Azul");
list.add("Verde");
list.addItemListener(this);
add("North",list);
}
public void itemStateChanged(ItemEvent evt){
int sIndex;

105
if(evt.getStateChange()==ItemEvent.SELECTED){
sIndex=((Integer)evt.getItem()).intValue();
System.out.println("Ha seleccionado
la opcion: "+sIndex);
}
else if(evt.getStateChange()==
ItemEvent.DESELECTED){
sIndex=((Integer)evt.getItem()).intValue();
System.out.println("Ha deseleccionado
la opcion: "+sIndex);
}
}
}

Paneles
Un panel es un contenedor (subclase de la clase
Container).
En el se puede colocar cualquier componente, inclusive otro panel.
La disposicion por defecto para un Panel es la de tipo
FlowLayout.
Ejercicio: Utilizacion Clase Panel

import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;

106
public class Operar extends Applet implements
ActionListener{
TextField t1,t2,t3;
TextArea ta;
Button b1,b2,b3;
public void init() {
t1=new TextField();
t2=new TextField();
t3=new TextField();
ta=new TextArea();
Label l1=new Label("Primer Numero",Label.CENTER);
Label l2=new Label("Segundo Numero",Label.CENTER);
Label l3=new Label("Resultado",Label.CENTER);
b1=new Button("Suma");
b2=new Button("Producto");
b3=new Button("Divisi\on");
b1.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
Panel p1=new Panel();
p1.setLayout(new GridLayout(3,2));
Panel p2=new Panel();
Panel p3=new Panel();
p1.add(l1); p1.add(t1);
p1.add(l2); p1.add(t2);
p1.add(l3); p1.add(t3);
p2.add(ta); p3.add(b1);
p3.add(b2); p3.add(b3);
add(p1);
add(p2);
add(p3);
}
public void actionPerformed(ActionEvent evt){
String str=evt.getActionCommand();
String str1=t1.getText();
String str2=t2.getText();
double d1,d2,total;
Double aux1=new Double(str1);
d1=aux1.doubleValue();
Double aux2=new Double(str2);
d2=aux2.doubleValue();
if(str=="Suma"){
total=d1+d2;
t3.setText(Double.toString(total));
ta.append("La operacion realizada ha sido
una suma"+"\n");
}else if(str=="Producto"){

107
total=d1*d2;
t3.setText(Double.toString(total));
ta.append("La operacion realizada ha sido
un producto"+"\n");
}else if(str=="Divisi\on"){
total=d1/d2;
t3.setText(Double.toString(total));
ta.append("La operacion realizada ha sido
una divisi\on"+"\n");
}
}
}

Cuadros de Di
alogo
Para implementar un cuadro de dialogo, se crea una subclase de la clase Dialog.
Los cuadros de dialogo son ventanas que dependen de otra ventana (Frame).
Cuando se destruye la ventana tambien se destruyen los cuadros de dialogo que dependen de ella.
En el constructor del cuadro de dialogo se llama al constructor de la clase Dialog, en este se da la
ventana de la cual depende.
Se asignan las dimensiones del cuadro mediante el metodo setSize().
La aplicacion debe utilizar el metodo show() para que aparezca el dialogo.
La ordenacion (layout) por defecto de las diferentes componentes de un cuadro de dialogo es
BorderLayout.
Hay cuatro constructores de la clase Dialog:
public Dialog(Frame parent);
public Dialog(Frame parent, boolean modal);
public Dialog(Frame parent, String title);
public Dialog(Frame parent, String title,
boolean modal)
Ejemplo:
import java.awt.*;
import java.awt.event.*;
public class VentanaDialog extends Frame

108
implements ActionListener{
SimpleDialog dialog;
TextArea textArea;
Button boton1;
public VentanaDialog(){
textArea=new TextArea(5,40);
textArea.setEditable(false);
add("Center",textArea);
boton1=new Button("Pulsar para mostrar dialogo");
boton1.addActionListener(this);
Panel panel=new Panel();
panel.add(boton1);
add("South",panel);
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}});
}
public void actionPerformed(ActionEvent evt){
String str=evt.getActionCommand();
if(str.equals("Pulsar para mostrar dialogo")){
if(dialog==null)
dialog=new SimpleDialog(this,"Cuadro de
dialogo");
dialog.show();
}
}
public void setText(String texto){
textArea.append(texto+"\n");
}
public static void main(String args[]){
VentanaDialog ventana=new VentanaDialog();
ventana.setTitle("Aplicacion");
ventana.setSize(200,200);
ventana.setVisible(true);
}
}
class SimpleDialog extends Dialog
implements ActionListener{

109
TextField campo;
VentanaDialog parent;
Button b1;
public SimpleDialog(Frame fr,String titulo){
super(fr,titulo,true);
parent=(VentanaDialog)fr;
Panel p1=new Panel();
Label etiqueta=new Label("Escribir texto:");
p1.add(etiqueta);
campo=new TextField(40);
p1.add(campo);
add("Center",p1);

Panel p2=new Panel();


p2.setLayout(new FlowLayout(FlowLayout.RIGHT))
b1=new Button("Cancel");
b1.addActionListener(this);
Button b2=new Button("Ok");
b2.addActionListener(this);
p2.add(b1);
p2.add(b2);
add("South",p2);

setSize(600,100);
}
public void actionPerformed(ActionEvent evt){
String str=evt.getActionCommand();
if(str.equals("Ok"))
parent.setText(campo.getText());
setVisible(false);
}
}

Criterios de Colocaci
on
Criterio BorderLayout
BorderLayout es el gestor de colocacion por defecto para todas las ventanas(Windows), tales como
marcos (Frames) y dialogos (Dialogs).
Utiliza cinco areas: norte, sur, este, oeste y centro.
Todo el espacio extra se coloca en el area del centro.
La clase BorderLayout posee los constructores:

110
public BorderLayout()
public BorderLayout(int hgap,int vgap)
Ejemplo:
import java.awt.*;
import java.applet.Applet;
public class BorderLayoutWin extends Applet {
public void init() {
setLayout(new BorderLayout(10,10));
add("North",new Label("Norte",Label.CENTER));
add("South",new Label("Sur",Label.CENTER));
add("East",new Label("Este",Label.CENTER) );
add("West",new Label("Oeste",Label.CENTER));
add("Center",new Label("Centro",Label.CENTER) );
}
public static void main(String args[]) {
Frame f = new Frame("BorderLayout");
BorderLayoutWin bl = new BorderLayoutWin();
bl.init();
f.add("Center", bl);
f.setSize(200,200);
f.setVisible(true);
}
}
Criterio CardLayout
Se utiliza la disposicion CardLayout cuando se tiene una zona que puede contener diferentes componentes en diferentes instantes.
Para a
nadir y mostrar una componente se utilizan los metodos:
add(String name, Component comp)
Con el primer argumento se identifica la componente que se esta a
nadiendo.
show(Container target, String name)
Para mostrar la componente correspondiente. El primer argumento es el contenedor que maneja
el CardLayout. El segundo identifica la componente a mostrar.
Algunos de los metodos definidos en la clase CardLayout son:
void first(Container target)
void last(Container target)
void next(Container target)

111
void previous(Container target)
Ejemplo:
import
import
import
public

java.awt.*;
java.awt.event.*;
java.applet.Applet;
class CardLayoutWin extends Applet
implements ItemListener {

Panel
final
final
final

cl;
String MES1 = "Panel1 con tres botones ";
String MES2 = "Panel2 con tres botones";
String MES3 = "Panel3 con tres botones";

public void init() {


setLayout(new GridLayout(0,1));
Panel panel = new Panel();
Choice choice = new Choice();
choice.addItem(MES1);
choice.addItem(MES2);
choice.addItem(MES3);
choice.setBackground(Color.white);
choice.addItemListener(this);
panel.add(choice);
add(panel);
cl = new Panel();
cl.setLayout(new CardLayout());
Panel panel1 = new Panel();
panel1.setLayout(new FlowLayout(FlowLayout.CENTER));
panel1.add(new Button("Button 1"));
panel1.add(new Button("Button 2"));
panel1.add(new Button("Button 3"));
Panel panel2 = new Panel();
panel1.setLayout(new GridLayout(0,1));
panel2.add(new Button("Button 1"));
panel2.add(new Button("Button 2"));
panel2.add(new Button("Button 3"));
Panel panel3 = new Panel();
panel3.setLayout(new BorderLayout());
panel3.add("North",new Button("Button 1"));
panel3.add("Center",new Button("Button 2"));
panel3.add("South",new Button("Button 3"));

112

cl.add(MES1, panel1);
cl.add(MES2, panel2);
cl.add(MES3, panel3);
add(cl);
}
public void itemStateChanged(ItemEvent evt){
String str;
if(evt.getStateChange()==ItemEvent.SELECTED){
str=(String)evt.getItem();
((CardLayout)cl.getLayout()).show(cl,str);
}
}
public static void main(String args[]) {
Frame f = new Frame("CardLayout");
CardLayoutWin cl = new CardLayoutWin();
cl.init();
f.add("Center", cl);
f.setSize(200,200);
f.setVisible(true);
}
}
Criterio FlowLayout
FlowLayout es el gestor de colocaci
on por defecto para los paneles (Panels). Coloca sus componentes
en una fila.
La clase FlowLayout tiene tres constructores:
public FlowLayout();
public FlowLayout(int alignment)
public FlowLayout(int alignment,
int horizontalGap, int verticalGap)
El argumento alignment puede tomar uno de estos valores:
1. FlowLayout.LEFT
2. FlowLayout.CENTER
3. FlowLayout.RIGHT.

113
Ejemplo:
import java.awt.*;
import java.applet.Applet;
public class FlowLayoutWin extends Applet {
public void init() {
setLayout(new FlowLayout());
add(new Label("Label1"));
add(new Label("Label2"));
add(new Label("Label3"));
add(new Label("Label4"));
add(new Label("Label5"));
add(new Label("Label6"));
}
public static void main(String args[]) {
Frame f = new Frame("FlowLayout");
FlowLayoutWin fl = new FlowLayoutWin();
fl.init();
f.add("Center", fl);
f.setSize(300,100);
f.setVisible(true);
}
}
Criterio GridLayout
La clase GridLayout coloca sus componentes en una rejilla de celdas.
Los constructores de la clase GridLayout son:
GridLayout(int rows, int columns)
GridLayout(int rows, int columns,
int horizontalGap, int verticalGap)
Al menos, uno de los argumentos rows o columns debe ser distinto de cero.
Ejemplo:
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
public class GridLayoutWin extends Applet
implements ActionListener{
final int n=20;

114
Label lab;
public void init() {
Button[] b=new Button[n-1];
setLayout(new GridLayout(n/5,n/4));
for(int i=0;i<n-1;i++){
add(b[i]=new Button(" "+i));
b[i].addActionListener(this);
}
lab=new Label("Label",Label.CENTER);
add(lab);
}
public void actionPerformed(ActionEvent evt){
String arg=evt.getActionCommand();
lab.setText(arg);
}
public static void main(String args[]) {
Frame f = new Frame("GridLayout");
GridLayoutWin gl = new GridLayoutWin();
gl.init();
f.add("Center", gl);
f.setSize(200,200);
f.setVisible(true);
}
}

115

Paquete javax.swing
Java 2 proporciona un sustituto de Awt: Swing, un nuevo conjunto de clases. Permite:
seleccion mas amplia de objetos
apariencia mejorada
mayor control por parte del programador sobre el aspecto y funcionamiento de la interfaz.
Se incorporan todos los aspectos u
tiles de Awt. En algunos casos se han extendido las clases o
implementado interfases de Awt.
Swing forma parte de las cinco libreras que constituyen las JFC (Java Foundation Classes), que
facilitan la creacion de interfaces graficas de usuario (GUIs). Engloban las siguientes caractersticas:
Awt
Las componentes Swing
Eleccion de la apariencia de las componentes Swing.
Accesibilidad API: es posible obtener informacion de la interfaz.
Java 2DT M API: es posible incorporar graficos en dos dimensiones de elevada calidad, texto e
imagenes en aplicaciones y applets.
Se pueden implementar elementos que transfieren informacion entre aplicaciones Java y aplicaciones nativas.
En la direccion http://java.sun./products/jfc se pueden encontrar paquetes nuevos que pueden distribuirse separadamente. Incluso las componentes mas sencillas de Swing tienen mas caractersticas que
las que AWT puede ofrecer:
los botones y etiquetas pueden incluir imagenes
se pueden agregar o cambiar los bordes de casi todas las componentes Swing
se puede modificar el comportamiento y la apariencia de una componentes Swing
se puede obtener informacion de las componentes: una herramienta puede obtener el texto de una
etiqueta o de un boton
Los paquetes que engloban todas las clases referentes a Swing son los que comienzan por javax.swing.
Los mas usados son:
javax.swing: todas las componentes
javax.swing.event: los sucesos

116

Swing vs Awt
Ejemplo Awt
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class Boton extends Applet
implements ActionListener{
Button b;
public void init(){
b=new Button("Pulsar");
add(b);
b.addActionListener(this);
}
public void actionPerformed(ActionEvent e){
b.setLabel("OK");
}
}
Ejemplo Swing
//clase Container
import java.awt.*;
//clase ActionEvent
import java.awt.event.*;
//componentes de Swing y JApplet
import javax.swing.*;
public class JBoton extends JApplet
implements ActionListener{
JButton b;
public void init(){
Container contenedor=getContentPane();
contenedor.setLayout(new FlowLayout());
b=new JButton("Pulsar");
contenedor.add(b);
b.addActionListener(this);
}
public void actionPerformed(ActionEvent e){
b.setText("OK");
}
}
Principales diferencias:
Las componentes se importan del paquete javax.swing

117
Para cada elemento de Awt existe un equivalente en Swing. El nombre es el mismo precedido de
la letra J.
En Awt, los componentes se pueden colocar directamente sobre el applet, con el metodo add. En
Swing, el JApplet no act
ua como contenedor de sus componentes; contiene un objeto Container,
panel de contenido, en el cual se colocan todos los componentes del applet con el metodo add. Se
puede obtener referencia de dicho panel usando el metodo getContentPane de la clase JApplet.
La disposicion por defecto en el panel de contenido de un JApplet es la BorderLayout.
La superclase de los componentes de Swing es JComponent, que deriva de la clase Container de
Awt y, por tanto, de la clase Component de Awt.

Applets en Swing
Cualquier applet que contenga componentes Swing debe ser subclase de JApplet.
La clase JApplet es subclase de java.applet.Applet.
Caractersticas de los japplets:
proporcionan apoyo a otras tecnologas.
son contenedores Swing de alto nivel y, por tanto, tienen un panel raz, que permite agregar una
barra de men
us.
todo contenedor de alto nivel posee un panel de contenido:
los componentes se agregan al panel.
la disposicion de los componentes se fija en el panel.
la disposicion por defecto en el panel de contenido de un japplet es BorderLayout.
Funcionamiento:
Si el navegador reconoce las clases Swing, se puede usar una <APPLET> tag. En caso contrario,
es necesario un Java plug-in. Por lo que es necesario incluir un <OBJECT> o <EMBED> tag.
Se puede bajar una herramienta gratis que genera automaticamente los tags necesarios. Para obtenerla junto con el Plug-in:
http://java.sun.com/products/plugin/.
Requiere tiempo bajarse el Plug-in, por lo que es aconsejable avisar a los posibles usuarios de que
la pagina contiene un applet.
Metodos nuevos que incorpora la clase JApplet:
void setContentPane(Container c):Asigna la propiedad contentPane. Este metodo es llamado
por el constructor. constructor.
Container getContentPane():Devuelve el objeto contentPane para este applet.
JRootPane createRootPane():Es llamado por el constructor para crear el rootPane por defecto.
void setRootPane(JRootPane jrp):Asigna la propiedad rootPane.
JRootPane getRootPane():Devuelve el objeto rootPane para este applet.

118
u para este applet.
void setJMenuBar(JMenuBar jmb):Asigna la barra de men
u en este applet.
JMenuBar getJMenuBar(): Devuelve la barra de men

Contenedores y Componentes
Todos los elementos que configuran una interfaz grafica de usuario en Swing se pueden clasificar en:
contenedores superiores: applets, ventanas de dialogo y marcos.
contenedores intermedios: contenedores intermedios como paneles, paneles desplazables, paneles
divididos, barras de herramientas, paneles con solapas.
contenedores especiales: marcos internos, paneles raz, . . .
componentes basicos: botones, listas, campos de texto, men
us, . . .
informacion no editable: etiquetas, barras de estado, . . .
informacion formateada y editable: paletas de colores, seleccionadores de ficheros, tablas, texto,
arboles.
La clase JComponent
Excepto de los contenedores superiores, todos los demas elementos de Swing cuyo nombre comienza
con j descienden de la clase JComponent. Dicha clase es subclase de Container y , por tanto, de
Component.
Algunos de los metodos que incorpora JComponent son:
void setToolTipText(String text)
void setBorder(Border border)
void setPreferredSize(Dimension preferredSize)
void setMaximumSize(Dimension maximumSize)
void setMinimumSize(Dimension minimumSize)
void setAlignmentX(float alignmentX)
void setAlignmentY(float alignmentY)
void revalidate()
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class EjemploContenedores extends JApplet{
JButton boton;
JLabel etiqueta;

119
JPanel panel;
public void init(){
Container contenedor=getContentPane();
JPanel panel=new JPanel();
panel.setBorder(BorderFactory.createEmptyBorder(
30,//b. superior
30,//izqda
10,//b.inferior
30));//dcha
panel.setLayout(new GridLayout(0,1));
boton=new JButton("OK");
panel.add(boton);
etiqueta=new JLabel("Esto es una prueba");
panel.add(etiqueta);
contenedor.add(panel);
}
}
La jerarqua de todos los componentes involucrados es la siguiente:
contenedor superior: en nuestro caso es un applet (JApplet). Tambien contamos con las ventanas
de dialogo (JDialog) y los marcos (JFrame).
contenedor intermedio: en este ejemplo es un panel (JPanel). Permite simplificar la colocacion
de los componentes del applet. Otros contenedores intermedios son los paneles desplazables
(JScrollPane) y los paneles con solapas
(JTabbedPane).
componentes basicos: botones, etiquetas, . . .
Pero todo contenedor de alto nivel contiene un panel de contenido que alberga todos los componentes
visibles de la interfaz, salvo las barras de men
u.
Veamos a continuacion ejemplos ilustrativos de algunos contenedores.
Paneles divididos
Un objeto de la clase JSplitPane esta formado por dos componentes separados por una barra divisoria
que puede manipularse con el raton.
El procedimiento es colocar cada componente en un panel desplazable que, a su vez, se incluye en
el panel dividido.
Ejemplo:
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;

120
public class PanelDividido extends JApplet
implements ListSelectionListener{
private JLabel foto;
private JList lista;
private JSplitPane panel;
private String[] titulos=
{"foto1.gif","foto2.gif","foto3.gif"};
public void init(){
Container contenedor=getContentPane();
lista=new JList(titulos);
lista.setSelectionMode(
ListSelectionModel.SINGLE_SELECTION);
lista.setSelectedIndex(0);
lista.addListSelectionListener(this);
JScrollPane pd1=new JScrollPane(lista);
ImageIcon foto1=
new ImageIcon("Fotos/"+titulos[0]);
foto=new JLabel(foto1);
foto.setPreferredSize(
new Dimension(foto1.getIconWidth(),
foto1.getIconHeight()));
JScrollPane pd2=new JScrollPane(foto);
panel=
new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,pd1,pd2);
panel.setOneTouchExpandable(true);
panel.setDividerLocation(150);
Dimension tamMinimo=new Dimension(100,50);
pd1.setMinimumSize(tamMinimo);
pd2.setMinimumSize(tamMinimo);
panel.setPreferredSize(new Dimension(400,200));
contenedor.add(panel);
}
public void valueChanged(ListSelectionEvent e)
{
JList l=(JList)e.getSource();
if (l.isSelectionEmpty())
{

121
foto.setIcon(null);
}else
{
int indice=l.getSelectedIndex();
ImageIcon nuevaFoto=
new ImageIcon("Fotos/"+titulos[indice]);
foto.setIcon(nuevaFoto);
foto.setPreferredSize(
new Dimension(nuevaFoto.getIconWidth(),
nuevaFoto.getIconHeight()));
foto.revalidate();
}
}
}

Constructores:
public JSplitPane()
public JSplitPane(int newOrientation)
public JSplitPane(int newOrientation,boolean newContinuousLayout)
public JSplitPane(int newOrientation,Component newLeftComponent,
Component newRightComponent)
public JSplitPane(int i,boolean b,Component c1,
Component c2)
Los argumentos enteros pueden ser
JSplitPane.HORIZONTAL_SPLIT
y
JSplitPane.VERTICAL_SPLIT
Metodos
void setOrientation(int orientation)
void setDividerSize(int newSize)
void setOneTouchExpandable(boolean newValue)
void setTopComponent(Componentcomponent)
void setBottomComponent(Component component)
void setLeftComponent(Component component)

122
void setRightComponent(Component component)
void setDividerLocation(double
proportionalLocation)
void setDividerLocation(int location)
void resetToPreferredSize()

Componentes B
asicos
Men
us desplegables.
Los objetos de la clase JComboBox pueden ser editables o no editables. Por defecto son no editables.
Los editables tienen la apariencia de un campo de texto.
Ejemplo:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class EjemploComboB extends JApplet
implements ActionListener{
JLabel foto;
public void init(){
Container contenedor=getContentPane();
JPanel panel=new JPanel();
panel.setLayout(new BorderLayout());
String[] titulos=
{"foto1.gif","foto2.gif","foto3.gif"};
JComboBox lista=new JComboBox(titulos);
lista.setSelectedIndex(2);
lista.addActionListener(this);
ImageIcon fotoSelecc=new ImageIcon("Fotos/"+
titulos[lista.getSelectedIndex()]);
foto=new JLabel(fotoSelecc);
foto.setPreferredSize(
new Dimension(fotoSelecc.getIconWidth(),
fotoSelecc.getIconHeight()));
panel.add(lista,BorderLayout.NORTH);
panel.add(foto,BorderLayout.SOUTH);
panel.setBorder(
BorderFactory.createEmptyBorder(20,20,20,20));
contenedor.add(panel);

123
}
public void actionPerformed(ActionEvent e)
{
JComboBox c=(JComboBox)e.getSource();
String nombre=(String)c.getSelectedItem();
ImageIcon nuevaFoto=
new ImageIcon("Fotos/"+nombre);
foto.setIcon(nuevaFoto);
foto.setPreferredSize(
new Dimension(nuevaFoto.getIconWidth(),
nuevaFoto.getIconHeight()));
}
}
Constructores:
public JComboBox()
public JComboBox(ComboBoxModel aModel)
public JComboBox(Object[] items)
public JComboBox(Vector items)
Metodos:
void addItem(Object anObject)
void insertItemAt(Object anObject,int index)
void setEditable(boolean aFlag)
boolean isEditable()
Tablas
La claseJTable permite crear tablas de datos, editables opcionalmente.
Ejemplo:

import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
public class EjemploTabla extends JApplet {
private boolean DEBUG = true;
public void init() {
Object[][] datos = {

124
{"Maria", "Gonzalez",
"Gutierrez", new Integer(5),"Aprobado"},
{"Juan", "Gomez",
"Perez", new Integer(3), "Suspenso"},
{"Ana", "Garcia",
"Perez", new Integer(10), "Matricula"},
{"Pedro", "Diaz",
"Martinez", new Integer(7), "Notable"},
{"Miguel", "Gutierrez",
"Perez", new Integer(4), "Suspenso"}
};
String[] encab = {"Nombre",
"Primer Apellido",
"Segundo Apellido",
"Nota Examen",
"Nota Final"};
final JTable tabla = new JTable(datos, encab);
tabla.setPreferredScrollableViewportSize(
new Dimension(500, 70));
if (DEBUG) {
tabla.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
imprimirDatos(tabla);
}
});
}
JScrollPane pd = new JScrollPane(tabla);
getContentPane().add(pd, BorderLayout.CENTER);
}
private void imprimirDatos(JTable t) {
int numFilas = t.getRowCount();
int numCols = t.getColumnCount();
TableModel modelo= t.getModel();
System.out.println("Datos: ");
for (int i=0; i < numFilas; i++) {
System.out.print("
fila " + i + ":");
for (int j=0; j < numCols; j++) {
System.out.print(" " + modelo.getValueAt(i, j));
}
System.out.println();
}

125
System.out.println("-----");
}
}
Existen ciertas desventajas:
Cada celda es editable automaticamente.
Tratan todo tipo de datos de la misma forma.
Todos los datos deben almacenarse en un array o vector.
Constructores:
JTable()
JTable(int numRows,int numColumns)
JTable(Object[][] rowData,Object[] columnName)
JTable(Vector rowData,Vector columnNames)
Metodos:
void
setPreferredScrollableViewportSize(Dimension rowHeight)
void setMinWidth(int minWidth), (en TableColumn)
void setPreferredWidth(int preferredWidth), (en TableColumn)
void setMaxWidth(int maxWidth), (en TableColumn)
void setSelectionMode(int selectionMode). Los argumentos son
ListSelectionModel.SINGLE_SELECTION,
ListSelectionModel.SINGLE_INTERVAL_SELECTION,
ListSelectionModel.MULTIPLE_INTERVAL_SELECTION.
Componentes de texto
Existen cinco componentes de texto que proceden de la superclase JTextComponent:
JTextField
JPasswordField
JTextArea
JEditorPane
JTextPane

126
Ejemplo:

import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import java.io.IOException;
public class EjemploTexto extends JApplet
implements ActionListener {
private String newline = "\n";
protected static final String campoTextoString =
"JTextField";
protected static final String passwordString =
"JPasswordField";
protected JLabel accionEtiqueta;
public void init() {

JTextField campoTexto = new JTextField(10);


campoTexto.setActionCommand(campoTextoString);
campoTexto.addActionListener(this);

JPasswordField password = new JPasswordField(10);


password.setActionCommand(passwordString);
password.addActionListener(this);

JLabel campoTextoEtiqueta = new JLabel(


campoTextoString + ": ");
campoTextoEtiqueta.setLabelFor(campoTexto);
JLabel passwordEtiqueta= new JLabel(
passwordString + ": ");
passwordEtiqueta.setLabelFor(password);

accionEtiqueta =
new JLabel("Escribe y dale Return en un campo");
accionEtiqueta.setBorder(

127
BorderFactory.createEmptyBorder(10,0,0,0));

JPanel panel = new JPanel();


GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
panel.setLayout(gridbag);
JLabel[] etiquetas =
{campoTextoEtiqueta , passwordEtiqueta};
JTextField[] campos = {campoTexto , password};
ponerEtiquetas(etiquetas, campos, gridbag, panel);
c.gridwidth = GridBagConstraints.REMAINDER;
c.anchor = GridBagConstraints.WEST;
c.weightx = 1.0;
gridbag.setConstraints(accionEtiqueta, c);
panel.add(accionEtiqueta);
panel.setBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Campos de texto"),
BorderFactory.createEmptyBorder(5,5,5,5)));

JTextArea areaTexto = new JTextArea(


"Este es un area de texto editable" +
"que ha sido incializada con el metodo setText. ");
areaTexto.setFont(new Font("Serif", Font.ITALIC, 16));
areaTexto.setLineWrap(true);
areaTexto.setWrapStyleWord(true);
JScrollPane sp = new JScrollPane(areaTexto);
sp.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
sp.setPreferredSize(new Dimension(250, 250));
sp.setBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Plain Text"),
BorderFactory.createEmptyBorder(5,5,5,5)),
sp.getBorder()));

JEditorPane editorPane = crearEditorPane();


JScrollPane editorSP = new JScrollPane(editorPane);
editorSP.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

128
editorSP.setPreferredSize(new Dimension(250, 145));
editorSP.setMinimumSize(new Dimension(10, 10));

JTextPane textPane = crearTextPane();


JScrollPane paneSP = new JScrollPane(textPane);
paneSP.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
paneSP.setPreferredSize(new Dimension(250, 155));
paneSP.setMinimumSize(new Dimension(10, 10));

JSplitPane splitPane =
new JSplitPane(JSplitPane.VERTICAL_SPLIT,
editorSP,
paneSP);
splitPane.setOneTouchExpandable(true);
JPanel panelDcho = new JPanel();
panelDcho.add(splitPane);
panelDcho.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Texto formateado"),
BorderFactory.createEmptyBorder(5,5,5,5)));

JPanel panelIzq = new JPanel();


BoxLayout boxIzq =
new BoxLayout(panelIzq, BoxLayout.Y_AXIS);
panelIzq.setLayout(boxIzq);
panelIzq.add(panel);
panelIzq.add(sp);
Container contenedor = getContentPane();
BoxLayout box =
new BoxLayout(contenedor, BoxLayout.X_AXIS);
contenedor.setLayout(box);
contenedor.add(panelIzq);
contenedor.add(panelDcho);
}
private void ponerEtiquetas(JLabel[] e,
JTextField[] ct,
GridBagLayout gridbag,
Container cont) {
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.EAST;
int numEtiquetas = e.length;

129

for (int i = 0; i < numEtiquetas; i++) {


c.gridwidth = GridBagConstraints.RELATIVE;
c.fill = GridBagConstraints.NONE;
c.weightx = 0.0;
gridbag.setConstraints(e[i], c);
cont.add(e[i]);
c.gridwidth = GridBagConstraints.REMAINDER;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1.0;
gridbag.setConstraints(ct[i], c);
cont.add(ct[i]);
}
}
public void actionPerformed(ActionEvent e) {
String prefijo = "Has escrito\"";
if (e.getActionCommand().equals(campoTextoString)) {
JTextField source = (JTextField)e.getSource();
accionEtiqueta.
setText(prefijo+ source.getText() + "\"");
} else {
JPasswordField source =
(JPasswordField)e.getSource();
accionEtiqueta.
setText(prefijo +
new String(source.getPassword())
+ "\"");
}
}
private JEditorPane crearEditorPane() {
JEditorPane editorPane = new JEditorPane();
editorPane.setEditable(false);
String s = null;
try {
s = "file:"
+ System.getProperty("user.dir")
+ System.getProperty("file.separator")
+ "TextSamplerDemoHelp.html";
URL helpURL = new URL(s);
displayURL(helpURL, editorPane);
} catch (Exception e) {
System.err.println("Couldnt create help URL: "
+ s);
}

130

return editorPane;
}
private void displayURL(URL url, JEditorPane editorPane) {
try {
editorPane.setPage(url);
} catch (IOException e) {
System.err.println("Attempted to read a bad URL: " +
url);
}
}
private JTextPane crearTextPane() {
JTextPane textPane = new JTextPane();
String[] initString =
{ "Este es un JTextPane editable, ",
"otro ",
"componente ",
"formateado ",
"que puede incluir componentes.." + newline,
" " + newline,
"...e iconos..." + newline,
" ",
newline + "JTextPane es una subclase
de JEditorPane que " +
"usa un StyledEditorKit y
StyledDocument, y tiene " +
"metodos para actuar con esos objetos."
};
String[] initStyles =
{ "italic", "bold", "small", "large",
"regular", "button", "icon", "regular",
"regular"
};
initStylesForTextPane(textPane);
Document doc = textPane.getDocument();
try {
for (int i=0; i < initString.length; i++) {
doc.insertString(
doc.getLength(), initString[i],
textPane.getStyle(initStyles[i]));
}

131
} catch (BadLocationException ble) {
System.err.println("Couldnt insert initial text.");
}
return textPane;
}
protected void initStylesForTextPane(JTextPane textPane) {
Style def = StyleContext.getDefaultStyleContext().
getStyle(StyleContext.DEFAULT_STYLE);
Style regular = textPane.addStyle("regular", def);
StyleConstants.setFontFamily(def, "SansSerif");
Style s = textPane.addStyle("italic", regular);
StyleConstants.setItalic(s, true);
s = textPane.addStyle("bold", regular);
StyleConstants.setBold(s, true);
s = textPane.addStyle("small", regular);
StyleConstants.setFontSize(s, 10);
s = textPane.addStyle("large", regular);
StyleConstants.setFontSize(s, 16);
s = textPane.addStyle("icon", regular);
StyleConstants.setAlignment(s,
StyleConstants.ALIGN_CENTER);
StyleConstants.setIcon(s,
new ImageIcon("Imagenes/Pig.gif"));
s = textPane.addStyle("button", regular);
StyleConstants.setAlignment(s,
StyleConstants.ALIGN_CENTER);
JButton button = new JButton(
new ImageIcon("Imagenes/sound.gif"));
button.setMargin(new Insets(0,0,0,0));
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Toolkit.getDefaultToolkit().beep();
}
});
StyleConstants.setComponent(s, button);
}
}

132
Metodos de la clase JTextComponent:
void setDisabledTextColor(Color c)
void setMargin(Insets m)
void setEditable(boolean b)
String getSelectedText()
void selectAll()
void select(int selectionStart,
int selectionEnd)
void setSelectedTextColor(Color c)
void setSelectionColor(Color c)
void cut()
void copy()
void paste()
Ayuda
Se puede crear un peque
no men
u de ayuda para cualquier objeto de la clase JComponent
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class EjemploAyuda extends JApplet{
final static String BOTONES="Panel con botones";
final static String CAMPO=
"Panel con campo de texto";
public void init(){
Container contenedor=getContentPane();
JTabbedPane panel=new JTabbedPane();
JPanel p1=new JPanel();
p1.add(new JButton("Boton 1"));
p1.add(new JButton("Boton 2"));
p1.add(new JButton("Boton 3"));
panel.addTab(BOTONES,
new ImageIcon("Imagenes/left.gif"),
p1,"Aparecen tres botones");
JPanel p2=new JPanel();
JTextField campo=
new JTextField("Campo de texto",20);
campo.setToolTipText("Escribe lo que quieras
en este campo de texto");
p2.add(campo);
panel.addTab(CAMPO,

133
new ImageIcon("Imagenes/right.gif"),
p2,"Aparece un campo de texto");
contenedor.add(panel,BorderLayout.CENTER);
}
}
Metodo de la clase JComponent:
void setToolTipText(String text)

Criterios de Colocaci
on
Todo contenedor posee un criterio de colocacion por defecto. Los cinco mas usados son: BorderLayout,
BoxLayout, FlowLayout, GridBagLayout y GridLayout.
BorderLayout: es la disposicion por defecto de todo panel de contenido, (el contenedor principal
de los marcos, applets y ventanas de dialogo). Se dispone de cinco areas: norte, sur, este, oeste y
centro. El espacio extra ocupa el centro del area.
BoxLayout: coloca los componentes en una sola fila o columna. Respeta las medidas maximas
requeridas de los componentes y permite alinearlos.
FlowLayout: es la disposicion por defecto de los jpaneles. Coloca los componentes uno detras
de otro, de izquierda a derecha.
GridLayout: agrupa los componentes (todos de igual dimension) en filas y columnas.
GridBagLayout: agrupa los componentes en una red de celdas, permitiendo que tengan diferentes dimensiones.
Si queremos modificar la disposicion por defecto de un contenedor, debemos llamar a su metodo
setLayout. Por ejemplo, si queremos modificar la disposicion por defecto de un panel:
JPanel panel=new JPanel();
panel.setLayout(new BorderLayout());
Podemos optar por prescindir de los criterios. En ese caso debemos especificar las dimensiones y
la posicion de cada componente dentro del contenedor. Pero puede haber problemas al reajustar el
contenedor.
BorderLayout
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class JBotonesbl extends JApplet{
JButton b1, b2, b3, b4, b5;

134
public void init(){
Container contenedor=getContentPane();
b1=new JButton("Norte");
contenedor.add(b1,BorderLayout.NORTH);
b2=new JButton("Sur");
contenedor.add(b2,BorderLayout.SOUTH);
b3=new JButton("Este");
contenedor.add(b3,BorderLayout.EAST);
b4=new JButton("Oeste");
contenedor.add(b4,BorderLayout.WEST);
b5=new JButton("Centro");
contenedor.add(b5,BorderLayout.CENTER);
}
}
BoxLayout
Se agrupan los componentes uno sobre otro, comenzando en la parte superior de la ventana, o en
fila, de izquierda a derecha.
A diferencia del resto de disposiciones de Awt, la BoxLayout respeta el tama
no maximo y la alineacion de cada componente.
Constructor:
public BoxLayout(Container,int)
Metodos:
Component createRigidArea(Dimension)
Component createHorizontalGlue()
Component createVerticalGlue
Ejemplo:
import java.awt.*; import javax.swing.*;
public class JBotonesboxl extends JApplet{
JButton b1, b2, b3, b4;
public void init(){
Container contenedor=getContentPane();
contenedor.setLayout(
new BoxLayout(contenedor,BoxLayout.Y_AXIS));
b1=new JButton("Boton1");
//setAlignment de JComponent
b1.setAlignmentX(Component.CENTER_ALIGNMENT);
contenedor.add(b1);
b2=new JButton("2");
b2.setAlignmentX(Component.CENTER_ALIGNMENT);
contenedor.add(b2);

135
b3=new JButton("El boton mas grande");
b3.setAlignmentX(Component.CENTER_ALIGNMENT);
contenedor.add(b3);
b4=new JButton("4");
b4.setAlignmentX(Component.CENTER_ALIGNMENT);
contenedor.add(b4);
}}
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class JBotonesboxl2 extends JApplet{
JButton b1, b2;
JPanel p1,p2;
JScrollPane sp;
JLabel etiqueta;
JList lista;
public void init(){
String[] paises={"Francia","Alemania",
"Irlanda","Espa~
na",
"Reino Unido","Francia","Portugal",
"Suecia","Austria",
"B
elgica","Luxemburgo","Holanda"};
Container contenedor=getContentPane();
p1=new JPanel();
p1.setLayout(new BoxLayout(p1,BoxLayout.Y_AXIS));
etiqueta=new JLabel("Paises de Europa:");
lista=new JList(paises);
sp=new JScrollPane(lista);
//Quedan alineados scroller y etiqueta
sp.setAlignmentX(LEFT_ALIGNMENT);
p1.add(etiqueta);
p1.add(Box.createRigidArea(new Dimension(0,5)));
p1.add(sp);
p1.setBorder(BorderFactory.
createEmptyBorder(10,10,10,10));
p2=new JPanel();
p2.setLayout(new BoxLayout(p2,BoxLayout.X_AXIS));
p2.setBorder(
BorderFactory.createEmptyBorder(0,10,10,10));
p2.add(Box.createHorizontalGlue());
b1=new JButton("Cancel");
p2.add(b1);

136
p2.add(Box.createRigidArea(new Dimension(10,0)));
b2=new JButton("OK");
p2.add(b2);
contenedor.add(p1,BorderLayout.CENTER);
contenedor.add(p2,BorderLayout.SOUTH);

//Para que aparezcan las barras


validate();
}
}
Separamos la etiqueta y el panel desplazable con un area rgida, que permite agregar espacio entre
componentes. En este caso, no tiene anchura y fija cinco pixels entre ambas componentes. De forma
analoga ocurre con los botones.
Para desplazar los botones a la derecha de su contenedor, la primera componente que se a
nade es lo
que se conoce como pegamento: una componente invisible que crece lo necesario para absorber cualquier
espacio extra en su contenedor.
Como alternativa a las componentes invisibles, se pueden usar bordes vacos para crear espacios
alrededor de las componentes.
Componentes invisibles
En una disposicion BoxLayout es conveniente a
nadir espacio entre las componentes. Una opcion es
insertar componentes invisibles, con la ayuda de la clase Box.
a
rea rgida: para insertar un espacio de tama
no fijo entre dos componentes. Para a
nadir 5 pixels
entre dos componentes dispuestas en horizontal:
contenedor.add(primeraComponente);
contenedor.add(Box.createRigidArea(new Dimension(5,0)));
contenedor.add(segundaComponente);

pegamento: para especificar que exceso de espacio debera desaparecer. Por ejemplo, para que en
una disposicion en horizontal el espacio extra dejado por dos componentes no quede a la derecha
si no en el centro:
contenedor.add(primeraComponente);
contenedor.add(Box.createHorizontalGlue());
contenedor.add(segundaComponente);

Problemas de alineaci
on

137
Un grupo de componentes con igual alineacion, pero es necesario modificarla.
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class Botones extends JApplet{
JButton b1, b2;
Icon imagen;
public void init(){
Container contenedor=getContentPane();
contenedor.setLayout(
new BoxLayout(contenedor,BoxLayout.X_AXIS));
b1=new JButton("OK");
contenedor.add(b1);
b2=
new JButton("Cancel",
new ImageIcon("figura.gif"));
contenedor.add(b2);
}
}
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class Botones extends JApplet
{
JButton b1, b2;
Icon imagen;
public void init(){
Container contenedor=getContentPane();
contenedor.setLayout(
new BoxLayout(contenedor,BoxLayout.X_AXIS));
b1=new JButton("OK");
b1.setAlignmentY(Component.BOTTOM_ALIGNMENT);
contenedor.add(b1);
b2=
new JButton("Cancel",
new ImageIcon("figura.gif"));

138
b2.setAlignmentY(Component.BOTTOM_ALIGNMENT);
contenedor.add(b2);
}
}
Dos o mas componentes dispuestas en BoxLayout tienen diferentes alineaciones por defecto. En
el siguiente ejemplo, el borde izquierdo de la etiqueta esta, por defecto, alineado con el centro del
panel.
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class PanelEtiqueta extends JApplet
{
JPanel p;
JLabel etiqueta;
public void init(){
Container contenedor=getContentPane();
contenedor.setLayout(
new BoxLayout(contenedor,BoxLayout.Y_AXIS));
etiqueta=new JLabel("Esto es una prueba");
contenedor.add(etiqueta);
p=new JPanel();
p.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(Color.red),
p.getBorder()));
contenedor.add(p);
}
}
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class PanelEtiqueta extends JApplet
{
JPanel p;
JLabel etiqueta;
public void init(){
Container contenedor=getContentPane();

139
contenedor.setLayout(
new BoxLayout(contenedor,BoxLayout.Y_AXIS));
etiqueta=new JLabel("Esto es una prueba");
contenedor.add(etiqueta);
p=new JPanel();
p.setBorder(BorderFactory.
createCompoundBorder(
BorderFactory.createLineBorder(Color.red),
p.getBorder()));
p.setAlignmentX(LEFT_ALIGNMENT);
contenedor.add(p);
}
}
Por defecto, la mayora de las componentes poseen alineacion en el centro para X e Y. Sin embargo, los
botones, combo boxes, etiquetas y opciones de men
u poseen para X la alineacion izquierda.
Especificar el tama
no de las componentes
En ocasiones, modificar la alineacion no resuelve nuestros problemas. Por ejemplo, si el contenedor
con disposicion Box Layout ocupa demasiado espacio, una o mas componentes posiblemente necesitan
restringir su tama
no maximo.
Para detectar problemas de este tipo es aconsejable:
agregar un borde a las componentes en cuestion. Esto permite apreciar que tama
no realmente
tienen:
componente.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(Color.red),
componente.getBorder()));

Usar el System.out.println para imprimir los tama


nos maximo, mnimo y preferible de las
componentes.
Estas dimensiones se pueden modificar de la siguiente forma:
componente.setMinimumSize(new Dimension(50,25));
componente.setPreferredSize(new Dimension(50,25));
componente.setMaximumSize(new Dimension(
Short.MAX_VALUE,Short.MAX_VALUE));

140

CardLayout
Permite manejar dos o mas componentes, (normalmente objetos de la clase JPanel) que comparten un
mismo espacio. Una opcion es usar un panel con solapas.
Ejemplo 1
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class EjemploCardL extends JApplet
implements ItemListener{
JPanel p;
final static String BOTONES="Panel con botones";
final static String CAMPO=
"Panel con campo de texto";
public void init(){
Container contenedor=getContentPane();
String opciones[]={BOTONES,CAMPO};
JPanel pc=new JPanel();
JComboBox cb=new JComboBox(opciones);
cb.setEditable(false);
cb.addItemListener(this);
pc.add(cb);
contenedor.add(pc,BorderLayout.NORTH);
p=new JPanel();
p.setLayout(new CardLayout());
JPanel p1=new JPanel();
p1.add(new JButton("Boton 1"));
p1.add(new JButton("Boton 2"));
p1.add(new JButton("Boton 3"));
JPanel p2=new JPanel();
p2.add(new JTextField("Campo de texto",20));
p.add(p1,BOTONES);
p.add(p2,CAMPO);
contenedor.add(p,BorderLayout.CENTER);
}
public void itemStateChanged(ItemEvent e){
CardLayout cl=(CardLayout)(p.getLayout());
cl.show(p,(String)e.getItem());

141
}
}
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class EjemploSolapas extends JApplet{
final static String BOTONES="Panel con botones";
final static String CAMPO=
"Panel con campo de texto";
public void init(){
Container contenedor=getContentPane();
JTabbedPane panel=new JTabbedPane();
JPanel p1=new JPanel();
p1.add(new JButton("Boton 1"));
p1.add(new JButton("Boton 2"));
p1.add(new JButton("Boton 3"));
panel.addTab(BOTONES,p1);
JPanel p2=new JPanel();
p2.add(new JTextField("Campo de texto",20));
panel.addTab(CAMPO,p2);
contenedor.add(panel,BorderLayout.CENTER);
}
}

FlowLayout
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class EjemploFL extends JApplet{
public void init(){
Container contenedor=getContentPane();
contenedor.setLayout(new FlowLayout());
contenedor.add(new JButton("Boton 1"));
contenedor.add(new JButton("2"));
contenedor.add(new JButton("El mas grande"));

142
}
}

GridLayout
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class EjemploGL extends JApplet{
public void init(){
Container contenedor=getContentPane();
contenedor.setLayout(new GridLayout(0,2));
contenedor.add(new
contenedor.add(new
contenedor.add(new
contenedor.add(new
contenedor.add(new

JButton("Boton 1"));
JButton("2"));
JButton("El mas grande"));
JButton("4"));
JButton("Boton 5"));

}
}

GridBagLayout
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class EjemploGBL extends JApplet{
public void init(){
Container contenedor=getContentPane();
GridBagLayout gridbag=new GridBagLayout();
GridBagConstraints c=new GridBagConstraints();
contenedor.setLayout(gridbag);
//c.fill=GridBagConstraints.BOTH;
//c.weightx=1.0;
colocaBoton("Boton 1",gridbag,c,contenedor);
colocaBoton("Boton 2",gridbag,c,contenedor);
//c.gridx=0;
colocaBoton("Boton 3",gridbag,c,contenedor);
//c.gridx=GridBagConstraints.RELATIVE;

143
c.gridwidth=GridBagConstraints.REMAINDER;
colocaBoton("Boton 4",gridbag,c,contenedor);
//c.weightx=0.0;
colocaBoton("Boton 5",gridbag,c,contenedor);
c.gridwidth=GridBagConstraints.RELATIVE;
colocaBoton("Boton 6",gridbag,c,contenedor);
c.gridwidth=GridBagConstraints.REMAINDER;
colocaBoton("Boton 7",gridbag,c,contenedor);
c.gridwidth=1;
c.gridheight=2;
//c.weighty=1.0;
colocaBoton("Boton 8",gridbag,c,contenedor);
//c.weighty=0.0;
c.gridwidth=GridBagConstraints.REMAINDER;
c.gridheight=1;
colocaBoton("Boton 9",gridbag,c,contenedor);
colocaBoton("Boton 10",gridbag,c,contenedor);
}
public void colocaBoton(String nombre,
GridBagLayout gridbag,GridBagConstraints c,
Container
contenedor){
JButton boton=new JButton(nombre);
gridbag.setConstraints(boton,c);
contenedor.add(boton);
}
}

Acciones
Si dos o mas componentes realizan la misma accion, es conveniente usar un objeto de la interfase Action
del paquete
javax.swing, que extiende ActionListener. Esta interfase centraliza el manejo de texto, iconos y
botones de barras de herramientas y men
us.
El primer ejemplo muestra la forma tradicional de implementar una interfaz formada por un area
de texto, una barra de men
us y una barra de botones. La accion de seleccionar una opcion del primer
men
u o pulsar un boton de la barra se ve reflejada en el area de texto. Seleciconar una opcion del
segundo men
u activa o desactiva un boton o una opcion del primer men
u.
El segundo ejemplo utiliza la interfase Action para centralizar la gestion de la accion pulsar o
seleccionar opcion o boton.
Ejemplo:
import javax.swing.*;

144
import java.awt.*;
import java.awt.event.*;
public class EjemploAccionPre extends JApplet{
protected JTextArea areaTexto;
protected JMenuItem m11,m12,m13;
protected JButton b1,b2,b3;
public void init(){
Container contenedor=getContentPane();
JToolBar barra=new JToolBar();
b1=new JButton(new ImageIcon("izquierda.gif"));
b2=new JButton(new ImageIcon("centro.gif"));
b3=new JButton(new ImageIcon("derecha.gif"));
b1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
areaTexto.append(
"AccionEvent en: "
+ "primer boton"
+ "\n"
+ " Event source: " + e.getSource()
+ "\n");
}
});
b2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
areaTexto.append(
"AccionEvent en: "
+ "segundo boton"
+ "\n"
+ " Event source: " + e.getSource()
+ "\n");
}
});
b3.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
areaTexto.append(
"AccionEvent en: "
+ "tercer boton"
+ "\n"
+ " Event source: " + e.getSource()
+ "\n");
}
});
barra.add(b1);
barra.add(b2);
barra.add(b3);

145

JMenuBar mb=new JMenuBar();


JMenu menuPrincipal=new JMenu("Menu");
JMenu estado=new JMenu("Estado");
m11=new JMenuItem("Ir a la izquierda");
m12=new JMenuItem("Hacer algo");
m13=new JMenuItem("Ir a la derecha");
m11.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
areaTexto.append(
"AccionEvent en: "
+ "primera opcion"
+ "\n"
+ " Event source: " + e.getSource()
+ "\n");
}
});
m12.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
areaTexto.append(
"AccionEvent en: "
+ "segunda opcion"
+ "\n"
+ " Event source: " + e.getSource()
+ "\n");
}
});
m13.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
areaTexto.append(
"AccionEvent en: "
+ "tercera opcion"
+ "\n"
+ " Event source: " + e.getSource()
+ "\n");
}
});
menuPrincipal.add(m11);
menuPrincipal.add(m12);
menuPrincipal.add(m13);
JCheckBoxMenuItem m21=
new JCheckBoxMenuItem("Primera accion");
m21.setSelected(true);
JCheckBoxMenuItem m22=

146
new JCheckBoxMenuItem("Segunda accion");
m22.setSelected(true);
JCheckBoxMenuItem m23=
new JCheckBoxMenuItem("Tercera accion");
m23.setSelected(true);

m21.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent e){
boolean seleccionado=(e.getStateChange()==
ItemEvent.SELECTED);
m11.setEnabled(seleccionado);
b1.setEnabled(seleccionado);
}
});
m22.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent e){
boolean seleccionado=(e.getStateChange()==
ItemEvent.SELECTED);
m12.setEnabled(seleccionado);
b2.setEnabled(seleccionado);
}
});
m23.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent e){
boolean seleccionado=(e.getStateChange()==
ItemEvent.SELECTED);
m13.setEnabled(seleccionado);
b3.setEnabled(seleccionado);
}
});
estado.add(m21);
estado.add(m22);
estado.add(m23);
mb.add(menuPrincipal);
mb.add(estado);
setJMenuBar(mb);
areaTexto=new JTextArea(5,30);
JScrollPane panelDespl=
new JScrollPane(areaTexto);
contenedor.add(barra,BorderLayout.SOUTH);
contenedor.add(panelDespl,BorderLayout.CENTER);
validate();

147
}
}
Ejemplo:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class EjemploAccionPost extends JApplet{

protected JTextArea areaTexto;


protected Action accIzqu,accCentr,accDcha;
public void init(){
Container contenedor=getContentPane();
JToolBar barra=new JToolBar();
JMenu menuPrincipal=new JMenu("Menu");
JButton boton;
JMenuItem m;

accIzqu=new AbstractAction("Ir a la izquierda",


new ImageIcon("izquierda.gif"))
{
public void actionPerformed(ActionEvent e)
{
areaTexto.append(
"AccionEvent en: "
+ "primer boton/item"
+ "\n"
+ " Event source: " + e.getSource()
+ "\n");
}
};
boton=barra.add(accIzqu);
boton.setText("");
m=menuPrincipal.add(accIzqu);
m.setIcon(null);
accCentr=new AbstractAction("Hacer algo",
new ImageIcon("centro.gif"))
{
public void actionPerformed(ActionEvent e)
{
areaTexto.append(
"AccionEvent en: "

148
+
+
+
+

"segundo boton/item"
"\n"
" Event source: " + e.getSource()
"\n");

}
};
boton=barra.add(accCentr);
boton.setText("");
m=menuPrincipal.add(accCentr);
m.setIcon(null);
accDcha=new AbstractAction("Ir a la derecha",
new ImageIcon("derecha.gif"))
{
public void actionPerformed(ActionEvent e)
{
areaTexto.append(
"AccionEvent en: "
+ "tercer boton/item"
+ "\n"
+ " Event source: " + e.getSource()
+ "\n");
}
};
boton=barra.add(accDcha);
boton.setText("");
m=menuPrincipal.add(accDcha);
m.setIcon(null);
areaTexto=new JTextArea(5,30);
JScrollPane panelDespl=new JScrollPane(areaTexto);
contenedor.add(barra,BorderLayout.SOUTH);
contenedor.add(panelDespl,BorderLayout.CENTER);
JMenuBar mb=new JMenuBar();
mb.add(menuPrincipal);
mb.add(crearMenu());
setJMenuBar(mb);
validate();
}
protected JMenu crearMenu()
{
JMenu estado=new JMenu("Estado");
JCheckBoxMenuItem mi;

149
mi=new JCheckBoxMenuItem("Primera accion");
mi.setSelected(true);
mi.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent e){
JCheckBoxMenuItem mii=
(JCheckBoxMenuItem)(e.getSource());
boolean seleccionado=(e.getStateChange()==
ItemEvent.SELECTED);
accIzqu.setEnabled(seleccionado);
}
});
estado.add(mi);
mi=new JCheckBoxMenuItem("Segunda accion");
mi.setSelected(true);
mi.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent e){
JCheckBoxMenuItem mii=
(JCheckBoxMenuItem)(e.getSource());
boolean seleccionado=(e.getStateChange()==
ItemEvent.SELECTED);
accCentr.setEnabled(seleccionado);
}
});
estado.add(mi);
mi=new JCheckBoxMenuItem("Tercera accion");
mi.setSelected(true);
mi.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent e){
JCheckBoxMenuItem mii=
(JCheckBoxMenuItem)(e.getSource());
boolean seleccionado=(e.getStateChange()==
ItemEvent.SELECTED);
accDcha.setEnabled(seleccionado);
}
});
estado.add(mi);
return estado;
}
}

Bordes
Cualquier objeto de la clase JComponent puede tener uno o mas bordes.

150
Se utiliza el metodo setBorder y la clase BorderFactory, que devuelve objetos de la interfase
Border del paquete
javax.swing.border.
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class Bordes1 extends JApplet{
JTextArea areaTexto;
JScrollPane pd;
JLabel titulo;
JPanel p1,p2;
public void init(){
Container contenedor=getContentPane();
p1=new JPanel();
titulo=new JLabel("Escribe lo que quieras:");
titulo.setBorder(
BorderFactory.createLineBorder(Color.red));
p1.add(titulo);
p2=new JPanel();
areaTexto=new JTextArea(5,30);
pd=new JScrollPane(areaTexto,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
p2.add(pd);
contenedor.add(p1,BorderLayout.NORTH);
contenedor.add(p2,BorderLayout.CENTER);
validate();
}}
Podemos implementar nuestros propios bordes. Deberemos crear una subclase de AbstractBorder
e jmplementar los metodos paintBorder y getBorderInsets.
Tambien es posible a
nadir un borde adicional alrededor de una componente ya enmarcada. Por
ejemplo, crear espacio extra alrededor de una componente.
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class Bordes2 extends JApplet{
JTextArea areaTexto;
JScrollPane pd;
JLabel titulo;
JPanel p1,p2;
public void init(){
Container contenedor=getContentPane();
p1=new JPanel();

151
titulo=new JLabel(
"
Escribe lo que quieras:
");
titulo.setBorder(
BorderFactory.createLineBorder(Color.red));
p1.add(titulo);
p2=new JPanel();
areaTexto=new JTextArea(5,30);
pd=new JScrollPane(areaTexto,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
pd.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(40,0,0,0),
pd.getBorder()));
p2.add(pd);
contenedor.add(p1,BorderLayout.NORTH);
contenedor.add(p2,BorderLayout.CENTER);
validate();}}
Metodos:
Border createLineBorder(Color color)
Border createLineBorder(Color color,
int thickness)
Border createEtchedBorder()
Border createEtchedBorder(Color highlight,
Color shadow)
Border createLoweredBevelBorder()
Border createRaisedBevelBorder()
Border createEmptyBorder()
Border createEmptyBorder(int top,int left,
int bottom,int right)
MatteBorder createMatteBorder(int top,int left,
int bottom,int right,Color color)
MatteBorder createMatteBorder(int top,int left,
int bottom,int right,Icon titleIcon)
TitledBorder createTitledBorder(String title)
TitledBorder createTitledBorder(Border border)
TitledBorder createTitledBorder(Border border,
String title)
TitledBorder createTitledBorder(Border border,
String title,int titleJustification,
int titlePosition)

152
TitledBorder createTitledBorder(Border border,
String title,
int titleJustification,int titlePosition,Font titleFont)
TitledBorder createTitledBorder(Border border,
String title,
int titleJustification,int titlePosition,Font titleFont,Color titleColor)
CompoundBorder createCompoundBorder(Border
outsideBorder,Border insiderBorder)

Elecci
on del Aspecto
Se puede elegir el aspecto que queremos que tenga nuestra interfaz. Para ello, usaremos el metodo
UIManager.setLookAndFeel.
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class JBotonAspJava extends JApplet{
public void init(){
try
{
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
}catch(Exception e){}
Container contenido=getContentPane();
contenido.setLayout(new FlowLayout());
contenido.add(new JButton("Boton 1"));
contenido.add(new JButton("2"));
contenido.add(new JButton("El mas grande"));
}
}
Los argumentos de setLookAndFeel pueden ser:
UIManager.getCrossPlatformLookAndFeelClassName(): el aspecto Java.
UIManager.getSystemLookAndFeelClassName(): el aspecto del entorno de trabajo.
javax.swing.plaf.metal.MetalLookAndFeel: el aspecto Java.
com.sun.java.swing.plaf.windows.WindowsLookAndFeel: el aspecto Windows.
javax.swing.plaf.mac.MacLookAndFeel: el aspecto Mac.
Es posible modificar el aspecto de la interfaz una vez que se ha hecho visible.
Es necesario el metodo
SwingUtilities.updateComponentTreeUI.
Ejemplo:

153
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class BotonAsp extends JApplet
implements ActionListener{
JButton b;
public void init(){
Container contenido=getContentPane();
contenido.setLayout(new FlowLayout());
b=new JButton("Pulsar");
contenido.add(b);
b.addActionListener(this);
}
public void actionPerformed(ActionEvent e){
b.setText("OK");
try
{
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
}catch(Exception exc){}
SwingUtilities.updateComponentTreeUI(b);
}
}

154
Interfase

M
etodos

Par
ametro

ActionListener

actionPerformed

CaretListener

caretUpdate

ChangeListener

stateChanged

ActionEvent
getActionCommand
getModifiers
CaretEvent
getDot
getMark
ChangeEvent

ComponentListener

componentMoved
componentHidden
componentResized
componentAdded
componentRemoved

ContainerListener

DocumentListener

changedUpdate
insertUpdate
removeUpdate

InternalFrameListener

internalFrameOpened
internalFrameClosing
internalFrameClosed
internalFrameIconified
internalFrameDeiconified
internalFrameActivated
internalFrameDeactivated
itemStateChanged

ItemListener

ListDataListener

ListSelectionListener

FocusListener
KeyListener

intervalAdded
intervalRemoved
contentsChanged
valueChanged

focusGained
focusLost
keyPressed
keyReleased
keyTyped

MouseListener

mousePressed
mouseReleased
mouseEntered
mouseExited
mouseClicked

MouseMotionListener

mouseDragged
mouseMoved
windowClosing
windowOpened
windowIconified
windowDeiconified
windowClosed
windowActivated

WindowListener

ComponentEvent
getComponent

Sucesos
generados por
JButton
JMenuItem
JTextField
JTextComponent

JSlider
JColorChooser
JComponent

ContainerEvent
getChild
getContainer
DocumentEvent
getDocument
getLength
getOffset
getChange
getType
InternalFrameEvent

Container

ItemEvent
getItem
getItemSelectable
getStateChange
ListDataEvent
getIndex0
getIndex1
ListSelectionEvent
getFirstIndex
getLastIndex
getValueIsAdjusting
FocusEvent
IsTemporary
KeyEvent
getKeyChar
getKeyCode
getKeyModifiersText
getKeyText
IsActionKey
MouseEvent
getClickCount
getX
getY
getPoint
TranslatePoint
IsPopupTrigger

JCheckBox
JCheckBoxMenuItem
JComboBox

JTextComponent (documento)

JInternalFrame

JList (contenidos)

JList
JTable

JComponent
JComponent

JComponent

JComponent
WindowEvent
getWindow

JFrame
JDialog


GRAFICOS
EN JAVA

156

Gr
aficos en Java
Dentro del paquete java.awt se encuentra definida la clase Graphics, que incorpora al lenguaje
Java la posibilidad de a
nadir elementos graficos.
Principios basicos

Al iniciar la ejecucion del programa, el sistema se encarga de visualizar graficamente todas las
componentes de su interfase.
Existen motivos que exigen una regeneracion de esa interfase.
La regeneracion se produce seg
un un orden jerarquico, comenzando con la componente de jerarqua
mas alta que necesita ser regenerada.
El AWT es el encargado de toda la gestion del proceso.
Una llamada al metodo repaint() de una componente obliga a su regeneracion.
La manera mas simple de dibujar una componente es insertar el codigo de dibujo en su metodo
paint().
El metodo paint() recibe como u
nico argumento un objeto de tipo Graphics (contexto grafico).
Estos objetos soportan dos tipos de procesos de dibujo:
Primitivas graficas (lneas, rectangulos, texto, etc.)
Imagenes
Cada componente tiene su propio sistema de coordenadas referidas a la esquina superior izquierda
de su area de dibujo.
Para las operaciones graficas sobre una componente se tiene en cuenta su sistema de coordenadas.

Primitivas Gr
aficas
La clase Graphics es una clase abstracta que dispone de metodos para dibujar lneas, rectangulos,
rectangulos redondeados, ovalos, arcos, polgonos, texto...
Lneas
public abstract void
drawLine (int x1, int y1, int x2, int y2)
Dibuja una lnea desde el punto de coordenadas (x1,y1) al punto de coordenadas (x2,y2).
Rect
angulos
public abstract void
drawRect (int x, int y, int ancho, int alto)

157
Dibuja un rectangulo cuya esquina superior izquierda esta en el punto de coordenadas (x,y)
con las dimensiones en puntos especificadas.
public abstract void
drawRoundRect (int x, int y, int ancho,
int alto, int dh, int dv)
Dibuja un rectangulo de esquinas redondeadas, siendo dh y dv los diametros horizontal y
vertical respectivamente de los arcos de las cuatro esquinas.
Ejemplo:
import java.awt.*;
import java.applet.*;
public class dibujarGraficos extends Applet{
public void paint(Graphics g){
g.drawLine(0,0,160,80);
g.drawRect(0,0,50,50);
g.drawRoundRect(20,20,40,40,15,15);
g.drawRoundRect(60,60,80,80,80,80);
}
}

public void
draw3DRect (int x, int y, int ancho,
int alto, boolean elev)
Dibuja un rectangulo con el efecto de estar elevado o hundido, si el valor del parametro elev
es true o false respectivamente.
public abstract void
fillRect (int x, int y, int ancho, int alto)
Dibuja un rectangulo relleno del color vigente.
public abstract void
fillRoundRect (int x, int y, int ancho,
int alto, int dh, int dv)
Dibuja un rectangulo de esquinas redondeadas con relleno.
public void
fill3DRect (int x, int y, int ancho,
int alto, boolean elev)
Dibuja un rectangulo elevado o hundido y con relleno.

158

public abstract void


clearRect (int x, int y, int ancho, int alto)
Borra el area especificada por el rectangulo, rellenandola con el color del fondo de la componente.

Ovalos
public abstract void
drawOval (int x, int y, int ancho, int alto)
Dibuja un crculo o elipse inscrita en un rectangulo.
public abstract void
fillOval (int x, int y, int ancho, int alto)
Dibuja un crculo o elipse rellena con el color vigente.
Arcos
public abstract void
drawArc (int x, int y, int ancho, int alto,
int ang1, int ang2)
Dibuja un arco elptico o circular con centro en un rectangulo. Los parametros ang1 y ang2
indican los angulos (en grados) de comienzo y final del arco respectivamente.
public abstract void
fillArc (int x, int y, int ancho, int alto,
int ang1, int ang2)
Dibuja un sector elptico o circular relleno con el color vigente.
Polgonos
public abstract void
drawPolygon (int x[], int y[], int n)
Dibuja un polgono cerrado uniendo los n puntos cuyas coordenadas son (x[i],y[i]).
public void drawPolygon (Polygon p)
Dibuja un polgono especificado por el argumento de tipo Polygon.
public abstract void
fillPolygon (int x[], int y[], int n)
Dibuja un polgono cerrado con relleno.

159

public void fillPolygon (Polygon p)


Dibuja el polgono con relleno.
Ejemplo:
import java.applet.*;
import java.awt.*;
public class dibujarPoligono extends Applet{
int
int
int
int
int
int

polyg1_x[]={40,80,0,40};
polyg1_y[]={5,45,45,5};
polyg2_x[]={140,180,180,140,100,100,140};
polyg2_y[]={5,25,45,65,45,25,5};
polyg3_x[]={240,260,220,260,220,240};
polyg3_y[]={5,65,85,25,25,5};

public void paint(Graphics g){


g.drawPolygon(polyg1_x,polyg1_y,
polyg1_x.length);
g.drawPolygon(polyg2_x,polyg2_y,
polyg2_x.length);
g.drawPolygon(polyg3_x,polyg3_y,
polyg3_x.length);
}
}

Texto como entidad grafica


El punto de posicionamiento del texto es el de inicio de la lnea de base sobre la que se apoya.
public void
drawBytes (byte datos[], int offset, int l,
int x, int y)
Dibuja el texto dado en la matriz de bytes con el tipo y color vigente en la posicion dada
por el punto (x,y). El parametro l indica el n
umero de caracteres a dibujar y offset es el
ndice de la matriz correspondiente al primer caracter a dibujar.
public void
drawChars (char datos[], int offset, int l,
int x, int y)
Dibuja el texto dado como matriz de caracteres.

160

public abstract void


drawString (String str, int x, int y)
Dibuja la cadena str en la posicion (x,y).
Metodos para gestionar los tipos de letra y aspectos metricos del texto:
public abstract Font getFont ()
Devuelve un objeto de la clase Font con la informacion del tipo de letra vigente en el contexto
grafico.
public FontMetrics getFontMetrics ()
Devuelve un objeto de la clase FontMetrics con la informacion de tipo metrico del tipo de
letra vigente del contexto grafico.
public abstract FontMetrics
getFontMetrics (Font f)
Devuelve un objeto de la clase FontMetrics con la informacion del tipo de fuente especificado en el parametro f.
public abstract void setFont (Font f)
Establece el tipo de letra para el contexto grafico.
Ejemplo:
import java.awt.*;
import java.applet.*;
public class dibujarTexto extends Applet{
String texto2=new String("Argentina 2001");
char[] texto1={C,U,R,S,O, ,
J,A,V,A};
public void paint(Graphics g){
g.drawChars(texto1,0,texto1.length,0,25);
g.drawString(texto2,0,50);
g.drawString("Corrientes"+" Misiones",0,70);
}
}

Otros M
etodos de la Clase Graphics
public abstract void
clipRect (int x, int y, int ancho, int alto)

161
Todas las operaciones graficas que se realicen sobre un contexto grafico u
nicamente tienen
efecto si quedan dentro de una cierta region rectangular. Este metodo permite establecer
esta region.
public abstract Rectangle getClipBounds()
Devuelve la region de dibujo del contexto grafico.
public abstract void
copyArea (int x, int y, int ancho,
int alto, int dx, int dy)
Efect
ua una copia del area rectangular. El vector de desplazamiento del area es (dx,dy).
public abstract Graphics create ()
Devuelve una copia del contexto grafico.
public Graphics create (int x, int y,
int ancho, int alto)
Crea un nuevo contexto grafico identico al actual salvo en los siguientes aspectos: el origen
del nuevo contexto grafico pasa a ser el punto (x,y) del actual y se establece una region de
dibujo adicional a partir del origen con las dimensiones dadas.
public abstract void dispose ()
Libera la memoria reservada por el contexto grafico.
public void finalize ()
Efect
ua la llamada al metodo dispose() cuando el contexto grafico no vuelve a ser utilizado.
public abstract Color getColor ()
Devuelve un objeto de la clase Color con el color vigente en el contexto grafico.
public abstract void setColor (Color c)
Establece un color para el contexto grafico.
public abstract void setPaintMode ()
Establece el modo de pintura para el contexto grafico.
public abstract void setXORMode (Color c)
A partir de ese momento, cuando se realice una operacion grafica, los puntos que se encuentren en el color actual del contexto cambiaran al color c y viceversa.

162

public string toString ()


Devuelve una representacion del contexto grafico en forma de cadena de caracteres.
public abstract void translate (int x, int y)
Traslada el origen de coordenadas al punto (x,y).
Ejemplo:
import java.awt.*;
import java.applet.*;
public class dibujarTexto extends Applet{
String texto2=new String("Argentina 2001");
char[] texto1={C,U,R,S,O, ,
J,A,V,A};
public void paint(Graphics g){
g.setColor(Color.red);
g.drawChars(texto1,0,texto1.length,0,25);
g.setColor(Color.black);
g.drawString(texto2,0,50);
g.setColor(Color.blue);
g.drawString("Corrientes "+ " Misiones ",0,70);
}
}

Ejemplo de Utilizaci
on de
Primitivas Gr
aficas
import java.awt.*;
import java.applet.Applet;
public class Estadio extends Applet {
public void init() {
validate();
}
public void paint(Graphics g) {
int ancho, alto;
Dimension d = getSize();
ancho=d.width-40;
alto=d.height-40;

163

g.fillRect(20,0,ancho,5);
g.drawString("ESTADIO JAVA",ancho/2-10,17);
g.translate(20,20);
g.drawRect(0, 0, ancho, alto);
g.drawLine(ancho/2, 0, ancho/2, alto);
g.fillOval(ancho/2-2, alto/2-2, 4, 4);
g.drawOval(ancho/2-alto/6, alto/3, alto/3,
alto/3);
g.drawRect(0, alto/4, ancho/6, alto/2);
g.drawRect(0, 2*alto/5, ancho/15, alto/5);
g.drawArc(ancho/6-alto/10,2*alto/5,alto/5,
alto/5,-90,180);
g.drawRect(ancho-ancho/6, alto/4,
ancho/6, alto/2);
g.drawRect(14*ancho/15, 2*alto/5,
ancho/15, alto/5);
g.drawArc(5*ancho/6-alto/10,2*alto/5,
alto/5, alto/5,90,180);
}
}

Uso de Im
agenes
Para el uso de imagenes Java dispone de varias clases repartidas por los paquetes java.applet,
java.awt y
java.awt.image.
Las imagenes deben encontrarse en ficheros con formato GIF o JPEG.
Las imagenes deben ser cargadas con los metodos definidos para ello en las clases Applet o
Toolkit.
Una vez cargada, toda imagen es representada mediante un objeto de la clase Image.
Para que la imagen sea visualizada es preciso dar la orden correspondiente.

164

Metodos para la carga de imagenes


Definidos en la clase Applet:
public Image getImage (URL url)
public Image getImage (URL url, String Fichero)
La llamada a estos metodos solo puede hacerse en un applet y siempre dentro de un metodo
y no dentro de un constructor.
Definidos en la clase Toolkit:
public abstract Image getImage (URL url)
public abstract Image getImage (String Fichero)
Estas dos variantes pueden ser usadas tanto por applets como por aplicaciones. Para obtener
un objeto de la clase Toolkit puede utilizarse el metodo getDefaultToolkit() de la propia
clase Toolkit, o el metodo getToolkit() de la propia componente.
Visualizacion de imagenes
Se utiliza el metodo drawImage() de la clase Graphics.
public abstract boolean
drawImage (Image img, int x, int y, Color c,
ImageObserver obser)
Muestra la correspondiente imagen, situando su esquina superior izquierda en el punto (x,y).
Los puntos transparentes en la imagen se muestran con el color c. El parametro obser indica
el objeto al que debe notificarse si la operacion se ha realizado correctamente.
public abstract boolean
drawImage (Image img, int x, int y,
ImageObserver obser)
Los puntos transparentes no son modificados.
public abstract boolean
drawImage (Image img, int x, int y, int ancho,
int alto, Color c, ImageObserver obser)
La imagen se cambia de escala para que ocupe todo el rectangulo dado.
public abstract boolean
drawImage (Image img, int x, int y, int ancho,
int alto, ImageObserver obser)

165
Imagen escalada pero sin modificar los puntos transparentes.
Observaciones:
El metodo drawImage() devuelve una variable boolean que indica si el proceso de dibujo ha sido
realizado correctamente.
El objeto que act
ua de observador debe pertenecer a una clase que implemente la interfase
ImageObserver. La clase Component implementa dicha interfase, es por eso que normalmente
se utiliza la propia componente (this) como observador de la imagen.
Cuando a una imagen se le asocia un observador, cualquier informacion disponible sobre la imagen
provoca la llamada al metodo imageUpdate() del observador.
Ejemplo:
import java.awt.*;
import java.applet.Applet;
public class Figura extends Applet
{
Image fondo, fig;
public void init () {
fondo = getImage(getDocumentBase(),
"Fondo.gif");
fig = getImage(getDocumentBase(),"Logo.gif");
}
public void paint( Graphics g ) {
int ancho, alto;
Dimension d = getSize();
ancho = fig.getWidth(this);
alto = fig.getHeight(this);
g.drawImage(fondo, 0, 0, d.width, d.height,
this);
g.drawImage(fig,(d.width-ancho)/2,
(d.height-alto-20)/2,this);
}
}
la figura del fondo se adapta a las dimensiones de la ventana

Im
agenes Off-screen
Para crear imagenes la clase Component tiene definido el metodo createImage():
public Image createImage(ImageProducer prod)
public Image createImage(int ancho, int alto)
Los pasos a seguir para crear y visualizar imagenes off-screen son los siguientes:

166
1. Utilizar el metodo createImage() para crear un objeto de tipo Image.
2. Obtener su contexto grafico asociado con el metodo
getGraphics().
3. Efectuar todas las operaciones sobre ese contexto.
4. Visualizar la imagen con el metodo drawImage().
Ejemplo:
import java.awt.*;
import java.applet.Applet;
public class Imagen extends Applet
{
int x[] = new int[5];
int y[] = new int[5];
public void init () {
x[0]=20;
y[0]=20;
x[2]=180; y[2]=180;
x[4]=20;
y[4]=20;
}

x[1]=180;
x[3]=20;

y[1]=20;
y[3]=180;

public void rehacer () {


int xaux, yaux;
xaux=x[0]; yaux=y[0];
x[0]=(x[0]+x[1])/2; y[0]=(y[0]+y[1])/2;
x[1]=(x[1]+x[2])/2; y[1]=(y[1]+y[2])/2;
x[2]=(x[2]+x[3])/2; y[2]=(y[2]+y[3])/2;
x[3]=(x[3]+xaux)/2; y[3]=(y[3]+yaux)/2;
x[4]=x[0]; y[4]=y[0];
}
public void paint( Graphics g ) {
Image imagen;
Graphics gg;
imagen=createImage(200,200);
gg=imagen.getGraphics();
for(int i=1;i<20;i++) {
gg.drawPolygon (x, y, 5);
rehacer();
}
g.drawImage(imagen,0,0,200,200,this);
}
}

M
etodos de la Clase Image

167

public abstract void flush ()


Elimina la imagen y todos los recursos que utiliza.
public abstract Graphics getGraphics ()
Crea un contexto grafico para trabajar con una imagen (off-screen).
public abstract int
getHeight (ImageObserver obser)
Devuelve la altura de la imagen en puntos. En caso de no ser conocida, devuelve el valor -1
y se lo notifica al observador.
public abstract int
getWidth (ImageObserver obser)
Devuelve la anchura en puntos de la imagen.
public abstract Object
getProperty (String nombre, ImageObserver obser)
Devuelve la propiedad cuyo nombre se indica. Si la propiedad no es conocida, devuelve null
y el observador recibe la notificacion.
public abstract ImageProducer getSource ()
Devuelve un objeto que implementa la interfase ImageProducer y que es el encargado de
reconstruir la imagen siempre que sea solicitado.

Manipulando Im
agenes
Uso de Filtros
Toda imagen lleva asociados dos objetos importantes:
Productor: Crea todos los datos que el sistema necesita para visualizar la imagen y se los pasa al
consumidor. Debe ser un objeto que implemente la interfase ImageProducer.
Consumidor: Produce la visualizacion. Debe ser un objeto que implemente la interfase ImageConsumer.
Un filtro es un objeto de la clase ImageFilter que intercepta y modifica los datos que el productor
enva al consumidor.
Manipulacion de imagenes. Pasos a seguir:
1. Crear el objeto Image con el metodo getImage().
2. Obtener el productor de la imagen con el metodo
getSource() de la clase Image.

168
3. Crear un ejemplar del filtro.
4. Crear un objeto de la clase FilteredImageSource, pasando como argumentos al constructor el
productor de la imagen y el filtro.
5. Crear un nuevo objeto de la clase Image con el metodo createImage(), dando como productor
para la imagen manipulada el objeto FilteredImageSource anterior.
Ejemplo:
import java.awt.*;
import java.awt.image.*;
import java.applet.Applet;
public class Filtros extends Applet
{
Image
img1, img2;
ImageProducer
productor1, productor2;
ImageFilter
filtro;
public void init () {
img1 = getImage(getDocumentBase(),"Logo1.gif");
productor1 = img1.getSource();
filtro = new RotateFilter(Math.PI);
productor2 =
new FilteredImageSource(productor1, filtro);
img2 = createImage(productor2);
}
public void paint( Graphics g ) {
g.drawImage(img1, 10, 20, this);
g.drawImage(img2, 200, 20, this);
}
}
Va Internet pueden obtenerse filtros para manipular imagenes (por ejemplo el filtro RotateFilter).
En los paquete java.awt.image se incluyen los filtros:
CropImageFilter: se utiliza para obtener una nueva imagen formada por una parte rectangular de la imagen inicial. Para utilizar este filtro no es necesario crear una subclase de la
CropImageFilter, se puede utilizar su constructor:
CropImageFilter(int x,int y,int width,int height) Construye un objeto CropImageFilter
que extrae la region rectangular indicada en pixels, de la imagen dada.
RGBImageFilter: sirve para modificar el color o la transparencia de todos los puntos de la
imagen. Para utilizar este filtro se crea una subclase de la clase RGBImageFilter y se redefine
el metodo

169
public int filterRGB(int x, int y, int argb) Este metodo debe ser implementado por toda
subclase de la clase RGBImageFilter. En este metodo se convierte cada pixel de entrada
(modelo de color RGB), en un pixel de salida.
El programador puede crear sus propios filtros creando subclases de la clase ImageFilter definida
dentro del paquete java.awt.image.
Ejemplo:
import
import
import
import

java.awt.*;
java.awt.image.ImageFilter.*;
java.awt.image.*;
java.applet.Applet;

public class FiltroApplet extends Applet {


Image
img1, img2;
ImageProducer
productor1, productor2;
ImageFilter
filtro1;
public void init() {
img1= getImage(getDocumentBase(),"Logo2.GIF");
productor1 = img1.getSource();
filtro1 = new CropImageFilter(50,50,50,50);
productor2 =
new FilteredImageSource(productor1,filtro1);
img2= createImage(productor2);
}

public void paint(Graphics g){


g.drawImage(img1, 10, 20, this);
g.drawImage(img2, 280, 50, this);
}
}
}
Ejemplo:
import java.awt.*;
import java.awt.image.*;
import java.applet.Applet;
public class FiltroApplet1 extends Applet
{
Image img1, img2;
ImageProducer productor1, productor2;
MiFiltro filtro;

170
public void init () {
img1 = getImage(getDocumentBase(),"Logo3.gif");
productor1 = img1.getSource();
filtro = new MiFiltro();
productor2 =
new FilteredImageSource(productor1,filtro);
img2 = createImage(productor2);
}
public void paint( Graphics g ) {
g.drawImage(img1, 10, 20, this);
g.drawImage(img2, 250, 20, this);
}
}
class MiFiltro extends RGBImageFilter{
public MiFiltro(){
super();
}
public int filterRGB(int x,int y, int rgb){
int rojo,verde,azul;
Color c1=new Color(rgb);
rojo=255-c1.getRed();
verde=255-c1.getGreen();
azul=255-c1.getBlue();
Color c2=new Color(rojo,azul,verde);
return(c2.getRGB());
}
}
Algunos metodos de la clase ImageFilter
void setDimensions (int ancho, int alto)
Mediante este metodo el productor comunica al consumidor las dimensiones de la imagen.
Si el filtro desea cambiarlas, debe hacerlo dentro de este metodo.
void setColorModel (ColorModel model)
El productor comunica al consumidor la forma de colorear o el modelo de coloreado de los
puntos.
void setHints (int hintflags)
Indica el orden en el que se tratan los diferentes puntos de la imagen.
void setPixels (int x, int y, int ancho,
int alto, ColorModel m, byte puntos[],
int off, int scansize)

171

32 bits
TT
32

RR
24

AA

VV
16

0xTTRRVVAA

El productor llama al metodo setpixels() del consumidor para efectuar la representacion


grafica de cada punto de la imagen. En los argumentos se indican la region rectangular a
representar, el modo de colorear, los puntos, el punto inicial y el n
umero de puntos por lnea.
void imageComplete (int status)
El productor llama a este metodo cuando ha finalizado su labor o ha encontrado un error.
Nota: Como ejemplo se puede consultar la clase RotateFilter utilizada en el ejemplo 3.
La clase MemoryImageSource
Esta clase produce una imagen desde un array de enteros. Un objeto MemoryImageSource es un
productor, se puede obtener la imagen utilizando el metodo createImage de la clase Component o
Toolkit.
El constructor de esta clase es:
public MemoryImageSource(int width,int height,int[] pixels,
int offset,int scan3ize)
Ejemplo:
import java.applet.*;
import java.awt.*;
import java.awt.image.*;
public class MemoryImageTest extends Applet{
Image memImage;
int pixArray[]={0,0xFFFF00FF,0xFFFF00FF,0,0,
0xFF007F7F,0xFF007F7F,0xFF007F7F,0xFF007F7F,
0xFFFF00FF,0,0,0xFFFF00FF,0,0,0,0xFF007F7F,0,
0xFFFF00FF,0,0,0,0,0,0,0xFF007F7F,0,
0xFFFF00FF,0,0,0,0,0,0,0xFF007F7F,0,
0xFFFF00FF,0,0,0xFFFF00FF,0,

172
0xFF007F7F,0,0xFF007F7F,0,
0,0xFFFF00FF,0xFFFF00FF,0,0,
0,0xFF007F7F,0,0};
public void init(){
memImage=createImage(
new MemoryImageSource(9,6,pixArray,0,9));
}

public void paint(Graphics g){


g.drawImage(memImage,0,0,90,60,this);
}
}
La clase PixelGrabber
Esta clase permite obtener los pixels de una imagen y colocarlos en un array.
Uno de los constructores de esta clase es:
public PixelGrabber(Image image,int x,int y,
int width,int height,boolean forceRGB)
Algunos de los metodos de esta clase son:
boolean grabPixels()
int getWidth()
int getHeight()
Object getPixels()
Ejemplo:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
public class PixelGrabberEjem extends Frame
implements ActionListener
{
Image imagenTranspuesta;
int ancho;
int alto;
String ficheroNombre = "";

173
public PixelGrabberEjem()
{
MenuBar mbar = new MenuBar();
Menu m = new Menu("Archivo");
MenuItem m1 = new MenuItem("Abrir");
m1.addActionListener(this);
m.add(m1);
MenuItem m2 = new MenuItem("Salir");
m2.addActionListener(this);
m.add(m2);
mbar.add(m);
setMenuBar(mbar);
}
public void actionPerformed(ActionEvent evt)
{ String arg = evt.getActionCommand();
if (arg.equals("Abrir"))
{ FileDialog d = new FileDialog(this, "Abrir fichero",
FileDialog.LOAD);
d.show();
String f = d.getFile();
if (f != null)
{ ficheroNombre =f;
imagenTranspuesta(ficheroNombre);
}
}
else if(arg.equals("Salir")) System.exit(0);
}
public void imagenTranspuesta(String f)
{
Image imagen = Toolkit.getDefaultToolkit().getImage(f);
PixelGrabber gr = new PixelGrabber(imagen, 0, 0, -1, -1,
true);
try
{ if (gr.grabPixels())
{ ancho = gr.getWidth();
alto = gr.getHeight();
int[] pixels = (int[])gr.getPixels();
int[] transPixels = new int[alto * ancho];
for (int x = 0; x < ancho; x++)
for (int y = 0; y < alto; y++)
transPixels[x * alto + y] = pixels[y * ancho + x];
imagenTranspuesta = createImage(new
MemoryImageSource(alto,ancho, transPixels, 0, alto));
repaint();
}
}
catch(InterruptedException e) {}

174
}

Utilizaci
on de colores
El tratamiento del color en los procesos graficos se realiza por medio de la clase Color definida en
el paquete java.awt.
Todo color se identifica mediante su formato RGB que consta de tres valores enteros en el rango
comprendido entre 0 y 255, cada valor representa la contribucion de cada uno de los tres colores
primarios (rojo, verde y azul).
Constantes que definen colores habituales

constante
color
black
negro
blue
azul
cyan
ciano
darkGray
gris oscuro
gray
gris
green
verde
lightGray gris claro

constante color
magenta magenta
orange
naranja
pink
rosa
red
rojo
white
blanco
yellow
amarillo

Metodos de la clase Color


public Color (int rojo, int verde, int azul)
Crea un color como combinacion de los tres colores primarios. Cada argumento es un n
umero
entero entre 0 y 255.
public Color (float r, float v, float a)
Crea un color como combinacion de los tres colores primarios. Cada argumento es un n
umero
entre 0.0 y 1.0.
public Color (int rgb)
El argumento rgb es un n
umero entero, los 8 primeros bits de su representacion interna
(desde el bit 0 al bit 7) indican la contribucion del color azul, los 8 siguientes la del verde y
los 8 u
ltimos la del rojo.
public Color brighter ()
Devuelve una version mas brillante del color sobre el que se hace la llamada al metodo.
public Color darker ()

175
Devuelve una version mas oscura del color.
public boolean equals (Object obj)
Devuelve true si obj es un objeto de la clase Color y tiene los mismos valores RGB que el
color sobre el que se hace la llamada al metodo.
public int getRed ()
Devuelve la componente roja del color, en el rango comprendido entre 0 y 255.
public int getGreen ()
Devuelve la componente verde del color.
public int getBlue ()
Devuelve la componente azul del color.
public static Color
getHSBColor (float mat, float sat, float br)
Crea un color a partir de su matiz, saturacion y brillo (formato HSB). Cada una de las tres
componentes debe ser un n
umero de tipo float entre 0.0 y 1.0.
public int getRGB ()
Devuelve un entero con la representacion RGB del color.
public static int HSBtoRGB (float mat,
float sat, float br)
Devuelve el valor RGB correspondiente a un color dado en formato HSB.
public static float[]
RGBtoHSB (int rojo, int verde, int azul,
float hsbvals[])
Convierte un color en formato RGB al formato HSB. Los valores del matiz, saturacion y
brillo son colocados en la matriz hsbvals.

El color actual para un contexto grafico se indica mediante el metodo setColor() de la clase
Graphics.
Ejemplo:

176
import java.awt.*;
import java.applet.Applet;
import java.util.Random;
class GeneradorAleatorio extends Random {
public GeneradorAleatorio () {
super();
}
int ValorAleatorio (int max) {
Float aux = new Float(max*nextFloat());
return(aux.intValue());
}
void ColorAleatorio (Graphics g) {
int rojo, verde, azul;
rojo=ValorAleatorio(255);
verde=ValorAleatorio(255);
azul=ValorAleatorio(255);
g.setColor(new Color(rojo, verde, azul));
}
void FiguraAleatoria(Graphics g,boolean cuadrado){
int x, y, lado;
ColorAleatorio(g);
x=ValorAleatorio(200);
y=ValorAleatorio(200);
if (200-x<200-y)
lado=ValorAleatorio(200-x);
else
lado=ValorAleatorio(200-y);
if (cuadrado)
g.fillRect(x, y, lado, lado);
else
g.fillOval(x+200, y, lado, lado);
}
}

public class Colores extends Applet {


public void init () {
setSize(410,210);
}
public void paint( Graphics g ) {
GeneradorAleatorio r =
new GeneradorAleatorio();
g.drawRect(0, 0, 200, 200);
g.drawRect(200, 0, 200, 200);

177
for(int i=1; i<500; i++) {
r.FiguraAleatoria(g,true);
r.FiguraAleatoria(g,false);
}
}
}

Tipos de Letra
La clase Font
La clase Font se utiliza para representar las diferentes fuentes de letra con sus diferentes estilos.
Variables miembro de la clase:
protected String name: nombre del tipo.
protected int size: tama
no del tipo.
protected int style: estilo del tipo, es la suma de las constantes PLAIN (texto normal), BOLD
(texto en negrita) o ITALIC (texto en italica) definidas de la manera siguiente:
public final static int PLAIN = 0
public final static int BOLD = 1
public final static int ITALIC = 2
Constructor de la clase:
public Font (String nom, int est, int tam)
Crea un nuevo tipo de letra con el nombre, estilo y tama
no indicados.
Para obtener una matriz con los nombres de los tipos de letra disponibles puede usarse el metodo
getFontList() de la clase Toolkit.
La utilizacion de diferentes tipos de letra en un contexto grafico es muy similar en su funcionamiento
a los colores. Cada contexto lleva asociado un tipo de letra que en todo momento puede cambiarse
mediante el metodo setFont() de la clase Graphics.
Ademas, la clase Font define los siguientes metodos:
public boolean equals (Object obj)
Devuelve true si el argumento es un objeto de la clase Font y su nombre, estilo y tama
no
coinciden con los correspondientes al Font sobre el que se hace la llamada al metodo.
public String getFamily ()
Devuelve una cadena con el nombre especfico de la familia a la que pertenece el tipo de
letra, en la plataforma sobre la que se trabaje.

178

public static Font getFont (String n)


El argumento n es tratado como el nombre de una propiedad del sistema. El valor de esta
propiedad debera ser de una de las formas siguientes:
nombre-estilo-tama
no
nombre-tama
no
nombre-estilo
nombre
Donde estilo es la cadena bold, la cadena bolditalic o la cadena italic, y tama
no es
el n
umero de puntos del tipo de letra. Con estas propiedades se devuelve el tipo de letra
correspondiente.
public static Font getFont (String n, Font f)
Igual que el metodo anterior, con la u
nica diferencia de devolver el tipo de letra f si no se
encuentra la propiedad indicada.
public String getName ()
Devuelve el nombre logico del tipo de letra.
public int getSize ()
Devuelve el tama
no del tipo de letra.
public int getStyle ()
Devuelve el estilo del tipo de letra.
public boolean isBold ()
Devuelve true si el estilo de la letra es bold (negrita) y false en otro caso.
public boolean isItalic ()
Devuelve true si el estilo de la letra es italic (italica) y false en otro caso.
public boolean isPlain ()
Devuelve true si el estilo de la letra es normal y false en otro caso.
public String toString ()
Devuelve una representacion del tipo de letra en forma de una cadena de caracteres.
Ejemplo:

179

import java.awt.*;
import java.applet.Applet;
public class Fuentes extends Applet
{
Font fuente1, fuente2, fuente3, fuente4;
public void
fuente1
fuente2
fuente3
fuente4
}

init() {
= new Font("Helvetica", 0, 18);
= new Font("Times", 1, 14);
= new Font("New York", 2, 12);
= new Font("Geneva", 3, 10);

public void paint( Graphics g ) {


g.setFont(fuente1);
g.drawString("Helvetica,
normal, 18 puntos", 20, 20 );
g.setFont(fuente2);
g.drawString("Times,
negrita, 14 puntos", 20, 40 );
g.setFont(fuente3);
g.drawString("New York,
italica, 12 puntos", 20, 60 );
g.setFont(fuente4);
g.drawString("Geneva,
negrita, italica, 10 puntos", 20, 80 );
}
}

Aspectos m
etricos del texto
La clase FontMetrics controla los aspectos metricos de un determinado tipo de letra. De hecho, la
u
nica variable miembro declarada en la clase, es la variable de la clase Font que lleva por nombre font.
El constructor de la clase es:
protected FontMetrics (Font f)

180
a

b
d

Programacin en
lenguaje Java

Lnea superior
Lnea de base
Lnea inferior
Lnea superior
Lnea de base
Lnea inferior

Crea el objeto asociandole su tipo de letra.


En cualquier momento puede obtenerse el objeto Font con la llamada al metodo:
public Font getFont ()
Devuelve el tipo de letra descrito por el objeto
FontMetrics.
Cada tipo determina tres lneas diferentes (vease la Figura ):
Lnea de base : sobre la que se apoyan todos los caracteres.
Lnea superior : la que indica la altura maxima que pueden alcanzar los caracteres de la fuente.
Lnea inferior : indica la distancia maxima que los caracteres pueden descender por debajo de la
lnea de base. Por ejemplo, un caracter como la p, aunque se apoye en la lnea de base, parte de
el quedara por debajo de la misma.
Para obtener las diferentes distancias entre las lneas, la clase FontMetrics dispone de los siguientes
metodos:
public int getAscent ()
Determina la distancia entre la lnea de base y la lnea superior (distancia a en la Figura ).
public int getDescent ()
Determina la distancia entre la lnea de base y la lnea inferior (distancia b en la Figura).
public int getHeight ()
Determina la distancia entre las lneas de base de dos lneas consecutivas de texto (distancia
c en la Figura).
public int getLeading ()
Determina la distancia entre la lnea inferior del texto y la superior de la siguiente (distancia
d en la Figura).
Cada caracter tiene ademas una anchura que influye en la posicion del siguiente caracter, ya que si
un caracter tiene una anchura a y se coloca en la posicion (x, y), el caracter siguiente debe ir colocado
en la posicion (x + a, y). Para medir esas anchuras, la clase FontMetrics dispone de varios metodos.
Logicamente, esas distancias dependen del tipo de letra asociado:
public int bytesWidth (byte data[], int inicio,
int longitud)

181
Devuelve la anchura de la submatriz de caracteres que comienza en el ndice inicio y tiene
la longitud indicada por el argumento longitud.
public int charsWidth (byte data[], int inicio,
int longitud)
Identico al metodo anterior.
public int charWidth (char c)
Devuelve la anchura del caracter que se indica en el argumento c.
public int stringWidth (String str)
Devuelve la anchura de la cadena de caracteres que se indica en el argumento str.
public int getMaxAdvance ()
Devuelve la anchura maxima de un caracter en la fuente de letra asociada. En caso de no
conocer esa anchura, devuelve -1.
public int[] getWidths (String str)
Devuelve una matriz con la anchura de los primeros 256 caracteres en el tipo asociado.
Por u
ltimo, la clase FontMetrics define ademas los metodos:
public int getMaxAscent ()
Determina la longitud maxima a la que un caracter puede llegar por encima de la lnea de
base en el correspondiente tipo de letra.
public int getMaxDescent ()
Determina la longitud maxima a la que un caracter puede descender por debajo de la lnea
de base en el correspondiente tipo de letra.
public String toString ()
Devuelve una representacion del objeto en forma de cadena de caracteres.
Ejemplo
import java.awt.*;
import java.applet.*;
public class dibujarTexto extends Applet{
Font f1=new Font("TimesRoman",Font.PLAIN,14);
String str="Esta es una prueba";
public void paint(Graphics g){

182
int longitud=getFontMetrics(f1).stringWidth(str);
g.drawString(str,5,30);
g.drawLine(5,
30+getFontMetrics(f1).getDescent(),5+longitud,
30+getFontMetrics(f1).getDescent());
g.drawLine(5,
30-getFontMetrics(f1).getAscent(),5+longitud,
30-getFontMetrics(f1).getAscent());
g.drawLine(5,30,5+longitud,30);
}
}

Pr
actica 1
import
import
import
import

java.applet.*;
java.awt.event.*;
java.util.*;
java.awt.*;

public class CirculosRepaint extends Applet implements MouseListener{


Vector vectorFiguras;
public void init(){
vectorFiguras=new Vector();
addMouseListener(this);
}
public void paint(Graphics g){
Circulo s;
int numFiguras;
numFiguras=vectorFiguras.size();
for(int i=0;i<numFiguras;i++){
s=(Circulo)vectorFiguras.elementAt(i);
s.draw(g);
}
}
public void mouseClicked(MouseEvent e){
Circulo s;
s=new Circulo();
s.x=e.getX(); s.y=e.getY();
vectorFiguras.addElement(s);
repaint();
}
public void mouseReleased(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mousePressed(MouseEvent e){}

183
}
class Circulo{
static public final int r=20;
Color color=Color.red;
int x,y;
void draw(Graphics g){
g.setColor(color);
g.fillOval(x-r,y-r,2*r,2*r);
}
}

Pr
actica 2
import
import
import
import

java.applet.*;
java.awt.event.*;
java.util.*;
java.awt.*;

public class CirculosRepaint1 extends Applet implements MouseListener{


Vector vectorFiguras;
Graphics gra1,gra2;
Canvas c=new Canvas();
public void init(){
vectorFiguras=new Vector();
addMouseListener(this);
c.addMouseListener(this);
c.setBounds(0,0,150,150);
c.setEnabled(true);
setLayout(null);
add(c);
gra1=c.getGraphics();
gra1.setColor(Color.red);
gra2=this.getGraphics();
gra2.setColor(Color.blue);
}
public void paint(Graphics g){
Circulo s;
int numFiguras;
numFiguras=vectorFiguras.size();
for(int i=0;i<numFiguras;i++){
s=(Circulo)vectorFiguras.elementAt(i);

184
s.draw(g);
}
}
public void mouseClicked(MouseEvent e){
Circulo s;
s=new Circulo();
s.x=e.getX(); s.y=e.getY();
vectorFiguras.addElement(s);
repaint();
}
public void mouseReleased(MouseEvent e){
Circulo s=new Circulo();
s.x=e.getX();
s.y=e.getY();
if(e.getComponent()==c)
s.draw(gra1);
else
s.draw(gra2);
}
public void mouseExited(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mousePressed(MouseEvent e){}
}
class Circulo{
static public final int r=20;
Color color=Color.red;
int x,y;
void draw(Graphics g){
g.setColor(color);
g.fillOval(x-r,y-r,2*r,2*r);
}
}

Pr
actica 3
import java.awt.*; import java.applet.Applet; import
java.awt.event.*;
public class Sectores extends Applet implements ActionListener{
Label l1,l2,l3,l4;
TextField f1,f2,f3,f4;
Button dibujar;

185
public void init(){
setLayout(null);
l1=new Label("Sobresal. :");
l1.setBounds(10,10,75,20);
add(l1);
l2=new Label("Notables:");
l2.setBounds(10,40,75,20);
add(l2);
l3=new Label("Aprobados:");
l3.setBounds(10,70,75,20);
add(l3);
l4=new Label("Suspensos:");
l4.setBounds(10,100,75,20);
add(l4);
f1=new TextField("0");
f1.setBounds(90,10,40,20);
add(f1);
f2=new TextField("0");
f2.setBounds(90,40,40,20);
add(f2);
f3=new TextField("0");
f3.setBounds(90,70,40,20);
add(f3);
f4=new TextField("0");
f4.setBounds(90,100,40,20);
add(f4);
dibujar=new Button("Dibujar");
dibujar.setBounds(10,150,50,20);
dibujar.addActionListener(this);
add(dibujar);
repaint();
}
public void paint(Graphics g){
int n1,n2,n3,n4,total,anterior;
n1=(new Integer(f1.getText())).intValue();
n2=(new Integer(f2.getText())).intValue();
n3=(new Integer(f3.getText())).intValue();
n4=(new Integer(f4.getText())).intValue();

186
total=n1+n2+n3+n4;
g.drawOval(140,10,150,150);
if(total!=0){
g.setColor(Color.red);
g.fillArc(140,10,150,150,0,360*n1/total);
g.setColor(Color.green);
g.fillArc(140,10,150,150,360*n1/total,360*n2/total);
g.setColor(Color.yellow);
g.fillArc(140,10,150,150,360*(n1+n2)/total,360*n3/total);
g.setColor(Color.yellow);
g.setColor(Color.blue);
g.fillArc(140,10,150,150,360*(n1+n2+n3)/total,360*n4/total);
}
}
public void actionPerformed(ActionEvent ae){
Object componente=ae.getSource();
if(componente.equals(dibujar)){
repaint();}
}
}

Pr
actica 4
import
import
import
import

java.applet.*;
java.awt.event.*;
java.util.*;
java.awt.*;

public class CirculosRepaint1 extends Applet implements


MouseListener{
Vector vectorFiguras;
Graphics gra1,gra2;
Canvas c=new Canvas();
public void init(){
vectorFiguras=new Vector();
addMouseListener(this);
c.addMouseListener(this);
c.setBounds(0,0,150,150);
c.setEnabled(true);
setLayout(null);
add(c);
gra1=c.getGraphics();
gra1.setColor(Color.red);
gra2=this.getGraphics();
gra2.setColor(Color.blue);

187
}
public void paint(Graphics g){
Circulo s;
int numFiguras;
numFiguras=vectorFiguras.size();
for(int i=0;i<numFiguras;i++){
s=(Circulo)vectorFiguras.elementAt(i);
s.draw(g);
}
}
public void mouseClicked(MouseEvent e){
Circulo s;
s=new Circulo();
s.x=e.getX(); s.y=e.getY();
vectorFiguras.addElement(s);
repaint();
}
public void mouseReleased(MouseEvent e){
Circulo s=new Circulo();
s.x=e.getX();
s.y=e.getY();
if(e.getComponent()==c)
s.draw(gra1);
else
s.draw(gra2);
}
public void mouseExited(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mousePressed(MouseEvent e){}
} class Circulo{
static public final int r=20;
Color color=Color.red;
int x,y;
void draw(Graphics g){
g.setColor(color);
g.fillOval(x-r,y-r,2*r,2*r);
}
}

188

Gr
aficos 2-D
En la version 1.2 de Java se incluyen paquetes que permiten trabajar con graficos en 2-D, ademas
tambien aparecen paquetes que extienden las posibilidades de trabajo con texto como entidad grafica
y con imagenes.
En la Java 2D API, se pueden encontrar paquetes nuevos como:
java.awt.color
java.awt.font
java.awt.geom :En este paquete se encuentran clases como:
Arc2D, Arc2D.Double,Ellipse2D,Ellipse2D.Double ,
Line2D,Line2D.Double,Point2D,Point2D.Double,
Rectangle2D,Rectangle.Double, etc
java.awt.print
Ademas, en los paquetes java.awt y java.awt.image se han incluido nuevas clases que permiten
trabajar en 2D.
java.awt
java.awt.AlphaComposite
java.awt.BasicStroke
java.awt.Color
java.awt.Composite
java.awt.CompositeContext
java.awt.Font
java.awt.GradientPaint
java.awt.Graphics2D
java.awt.GraphicsConfiguration
java.awt.GraphicsDevice
java.awt.GraphicsEnvironment
java.awt.Paint
java.awt.PaintContext
java.awt.Rectangle
java.awt.Shape
java.awt.Stroke
java.awt.TexturePaint
java.awt.Toolkit
java.awt.Transparency

189
java.awt.image
java.awt.image.AffineTransformOp
java.awt.image.BandCombineOp
java.awt.image.BandedSampleModel
java.awt.image.BufferedImage
java.awt.image.BufferedImageFilter
java.awt.image.BufferedImageOp
java.awt.image.ByteLookupTable
java.awt.image.ColorConvertOp
java.awt.image.ColorModel
java.awt.image.ComponentColorModel
java.awt.image.ComponentSampleModel
java.awt.image.ConvolveOp
java.awt.image.DataBuffer
java.awt.image.DataBufferByte
java.awt.image.DataBufferInt
java.awt.image.DataBufferShort
java.awt.image.DirectColorModel
java.awt.image.IndexColorModel
java.awt.image.Kernel
java.awt.image.LookupOp
java.awt.image.LookupTable
java.awt.image.MultiPixelPackedSampleModel
java.awt.image.PackedColorModel
java.awt.image.Raster
java.awt.image.RasterformatException
java.awt.image.RasterOp
java.awt.image.RenderedImage
java.awt.image.RescaleOp
java.awt.image.SampleModel
java.awt.image.ShortLookupTable
java.awt.image.SinglePixelPackedSampleModel
java.awt.image.WritableRaster
A continuacion se presenta una coleccion de ejemplos donde se muestran algunas de estas posibilidades.

190
Ejemplo: Las clases Ellipse2D.Double y Rectangle2D.Double definen elipses y rectangulos, especificados en doble precision. La clase Graphics2D extiende las posibilidades de la clase Graphics.
import java.awt.*;
import java.awt.geom.*;
import java.applet.*;
public class ShapeExample extends Applet {
Ellipse2D.Double circle =
new Ellipse2D.Double(10, 10, 350, 350);
Rectangle2D.Double square =
new Rectangle2D.Double(10, 10, 350, 350);
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.fill(circle);
g2d.draw(square);
}
}
Ejemplo:
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
public class ShapeExample extends JPanel {
Ellipse2D.Double circle =
new Ellipse2D.Double(10, 10, 350, 350);
Rectangle2D.Double square =
new Rectangle2D.Double(10, 10, 350, 350);
public void paintComponent(Graphics g) {
clear(g);
Graphics2D g2d = (Graphics2D)g;
g2d.fill(circle);
g2d.draw(square);
}
void clear(Graphics g) {
super.paintComponent(g);
}
Ellipse2D.Double getCircle() {
return(circle);
}
public static void main(String[] args) {
ShapeExample obj=new ShapeExample();

191
JFrame jf=new JFrame();
jf.setBackground(Color.white);
obj.setBackground(Color.white);
jf.setSize(200, 200);
jf.setContentPane(obj);
jf.setVisible(true);
}
}
Ejemplo:La clase GradientPaint proporciona un nuevo metodo para rellenar con color un objeto
Shape.
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
public class GradientPaintExample extends JPanel {
Ellipse2D.Double circle =
new Ellipse2D.Double(10, 10, 350, 350);
GradientPaint gradient =
new GradientPaint(0, 0, Color.red, 175, 175,
Color.yellow,true);
public void paintComponent(Graphics g) {
clear(g);
Graphics2D g2d = (Graphics2D)g;
drawGradientCircle(g2d);
}
void drawGradientCircle(Graphics2D g2d) {
g2d.setPaint(gradient);
g2d.fill(circle);
g2d.setPaint(Color.black);
g2d.draw(circle);
}
void clear(Graphics g) {
super.paintComponent(g);
}
public static void main(String[] args) {
GradientPaintExample obj=
new GradientPaintExample();
JFrame jf=new JFrame();
jf.setBackground(Color.white);
obj.setBackground(Color.white);
jf.setSize(200, 200);
jf.setContentPane(obj);

192
jf.setVisible(true);
}
}
Ejemplo:
import
import
import
public

javax.swing.*;
java.awt.*;
java.awt.geom.*;
class RotationExample1 extends JPanel {

Color[] colors ={ Color.white, Color.black };


Ellipse2D.Double circle =new Ellipse2D.Double(10, 10, 350, 350);
GradientPaint gradient =new GradientPaint(0, 0, Color.red, 175, 175,
Color.yellow,true);
public void paintComponent(Graphics g) {
clear(g);
Graphics2D g2d = (Graphics2D)g;
drawGradientCircle(g2d);
drawThickCircleOutline(g2d);
g2d.translate(185.0, 185.0);
for (int i=0; i<16; i++) {
g2d.rotate(Math.PI/8.0);
g2d.setPaint(colors[i%2]);
g2d.drawString("Java", 0, 0);
}
}
void drawGradientCircle(Graphics2D g2d) {
g2d.setPaint(gradient);
g2d.fill(circle);
g2d.setPaint(Color.black);
g2d.draw(circle);
}
void drawThickCircleOutline(Graphics2D g2d) {
g2d.setPaint(Color.blue);
g2d.setStroke(new BasicStroke(8));
g2d.draw(circle);
}
void clear(Graphics g) {
super.paintComponent(g);
}
public static void main(String[] args) {
RotationExample obj=new RotationExample();
JFrame jf=new JFrame();
jf.setBackground(Color.white);

193
obj.setBackground(Color.white);
jf.setSize(200, 200);
jf.setContentPane(obj);
jf.setVisible(true);
}
}
Ejemplo:La clase GraphicsEnvironment describe la coleccion de objetos GraphicsDevice y Font
disponibles para una aplicacion Java(tm).
import java.awt.*;
public class ListFonts {
public static void main(String[] args) {
GraphicsEnvironment env =
GraphicsEnvironment.getLocalGraphicsEnvironment();
String[] fontNames =
env.getAvailableFontFamilyNames();
System.out.println("Tipos de Letra:");
for(int i=0; i<fontNames.length;i++)
System.out.println(" " + fontNames[i]);
}
}
Ejemplo:
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
public class FontExample1 extends GradientPaintExample {
Ellipse2D.Double circle =
new Ellipse2D.Double(10, 10, 350, 350);
GradientPaint gradient =
new GradientPaint(0, 0, Color.red, 175, 175,
Color.yellow,true);
public FontExample1() {
GraphicsEnvironment env =GraphicsEnvironment.getLocalGraphicsEnvironment();
env.getAvailableFontFamilyNames();
setFont(new Font("Goudy Handtooled BT",
Font.PLAIN, 100));
}
void drawBigString(Graphics2D g2d) {
g2d.setPaint(Color.black);
g2d.drawString("Java 2D", 25, 215);
}

194

void clear(Graphics g) {
super.paintComponent(g);
}
public void paintComponent(Graphics g) {
clear(g);
Graphics2D g2d = (Graphics2D)g;
drawGradientCircle(g2d);
drawBigString(g2d);
}
protected void drawGradientCircle(Graphics2D g2d) {
g2d.setPaint(gradient);
g2d.fill(circle);
g2d.setPaint(Color.black);
g2d.draw(circle);
}
public static void main(String[] args) {
FontExample1 obj=new FontExample1();
JFrame jf=new JFrame();
jf.setBackground(Color.white);
obj.setBackground(Color.white);
jf.setSize(200, 200);
jf.setContentPane(obj);
jf.setVisible(true);
}
}
Ejemplo:
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
public class DashedStrokeExample extends JPanel {
Ellipse2D.Double circle =
new Ellipse2D.Double(10, 10, 350, 350);
GradientPaint gradient =
new GradientPaint(0, 0, Color.red, 175, 175,Color.yellow,true);

public void paintComponent(Graphics g) {


clear(g);
Graphics2D g2d = (Graphics2D)g;
drawGradientCircle(g2d);
drawBigString(g2d);

drawDashedCircleOutline(g2d);
}
void drawDashedCircleOutline(Graphics2D g2d) {
g2d.setPaint(Color.blue);
float[] dashPattern = { 30, 10, 10, 10 };
g2d.setStroke(new BasicStroke(8,
BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER, 10,
dashPattern, 0));
g2d.draw(circle);
}
void clear(Graphics g) {
super.paintComponent(g);
}
void drawBigString(Graphics2D g2d) {
g2d.setPaint(Color.black);
g2d.drawString("Java 2D", 25, 215);
}
void drawGradientCircle(Graphics2D g2d) {
g2d.setPaint(gradient);
g2d.fill(circle);
g2d.setPaint(Color.black);
g2d.draw(circle);
}
public static void main(String[] args) {
DashedStrokeExample obj=
new DashedStrokeExample();
JFrame jf=new JFrame();
jf.setBackground(Color.white);
obj.setBackground(Color.white);
jf.setSize(200, 200);
jf.setContentPane(obj);
jf.setVisible(true);
}
}

196

PROCESOS LIGEROS (THREADS)

197

Procesos Ligeros (Threads)


Un proceso ligero es una parte de codigo o miniprograma que puede ser ejecutada independientemente, de forma que una aplicacion o un applet puede tener varios procesos ligeros ejecutandose
simultaneamente y efectuando diferentes tareas.
Esto constituye una alternativa a los programas secuenciales en los que existe un principio, una
secuencia de instrucciones y un final, habiendo en cada instante un u
nico punto de ejecucion.
Los procesos ligeros, a veces tambien llamados contextos de ejecuci
on, pueden ser utilizados para la
implementacion de algoritmos paralelos o procesos concurrentes, sin ser necesario disponer de equipos
con estructura multiprocesador. En el caso de un solo procesador, los procesos ligeros incorporan
mecanismos para compartirlo, estableciendose prioridades entre ellos.
Los procesos ligeros son implementados por medio de una clase especial definida en el paquete
java.lang: la clase Thread. Para construir un proceso ligero debe crearse una subclase de la clase
Thread.
Ejemplo:
import java.applet.Applet;
public class EjemploThreads extends Applet {
public void init () {
new PotenciaThread("Primer
proceso ligero",2).start();
new PotenciaThread("Segundo
proceso ligero",3).start();
new PotenciaThread("Tercer
proceso ligero",5).start();
}
}
class PotenciaThread extends Thread {
long num;
public PotenciaThread(String nombre,long n) {
super(nombre);num=n;
}
public void run() {
long aux=1;
for(int i=1; i<=3; i++) {
aux*=num;
System.out.println(num +
"^" + i + "=" + aux);
}
}
}

198
Salida:
2^1=2
3^1=3
5^1=5
2^2=4
3^2=9
5^2=25
2^3=8
3^3=27
5^3=125

El M
etodo run()
El metodo run() constituye el cuerpo del proceso ligero; en el se indica la accion para la que esta
programado el proceso ligero. Frecuentemente esta accion es un ciclo o una operacion que lleva mucho
tiempo.
En la definicion de la clase Thread del paquete java.lang se incluye el metodo run(). El programador debe adaptar dicho metodo a los objetivos de cada uno de sus procesos ligeros, y puede hacerse
de dos formas diferentes:
Redefiniendo el metodo en una subclase de Thread, igual que se hizo en el ejemplo anterior.
Creando el proceso ligero y
Runnable (tambien definida
cuando define un metodo sin
del objeto que implementa la

asociandole un objeto de una clase que implemente la interfase


en el paquete java.lang). Una clase implementa esta interfase
argumentos que se llame run(). De esta manera, el metodo run()
interfase Runnable pasara a ser el metodo run() del proceso ligero.

La segunda de las opciones es la que debera usarse cuando se quieran integrar procesos ligeros en applets.
A continuacion se presenta el programa que calcula de manera simultanea las potencias de tres
n
umeros usando esta nueva variante.
Ejemplo:
import java.applet.Applet;
public class EjemploThreads extends Applet{
public void init () {
PotenciaRun p1 = new PotenciaRun(2);
PotenciaRun p2 = new PotenciaRun(3);
PotenciaRun p3 = new PotenciaRun(5);
new Thread(p1).start();
new Thread(p2).start();
new Thread(p3).start();
}
}
class PotenciaRun implements Runnable {

199
long num;
public PotenciaRun(long n) {
num=n;
}
public void run() {
long aux=1;
for(int i=1; i<=10; i++) {
aux*=num;
System.out.println(num+"^"+i+"="+aux);
}
}
}

Estado de un Proceso Ligero


Un proceso ligero puede estar, en cada instante, en uno de los siguientes estados desde el momento
de su creacion:
Disponible: El proceso ligero ha sido creado con la sentencia new, pero el sistema no ha asignado
ning
un recurso para el y no se ha utilizado el metodo start() para iniciar su ejecucion. En
tal estado, lo u
nico que podra hacerse es efectuar una llamada al metodo start() o stop().
Cualquier otra operacion causara una excepcion del tipo IllegalThreadStateException.
Ejecutable: Se ha efectuado la llamada al metodo start() y el sistema ha asignado los recursos
necesarios para su ejecucion.
No debe confundirse el hecho de que el proceso ligero este en estado ejecutable con el hecho de
que se esten ejecutando realmente las sentencias de su metodo run().
No ejecutable: El proceso ligero no puede ejecutarse, un proceso ligero entra en este estado por
varios motivos: se ha efectuado una llamada a los metodos sleep(), suspend() o wait() o porque
esta a la espera de realizar una operacion de entrada o salida.
Desactivado: Se alcanza este estado cuando, o bien todas las instrucciones de su metodo run()
se han ejecutado con normalidad, o bien el proceso ligero ha recibido un mensaje stop().

Cambios de Estado en un Proceso Ligero


Desde su creacion, un proceso ligero puede cambiar de un estado a otro, tal como se indica en la
siguiente figura. Dichos cambios de estado pueden ser provocados por la utilizacion de algunos metodos
que se encuentran implementados en la clase Thread del paquete java.lang. En esta seccion se explicaran en detalle algunos de los mas importantes.

La Clase Thread
La clase Thread dispone de los constructores siguientes:
public Thread()

200

Ejecutable

start

Disponible

Stop
fin

resume()
notify()
notifyAll()

Stop
fin

yield()
suspend()
sleep()
wait()
No ejecutable

Stop
fin
Desactivado

public Thread(String n)
public Thread(Runnable obj)
public Thread(Runnable obj, String n)
public Thread(ThreadGroup g, String n)
public Thread(ThreadGroup g, Runnable obj)
public Thread(ThreadGroup g, Runnable obj,
String n)
Para cambiar un proceso ligero a estado ejecutable se llama al metodo start(), que invoca su
metodo run().
Un proceso ligero pasa al estado no ejecutable cuando esta en espera de una operacion de entrada/salida o se ha llama a uno de los metodos:
suspend(): provoca la suspension del metodo run() hasta recibir la orden de continuar.
sleep(long t): provoca el estado no ejecutable por un tiempo de t milisegundos.
wait(): el proceso ligero entre en estado no ejecutable hasta que se produzca una condicion.

Paso a ejecutable
Un proceso ligero puede pasar de no ejecutable a ejecutable de una u
nica forma, que depende
de como entro en el estado no ejecutable. Cualquier otro intento provocara una excepcion del tipo
IllegalThreadStateException:
Si entro con el metodo suspend(): entonces recuperara el estado ejecutable con una llamada al
metodo resume().
Si entro con el metodo sleep(long t): debe transcurrir ese tiempo para que el proceso ligero
vuelva al estado ejecutable.
Si entro con el metodo wait(): es preciso que otro proceso ligero invoque a su metodo notify()
o al metodo notifyAll().

201
El u
ltimo estado en el que se puede encontrar un proceso ligero es desactivado. Puede llegar a el
desde cualquiera de los otros tres estados por dos motivos:
porque finalice la ejecucion de su metodo run() o
por la utilizacion del metodo stop().
El metodo isAlive() permite reconocer si un proceso ligero ha sido iniciado con el metodo start()
pero no finalizado con stop(), es decir, este metodo devuelve true si el metodo esta en estado ejecutable
o no ejecutable.

Prioridad de un Proceso Ligero


Todo proceso ligero tiene una prioridad, de forma que cuando varios procesos ligeros deben compartir
un procesador (como ocurre en la mayora de los casos) el sistema sepa a quien asignarlo.
Los procesos ligeros con prioridad mas alta tienen preferencia sobre los de prioridad mas baja. La
prioridad esta definida por un n
umero en el rango determinado por MIN PRIORITY y MAX PRIORITY
(constantes definidas en la clase Thread con los valores 1 y 10, respectivamente). De acuerdo con este
sistema de prioridades, en maquinas con un u
nico procesador, siempre se estara ejecutando el proceso
ligero con mas alta prioridad que este en estado ejecutable.
El metodo setPriority() asigna al proceso ligero como prioridad el valor mas peque
no entre ese
entero y la prioridad maxima permitida para el grupo al que pertenece. En el caso de que el metodo
setPriority() reciba un valor fuera del rango MIN PRIORITY, MAX PRIORITY se produce una excepcion
del tipo IllegalArgumentException.
El metodo getPriority() devuelve un entero con la prioridad del proceso ligero correspondiente.
Ejemplo:
import java.applet.Applet;
public class Prioridades extends Applet{
public void init () {
new AThread("Primero",1,0).start();
new AThread("Segundo",2,0).start();
new AThread("Tercero",3,10).start();
}
}
class AThread extends Thread {
int delay;
public AThread(String nombre,int pr,int time) {
super(nombre);
setPriority(pr);
delay=time;
}
public void run() {
try {for(int i=1; i<=5; i++) {
System.out.println("Ejecutando "+getName());

202
sleep(delay);
}
} catch (InterruptedException e) {
System.out.println("Interrupcion incorrecta");
}
}
}
Salida: Trabajando sobre un sistema de un solo procesador, la salida en la ventana stdout del programa
anterior debera ser similar a la siguiente:
Ejecutando
Ejecutando
Ejecutando
Ejecutando
Ejecutando
Ejecutando
Ejecutando
Ejecutando
Ejecutando
Ejecutando
Ejecutando
Ejecutando
Ejecutando
Ejecutando
Ejecutando

Tercero
Segundo
Segundo
Tercero
Segundo
Segundo
Tercero
Segundo
Tercero
Primero
Tercero
Primero
Primero
Primero
Primero

Grupos de Procesos Ligeros


En Java, los procesos ligeros pueden agruparse de manera que cada uno de ellos pertenezca a un
grupo. El uso de grupos permite manipular de forma conjunta todos sus procesos ligeros en lugar de
hacerlo individualmente.
La clase ThreadGroup
public ThreadGroup(String nombre)
public ThreadGroup(ThreadGroup g,
String nombre)
String getName()
ThreadGroup getParent()
boolean parentOf(ThreadGroup g)
void setMaxPriority(int pri)
int getMaxPriority()

203
void setDaemon(boolean daemon)
boolean isDaemon()
void stop()
void suspend()
void destroy()
void checkAccess()

Procesos Ligeros Sincronizados


Es com
un que en un programa existan varios procesos ligeros que compartan datos; por ejemplo,
uno de ellos escribe datos en un fichero, mientras que el otro los lee.
En tales casos es preciso que los procesos ligeros act
uen de manera sincronizada.
Ejemplo: Se quiere implementar un algoritmo que eval
ue expresiones de la forma:
xn + xn1 + xn2 + . . . + x2 + x + 1
para cualquier pareja de n
umeros enteros x y n > 0.
Para ello se considera la siguiente expresion equivalente:
x(x(. . . (x(x + 1) + 1) . . .) + 1) + 1
El calculo se reduce a una sucesion de dos operaciones:
Sumar una unidad a un entero.
Multiplicar dos enteros.
La implementacion del algoritmo puede hacerse con dos procesos ligeros, cada uno de ellos especializado
en una de las operaciones elementales comentadas. Ambos procesos ligeros deben estar sincronizados,
ya que trabajaran sobre datos comunes y deben alternarse de forma perfecta en su ejecucion.
Ejemplo:
import java.applet.Applet;
public class Sincronizacion extends Applet{
public void init() {
Datos v = new Datos(2,7);
new SumaThread(v).start();
new ProductoThread(v).start();
}
}
class Datos {
int x,n,acumulado;

204
private boolean test = true;
public Datos (int x, int n) {
this.x=x;this.n=n;acumulado=x;
}
public synchronized void OperaSuma () {
while (test == false) {
try{ wait();
} catch (InterruptedException e) {}
}
acumulado++;test=false;notify();
}
public synchronized void OperaProducto () {
while (test == true) {
try{ wait();
} catch (InterruptedException e) {}
}
acumulado*=x;test=true;notify();
}
}
class SumaThread extends Thread {
Datos susDatos;
public SumaThread (Datos v) {susDatos=v;}
public void run () {
for(int i=1;i<=susDatos.n;i++)
susDatos.OperaSuma();
System.out.println("Resultado = "
+ susDatos.acumulado);
}
}
class ProductoThread extends Thread {
Datos susDatos;
public ProductoThread (Datos v) {susDatos=v;}
public void run () {
for(int i=1;i<=susDatos.n-1;i++)
susDatos.OperaProducto();
}
}

205

Pr
actica 1
class Carrera{
static Animal laLiebre;
static Animal laTortuga;
public static void main(String args[]){
laLiebre=new Animal(5,"L");
laTortuga=new Animal(1,"T");
laTortuga.run();
laLiebre.run();
}
}
class Animal{
int miVelocidad;
String miNombre;
public Animal(int laVelocidad, String elNombre){
miNombre=elNombre;
miVelocidad=laVelocidad;
}
public void duerme(int tiempo){
for(int i=0;i<tiempo;i++){;}
}
public void run(){
for(int i=0;i<10;i++){
System.out.print(miNombre);
duerme(1000/miVelocidad);
}
System.out.println("\n"+miNombre+" ha llegado");
}
}

206

Pr
actica 2
class CarreraHilos{
static Animal laLiebre;
static Animal laTortuga;
public static void main(String args[]){
laLiebre=new Animal(5,"L");
laTortuga=new Animal(1,"T");
laTortuga.start();
laLiebre.start();
}
}
class Animal extends Thread{
int miVelocidad;
String miNombre;
public Animal(int laVelocidad, String elNombre){
miNombre=elNombre;
miVelocidad=laVelocidad;
}
public void run(){
try{for(int i=0;i<10;i++){
System.out.print(miNombre);
sleep(300000/miVelocidad);
}}catch(InterruptedException e){System.out.println("Interrupci
on Incorrecta");}
System.out.println("\n"+miNombre+" ha llegado");
}
}

207

Ejercicio: Gesti
on de un Almac
en
Se trata de simular mediante la tecnica de los procesos ligeros un almacen, en el que hay un productor,
que se encarga de reponer material, y unos consumidores, que compran un n
umero aleatorio de unidades
mientras el almacen permanece abierto.
Para ello, se sugiere el siguiente proceso:
1. Definir una clase ALMACEN, que contenga la siguente informacion:
(a) Cantidad en stock.
(b) Maxima cantidad permitida de compra a cada comprador
(c) Stock mnimo al que hay que reponer.
(d) Cantidad a reponer
(e) Tiempo de apertura del almacen
(f) Si esta abierto o cerrado
(g) Si necesita reponer stock
y permita:
(a) Reponer material
(b) Comprar material
2. Definir una clase PRODUCTOR, que contenga la siguiente informacion:
(a) Almacen que regenta.
y permita:
(a) Reponer material
(b) Cerrar el almacen cuando proceda.
3. Definir una clase CONSUMIDOR, que contenga la siguiente informacion:
(a) Almacen en el que compra.
(b) N
umero de identificacion.
y permita:
(a) Comprar material
4. Escribir un Applet que ponga en funcionamiento el sistema.

208

Clase Tienda
import java.applet.Applet;
class Tienda {
public static void main(String args[]) {
Almacen a = new Almacen();
Productor p1 = new Productor(a);
Consumidor c1 = new Consumidor(a,1);
Consumidor c2 = new Consumidor(a,2);
Consumidor c3 = new Consumidor(a,3);
System.out.println("La cantidad inicial
es de " + a.stock + " unidades.");
p1.start();
c1.start();
c2.start();
c3.start();
}
}

Clase Productor
class Productor extends Thread {
private Almacen almacen;
public Productor(Almacen a) {
almacen = a;
}
public void run() {
while(!almacen.cerrado){
if(System.currentTimeMillis()
-almacen.hora>almacen.TIEMPOAPERTURA){
almacen.cerrado=true;
System.out.println("Se cierra la
tienda.");
}
almacen.reponer();
try {
sleep((int)(Math.random() * 100));
} catch (InterruptedException e) {
}
}
}
}

209

Clase Consumidor
class Consumidor extends Thread {
private Almacen almacen;
private int numero;
public Consumidor(Almacen a,int numero) {
almacen = a;
this.numero = numero;
}
public void run() {
int value;
while(!almacen.cerrado){
value=(int)(Math.random()*
almacen.MAXCOMPRA);
almacen.comprar(numero,value);
}
}
}

Clase Almac
en
class Almacen {
public int stock=100;
private boolean necesitareponer;
public boolean cerrado=false;
final int MAXCOMPRA=30;
final int LIMITEREPONER=50;
final int CANTIDADREPONER=100;
final long TIEMPOAPERTURA=3000;
long hora=System.currentTimeMillis();
public synchronized void comprar(int consumidor,
int cantidad) {
while (necesitareponer == true) {
try {
wait();
} catch (InterruptedException e) {
}
}
if(!cerrado){
if(stock<cantidad){
cantidad=stock;
}
stock-=cantidad;
System.out.println("Quedan " + stock +
" unidades. El Consumidor " + consumidor

210
+ " ha comprado " + cantidad +
" unidades.");
if(stock<=LIMITEREPONER)
necesitareponer = true;
}
notify();
}
public synchronized void reponer() {
if (!cerrado){
while (necesitareponer == false) {
try {
wait();
} catch (InterruptedException e) {
}
}
stock+=CANTIDADREPONER;
System.out.println("Quedan " + stock
+ " unidades. El Productor repuso " +
CANTIDADREPONER + " unidades.");
necesitareponer = false;
}
notify();
}
}

Programa Completo
import java.applet.Applet;
class Tienda {
public static void main(String args[]) {
Almacen a = new Almacen();
Productor p1 = new Productor(a);
Consumidor c1 = new Consumidor(a,1);
Consumidor c2 = new Consumidor(a,2);
Consumidor c3 = new Consumidor(a,3);
System.out.println("La cantidad inicial
es de " + a.stock + " unidades.");
p1.start();
c1.start();
c2.start();
c3.start();
}
}
class Productor extends Thread {

211
private Almacen almacen;
public Productor(Almacen a) {
almacen = a;
}
public void run() {
while(!almacen.cerrado){
if(System.currentTimeMillis()
-almacen.hora>almacen.TIEMPOAPERTURA){
almacen.cerrado=true;
System.out.println("Se cierra la tienda.");
}
almacen.reponer();
try {
sleep((int)(Math.random() * 100));
} catch (InterruptedException e) {
}
}
}
}
class Consumidor extends Thread {
private Almacen almacen;
private int numero;
public Consumidor(Almacen a,int numero) {
almacen = a;
this.numero = numero;
}
public void run() {
int value;
while(!almacen.cerrado){
value=(int)(Math.random()*almacen.MAXCOMPRA);
almacen.comprar(numero,value);
}
}
}
class Almacen {
public int stock=100;
private boolean necesitareponer;
public boolean cerrado=false;
final int MAXCOMPRA=30;
final int LIMITEREPONER=50;
final int CANTIDADREPONER=100;

212
final long TIEMPOAPERTURA=3000;
long hora=System.currentTimeMillis();
public synchronized void comprar(int consumidor,
int cantidad) {
while (necesitareponer == true) {
try { wait();
} catch (InterruptedException e) {
}
}
if(!cerrado){
if(stock<cantidad){
cantidad=stock;
}
stock-=cantidad;
System.out.println("Quedan " + stock +
" unidades. El Consumidor " + consumidor
+ " ha comprado " +cantidad+" unidades.");
if(stock<=LIMITEREPONER)
necesitareponer = true;
}
notify();
}
public synchronized void reponer() {
if (!cerrado){
while (necesitareponer == false) {
try { wait();
} catch (InterruptedException e) {
}
}
stock+=CANTIDADREPONER;
System.out.println("Quedan " + stock
+ " unidades. El Productor repuso " +
CANTIDADREPONER + " unidades.");
necesitareponer = false;
}
notify();
}
}

Y SONIDO
ANIMACION

214

Animaci
on de Gr
aficos
Mostrar sucesivos fotogramas con cierta rapidez (10-20 por segundo).
Debe utilizarse un proceso ligero (thread) que se encargue de ejecutar el ciclo de la animacion.
A continuacion se muestra un programa, que es un ejemplo de una animacion.
El significado de las variables es como sigue:
umero del fotograma que se esta mostrando en un cierto instante.
numFotograma: da el n
frecuencia: da el maximo del n
umero de
fotogramas/segundo.

tiempoDemora: da el n
umero de milesimas de segundo que trascurren entre fotogramas. Este
se
calcula a partir del valor de la variable frecuencia.
animacionThread: es un objeto de la clase Thread, que representa el proceso ligero que se encarga
de la animacion.
time: da el tiempo transcurrido en milisegundos.
Los metodos utilizados son:
init(): simplemente, asigna blanco al color del fondo.
start(): crea el proceso ligero en caso de que no exista y lo arranca.
stop(): para el proceso ligero.
run(): que contiene el ciclo de la animacion dentro del bucle while, en el que se incrementa en
una unidad el n
umero del fotograma, se llama al metodo repaint() por defecto y se interrumpe su
ejecucion durante el tiempo de demora. El metodo repaint() llama automaticamente al metodo
paint() y este a su vez utiliza el metodo paintAnimation() para dibujar el grafico que se muestra
en la Figura, girandolo un grado, en el sentido de las agujas del reloj, en cada fotograma.
paint(): llama al metodo paintAnimation().
paintAnimation(): dibuja un fotograma con el angulo que le corresponde.

Ejemplo de Gr
afico Animado
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class Anim extends Applet
implements Runnable {

215

int numFotograma= -1;


int frecuencia=20;
int tiempoDemora=1000/frecuencia;
Thread thread;
public void init() {
setBackground(Color.white);
addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent me){
if(thread==null){start();}
else{stop();}
}});
}
public void start() {
if(thread == null) {
thread = new Thread(this);
thread.start();
}
}
public void stop() {
thread = null;
}
public void run() {
long time=System.currentTimeMillis();
while (Thread.currentThread() == thread) {
time+=tiempoDemora;
numFotograma++;
repaint();
try {
Thread.sleep(Math.max(
0,time-System.currentTimeMillis()));
} catch (InterruptedException e) {
break;
}
}
}
public void paint(Graphics g)
{
paintAnimation(g);
}
public void paintAnimation(Graphics g) {
int x0, y0,ovalWidth=10,ovalHeight=10;

216
int radio=100,radio1=80;
float angulo;
for(int i=0;i<20;i++){
angulo=
(float)((numFotograma+10*i)*0.0174533);
g.fillOval((int)(150+
radio*Math.cos(angulo)),(int)(150+radio*
Math.sin(angulo)),ovalWidth, ovalHeight);
g.drawOval((int)(150+radio1*
Math.cos(angulo)), (int)(150+
radio1*Math.sin(angulo)),ovalWidth,
ovalHeight);
}
}
}
Observese que el programa anterior produce la animacion, pero se genera un parpadeo de la imagen
debido a varias razones:
1. Por defecto, antes de llamar al metodo paint() se borra el fondo de la animacion, por lo que se
ve un fotograma blanco entre fotogramas sucesivos.
2. Se van mostrando en pantalla distintas partes del dibujo hasta mostrarse el dibujo completo de
un fotograma, dando esa impresion de parpadeo.
Vamos a eliminar dicho parpadeo, creando una imagen del tama
no apropiado fuera de la pantalla y
enviandola a la misma mediante el metodo drawImage(), solo cuando la imagen este completa.

Eliminamos el Parpadeo en el Gr
afico Anterior
import java.awt.*;
import java.applet.Applet;
import java.applet.event.*;
public class Anim extends Applet
implements Runnable {
int numFotograma= -1;
int frecuencia=20;
int tiempoDemora=1000/frecuencia;
Thread thread;
Image imag;
Graphics grafic;
Dimension dimen;
public void init() {
setBackground(Color.white);
addMouseListener(new MouseAdapter(){

217
public void mouseClicked(MouseEvent me){
if(thread==null){start();}
else{stop();}
}});
}

public void start() {


if(thread == null) {
thread = new Thread(this);
thread.start();
}
}
public void stop() {
thread = null;
}
public void run() {
long time=System.currentTimeMillis();
while (Thread.currentThread() == thread) {
time+=tiempoDemora;
numFotograma++;
repaint();
try {
Thread.sleep(Math.max(0,
time-System.currentTimeMillis()));
} catch (InterruptedException e) {
break;
}
}
}
public void paint(Graphics g)
{
if(imag!=null)
g.drawImage(imag,0,0,this);
}
public void update(Graphics g)
{
Dimension d=getSize();
if((grafic==null) ||(d.width!=dimen.width)
||(d.height!=dimen.height)){
dimen=d;
imag=createImage(d.width,d.height);

218
grafic=imag.getGraphics();
}
grafic.setColor(getBackground());
grafic.fillRect(0,0,d.width,d.height);
grafic.setColor(Color.black);
paintAnimation(grafic);
g.drawImage(imag,0,0,this);
}
public void paintAnimation(Graphics g) {
int x0, y0,ovalWidth=10,ovalHeight=10;
radio=100,radio1=80;
float angulo;
for(int i=0;i<20;i++){
angulo=(float)((numFotograma+10*i)*0.0174533);
g.fillOval((int)(150+radio*Math.cos(angulo)),
(int)(150+radio*Math.sin(angulo)),ovalWidth,
ovalHeight);
g.drawOval((int)(150+radio1*Math.cos(angulo)),
(int)(150+radio1*Math.sin(angulo)),ovalWidth,
ovalHeight);
}
}
}

Mover una Im
agenes sobre Otras
Este metodo consiste en mover una imagen sobre otra que esta en el fondo.
En este programa tambien se utiliza un doble amortiguador para eliminar el parpadeo. Los cambios
con respecto al programa anterior son:
1. Se crean las variables mar y barco para almacenar las imagenes del mar y del barco, respectivamente.
Image mar;
Image barco;
2. Se cargan las imagenes de ambos en las variables correspondientes:
mar=getImage(getDocumentBase(),
"ejemplo/mar.gif");
barco=getImage(getDocumentBase(),
"ejemplo/barco.gif");
3. Se cambia el metodo paintAnimation():

219
public void paintAnimation(Graphics g) {
int w1 = mar.getWidth(this);
int h1 = mar.getHeight(this);
if((w1>0)&&(h1>0)){
g.drawImage(mar,0,0,this);
}
int w = barco.getWidth(this);
int h = barco.getHeight(this);
if((w>0)&&(h>0)){
g.drawImage(barco, (numFotograma*2)%(w1-w),
((h1-h)/2)+3,this);
}
}

Mostrar una Secuencia de Im


agenes
En el ejemplo siguiente se crea una matriz de imagenes que se van mostrando una a una. Se utiliza
de nuevo un doble regulador para eliminar el parpadeo. El metodo paintAnimation() se limita a
mostrar la imagen correspondiente.

Ejemplo:
import java.awt.*; import java.applet.*; public class Secuencia
extends Applet implements Runnable {
int numFotograma=0;
Thread thread;
Image imagenes[];
public void init() {
imagenes = new Image[8];
for (int i = 1; i <= 8; i++)
imagenes[i-1] = getImage(getDocumentBase(),"CARA"+i+".gif");
}
public void start() {
if (thread == null) {

220
thread = new Thread(this);
thread.start();
}
}
public void stop() {
thread = null;
}
public void run() {
while (thread!=null) {
numFotograma++;
if(numFotograma>7)numFotograma=0;
repaint();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
}
}
public void paint(Graphics g) {
g.drawImage(imagenes[numFotograma],0,0,this);
}
}
Ejemplo:
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class Secuencia extends Applet
implements Runnable {
int numFotograma=0;
int frecuencia=5;
int tiempoDemora=1000/frecuencia;
Thread thread;
Dimension dimen;
Image imag;
Graphics grafic;
Image imagenes[];
public void init() {
imagenes = new Image[8];
for (int i = 1; i <= 8; i++) {
imagenes[i-1] = getImage(getDocumentBase(),
"CARA"+i+".gif");
}
addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent me){
if(thread==null){start();}
else{stop();}

221
}});
}
public void start() {
thread = new Thread(this);
thread.start();
}
public void stop() {
thread = null;
}
public void run() {
long time=System.currentTimeMillis();
while (Thread.currentThread() == thread) {
time+=tiempoDemora;
numFotograma++;
repaint();
try {
Thread.sleep(Math.max(
0,time-System.currentTimeMillis()));
} catch (InterruptedException e) {
break;
}
}
}
public void paint(Graphics g) {
update(g);
}
public void update(Graphics g) {
Dimension d = getSize();
if ( (grafic == null)||(d.width != dimen.width)
|| (d.height != dimen.height) ) {
dimen = d;
imag = createImage(d.width, d.height);
grafic = imag.getGraphics();
}
grafic.setColor(getBackground());
grafic.fillRect(0,0,d.width,d.height);
grafic.setColor(Color.black);
paintAnimation(grafic);
g.drawImage(imag,0,0,this);
}
public void paintAnimation(Graphics g){
if(numFotograma>7)
numFotograma=0;
g.drawImage(imagenes[numFotograma],0,0,null);
}
}

222

Utilizaci
on de la Clase
MediaTracker
Algunos de los metodos mas u
tiles de la clase MediaTracker son:
El metodo addImage(Image imag, int id) permite
a
nadir una imagen a la lista que se quiere controlar. Ademas, a cada imagen se le puede asignar
un identificador, de forma que las que tienen un ID mas peque
no se cargan antes.
Los metodos checkAll() y checkID(int id) permiten saber si las imagenes ya han sido cargadas.
Los metodos getErrorsAny() y getErrorsID(int id) muestran los errores que se cometen durante la carga de las imagenes.
Los metodos statusAll() y statusID(int id) devuelven los estados en que se encuentran las
imagenes que se estan cargando.
Los metodos waitForAll() y waitForID(int id) cargan todas las imagenes o la indicada por
su id, esperando a que se complete la carga.
Para incorporar el control de las imagenes mediante la clase MediaTracker, al codigo anterior se le
a
naden las lneas siguientes:
1. Se inicializa la variable tracker de la clase MediaTracker:
MediaTracker tracker;
2. En el metodo init() se cargan las imagenes y se a
naden al controlador:
for (int i = 1; i <= 3;i++) {
imagenes[i-1] = getImage(getDocumentBase(),
"CARA"+i+".gif");
tracker.addImage(imagenes[i-1], 0);
}
3. En el metodo update(), se pregunta si las imagenes ya estan cargadas y entonces se dibujan:
if (tracker.statusID(0,true) ==
MediaTracker.COMPLETE) {
if(numFotograma>7)
numFotograma=0;
grafic.drawImage(imagenes[numFotograma],
0,0,this);
g.drawImage(imag,0,0,this);
}
}

223

Sonido
El lenguaje Java permite trabajar con sonidos mediante algunos comandos de la clase Applet y la
interfase AudioClip. El lenguaje Java soporta sonidos en formato .au.
En el paquete Applet se encuentran los siguientes metodos:
getAudioClip(URL url)
Localiza el sonido especificado por el argumento correspondiente a la variable url.
getAudioClip(URL url, String name)
Localiza el sonido especificado por los argumentos url y name.
play(URL url)
Emite el sonido correspondiente al objeto url. Si el sonido no puede encontrarse no ocurre
nada.
play(URL url, String name)
Emite el sonido correspondiente al objeto url y a name. Si el sonido no puede encontrarse
no ocurre nada.
En la interfase AudioClip se definen los siguientes metodos:
loop()
Comienza a emitir el sonido repitiendose automaticamente sin parar.
play()
Emite este sonido una sola vez. Cada vez que se llama a este metodo, el sonido se emite
desde su comienzo.
stop()
Interrumpe la emision del sonido.
La nueva version de JDK, permite crear audioclips tanto para applets como para aplicaciones.
Ademas los clips pueden estar en uno de los siguientes formatos: AIFF, AU, WAV, MIDI,RMF.
Ejemplo:
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Piano extends Applet implements
ActionListener{
String items[] = {"C","D","E","F","G","A","B",
"C"};

224
Button auxButton[]=new Button[items.length];
public void init()
{
setLayout (new GridLayout(1, 8));
int i;
for (i= 0; i < items.length; i++){
auxButton[i]=new Button(items[i]);
auxButton[i].addActionListener(this);
add (auxButton[i]);
}
}
public void actionPerformed(ActionEvent evt)
{
String arg=evt.getActionCommand();
{
if (arg.equals("C"))
play (getDocumentBase(), "cnote.au");
else if (arg.equals("D"))
play (getDocumentBase(), "dnote.au");
else if (arg.equals("E"))
play (getDocumentBase(), "enote.au");
else if (arg.equals("F"))
play (getDocumentBase(), "fnote.au");
else if (arg.equals("G"))
play (getDocumentBase(), "gnote.au");
else if (arg.equals("A"))
play (getDocumentBase(), "anote.au");
else if (arg.equals("B"))
play (getDocumentBase(), "bnote.au");
else if (arg.equals("C"))
play (getDocumentBase(), "c1note.au");
}
}
}
Ejemplo:
import java.applet.*;
import java.awt.*;
public class SoundApplet extends Applet
implements ActionListener{
AudioClip sound;
Button button1;
Button button2;
Button button3;

225
boolean estadoLoop;
public void init() {
estadoLoop=false;
button1=new Button("Play");
button1.addActionListener(this);
button2=new Button("Loop");
button2.addActionListener(this);
button3=new Button("Stop");
button3.addActionListener(this);
add(button1);
add(button2);
add(button3);
sound=getAudioClip(getDocumentBase(),
"sonido.au");
validate();
}

public void stop() {


if(estadoLoop)
sound.stop();
}
public void start() {
if(estadoLoop)
sound.loop();
}
public void actionPerformed(ActionEvent ae){
Object componente=ae.getSource();
if(componente.equals(button1){
sound.play();
showStatus("play");
}
else if(componente.equals(button2){
estadoLoop=true;
sound.loop();
showStatus("loop");
}
else if(componente.equals(button3){
estadoLoop=false;
sound.stop();
showStatus("stop");
}
}
}

DE FICHEROS
GESTION

227

Introducci
on
Es de sobra conocido que las diferentes maquinas y sistemas operativos utilizan diferentes representaciones para almacenar la informacion en la memoria del ordenador (memoria RAM, discos duros,
etc.). Cuando se quiere acceder a esta informacion (datos) se necesita conocer como esta almacenada.
Lo malo es que al cambiar de maquina, tambien cambia la forma de almacenamiento, por lo que los
programas de lectura y escritura de datos dependen de la maquina. Ello da lugar a la existencia de
notables problemas de compatibilidad entre plataformas y conduce a la necesidad de transformar unos
sistemas en otros mediante programas adecuados.
Una de las ideas centrales del lenguaje Java es la creacion de un sistema de trabajo independiente
de la maquina. El paquete Java.io permite trabajar con los datos con esa independencia. Se trata,
por tanto, de transformar todo a un mismo sistema de forma que el usuario no tenga que preocuparse
de que tipo de maquina o sistema esta utilizando. Ello naturalmente conduce a una utilizacion facil y
comoda y a una compatibilidad muy deseables.

Entrada y Salida de Datos


Las clases del paquete java.io hacen referencia al concepto de flujo, (stream). Corrientes que permiten
la lectura o escritura de datos desde o en un archivo o pantalla. De esta forma tendremos flujos de
entrada y de salida con sus correspondientes metodos de lectura y escritura. Todas las clases derivadas
de las clases InputStream o Reader poseen metodos read() para leer un byte o un array de bytes. Y las
derivadas de las clases OutputStream o Writer tienen metodos write() para escribir un byte o un array
de bytes.
Entrada
InputStream
FilterInputStream
BufferedInputStream
DataInputStream
PushbackInputStream
ByteArrayInputStream
FileInputStream
ObjectInputStream
PipedInputStream
SequenceInputStream
Reader
BufferedReader
LineNumberedReader
CharArrayReader
FilterReader

228
PushbackReader
InputStreamReader
FileReader
PipedReader
StringReader
Una clase para flujos de datos (InputStream) y otra para caracteres Unicode (16 bits) para soportar
internacionalizacion
(Reader).
Salida
OutputStream
FilterOutputStream
BufferedOutputStream
DataOutputStream
PushbackOutputStream
ByteArrayOutputStream
FileOutputStream
ObjectOutputStream
PipedOutputStream
Writer
BufferedWriter
CharArrayWriter
FilterWriter
OutputStreamWriter
FileWriterr
PipedWriter
StringWriter
Una clase para flujos de datos (OutputStream) y otra para caracteres Unicode (16 bits) para soportar
internacionalizacion (Writer).

Ejemplo 1
Lee los datos del fichero Fichero1.txt (caracteres o n
umeros) y los escribe en Fichero2.txt.

229
import java.io.*;
class LeerEscribir {
public static void main(String args[]) {
try {
File leer = new File("file1");
FileInputStream f1 =
new FileInputStream(leer);
File escribir = new File("file2");
FileOutputStream f2 =
new FileOutputStream(escribir);
int c;
while ((c = f1.read()) != -1) {
f2.write(c);
}
f1.close();
f2.close();
} catch (Exception e) {
System.out.println("LeerEscribir: " + e);
}
}
}
Se crean dos objetos de la clase File que representan los dos ficheros que se van a manejar. El constructor
toma como argumento el nombre del fichero correspondiente. La corriente FileInputStream permite
leer datos del fichero dado como argumento en su construc tor. La corriente FileOutputStream permite
escribir datos en el fichero dado como argumento en su constructor. Leemos los datos de Fichero1.txt
a traves de su corriente asociada gracias al metodo int read() de la clase FileInputStream que lee un
byte cada vez que es llamado y devuelve -1 si se alcanza final de fichero. Cada byte c ledo se escribe en
el fichero Fichero2.txt a traves de su corriente asociada mediante el metodo public void write(int
b) de la clase FileOutputStream que escribe el byte dado como argumento en la corriente f2, y por
tanto en el segundo fichero. Por u
ltimo, el metodo public void close() cierra ambas corrientes.

Ejemplo 2
Escribe en un fichero el n
umero introducido en el teclado.
import java.io.*;
class LeerEscribir {
public static void main(String args[]) {
int aux;
System.out.println("Escribir un numero entero:");
try {
FileOutputStream fos =
new FileOutputStream("Lista");
aux=System.in.read();

230
aux+=2;
fos.write(aux);
fos.close();
} catch (IOException e) {
System.out.println("LeerEscribir: " + e);
}
}
}
El metodo int read(byte[] b) de la clase InputStream lee bytes de la corriente in (de pantalla) y
los almacena en el array aux dado como argumento. Lee tantos bytes como elementos pueda almacenar
su array argumento. El metodo void write(byte[] b) de la clase FileOutputStream escribe los bytes
del array aux dado como argumento en f1 y, por tanto, en el fichero.

Ejemplo 3
Escribe y lee datos formateados.
import java.io.*;
class LeerEscribir {
public static void main(String args[]) {
int aux=0;
try {
DataOutputStream sum =
new DataOutputStream(
new FileOutputStream("Suma"));
for(int i=0;i<6;i++){
sum.writeInt(i+1);
sum.writeChar(\n);
}
sum.close();
DataInputStream dat =
new DataInputStream(
new FileInputStream("Suma"));
while(aux!=5){
aux=dat.readInt();
dat.readChar();
System.out.println(aux);
}
dat.close();
} catch (IOException e) {
System.out.println("LeerEscribir: " + e);}}}
Las clases DataOutputStream y DataInputStream permiten escribir y leer datos primitivos for
mateados. En primer lugar creamos una corriente de escritura formateada sum dando como argumento al constructor un objeto de la clase FileOutputStream asociado al chero sum.txt. De esta
forma el metodo final void writeInt(int v) de la clase DataOutputStream escribe en el fichero, a
traves de las corrientes intermedias, los enteros 0,1,2,3,4,5 en formato de cuatro bytes; el metodo void

231
writeChar(int v) de la clase DataOutputStream escribe el caracter cambio de lnea tras cada entero,
en formato de dos bytes. Escrita la columna de enteros en el fichero sum.txt se realiza el proceso
inverso. A traves de una corriente dat de lectura, (construida mediante un objeto FileInputStream
asociado al fichero), vamos leyendo cada entero y cada caracter cambio de lnea del fichero gracias a
los metodos int readInt() y char readChar() de la clase DataInputStream. y los imprimimos en
pantalla.

Ejemplo 4
Escribe caracteres en un fichero.
import java.io.*;
class LeerEscribir {
public static void main(String args[]) {
try {
String str1="Esto es una prueba");
String str2="Utilizo la clase FileWriter";
int aux1=1;
double aux2=2.3;
File f=new File("Lista");
FileWriter dat=new FileWriter(f);
dat.write(str1);
dat.write(\n);
dat.write(str2);
dat.write(" "+aux1);
dat.write(\n);
dat.write(" "+aux2);
dat.close();
}
} catch (IOException e) {
System.out.println("LeerEscribir: " + e);
}
}
}
La clase FileWriter es adecuada para escribir ficheros de caracteres. Creamos un objeto de dicha
clase dando como argumento al constructor el objeto File que representa el fichero que queramos escribir. Los metodos void write(String str) y void write(int c) de la superclase Writer escriben
en el fichero cadenas de caracteres o un u
nico caracter.

Ejemplo 5
Lee caracteres de un fichero.
import java.io.*;
class LeerEscribir {

232
public static void main(String args[]) {
try {
int NMaxChar=200;
char[] texto=new char[NMaxChar];
File f=new File("Lista");
FileReader dat=new FileReader(f);
dat.read(texto);
dat.close();
System.out.println(texto);
dat.close();
}
} catch (IOException e) {
System.out.println("LeerEscribir: " + e);
}
}
}
La clase FileReader es adecuada para leer ficheros de caracteres. Creamos un objeto de dicha
clase dando como argumento al constructor el objeto File que representa el fichero que queramos leer.
Los metodos int read(char b[]) y int read() de la superclase Reader leen del fichero cadenas de
caracteres o un u
nico caracter.

Ejemplo 6
Lee lneas de texto del teclado.
import java.io.*;
class LeerEscribir {
public static void main(String args[])
throws IOException {
system.out.print(">");
InputStreamReader is=
new InputStreamReader(System.in);
BufferedReader fis=new BufferedReader(is);
String inputLine=fis.readLine();
fis.close();
OutputStreamWriter os=
new OutputStreamWriter(System.out);
BufferedWriter fos=new BufferedWriter(os);
fos.write(inputLine,0,inputLine.length());
fos.newLine();
fos.close();
}
}

233
System.in es un flujo orientado a bytes. InputStreamReader es un puente entre estos y los flujos
orientados a caracteres. BufferedReader contiene el metodo readLine() que nos permite leer una
lnea de texto. BufferedReader y BufferedReader

Ejemplo 7
import java.io.*;
class LeerEscribir {
public static void main(String args[])
throws IOException {
double x;
InputStreamReader is=
new InputStreamReader(System.in);
BufferedReader fis=new BufferedReader(is);
String inputLine=fis.readLine();
fis.close();
Double d=new Double(inputLine);
x=d.doubleValue();
System.out.println(x)
}
}

Ejemplo 8
Lee texto de un fichero.
import java.io.*;
class LeerEscribir {
public static void main(String args[])
throws IOException {
double x;
FileReader is=new FileReader(args[0]);
BufferedReader fis=new BufferedReader(is);
String inputLine=fis.readLine();
while((inputLine!=null)){
System.out.println(inputLine);
inputLine=fis.readLine();
}
fis.close();
}
}
La clase FileReader es subclase de InputStreamReader, esta clase admite constructor String con
el nombre de un fichero.

234

Ejemplo 9
Lee strings de un fichero.
import java.io.*;
class LeerEscribir {
public static void main(String args[])
throws IOException {
String inputLine="Esto es una prueba";
FileWriter os=new FileWriter("Prueba.txt");
BufferedWriter fos=new BufferedWriter(os);
fos.write(inputLine,0,inputLine.length());
fos.newLine();
fos.close();
FileReader is=new FileReader("Prueba.txt");
BufferedReader fis=new BufferedReader(is);
String leido=fis.readLine();
fis.close();
System.out.println("He leido de Prueba.txt:"+
leido);
}
}

Ejemplo 10
Aplicacion que lee datos de un fichero y los escribe en un area de texto.
import java.io.*;
import java.awt.*;
import java.awt.event.*;
public class FileViewer extends Frame
implements ActionListener{
TextArea textarea;
public FileViewer(){
textarea=new TextArea("",24,80);
textarea.setFont(
new Font("MonoSpaced", Font.PLAIN,12));
textarea.setEditable(false);
add("Center",textarea);
Panel p=new Panel();
p.setLayout(
new FlowLayout(FlowLayout.RIGHT,10,5));
add(p,"South");

235
Font font=new Font("SansSerif", Font.BOLD,14);
Button openfile=new Button("Open File");
Button close=new Button("Close");
openfile.addActionListener(this);
close.addActionListener(this);
p.add(openfile);
p.add(close);
}
public void setFile(String filename){
String str;
try{
FileReader f=
new FileReader(new File(filename));
BufferedReader in=new BufferedReader(f);
while((str=in.readLine())!=null){
textarea.append(str);
textarea.append("\n");
}
}catch(IOException e){ }
}
public void actionPerformed(ActionEvent e){
String cmd=e.getActionCommand();
if(cmd.equals("Open File")){
FileDialog f=
new FileDialog(this,"Open file",FileDialog.LOAD);
f.show();
setFile(f.getFile());
f.dispose();
}
else if(cmd.equals("close"))
this.dispose();
}
public static void main(String[] args){
FileViewer f=new FileViewer();
f.setSize(200,200);
f.setVisible(true);
}
}

Ejemplo 11
Un archivo .zip contiene un conjunto de entradas que se corresponden con archivos comprimidos.
ZipFile.entries() y cada uno de estos ZipEntry puede ser abierto como un
InputStream, getInputStream(), del cual podemos leer datos. Tambien se pueden crear archivos .zip.

236
GZipOutputStream y GZipInputStream admite Salida y Entrada de flujos comprimidos en formato
GZIP(.gz).
import java.io.*;
import java.util.*;
import java.util.zip.*;
class UnzipApp {
public static void main(String args[])
throws IOException {
ZipFile f= new ZipFile(args[0]);
Enumeration entradas=f.entries();
System.out.println("Descomprimiendo"+
args[0]+"...");
while(entradas.hasMoreElements()){
ZipEntry entrada=
(ZipEntry) entradas.nextElement();
System.out.println(" "+entrada.getName());
InputStream in=f.getInputStream(entrada);
FileOutputStream fos=
new FileOutputStream(entrada.getName());
for(int ch=in.read();ch!=-1;ch=in.read())
fos.write(ch);
fos.close();
in.close();
}
f.close();
}
}

Você também pode gostar