Sunteți pe pagina 1din 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 Interes 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
5

Programacion Orientada a Objetos

Java es un Lenguaje Orientado a Objetos que incorpora una gran numero de clases predefinidas orga-
nizadas 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

Programacion Orientada a Objetos

Un objeto es un conjunto constituido por una o varias variables y, opcionalmente, por me-
todos.

Todo aquello que el objeto conoce (estado) se expresa por sus variables, y todo lo que puede hacer
(comportamiento) se expresa por sus metodos.
6

ESTADO VARIABLES MIEMBRO

OBJETO

COMPORTAMIENTO MTODOS

MTODO 1

VARIABLES MTODO
MTODO MIEMBRO
3 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
7

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

Declaracion 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 mayuscula.


Cuerpo de una clase
El cuerpo de una clase contiene dos secciones:
1. Declaracion de sus variables.

2. Definicion de sus metodos.

DeclaracionClase{
declaracionVariablesMiembro
...
declaracionMetodos
}

Declaracion 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;

Declaracion 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 numero y tipo de argumentos requeridos por dicho metodo.

tipo metodo(argumentos){
...
}

Si un metodo no devuelve ningun 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;
}
}

Creacion y Utilizacion 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
multiple:

String str = new String(h,o,l,a);

Con esta declaracion se realizan tres acciones:

1. Declaracion: se declara una variable de tipo String cuyo nombre es str

2. Creacion del objeto: el operador new crea un nuevo objeto de tipo String

3. Iniciacion: 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 numero 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 contin-
uacion 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 super-
clase. Sin embargo, las subclases no estan limitadas al estado y comportamiento de su superclase, ya
que las subclases pueden:
Anadir nuevas variables miembro.

Anadir nuevos metodos a los heredados de la superclase.

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; }
}

Declaracion de una Clase


En la declaracion de una clase se puede:
Declarar cual es su superclase.

Listar las interfases que implementa.

Declarar si es publica, 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 publica

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 publica, 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: Disenamos una clase que busca informacion en una base de datos que contiene infor-
macion secreta. Cierta informacion, la disponible a traves de los metodos y variables publicos 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; //no permitido
d.protVar=2; //permitido
a.metodo1(); //no permitido
d.metodo1(); //permitido
}
}

Acceso publico

Cualquier clase en cualquier paquete tiene acceso a las variables y metodos publicos 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 ningun 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 Metodos Abstractos


Algunas veces necesitamos implementar un concepto abstracto.
Por ejemplo, podemos definir una aplicacion que dibuje crculos, rectangulos, etc. Todos estos ob-
jetos 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 sub-
clases. 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 nucleo 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 pequenos 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 numeros aleatorios.
Acceso a las propiedades del sistema.

Paquete java.net

Soporta todo lo relacionado con la red. Es util para construir applets que necesitan utilizar
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 com-
ponentes 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)

ac + bd ad bc
(a, b)/(c, d) = ( , ).
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

Creacion de Applets y Aplicaciones

PROGRAM A
JAVA

MiPrograma.java

COMPILA DOR INTRPR ETE

MiPrograma.class

0010110100

MI
PROGRAMA

Creacion de aplicaciones

Las aplicaciones son programas autonomos que no necesitan de un navegador para ejecutarse.

1. Creacion del codigo fuente


Debe utilizarse algun 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. Compilacion del codigo fuente


La compilacion se puede efectuar directamente con un editor de Java (Kawa, JCreator, etc.),
utilizando la opcion Compile del menu 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 anadiendo a la variable Path, el camino donde se halla el compi-
lador. Para ello basta con escribir en el fichero autoexec.bat,

SET PATH=C:\Archivos de programa\Java\jdk1.5.0_07\bin\;

3 Ejecucion de la aplicacion La ejecucion se puede hacer con un editor de Java (Kawa, JCreator,
etc.), en particular, utilizando la opcion Run del menu 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 Perez"

Creacion de applets
31

1. Creacion del codigo fuente


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. Compilacion del codigo fuente: Similar al caso de las aplicaciones.


Se generan tantos ficheros .class como clases definidas en el fichero fuente.

3 Integracion en un documento HTML


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 Ejecucion 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 menu Build.

La orden que debe darse desde el DOS:


appletviewer Ejemplo.html

Ejemplo aplicacion

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 actua. 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 tamano de la memoria necesario para almacenarla y como debe inter-
pretarse 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 (mayuscula o minuscula) o con un signo de subrayado (_).

2. El resto del nombre puede estar formado por combinaciones de letras, numeros y signos de sub-
rayado. 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:

Basicas: 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 unico valor que
puede tomar una expresion de este tipo.

Tipo Tamano Mnimo Maximo


byte 8 bits 256 255
short 16 bits 32768 32767
int 32 bits 2147483648 2147483647
long 64 bits 9223372036854775808 922337203685477580
float 32 bits 224 E 149 224 E104
double 64 bits 253 E 1045 253 E1000
boolean N/A false true
char 16 bits 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 numeros
almacenados en coma flotante.
Los numeros en coma flotante pueden almacenar valores mas grandes y mas pequenos que los
enteros.
Campo de Accion de una Variable
Se denomina campo de accion 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.

Parametro 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.

Parametro de un manipulador de excepciones. Es el argumento de un manipulador de excep-


ciones.

Iniciacion 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 pro-
grama. Se las precede del adjetivo final. Por convenio, las constantes se escriben todas en mayusculas.
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.

/** documentacion */. 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 logicos

de asignacion

Operadores Aritmeticos
Los operadores aritmeticos binarios, salvo el operador %, que solo actua con enteros, manejan indis-
tintamente los tipos enteros y los de coma flotante.
Cuando un operador tiene operandos de diferente tipo, estos se convierten a un tipo comun siguiendo
las reglas:
la categora de los tipos, de mayor a menor, es la siguiente: double, float, long, int,
short,char.
39

Operadores Binarios
Operador Operacion Descripcion
+ 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.

Operadores Unarios
Operador Operacion Descripcion
+y- +a y -a Fijan el signo del operando
++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 ultimas 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

Operadores Relacionales
Operador Empleo Descripcion
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 Descripcion
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 Asignacion
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 Asignacion
Operador Empleo Descripcion
+= 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 multiplos de 2. Estos podran almacenarse as:

int m1 = 2;
int m2 = 4;
int m3 = 6;
...
int 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 expresion 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 algun 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 numero 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 declaracion: 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 segun 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 numero 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 evaluan 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 ultimo 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 ano es bisiesto o no
lo es, dado un ano cualquiera.
Nota: Una ano es bisiesto si es divisible por 4 pero no por 100. Un ano 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 unica 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 numero de das de cada mes en un ano 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;
case 4:
case 6:
case 9:
case 11:
numDias=30;
break;
case 2:
if(((a%4==0) && !(a%100==0))||
(a%400==0))
numDias=29;
else
numDias=28;
break;

}
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 numeros 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 numeros 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 evaluan 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 evalua 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
Actua 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 evalua 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 numero (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 numero (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 Bifurcacion
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 ultimo caso, la
sintaxis es: return expresion;

Algoritmo de la Biseccion para la Busqueda de un Numero 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. 1:56
Iter. 2:28
Iter. 3:14
Iter. 4:7
Iter. 5:11
Iter. 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 Numero 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");
}
}

Generacion de una Piramide de Numeros 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 Metodo main()
El metodo main() es el metodo de arranque de toda aplicacion 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 Si
mtodo main?

Enva un mensaje Arranca el


de error mtodo main

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

public: puede ser llamado por cualquier objeto.

static: es un metodo de clase.

void: no devuelve ningun 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 disena 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 segun 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 unico 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.

Practica 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

Practica 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 basicos

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 excepcion 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 ex-
cepciones que se pudieran originar en la ejecucion de cada metodo.

La busqueda 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 imposicion 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 Ejecucion (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 efectua 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.

Construccion 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 acompanado 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 excepcion:

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 busqueda comienza en el mismo metodo en el que se produjo la excepcion y
continua 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 excepcion:

1. Se ejecutan normalmente las sentencias del bloque try.

2. Si existe bloque finally se ejecutan sus sentencias.

Soluciones alternativas al programa del ejemplo

Solucion 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

Solucion 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());
}
}
}

Declaracion 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.

Practica 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.

Como 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 accion 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 KeyListener
AdjustmentListener MouseListener
ComponentListener MouseMotionListener
ContainerListener TextListener
FocusListener WindowListener
ItemListener
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 windowClosed(WindowEvent e)
void windowIconified(WindowEvent e)
void windowOpened(WindowEvent e)
void windowClosing(WindowEvent e)
void windowDeiconified(WindowEvent e)
void windowActivated(WindowEvent e)
void 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 acompanada 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 Component Item Te x t


Event Event Event Event Event

Container Focus Input Paint Wi n d o w


Event Event Event Event Event

Key Mouse
Event 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

ActionEvent: pulsar un boton, seleccionar un menu, activar un campo de texto.

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

ComponentEvent: modificar el tamano de una componente, moverla, mostrarla o esconderla.

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 Metodos Parametro Sucesos


generados por
ActionListener actionPerformed ActionEvent Button
getActionCommand List
getModifiers MenuItem
TextField
AdjustmentListener adjustmentValueChanged AdjustmentEvent Scrollbar
getAdjustable
getAdjustmentType
getValue
ItemListener itemStateChanged ItemEvent Checkbox
getItem CheckboxMenuItem
getItemSelectable Choice
getStateChange List
TextListener textValueChanged TextEvent TextComponent
ComponentListener componentMoved ComponentEvent Component
componentHidden getComponent
componentResized
ContainerListener componentAdded ContainerEvent Container
componentRemoved getChild
getContainer
FocusListener focusGained FocusEvent Component
focusLost IsTemporary
KeyListener keyPressed KeyEvent Component
keyReleased getKeyChar
keyTyped getKeyCode
getKeyModifiersText
getKeyText
IsActionKey
MouseListener mousePressed MouseEvent Component
mouseReleased getClickCount
mouseEntered getX
mouseExited getY
mouseClicked getPoint
TranslatePoint
IsPopupTrigger
MouseMotionListener mouseDragged Component
mouseMoved
WindowListener windowClosing WindowEvent Window
windowOpened getWindow
windowIconified
windowDeiconified
windowClosed
windowActivated
windowDeactivated
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 comun:

Una posicion en la pantalla y un tamano

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 menus, 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 anade 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 tamano de dicha componente.

void setSize(int width,int height): Modifica el tamano de dicha componente.


89

void setBounds(int x,int y,int width,int height):


Mueve y modifica el tamano 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 boton, 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 multiples 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 unica 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 menu. 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)

Menus
Existen las siguientes clases que permiten construir menus y barras de menus:
MenuItem
Los objetos MenuItem representan las opciones de un menu.

CheckboxMenuItem
Subclase de MenuItem. Estos objetos hacen referencia a las opciones que actuan como
botones de marca.

Menu
Subclase de MenuItem. Los menus se representan mediante los objetos de tipo Menu, que
solo existen en barras de menu.

MenuBar
Hace referencia al menu principal. Las barras de menu estan ligadas unicamente 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 menus de tipo flotante. El constructor de esta clase es:

public Choice()

La primera opcion que se anade al menu 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 Dialogo

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 Colocacion

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 com-
ponentes en diferentes instantes.
Para anadir y mostrar una componente se utilizan los metodos:
add(String name, Component comp)
Con el primer argumento se identifica la componente que se esta anadiendo.

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 java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
public class CardLayoutWin extends Applet
implements ItemListener {

Panel cl;
final String MES1 = "Panel1 con tres botones ";
final String MES2 = "Panel2 con tres botones";
final 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 colocacion 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 utiles 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 aplica-
ciones nativas.

En la direccion http://java.sun./products/jfc se pueden encontrar paquetes nuevos que pueden dis-


tribuirse 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 actua 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 menus.

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 obten-
erla 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

void setJMenuBar(JMenuBar jmb):Asigna la barra de menu para este applet.

JMenuBar getJMenuBar(): Devuelve la barra de menu en este applet.

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, menus, . . .

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 menu.
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

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 Basicos
Menus 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 pequeno menu 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 Colocacion

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 dife-
rentes 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 tamano maximo y la alin-
eacion 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",
"Belgica","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 anade 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 anadir espacio entre las componentes. Una opcion es
insertar componentes invisibles, con la ayuda de la clase Box.

area rgida: para insertar un espacio de tamano fijo entre dos componentes. Para anadir 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 alineacion
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 menu poseen para X la alineacion izquierda.

Especificar el tamano 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 tamano maximo.
Para detectar problemas de este tipo es aconsejable:

agregar un borde a las componentes en cuestion. Esto permite apreciar que tamano realmente
tienen:

componente.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(Color.red),
componente.getBorder()));

Usar el System.out.println para imprimir los tamanos 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 JButton("Boton 1"));


contenedor.add(new JButton("2"));
contenedor.add(new JButton("El mas grande"));
contenedor.add(new JButton("4"));
contenedor.add(new 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 menus.
El primer ejemplo muestra la forma tradicional de implementar una interfaz formada por un area
de texto, una barra de menus y una barra de botones. La accion de seleccionar una opcion del primer
menu o pulsar un boton de la barra se ve reflejada en el area de texto. Seleciconar una opcion del
segundo menu activa o desactiva un boton o una opcion del primer menu.
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 anadir 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)

Eleccion 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 Metodos Parametro Sucesos


generados por
ActionListener actionPerformed ActionEvent JButton
getActionCommand JMenuItem
getModifiers JTextField
CaretListener caretUpdate CaretEvent JTextComponent
getDot
getMark
ChangeListener stateChanged ChangeEvent JSlider
JColorChooser
ComponentListener componentMoved ComponentEvent JComponent
componentHidden getComponent
componentResized
ContainerListener componentAdded ContainerEvent Container
componentRemoved getChild
getContainer
DocumentListener changedUpdate DocumentEvent JTextComponent (documento)
insertUpdate getDocument
removeUpdate getLength
getOffset
getChange
getType
InternalFrameListener internalFrameOpened InternalFrameEvent JInternalFrame
internalFrameClosing
internalFrameClosed
internalFrameIconified
internalFrameDeiconified
internalFrameActivated
internalFrameDeactivated
ItemListener itemStateChanged ItemEvent JCheckBox
getItem JCheckBoxMenuItem
getItemSelectable JComboBox
getStateChange
ListDataListener intervalAdded ListDataEvent JList (contenidos)
intervalRemoved getIndex0
contentsChanged getIndex1
ListSelectionListener valueChanged ListSelectionEvent JList
getFirstIndex JTable
getLastIndex
getValueIsAdjusting
FocusListener focusGained FocusEvent JComponent
focusLost IsTemporary
KeyListener keyPressed KeyEvent JComponent
keyReleased getKeyChar
keyTyped getKeyCode
getKeyModifiersText
getKeyText
IsActionKey
MouseListener mousePressed MouseEvent JComponent
mouseReleased getClickCount
mouseEntered getX
mouseExited getY
mouseClicked getPoint
TranslatePoint
IsPopupTrigger
MouseMotionListener mouseDragged JComponent
mouseMoved
WindowListener windowClosing WindowEvent JFrame
windowOpened getWindow JDialog
windowIconified
windowDeiconified
windowClosed
windowActivated
GRAFICOS EN JAVA
156

Graficos en Java
Dentro del paquete java.awt se encuentra definida la clase Graphics, que incorpora al lenguaje
Java la posibilidad de anadir 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 segun 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 unico 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 Graficas
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).

Rectangulos

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 com-
ponente.

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 polyg1_x[]={40,80,0,40};
int polyg1_y[]={5,45,45,5};
int polyg2_x[]={140,180,180,140,100,100,140};
int polyg2_y[]={5,25,45,65,45,25,5};
int polyg3_x[]={240,260,220,260,220,240};
int 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 numero 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 especifi-
cado 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 Metodos 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 unicamente 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)

Efectua 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 ()

Efectua 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 encuen-
tren 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 Utilizacion de
Primitivas Graficas

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 Imagenes

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 actua 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

Imagenes 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[1]=180; y[1]=20;
x[2]=180; y[2]=180; x[3]=20; y[3]=180;
x[4]=20; y[4]=20;
}

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);
}
}

Metodos 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 Imagenes
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 rectan-
gular 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 java.awt.*;
import java.awt.image.ImageFilter.*;
import java.awt.image.*;
import 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 RR VV AA
32 24 16 8 0

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 numero 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

Utilizacion 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 constante color


black negro magenta magenta
blue azul orange naranja
cyan ciano pink rosa
darkGray gris oscuro red rojo
gray gris white blanco
green verde yellow amarillo
lightGray gris claro

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 numero
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 numero
entre 0.0 y 1.0.

public Color (int rgb)

El argumento rgb es un numero 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 ultimos 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 numero 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: tamano 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 tamano 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 tamano


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-tamano
nombre-tamano
nombre-estilo
nombre

Donde estilo es la cadena bold, la cadena bolditalic o la cadena italic, y tamano es


el numero 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 unica 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 tamano 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 init() {


fuente1 = new Font("Helvetica", 0, 18);
fuente2 = new Font("Times", 1, 14);
fuente3 = new Font("New York", 2, 12);
fuente4 = 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 metricos del texto


La clase FontMetrics controla los aspectos metricos de un determinado tipo de letra. De hecho, la
unica 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

Lnea superior
a
b
Programacin en Lnea de base
Lnea inferior
d
c Lnea superior

lenguaje Java 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 ultimo, 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);
}
}

Practica 1

import java.applet.*;
import java.awt.event.*;
import java.util.*;
import 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);
}

Practica 2

import java.applet.*;
import java.awt.event.*;
import java.util.*;
import 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);
}

Practica 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();}
}
}

Practica 4

import java.applet.*;
import java.awt.event.*;
import java.util.*;
import 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

Graficos 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 posibili-
dades.
190

Ejemplo: Las clases Ellipse2D.Double y Rectangle2D.Double definen elipses y rectangulos, especi-


ficados 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 javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
public 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 independien-
temente, 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 unico punto de ejecucion.

Los procesos ligeros, a veces tambien llamados contextos de ejecucion, 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 Metodo 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 progra-
mador 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 asociandole un objeto de una clase que implemente la interfase
Runnable (tambien definida en el paquete java.lang). Una clase implementa esta interfase
cuando define un metodo sin argumentos que se llame run(). De esta manera, el metodo run()
del objeto que implementa la 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
numeros 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
ningun recurso para el y no se ha utilizado el metodo start() para iniciar su ejecucion. En
tal estado, lo unico 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 ex-
plicaran en detalle algunos de los mas importantes.

La Clase Thread
La clase Thread dispone de los constructores siguientes:

public Thread()
200

Ejecutable
yield()
suspend()
start sleep()
wait()
resume()
Stop notify()
fin notifyAll()
Disponible No ejecutable

Stop Stop
fin 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 en-
trada/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 unica 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 ultimo 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 numero 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 unico 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 pequeno 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 Tercero
Ejecutando Segundo
Ejecutando Segundo
Ejecutando Tercero
Ejecutando Segundo
Ejecutando Segundo
Ejecutando Tercero
Ejecutando Segundo
Ejecutando Tercero
Ejecutando Primero
Ejecutando Tercero
Ejecutando Primero
Ejecutando Primero
Ejecutando Primero
Ejecutando 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 comun 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 actuen de manera sincronizada.

Ejemplo: Se quiere implementar un algoritmo que evalue expresiones de la forma:

xn + xn1 + xn2 + . . . + x2 + x + 1

para cualquier pareja de numeros 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

Practica 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

Practica 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("Interrupcion Incorrecta");}
System.out.println("\n"+miNombre+" ha llegado");

}
207

Ejercicio: Gestion de un Almacen


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 numero 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) Numero 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 Almacen
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();
}
}
ANIMACION Y SONIDO
214

Animacion de Graficos

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:

numFotograma: da el numero del fotograma que se esta mostrando en un cierto instante.

frecuencia: da el maximo del numero de


fotogramas/segundo.

tiempoDemora: da el numero 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 numero 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 Grafico 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 tamano 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 Grafico 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 Imagenes 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, respectiva-
mente.

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 Imagenes

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

Utilizacion de la Clase
MediaTracker

Algunos de los metodos mas utiles de la clase MediaTracker son:

El metodo addImage(Image imag, int id) permite


anadir 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 pequeno 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 du-
rante 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
anaden 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 anaden 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");
}
}
}
GESTION DE FICHEROS
227

Introduccion

Es de sobra conocido que las diferentes maquinas y sistemas operativos utilizan diferentes repre-
sentaciones 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 numeros) 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 ultimo, el metodo public void close() cierra ambas corrientes.

Ejemplo 2

Escribe en un fichero el numero 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 argu-
mento 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 es-
cribir. Los metodos void write(String str) y void write(int c) de la superclase Writer escriben
en el fichero cadenas de caracteres o un unico 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 unico 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();
}
}

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