Transp Are Nci As Java
Transp Are Nci As Java
Transp Are Nci As Java
Direcciones de Inter
es en Internet
http://www.sun.com
Direccion de la empresa Sun Microsystems, desarrolladora de Java.
http://java.sun.com
Lugar oficial de informacion sobre el lenguaje Java.
http://www.javaworld.com
Revista electronica sobre Java.
http://www.engapplets.vt.edu/
Direccion con interesantes applets aplicados a la ingeniera.
http://www.stat.duke.edu/sites/java.html
Direccion con applets relacionados con la estadstica.
http://www.um.es/ psibm/tutorial/
Tutorial de html en castellano.
http://www.wmaestro.com/webmaestro/index.html
Tutorial de html en castellano.
3
http://www.digitaleconomist.com/
Direccion con interesantes applets aplicados a la economa.
http://members.nbci.com/surendranath/
Applets.html
Direccion con interesantes applets aplicados a la fsica.
http://home.planetinternet.be/ poolly/eng/
eng.html
Direccion con interesantes applets aplicados a la fsica.
PROGRAMACION
ORIENTADA A OBJETOS
Programaci
on Orientada a Objetos
Java es un Lenguaje Orientado a Objetos que incorpora una gran n
umero de clases predefinidas organizadas en paquetes.
La programacion en Java supone definir clases de forma jerarquica, construir objetos de dichas clases
y realizar acciones con ellos.
Los objetos constituyen el concepto fundamental para entender la tecnologa que se conoce como
tecnologa orientada a objetos.
Objetos del mundo real:
COCHE
MESA
ORDENADOR
TELEVISOR
Todos estos objetos del mundo real tienen:
un estado
un comportamiento
Programaci
on Orientada a Objetos
Un objeto es un conjunto constituido por una o varias variables y, opcionalmente, por metodos.
Todo aquello que el objeto conoce (estado) se expresa por sus variables, y todo lo que puede hacer
(comportamiento) se expresa por sus metodos.
ESTADO
VARIABLES MIEMBRO
OBJETO
COMPORTAMIENTO
MTODOS
MTODO 1
MTODO
3
VARIABLES
MIEMBRO
MTODO
2
MTODO 4
Ejemplo de Objeto
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
8
Los nombres de las clases, por convenio, comienzan por may
uscula.
Cuerpo de una clase
El cuerpo de una clase contiene dos secciones:
1. Declaraci
on de sus variables.
2. Definici
on de sus metodos.
DeclaracionClase{
declaracionVariablesMiembro
...
declaracionMetodos
}
Declaraci
on de las variables miembro
Como mnimo, en la declaracion de una variable miembro aparecen dos componentes:
1. El tipo de dato de la variable.
2. Su nombre.
tipo variableNombre;
Declaraci
on de los metodos miembro
La implementacion de un metodo consta de dos partes: la declaracion y el cuerpo del mismo. En la
declaracion del metodo, ademas del nombre, va una cierta informacion, como:
El valor de retorno del metodo (el tipo de valor que devuelve).
El n
umero y tipo de argumentos requeridos por dicho metodo.
tipo metodo(argumentos){
...
}
Si un metodo no devuelve ning
un valor, debe declararse como void, y si devuelve un valor, debe utilizar
la sentencia return para devolverlo.
Clase Automovil
class Automovil{
String
Modelo;
int
Cilindrada;
float
Velocidad;
int
Marcha;
Automovil(String m,int c) {
super();
9
Modelo=m;
Cilindrada=c;
Velocidad=0;
Marcha=0;
}
void Acelera(float v) {
Velocidad=Velocidad+v;
}
void Frena(float v) {
Velocidad=Velocidad-v;
}
void Para() {
Marcha=0;
Velocidad=0;
}
void CambiaMarcha(int m) {
Marcha=m;
}
}
Creaci
on y Utilizaci
on de Objetos
En Java se crea un objeto sin mas que crear un ejemplar de una clase.
Pueden utilizarse clases definidas por el propio programador o las que se encuentran definidas en los
diferentes paquetes que incluye el entorno de desarrollo Java.
As, para crear un nuevo objeto de la clase String definida en el paquete java.lang se usa el comando
m
ultiple:
String str = new String(h,o,l,a);
Con esta declaracion se realizan tres acciones:
1. Declaraci
on: se declara una variable de tipo String cuyo nombre es str
2. Creaci
on del objeto: el operador new crea un nuevo objeto de tipo String
3. Iniciaci
on: String(h,o,l,a) inicia la cadena asignandole el contenido hola".
Constructor de una clase
Los constructores se reconocen porque tienen el mismo nombre que la clase y no tienen tipo de
retorno (o tipo void)
Siempre existe un costructor por defecto que no recibe argumentos.
Una clase puede tener varios constructores, pero todos ellos deben tener el mismo nombre (el de
la clase), y diferente n
umero o tipo de argumentos, para que el compilador pueda distinguirlos.
Los constructores solo pueden ser llamados con el operador new.
10
Por ejemplo, para crear un objeto de la clase Automovil llamado micoche,
Automovil micoche;
micoche= new Automovil(...,...);
Para acceder a las variables de un objeto, se concatenan los nombres del objeto y de la variable con
un punto. Por ejemplo, para acceder a la variable miembro modelo del objeto miCoche
miCoche.modelo
Para llamar a los metodos de un objeto, se concatena el nombre del objeto con el del metodo
mediante un punto, dando los argumentos del metodo entre parentesis, como en:
miChoche.cambiaMarcha(2);
Si el metodo no requiere argumentos, se utilizan los parentesis vacos.
miChoche.para();
Las llamadas a metodos tambien se conocen como mensajes.
Clase Punto
class Punto{
int x,y;
Punto(int x,int y){
this.x=x;
this.y=y;
}
double distancia(int x,int y){
int dx=this.x-x;
int dy=this.y-y;
return Math.sqrt(dx*dx+dy*dy);
}
double distancia(Punto p){
return distancia(p.x,p.y);
}
}
class DistanciaPuntos{
public static void main(String
args[]){
Punto p1=new Punto(0,0);
Punto p2=new Punto(30,40);
System.out.println("p1=("+p1.x+","+
p1.y+")");
System.out.println("p2=("+p2.x+","+
p2.y+")");
System.out.println("Distancia de
11
p1 a p2=",p1.distancia(p2));
System.out.println("Distancia de
p1 a (60,80)=",
p1.distancia(60,80));
}
}
Herencia
En programacion orientada a objetos se pueden definir clases (subclases) en terminos de otras clases
(superclases).
En Java, toda clase tiene una superclase. La superclase por defecto es la clase Object.
Para especificar la superclase se escribe la palabra extends y el nombre de la superclase a continuacion del nombre de la clase:
class SubClase extends SuperClase{...}
Toda subclase hereda el estado (en la forma de declaracion de variables) y los metodos de la superclase. Sin embargo, las subclases no estan limitadas al estado y comportamiento de su superclase, ya
que las subclases pueden:
A
nadir nuevas variables miembro.
nadir nuevos metodos a los heredados de la superclase.
A
Dar implementaciones particulares a los metodos heredados, anulando la definicion original de los
metodos, dada por la superclase, y sustituyendola por otra.
Clase Camion
class Camion extends Automovil {
float
PMA;
float
PesoCarga;
Camion(String m,int c,float p) {
super(m,c);
PesoCarga=p;
}
void Carga(float c) {
PesoCarga= PesoCarga+c;
void Descarga(float c) {
PesoCarga= PesoCarga-c;
void Para(){
12
super.Para();
PesoCarga=0; }
}
Declaraci
on de una Clase
En la declaracion de una clase se puede:
Declarar cual es su superclase.
Listar las interfases que implementa.
Declarar si es p
ublica, abstracta o final.
Implementar interfases
class Nombre extends SuperClase implements
Iterfase1,Interfase2...{...}
Una interfase declara un conjunto de metodos y constantes, sin especificar la implementacion para los
metodos. De forma que la clase que implementa dicha interfase debe implementarlos.
Clase p
ublica
public class Nombre ...{...}
Se pueden crear objetos de esa clase desde cualquier otra clase. Por defecto solo lo pueden hacer las
clases definidas en el mismo paquete.
Clase abstracta
abstract class Nombre ...{...}
No se pueden crear objetos de esas clases. Dentro de esta clase se pueden declarar metodos abstract
sin dar una implementacion de los mismos. Cualquier subclase debe dar una implementacion de dichos
metodos abstractos.
Clase final
final class Nombre ...{...}
No se pueden crear subclases suyas.
Por defecto una clase no es p
ublica, ni abstracta, ni final.
Se puede especificar que otros objetos pueden crear ejemplares de la clase:
private: ninguna clase puede crear objetos de esta.
protected: solo las subclases y las clases del mismo paquete pueden crear objetos de esta clase.
public: cualquier clase puede crear un ejemplar.
13
No especificado: solo clases del mismo paquete.
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);
}
}
15
lib1.mensajePaginas();
dicc1.mensajeDef();
}
}
16
Ejemplo:
package Ejemplo;
class AClase {
protected int protVar;
protected void protMetodo(){
protVar=1; //permitido
}
}
class BClase{
void accMetodo(){
AClase ap=new AClase();
ap.protVar=2; //permitido
ap.protMetodo(); //permitido
System.out.println("var1="+
ap.protVar); }}
-----------import Ejemplo.*;
package EjemploPrueba;
class CClase extends AClase{
void metodo3(AClase a,
CClase d){
a.protVar=2;
d.protVar=2;
a.metodo1();
d.metodo1();
}
}
//no permitido
//permitido
//no permitido
//permitido
Acceso p
ublico
Cualquier clase en cualquier paquete tiene acceso a las variables y metodos p
ublicos de una
clase.
Ejemplo:
package Ejemplo;
class AClase {
public int protVar;
public void protMetodo(){
protVar=1; //permitido
}}
package EjemploPrueba;
class BClase{
void accMetodo(){
AClase ap=new AClase();
ap.protVar=2; //permitido
17
ap.protMetodo(); //permitido
System.out.println("var1="+
ap.protVar);
}
}
Acceso no especificado
Las clases definidas en el mismo paquete tiene acceso a las variables y metodos de una clase
cuyo acceso es no especificado.
Variables y metodos: final
El valor de una variable es constante si esta se declara final, un metodo no puede ser
redefinido si se declara final.
18
}
class Principal{
public static void main(String
args[]){
Entero x1=new Entero();
Entero x2=new Entero();
x1.cambiarX(1);
x2.x=2;
System.out.println("x1.x="+x1.x());
System.out.println("x2.x="+x2.x());
}}
Salida: x1.x=1, x2.x=2
Ejemplo:
class Entero{
static int x;
public int x(){
return x;// permitido
}
public void cambiarX(int nuevoX){
x=nuevoX;
}
}
class Principal{
public static void main(String
args[]){
Entero x1=new Entero();
Entero x2=new Entero();
x1.cambiarX(1);
x2.x=2;
System.out.println("x1.x="+x1.x());
System.out.println("x2.x="+x2.x());
}
}
Salida: x1.x=2, x2.x=2
Ejemplo:
class Entero{
int x;
static public int x(){
return x;//no permitido
}
public void cambiarX(int nuevoX){
x=nuevoX;
}
}
class Principal{
19
public static void main(String
args[]){
Entero x1=new Entero();
Entero x2=new Entero();
x1.cambiarX(1);
x2.x=2;
System.out.println("x1.x="+x1.x());
System.out.println("x2.x="+x2.x());
}}
Salida: Error!!
Ejemplo:
class Entero{
static int x;
static public int x(){
return x;//permitido
}
public void cambiarX(int nuevoX){
x=nuevoX;
}
}
class Principal{
public static void main(String
args[]){
Entero x1=new Entero();
Entero x2=new Entero();
x1.cambiarX(1);
x2.x=2;
System.out.println("x1.x="+x1.x());
System.out.println("x2.x="+x2.x());
}}
Salida: x1.x=2, x2.x=2
Ejemplo:
class Entero{
static int x;
static public int x(){
return x;
}
static public void
cambiarX(int nuevoX){
x=nuevoX;
}
}
class Principal1{
public static void main(String
args[]){
20
Entero.cambiarX(1);
Entero.x=2;
System.out.println("El valor final
es "+ Entero.x());
}
}
Salida: El valor final es 2
Herencia
Una subclase hereda las variables y los metodos de su superclase y de todas sus antecesoras:
hereda los miembros declarados public o protected.
hereda los miembros declarados sin ning
un acceso si esta en el mismo paquete que su superclase.
no heredan un miembro si lo declaran con el mismo nombre que en la superclase. En este caso se
ocultan variables y se redefinen metodos.
Ejemplo:
class ASuper{
int var1;
void metodo(){
var=1;
}
}
class BSub extends ASuper{
int var;
void metodo(){
var=2;
super.metodo();
System.out.println(var);
System.out.println(super.var);
}
}
Clases y M
etodos Abstractos
Algunas veces necesitamos implementar un concepto abstracto.
Por ejemplo, podemos definir una aplicacion que dibuje crculos, rectangulos, etc. Todos estos objetos comparten un cierto estado (posicion, dimensiones) y un comportamiento (mover, redimensionar,
dibujar). Pero no es lo mismo dibujar un crculo que un rectangulo. Todos los objetos graficos deben
saber como dibujarse, pero difieren en la manera de hacerlo.
Declaramos una clase abstracta con variables y metodos que seran compartidos por todas las subclases. Y con metodos abstractos, que necesitan ser implementados por las subclases, pero de diferentes
maneras.
Ejemplo:
21
abstract class Figura{
int x,y;
.......
void mover(int nuevax,int nuevay){
...
}
abstract void dibujar();
}
class Circulo extends Figura{
void dibujar(){...}
}
class Rectangulo extends Figura{
void dibujar(){...}
}
22
Paquete java.awt
Suministra la interfase de comunicacion con el usuario, que se llama (Abstract Window
Toolkit).
Paquete java.awt.event
Suministra las clases necesarias para controlar todos los sucesos que ocurren sobre la ventana
de nuestro applet o aplicacion.
Paquete java.awt.image
Paquete que sirve para tratar los datos de imagenes.
Paquete java.awt.peer
Conecta las componentes a sus correspondientes implementaciones independientes de la
plataforma.
Paquete java.awt.geom
En este paquete se encuentran clases y metodos para trabajar con objetos geometricos en
2D.
Paquete javax.swing
En este paquete se encuentran clases y metodos para crear una interfase de usuario. Este
paquete se puede considerar como una version actualizada del paquete java.awt, pues las
nuevas clases ofrecen mayores posibilidades que las que ofrece el paquete java.awt.
Paquete javax.swing.event
Suministra las clases necesarias para controlar todos los sucesos que ocurren sobre los componentes swing.
Paquete javax.swing.table
Suministra las clases e interfases necesarias para trabajar con objetos javax.swing.JTable.
Paquete javax.swing.text
Suministra las clases e interfases necesarias para trabajar con componentes de texto, editables
y no-editables.
Paquete javax.swing.border
Suministra las clases e interfases necesarias para dibujar bordes alrededor de las componentes
swing.
Como cargar un paquete:
Para importar una clase especfica de un paquete:
23
import paquete.nombreclase
Para importar todas las clases de un paquete:
import paquete.*
Por ejemplo, para cargar todas las clases del paquete java.awt:
import java.awt.*
Clase Lista
import java.io.*; import java.util.*;
public class Lista{
private long dni[];
int numero;
int maxnum;
public Lista(int longitud){
dni=new long[longitud];
maxnum=longitud;
numero=0;
System.out.println("Se crea la lista");
}
public boolean alta(long newdni){
if(numero<maxnum)
{
dni[numero]=newdni;
System.out.println("Se da de alta el DNI"+newdni);
numero++;
return(true);
}
else
return(false);
}
24
34567
42039
20456
25
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
(a, b)/(c, d) = (
ac + bd ad bc
,
).
c2 + d2 c2 + d2
(-2,6)
El modulo de la suma es = 6.32456
El argumento de la suma es = -1.24905 radianes
(-14,-22)
El argumento de c2 es = 0 radianes
Al calcular el cociente se ha producido una excepcion
class ZerodivisorException
con el mensaje: Divide por cero
Programa de Prueba
import java.io.*;
import java.applet.*;
//import Complejo;
public class PComplejo extends Applet{
public void init() {
Complejo c1,c2,c3;
c1=new Complejo(1.0,2.0);c2=new Complejo(3.0,4.0);
c3=new Complejo(0.0,0.0);c1.imprime();
c2.imprime();c3=c2;c3.opuesto();c3.imprime();
c3.conjugado();c3.imprime();
c3.suma(c1,c2);c3.imprime();
System.out.println("El modulo de la suma es = "
+ c3.modulo());
System.out.println("El argumento de la suma es = "
+ c3.argumento() + " radianes");
c3.producto(c1,c2);c3.imprime();
c2.preal=0.0;c2.pimag=0.0;
System.out.println("El argumento de c2 es = "
+ c2.argumento() + " radianes");
try{ c3.cociente(c1,c2);
System.out.println("El cociente es: ");
c3.imprime();
}catch (ZerodivisorException e){
System.out.println("Al calcular el cociente se ha
producido una excepcion " + e.getClass()
+ "\ncon el mensaje: " + e.getMessage());
}
}
}
28
ENTORNO JDK
29
Creaci
on de Applets y Aplicaciones
PROGRAM A
JAVA
MiPrograma.java
COMPILA DOR
INTRPR ETE
MiPrograma.class
0010110100
MI
PROGRAMA
Creaci
on de aplicaciones
Las aplicaciones son programas autonomos que no necesitan de un navegador para ejecutarse.
on del codigo fuente
1. Creaci
Debe utilizarse alg
un editor de texto (SimpleText, Edit, Word,...).
Ejemplo 1:
public class MiAplicacion {
public static void main(String argv[]) {
System.out.println("SOY UNA APLICACION");
}
}
30
El formato del fichero fuente debe ser solo texto.
El nombre de dicho fichero debe ser el mismo que el de la clase con el metodo main() pero con la
terminacion .java.
2. Compilaci
on del codigo fuente
La compilacion se puede efectuar directamente con un editor de Java (Kawa, JCreator, etc.),
utilizando la opcion Compile del men
u Build. La compilacion tambien se puede efectuar desde
el DOS, mediante un comando de la forma:
javac MiAplicacion.java
En caso de estar en un directorio diferente al que contiene el codigo fuente debe indicarse el camino
(path) completo para llegar a el.
Esto tambien puede resolverse a
nadiendo a la variable Path, el camino donde se halla el compilador. Para ello basta con escribir en el fichero autoexec.bat,
SET PATH=C:\Archivos de programa\Java\jdk1.5.0_07\bin\;
3 Ejecuci
on de la aplicaci
on La ejecucion se puede hacer con un editor de Java (Kawa, JCreator,
etc.), en particular, utilizando la opcion Run del men
u Build. Tambien se puede hacer desde el
DOS, para ello se utiliza el fichero .class asociado a la clase que tiene el metodo main()
La orden debe darse desde el DOS:
java MiAplicacion
Para poder ejecutar una aplicacion, el directorio actual debe ser el que contiene el codigo objeto
(el fichero MiAplicacion.class).
Aplicaciones que reciben argumentos
Ejemplo 2:
public class MiNombre {
public static void main(String argv[]) {
System.out.println("BIENVENIDO "+ argv[0]);
}
}
Los argumentos se pasan desde la lnea de comandos del DOS, al mismo tiempo que se ordena la
ejecucion de la aplicacion:
java MiNombre "Pepe P
erez"
Creaci
on de applets
31
on del codigo fuente
1. Creaci
Ejemplo:
import java.applet.Applet;
public class MiApplet extends Applet{
public void init() {
System.out.println("SOY UN
APPLET");
}
}
El nombre del fichero con el codigo fuente debe ser el mismo que el de la subclase de la clase
Applet pero con la terminacion .java.
2. Compilaci
on del codigo fuente: Similar al caso de las aplicaciones.
Se generan tantos ficheros .class como clases definidas en el fichero fuente.
on en un documento HTML
3 Integraci
Se utiliza el comando <APPLET> del HTML.
Ejemplo (Fichero "Ejemplo.html"):
<HTML>
Esta página incluye un applet:
<HR>
<APPLET CODE=MiApplet.class
HEIGHT=50
WIDTH=300>
</APPLET>
<HR>
<A HREF="MiApplet.java">
CODIGO FUENTE
</A>
</HTML>
El parametro CODE toma como valor el fichero generado por el compilador correspondiente a la
subclase de la clase Applet.
4 Ejecuci
on del applet
Existen dos alternativas:
(a) Utilizar un navegador compatible con Java (p.e. Netscape, InternetExplorer).
Abrir con el navegador el documento HTML que integra el applet.
32
(b) Utilizar la herramienta de visualizacion de applets del JDK.
En particular, si se utiliza un editor de Java (Kawa, JCreator, etc.), basta con seleccionar el
fichero.html y llamar al comando Run del men
u Build.
La orden que debe darse desde el DOS:
appletviewer Ejemplo.html
Ejemplo aplicaci
on
PrimeraAplicacion.java
Ejemplo applet
MiPrimerApplet.java
33
MiPrimerApplet.html
<title> Mi primer applet </title>
<hr>
<applet code=MiPrimerApplet.class width=200 height=200>
</applet>
<hr>
<a href="MiPrimerApplet.java"> CODIGO FUENTE.</a>
EJEMPLO
import java.awt.*;
public class EjemploAplicacion
extends Frame{
Button boton;
public EjemploAplicacion(){
boton=new Button("OK");
add("South",boton);
}
public static void main(String[] args){
EjemploAplicacion ejem=
new EjemploAplicacion();
ejem.resize(100,100);
ejem.show();
}
}
EL LENGUAJE JAVA
35
Variables
Las variables son zonas o espacios de memoria en las que se almacena la informacion. Son los pilares
de la programacion y los elementos sobre los que se act
ua. Es necesario especificar su nombre y su tipo.
el nombre sirve para saber a que zona de memoria se esta uno refiriendo.
el tipo sirve para saber el tama
no de la memoria necesario para almacenarla y como debe interpretarse la informacion. La informacion se almacena en binario, es decir, en forma de bits (ceros
y unos), por lo que hay que transformarla tanto para almacenarla como para interpretarla.
Toda variable y toda expresion tienen un tipo. Esto limita los valores que pueden tomar las variables
y producir las expresiones, limita las operaciones que pueden realizarse con las variables y expresiones
y determina el significado de las operaciones que las afectan.
Al declarar una variable, debe especificarse su tipo y su nombre.
int a,b;
String nombre,domicilio;
long d;
boolean f;
Tipos de Datos
Hay tres tipos de variables o expresiones:
B
asicas: contienen la informacion propiamente dicha. Estas
pueden ser:
Numericas: a su vez pueden ser:
36
Enteras: byte, short, int, long, que toman valores enteros.
Coma flotante: float (simple precision), double (doble precision), que toman valores
reales.
Booleanas: boolean, que toman los valores logicos true y false.
Tipo caracter: char, que toman solo valores de tipo caracter.
Referenciales: no contienen la informacion, sino donde se encuentra esta, es decir, son referencias
a objetos. Estas pueden ser:
Tipo clase: class, que contienen referencias a clases.
Tipo interfase: interface, que contienen referencias a una interfase.
Tipo matriz: array, que contienen referencias a una matriz.
Tipo nulo: es un tipo especial que no tiene nombre. La referencia nula null es el u
nico valor que
puede tomar una expresion de este tipo.
Tipo
byte
short
int
long
float
double
boolean
char
Tama
no
8 bits
16 bits
32 bits
64 bits
32 bits
64 bits
N/A
16 bits
Mnimo
M
aximo
256
255
32768
32767
2147483648
2147483647
9223372036854775808 922337203685477580
224 E 149
224 E104
253 E 1045
253 E1000
false
true
Caracter Unicode
Campo de Acci
on de una Variable
Se denomina campo de acci
on de una variable al bloque de codigo en el que dicha variable es accesible.
Ademas, este campo determina cuando la variable se crea y se destruye.
Atendiendo al campo de accion, se pueden clasificar las variables en las clases siguientes:
Variable de clase. Se declara dentro de la definicion de una clase o interfase, usando la palabra
clave static. Estas variables son creadas e iniciadas, a valores determinados o por defecto, al
construirse la clase, dejando de existir cuando desaparece dicha clase y tras completar el proceso
previo a la destruccion del objeto.
37
Variables miembro de una clase. Se declaran en la definicion de una clase sin usar la palabra clave
static. Si a es una variable miembro de una clase A, cada vez que se construye un nuevo objeto
de la clase A o una subclase de A se crea una nueva variable a y se inicia dandole un valor concreto
o por defecto. La variable deja de existir cuando desaparece la clase a la que pertenece y tras
completar el proceso previo a la des truccion del objeto.
Componentes de una matriz. Son variables sin nombre que se crean e inician a valores concretos
o por defecto cuando se crea un objeto nuevo de tipo matriz. Las componentes de la matriz dejan
de existir cuando desaparece la misma.
Variable local. Se declara dentro de un bloque de codigo y solo es accesible dentro del mismo. Las
variables locales no se inician hasta que se ejecuta la sentencia de declaracion correspondiente.
Las variables locales dejan de existir cuando se termina el bloque en el que estan declaradas.
Par
ametro de un metodo o constructor. Es el argumento formal de un metodo o un constructor,
mediante el cual se pasan valores al mismo. Cada vez que se invoca el metodo se crea una variable
con ese nombre y se le asigna el valor que tena la correspondiente variable en el metodo que la
llama. Su campo de accion es el metodo o constructor del cual es argumento.
Par
ametro de un manipulador de excepciones. Es el argumento de un manipulador de excepciones.
Iniciaci
on de Variables
Al declarar las variables locales, las de clase y las que son miembros de clases pueden darse valores
iniciales. Por ejemplo:
int edad=30;
double estatura=1.78;
boolean Terminado=true;
Ademas de reservar espacio en memoria para ellas, se almacenan los valores indicados.
Los parametros de los metodos y los de los manipuladores de excepciones no pueden iniciarse de
este modo. El valor de estos parametros es fijado por el metodo que los llama.
Constantes
Las constantes en Java son como las variables, pero su valor no se altera durante la ejecucion del programa. Se las precede del adjetivo final. Por convenio, las constantes se escriben todas en may
usculas.
Por ejemplo:
final double PI=3.14159265358979;
final double E=2.71728182;
38
Comentarios
Existen tres clases de comentarios:
/* texto */. El texto comprendido entre /* y */ es ignorado por el compilador. Se utiliza para
comentarios de mas de una lnea.
// texto. El texto desde // hasta el final de lnea es ignorado. Se utiliza para comentarios de
una sola lnea.
/** documentaci
on */. El texto comprendido entre /** y */ puede ser procesado por otra
herramienta para preparar documentacion de la siguiente
declaracion de clase, constructor, interfase, metodo o campo.
Operadores
Existen operadores unarios y binarios que requieren uno o dos operandos, respectivamente.
Los operadores unarios pueden aparecer antes o despues del operando, aunque, en ese caso, la accion
que realizan puede ser diferente.
x++;
++y;
Los operadores binarios siempre aparecen entre los dos operandos:
5*6;
a+b;
Todo operador devuelve siempre un valor. Dicho valor y su tipo dependen del operador y del tipo
de los operandos.
Los operadores pueden clasificarse en las siguientes
categoras:
aritmeticos
relacionales y condicionales
bit-a-bit y l
ogicos
de asignacion
Operadores Aritm
eticos
Los operadores aritmeticos binarios, salvo el operador %, que solo act
ua con enteros, manejan indistintamente los tipos enteros y los de coma flotante.
Cuando un operador tiene operandos de diferente tipo, estos se convierten a un tipo com
un siguiendo
las reglas:
la categora de los tipos, de mayor a menor, es la siguiente: double, float, long, int,
short,char.
39
Operador
+
*
/
%
Operadores Binarios
Operaci
on Descripci
on
a + b
Adicion
a - b
Diferencia
a * b
Producto
a / b
Division
a % b
resto de dividir a entre b
Table 2: Operadores Binarios.
en cualquier operacion en la que aparezcan operandos de tipos diferentes, se eleva la categora del
que la tenga menor.
en una sentencia de asignacion, el resultado final se convierte al tipo de la variable a la que son
asignados.
Operador
+y++
--
Operadores Unarios
Operaci
on Descripci
on
Fijan el signo del operando
+a y -a
++x
Suma 1 a x antes de usarla
x++
Suma 1 a x despues de usarla
--x
Resta 1 a x antes de usarla
x-Resta 1 a x despues de usarla
Table 3: Lista de operadores unarios
Ejemplos:
int i=7;
4 * i++;
i+2;
Las dos u
ltimas sentencias dan como resultado 4*7=28 y 8+2=10.
int i=7;
4 * ++i;
i+2;
En este caso los resultados son 4*8=32 y 8+2=10.
40
Operador
>
>=
<
<=
==
!=
Operadores Relacionales
Empleo Descripci
on
true si a es mayor que b,
a > b
false en caso contrario.
true si a es mayor o igual que b,
a >= b
false en caso contrario.
true si a es menor que b,
a < b
false en caso contrario.
true si a es menor o igual que b,
a <= b
false en caso contrario.
true si a y b son iguales,
a == b
false en caso contrario.
true si a y b son diferentes,
a != b
false en caso contrario.
Operadores Condicionales
Operador Empleo Descripci
on
true si a y b son true,
&&
a && b
false en caso contrario.
false si a y b son false,
||
a || b
true en caso contrario.
false si a es true y
!
!a
true si a es false
Table 5: Lista de operadores condicionales.
Operadores de Asignaci
on
El operador = asigna a la variable de la izquierda el valor que toma la expresion de la derecha:
float i = 3.5;
Ademas:
n = n*5;
41
Operadores de Asignaci
on
Operador Empleo Descripci
on
+=
a += b
a = a + b
-=
a -= b
a = a - b
*=
a *= b
a = a * b
/=
a /= b
a = a / b
%=
a %= b
a = a % b
&=
a &= b
a = a & b
|=
a |= b
a = a | b
^=
a ^= b
a = a ^ b
<<=
a <<= b
a = a << b
>>=
a >>= b
a = a >> b
>>>=
a >>>= b a = a >>> b
Table 6: Lista de operadores de asignacion.
es equivalente a:
n *= 5;
El operador cast
A veces se necesita almacenar valores de un tipo en variables de tipo diferente. Como Java no
permite almacenar a cada variable mas que valores de su tipo, es necesario transformarlos previamente.
Para ello, se recurre al operador cast, que transforma un tipo de dato en otro compatible, tal como
se ve en el siguiente ejemplo:
float a;
int b;
b = (int) a;
Matrices
Considerense los 100 primeros m
ultiplos de 2. Estos podran almacenarse as:
int
int
int
...
int
m1 = 2;
m2 = 4;
m3 = 6;
m100 = 200;
Para ello, se dispone de las matrices (arrays), cuya declaracion se hace como sigue:
42
int mult[];
mult = new int[100];
En la primera sentencia se especifica el tipo de los elementos de la matriz (int en este caso) y se
da un nombre a la matriz, seguido de un doble corchete [], el cual indica al compilador que lo que se
declara es una matriz.
Pero la declaracion int mult[]; no asigna memoria para almacenar los elementos de la matriz, de
manera que si se intenta acceder a alguno de ellos o asignarle un valor, el compilador dara un mensaje
de error. Para evitar esto y asignar la memoria necesaria se recurre al operador new.
A partir de ese instante ya se pueden dar valores a todos los elementos de la matriz:
public class Multiplo{
public static void
main(String args[]){
int mult[];
mult=new int[100];
for(int i=0;i<mult.length;i++){
mult[i]=2*(i+1);
System.out.println(mult[i]);
}
}
}
Ejemplo:
public class ArrayExample{
public static void
main(String args[]){
int smallPrimes[]={2,3,5,7,11,13};
int bigInts[]={1001,1002,1003,1004,
1005,1006,1007};
System.arraycopy(smallPrimes,2,
bigInts,3,4);
for(int i=0;i<bigInts.length;i++){
System.out.println(i +" despues
de la copia es "+bigInts[i]);
}
}
}
Cadenas de Caracteres
Se denomina cadena de caracteres a una secuencia o conjunto ordenado de ellos. Toda cadena de
caracteres se implementa mediante la clase String.
String a[] = new String[20];
Otra forma:
43
"Hola"
Tambien se pueden unir dos cadenas de caracteres mediante el operador de concatenacion +. Por
ejemplo:
"La ecuacion tiene " +
n + " soluciones."
Expresiones
Toda expresi
on es una combinacion de variables, operadores y llamadas a metodos, que calculen un
valor.
Las expresiones se utilizan para calcular y asignar valores a variables y para controlar la ejecucion
de un programa. Realizan las operaciones indicadas por sus elementos y devuelven alg
un valor.
Existen dos tipos de expresiones:
Numericas: que toman valores numericos.
Booleanas: que solo toman los valores true o false.
Expresiones Numericas
Cualquier variable que represente un n
umero es una expresion numerica.
int i
i+10
--n;
Toda asignacion es tambien una expresion:
a = 100
b* = 2
Expresiones Booleanas
Solo poseen los valores true o false.
n != m
a < b
En una expresion es importante el orden en que se aplican los operadores. No es lo mismo
5 * 3 + 4
que
5 * (3 + 4)
44
. [] ()
++ -- ! ~ instanceof
new (type)
* / %
+ << >> >>>
< >
== !=
&
^
|
&&
||
? :
= += -= *= /= %= ^=
&= |= <<= >>= >>>=
Table 7: Orden de preferencia de los operadores.
Sentencias y Bloques
Un programa no es mas que un conjunto de sentencias ordenadas. Una sentencia es una instruccion
completa para el compilador, que acaba en un punto y coma.
Una expresion como a = 100 o a < b se convierte en una sentencia cuando va seguida de un punto
y coma:
a = 100;
a < b;
Una sentencia indica una accion. La expresion
2+2;
indica al compilador que realice esa operacion pero no lo que debe hacer con el resultado. Por el
contrario, la sentencia
a = 2+2;
ordena al compilador que almacene el resultado en la variable a.
Veamos cuatro clases de sentencias:
Sentencias de declaraci
on: establecen los nombres y el tipo de variables.
Sentencias de asignacion: asignan valores a las variables.
Sentencias de funcion: llaman a funciones para realizar una determinada tarea.
Sentencias estructuradas o de control de flujo: while, if-else, switch, etc., que se analizan en
la seccion siguiente.
45
Un bloque es un conjunto de dos o mas sentencias agrupadas y encerradas entre llaves, no existiendo
punto y coma tras la llave de cierre. Por ejemplo, el programa que sigue contiene un bloque.
for(i=0;i<100;i++) {
mult[i] = 2*(i+1);
System.out.println("Elemento i"+mult[i]);
}
Control de Flujo
Puede determinarse el orden de ejecucion de las sentencias seg
un convenga. Para ello nos servimos
de las sentencias estructuradas o de control de flujo.
Sentencia if-else
Se define primero la sentencia if, que tiene el formato:
if(expresion)
{sentencias}
Si expresion es true, se ejecuta {sentencias}, si es false, no se ejecuta {sentencias}.
Una alternativa mas potente es la sentencia if-else:
if(expresion)
{sentencias1}
else
{sentencias2}
Si expresion es true, se ejecuta {sentencias1}; en caso contrario, se pasa a ejecutar {sentencias2}.
Ejemplo:
public boolean retirar(double cantidad){
boolean resultado=false;
System.out.println("Retirar de cuenta "+ cuenta);
System.out.println("Cantidad: "+ cantidad);
if(cantidad>saldo)
System.out.println("No hay fondos");
else{
saldo-=cantidad;
System.out.println("Nuevo saldo: "+saldo);
resultado=true;
}
return resultado;
}
Sentencia else-if
La sentencia else-if ampla el n
umero de opciones.
46
Expresin booleana
if( cantidad >saldo )
Bloque then
47
Ejercicio: Escribir un applet o aplicacion que escriba en la salida estandar si un a
no es bisiesto o no
lo es, dado un a
no cualquiera.
Nota: Una a
no es bisiesto si es divisible por 4 pero no por 100. Un a
no que es divisible por 4 y 100
es bisiesto si es tambien divisible por 400.
class Bisiesto{
public static void main(String args[]){
int anio=Integer.parseInt(args[0]);
if((anio%4==0)&&(anio%100!=0))
System.out.println("El anio " + anio+" es bisiesto");
else if((anio%4==0)&&(anio%100==0)&&(anio%400==0))
System.out.println("El anio " + anio+" es bisiesto");
else
System.out.println("El anio " + anio+" no es bisiesto");
}}
Sentencia switch
Se dispone de varias opciones derivadas de la evaluacion de una u
nica expresion. La sintaxis es la
siguiente:
switch(expresion) {
case {expresion1_constante1}:
{sentencias1}
case {expresion2_constante2}:
{sentencias2}
...
case {expresionN_constanteN}:
{sentenciasN}
default {sentencias}
Cada case lleva una o mas constantes enteras o expresiones constantes enteras. Si un case coincide
con el valor de expresion, la ejecucion comienza ah. Todas las expresiones de los case deben ser
diferentes. Si ninguna de ellas coincide con expresion, se ejecutan las sentencias correspondientes a
default. El default es optativo; si no esta y ninguno de los casos coincide, no se ejecuta ninguna
accion.
Ejemplo:
class Califica{
static void calificacion(int nota){
switch (nota){
case 3:
System.out.println("S"); break;
case 5:
System.out.println("A"); break;
case 7:
System.out.println("N"); break;
case 9:
48
Expresin Aritmtica
char, byte, short, int
switch (
nota
){
expresion1_constante1
case 3 :
System.out.println("S"); break;
expresion2_constante2
case 5 :
System.out.println("A"); break;
expresion3_constante3
case 7 :
System.out.println("N"); break;
expresion4_constante4
case 9 :
System.out.println("SB"); break;
default: System.out.println("Ser
calificado posteriormente");
}
System.out.println("SB"); break;
default: System.out.println("Sera
calificado posteriormente");
}
}
public static void
main(String args[]){
calificacion(5);
calificacion(8);
}
}
Ejercicio: Escribir una aplicacion que devuelva el n
umero de das de cada mes en un a
no cualquiera.
public class Calendario{
public static void
main(String args[]){
int mes=1;
int a=2000;
int numDias=0;
switch(mes){
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
numDias=31;
49
Expresin booleana
while ( numero<=100 ) {
sum=sum+numero;
numero=numero+1;
}
break;
4:
6:
9:
11:
numDias=30;
break;
case 2:
if(((a%4==0) && !(a%100==0))||
(a%400==0))
numDias=29;
else
numDias=28;
break;
case
case
case
case
}
System.out.println("Numero de
dias= "+numDias);
}
}
Ciclo while
while(expresion)
{sentencias}
Se ejecuta el bloque {sentencias} mientras el valor de la expresion es true. El ciclo se repite hasta
que el valor de expresion toma el valor false. Entonces, el compilador sale del ciclo.
Ejemplo: Supongamos que queremos sumar los primeros 100 n
umeros enteros.
int sum=0; numero=1;
while(numero<=100){
sum=sum+numero;
numero=numero+1;
}
Ejemplo:
50
class Bisiesto1{
public static void
main(String args[]){
char ans;
System.out.println("Quiere
introducir anio?? (y/n)");
ans=SavitchIn.readLineNonwhiteChar();
while((ans==y) || (ans==Y) ){
System.out.println("Introduzca
un anio");
int anio=SavitchIn.readLineInt();
if((anio%4==0)&&(anio%100!=0))
System.out.println("El anio " +
anio+" es bisiesto");
else if((anio%4==0)&&(anio%100==0)
&& (anio%400==0))
System.out.println("El anio " +
anio+" es bisiesto");
else
System.out.println("El anio " +
anio+" no es bisiesto");
Ejercicio: Calcular el producto de los primeros 20 n
umeros impares.
class Pares{
public static void
main(String args[]){
int producto=1, numero=1;
int limite=20, ultimoNumero;
ultimoNumero=2*limite+1;
while(numero<=ultimoNumero){
producto=producto*numero;
numero=numero+2;
}
System.out.println("Resultado="+
producto);
}
}
Ciclo do-while
do{
sentencias
}while({expresion});
51
Mientras en los ciclos while y for, las condiciones de termino se eval
uan al principio de cada iteracion,
en el ciclo do-while se comprueban al final, despues de cada repeticion del ciclo, por lo que el bloque
{sentencias} se ejecuta siempre, al menos una vez.
As, primero se ejecutan las sentencias del bloque sentencias y despues se eval
ua expresion.
Si es verdadera, se vuelve a ejecutar el bloque sentencias, y as sucesivamente.
Cuando expresion toma el valor false se acaba el ciclo.
El bloque while:
int a = 1;
while ( a != 15 ) {
a = a + 1;
}
equivale al bloque con do-while:
int a = 1;
do {
a = a + 1;
} while (a != 14);
Ciclo for
Act
ua hasta un cierto lmite impuesto por el programador. Su sintaxis es la siguiente:
for(iniciacion;limite;incremento)
{sentencias}
El ciclo for es equivalente a:
iniciacion
while(limite) {
{sentencias}
incremento
}
iniciacion e incremento suelen ser asignaciones o llamadas a una funcion, que en el caso de ser
mas de una, se separan por comas, y limite, una expresion relacional.
La expresion iniciacion se ejecuta al comienzo del bucle.
La expresion limite indica cuando se ejecuta el bucle y se eval
ua al comienzo de cada iteracion,
de manera que cuando su valor es true se ejecuta el bloque {sentencia} y si es false, el ciclo
for concluye.
Las sentencias del bloque sentencias se ejecutan en cada ciclo.
Las sentencias del bloque incremento se ejecutan al final de cada iteracion o ciclo.
El ciclo for es frecuente en la iniciacion de los elementos de un matriz:
int mult[];
mult = new int[100];
for(int i=0;i<100;i++) {
mult[i] = 2*(i+1);
}
52
Definiciones Recursivas
Factorial de un n
umero (Forma 1)
public class Factorial {
public static long factorial(long x){
if(x==1) return 1;
else return x*factorial(x-1);
}
public static void
main(String args[]) {
Long argumento=new Long(args[0]);
long n=argumento.longValue();
System.out.println(factorial(n));
}
}
Factorial de un n
umero (Forma 2)
import java.math.*;
public class Factorial1 {
public static BigInteger
factorial(long x){
BigInteger fact;
fact= BigInteger.valueOf(x);
if(fact== BigInteger.valueOf(1))
return BigInteger.valueOf(1);
else
return fact.multiply(factorial(x-1));
}
public static void
main(String args[]) {
Long argumento=new Long(args[0]);
long n=argumento.longValue();
System.out.println(
factorial(n).toString());
}
}
Sentencias de Bifurcaci
on
Permiten alterar el flujo de ejecucion normal del programa. Por ejemplo, la sentencia break en un
ciclo obliga al programa a abandonar el ciclo y continuar con la ejecucion de las sentencias que siguen.
La sentencia continue se usa dentro de un ciclo para iniciar la siguiente iteracion del ciclo que la
contiene. De esta manera se evita ejecutar las sentencias del ciclo siguientes a continue. Por ejemplo,
con las sentencias:
53
for (i = 0; i < n; i++) {
if(a[i] < 0)
continue;
}
se ignoran los valores negativos de la matriz a.
La sentencia return finaliza la ejecucion de la funcion que la contiene y devuelve el control a la
sentencia siguiente de la funcion de llamada. Ademas, puede devolver un valor. En este u
ltimo caso, la
sintaxis es: return expresion;
Algoritmo de la Bisecci
on para la B
usqueda de un N
umero en
una Matriz Ordenada de Enteros
import java.applet.Applet;
public class BusquedaBinaria extends Applet{
public static int Buscar(int x[], int n) {
int e1=0;
int e2=x.length-1;
int centro;
if(x[e1]==n)
return(e1);
else if (x[e2]==n)
return(e2);
while (e1<e2)
{
centro=(e1+e2)/2;
if(centro==e1)
return(-1);
else if(x[centro]==n)
return(centro);
else if (x[centro]<n)
e1=centro;
else
e2=centro;
}
return(-1); }
public void init() {
int datos[]={1,4,6,9,11,16,21,23,29,30};
System.out.println(1+" --> "+
Buscar(datos,1));
System.out.println(16+" --> "+
Buscar(datos,16));
System.out.println(29+" --> "+
Buscar(datos,29));
System.out.println(30+" --> "+
54
Buscar(datos,30));
System.out.println(2+" --> "+
Buscar(datos,2));
System.out.println(18+" --> "+
Buscar(datos,18));
System.out.println(22+" --> "+
Buscar(datos,22));
System.out.println(28+" --> "+
Buscar(datos,28));
}
}
Conjetura de Collatz
public class Collatz {
public static int F(int x) {
if(x%2==1)
return (3*x+1)/2;
else
return x/2;
}
public static void main(String args[]) {
int n, i=1;
Integer argumento=new Integer(args[0]);
n=argumento.intValue();
while(n!=1) {
System.out.println( "Iter. " + i +
":" + n );
i++;
n=F(n);
}
System.out.println("SE ALCANZA EL 1
TRAS "+ i +" ITERACIONES");
}
}
Por ejemplo, haciendo la llamada al metodo main() de la clase Collatz al mismo tiempo que se
pasa el valor inicial n = 56, se obtiene un resultado como el que se muestra a continuacion:
Iter.
Iter.
Iter.
Iter.
Iter.
Iter.
1:56
2:28
3:14
4:7
5:11
6:17
55
Iter. 7:26
Iter. 8:13
Iter. 9:20
Iter. 10:10
Iter. 11:5
Iter. 12:8
Iter. 13:4
Iter. 14:2
SE ALCANZA EL 1 TRAS 15 ITERACIONES
Generaci
on de una Pir
amide de N
umeros Mediante Bucles
Anidados
public class Piramide {
public static void main(String args[]) {
int i,j,k,m;
56
1
232
34543
4567654
567898765
67890109876
7890123210987
890123454321098
90123456765432109
0123456789876543210
123456789010987654321
23456789012321098765432
3456789012345432109876543
456789012345676543210987654
56789012345678987654321098765
int altura=12;
if(args.length>=1)
{
Integer argumento=new Integer(args[0]);
altura=argumento.intValue();
}
else
altura=10;
for(i=1,m=1;i<=altura;i++,m+=2)
{
for (j=1;j<=altura-i;j++)
System.out.print(" ");
for (k=i;k<=m;k++)
System.out.print(k%10);
for (j=m-1;j>=i;j--)
System.out.print(j%10);
System.out.println("");
}
}
}
El M
etodo main()
El metodo main() es el metodo de arranque de toda aplicaci
on en lenguaje Java.
Puede ejecutarse una clase cualquiera sin mas que incluir en ella el metodo main(). Cuando se trata
de aplicaciones, bastara implementarlo en una de las clases (la que se arranca).
El metodo main() es la herramienta de que dispone el lenguaje Java para decirle al ordenador que
hacer tras arrancar una aplicacion o clase. Por ello, es llamado automaticamente por el entorno Java
al arrancar la clase o aplicacion, controla el flujo del programa desde su comienzo, asigna los recursos
que se necesiten y se encarga de llamar a cualquier otro metodo que se requiera.
Forma de declarar el metodo main():
57
Arranca el
intrprete de Java
Carga la clase o
aplicacin
Arranca la clase
o aplicacin
No
Existe el
mtodo main?
Enva un mensaje
de error
Si
Arranca el
mtodo main
58
Los programas pueden necesitar informacion para poder ejecutarse seg
un los deseos del usuario.
Una de las herramientas que lo permiten son los argumentos de la lnea de comandos. Son caracteres o
cadenas de caracteres que el usuario teclea y que permiten modificar el comportamiento de la aplicacion
sin necesidad de recompilarla.
El metodo main() acepta como u
nico argumento una matriz de elementos de la clase String, que
se llaman argumentos de la lnea de comandos, puesto que se les puede dar valores al comienzo de la
ejecucion, mediante un cuadro de dialogo que se muestra al usuario al ejecutar el programa Java o en
el comando de arranque de la aplicacion (entornos UNIX y WINDOWS). Mediante estos argumentos
se puede enviar informacion a la aplicacion.
Por tanto, el programa Java debe ser capaz de leer los argumentos y programarlos. El proceso es
el siguiente: al ejecutar una aplicacion, el sistema pasa los argumentos tecleados por el usuario a su
metodo main(), y los almacena en una matriz de objetos de tipo String. Cada uno de los argumentos
es uno de los elementos de la matriz.
Pr
actica 1
public class Matriz {
public int nfilas, ncolumnas;
public float x[][];
public Matriz(float m[][]) {
nfilas=m.length;
ncolumnas=m[0].length;
x=m;
}
public Matriz(int n, int m) {
nfilas=n;
ncolumnas=m;
x=new float[n][m];
}
public void Mostrar() {
int i,j;
for(i=0;i<nfilas;i++) {
for(j=0;j<ncolumnas;j++)
System.out.print(x[i][j]+"
System.out.println("");
}
}
");
}
import java.applet.Applet; import curso.*;
public class Producto extends Applet{
public Matriz Multiplicar (Matriz A, Matriz B) {
int i,j,k;
float suma;
59
Matriz C= new Matriz (A.nfilas, B.ncolumnas);
for(i=0;i<A.nfilas;i++)
for(j=0;j<B.ncolumnas;j++)
{
suma=0;
for(k=0;k<A.ncolumnas;k++)
suma+=A.x[i][k]*B.x[k][j];
C.x[i][j]=suma;
}
return(C);
}
public void init() {
float x[][]={{2,1,0},{-1,3,2},{4,1,-1}};
float y[][]={{2,3},{5,4},{1,2}};
Matriz A=new Matriz(x);
Matriz B=new Matriz(y);
Matriz C;
System.out.println("Producto:");
C=Multiplicar(A,B);
C.Mostrar();
}
}
60
Pr
actica 2
class Persona{
int edad, telefono;
String nombre;
public Persona(){
nombre="No ha sido dado";
edad=0;
telefono=0;
}
public Persona(String nombre, int edad, int telefono){
this.nombre=nombre;
this.edad=edad;
this.telefono=telefono;
}
}
class Agenda{
Persona[] entradas;
int contador;
public Agenda(int tamano){
contador=0;
entradas=new Persona[tamano];
System.out.println("Se ha creado una matriz de tamano "+tamano);
}
void anadir(Persona nuevaPersona){
if(contador==entradas.length) aumentarTamano();
entradas[contador]=nuevaPersona;
contador++;
}
void aumentarTamano(){
int nuevaLongitud=2*entradas.length;
Persona[] entradasAux=new Persona[nuevaLongitud];
for(int i=0;i<entradas.length;i++){
entradasAux[i]=entradas[i];
}
entradas=entradasAux;
System.out.println("La nueva matriz de tamano "+entradas.length);
}
Persona busqueda(String buscarNombre){
Persona encontrarPersona;
int localizador=0;
while((localizador<contador) &&
!(buscarNombre.equals(entradas[localizador].nombre)))
localizador++;
if(localizador==contador)
encontrarPersona=null;
61
else
encontrarPersona=entradas[localizador];
return encontrarPersona;
}
}
class PrincipalAgenda{
public static void main(String args[]){
Agenda miAgenda;
Persona persona,personaBuscar;
miAgenda=new Agenda(4);
for(int i=0;i<4;i++){
persona=new Persona("X"+i,10+i,677888+i);
System.out.println("La persona anadida es "+persona.nombre);
miAgenda.anadir(persona);
}
persona=new Persona("X5",15,5555788);
miAgenda.anadir(persona);
System.out.println("La persona anadida es "+persona.nombre);
personaBuscar=miAgenda.busqueda("X2");
if(personaBuscar==null)
System.out.println("No se encuentra la persona indicada");
else
System.out.println("La persona indicada se encuentra en la agenda");
}
}
EXCEPCIONES
63
Excepciones
Conceptos b
asicos
Los errores forman parte de todo programa. El lenguaje Java usa las excepciones para su tratamiento
y manipulacion.
Una excepcion es un suceso que ocurre durante la ejecucion del programa, y que rompe el flujo
normal del mismo.
Cuando ocurre uno de estos sucesos, se crea una excepcion y el control del programa pasa desde
el punto donde el error se produjo a otro punto especificado por el programador.
Se dice que la excepcion es lanzada (thrown) desde el punto donde se crea y es recogida
(caught) en el punto donde se transfiere el control
Java hereda la terminologa y la sintaxis del tratamiento de excepciones del lenguaje C++.
Toda excepcion es representada por un objeto de la clase Throwable o cualquier subclase suya.
Para dar respuesta a las excepciones se utilizan los manipuladores de excepciones (exception
handler).
Primer ejemplo de excepciones
Dado el programa en Java:
public class PrimeraExcepcion{
public static void main(){
int a[] = new int[3];
a[0]=5;
a[1]=3;
a[2]=4;
System.out.println(a[1] );
System.out.println(a[4] );
}
}
La consola de Java devuelve el siguiente mensaje:
3
Exception Occurred:
java.lang.ArrayIndexOutOfBoundsException: 4
at PrimeraExcepcion.main(PrimeraExcepcion.java:9)
at com.apple.mrj.JManager.JMStaticMethodDispatcher.
run(JMAWTContextImpl.java)
at java.lang.Thread.run(Thread.java)
64
Throwable
Error
Exception
RuntimeException
Causas de excepciones
En un programa Java las excepciones pueden provocarse por:
1. El propio sistema cuando detecta un error o una condicion de ejecucion anormal. Algunas de
estas causas de excepciones son:
Operacion que provoca una violacion de las normas semanticas del lenguaje. Por ejemplo,
ndice fuera de lmites en una matriz.
Error al cargar una parte del programa.
Exceso en el uso de un cierto recurso. Por ejemplo, agotar la memoria.
Error interno en la maquina virtual.
2. Explcitamente por el programador, utilizando la sentencia throw.
Por que usar excepciones?
Tipos de Excepciones
Toda excepci
on es un objeto de la clase Throwable o de alguna de sus subclases
El programador puede crear sus propios tipos de excepciones construyendo subclases de la clase Throwable
que se adapten mejor a sus necesidades particulares. Por convenio, todos los nombres de las clases de
excepciones terminan con la palabra Exception.
La clase Throwable es la superclase de todos los errores y excepciones en el lenguaje java.
La clase Error agrupa todos los errores graves del sistema que conducen a situaciones de difcil
solucion. Es poco probable que dentro de un programa Java se intente hacer un tratamiento de
este tipo de errores.
65
La clase Exception y sus subclases son una forma de la clase Throwable que indica condiciones
que un programa razonable debe querer capturar.
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
67
La clase Error
La clase Error agrupa todos los errores graves del sistema que conducen a situaciones de difcil
solucion.
Es poco probable que dentro de un programa Java se intente hacer un tratamiento de este tipo de
errores.
Tratamiento de excepciones
Ejemplo:
import java.io.*;
class Division{
public static void main(String args[]){
BufferedReader f;
float x,y;
f=new BufferedReader(
new FileReader("Datos"));
x=new Float(f.readLine()).floatValue();
y=new Float(f.readLine()).floatValue();
System.out.println("Resultado = " + x/y);
}
}
En el programa anterior se producen dos errores de compilacion:
El metodo main() debe tratar una posible excepcion del tipo FileNotFoundException.
Tambien debe tratar las excepciones IOException que se pueden producir al leer los datos.
Existe otro punto que puede provocar una excepcion: al efectuar la division se produce una
ArithmeticException si el divisor es nulo. Sin embargo, no es necesario tratarla, ya que es de tipo
runtime.
68
Un metodo puede responder a una excepcion de dos formas:
1. Incorporando un manipulador de excepciones apropiado al tipo de la misma.
2. Declarandola y dejando que sea alguno de los metodos de los que provino quien se encargue de
responderla.
Construcci
on de un manipulador de excepciones
Las tres componentes basicas de un manipulador de excepciones son:
El bloque try: agrupa todas las sentencias que pueden provocar excepciones.
El bloque o bloques catch: sentencias que se ejecutan cuando se produce la excepcion.
El bloque finally (opcional): sentencias que se ejecutan siempre:
Tras las sentencias del bloque try si no se producen excepciones.
Tras las sentencias del bloque catch si se ha producido alguna excepcion.
El bloque try define el alcance del manipulador de excepciones y debe ir acompa
nado de al menos un
bloque catch o el bloque finally.
try{
...
} catch (...) {
...
} catch (...) {
...
} ...
} finally {
...
}
}
Cuando existen varias sentencias del metodo que potencialmente pueden provocar una excepcion, hay
dos posibilidades:
(a) Agrupar todas las sentencias en un solo bloque try con varios bloques catch para responder a
cada una de las excepciones.
(b) Agrupar cada sentencia individual en un bloque try con su bloque catch correspondiente.
Cada bloque catch requiere un argumento que indica el tipo de excepcion que trata, este argumento
pertenece siempre a una subclase de la clase Throwable. Puede utilizarse el metodo getMessage() de
este argumento para mostrar informacion adicional sobre el error que provoco la excepcion.
69
Funcionamiento del manipulador de excepciones.
Si se produce una excepci
on:
1. Una instruccion dentro de un bloque try provoca una excepcion.
2. Se abandona el flujo de ejecucion normal del programa.
3. El sistema busca el primer bloque catch cuyo tipo de excepcion se ajusta al de la que se ha
producido. La b
usqueda comienza en el mismo metodo en el que se produjo la excepcion y
contin
ua por los metodos de los que provena la llamada.
4. Se ejecutan las sentencias de ese bloque.
5. Si existe bloque finally se ejecutan sus sentencias, en otro caso se da por concluida la ejecucion
del programa.
Si no se produce ninguna excepci
on:
1. Se ejecutan normalmente las sentencias del bloque try.
2. Si existe bloque finally se ejecutan sus sentencias.
Soluciones alternativas al programa del ejemplo
Soluci
on 1:
import java.io.*; class Division{
public static void main(String args[]){
BufferedReader f;
float x,y;
try{
f=new BufferedReader
(new FileReader("Datos"));
x=new Float(f.readLine()).floatValue();
y=new Float(f.readLine()).floatValue();
System.out.println("Resultado = " + x/y);
} catch(FileNotFoundException e){
System.err.
println("No encontrado el fichero");
} catch(IOException e){
System.err.println("Error de lectura");
}
}
}
70
Soluci
on 2:
import java.io.*;
class Division{
public static void main(String args[]){
BufferedReader f;
float x,y;
try{
f=new BufferedReader
(new FileReader("Datos"));
x=new Float(f.readLine()).floatValue();
y=new Float(f.readLine()).floatValue();
System.out.println("Resultado = " + x/y);
} catch(Exception e){
System.err.
println("Error: "+ e.toString());
}
}
}
Declaraci
on de Excepciones
La alternativa a la construccion de un manipulador para una excepcion es dejar que un metodo
anterior en la sucesion de llamadas se encargue de responderla, utilizando para ello el comando throws.
Ejemplo:
public void S(int v[])
throws IndexOutOfBoundsException {
......................
......................
......................
}
Indica que en el metodo S() puede generarse una excepcion IndexOutOfBoundsException, pero en ese
caso, el bloque catch para tratarla debe buscarse no en el metodo S() sino a partir del metodo en el
que se hizo la llamada a el.
La Sentencia throw
La sentencia throw se utiliza para lanzar excepciones, es decir, cuando se detecta una situacion
que provocara un error, debe crearse un objeto de la clase de excepcion correspondiente, e indicar que
la excepcion se ha producido mediante una sentencia de la forma:
throw Objeto;
donde Objeto debe pertenecer a alguna de las subclases de la clase Throwable.
71
La sentencia throw es utilizada implcitamente por el sistema cuando detecta algunos errores
estandar.
El programador puede utilizarla para lanzar sus propias excepciones de forma explcita.
Pr
actica de Excepciones
Terminar de escribir el siguiente programa realizando el tratamiento de las excepciones. (Nota: No
olvidar introducir los argumentos para ejecutar la aplicacion. Hay que introducir los nombres de 2
ficheros.)
import java.io.*;
class LeerEscribir{
public static void main(String argv[]){
File leer=new File(argv[0]);
FileInputStream f1=new FileInputStream(leer);
File escribir=new File(argv[1]);
FileOutputStream f2=
new FileOutputStream(escribir);
int c;
while((c=f1.read()) != -1){
f2.write(c);
}
f1.close();
f2.close();
}
}
Solucion 1
import java.io.*;
class LeerEscribir1{
public static void main(String argv[]){
try{
File leer=new File(argv[0]);
FileInputStream f1=new FileInputStream(leer);
File escribir=new File(argv[1]);
FileOutputStream f2=
new FileOutputStream(escribir);
int c;
while((c=f1.read()) != -1){
f2.write(c);
}
f1.close();
72
f2.close();
}
catch(Exception e){
System.out.println("LeerEscribir: "+e);
}
finally{System.out.println(" Se ha realizado con exito");}
}
}
Solucion 2
import java.io.*;
class LeerEscribir{
public static void main(String argv[])
throws IOException{
File leer=new File(argv[0]);
FileInputStream f1=new FileInputStream(leer);
File escribir=new File(argv[1]);
FileOutputStream f2=
new FileOutputStream(escribir);
int c;
while((c=f1.read()) != -1){
f2.write(c);
}
f1.close();
f2.close();
}
}
CONTROL DE SUCESOS
74
Programa 1
import java.awt.*;
public class Marco1{
public Marco1(){
setTitle("Marco");
setSize(300,300);
}
public static void main(String[] args){
Marco1 m=new Marco1();
m.show();
}
}
Como cerrar la ventana?
Se puede controlar perfectamente como transmitir los sucesos desde las fuentes de sucesos, (botones,
barras de desplazamiento) a los receptores de sucesos. Cualquier objeto puede ser un receptor de sucesos.
Las fuentes de sucesos poseen metodos que permiten registrar receptores de sucesos con ellos. Las
fuentes de sucesos son objetos que tienen la capacidad de detectar sucesos y notificar a los receptores
que se han producido dichos sucesos.
Resumiendo:
un receptor es un ejemplar de una clase que implementa una interfase especial llamada interfase
receptora
una fuente de sucesos es un objeto que puede registrar receptores y enviarles mensajes cuando
ocurren sucesos. Estos mensajes son metodos de la interfase receptora.
C
omo registrar el receptor con la fuente?
eventSourceObject.
addEventListener(eventListenerObject);
Ejemplo:
Button b=new Button("OK");
b.addActionListener(objeto);
75
El objeto es avisado cuando tiene lugar un suceso de acci
on en el boton, (presionar el boton, en este
caso).
Por tanto, la clase a la que pertenece el objeto (el receptor) debe implementar la interfase apropiada:
ActionListener, en este caso.
Para implementar ActionListener, la clase del receptor debe poseer un metodo (actionPerformed)
que recibe un objeto de la clase ActionEvent como parametro.
En el paquete java.awt.Event aparecen once interfases receptoras:
ActionListener
AdjustmentListener
ComponentListener
ContainerListener
FocusListener
ItemListener
KeyListener
MouseListener
MouseMotionListener
TextListener
WindowListener
Volvamos al ejemplo de partida y veamos como cerrar la ventana. Para ello, en primer lugar
redefinimos la clase Marco1. Si queremos cerrar la ventana, el suceso que se va a crear es un objeto de
la clase WindowEvent.
marco.addWindowListener(x);
Quien puede recibir el suceso?
Un objeto de una clase que implemente la interfase
WindowListener. En nuestro caso, la fuente y el receptor son el mismo.
Ejemplo:
import java.awt.*;
import java.awt.event.*;
class Marco extends Frame
implements WindowListener{
public Marco(){
addWindowListener(this);
}
}
Pero implementar una interfase no es suficiente. Se deben implementar los metodos necesarios para
la interfase
WindowListener en la clase Marco. Nuestra clase debe implementar todos los metodos definidos en
la interfase WindowListener. Existen siete metodos. Java los llama como respuestas a siete sucesos
diferentes que pueden ocurrir en una ventana:
76
void
void
void
void
void
void
void
windowClosed(WindowEvent e)
windowIconified(WindowEvent e)
windowOpened(WindowEvent e)
windowClosing(WindowEvent e)
windowDeiconified(WindowEvent e)
windowActivated(WindowEvent e)
windowDeactivated(WindowEvent e)
Ejemplo:
import java.awt.*;
import java.awt.event.*;
public class Marco extends Frame
implements WindowListener{
public Marco(){
setTitle("Marco");
setSize(300,300);
addWindowListener(this);
}
public void windowClosing(WindowEvent e){
System.exit(0);
}
public void windowClosed(WindowEvent e){}
public void windowIconified(WindowEvent e){}
public void windowOpened(WindowEvent e){}
public void windowDeiconified(WindowEvent e){}
public void windowActivated(WindowEvent e){}
public void windowDeactivated(WindowEvent e){}
public static void main(String[] args){
Marco m=new Marco();
m.show();
}
}
Se han implementado seis metodos que no realizan ninguna accion. Simplifiquemos el programa
anterior.
Cada interfase receptora viene acompa
nada de una clase adaptadora que implementa todos los
metodos de la interfase pero no hace nada con ellos. Existe una clase adaptadora para cada una de las
siete interfases receptoras con mas de un metodo:
ComponentAdapter MouseAdapter
ContainerAdapter MouseMotionAdapter
FocusAdapter
WindowAdapter
KeyAdapter
77
Ejemplo:
import java.awt.*;
import java.awt.event.*;
class CerrarVentana extends WindowAdapter{
public void windowClosing(WindowEvent e){
System.exit(0);
}
}
class MarcoSimplificado extends Frame{
public MarcoSimplificado(){
CerrarVentana v = new CerrarVentana();
setTitle("Marco");
setSize(300,300);
addWindowListener(v);
}
public static void main(String[] args){
MarcoSimplificado m=new MarcoSimplificado();
m.show();
}
}
Ejemplo:
import java.awt.*;
import java.awt.event.*;
78
Sucesos
La superclase que engloba todos los sucesos es la clase EventObject implementada en el paquete
java.util
Event
Object
AW T E v e n t
Action Adjustment
Event Event
Container Focus
Event
Event
Component Item
Event
Event
Input
Paint
Event Event
Key
Event
Te x t
Event
Wi n d o w
Event
Mouse
Event
ActionEvent
FocusEvent MouseEvent
AdjustmentEvent ItemEvent
TextEvent
ComponentEvent
KeyEvent
WindowEvent
ContainerEvent
Describamos brevemente las clases del paquete
java.awt.event
u, activar un campo de texto.
ActionEvent: pulsar un boton, seleccionar un men
AdjustmentEvent: ajustar una barra de desplazamiento.
ItemEvent: seleccionar un boton de marca o un tem de una lista.
TextEvent: modificar el contenido de un area de texto.
79
no de una componente, moverla, mostrarla o esconderla.
ComponentEvent: modificar el tama
KeyEvent: pulsar o soltar una tecla.
MouseEvent: pulsar el boton del raton, soltarlo, mover o arrastrar el raton.
FocusEvent: activar o desactivar una componente.
WindowEvent: activar, desactivar, cerrar la ventana.
80
Interfase
M
etodos
Par
ametro
ActionListener
actionPerformed
ActionEvent
getActionCommand
getModifiers
AdjustmentListener
adjustmentValueChanged
ItemListener
itemStateChanged
TextListener
ComponentListener
textValueChanged
componentMoved
componentHidden
componentResized
componentAdded
componentRemoved
AdjustmentEvent
getAdjustable
getAdjustmentType
getValue
ItemEvent
getItem
getItemSelectable
getStateChange
TextEvent
ComponentEvent
getComponent
ContainerListener
FocusListener
KeyListener
focusGained
focusLost
keyPressed
keyReleased
keyTyped
MouseListener
mousePressed
mouseReleased
mouseEntered
mouseExited
mouseClicked
MouseMotionListener
mouseDragged
mouseMoved
windowClosing
windowOpened
windowIconified
windowDeiconified
windowClosed
windowActivated
windowDeactivated
WindowListener
ContainerEvent
getChild
getContainer
FocusEvent
IsTemporary
KeyEvent
getKeyChar
getKeyCode
getKeyModifiersText
getKeyText
IsActionKey
MouseEvent
getClickCount
getX
getY
getPoint
TranslatePoint
IsPopupTrigger
Sucesos
generados por
Button
List
MenuItem
TextField
Scrollbar
Checkbox
CheckboxMenuItem
Choice
List
TextComponent
Component
Container
Component
Component
Component
Component
WindowEvent
getWindow
Window
81
Ejemplo 1
import java.awt.*;
import java.applet.Applet;
public class Boton extends Applet{
Button a;
public void init(){
a=new Button("OK");
add(a);
}
}
Ejemplo 2
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class Boton extends Applet
implements ActionListener{
Button a;
public void init(){
a=new Button("OK");
add(a);
a.addActionListener(this);
}
public void actionPerformed(ActionEvent evt){
a.setLabel("Cancel");
}
}
Ejemplo 3
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
82
public class Botones extends Applet
implements ActionListener{
Button a,b;
public void init(){
a=new Button("a");
b=new Button("b");
add(a);
a.addActionListener(this);
add(b);
b.addActionListener(this);
}
public void actionPerformed(ActionEvent evt){
String arg=evt.getActionCommand();
if(arg.equals("a"))
b.setLabel("a");
else if(arg.equals("b"))
a.setLabel("b");
}
}
Ejemplo 4
import java.awt.*;
import java.applet.Applet;
83
import java.awt.event.*;
public class Sucesos extends Applet
implements MouseListener,ItemListener,
ActionListener,MouseMotionListener,
FocusListener{
List mensajes;
Button boton;
Choice colores;
Label etiqueta1,etiqueta2,etiqueta3,etiqueta4;
TextField nombre;
TextArea acciones;
int x,y,w,h;
public void init() {
addMouseMotionListener(this);
setLayout(null);
// Se crea la etiqueta 1
etiqueta1=new Label("BIENVENIDO!",Label.CENTER);
etiqueta1.setBounds(80,10,120,20);
add(etiqueta1);
// Se crea la etiqueta 2
etiqueta2=new Label("Mensajes",Label.CENTER);
etiqueta2.setBounds(10,40,120,20);
add(etiqueta2);
// Se crea la lista de mensajes
mensajes=new List(4,false);
mensajes.add("Hola");
mensajes.add("Cuidado");
mensajes.add("Peligro");
mensajes.add("Adios");
mensajes.setBounds(10,70,120,63);
mensajes.addMouseListener(this);
mensajes.addItemListener(this);
add(mensajes);
// Se crea el boton
boton=new Button("BOTON");
boton.setBounds(150,40,120,20);
boton.addMouseListener(this);
boton.addActionListener(this);
add(boton);
// Se crea el menu flotante
colores=new Choice();
colores.addItem("azul");
colores.addItem("verde");
colores.addItem("rojo");
84
colores.addItem("amarillo");
colores.addItem("negro");
colores.setBounds(150,70,120,80);
colores.addMouseListener(this);
colores.addItemListener(this);
add(colores);
// Se crea la etiqueta 3
etiqueta3=new Label("Acciones",Label.CENTER);
etiqueta3.setBounds(80,140,120,20);
etiqueta3.addMouseListener(this);
add(etiqueta3);
// Se crea la zona de texto no editable
acciones=new TextArea(15,25);
//acciones.setEditable(false);
acciones.setBounds(20,170,240,160);
acciones.addMouseListener(this);
add(acciones);
// Se crea la etiqueta 4
etiqueta4=new Label("Nombre",Label.CENTER);
etiqueta4.setBounds(80,350,120,20);
etiqueta4.addMouseListener(this);
add(etiqueta4);
// Se crea la zona de texto editable
nombre=new TextField(20);
nombre.setBounds(80,380,120,20);
nombre.addMouseListener(this);
nombre.addFocusListener(this);
add(nombre);
}
public void mouseEntered(MouseEvent evt) {
Object componente=evt.getSource();
if(componente.equals(boton)){
acciones.append("Se entra en el boton\n");
}else if(componente.equals(mensajes)){
acciones.append("Se entra en la lista\n");
}else if(componente.equals(acciones)){
acciones.append("Se entra en el campo de
acciones\n");
}else if(componente.equals(nombre)){
acciones.append("Se entra en el campo
nombre\n");
}
}
public void mouseExited(MouseEvent evt) {
Object componente=evt.getSource();
85
if(componente.equals(boton)){
acciones.append("Se sale del boton\n");
}else if(componente.equals(mensajes)){
acciones.append("Se sale de la lista\n");
}else if(componente.equals(acciones)){
acciones.append("Se sale de el campo de
acciones\n");
}else if(componente.equals(nombre)){
acciones.append("Se sale de el campo
nombre\n");
}
}
public void mouseClicked(MouseEvent evt) {
acciones.append("Se ha pulsado el raton\n");
}
public void mousePressed(MouseEvent evt) {
acciones.append("Se ha presionado el raton\n");
}
public void mouseReleased(MouseEvent evt) {
acciones.append("Se ha liberado el raton\n");
}
public void mouseDragged(MouseEvent evt) {
acciones.append("Se ha arrastrado el raton\n");
}
public void mouseMoved(MouseEvent evt) {
acciones.append("Se ha movido el raton\n");
}
public void itemStateChanged(ItemEvent evt) {
Object componente=evt.getSource();
if(componente.equals(mensajes)){
String mensaje=mensajes.getSelectedItem();
acciones.append("Se ha seleccionado "+
mensaje+"\n");
boton.setLabel(mensaje);
}
else if(componente.equals(colores)){
String color=(String)evt.getItem();
acciones.append("Se ha seleccionado el "+
color+"\n");
}
}
86
INTERFASES DE USUARIO
88
Paquete java.awt
En este paquete se encuentran clases que permiten definir las distintas componentes de una interfase.
La siguiente figura muestra algunas de las componentes disponibles en Java:
Paquete java.awt
Todas las componentes tienen lo siguiente en com
un:
Una posicion en la pantalla y un tama
no
Un color del fondo y un color del primer plano
Estar activadas o desactivadas
Una interfase para manejar los sucesos que ocurran sobre esa componente
Todas las componentes, excepto los men
us, se implementan como subclases de la clase Component y
por tanto, heredan de esta todos los procedimientos, que son los que permiten darles funcionalidad en
un programa.
Cuando se crea una componente, esta se a
nade a un contenedor para lo cual se utiliza el metodo
add() definido en la clase Container.
Este metodo tiene las tres definiciones siguientes:
Component add(Component comp)
Component add(Component comp,int pos)
Component add(Sring name,Component comp)
Algunos de los metodos definidos en la clase Component y que pueden ser utilizados por toda subclase
son:
String getName(): Devuelve el nombre de la componente.
void setName(String name): Asigna el nombre a la componente.
void setEnabled(boolean b): Para activar o desactivar la componente correspondiente.
void setVisible(boolean b): Para mostrar o ocultar la componente correspondiente.
Color getBackground(): Devuelve el color del fondo de dicha componente.
void setBackground(Color c): Asigna el color del fondo de dicha componente.
Font getFont(): Devuelve el tipo de letra de dicha componente.
void setFont(): Asigna el tipo de letra de dicha componente.
Dimension getSize(): Devuelve el tama
no de dicha componente.
void setSize(int width,int height): Modifica el tama
no de dicha componente.
89
void setBounds(int x,int y,int width,int height):
Mueve y modifica el tama
no de dicha componente.
FontMetrics getFontMetrics(Font font):Devuelve el aspecto metrico del tipo de letra.
void paint(Graphics g):Dibuja en esta componente.
void update(Graphics g):Actualiza esta componente.
void repaint():Redibuja esta componente.
Botones
La clase Button
La clase Button proporciona dos constructores para crear botones:
public Button()
public Button(String label)
Entre los metodos que proporciona la clase Button destaca:
void setLabel(String label)
void addActionListener(ActionListener al)
String getLabel()
Ejemplo:
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class Botones extends Applet {
// Se crean cuatro botones con diferentes nombres
Button a, b,c,d;
public void init() {
setLayout(new GridLayout(2,2,10,10));
a = new Button("Boton 1");
a.addActionListener(this);
b = new Button("Boton 2");
b.addActionListener(this);
c = new Button("Boton 3");
c.addActionListener(this);
d = new Button("Boton 4");
90
d.addActionListener(this);
setLayout(new GridLayout(2,2,10,10));
add(a);
add(b);
add(c);
add(d);
}
public void actionPerformed(ActionEvent evt) {
String arg = evt.getActionCommand();
// Al presionar sobre un bot
on, cambia su etiqueta
if (arg.equals("Boton 1"))
a.setLabel("A");
else if (arg.equals("Boton 2"))
b.setLabel("B");
else if (arg.equals("Boton 3"))
c.setLabel("C");
else if (arg.equals("Boton 4"))
d.setLabel("D");
}
}
La clase Checkbox
Para crear estos botones, se dispone de las clases Checkbox y CheckboxGroup.
La clase Checkbox proporciona tres constructores:
public Checkbox()
public Checkbox(String label)
public Checkbox(String label,boolean state)
public Checkbox(String label,CheckboxGroup group,
boolean state)
Entre sus metodos destacan:
void setCheckboxGroup(CheckboxGroup g)
CheckboxGroup getCheckboxGroup()
void setLabel(String label)
String getLabel()
void setState(boolean state)
boolean getState()
91
void addItemListener(ItemListener l)
void removeItemListener(ItemListener l)
La clase CheckboxGroup
El constructor de la clase CheckboxGroup es:
public CheckboxGroup()
Entre sus metodos destaca:
Checkbox getSelectedCheckbox()
void setSelectedCheckbox(Checkbox box)
String toString()
Ejemplo:
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class Botones extends Applet
implements ActionListener,
ItemListener{
Button a, b,c;
Checkbox d, e,f;
public void init() {
setLayout(null);
a = new Button("Boton 1");
a.addActionListener(this);
a.setBounds(10,10,50,20);
b = new Button("Boton 2");
b.setBounds(70,10,50,20);
b.addActionListener(this);
c = new Button("Boton 3");
c.setBounds(130,10,50,20);
c.addActionListener(this);
CheckboxGroup ch=new CheckboxGroup();
d=new Checkbox("Boton 4",ch,true);
d.setBounds(10,40,60,20);
d.addItemListener(this);
e=new Checkbox("Boton 5",ch,false);
e.setBounds(80,40,60,20);
e.addItemListener(this);
f=new Checkbox("Boton 6",ch,false);
f.setBounds(140,40,60,20);
92
f.addItemListener(this);
add(a);
add(b);
add(c);
add(d);
add(e);
add(f);
}
public void actionPerformed(ActionEvent evt) {
String arg = evt.getActionCommand();
if (arg.equals("Boton 1"))
a.setLabel("A");
else if (arg.equals("Boton 2"))
b.setLabel("B");
else if (arg.equals("Boton 3"))
c.setLabel("C");
}
public void itemStateChanged(ItemEvent evt) {
if(evt.getItem().equals("Boton 4")){
d.setLabel("D");
}else if(evt.getItem().equals("Boton 5")){
e.setLabel("E");
}else if(evt.getItem().equals("Boton 6")){
f.setLabel("F");
}
}
}
Canvas
Cuando se empieza a llenar una ventana con muchos elementos de interfase y m
ultiples paneles, lo
mejor es no dibujar directamente sobre la superficie de la ventana puesto que el dibujo puede interferir
con las componentes que se han colocado en la ventana. Un Canvas es un area rectangular en la cual
se puede dibujar.
Ejemplo:
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class Checkboxes extends Applet
implements ItemListener{
NuevoCanvas area;
Checkbox peq, medio, grande;
CheckboxGroup grupo;
93
public void init() {
setLayout(new BorderLayout());
Panel p=new Panel();
area=new NuevoCanvas();
grupo = new CheckboxGroup();
peq = new Checkbox("Peque\~no", grupo, true);
peq.addItemListener(this);
medio = new Checkbox("Medio", grupo, false);
medio.addItemListener(this);
grande = new Checkbox("Grande", grupo, false);
grande.addItemListener(this);
p.add(peq);
p.add(medio);
p.add(grande);
add(p,"South");
add(area,"Center");
}
public void itemStateChanged(ItemEvent evt){
if(evt.getItem().equals("Peque\~no")){
area.setFont(new Font("SansSerif",
Font.PLAIN,8));
area.repaint();}
else if(evt.getItem().equals("Medio")){
area.setFont(new Font("SansSerif",
Font.PLAIN,12));
area.repaint();}
else if(evt.getItem().equals("Grande")){
area.setFont(new Font("SansSerif",
Font.PLAIN,14));
area.repaint();}
}
}
class NuevoCanvas extends Canvas{
public NuevoCanvas(){
setFont(new Font("SansSerif",Font.PLAIN,8));
}
public void paint(Graphics g){
g.drawString("Esto es una prueba",50,50);
}
}
Zonas de Texto
La clase TextComponent es la superclase de las clases
TextArea y TextField, que permiten mostrar y editar texto.
Consta de los siguientes metodos:
94
String getSelectedText()
String getText()
boolean setEditable(boolean t)
void selectAll()
void select(int begin,int end)
void setText(String text)
addTextListener(TextListener tl)
La clase TextArea
Zona con varias lneas que permite mostrar texto.
El metodo setEditable() permite elegir si el area es editable.
La clase TextArea consta de los siguientes constructores:
public TextArea()
public TextArea(int rows, int cols)
public TextArea(String text)
public TextArea(String text,int rows,
int cols)
TextArea(String text,int rows,
int cols,int scroll)
donde scroll puede tomar los valores:
TextArea.SCROLLBARS BOTH
TextArea.SCROLLBARS VERTICAL ONLY
TextArea.SCROLLBARS HORIZONTAL ONLY
TextArea.SCROLLBARS NONE
Algunos de los metodos de esta clase son:
void append(String text)
int getColumns()
int getRows()
void insert(String str,int pos)
void replaceRange(String str,int start,int end)
95
La clase TextField
Un campo de texto es una componente con una u
nica lnea de texto editable.
Los constructores de un campo de texto son:
public TextField()
public TextField(int cols)
public TextField(String text)
public TextField(String text,int cols)
Algunos de los metodos de esta clase son:
void addActionListener(ActionListener al)
Ejemplo
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
public class TextWin extends Applet
implements ActionListener{
TextArea textAr;
TextField textF;
public void init()
{
setLayout(new BorderLayout());
textAr=new TextArea();
textF=new TextField();
textF.addActionListener(this);
add("North",textAr);
add("South",textF);
}
public void actionPerformed(ActionEvent evt)
{
textAr.append(textF.getText()+"\n");
textF.selectAll();
}
}
Etiquetas
La clase Label permite poner texto fijo en un programa.
Se tienen tres constructores en la clase Label:
public Label()
96
public Label(String label)
public Label(String label, int alignment)
Entre sus metodos:
void setAlignment(int alignment)
El parametro alignment puede tomar los valores:
Label.CENTER, Label.LEFT o Label.RIGHT.
void setText(String label)
String getText()
Ejemplo:
import java.awt.*;
public class LabelWin extends Frame {
public LabelWin() {
setLayout(new GridLayout(3,1));
Label l1 = new Label();
l1.setBackground(Color.white);
l1.setText("Blanco");
Label l2 = new Label("Amarillo");
l2.setBackground(Color.yellow);
Label l3 = new Label("Gris");
l3.setBackground(Color.gray);
l3.setAlignment(Label.CENTER);
setTitle("Label");
add(l1);
add(l2);
add(l3);
}
Marcos
La subclase Frame de la clase Window permite crear marcos donde se muestran las aplicaciones y los
applets.
Un objeto de la clase Frame es un marco con borde y barra de ttulo. Puede tener tambien una
barra de men
u. Los objetos de tipo Frame son necesarios en toda aplicacion.
Existen dos constructores de la clase Frame:
97
public Frame()
public Frame(String title)
Con el segundo de estos constructores se le da un ttulo al marco. Algunos de los metodos definidos
en la clase Frame son:
MenuBar getMenuBar()
String getTitle()
void setMenuBar(MenuBar mb)
void setTitle(String title)
Men
us
Existen las siguientes clases que permiten construir men
us y barras de men
us:
MenuItem
Los objetos MenuItem representan las opciones de un men
u.
CheckboxMenuItem
Subclase de MenuItem. Estos objetos hacen referencia a las opciones que act
uan como
botones de marca.
Menu
Subclase de MenuItem. Los men
us se representan mediante los objetos de tipo Menu, que
solo existen en barras de men
u.
MenuBar
Hace referencia al men
u principal. Las barras de men
u estan ligadas u
nicamente a los
contenedores de tipo Frame.
La clase MenuItem
La clase MenuItem consta de los constructores:
public MenuItem()
public MenuItem(String label)
public MenuItem(String label,MenuShortcut ms)
Entre sus metodos:
String getLabel()
void setLabel(String label)
98
boolean isEnabled()
void setEnabled(boolean b)
MenuShorcut getShortcut()
void setShortcut(MenuShortcut s)
void getActionCommand()
void addActionListener(ActionListener al)
La clase Menu
La clase Menu posee los siguientes constructores:
public Menu()
public Menu(String label)
public Menu(MenuBar mb)
public void setTitle(String label,boolean tearoff)
Entre sus metodos:
int getItemCount()
MenuItem getItem(int index)
MenuItem add(MenuItem mi)
void add(String label)
void insert(MenuItem mi,int index)
void insert(String label,int index)
void addSeparator()
void insertSeparator(int index)
void remove(int index)
void removeAll()
La clase MenuBar
La clase MenuBar tiene el constructor:
public MenuBar()
Entre sus metodos:
99
Menu add(Menu m)
void remove(int index)
int getMenuCount()
Menu getMenu(int i)
La clase CheckboxMenuItem
La clase CheckboxMenuItem consta de los constructores:
public CheckboxMenuItem()
public CheckboxMenuItem(String label)
public CheckboxMenuItem(String label,boolean state)
Entre sus metodos:
boolean getState()
void setState(boolean b)
void addItemListener(ItemListener l)
La clase MenuShortcut
La clase MenuShortcut consta de los constructores:
public MenuShortcut(int key)
public MenuShortcut(int key,boolean useShiftModifier)
Entre sus metodos:
int getKey()
boolean useShiftModifier()
Ejemplo:
import java.awt.*;
import java.awt.event.*;
public class Menus extends Frame
implements ActionListener, ItemListener{
MenuBar barra;
Menu m1,m2;
MenuItem mi1,mi2, mi3;
CheckboxMenuItem mi4;
100
public Menus() {
barra = new MenuBar();
setMenuBar(barra);
m1 = new Menu("Menu1");
barra.add(m1);
m2 = new Menu("Menu2");
barra.add(m2);
mi1 = new MenuItem("Salir");
mi1.addActionListener(this);
m1.add(mi1);
mi2 = new MenuItem("MenuItem 1");
mi2.setShortcut(
new MenuShortcut(KeyEvent.VK_5));
mi2.addActionListener(this);
m2.add(mi2);
mi3 = new MenuItem("MenuItem 2");
mi3.addActionListener(this);
m2.add(mi3);
mi4 = new CheckboxMenuItem("MenuItem 3");
mi4.addItemListener(this);
m2.add(mi4);
}
public void actionPerformed(ActionEvent evt){
MenuItem c=(MenuItem) evt.getSource();
String arg=c.getLabel();
if(arg.equals("Salir")){
System.exit(0);
}else if((arg.equals("MenuItem 1")) ||
(arg.equals("MenuItem 2"))){
System.out.println(arg);
}
}
public void itemStateChanged(ItemEvent evt){
CheckboxMenuItem c=
(CheckboxMenuItem) evt.getSource();
String arg=c.getLabel();
if(arg.equals("MenuItem 3")){
System.out.println(arg);
}
}
public static void main(String argv[]) {
Menus menus = new Menus();
menus.setTitle("Barra de Menus");
101
menus.setSize(200,200);
menus.setVisible(true);
}
}
Elecciones
La clase Choice construye men
us de tipo flotante. El constructor de esta clase es:
public Choice()
La primera opcion que se a
nade al men
u se considera como la opcion seleccionada por defecto, hasta
que el usuario elija otra.
Entre los metodos de la clase Choice destacan:
public int getItemCount()
public String getItem(int index)
public void addItem(String item)
public String getSelectedItem()
public void select(int pos)
public void select(String str)
public void addItemListener(ItemListener l)
Ejemplo:
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class Popup extends Applet
implements ItemListener {
Choice choice;
Color color;
public void init() {
color=Color.yellow;
choice = new Choice();
choice.addItem("rojo");
choice.addItem("azul");
choice.addItem("verde");
choice.addItemListener(this);
add(choice);
}
102
public void paint(Graphics g){
setBackground(color);
}
public void itemStateChanged(ItemEvent evt){
String str=(String)evt.getItem();
if(str.equals("rojo"))
color=Color.red;
else if(str.equals("azul"))
color=Color.blue;
else if(str.equals("verde"))
color=Color.green;
repaint();
}
}
Ejercicio:
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class Opera extends Applet implements ActionListener{
TextField t1,t2;
Choice opcion;
TextArea ta;
Button b1,b2;
public void init() {
setLayout(null);
103
t1=new TextField();
t2=new TextField();
ta=new TextArea();
Label l1=new Label("N\umero");
Label l2=new Label("Operaci\on");
b1=new Button("Calcular");
b1.addActionListener(this);
b2=new Button("Borrar");
b2.addActionListener(this);
opcion=new Choice();
opcion.addItem("|x|");
opcion.addItem("E^x");
opcion.addItem("x^5");
l1.setBounds(10,10,50,30);
t1.setBounds(60,10,100,30);
l2.setBounds(10,80,50,50);
opcion.setBounds(70,80,100,50);
ta.setBounds(10,150,300,100);
b1.setBounds(10,300,80,30);
b2.setBounds(150,300,80,30);
add(l1);
add(t1);
add(l2);
add(t2);
add(ta);
add(b1);
add(b2);
add(opcion);
}
public void actionPerformed(ActionEvent evt){
String str=evt.getActionCommand();
if(str=="Calcular"){
String str1=t1.getText();
String str2=opcion.getSelectedItem();
double d1;
Double aux1=new Double(str1);
d1=aux1.doubleValue();
if(str2=="|x|")
ta.append("|"+d1+"|"+"="+Math.abs(d1)+"\n");
else if(str2=="E^x")
ta.append("E"+"^"+d1+"="+Math.exp(d1)+"\n");
else if(str2=="x^5")
ta.append(d1+"^"+5+"="+Math.pow(d1,5)+"\n");
}
else if(str=="Borrar") ta.setText(" ");
}
}
104
Listas
La clase List permite crear un area desplazable conteniendo opciones que se pueden seleccionar.
Posee los constructores:
public List(int rows)
public List()
public List(int rows, boolean multipleSelections)
Entre sus metodos se encuentran:
void add(String item)
void add(String item, int index)
String getItem(int index)
void select (int index)
String getSelectedItem ()
void setMultipleMode (boolean b)
void addItemListener(ItemListener il)
void addActionListener(ActionListener al)
Ejemplo:
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class ListWin extends Applet implements ItemListener {
Button button;
List list;
public void init() {
setLayout(new BorderLayout());
list = new List(3, true);
list.add("Rojo");
list.add("Azul");
list.add("Verde");
list.addItemListener(this);
add("North",list);
}
public void itemStateChanged(ItemEvent evt){
int sIndex;
105
if(evt.getStateChange()==ItemEvent.SELECTED){
sIndex=((Integer)evt.getItem()).intValue();
System.out.println("Ha seleccionado
la opcion: "+sIndex);
}
else if(evt.getStateChange()==
ItemEvent.DESELECTED){
sIndex=((Integer)evt.getItem()).intValue();
System.out.println("Ha deseleccionado
la opcion: "+sIndex);
}
}
}
Paneles
Un panel es un contenedor (subclase de la clase
Container).
En el se puede colocar cualquier componente, inclusive otro panel.
La disposicion por defecto para un Panel es la de tipo
FlowLayout.
Ejercicio: Utilizacion Clase Panel
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
106
public class Operar extends Applet implements
ActionListener{
TextField t1,t2,t3;
TextArea ta;
Button b1,b2,b3;
public void init() {
t1=new TextField();
t2=new TextField();
t3=new TextField();
ta=new TextArea();
Label l1=new Label("Primer Numero",Label.CENTER);
Label l2=new Label("Segundo Numero",Label.CENTER);
Label l3=new Label("Resultado",Label.CENTER);
b1=new Button("Suma");
b2=new Button("Producto");
b3=new Button("Divisi\on");
b1.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
Panel p1=new Panel();
p1.setLayout(new GridLayout(3,2));
Panel p2=new Panel();
Panel p3=new Panel();
p1.add(l1); p1.add(t1);
p1.add(l2); p1.add(t2);
p1.add(l3); p1.add(t3);
p2.add(ta); p3.add(b1);
p3.add(b2); p3.add(b3);
add(p1);
add(p2);
add(p3);
}
public void actionPerformed(ActionEvent evt){
String str=evt.getActionCommand();
String str1=t1.getText();
String str2=t2.getText();
double d1,d2,total;
Double aux1=new Double(str1);
d1=aux1.doubleValue();
Double aux2=new Double(str2);
d2=aux2.doubleValue();
if(str=="Suma"){
total=d1+d2;
t3.setText(Double.toString(total));
ta.append("La operacion realizada ha sido
una suma"+"\n");
}else if(str=="Producto"){
107
total=d1*d2;
t3.setText(Double.toString(total));
ta.append("La operacion realizada ha sido
un producto"+"\n");
}else if(str=="Divisi\on"){
total=d1/d2;
t3.setText(Double.toString(total));
ta.append("La operacion realizada ha sido
una divisi\on"+"\n");
}
}
}
Cuadros de Di
alogo
Para implementar un cuadro de dialogo, se crea una subclase de la clase Dialog.
Los cuadros de dialogo son ventanas que dependen de otra ventana (Frame).
Cuando se destruye la ventana tambien se destruyen los cuadros de dialogo que dependen de ella.
En el constructor del cuadro de dialogo se llama al constructor de la clase Dialog, en este se da la
ventana de la cual depende.
Se asignan las dimensiones del cuadro mediante el metodo setSize().
La aplicacion debe utilizar el metodo show() para que aparezca el dialogo.
La ordenacion (layout) por defecto de las diferentes componentes de un cuadro de dialogo es
BorderLayout.
Hay cuatro constructores de la clase Dialog:
public Dialog(Frame parent);
public Dialog(Frame parent, boolean modal);
public Dialog(Frame parent, String title);
public Dialog(Frame parent, String title,
boolean modal)
Ejemplo:
import java.awt.*;
import java.awt.event.*;
public class VentanaDialog extends Frame
108
implements ActionListener{
SimpleDialog dialog;
TextArea textArea;
Button boton1;
public VentanaDialog(){
textArea=new TextArea(5,40);
textArea.setEditable(false);
add("Center",textArea);
boton1=new Button("Pulsar para mostrar dialogo");
boton1.addActionListener(this);
Panel panel=new Panel();
panel.add(boton1);
add("South",panel);
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}});
}
public void actionPerformed(ActionEvent evt){
String str=evt.getActionCommand();
if(str.equals("Pulsar para mostrar dialogo")){
if(dialog==null)
dialog=new SimpleDialog(this,"Cuadro de
dialogo");
dialog.show();
}
}
public void setText(String texto){
textArea.append(texto+"\n");
}
public static void main(String args[]){
VentanaDialog ventana=new VentanaDialog();
ventana.setTitle("Aplicacion");
ventana.setSize(200,200);
ventana.setVisible(true);
}
}
class SimpleDialog extends Dialog
implements ActionListener{
109
TextField campo;
VentanaDialog parent;
Button b1;
public SimpleDialog(Frame fr,String titulo){
super(fr,titulo,true);
parent=(VentanaDialog)fr;
Panel p1=new Panel();
Label etiqueta=new Label("Escribir texto:");
p1.add(etiqueta);
campo=new TextField(40);
p1.add(campo);
add("Center",p1);
setSize(600,100);
}
public void actionPerformed(ActionEvent evt){
String str=evt.getActionCommand();
if(str.equals("Ok"))
parent.setText(campo.getText());
setVisible(false);
}
}
Criterios de Colocaci
on
Criterio BorderLayout
BorderLayout es el gestor de colocacion por defecto para todas las ventanas(Windows), tales como
marcos (Frames) y dialogos (Dialogs).
Utiliza cinco areas: norte, sur, este, oeste y centro.
Todo el espacio extra se coloca en el area del centro.
La clase BorderLayout posee los constructores:
110
public BorderLayout()
public BorderLayout(int hgap,int vgap)
Ejemplo:
import java.awt.*;
import java.applet.Applet;
public class BorderLayoutWin extends Applet {
public void init() {
setLayout(new BorderLayout(10,10));
add("North",new Label("Norte",Label.CENTER));
add("South",new Label("Sur",Label.CENTER));
add("East",new Label("Este",Label.CENTER) );
add("West",new Label("Oeste",Label.CENTER));
add("Center",new Label("Centro",Label.CENTER) );
}
public static void main(String args[]) {
Frame f = new Frame("BorderLayout");
BorderLayoutWin bl = new BorderLayoutWin();
bl.init();
f.add("Center", bl);
f.setSize(200,200);
f.setVisible(true);
}
}
Criterio CardLayout
Se utiliza la disposicion CardLayout cuando se tiene una zona que puede contener diferentes componentes en diferentes instantes.
Para a
nadir y mostrar una componente se utilizan los metodos:
add(String name, Component comp)
Con el primer argumento se identifica la componente que se esta a
nadiendo.
show(Container target, String name)
Para mostrar la componente correspondiente. El primer argumento es el contenedor que maneja
el CardLayout. El segundo identifica la componente a mostrar.
Algunos de los metodos definidos en la clase CardLayout son:
void first(Container target)
void last(Container target)
void next(Container target)
111
void previous(Container target)
Ejemplo:
import
import
import
public
java.awt.*;
java.awt.event.*;
java.applet.Applet;
class CardLayoutWin extends Applet
implements ItemListener {
Panel
final
final
final
cl;
String MES1 = "Panel1 con tres botones ";
String MES2 = "Panel2 con tres botones";
String MES3 = "Panel3 con tres botones";
112
cl.add(MES1, panel1);
cl.add(MES2, panel2);
cl.add(MES3, panel3);
add(cl);
}
public void itemStateChanged(ItemEvent evt){
String str;
if(evt.getStateChange()==ItemEvent.SELECTED){
str=(String)evt.getItem();
((CardLayout)cl.getLayout()).show(cl,str);
}
}
public static void main(String args[]) {
Frame f = new Frame("CardLayout");
CardLayoutWin cl = new CardLayoutWin();
cl.init();
f.add("Center", cl);
f.setSize(200,200);
f.setVisible(true);
}
}
Criterio FlowLayout
FlowLayout es el gestor de colocaci
on por defecto para los paneles (Panels). Coloca sus componentes
en una fila.
La clase FlowLayout tiene tres constructores:
public FlowLayout();
public FlowLayout(int alignment)
public FlowLayout(int alignment,
int horizontalGap, int verticalGap)
El argumento alignment puede tomar uno de estos valores:
1. FlowLayout.LEFT
2. FlowLayout.CENTER
3. FlowLayout.RIGHT.
113
Ejemplo:
import java.awt.*;
import java.applet.Applet;
public class FlowLayoutWin extends Applet {
public void init() {
setLayout(new FlowLayout());
add(new Label("Label1"));
add(new Label("Label2"));
add(new Label("Label3"));
add(new Label("Label4"));
add(new Label("Label5"));
add(new Label("Label6"));
}
public static void main(String args[]) {
Frame f = new Frame("FlowLayout");
FlowLayoutWin fl = new FlowLayoutWin();
fl.init();
f.add("Center", fl);
f.setSize(300,100);
f.setVisible(true);
}
}
Criterio GridLayout
La clase GridLayout coloca sus componentes en una rejilla de celdas.
Los constructores de la clase GridLayout son:
GridLayout(int rows, int columns)
GridLayout(int rows, int columns,
int horizontalGap, int verticalGap)
Al menos, uno de los argumentos rows o columns debe ser distinto de cero.
Ejemplo:
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
public class GridLayoutWin extends Applet
implements ActionListener{
final int n=20;
114
Label lab;
public void init() {
Button[] b=new Button[n-1];
setLayout(new GridLayout(n/5,n/4));
for(int i=0;i<n-1;i++){
add(b[i]=new Button(" "+i));
b[i].addActionListener(this);
}
lab=new Label("Label",Label.CENTER);
add(lab);
}
public void actionPerformed(ActionEvent evt){
String arg=evt.getActionCommand();
lab.setText(arg);
}
public static void main(String args[]) {
Frame f = new Frame("GridLayout");
GridLayoutWin gl = new GridLayoutWin();
gl.init();
f.add("Center", gl);
f.setSize(200,200);
f.setVisible(true);
}
}
115
Paquete javax.swing
Java 2 proporciona un sustituto de Awt: Swing, un nuevo conjunto de clases. Permite:
seleccion mas amplia de objetos
apariencia mejorada
mayor control por parte del programador sobre el aspecto y funcionamiento de la interfaz.
Se incorporan todos los aspectos u
tiles de Awt. En algunos casos se han extendido las clases o
implementado interfases de Awt.
Swing forma parte de las cinco libreras que constituyen las JFC (Java Foundation Classes), que
facilitan la creacion de interfaces graficas de usuario (GUIs). Engloban las siguientes caractersticas:
Awt
Las componentes Swing
Eleccion de la apariencia de las componentes Swing.
Accesibilidad API: es posible obtener informacion de la interfaz.
Java 2DT M API: es posible incorporar graficos en dos dimensiones de elevada calidad, texto e
imagenes en aplicaciones y applets.
Se pueden implementar elementos que transfieren informacion entre aplicaciones Java y aplicaciones nativas.
En la direccion http://java.sun./products/jfc se pueden encontrar paquetes nuevos que pueden distribuirse separadamente. Incluso las componentes mas sencillas de Swing tienen mas caractersticas que
las que AWT puede ofrecer:
los botones y etiquetas pueden incluir imagenes
se pueden agregar o cambiar los bordes de casi todas las componentes Swing
se puede modificar el comportamiento y la apariencia de una componentes Swing
se puede obtener informacion de las componentes: una herramienta puede obtener el texto de una
etiqueta o de un boton
Los paquetes que engloban todas las clases referentes a Swing son los que comienzan por javax.swing.
Los mas usados son:
javax.swing: todas las componentes
javax.swing.event: los sucesos
116
Swing vs Awt
Ejemplo Awt
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class Boton extends Applet
implements ActionListener{
Button b;
public void init(){
b=new Button("Pulsar");
add(b);
b.addActionListener(this);
}
public void actionPerformed(ActionEvent e){
b.setLabel("OK");
}
}
Ejemplo Swing
//clase Container
import java.awt.*;
//clase ActionEvent
import java.awt.event.*;
//componentes de Swing y JApplet
import javax.swing.*;
public class JBoton extends JApplet
implements ActionListener{
JButton b;
public void init(){
Container contenedor=getContentPane();
contenedor.setLayout(new FlowLayout());
b=new JButton("Pulsar");
contenedor.add(b);
b.addActionListener(this);
}
public void actionPerformed(ActionEvent e){
b.setText("OK");
}
}
Principales diferencias:
Las componentes se importan del paquete javax.swing
117
Para cada elemento de Awt existe un equivalente en Swing. El nombre es el mismo precedido de
la letra J.
En Awt, los componentes se pueden colocar directamente sobre el applet, con el metodo add. En
Swing, el JApplet no act
ua como contenedor de sus componentes; contiene un objeto Container,
panel de contenido, en el cual se colocan todos los componentes del applet con el metodo add. Se
puede obtener referencia de dicho panel usando el metodo getContentPane de la clase JApplet.
La disposicion por defecto en el panel de contenido de un JApplet es la BorderLayout.
La superclase de los componentes de Swing es JComponent, que deriva de la clase Container de
Awt y, por tanto, de la clase Component de Awt.
Applets en Swing
Cualquier applet que contenga componentes Swing debe ser subclase de JApplet.
La clase JApplet es subclase de java.applet.Applet.
Caractersticas de los japplets:
proporcionan apoyo a otras tecnologas.
son contenedores Swing de alto nivel y, por tanto, tienen un panel raz, que permite agregar una
barra de men
us.
todo contenedor de alto nivel posee un panel de contenido:
los componentes se agregan al panel.
la disposicion de los componentes se fija en el panel.
la disposicion por defecto en el panel de contenido de un japplet es BorderLayout.
Funcionamiento:
Si el navegador reconoce las clases Swing, se puede usar una <APPLET> tag. En caso contrario,
es necesario un Java plug-in. Por lo que es necesario incluir un <OBJECT> o <EMBED> tag.
Se puede bajar una herramienta gratis que genera automaticamente los tags necesarios. Para obtenerla junto con el Plug-in:
http://java.sun.com/products/plugin/.
Requiere tiempo bajarse el Plug-in, por lo que es aconsejable avisar a los posibles usuarios de que
la pagina contiene un applet.
Metodos nuevos que incorpora la clase JApplet:
void setContentPane(Container c):Asigna la propiedad contentPane. Este metodo es llamado
por el constructor. constructor.
Container getContentPane():Devuelve el objeto contentPane para este applet.
JRootPane createRootPane():Es llamado por el constructor para crear el rootPane por defecto.
void setRootPane(JRootPane jrp):Asigna la propiedad rootPane.
JRootPane getRootPane():Devuelve el objeto rootPane para este applet.
118
u para este applet.
void setJMenuBar(JMenuBar jmb):Asigna la barra de men
u en este applet.
JMenuBar getJMenuBar(): Devuelve la barra de men
Contenedores y Componentes
Todos los elementos que configuran una interfaz grafica de usuario en Swing se pueden clasificar en:
contenedores superiores: applets, ventanas de dialogo y marcos.
contenedores intermedios: contenedores intermedios como paneles, paneles desplazables, paneles
divididos, barras de herramientas, paneles con solapas.
contenedores especiales: marcos internos, paneles raz, . . .
componentes basicos: botones, listas, campos de texto, men
us, . . .
informacion no editable: etiquetas, barras de estado, . . .
informacion formateada y editable: paletas de colores, seleccionadores de ficheros, tablas, texto,
arboles.
La clase JComponent
Excepto de los contenedores superiores, todos los demas elementos de Swing cuyo nombre comienza
con j descienden de la clase JComponent. Dicha clase es subclase de Container y , por tanto, de
Component.
Algunos de los metodos que incorpora JComponent son:
void setToolTipText(String text)
void setBorder(Border border)
void setPreferredSize(Dimension preferredSize)
void setMaximumSize(Dimension maximumSize)
void setMinimumSize(Dimension minimumSize)
void setAlignmentX(float alignmentX)
void setAlignmentY(float alignmentY)
void revalidate()
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class EjemploContenedores extends JApplet{
JButton boton;
JLabel etiqueta;
119
JPanel panel;
public void init(){
Container contenedor=getContentPane();
JPanel panel=new JPanel();
panel.setBorder(BorderFactory.createEmptyBorder(
30,//b. superior
30,//izqda
10,//b.inferior
30));//dcha
panel.setLayout(new GridLayout(0,1));
boton=new JButton("OK");
panel.add(boton);
etiqueta=new JLabel("Esto es una prueba");
panel.add(etiqueta);
contenedor.add(panel);
}
}
La jerarqua de todos los componentes involucrados es la siguiente:
contenedor superior: en nuestro caso es un applet (JApplet). Tambien contamos con las ventanas
de dialogo (JDialog) y los marcos (JFrame).
contenedor intermedio: en este ejemplo es un panel (JPanel). Permite simplificar la colocacion
de los componentes del applet. Otros contenedores intermedios son los paneles desplazables
(JScrollPane) y los paneles con solapas
(JTabbedPane).
componentes basicos: botones, etiquetas, . . .
Pero todo contenedor de alto nivel contiene un panel de contenido que alberga todos los componentes
visibles de la interfaz, salvo las barras de men
u.
Veamos a continuacion ejemplos ilustrativos de algunos contenedores.
Paneles divididos
Un objeto de la clase JSplitPane esta formado por dos componentes separados por una barra divisoria
que puede manipularse con el raton.
El procedimiento es colocar cada componente en un panel desplazable que, a su vez, se incluye en
el panel dividido.
Ejemplo:
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
120
public class PanelDividido extends JApplet
implements ListSelectionListener{
private JLabel foto;
private JList lista;
private JSplitPane panel;
private String[] titulos=
{"foto1.gif","foto2.gif","foto3.gif"};
public void init(){
Container contenedor=getContentPane();
lista=new JList(titulos);
lista.setSelectionMode(
ListSelectionModel.SINGLE_SELECTION);
lista.setSelectedIndex(0);
lista.addListSelectionListener(this);
JScrollPane pd1=new JScrollPane(lista);
ImageIcon foto1=
new ImageIcon("Fotos/"+titulos[0]);
foto=new JLabel(foto1);
foto.setPreferredSize(
new Dimension(foto1.getIconWidth(),
foto1.getIconHeight()));
JScrollPane pd2=new JScrollPane(foto);
panel=
new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,pd1,pd2);
panel.setOneTouchExpandable(true);
panel.setDividerLocation(150);
Dimension tamMinimo=new Dimension(100,50);
pd1.setMinimumSize(tamMinimo);
pd2.setMinimumSize(tamMinimo);
panel.setPreferredSize(new Dimension(400,200));
contenedor.add(panel);
}
public void valueChanged(ListSelectionEvent e)
{
JList l=(JList)e.getSource();
if (l.isSelectionEmpty())
{
121
foto.setIcon(null);
}else
{
int indice=l.getSelectedIndex();
ImageIcon nuevaFoto=
new ImageIcon("Fotos/"+titulos[indice]);
foto.setIcon(nuevaFoto);
foto.setPreferredSize(
new Dimension(nuevaFoto.getIconWidth(),
nuevaFoto.getIconHeight()));
foto.revalidate();
}
}
}
Constructores:
public JSplitPane()
public JSplitPane(int newOrientation)
public JSplitPane(int newOrientation,boolean newContinuousLayout)
public JSplitPane(int newOrientation,Component newLeftComponent,
Component newRightComponent)
public JSplitPane(int i,boolean b,Component c1,
Component c2)
Los argumentos enteros pueden ser
JSplitPane.HORIZONTAL_SPLIT
y
JSplitPane.VERTICAL_SPLIT
Metodos
void setOrientation(int orientation)
void setDividerSize(int newSize)
void setOneTouchExpandable(boolean newValue)
void setTopComponent(Componentcomponent)
void setBottomComponent(Component component)
void setLeftComponent(Component component)
122
void setRightComponent(Component component)
void setDividerLocation(double
proportionalLocation)
void setDividerLocation(int location)
void resetToPreferredSize()
Componentes B
asicos
Men
us desplegables.
Los objetos de la clase JComboBox pueden ser editables o no editables. Por defecto son no editables.
Los editables tienen la apariencia de un campo de texto.
Ejemplo:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class EjemploComboB extends JApplet
implements ActionListener{
JLabel foto;
public void init(){
Container contenedor=getContentPane();
JPanel panel=new JPanel();
panel.setLayout(new BorderLayout());
String[] titulos=
{"foto1.gif","foto2.gif","foto3.gif"};
JComboBox lista=new JComboBox(titulos);
lista.setSelectedIndex(2);
lista.addActionListener(this);
ImageIcon fotoSelecc=new ImageIcon("Fotos/"+
titulos[lista.getSelectedIndex()]);
foto=new JLabel(fotoSelecc);
foto.setPreferredSize(
new Dimension(fotoSelecc.getIconWidth(),
fotoSelecc.getIconHeight()));
panel.add(lista,BorderLayout.NORTH);
panel.add(foto,BorderLayout.SOUTH);
panel.setBorder(
BorderFactory.createEmptyBorder(20,20,20,20));
contenedor.add(panel);
123
}
public void actionPerformed(ActionEvent e)
{
JComboBox c=(JComboBox)e.getSource();
String nombre=(String)c.getSelectedItem();
ImageIcon nuevaFoto=
new ImageIcon("Fotos/"+nombre);
foto.setIcon(nuevaFoto);
foto.setPreferredSize(
new Dimension(nuevaFoto.getIconWidth(),
nuevaFoto.getIconHeight()));
}
}
Constructores:
public JComboBox()
public JComboBox(ComboBoxModel aModel)
public JComboBox(Object[] items)
public JComboBox(Vector items)
Metodos:
void addItem(Object anObject)
void insertItemAt(Object anObject,int index)
void setEditable(boolean aFlag)
boolean isEditable()
Tablas
La claseJTable permite crear tablas de datos, editables opcionalmente.
Ejemplo:
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
public class EjemploTabla extends JApplet {
private boolean DEBUG = true;
public void init() {
Object[][] datos = {
124
{"Maria", "Gonzalez",
"Gutierrez", new Integer(5),"Aprobado"},
{"Juan", "Gomez",
"Perez", new Integer(3), "Suspenso"},
{"Ana", "Garcia",
"Perez", new Integer(10), "Matricula"},
{"Pedro", "Diaz",
"Martinez", new Integer(7), "Notable"},
{"Miguel", "Gutierrez",
"Perez", new Integer(4), "Suspenso"}
};
String[] encab = {"Nombre",
"Primer Apellido",
"Segundo Apellido",
"Nota Examen",
"Nota Final"};
final JTable tabla = new JTable(datos, encab);
tabla.setPreferredScrollableViewportSize(
new Dimension(500, 70));
if (DEBUG) {
tabla.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
imprimirDatos(tabla);
}
});
}
JScrollPane pd = new JScrollPane(tabla);
getContentPane().add(pd, BorderLayout.CENTER);
}
private void imprimirDatos(JTable t) {
int numFilas = t.getRowCount();
int numCols = t.getColumnCount();
TableModel modelo= t.getModel();
System.out.println("Datos: ");
for (int i=0; i < numFilas; i++) {
System.out.print("
fila " + i + ":");
for (int j=0; j < numCols; j++) {
System.out.print(" " + modelo.getValueAt(i, j));
}
System.out.println();
}
125
System.out.println("-----");
}
}
Existen ciertas desventajas:
Cada celda es editable automaticamente.
Tratan todo tipo de datos de la misma forma.
Todos los datos deben almacenarse en un array o vector.
Constructores:
JTable()
JTable(int numRows,int numColumns)
JTable(Object[][] rowData,Object[] columnName)
JTable(Vector rowData,Vector columnNames)
Metodos:
void
setPreferredScrollableViewportSize(Dimension rowHeight)
void setMinWidth(int minWidth), (en TableColumn)
void setPreferredWidth(int preferredWidth), (en TableColumn)
void setMaxWidth(int maxWidth), (en TableColumn)
void setSelectionMode(int selectionMode). Los argumentos son
ListSelectionModel.SINGLE_SELECTION,
ListSelectionModel.SINGLE_INTERVAL_SELECTION,
ListSelectionModel.MULTIPLE_INTERVAL_SELECTION.
Componentes de texto
Existen cinco componentes de texto que proceden de la superclase JTextComponent:
JTextField
JPasswordField
JTextArea
JEditorPane
JTextPane
126
Ejemplo:
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import java.io.IOException;
public class EjemploTexto extends JApplet
implements ActionListener {
private String newline = "\n";
protected static final String campoTextoString =
"JTextField";
protected static final String passwordString =
"JPasswordField";
protected JLabel accionEtiqueta;
public void init() {
accionEtiqueta =
new JLabel("Escribe y dale Return en un campo");
accionEtiqueta.setBorder(
127
BorderFactory.createEmptyBorder(10,0,0,0));
128
editorSP.setPreferredSize(new Dimension(250, 145));
editorSP.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)));
129
130
return editorPane;
}
private void displayURL(URL url, JEditorPane editorPane) {
try {
editorPane.setPage(url);
} catch (IOException e) {
System.err.println("Attempted to read a bad URL: " +
url);
}
}
private JTextPane crearTextPane() {
JTextPane textPane = new JTextPane();
String[] initString =
{ "Este es un JTextPane editable, ",
"otro ",
"componente ",
"formateado ",
"que puede incluir componentes.." + newline,
" " + newline,
"...e iconos..." + newline,
" ",
newline + "JTextPane es una subclase
de JEditorPane que " +
"usa un StyledEditorKit y
StyledDocument, y tiene " +
"metodos para actuar con esos objetos."
};
String[] initStyles =
{ "italic", "bold", "small", "large",
"regular", "button", "icon", "regular",
"regular"
};
initStylesForTextPane(textPane);
Document doc = textPane.getDocument();
try {
for (int i=0; i < initString.length; i++) {
doc.insertString(
doc.getLength(), initString[i],
textPane.getStyle(initStyles[i]));
}
131
} catch (BadLocationException ble) {
System.err.println("Couldnt insert initial text.");
}
return textPane;
}
protected void initStylesForTextPane(JTextPane textPane) {
Style def = StyleContext.getDefaultStyleContext().
getStyle(StyleContext.DEFAULT_STYLE);
Style regular = textPane.addStyle("regular", def);
StyleConstants.setFontFamily(def, "SansSerif");
Style s = textPane.addStyle("italic", regular);
StyleConstants.setItalic(s, true);
s = textPane.addStyle("bold", regular);
StyleConstants.setBold(s, true);
s = textPane.addStyle("small", regular);
StyleConstants.setFontSize(s, 10);
s = textPane.addStyle("large", regular);
StyleConstants.setFontSize(s, 16);
s = textPane.addStyle("icon", regular);
StyleConstants.setAlignment(s,
StyleConstants.ALIGN_CENTER);
StyleConstants.setIcon(s,
new ImageIcon("Imagenes/Pig.gif"));
s = textPane.addStyle("button", regular);
StyleConstants.setAlignment(s,
StyleConstants.ALIGN_CENTER);
JButton button = new JButton(
new ImageIcon("Imagenes/sound.gif"));
button.setMargin(new Insets(0,0,0,0));
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Toolkit.getDefaultToolkit().beep();
}
});
StyleConstants.setComponent(s, button);
}
}
132
Metodos de la clase JTextComponent:
void setDisabledTextColor(Color c)
void setMargin(Insets m)
void setEditable(boolean b)
String getSelectedText()
void selectAll()
void select(int selectionStart,
int selectionEnd)
void setSelectedTextColor(Color c)
void setSelectionColor(Color c)
void cut()
void copy()
void paste()
Ayuda
Se puede crear un peque
no men
u de ayuda para cualquier objeto de la clase JComponent
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class EjemploAyuda extends JApplet{
final static String BOTONES="Panel con botones";
final static String CAMPO=
"Panel con campo de texto";
public void init(){
Container contenedor=getContentPane();
JTabbedPane panel=new JTabbedPane();
JPanel p1=new JPanel();
p1.add(new JButton("Boton 1"));
p1.add(new JButton("Boton 2"));
p1.add(new JButton("Boton 3"));
panel.addTab(BOTONES,
new ImageIcon("Imagenes/left.gif"),
p1,"Aparecen tres botones");
JPanel p2=new JPanel();
JTextField campo=
new JTextField("Campo de texto",20);
campo.setToolTipText("Escribe lo que quieras
en este campo de texto");
p2.add(campo);
panel.addTab(CAMPO,
133
new ImageIcon("Imagenes/right.gif"),
p2,"Aparece un campo de texto");
contenedor.add(panel,BorderLayout.CENTER);
}
}
Metodo de la clase JComponent:
void setToolTipText(String text)
Criterios de Colocaci
on
Todo contenedor posee un criterio de colocacion por defecto. Los cinco mas usados son: BorderLayout,
BoxLayout, FlowLayout, GridBagLayout y GridLayout.
BorderLayout: es la disposicion por defecto de todo panel de contenido, (el contenedor principal
de los marcos, applets y ventanas de dialogo). Se dispone de cinco areas: norte, sur, este, oeste y
centro. El espacio extra ocupa el centro del area.
BoxLayout: coloca los componentes en una sola fila o columna. Respeta las medidas maximas
requeridas de los componentes y permite alinearlos.
FlowLayout: es la disposicion por defecto de los jpaneles. Coloca los componentes uno detras
de otro, de izquierda a derecha.
GridLayout: agrupa los componentes (todos de igual dimension) en filas y columnas.
GridBagLayout: agrupa los componentes en una red de celdas, permitiendo que tengan diferentes dimensiones.
Si queremos modificar la disposicion por defecto de un contenedor, debemos llamar a su metodo
setLayout. Por ejemplo, si queremos modificar la disposicion por defecto de un panel:
JPanel panel=new JPanel();
panel.setLayout(new BorderLayout());
Podemos optar por prescindir de los criterios. En ese caso debemos especificar las dimensiones y
la posicion de cada componente dentro del contenedor. Pero puede haber problemas al reajustar el
contenedor.
BorderLayout
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class JBotonesbl extends JApplet{
JButton b1, b2, b3, b4, b5;
134
public void init(){
Container contenedor=getContentPane();
b1=new JButton("Norte");
contenedor.add(b1,BorderLayout.NORTH);
b2=new JButton("Sur");
contenedor.add(b2,BorderLayout.SOUTH);
b3=new JButton("Este");
contenedor.add(b3,BorderLayout.EAST);
b4=new JButton("Oeste");
contenedor.add(b4,BorderLayout.WEST);
b5=new JButton("Centro");
contenedor.add(b5,BorderLayout.CENTER);
}
}
BoxLayout
Se agrupan los componentes uno sobre otro, comenzando en la parte superior de la ventana, o en
fila, de izquierda a derecha.
A diferencia del resto de disposiciones de Awt, la BoxLayout respeta el tama
no maximo y la alineacion de cada componente.
Constructor:
public BoxLayout(Container,int)
Metodos:
Component createRigidArea(Dimension)
Component createHorizontalGlue()
Component createVerticalGlue
Ejemplo:
import java.awt.*; import javax.swing.*;
public class JBotonesboxl extends JApplet{
JButton b1, b2, b3, b4;
public void init(){
Container contenedor=getContentPane();
contenedor.setLayout(
new BoxLayout(contenedor,BoxLayout.Y_AXIS));
b1=new JButton("Boton1");
//setAlignment de JComponent
b1.setAlignmentX(Component.CENTER_ALIGNMENT);
contenedor.add(b1);
b2=new JButton("2");
b2.setAlignmentX(Component.CENTER_ALIGNMENT);
contenedor.add(b2);
135
b3=new JButton("El boton mas grande");
b3.setAlignmentX(Component.CENTER_ALIGNMENT);
contenedor.add(b3);
b4=new JButton("4");
b4.setAlignmentX(Component.CENTER_ALIGNMENT);
contenedor.add(b4);
}}
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class JBotonesboxl2 extends JApplet{
JButton b1, b2;
JPanel p1,p2;
JScrollPane sp;
JLabel etiqueta;
JList lista;
public void init(){
String[] paises={"Francia","Alemania",
"Irlanda","Espa~
na",
"Reino Unido","Francia","Portugal",
"Suecia","Austria",
"B
elgica","Luxemburgo","Holanda"};
Container contenedor=getContentPane();
p1=new JPanel();
p1.setLayout(new BoxLayout(p1,BoxLayout.Y_AXIS));
etiqueta=new JLabel("Paises de Europa:");
lista=new JList(paises);
sp=new JScrollPane(lista);
//Quedan alineados scroller y etiqueta
sp.setAlignmentX(LEFT_ALIGNMENT);
p1.add(etiqueta);
p1.add(Box.createRigidArea(new Dimension(0,5)));
p1.add(sp);
p1.setBorder(BorderFactory.
createEmptyBorder(10,10,10,10));
p2=new JPanel();
p2.setLayout(new BoxLayout(p2,BoxLayout.X_AXIS));
p2.setBorder(
BorderFactory.createEmptyBorder(0,10,10,10));
p2.add(Box.createHorizontalGlue());
b1=new JButton("Cancel");
p2.add(b1);
136
p2.add(Box.createRigidArea(new Dimension(10,0)));
b2=new JButton("OK");
p2.add(b2);
contenedor.add(p1,BorderLayout.CENTER);
contenedor.add(p2,BorderLayout.SOUTH);
pegamento: para especificar que exceso de espacio debera desaparecer. Por ejemplo, para que en
una disposicion en horizontal el espacio extra dejado por dos componentes no quede a la derecha
si no en el centro:
contenedor.add(primeraComponente);
contenedor.add(Box.createHorizontalGlue());
contenedor.add(segundaComponente);
Problemas de alineaci
on
137
Un grupo de componentes con igual alineacion, pero es necesario modificarla.
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class Botones extends JApplet{
JButton b1, b2;
Icon imagen;
public void init(){
Container contenedor=getContentPane();
contenedor.setLayout(
new BoxLayout(contenedor,BoxLayout.X_AXIS));
b1=new JButton("OK");
contenedor.add(b1);
b2=
new JButton("Cancel",
new ImageIcon("figura.gif"));
contenedor.add(b2);
}
}
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class Botones extends JApplet
{
JButton b1, b2;
Icon imagen;
public void init(){
Container contenedor=getContentPane();
contenedor.setLayout(
new BoxLayout(contenedor,BoxLayout.X_AXIS));
b1=new JButton("OK");
b1.setAlignmentY(Component.BOTTOM_ALIGNMENT);
contenedor.add(b1);
b2=
new JButton("Cancel",
new ImageIcon("figura.gif"));
138
b2.setAlignmentY(Component.BOTTOM_ALIGNMENT);
contenedor.add(b2);
}
}
Dos o mas componentes dispuestas en BoxLayout tienen diferentes alineaciones por defecto. En
el siguiente ejemplo, el borde izquierdo de la etiqueta esta, por defecto, alineado con el centro del
panel.
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class PanelEtiqueta extends JApplet
{
JPanel p;
JLabel etiqueta;
public void init(){
Container contenedor=getContentPane();
contenedor.setLayout(
new BoxLayout(contenedor,BoxLayout.Y_AXIS));
etiqueta=new JLabel("Esto es una prueba");
contenedor.add(etiqueta);
p=new JPanel();
p.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(Color.red),
p.getBorder()));
contenedor.add(p);
}
}
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class PanelEtiqueta extends JApplet
{
JPanel p;
JLabel etiqueta;
public void init(){
Container contenedor=getContentPane();
139
contenedor.setLayout(
new BoxLayout(contenedor,BoxLayout.Y_AXIS));
etiqueta=new JLabel("Esto es una prueba");
contenedor.add(etiqueta);
p=new JPanel();
p.setBorder(BorderFactory.
createCompoundBorder(
BorderFactory.createLineBorder(Color.red),
p.getBorder()));
p.setAlignmentX(LEFT_ALIGNMENT);
contenedor.add(p);
}
}
Por defecto, la mayora de las componentes poseen alineacion en el centro para X e Y. Sin embargo, los
botones, combo boxes, etiquetas y opciones de men
u poseen para X la alineacion izquierda.
Especificar el tama
no de las componentes
En ocasiones, modificar la alineacion no resuelve nuestros problemas. Por ejemplo, si el contenedor
con disposicion Box Layout ocupa demasiado espacio, una o mas componentes posiblemente necesitan
restringir su tama
no maximo.
Para detectar problemas de este tipo es aconsejable:
agregar un borde a las componentes en cuestion. Esto permite apreciar que tama
no realmente
tienen:
componente.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(Color.red),
componente.getBorder()));
140
CardLayout
Permite manejar dos o mas componentes, (normalmente objetos de la clase JPanel) que comparten un
mismo espacio. Una opcion es usar un panel con solapas.
Ejemplo 1
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class EjemploCardL extends JApplet
implements ItemListener{
JPanel p;
final static String BOTONES="Panel con botones";
final static String CAMPO=
"Panel con campo de texto";
public void init(){
Container contenedor=getContentPane();
String opciones[]={BOTONES,CAMPO};
JPanel pc=new JPanel();
JComboBox cb=new JComboBox(opciones);
cb.setEditable(false);
cb.addItemListener(this);
pc.add(cb);
contenedor.add(pc,BorderLayout.NORTH);
p=new JPanel();
p.setLayout(new CardLayout());
JPanel p1=new JPanel();
p1.add(new JButton("Boton 1"));
p1.add(new JButton("Boton 2"));
p1.add(new JButton("Boton 3"));
JPanel p2=new JPanel();
p2.add(new JTextField("Campo de texto",20));
p.add(p1,BOTONES);
p.add(p2,CAMPO);
contenedor.add(p,BorderLayout.CENTER);
}
public void itemStateChanged(ItemEvent e){
CardLayout cl=(CardLayout)(p.getLayout());
cl.show(p,(String)e.getItem());
141
}
}
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class EjemploSolapas extends JApplet{
final static String BOTONES="Panel con botones";
final static String CAMPO=
"Panel con campo de texto";
public void init(){
Container contenedor=getContentPane();
JTabbedPane panel=new JTabbedPane();
JPanel p1=new JPanel();
p1.add(new JButton("Boton 1"));
p1.add(new JButton("Boton 2"));
p1.add(new JButton("Boton 3"));
panel.addTab(BOTONES,p1);
JPanel p2=new JPanel();
p2.add(new JTextField("Campo de texto",20));
panel.addTab(CAMPO,p2);
contenedor.add(panel,BorderLayout.CENTER);
}
}
FlowLayout
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class EjemploFL extends JApplet{
public void init(){
Container contenedor=getContentPane();
contenedor.setLayout(new FlowLayout());
contenedor.add(new JButton("Boton 1"));
contenedor.add(new JButton("2"));
contenedor.add(new JButton("El mas grande"));
142
}
}
GridLayout
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class EjemploGL extends JApplet{
public void init(){
Container contenedor=getContentPane();
contenedor.setLayout(new GridLayout(0,2));
contenedor.add(new
contenedor.add(new
contenedor.add(new
contenedor.add(new
contenedor.add(new
JButton("Boton 1"));
JButton("2"));
JButton("El mas grande"));
JButton("4"));
JButton("Boton 5"));
}
}
GridBagLayout
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class EjemploGBL extends JApplet{
public void init(){
Container contenedor=getContentPane();
GridBagLayout gridbag=new GridBagLayout();
GridBagConstraints c=new GridBagConstraints();
contenedor.setLayout(gridbag);
//c.fill=GridBagConstraints.BOTH;
//c.weightx=1.0;
colocaBoton("Boton 1",gridbag,c,contenedor);
colocaBoton("Boton 2",gridbag,c,contenedor);
//c.gridx=0;
colocaBoton("Boton 3",gridbag,c,contenedor);
//c.gridx=GridBagConstraints.RELATIVE;
143
c.gridwidth=GridBagConstraints.REMAINDER;
colocaBoton("Boton 4",gridbag,c,contenedor);
//c.weightx=0.0;
colocaBoton("Boton 5",gridbag,c,contenedor);
c.gridwidth=GridBagConstraints.RELATIVE;
colocaBoton("Boton 6",gridbag,c,contenedor);
c.gridwidth=GridBagConstraints.REMAINDER;
colocaBoton("Boton 7",gridbag,c,contenedor);
c.gridwidth=1;
c.gridheight=2;
//c.weighty=1.0;
colocaBoton("Boton 8",gridbag,c,contenedor);
//c.weighty=0.0;
c.gridwidth=GridBagConstraints.REMAINDER;
c.gridheight=1;
colocaBoton("Boton 9",gridbag,c,contenedor);
colocaBoton("Boton 10",gridbag,c,contenedor);
}
public void colocaBoton(String nombre,
GridBagLayout gridbag,GridBagConstraints c,
Container
contenedor){
JButton boton=new JButton(nombre);
gridbag.setConstraints(boton,c);
contenedor.add(boton);
}
}
Acciones
Si dos o mas componentes realizan la misma accion, es conveniente usar un objeto de la interfase Action
del paquete
javax.swing, que extiende ActionListener. Esta interfase centraliza el manejo de texto, iconos y
botones de barras de herramientas y men
us.
El primer ejemplo muestra la forma tradicional de implementar una interfaz formada por un area
de texto, una barra de men
us y una barra de botones. La accion de seleccionar una opcion del primer
men
u o pulsar un boton de la barra se ve reflejada en el area de texto. Seleciconar una opcion del
segundo men
u activa o desactiva un boton o una opcion del primer men
u.
El segundo ejemplo utiliza la interfase Action para centralizar la gestion de la accion pulsar o
seleccionar opcion o boton.
Ejemplo:
import javax.swing.*;
144
import java.awt.*;
import java.awt.event.*;
public class EjemploAccionPre extends JApplet{
protected JTextArea areaTexto;
protected JMenuItem m11,m12,m13;
protected JButton b1,b2,b3;
public void init(){
Container contenedor=getContentPane();
JToolBar barra=new JToolBar();
b1=new JButton(new ImageIcon("izquierda.gif"));
b2=new JButton(new ImageIcon("centro.gif"));
b3=new JButton(new ImageIcon("derecha.gif"));
b1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
areaTexto.append(
"AccionEvent en: "
+ "primer boton"
+ "\n"
+ " Event source: " + e.getSource()
+ "\n");
}
});
b2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
areaTexto.append(
"AccionEvent en: "
+ "segundo boton"
+ "\n"
+ " Event source: " + e.getSource()
+ "\n");
}
});
b3.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
areaTexto.append(
"AccionEvent en: "
+ "tercer boton"
+ "\n"
+ " Event source: " + e.getSource()
+ "\n");
}
});
barra.add(b1);
barra.add(b2);
barra.add(b3);
145
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{
148
+
+
+
+
"segundo boton/item"
"\n"
" Event source: " + e.getSource()
"\n");
}
};
boton=barra.add(accCentr);
boton.setText("");
m=menuPrincipal.add(accCentr);
m.setIcon(null);
accDcha=new AbstractAction("Ir a la derecha",
new ImageIcon("derecha.gif"))
{
public void actionPerformed(ActionEvent e)
{
areaTexto.append(
"AccionEvent en: "
+ "tercer boton/item"
+ "\n"
+ " Event source: " + e.getSource()
+ "\n");
}
};
boton=barra.add(accDcha);
boton.setText("");
m=menuPrincipal.add(accDcha);
m.setIcon(null);
areaTexto=new JTextArea(5,30);
JScrollPane panelDespl=new JScrollPane(areaTexto);
contenedor.add(barra,BorderLayout.SOUTH);
contenedor.add(panelDespl,BorderLayout.CENTER);
JMenuBar mb=new JMenuBar();
mb.add(menuPrincipal);
mb.add(crearMenu());
setJMenuBar(mb);
validate();
}
protected JMenu crearMenu()
{
JMenu estado=new JMenu("Estado");
JCheckBoxMenuItem mi;
149
mi=new JCheckBoxMenuItem("Primera accion");
mi.setSelected(true);
mi.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent e){
JCheckBoxMenuItem mii=
(JCheckBoxMenuItem)(e.getSource());
boolean seleccionado=(e.getStateChange()==
ItemEvent.SELECTED);
accIzqu.setEnabled(seleccionado);
}
});
estado.add(mi);
mi=new JCheckBoxMenuItem("Segunda accion");
mi.setSelected(true);
mi.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent e){
JCheckBoxMenuItem mii=
(JCheckBoxMenuItem)(e.getSource());
boolean seleccionado=(e.getStateChange()==
ItemEvent.SELECTED);
accCentr.setEnabled(seleccionado);
}
});
estado.add(mi);
mi=new JCheckBoxMenuItem("Tercera accion");
mi.setSelected(true);
mi.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent e){
JCheckBoxMenuItem mii=
(JCheckBoxMenuItem)(e.getSource());
boolean seleccionado=(e.getStateChange()==
ItemEvent.SELECTED);
accDcha.setEnabled(seleccionado);
}
});
estado.add(mi);
return estado;
}
}
Bordes
Cualquier objeto de la clase JComponent puede tener uno o mas bordes.
150
Se utiliza el metodo setBorder y la clase BorderFactory, que devuelve objetos de la interfase
Border del paquete
javax.swing.border.
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class Bordes1 extends JApplet{
JTextArea areaTexto;
JScrollPane pd;
JLabel titulo;
JPanel p1,p2;
public void init(){
Container contenedor=getContentPane();
p1=new JPanel();
titulo=new JLabel("Escribe lo que quieras:");
titulo.setBorder(
BorderFactory.createLineBorder(Color.red));
p1.add(titulo);
p2=new JPanel();
areaTexto=new JTextArea(5,30);
pd=new JScrollPane(areaTexto,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
p2.add(pd);
contenedor.add(p1,BorderLayout.NORTH);
contenedor.add(p2,BorderLayout.CENTER);
validate();
}}
Podemos implementar nuestros propios bordes. Deberemos crear una subclase de AbstractBorder
e jmplementar los metodos paintBorder y getBorderInsets.
Tambien es posible a
nadir un borde adicional alrededor de una componente ya enmarcada. Por
ejemplo, crear espacio extra alrededor de una componente.
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class Bordes2 extends JApplet{
JTextArea areaTexto;
JScrollPane pd;
JLabel titulo;
JPanel p1,p2;
public void init(){
Container contenedor=getContentPane();
p1=new JPanel();
151
titulo=new JLabel(
"
Escribe lo que quieras:
");
titulo.setBorder(
BorderFactory.createLineBorder(Color.red));
p1.add(titulo);
p2=new JPanel();
areaTexto=new JTextArea(5,30);
pd=new JScrollPane(areaTexto,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
pd.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(40,0,0,0),
pd.getBorder()));
p2.add(pd);
contenedor.add(p1,BorderLayout.NORTH);
contenedor.add(p2,BorderLayout.CENTER);
validate();}}
Metodos:
Border createLineBorder(Color color)
Border createLineBorder(Color color,
int thickness)
Border createEtchedBorder()
Border createEtchedBorder(Color highlight,
Color shadow)
Border createLoweredBevelBorder()
Border createRaisedBevelBorder()
Border createEmptyBorder()
Border createEmptyBorder(int top,int left,
int bottom,int right)
MatteBorder createMatteBorder(int top,int left,
int bottom,int right,Color color)
MatteBorder createMatteBorder(int top,int left,
int bottom,int right,Icon titleIcon)
TitledBorder createTitledBorder(String title)
TitledBorder createTitledBorder(Border border)
TitledBorder createTitledBorder(Border border,
String title)
TitledBorder createTitledBorder(Border border,
String title,int titleJustification,
int titlePosition)
152
TitledBorder createTitledBorder(Border border,
String title,
int titleJustification,int titlePosition,Font titleFont)
TitledBorder createTitledBorder(Border border,
String title,
int titleJustification,int titlePosition,Font titleFont,Color titleColor)
CompoundBorder createCompoundBorder(Border
outsideBorder,Border insiderBorder)
Elecci
on del Aspecto
Se puede elegir el aspecto que queremos que tenga nuestra interfaz. Para ello, usaremos el metodo
UIManager.setLookAndFeel.
Ejemplo:
import java.awt.*;
import javax.swing.*;
public class JBotonAspJava extends JApplet{
public void init(){
try
{
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
}catch(Exception e){}
Container contenido=getContentPane();
contenido.setLayout(new FlowLayout());
contenido.add(new JButton("Boton 1"));
contenido.add(new JButton("2"));
contenido.add(new JButton("El mas grande"));
}
}
Los argumentos de setLookAndFeel pueden ser:
UIManager.getCrossPlatformLookAndFeelClassName(): el aspecto Java.
UIManager.getSystemLookAndFeelClassName(): el aspecto del entorno de trabajo.
javax.swing.plaf.metal.MetalLookAndFeel: el aspecto Java.
com.sun.java.swing.plaf.windows.WindowsLookAndFeel: el aspecto Windows.
javax.swing.plaf.mac.MacLookAndFeel: el aspecto Mac.
Es posible modificar el aspecto de la interfaz una vez que se ha hecho visible.
Es necesario el metodo
SwingUtilities.updateComponentTreeUI.
Ejemplo:
153
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class BotonAsp extends JApplet
implements ActionListener{
JButton b;
public void init(){
Container contenido=getContentPane();
contenido.setLayout(new FlowLayout());
b=new JButton("Pulsar");
contenido.add(b);
b.addActionListener(this);
}
public void actionPerformed(ActionEvent e){
b.setText("OK");
try
{
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
}catch(Exception exc){}
SwingUtilities.updateComponentTreeUI(b);
}
}
154
Interfase
M
etodos
Par
ametro
ActionListener
actionPerformed
CaretListener
caretUpdate
ChangeListener
stateChanged
ActionEvent
getActionCommand
getModifiers
CaretEvent
getDot
getMark
ChangeEvent
ComponentListener
componentMoved
componentHidden
componentResized
componentAdded
componentRemoved
ContainerListener
DocumentListener
changedUpdate
insertUpdate
removeUpdate
InternalFrameListener
internalFrameOpened
internalFrameClosing
internalFrameClosed
internalFrameIconified
internalFrameDeiconified
internalFrameActivated
internalFrameDeactivated
itemStateChanged
ItemListener
ListDataListener
ListSelectionListener
FocusListener
KeyListener
intervalAdded
intervalRemoved
contentsChanged
valueChanged
focusGained
focusLost
keyPressed
keyReleased
keyTyped
MouseListener
mousePressed
mouseReleased
mouseEntered
mouseExited
mouseClicked
MouseMotionListener
mouseDragged
mouseMoved
windowClosing
windowOpened
windowIconified
windowDeiconified
windowClosed
windowActivated
WindowListener
ComponentEvent
getComponent
Sucesos
generados por
JButton
JMenuItem
JTextField
JTextComponent
JSlider
JColorChooser
JComponent
ContainerEvent
getChild
getContainer
DocumentEvent
getDocument
getLength
getOffset
getChange
getType
InternalFrameEvent
Container
ItemEvent
getItem
getItemSelectable
getStateChange
ListDataEvent
getIndex0
getIndex1
ListSelectionEvent
getFirstIndex
getLastIndex
getValueIsAdjusting
FocusEvent
IsTemporary
KeyEvent
getKeyChar
getKeyCode
getKeyModifiersText
getKeyText
IsActionKey
MouseEvent
getClickCount
getX
getY
getPoint
TranslatePoint
IsPopupTrigger
JCheckBox
JCheckBoxMenuItem
JComboBox
JTextComponent (documento)
JInternalFrame
JList (contenidos)
JList
JTable
JComponent
JComponent
JComponent
JComponent
WindowEvent
getWindow
JFrame
JDialog
GRAFICOS
EN JAVA
156
Gr
aficos en Java
Dentro del paquete java.awt se encuentra definida la clase Graphics, que incorpora al lenguaje
Java la posibilidad de a
nadir elementos graficos.
Principios basicos
Al iniciar la ejecucion del programa, el sistema se encarga de visualizar graficamente todas las
componentes de su interfase.
Existen motivos que exigen una regeneracion de esa interfase.
La regeneracion se produce seg
un un orden jerarquico, comenzando con la componente de jerarqua
mas alta que necesita ser regenerada.
El AWT es el encargado de toda la gestion del proceso.
Una llamada al metodo repaint() de una componente obliga a su regeneracion.
La manera mas simple de dibujar una componente es insertar el codigo de dibujo en su metodo
paint().
El metodo paint() recibe como u
nico argumento un objeto de tipo Graphics (contexto grafico).
Estos objetos soportan dos tipos de procesos de dibujo:
Primitivas graficas (lneas, rectangulos, texto, etc.)
Imagenes
Cada componente tiene su propio sistema de coordenadas referidas a la esquina superior izquierda
de su area de dibujo.
Para las operaciones graficas sobre una componente se tiene en cuenta su sistema de coordenadas.
Primitivas Gr
aficas
La clase Graphics es una clase abstracta que dispone de metodos para dibujar lneas, rectangulos,
rectangulos redondeados, ovalos, arcos, polgonos, texto...
Lneas
public abstract void
drawLine (int x1, int y1, int x2, int y2)
Dibuja una lnea desde el punto de coordenadas (x1,y1) al punto de coordenadas (x2,y2).
Rect
angulos
public abstract void
drawRect (int x, int y, int ancho, int alto)
157
Dibuja un rectangulo cuya esquina superior izquierda esta en el punto de coordenadas (x,y)
con las dimensiones en puntos especificadas.
public abstract void
drawRoundRect (int x, int y, int ancho,
int alto, int dh, int dv)
Dibuja un rectangulo de esquinas redondeadas, siendo dh y dv los diametros horizontal y
vertical respectivamente de los arcos de las cuatro esquinas.
Ejemplo:
import java.awt.*;
import java.applet.*;
public class dibujarGraficos extends Applet{
public void paint(Graphics g){
g.drawLine(0,0,160,80);
g.drawRect(0,0,50,50);
g.drawRoundRect(20,20,40,40,15,15);
g.drawRoundRect(60,60,80,80,80,80);
}
}
public void
draw3DRect (int x, int y, int ancho,
int alto, boolean elev)
Dibuja un rectangulo con el efecto de estar elevado o hundido, si el valor del parametro elev
es true o false respectivamente.
public abstract void
fillRect (int x, int y, int ancho, int alto)
Dibuja un rectangulo relleno del color vigente.
public abstract void
fillRoundRect (int x, int y, int ancho,
int alto, int dh, int dv)
Dibuja un rectangulo de esquinas redondeadas con relleno.
public void
fill3DRect (int x, int y, int ancho,
int alto, boolean elev)
Dibuja un rectangulo elevado o hundido y con relleno.
158
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
polyg1_x[]={40,80,0,40};
polyg1_y[]={5,45,45,5};
polyg2_x[]={140,180,180,140,100,100,140};
polyg2_y[]={5,25,45,65,45,25,5};
polyg3_x[]={240,260,220,260,220,240};
polyg3_y[]={5,65,85,25,25,5};
160
Otros M
etodos de la Clase Graphics
public abstract void
clipRect (int x, int y, int ancho, int alto)
161
Todas las operaciones graficas que se realicen sobre un contexto grafico u
nicamente tienen
efecto si quedan dentro de una cierta region rectangular. Este metodo permite establecer
esta region.
public abstract Rectangle getClipBounds()
Devuelve la region de dibujo del contexto grafico.
public abstract void
copyArea (int x, int y, int ancho,
int alto, int dx, int dy)
Efect
ua una copia del area rectangular. El vector de desplazamiento del area es (dx,dy).
public abstract Graphics create ()
Devuelve una copia del contexto grafico.
public Graphics create (int x, int y,
int ancho, int alto)
Crea un nuevo contexto grafico identico al actual salvo en los siguientes aspectos: el origen
del nuevo contexto grafico pasa a ser el punto (x,y) del actual y se establece una region de
dibujo adicional a partir del origen con las dimensiones dadas.
public abstract void dispose ()
Libera la memoria reservada por el contexto grafico.
public void finalize ()
Efect
ua la llamada al metodo dispose() cuando el contexto grafico no vuelve a ser utilizado.
public abstract Color getColor ()
Devuelve un objeto de la clase Color con el color vigente en el contexto grafico.
public abstract void setColor (Color c)
Establece un color para el contexto grafico.
public abstract void setPaintMode ()
Establece el modo de pintura para el contexto grafico.
public abstract void setXORMode (Color c)
A partir de ese momento, cuando se realice una operacion grafica, los puntos que se encuentren en el color actual del contexto cambiaran al color c y viceversa.
162
Ejemplo de Utilizaci
on de
Primitivas Gr
aficas
import java.awt.*;
import java.applet.Applet;
public class Estadio extends Applet {
public void init() {
validate();
}
public void paint(Graphics g) {
int ancho, alto;
Dimension d = getSize();
ancho=d.width-40;
alto=d.height-40;
163
g.fillRect(20,0,ancho,5);
g.drawString("ESTADIO JAVA",ancho/2-10,17);
g.translate(20,20);
g.drawRect(0, 0, ancho, alto);
g.drawLine(ancho/2, 0, ancho/2, alto);
g.fillOval(ancho/2-2, alto/2-2, 4, 4);
g.drawOval(ancho/2-alto/6, alto/3, alto/3,
alto/3);
g.drawRect(0, alto/4, ancho/6, alto/2);
g.drawRect(0, 2*alto/5, ancho/15, alto/5);
g.drawArc(ancho/6-alto/10,2*alto/5,alto/5,
alto/5,-90,180);
g.drawRect(ancho-ancho/6, alto/4,
ancho/6, alto/2);
g.drawRect(14*ancho/15, 2*alto/5,
ancho/15, alto/5);
g.drawArc(5*ancho/6-alto/10,2*alto/5,
alto/5, alto/5,90,180);
}
}
Uso de Im
agenes
Para el uso de imagenes Java dispone de varias clases repartidas por los paquetes java.applet,
java.awt y
java.awt.image.
Las imagenes deben encontrarse en ficheros con formato GIF o JPEG.
Las imagenes deben ser cargadas con los metodos definidos para ello en las clases Applet o
Toolkit.
Una vez cargada, toda imagen es representada mediante un objeto de la clase Image.
Para que la imagen sea visualizada es preciso dar la orden correspondiente.
164
165
Imagen escalada pero sin modificar los puntos transparentes.
Observaciones:
El metodo drawImage() devuelve una variable boolean que indica si el proceso de dibujo ha sido
realizado correctamente.
El objeto que act
ua de observador debe pertenecer a una clase que implemente la interfase
ImageObserver. La clase Component implementa dicha interfase, es por eso que normalmente
se utiliza la propia componente (this) como observador de la imagen.
Cuando a una imagen se le asocia un observador, cualquier informacion disponible sobre la imagen
provoca la llamada al metodo imageUpdate() del observador.
Ejemplo:
import java.awt.*;
import java.applet.Applet;
public class Figura extends Applet
{
Image fondo, fig;
public void init () {
fondo = getImage(getDocumentBase(),
"Fondo.gif");
fig = getImage(getDocumentBase(),"Logo.gif");
}
public void paint( Graphics g ) {
int ancho, alto;
Dimension d = getSize();
ancho = fig.getWidth(this);
alto = fig.getHeight(this);
g.drawImage(fondo, 0, 0, d.width, d.height,
this);
g.drawImage(fig,(d.width-ancho)/2,
(d.height-alto-20)/2,this);
}
}
la figura del fondo se adapta a las dimensiones de la ventana
Im
agenes Off-screen
Para crear imagenes la clase Component tiene definido el metodo createImage():
public Image createImage(ImageProducer prod)
public Image createImage(int ancho, int alto)
Los pasos a seguir para crear y visualizar imagenes off-screen son los siguientes:
166
1. Utilizar el metodo createImage() para crear un objeto de tipo Image.
2. Obtener su contexto grafico asociado con el metodo
getGraphics().
3. Efectuar todas las operaciones sobre ese contexto.
4. Visualizar la imagen con el metodo drawImage().
Ejemplo:
import java.awt.*;
import java.applet.Applet;
public class Imagen extends Applet
{
int x[] = new int[5];
int y[] = new int[5];
public void init () {
x[0]=20;
y[0]=20;
x[2]=180; y[2]=180;
x[4]=20;
y[4]=20;
}
x[1]=180;
x[3]=20;
y[1]=20;
y[3]=180;
M
etodos de la Clase Image
167
Manipulando Im
agenes
Uso de Filtros
Toda imagen lleva asociados dos objetos importantes:
Productor: Crea todos los datos que el sistema necesita para visualizar la imagen y se los pasa al
consumidor. Debe ser un objeto que implemente la interfase ImageProducer.
Consumidor: Produce la visualizacion. Debe ser un objeto que implemente la interfase ImageConsumer.
Un filtro es un objeto de la clase ImageFilter que intercepta y modifica los datos que el productor
enva al consumidor.
Manipulacion de imagenes. Pasos a seguir:
1. Crear el objeto Image con el metodo getImage().
2. Obtener el productor de la imagen con el metodo
getSource() de la clase Image.
168
3. Crear un ejemplar del filtro.
4. Crear un objeto de la clase FilteredImageSource, pasando como argumentos al constructor el
productor de la imagen y el filtro.
5. Crear un nuevo objeto de la clase Image con el metodo createImage(), dando como productor
para la imagen manipulada el objeto FilteredImageSource anterior.
Ejemplo:
import java.awt.*;
import java.awt.image.*;
import java.applet.Applet;
public class Filtros extends Applet
{
Image
img1, img2;
ImageProducer
productor1, productor2;
ImageFilter
filtro;
public void init () {
img1 = getImage(getDocumentBase(),"Logo1.gif");
productor1 = img1.getSource();
filtro = new RotateFilter(Math.PI);
productor2 =
new FilteredImageSource(productor1, filtro);
img2 = createImage(productor2);
}
public void paint( Graphics g ) {
g.drawImage(img1, 10, 20, this);
g.drawImage(img2, 200, 20, this);
}
}
Va Internet pueden obtenerse filtros para manipular imagenes (por ejemplo el filtro RotateFilter).
En los paquete java.awt.image se incluyen los filtros:
CropImageFilter: se utiliza para obtener una nueva imagen formada por una parte rectangular de la imagen inicial. Para utilizar este filtro no es necesario crear una subclase de la
CropImageFilter, se puede utilizar su constructor:
CropImageFilter(int x,int y,int width,int height) Construye un objeto CropImageFilter
que extrae la region rectangular indicada en pixels, de la imagen dada.
RGBImageFilter: sirve para modificar el color o la transparencia de todos los puntos de la
imagen. Para utilizar este filtro se crea una subclase de la clase RGBImageFilter y se redefine
el metodo
169
public int filterRGB(int x, int y, int argb) Este metodo debe ser implementado por toda
subclase de la clase RGBImageFilter. En este metodo se convierte cada pixel de entrada
(modelo de color RGB), en un pixel de salida.
El programador puede crear sus propios filtros creando subclases de la clase ImageFilter definida
dentro del paquete java.awt.image.
Ejemplo:
import
import
import
import
java.awt.*;
java.awt.image.ImageFilter.*;
java.awt.image.*;
java.applet.Applet;
170
public void init () {
img1 = getImage(getDocumentBase(),"Logo3.gif");
productor1 = img1.getSource();
filtro = new MiFiltro();
productor2 =
new FilteredImageSource(productor1,filtro);
img2 = createImage(productor2);
}
public void paint( Graphics g ) {
g.drawImage(img1, 10, 20, this);
g.drawImage(img2, 250, 20, this);
}
}
class MiFiltro extends RGBImageFilter{
public MiFiltro(){
super();
}
public int filterRGB(int x,int y, int rgb){
int rojo,verde,azul;
Color c1=new Color(rgb);
rojo=255-c1.getRed();
verde=255-c1.getGreen();
azul=255-c1.getBlue();
Color c2=new Color(rojo,azul,verde);
return(c2.getRGB());
}
}
Algunos metodos de la clase ImageFilter
void setDimensions (int ancho, int alto)
Mediante este metodo el productor comunica al consumidor las dimensiones de la imagen.
Si el filtro desea cambiarlas, debe hacerlo dentro de este metodo.
void setColorModel (ColorModel model)
El productor comunica al consumidor la forma de colorear o el modelo de coloreado de los
puntos.
void setHints (int hintflags)
Indica el orden en el que se tratan los diferentes puntos de la imagen.
void setPixels (int x, int y, int ancho,
int alto, ColorModel m, byte puntos[],
int off, int scansize)
171
32 bits
TT
32
RR
24
AA
VV
16
0xTTRRVVAA
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));
}
173
public PixelGrabberEjem()
{
MenuBar mbar = new MenuBar();
Menu m = new Menu("Archivo");
MenuItem m1 = new MenuItem("Abrir");
m1.addActionListener(this);
m.add(m1);
MenuItem m2 = new MenuItem("Salir");
m2.addActionListener(this);
m.add(m2);
mbar.add(m);
setMenuBar(mbar);
}
public void actionPerformed(ActionEvent evt)
{ String arg = evt.getActionCommand();
if (arg.equals("Abrir"))
{ FileDialog d = new FileDialog(this, "Abrir fichero",
FileDialog.LOAD);
d.show();
String f = d.getFile();
if (f != null)
{ ficheroNombre =f;
imagenTranspuesta(ficheroNombre);
}
}
else if(arg.equals("Salir")) System.exit(0);
}
public void imagenTranspuesta(String f)
{
Image imagen = Toolkit.getDefaultToolkit().getImage(f);
PixelGrabber gr = new PixelGrabber(imagen, 0, 0, -1, -1,
true);
try
{ if (gr.grabPixels())
{ ancho = gr.getWidth();
alto = gr.getHeight();
int[] pixels = (int[])gr.getPixels();
int[] transPixels = new int[alto * ancho];
for (int x = 0; x < ancho; x++)
for (int y = 0; y < alto; y++)
transPixels[x * alto + y] = pixels[y * ancho + x];
imagenTranspuesta = createImage(new
MemoryImageSource(alto,ancho, transPixels, 0, alto));
repaint();
}
}
catch(InterruptedException e) {}
174
}
Utilizaci
on de colores
El tratamiento del color en los procesos graficos se realiza por medio de la clase Color definida en
el paquete java.awt.
Todo color se identifica mediante su formato RGB que consta de tres valores enteros en el rango
comprendido entre 0 y 255, cada valor representa la contribucion de cada uno de los tres colores
primarios (rojo, verde y azul).
Constantes que definen colores habituales
constante
color
black
negro
blue
azul
cyan
ciano
darkGray
gris oscuro
gray
gris
green
verde
lightGray gris claro
constante color
magenta magenta
orange
naranja
pink
rosa
red
rojo
white
blanco
yellow
amarillo
175
Devuelve una version mas oscura del color.
public boolean equals (Object obj)
Devuelve true si obj es un objeto de la clase Color y tiene los mismos valores RGB que el
color sobre el que se hace la llamada al metodo.
public int getRed ()
Devuelve la componente roja del color, en el rango comprendido entre 0 y 255.
public int getGreen ()
Devuelve la componente verde del color.
public int getBlue ()
Devuelve la componente azul del color.
public static Color
getHSBColor (float mat, float sat, float br)
Crea un color a partir de su matiz, saturacion y brillo (formato HSB). Cada una de las tres
componentes debe ser un n
umero de tipo float entre 0.0 y 1.0.
public int getRGB ()
Devuelve un entero con la representacion RGB del color.
public static int HSBtoRGB (float mat,
float sat, float br)
Devuelve el valor RGB correspondiente a un color dado en formato HSB.
public static float[]
RGBtoHSB (int rojo, int verde, int azul,
float hsbvals[])
Convierte un color en formato RGB al formato HSB. Los valores del matiz, saturacion y
brillo son colocados en la matriz hsbvals.
El color actual para un contexto grafico se indica mediante el metodo setColor() de la clase
Graphics.
Ejemplo:
176
import java.awt.*;
import java.applet.Applet;
import java.util.Random;
class GeneradorAleatorio extends Random {
public GeneradorAleatorio () {
super();
}
int ValorAleatorio (int max) {
Float aux = new Float(max*nextFloat());
return(aux.intValue());
}
void ColorAleatorio (Graphics g) {
int rojo, verde, azul;
rojo=ValorAleatorio(255);
verde=ValorAleatorio(255);
azul=ValorAleatorio(255);
g.setColor(new Color(rojo, verde, azul));
}
void FiguraAleatoria(Graphics g,boolean cuadrado){
int x, y, lado;
ColorAleatorio(g);
x=ValorAleatorio(200);
y=ValorAleatorio(200);
if (200-x<200-y)
lado=ValorAleatorio(200-x);
else
lado=ValorAleatorio(200-y);
if (cuadrado)
g.fillRect(x, y, lado, lado);
else
g.fillOval(x+200, y, lado, lado);
}
}
177
for(int i=1; i<500; i++) {
r.FiguraAleatoria(g,true);
r.FiguraAleatoria(g,false);
}
}
}
Tipos de Letra
La clase Font
La clase Font se utiliza para representar las diferentes fuentes de letra con sus diferentes estilos.
Variables miembro de la clase:
protected String name: nombre del tipo.
protected int size: tama
no del tipo.
protected int style: estilo del tipo, es la suma de las constantes PLAIN (texto normal), BOLD
(texto en negrita) o ITALIC (texto en italica) definidas de la manera siguiente:
public final static int PLAIN = 0
public final static int BOLD = 1
public final static int ITALIC = 2
Constructor de la clase:
public Font (String nom, int est, int tam)
Crea un nuevo tipo de letra con el nombre, estilo y tama
no indicados.
Para obtener una matriz con los nombres de los tipos de letra disponibles puede usarse el metodo
getFontList() de la clase Toolkit.
La utilizacion de diferentes tipos de letra en un contexto grafico es muy similar en su funcionamiento
a los colores. Cada contexto lleva asociado un tipo de letra que en todo momento puede cambiarse
mediante el metodo setFont() de la clase Graphics.
Ademas, la clase Font define los siguientes metodos:
public boolean equals (Object obj)
Devuelve true si el argumento es un objeto de la clase Font y su nombre, estilo y tama
no
coinciden con los correspondientes al Font sobre el que se hace la llamada al metodo.
public String getFamily ()
Devuelve una cadena con el nombre especfico de la familia a la que pertenece el tipo de
letra, en la plataforma sobre la que se trabaje.
178
179
import java.awt.*;
import java.applet.Applet;
public class Fuentes extends Applet
{
Font fuente1, fuente2, fuente3, fuente4;
public void
fuente1
fuente2
fuente3
fuente4
}
init() {
= new Font("Helvetica", 0, 18);
= new Font("Times", 1, 14);
= new Font("New York", 2, 12);
= new Font("Geneva", 3, 10);
Aspectos m
etricos del texto
La clase FontMetrics controla los aspectos metricos de un determinado tipo de letra. De hecho, la
u
nica variable miembro declarada en la clase, es la variable de la clase Font que lleva por nombre font.
El constructor de la clase es:
protected FontMetrics (Font f)
180
a
b
d
Programacin en
lenguaje Java
Lnea superior
Lnea de base
Lnea inferior
Lnea superior
Lnea de base
Lnea inferior
181
Devuelve la anchura de la submatriz de caracteres que comienza en el ndice inicio y tiene
la longitud indicada por el argumento longitud.
public int charsWidth (byte data[], int inicio,
int longitud)
Identico al metodo anterior.
public int charWidth (char c)
Devuelve la anchura del caracter que se indica en el argumento c.
public int stringWidth (String str)
Devuelve la anchura de la cadena de caracteres que se indica en el argumento str.
public int getMaxAdvance ()
Devuelve la anchura maxima de un caracter en la fuente de letra asociada. En caso de no
conocer esa anchura, devuelve -1.
public int[] getWidths (String str)
Devuelve una matriz con la anchura de los primeros 256 caracteres en el tipo asociado.
Por u
ltimo, la clase FontMetrics define ademas los metodos:
public int getMaxAscent ()
Determina la longitud maxima a la que un caracter puede llegar por encima de la lnea de
base en el correspondiente tipo de letra.
public int getMaxDescent ()
Determina la longitud maxima a la que un caracter puede descender por debajo de la lnea
de base en el correspondiente tipo de letra.
public String toString ()
Devuelve una representacion del objeto en forma de cadena de caracteres.
Ejemplo
import java.awt.*;
import java.applet.*;
public class dibujarTexto extends Applet{
Font f1=new Font("TimesRoman",Font.PLAIN,14);
String str="Esta es una prueba";
public void paint(Graphics g){
182
int longitud=getFontMetrics(f1).stringWidth(str);
g.drawString(str,5,30);
g.drawLine(5,
30+getFontMetrics(f1).getDescent(),5+longitud,
30+getFontMetrics(f1).getDescent());
g.drawLine(5,
30-getFontMetrics(f1).getAscent(),5+longitud,
30-getFontMetrics(f1).getAscent());
g.drawLine(5,30,5+longitud,30);
}
}
Pr
actica 1
import
import
import
import
java.applet.*;
java.awt.event.*;
java.util.*;
java.awt.*;
183
}
class Circulo{
static public final int r=20;
Color color=Color.red;
int x,y;
void draw(Graphics g){
g.setColor(color);
g.fillOval(x-r,y-r,2*r,2*r);
}
}
Pr
actica 2
import
import
import
import
java.applet.*;
java.awt.event.*;
java.util.*;
java.awt.*;
184
s.draw(g);
}
}
public void mouseClicked(MouseEvent e){
Circulo s;
s=new Circulo();
s.x=e.getX(); s.y=e.getY();
vectorFiguras.addElement(s);
repaint();
}
public void mouseReleased(MouseEvent e){
Circulo s=new Circulo();
s.x=e.getX();
s.y=e.getY();
if(e.getComponent()==c)
s.draw(gra1);
else
s.draw(gra2);
}
public void mouseExited(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mousePressed(MouseEvent e){}
}
class Circulo{
static public final int r=20;
Color color=Color.red;
int x,y;
void draw(Graphics g){
g.setColor(color);
g.fillOval(x-r,y-r,2*r,2*r);
}
}
Pr
actica 3
import java.awt.*; import java.applet.Applet; import
java.awt.event.*;
public class Sectores extends Applet implements ActionListener{
Label l1,l2,l3,l4;
TextField f1,f2,f3,f4;
Button dibujar;
185
public void init(){
setLayout(null);
l1=new Label("Sobresal. :");
l1.setBounds(10,10,75,20);
add(l1);
l2=new Label("Notables:");
l2.setBounds(10,40,75,20);
add(l2);
l3=new Label("Aprobados:");
l3.setBounds(10,70,75,20);
add(l3);
l4=new Label("Suspensos:");
l4.setBounds(10,100,75,20);
add(l4);
f1=new TextField("0");
f1.setBounds(90,10,40,20);
add(f1);
f2=new TextField("0");
f2.setBounds(90,40,40,20);
add(f2);
f3=new TextField("0");
f3.setBounds(90,70,40,20);
add(f3);
f4=new TextField("0");
f4.setBounds(90,100,40,20);
add(f4);
dibujar=new Button("Dibujar");
dibujar.setBounds(10,150,50,20);
dibujar.addActionListener(this);
add(dibujar);
repaint();
}
public void paint(Graphics g){
int n1,n2,n3,n4,total,anterior;
n1=(new Integer(f1.getText())).intValue();
n2=(new Integer(f2.getText())).intValue();
n3=(new Integer(f3.getText())).intValue();
n4=(new Integer(f4.getText())).intValue();
186
total=n1+n2+n3+n4;
g.drawOval(140,10,150,150);
if(total!=0){
g.setColor(Color.red);
g.fillArc(140,10,150,150,0,360*n1/total);
g.setColor(Color.green);
g.fillArc(140,10,150,150,360*n1/total,360*n2/total);
g.setColor(Color.yellow);
g.fillArc(140,10,150,150,360*(n1+n2)/total,360*n3/total);
g.setColor(Color.yellow);
g.setColor(Color.blue);
g.fillArc(140,10,150,150,360*(n1+n2+n3)/total,360*n4/total);
}
}
public void actionPerformed(ActionEvent ae){
Object componente=ae.getSource();
if(componente.equals(dibujar)){
repaint();}
}
}
Pr
actica 4
import
import
import
import
java.applet.*;
java.awt.event.*;
java.util.*;
java.awt.*;
187
}
public void paint(Graphics g){
Circulo s;
int numFiguras;
numFiguras=vectorFiguras.size();
for(int i=0;i<numFiguras;i++){
s=(Circulo)vectorFiguras.elementAt(i);
s.draw(g);
}
}
public void mouseClicked(MouseEvent e){
Circulo s;
s=new Circulo();
s.x=e.getX(); s.y=e.getY();
vectorFiguras.addElement(s);
repaint();
}
public void mouseReleased(MouseEvent e){
Circulo s=new Circulo();
s.x=e.getX();
s.y=e.getY();
if(e.getComponent()==c)
s.draw(gra1);
else
s.draw(gra2);
}
public void mouseExited(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mousePressed(MouseEvent e){}
} class Circulo{
static public final int r=20;
Color color=Color.red;
int x,y;
void draw(Graphics g){
g.setColor(color);
g.fillOval(x-r,y-r,2*r,2*r);
}
}
188
Gr
aficos 2-D
En la version 1.2 de Java se incluyen paquetes que permiten trabajar con graficos en 2-D, ademas
tambien aparecen paquetes que extienden las posibilidades de trabajo con texto como entidad grafica
y con imagenes.
En la Java 2D API, se pueden encontrar paquetes nuevos como:
java.awt.color
java.awt.font
java.awt.geom :En este paquete se encuentran clases como:
Arc2D, Arc2D.Double,Ellipse2D,Ellipse2D.Double ,
Line2D,Line2D.Double,Point2D,Point2D.Double,
Rectangle2D,Rectangle.Double, etc
java.awt.print
Ademas, en los paquetes java.awt y java.awt.image se han incluido nuevas clases que permiten
trabajar en 2D.
java.awt
java.awt.AlphaComposite
java.awt.BasicStroke
java.awt.Color
java.awt.Composite
java.awt.CompositeContext
java.awt.Font
java.awt.GradientPaint
java.awt.Graphics2D
java.awt.GraphicsConfiguration
java.awt.GraphicsDevice
java.awt.GraphicsEnvironment
java.awt.Paint
java.awt.PaintContext
java.awt.Rectangle
java.awt.Shape
java.awt.Stroke
java.awt.TexturePaint
java.awt.Toolkit
java.awt.Transparency
189
java.awt.image
java.awt.image.AffineTransformOp
java.awt.image.BandCombineOp
java.awt.image.BandedSampleModel
java.awt.image.BufferedImage
java.awt.image.BufferedImageFilter
java.awt.image.BufferedImageOp
java.awt.image.ByteLookupTable
java.awt.image.ColorConvertOp
java.awt.image.ColorModel
java.awt.image.ComponentColorModel
java.awt.image.ComponentSampleModel
java.awt.image.ConvolveOp
java.awt.image.DataBuffer
java.awt.image.DataBufferByte
java.awt.image.DataBufferInt
java.awt.image.DataBufferShort
java.awt.image.DirectColorModel
java.awt.image.IndexColorModel
java.awt.image.Kernel
java.awt.image.LookupOp
java.awt.image.LookupTable
java.awt.image.MultiPixelPackedSampleModel
java.awt.image.PackedColorModel
java.awt.image.Raster
java.awt.image.RasterformatException
java.awt.image.RasterOp
java.awt.image.RenderedImage
java.awt.image.RescaleOp
java.awt.image.SampleModel
java.awt.image.ShortLookupTable
java.awt.image.SinglePixelPackedSampleModel
java.awt.image.WritableRaster
A continuacion se presenta una coleccion de ejemplos donde se muestran algunas de estas posibilidades.
190
Ejemplo: Las clases Ellipse2D.Double y Rectangle2D.Double definen elipses y rectangulos, especificados en doble precision. La clase Graphics2D extiende las posibilidades de la clase Graphics.
import java.awt.*;
import java.awt.geom.*;
import java.applet.*;
public class ShapeExample extends Applet {
Ellipse2D.Double circle =
new Ellipse2D.Double(10, 10, 350, 350);
Rectangle2D.Double square =
new Rectangle2D.Double(10, 10, 350, 350);
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.fill(circle);
g2d.draw(square);
}
}
Ejemplo:
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
public class ShapeExample extends JPanel {
Ellipse2D.Double circle =
new Ellipse2D.Double(10, 10, 350, 350);
Rectangle2D.Double square =
new Rectangle2D.Double(10, 10, 350, 350);
public void paintComponent(Graphics g) {
clear(g);
Graphics2D g2d = (Graphics2D)g;
g2d.fill(circle);
g2d.draw(square);
}
void clear(Graphics g) {
super.paintComponent(g);
}
Ellipse2D.Double getCircle() {
return(circle);
}
public static void main(String[] args) {
ShapeExample obj=new ShapeExample();
191
JFrame jf=new JFrame();
jf.setBackground(Color.white);
obj.setBackground(Color.white);
jf.setSize(200, 200);
jf.setContentPane(obj);
jf.setVisible(true);
}
}
Ejemplo:La clase GradientPaint proporciona un nuevo metodo para rellenar con color un objeto
Shape.
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
public class GradientPaintExample extends JPanel {
Ellipse2D.Double circle =
new Ellipse2D.Double(10, 10, 350, 350);
GradientPaint gradient =
new GradientPaint(0, 0, Color.red, 175, 175,
Color.yellow,true);
public void paintComponent(Graphics g) {
clear(g);
Graphics2D g2d = (Graphics2D)g;
drawGradientCircle(g2d);
}
void drawGradientCircle(Graphics2D g2d) {
g2d.setPaint(gradient);
g2d.fill(circle);
g2d.setPaint(Color.black);
g2d.draw(circle);
}
void clear(Graphics g) {
super.paintComponent(g);
}
public static void main(String[] args) {
GradientPaintExample obj=
new GradientPaintExample();
JFrame jf=new JFrame();
jf.setBackground(Color.white);
obj.setBackground(Color.white);
jf.setSize(200, 200);
jf.setContentPane(obj);
192
jf.setVisible(true);
}
}
Ejemplo:
import
import
import
public
javax.swing.*;
java.awt.*;
java.awt.geom.*;
class RotationExample1 extends JPanel {
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);
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
197
198
Salida:
2^1=2
3^1=3
5^1=5
2^2=4
3^2=9
5^2=25
2^3=8
3^3=27
5^3=125
El M
etodo run()
El metodo run() constituye el cuerpo del proceso ligero; en el se indica la accion para la que esta
programado el proceso ligero. Frecuentemente esta accion es un ciclo o una operacion que lleva mucho
tiempo.
En la definicion de la clase Thread del paquete java.lang se incluye el metodo run(). El programador debe adaptar dicho metodo a los objetivos de cada uno de sus procesos ligeros, y puede hacerse
de dos formas diferentes:
Redefiniendo el metodo en una subclase de Thread, igual que se hizo en el ejemplo anterior.
Creando el proceso ligero y
Runnable (tambien definida
cuando define un metodo sin
del objeto que implementa la
La segunda de las opciones es la que debera usarse cuando se quieran integrar procesos ligeros en applets.
A continuacion se presenta el programa que calcula de manera simultanea las potencias de tres
n
umeros usando esta nueva variante.
Ejemplo:
import java.applet.Applet;
public class EjemploThreads extends Applet{
public void init () {
PotenciaRun p1 = new PotenciaRun(2);
PotenciaRun p2 = new PotenciaRun(3);
PotenciaRun p3 = new PotenciaRun(5);
new Thread(p1).start();
new Thread(p2).start();
new Thread(p3).start();
}
}
class PotenciaRun implements Runnable {
199
long num;
public PotenciaRun(long n) {
num=n;
}
public void run() {
long aux=1;
for(int i=1; i<=10; i++) {
aux*=num;
System.out.println(num+"^"+i+"="+aux);
}
}
}
La Clase Thread
La clase Thread dispone de los constructores siguientes:
public Thread()
200
Ejecutable
start
Disponible
Stop
fin
resume()
notify()
notifyAll()
Stop
fin
yield()
suspend()
sleep()
wait()
No ejecutable
Stop
fin
Desactivado
public Thread(String n)
public Thread(Runnable obj)
public Thread(Runnable obj, String n)
public Thread(ThreadGroup g, String n)
public Thread(ThreadGroup g, Runnable obj)
public Thread(ThreadGroup g, Runnable obj,
String n)
Para cambiar un proceso ligero a estado ejecutable se llama al metodo start(), que invoca su
metodo run().
Un proceso ligero pasa al estado no ejecutable cuando esta en espera de una operacion de entrada/salida o se ha llama a uno de los metodos:
suspend(): provoca la suspension del metodo run() hasta recibir la orden de continuar.
sleep(long t): provoca el estado no ejecutable por un tiempo de t milisegundos.
wait(): el proceso ligero entre en estado no ejecutable hasta que se produzca una condicion.
Paso a ejecutable
Un proceso ligero puede pasar de no ejecutable a ejecutable de una u
nica forma, que depende
de como entro en el estado no ejecutable. Cualquier otro intento provocara una excepcion del tipo
IllegalThreadStateException:
Si entro con el metodo suspend(): entonces recuperara el estado ejecutable con una llamada al
metodo resume().
Si entro con el metodo sleep(long t): debe transcurrir ese tiempo para que el proceso ligero
vuelva al estado ejecutable.
Si entro con el metodo wait(): es preciso que otro proceso ligero invoque a su metodo notify()
o al metodo notifyAll().
201
El u
ltimo estado en el que se puede encontrar un proceso ligero es desactivado. Puede llegar a el
desde cualquiera de los otros tres estados por dos motivos:
porque finalice la ejecucion de su metodo run() o
por la utilizacion del metodo stop().
El metodo isAlive() permite reconocer si un proceso ligero ha sido iniciado con el metodo start()
pero no finalizado con stop(), es decir, este metodo devuelve true si el metodo esta en estado ejecutable
o no ejecutable.
202
sleep(delay);
}
} catch (InterruptedException e) {
System.out.println("Interrupcion incorrecta");
}
}
}
Salida: Trabajando sobre un sistema de un solo procesador, la salida en la ventana stdout del programa
anterior debera ser similar a la siguiente:
Ejecutando
Ejecutando
Ejecutando
Ejecutando
Ejecutando
Ejecutando
Ejecutando
Ejecutando
Ejecutando
Ejecutando
Ejecutando
Ejecutando
Ejecutando
Ejecutando
Ejecutando
Tercero
Segundo
Segundo
Tercero
Segundo
Segundo
Tercero
Segundo
Tercero
Primero
Tercero
Primero
Primero
Primero
Primero
203
void setDaemon(boolean daemon)
boolean isDaemon()
void stop()
void suspend()
void destroy()
void checkAccess()
204
private boolean test = true;
public Datos (int x, int n) {
this.x=x;this.n=n;acumulado=x;
}
public synchronized void OperaSuma () {
while (test == false) {
try{ wait();
} catch (InterruptedException e) {}
}
acumulado++;test=false;notify();
}
public synchronized void OperaProducto () {
while (test == true) {
try{ wait();
} catch (InterruptedException e) {}
}
acumulado*=x;test=true;notify();
}
}
class SumaThread extends Thread {
Datos susDatos;
public SumaThread (Datos v) {susDatos=v;}
public void run () {
for(int i=1;i<=susDatos.n;i++)
susDatos.OperaSuma();
System.out.println("Resultado = "
+ susDatos.acumulado);
}
}
class ProductoThread extends Thread {
Datos susDatos;
public ProductoThread (Datos v) {susDatos=v;}
public void run () {
for(int i=1;i<=susDatos.n-1;i++)
susDatos.OperaProducto();
}
}
205
Pr
actica 1
class Carrera{
static Animal laLiebre;
static Animal laTortuga;
public static void main(String args[]){
laLiebre=new Animal(5,"L");
laTortuga=new Animal(1,"T");
laTortuga.run();
laLiebre.run();
}
}
class Animal{
int miVelocidad;
String miNombre;
public Animal(int laVelocidad, String elNombre){
miNombre=elNombre;
miVelocidad=laVelocidad;
}
public void duerme(int tiempo){
for(int i=0;i<tiempo;i++){;}
}
public void run(){
for(int i=0;i<10;i++){
System.out.print(miNombre);
duerme(1000/miVelocidad);
}
System.out.println("\n"+miNombre+" ha llegado");
}
}
206
Pr
actica 2
class CarreraHilos{
static Animal laLiebre;
static Animal laTortuga;
public static void main(String args[]){
laLiebre=new Animal(5,"L");
laTortuga=new Animal(1,"T");
laTortuga.start();
laLiebre.start();
}
}
class Animal extends Thread{
int miVelocidad;
String miNombre;
public Animal(int laVelocidad, String elNombre){
miNombre=elNombre;
miVelocidad=laVelocidad;
}
public void run(){
try{for(int i=0;i<10;i++){
System.out.print(miNombre);
sleep(300000/miVelocidad);
}}catch(InterruptedException e){System.out.println("Interrupci
on Incorrecta");}
System.out.println("\n"+miNombre+" ha llegado");
}
}
207
Ejercicio: Gesti
on de un Almac
en
Se trata de simular mediante la tecnica de los procesos ligeros un almacen, en el que hay un productor,
que se encarga de reponer material, y unos consumidores, que compran un n
umero aleatorio de unidades
mientras el almacen permanece abierto.
Para ello, se sugiere el siguiente proceso:
1. Definir una clase ALMACEN, que contenga la siguente informacion:
(a) Cantidad en stock.
(b) Maxima cantidad permitida de compra a cada comprador
(c) Stock mnimo al que hay que reponer.
(d) Cantidad a reponer
(e) Tiempo de apertura del almacen
(f) Si esta abierto o cerrado
(g) Si necesita reponer stock
y permita:
(a) Reponer material
(b) Comprar material
2. Definir una clase PRODUCTOR, que contenga la siguiente informacion:
(a) Almacen que regenta.
y permita:
(a) Reponer material
(b) Cerrar el almacen cuando proceda.
3. Definir una clase CONSUMIDOR, que contenga la siguiente informacion:
(a) Almacen en el que compra.
(b) N
umero de identificacion.
y permita:
(a) Comprar material
4. Escribir un Applet que ponga en funcionamiento el sistema.
208
Clase Tienda
import java.applet.Applet;
class Tienda {
public static void main(String args[]) {
Almacen a = new Almacen();
Productor p1 = new Productor(a);
Consumidor c1 = new Consumidor(a,1);
Consumidor c2 = new Consumidor(a,2);
Consumidor c3 = new Consumidor(a,3);
System.out.println("La cantidad inicial
es de " + a.stock + " unidades.");
p1.start();
c1.start();
c2.start();
c3.start();
}
}
Clase Productor
class Productor extends Thread {
private Almacen almacen;
public Productor(Almacen a) {
almacen = a;
}
public void run() {
while(!almacen.cerrado){
if(System.currentTimeMillis()
-almacen.hora>almacen.TIEMPOAPERTURA){
almacen.cerrado=true;
System.out.println("Se cierra la
tienda.");
}
almacen.reponer();
try {
sleep((int)(Math.random() * 100));
} catch (InterruptedException e) {
}
}
}
}
209
Clase Consumidor
class Consumidor extends Thread {
private Almacen almacen;
private int numero;
public Consumidor(Almacen a,int numero) {
almacen = a;
this.numero = numero;
}
public void run() {
int value;
while(!almacen.cerrado){
value=(int)(Math.random()*
almacen.MAXCOMPRA);
almacen.comprar(numero,value);
}
}
}
Clase Almac
en
class Almacen {
public int stock=100;
private boolean necesitareponer;
public boolean cerrado=false;
final int MAXCOMPRA=30;
final int LIMITEREPONER=50;
final int CANTIDADREPONER=100;
final long TIEMPOAPERTURA=3000;
long hora=System.currentTimeMillis();
public synchronized void comprar(int consumidor,
int cantidad) {
while (necesitareponer == true) {
try {
wait();
} catch (InterruptedException e) {
}
}
if(!cerrado){
if(stock<cantidad){
cantidad=stock;
}
stock-=cantidad;
System.out.println("Quedan " + stock +
" unidades. El Consumidor " + consumidor
210
+ " ha comprado " + cantidad +
" unidades.");
if(stock<=LIMITEREPONER)
necesitareponer = true;
}
notify();
}
public synchronized void reponer() {
if (!cerrado){
while (necesitareponer == false) {
try {
wait();
} catch (InterruptedException e) {
}
}
stock+=CANTIDADREPONER;
System.out.println("Quedan " + stock
+ " unidades. El Productor repuso " +
CANTIDADREPONER + " unidades.");
necesitareponer = false;
}
notify();
}
}
Programa Completo
import java.applet.Applet;
class Tienda {
public static void main(String args[]) {
Almacen a = new Almacen();
Productor p1 = new Productor(a);
Consumidor c1 = new Consumidor(a,1);
Consumidor c2 = new Consumidor(a,2);
Consumidor c3 = new Consumidor(a,3);
System.out.println("La cantidad inicial
es de " + a.stock + " unidades.");
p1.start();
c1.start();
c2.start();
c3.start();
}
}
class Productor extends Thread {
211
private Almacen almacen;
public Productor(Almacen a) {
almacen = a;
}
public void run() {
while(!almacen.cerrado){
if(System.currentTimeMillis()
-almacen.hora>almacen.TIEMPOAPERTURA){
almacen.cerrado=true;
System.out.println("Se cierra la tienda.");
}
almacen.reponer();
try {
sleep((int)(Math.random() * 100));
} catch (InterruptedException e) {
}
}
}
}
class Consumidor extends Thread {
private Almacen almacen;
private int numero;
public Consumidor(Almacen a,int numero) {
almacen = a;
this.numero = numero;
}
public void run() {
int value;
while(!almacen.cerrado){
value=(int)(Math.random()*almacen.MAXCOMPRA);
almacen.comprar(numero,value);
}
}
}
class Almacen {
public int stock=100;
private boolean necesitareponer;
public boolean cerrado=false;
final int MAXCOMPRA=30;
final int LIMITEREPONER=50;
final int CANTIDADREPONER=100;
212
final long TIEMPOAPERTURA=3000;
long hora=System.currentTimeMillis();
public synchronized void comprar(int consumidor,
int cantidad) {
while (necesitareponer == true) {
try { wait();
} catch (InterruptedException e) {
}
}
if(!cerrado){
if(stock<cantidad){
cantidad=stock;
}
stock-=cantidad;
System.out.println("Quedan " + stock +
" unidades. El Consumidor " + consumidor
+ " ha comprado " +cantidad+" unidades.");
if(stock<=LIMITEREPONER)
necesitareponer = true;
}
notify();
}
public synchronized void reponer() {
if (!cerrado){
while (necesitareponer == false) {
try { wait();
} catch (InterruptedException e) {
}
}
stock+=CANTIDADREPONER;
System.out.println("Quedan " + stock
+ " unidades. El Productor repuso " +
CANTIDADREPONER + " unidades.");
necesitareponer = false;
}
notify();
}
}
Y SONIDO
ANIMACION
214
Animaci
on de Gr
aficos
Mostrar sucesivos fotogramas con cierta rapidez (10-20 por segundo).
Debe utilizarse un proceso ligero (thread) que se encargue de ejecutar el ciclo de la animacion.
A continuacion se muestra un programa, que es un ejemplo de una animacion.
El significado de las variables es como sigue:
umero del fotograma que se esta mostrando en un cierto instante.
numFotograma: da el n
frecuencia: da el maximo del n
umero de
fotogramas/segundo.
tiempoDemora: da el n
umero de milesimas de segundo que trascurren entre fotogramas. Este
se
calcula a partir del valor de la variable frecuencia.
animacionThread: es un objeto de la clase Thread, que representa el proceso ligero que se encarga
de la animacion.
time: da el tiempo transcurrido en milisegundos.
Los metodos utilizados son:
init(): simplemente, asigna blanco al color del fondo.
start(): crea el proceso ligero en caso de que no exista y lo arranca.
stop(): para el proceso ligero.
run(): que contiene el ciclo de la animacion dentro del bucle while, en el que se incrementa en
una unidad el n
umero del fotograma, se llama al metodo repaint() por defecto y se interrumpe su
ejecucion durante el tiempo de demora. El metodo repaint() llama automaticamente al metodo
paint() y este a su vez utiliza el metodo paintAnimation() para dibujar el grafico que se muestra
en la Figura, girandolo un grado, en el sentido de las agujas del reloj, en cada fotograma.
paint(): llama al metodo paintAnimation().
paintAnimation(): dibuja un fotograma con el angulo que le corresponde.
Ejemplo de Gr
afico Animado
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class Anim extends Applet
implements Runnable {
215
216
int radio=100,radio1=80;
float angulo;
for(int i=0;i<20;i++){
angulo=
(float)((numFotograma+10*i)*0.0174533);
g.fillOval((int)(150+
radio*Math.cos(angulo)),(int)(150+radio*
Math.sin(angulo)),ovalWidth, ovalHeight);
g.drawOval((int)(150+radio1*
Math.cos(angulo)), (int)(150+
radio1*Math.sin(angulo)),ovalWidth,
ovalHeight);
}
}
}
Observese que el programa anterior produce la animacion, pero se genera un parpadeo de la imagen
debido a varias razones:
1. Por defecto, antes de llamar al metodo paint() se borra el fondo de la animacion, por lo que se
ve un fotograma blanco entre fotogramas sucesivos.
2. Se van mostrando en pantalla distintas partes del dibujo hasta mostrarse el dibujo completo de
un fotograma, dando esa impresion de parpadeo.
Vamos a eliminar dicho parpadeo, creando una imagen del tama
no apropiado fuera de la pantalla y
enviandola a la misma mediante el metodo drawImage(), solo cuando la imagen este completa.
Eliminamos el Parpadeo en el Gr
afico Anterior
import java.awt.*;
import java.applet.Applet;
import java.applet.event.*;
public class Anim extends Applet
implements Runnable {
int numFotograma= -1;
int frecuencia=20;
int tiempoDemora=1000/frecuencia;
Thread thread;
Image imag;
Graphics grafic;
Dimension dimen;
public void init() {
setBackground(Color.white);
addMouseListener(new MouseAdapter(){
217
public void mouseClicked(MouseEvent me){
if(thread==null){start();}
else{stop();}
}});
}
218
grafic=imag.getGraphics();
}
grafic.setColor(getBackground());
grafic.fillRect(0,0,d.width,d.height);
grafic.setColor(Color.black);
paintAnimation(grafic);
g.drawImage(imag,0,0,this);
}
public void paintAnimation(Graphics g) {
int x0, y0,ovalWidth=10,ovalHeight=10;
radio=100,radio1=80;
float angulo;
for(int i=0;i<20;i++){
angulo=(float)((numFotograma+10*i)*0.0174533);
g.fillOval((int)(150+radio*Math.cos(angulo)),
(int)(150+radio*Math.sin(angulo)),ovalWidth,
ovalHeight);
g.drawOval((int)(150+radio1*Math.cos(angulo)),
(int)(150+radio1*Math.sin(angulo)),ovalWidth,
ovalHeight);
}
}
}
Mover una Im
agenes sobre Otras
Este metodo consiste en mover una imagen sobre otra que esta en el fondo.
En este programa tambien se utiliza un doble amortiguador para eliminar el parpadeo. Los cambios
con respecto al programa anterior son:
1. Se crean las variables mar y barco para almacenar las imagenes del mar y del barco, respectivamente.
Image mar;
Image barco;
2. Se cargan las imagenes de ambos en las variables correspondientes:
mar=getImage(getDocumentBase(),
"ejemplo/mar.gif");
barco=getImage(getDocumentBase(),
"ejemplo/barco.gif");
3. Se cambia el metodo paintAnimation():
219
public void paintAnimation(Graphics g) {
int w1 = mar.getWidth(this);
int h1 = mar.getHeight(this);
if((w1>0)&&(h1>0)){
g.drawImage(mar,0,0,this);
}
int w = barco.getWidth(this);
int h = barco.getHeight(this);
if((w>0)&&(h>0)){
g.drawImage(barco, (numFotograma*2)%(w1-w),
((h1-h)/2)+3,this);
}
}
Ejemplo:
import java.awt.*; import java.applet.*; public class Secuencia
extends Applet implements Runnable {
int numFotograma=0;
Thread thread;
Image imagenes[];
public void init() {
imagenes = new Image[8];
for (int i = 1; i <= 8; i++)
imagenes[i-1] = getImage(getDocumentBase(),"CARA"+i+".gif");
}
public void start() {
if (thread == null) {
220
thread = new Thread(this);
thread.start();
}
}
public void stop() {
thread = null;
}
public void run() {
while (thread!=null) {
numFotograma++;
if(numFotograma>7)numFotograma=0;
repaint();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
}
}
public void paint(Graphics g) {
g.drawImage(imagenes[numFotograma],0,0,this);
}
}
Ejemplo:
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class Secuencia extends Applet
implements Runnable {
int numFotograma=0;
int frecuencia=5;
int tiempoDemora=1000/frecuencia;
Thread thread;
Dimension dimen;
Image imag;
Graphics grafic;
Image imagenes[];
public void init() {
imagenes = new Image[8];
for (int i = 1; i <= 8; i++) {
imagenes[i-1] = getImage(getDocumentBase(),
"CARA"+i+".gif");
}
addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent me){
if(thread==null){start();}
else{stop();}
221
}});
}
public void start() {
thread = new Thread(this);
thread.start();
}
public void stop() {
thread = null;
}
public void run() {
long time=System.currentTimeMillis();
while (Thread.currentThread() == thread) {
time+=tiempoDemora;
numFotograma++;
repaint();
try {
Thread.sleep(Math.max(
0,time-System.currentTimeMillis()));
} catch (InterruptedException e) {
break;
}
}
}
public void paint(Graphics g) {
update(g);
}
public void update(Graphics g) {
Dimension d = getSize();
if ( (grafic == null)||(d.width != dimen.width)
|| (d.height != dimen.height) ) {
dimen = d;
imag = createImage(d.width, d.height);
grafic = imag.getGraphics();
}
grafic.setColor(getBackground());
grafic.fillRect(0,0,d.width,d.height);
grafic.setColor(Color.black);
paintAnimation(grafic);
g.drawImage(imag,0,0,this);
}
public void paintAnimation(Graphics g){
if(numFotograma>7)
numFotograma=0;
g.drawImage(imagenes[numFotograma],0,0,null);
}
}
222
Utilizaci
on de la Clase
MediaTracker
Algunos de los metodos mas u
tiles de la clase MediaTracker son:
El metodo addImage(Image imag, int id) permite
a
nadir una imagen a la lista que se quiere controlar. Ademas, a cada imagen se le puede asignar
un identificador, de forma que las que tienen un ID mas peque
no se cargan antes.
Los metodos checkAll() y checkID(int id) permiten saber si las imagenes ya han sido cargadas.
Los metodos getErrorsAny() y getErrorsID(int id) muestran los errores que se cometen durante la carga de las imagenes.
Los metodos statusAll() y statusID(int id) devuelven los estados en que se encuentran las
imagenes que se estan cargando.
Los metodos waitForAll() y waitForID(int id) cargan todas las imagenes o la indicada por
su id, esperando a que se complete la carga.
Para incorporar el control de las imagenes mediante la clase MediaTracker, al codigo anterior se le
a
naden las lneas siguientes:
1. Se inicializa la variable tracker de la clase MediaTracker:
MediaTracker tracker;
2. En el metodo init() se cargan las imagenes y se a
naden al controlador:
for (int i = 1; i <= 3;i++) {
imagenes[i-1] = getImage(getDocumentBase(),
"CARA"+i+".gif");
tracker.addImage(imagenes[i-1], 0);
}
3. En el metodo update(), se pregunta si las imagenes ya estan cargadas y entonces se dibujan:
if (tracker.statusID(0,true) ==
MediaTracker.COMPLETE) {
if(numFotograma>7)
numFotograma=0;
grafic.drawImage(imagenes[numFotograma],
0,0,this);
g.drawImage(imag,0,0,this);
}
}
223
Sonido
El lenguaje Java permite trabajar con sonidos mediante algunos comandos de la clase Applet y la
interfase AudioClip. El lenguaje Java soporta sonidos en formato .au.
En el paquete Applet se encuentran los siguientes metodos:
getAudioClip(URL url)
Localiza el sonido especificado por el argumento correspondiente a la variable url.
getAudioClip(URL url, String name)
Localiza el sonido especificado por los argumentos url y name.
play(URL url)
Emite el sonido correspondiente al objeto url. Si el sonido no puede encontrarse no ocurre
nada.
play(URL url, String name)
Emite el sonido correspondiente al objeto url y a name. Si el sonido no puede encontrarse
no ocurre nada.
En la interfase AudioClip se definen los siguientes metodos:
loop()
Comienza a emitir el sonido repitiendose automaticamente sin parar.
play()
Emite este sonido una sola vez. Cada vez que se llama a este metodo, el sonido se emite
desde su comienzo.
stop()
Interrumpe la emision del sonido.
La nueva version de JDK, permite crear audioclips tanto para applets como para aplicaciones.
Ademas los clips pueden estar en uno de los siguientes formatos: AIFF, AU, WAV, MIDI,RMF.
Ejemplo:
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Piano extends Applet implements
ActionListener{
String items[] = {"C","D","E","F","G","A","B",
"C"};
224
Button auxButton[]=new Button[items.length];
public void init()
{
setLayout (new GridLayout(1, 8));
int i;
for (i= 0; i < items.length; i++){
auxButton[i]=new Button(items[i]);
auxButton[i].addActionListener(this);
add (auxButton[i]);
}
}
public void actionPerformed(ActionEvent evt)
{
String arg=evt.getActionCommand();
{
if (arg.equals("C"))
play (getDocumentBase(), "cnote.au");
else if (arg.equals("D"))
play (getDocumentBase(), "dnote.au");
else if (arg.equals("E"))
play (getDocumentBase(), "enote.au");
else if (arg.equals("F"))
play (getDocumentBase(), "fnote.au");
else if (arg.equals("G"))
play (getDocumentBase(), "gnote.au");
else if (arg.equals("A"))
play (getDocumentBase(), "anote.au");
else if (arg.equals("B"))
play (getDocumentBase(), "bnote.au");
else if (arg.equals("C"))
play (getDocumentBase(), "c1note.au");
}
}
}
Ejemplo:
import java.applet.*;
import java.awt.*;
public class SoundApplet extends Applet
implements ActionListener{
AudioClip sound;
Button button1;
Button button2;
Button button3;
225
boolean estadoLoop;
public void init() {
estadoLoop=false;
button1=new Button("Play");
button1.addActionListener(this);
button2=new Button("Loop");
button2.addActionListener(this);
button3=new Button("Stop");
button3.addActionListener(this);
add(button1);
add(button2);
add(button3);
sound=getAudioClip(getDocumentBase(),
"sonido.au");
validate();
}
DE FICHEROS
GESTION
227
Introducci
on
Es de sobra conocido que las diferentes maquinas y sistemas operativos utilizan diferentes representaciones para almacenar la informacion en la memoria del ordenador (memoria RAM, discos duros,
etc.). Cuando se quiere acceder a esta informacion (datos) se necesita conocer como esta almacenada.
Lo malo es que al cambiar de maquina, tambien cambia la forma de almacenamiento, por lo que los
programas de lectura y escritura de datos dependen de la maquina. Ello da lugar a la existencia de
notables problemas de compatibilidad entre plataformas y conduce a la necesidad de transformar unos
sistemas en otros mediante programas adecuados.
Una de las ideas centrales del lenguaje Java es la creacion de un sistema de trabajo independiente
de la maquina. El paquete Java.io permite trabajar con los datos con esa independencia. Se trata,
por tanto, de transformar todo a un mismo sistema de forma que el usuario no tenga que preocuparse
de que tipo de maquina o sistema esta utilizando. Ello naturalmente conduce a una utilizacion facil y
comoda y a una compatibilidad muy deseables.
228
PushbackReader
InputStreamReader
FileReader
PipedReader
StringReader
Una clase para flujos de datos (InputStream) y otra para caracteres Unicode (16 bits) para soportar
internacionalizacion
(Reader).
Salida
OutputStream
FilterOutputStream
BufferedOutputStream
DataOutputStream
PushbackOutputStream
ByteArrayOutputStream
FileOutputStream
ObjectOutputStream
PipedOutputStream
Writer
BufferedWriter
CharArrayWriter
FilterWriter
OutputStreamWriter
FileWriterr
PipedWriter
StringWriter
Una clase para flujos de datos (OutputStream) y otra para caracteres Unicode (16 bits) para soportar
internacionalizacion (Writer).
Ejemplo 1
Lee los datos del fichero Fichero1.txt (caracteres o n
umeros) y los escribe en Fichero2.txt.
229
import java.io.*;
class LeerEscribir {
public static void main(String args[]) {
try {
File leer = new File("file1");
FileInputStream f1 =
new FileInputStream(leer);
File escribir = new File("file2");
FileOutputStream f2 =
new FileOutputStream(escribir);
int c;
while ((c = f1.read()) != -1) {
f2.write(c);
}
f1.close();
f2.close();
} catch (Exception e) {
System.out.println("LeerEscribir: " + e);
}
}
}
Se crean dos objetos de la clase File que representan los dos ficheros que se van a manejar. El constructor
toma como argumento el nombre del fichero correspondiente. La corriente FileInputStream permite
leer datos del fichero dado como argumento en su construc tor. La corriente FileOutputStream permite
escribir datos en el fichero dado como argumento en su constructor. Leemos los datos de Fichero1.txt
a traves de su corriente asociada gracias al metodo int read() de la clase FileInputStream que lee un
byte cada vez que es llamado y devuelve -1 si se alcanza final de fichero. Cada byte c ledo se escribe en
el fichero Fichero2.txt a traves de su corriente asociada mediante el metodo public void write(int
b) de la clase FileOutputStream que escribe el byte dado como argumento en la corriente f2, y por
tanto en el segundo fichero. Por u
ltimo, el metodo public void close() cierra ambas corrientes.
Ejemplo 2
Escribe en un fichero el n
umero introducido en el teclado.
import java.io.*;
class LeerEscribir {
public static void main(String args[]) {
int aux;
System.out.println("Escribir un numero entero:");
try {
FileOutputStream fos =
new FileOutputStream("Lista");
aux=System.in.read();
230
aux+=2;
fos.write(aux);
fos.close();
} catch (IOException e) {
System.out.println("LeerEscribir: " + e);
}
}
}
El metodo int read(byte[] b) de la clase InputStream lee bytes de la corriente in (de pantalla) y
los almacena en el array aux dado como argumento. Lee tantos bytes como elementos pueda almacenar
su array argumento. El metodo void write(byte[] b) de la clase FileOutputStream escribe los bytes
del array aux dado como argumento en f1 y, por tanto, en el fichero.
Ejemplo 3
Escribe y lee datos formateados.
import java.io.*;
class LeerEscribir {
public static void main(String args[]) {
int aux=0;
try {
DataOutputStream sum =
new DataOutputStream(
new FileOutputStream("Suma"));
for(int i=0;i<6;i++){
sum.writeInt(i+1);
sum.writeChar(\n);
}
sum.close();
DataInputStream dat =
new DataInputStream(
new FileInputStream("Suma"));
while(aux!=5){
aux=dat.readInt();
dat.readChar();
System.out.println(aux);
}
dat.close();
} catch (IOException e) {
System.out.println("LeerEscribir: " + e);}}}
Las clases DataOutputStream y DataInputStream permiten escribir y leer datos primitivos for
mateados. En primer lugar creamos una corriente de escritura formateada sum dando como argumento al constructor un objeto de la clase FileOutputStream asociado al chero sum.txt. De esta
forma el metodo final void writeInt(int v) de la clase DataOutputStream escribe en el fichero, a
traves de las corrientes intermedias, los enteros 0,1,2,3,4,5 en formato de cuatro bytes; el metodo void
231
writeChar(int v) de la clase DataOutputStream escribe el caracter cambio de lnea tras cada entero,
en formato de dos bytes. Escrita la columna de enteros en el fichero sum.txt se realiza el proceso
inverso. A traves de una corriente dat de lectura, (construida mediante un objeto FileInputStream
asociado al fichero), vamos leyendo cada entero y cada caracter cambio de lnea del fichero gracias a
los metodos int readInt() y char readChar() de la clase DataInputStream. y los imprimimos en
pantalla.
Ejemplo 4
Escribe caracteres en un fichero.
import java.io.*;
class LeerEscribir {
public static void main(String args[]) {
try {
String str1="Esto es una prueba");
String str2="Utilizo la clase FileWriter";
int aux1=1;
double aux2=2.3;
File f=new File("Lista");
FileWriter dat=new FileWriter(f);
dat.write(str1);
dat.write(\n);
dat.write(str2);
dat.write(" "+aux1);
dat.write(\n);
dat.write(" "+aux2);
dat.close();
}
} catch (IOException e) {
System.out.println("LeerEscribir: " + e);
}
}
}
La clase FileWriter es adecuada para escribir ficheros de caracteres. Creamos un objeto de dicha
clase dando como argumento al constructor el objeto File que representa el fichero que queramos escribir. Los metodos void write(String str) y void write(int c) de la superclase Writer escriben
en el fichero cadenas de caracteres o un u
nico caracter.
Ejemplo 5
Lee caracteres de un fichero.
import java.io.*;
class LeerEscribir {
232
public static void main(String args[]) {
try {
int NMaxChar=200;
char[] texto=new char[NMaxChar];
File f=new File("Lista");
FileReader dat=new FileReader(f);
dat.read(texto);
dat.close();
System.out.println(texto);
dat.close();
}
} catch (IOException e) {
System.out.println("LeerEscribir: " + e);
}
}
}
La clase FileReader es adecuada para leer ficheros de caracteres. Creamos un objeto de dicha
clase dando como argumento al constructor el objeto File que representa el fichero que queramos leer.
Los metodos int read(char b[]) y int read() de la superclase Reader leen del fichero cadenas de
caracteres o un u
nico caracter.
Ejemplo 6
Lee lneas de texto del teclado.
import java.io.*;
class LeerEscribir {
public static void main(String args[])
throws IOException {
system.out.print(">");
InputStreamReader is=
new InputStreamReader(System.in);
BufferedReader fis=new BufferedReader(is);
String inputLine=fis.readLine();
fis.close();
OutputStreamWriter os=
new OutputStreamWriter(System.out);
BufferedWriter fos=new BufferedWriter(os);
fos.write(inputLine,0,inputLine.length());
fos.newLine();
fos.close();
}
}
233
System.in es un flujo orientado a bytes. InputStreamReader es un puente entre estos y los flujos
orientados a caracteres. BufferedReader contiene el metodo readLine() que nos permite leer una
lnea de texto. BufferedReader y BufferedReader
Ejemplo 7
import java.io.*;
class LeerEscribir {
public static void main(String args[])
throws IOException {
double x;
InputStreamReader is=
new InputStreamReader(System.in);
BufferedReader fis=new BufferedReader(is);
String inputLine=fis.readLine();
fis.close();
Double d=new Double(inputLine);
x=d.doubleValue();
System.out.println(x)
}
}
Ejemplo 8
Lee texto de un fichero.
import java.io.*;
class LeerEscribir {
public static void main(String args[])
throws IOException {
double x;
FileReader is=new FileReader(args[0]);
BufferedReader fis=new BufferedReader(is);
String inputLine=fis.readLine();
while((inputLine!=null)){
System.out.println(inputLine);
inputLine=fis.readLine();
}
fis.close();
}
}
La clase FileReader es subclase de InputStreamReader, esta clase admite constructor String con
el nombre de un fichero.
234
Ejemplo 9
Lee strings de un fichero.
import java.io.*;
class LeerEscribir {
public static void main(String args[])
throws IOException {
String inputLine="Esto es una prueba";
FileWriter os=new FileWriter("Prueba.txt");
BufferedWriter fos=new BufferedWriter(os);
fos.write(inputLine,0,inputLine.length());
fos.newLine();
fos.close();
FileReader is=new FileReader("Prueba.txt");
BufferedReader fis=new BufferedReader(is);
String leido=fis.readLine();
fis.close();
System.out.println("He leido de Prueba.txt:"+
leido);
}
}
Ejemplo 10
Aplicacion que lee datos de un fichero y los escribe en un area de texto.
import java.io.*;
import java.awt.*;
import java.awt.event.*;
public class FileViewer extends Frame
implements ActionListener{
TextArea textarea;
public FileViewer(){
textarea=new TextArea("",24,80);
textarea.setFont(
new Font("MonoSpaced", Font.PLAIN,12));
textarea.setEditable(false);
add("Center",textarea);
Panel p=new Panel();
p.setLayout(
new FlowLayout(FlowLayout.RIGHT,10,5));
add(p,"South");
235
Font font=new Font("SansSerif", Font.BOLD,14);
Button openfile=new Button("Open File");
Button close=new Button("Close");
openfile.addActionListener(this);
close.addActionListener(this);
p.add(openfile);
p.add(close);
}
public void setFile(String filename){
String str;
try{
FileReader f=
new FileReader(new File(filename));
BufferedReader in=new BufferedReader(f);
while((str=in.readLine())!=null){
textarea.append(str);
textarea.append("\n");
}
}catch(IOException e){ }
}
public void actionPerformed(ActionEvent e){
String cmd=e.getActionCommand();
if(cmd.equals("Open File")){
FileDialog f=
new FileDialog(this,"Open file",FileDialog.LOAD);
f.show();
setFile(f.getFile());
f.dispose();
}
else if(cmd.equals("close"))
this.dispose();
}
public static void main(String[] args){
FileViewer f=new FileViewer();
f.setSize(200,200);
f.setVisible(true);
}
}
Ejemplo 11
Un archivo .zip contiene un conjunto de entradas que se corresponden con archivos comprimidos.
ZipFile.entries() y cada uno de estos ZipEntry puede ser abierto como un
InputStream, getInputStream(), del cual podemos leer datos. Tambien se pueden crear archivos .zip.
236
GZipOutputStream y GZipInputStream admite Salida y Entrada de flujos comprimidos en formato
GZIP(.gz).
import java.io.*;
import java.util.*;
import java.util.zip.*;
class UnzipApp {
public static void main(String args[])
throws IOException {
ZipFile f= new ZipFile(args[0]);
Enumeration entradas=f.entries();
System.out.println("Descomprimiendo"+
args[0]+"...");
while(entradas.hasMoreElements()){
ZipEntry entrada=
(ZipEntry) entradas.nextElement();
System.out.println(" "+entrada.getName());
InputStream in=f.getInputStream(entrada);
FileOutputStream fos=
new FileOutputStream(entrada.getName());
for(int ch=in.read();ch!=-1;ch=in.read())
fos.write(ch);
fos.close();
in.close();
}
f.close();
}
}