TransparenciasJava PDF
TransparenciasJava PDF
Orientado a objeto.
Simple y elegante.
Facilita la labor del programador eliminando dos de los problemas de otros lenguajes:
Gestion de la memoria.
Punteros.
Lenguaje multitarea.
Penetracion en Internet.
Facilmente accesible.
Esas caractersticas han hecho de JAVA uno de los lenguajes lderes y de mayor crecimiento en el
mercado.
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.
1. Applets: Programas que se integran en las paginas Web y que se ejecutan a traves de la red.
2. Aplicaciones: Son programas normales que se ejecutan directamente por el sistema operativo
del usuario a traves de un interprete.
Por razones de seguridad, los applets tienen varias restricciones. Un applet no puede:
Java es un Lenguaje Orientado a Objetos que incorpora una gran numero de clases predefinidas orga-
nizadas en paquetes.
La programacion en Java supone definir clases de forma jerarquica, construir objetos de dichas clases
y realizar acciones con ellos.
Los objetos constituyen el concepto fundamental para entender la tecnologa que se conoce como
tecnologa orientada a objetos.
Objetos del mundo real:
COCHE
MESA
ORDENADOR
TELEVISOR
un estado
un comportamiento
Un objeto es un conjunto constituido por una o varias variables y, opcionalmente, por me-
todos.
Todo aquello que el objeto conoce (estado) se expresa por sus variables, y todo lo que puede hacer
(comportamiento) se expresa por sus metodos.
6
OBJETO
COMPORTAMIENTO MTODOS
MTODO 1
VARIABLES MTODO
MTODO MIEMBRO
3 2
MTODO 4
Ejemplo de Objeto
(a) modelo
(b) cilindrada
(c) velocidad
(d) marcha
2. Metodos:
(a) acelera
(b) frena
(c) para
(d) cambiaMarcha
7
Clases
En el mundo real, se encuentran muchos objetos del mismo tipo. Por ejemplo, mi automovil forma
parte del conjunto de todos los automoviles del mundo.
Clase Automovil
Una clase es un prototipo que define las variables y los metodos de todos los objetos con
caractersticas comunes.
Cuando se crea un ejemplar de una clase, las variables declaradas por la clase son almacenadas en
memoria.
Una vez creadas, se pueden utilizar los metodos miembro de la clase para asignar valores a las
variables.
Para definir una clase es necesario dar dos componentes: la declaracion y el cuerpo:
DeclaracionClase{
CuerpoClase
En la declaracion de una clase debe aparecer, como mnimo, la palabra class y el nombre de la
clase que se esta definiendo.
class NombreClase{
...
8
DeclaracionClase{
declaracionVariablesMiembro
...
declaracionMetodos
}
2. Su nombre.
tipo variableNombre;
tipo metodo(argumentos){
...
}
Si un metodo no devuelve ningun valor, debe declararse como void, y si devuelve un valor, debe utilizar
la sentencia return para devolverlo.
Clase Automovil
class Automovil{
String Modelo;
int Cilindrada;
float Velocidad;
int Marcha;
Automovil(String m,int c) {
super();
9
Modelo=m;
Cilindrada=c;
Velocidad=0;
Marcha=0;
}
void Acelera(float v) {
Velocidad=Velocidad+v;
}
void Frena(float v) {
Velocidad=Velocidad-v;
}
void Para() {
Marcha=0;
Velocidad=0;
}
void CambiaMarcha(int m) {
Marcha=m;
}
}
En Java se crea un objeto sin mas que crear un ejemplar de una clase.
Pueden utilizarse clases definidas por el propio programador o las que se encuentran definidas en los
diferentes paquetes que incluye el entorno de desarrollo Java.
As, para crear un nuevo objeto de la clase String definida en el paquete java.lang se usa el comando
multiple:
2. Creacion del objeto: el operador new crea un nuevo objeto de tipo String
Los constructores se reconocen porque tienen el mismo nombre que la clase y no tienen tipo de
retorno (o tipo void)
Una clase puede tener varios constructores, pero todos ellos deben tener el mismo nombre (el de
la clase), y diferente numero o tipo de argumentos, para que el compilador pueda distinguirlos.
Automovil micoche;
micoche= new Automovil(...,...);
Para acceder a las variables de un objeto, se concatenan los nombres del objeto y de la variable con
un punto. Por ejemplo, para acceder a la variable miembro modelo del objeto miCoche
miCoche.modelo
Para llamar a los metodos de un objeto, se concatena el nombre del objeto con el del metodo
mediante un punto, dando los argumentos del metodo entre parentesis, como en:
miChoche.cambiaMarcha(2);
Si el metodo no requiere argumentos, se utilizan los parentesis vacos.
miChoche.para();
Las llamadas a metodos tambien se conocen como mensajes.
Clase Punto
class Punto{
int x,y;
Punto(int x,int y){
this.x=x;
this.y=y;
}
double distancia(int x,int y){
int dx=this.x-x;
int dy=this.y-y;
return Math.sqrt(dx*dx+dy*dy);
}
double distancia(Punto p){
return distancia(p.x,p.y);
}
}
class DistanciaPuntos{
public static void main(String
args[]){
Punto p1=new Punto(0,0);
Punto p2=new Punto(30,40);
System.out.println("p1=("+p1.x+","+
p1.y+")");
System.out.println("p2=("+p2.x+","+
p2.y+")");
System.out.println("Distancia de
11
p1 a p2=",p1.distancia(p2));
System.out.println("Distancia de
p1 a (60,80)=",
p1.distancia(60,80));
}
}
Herencia
En programacion orientada a objetos se pueden definir clases (subclases) en terminos de otras clases
(superclases).
En Java, toda clase tiene una superclase. La superclase por defecto es la clase Object.
Para especificar la superclase se escribe la palabra extends y el nombre de la superclase a contin-
uacion del nombre de la clase:
class SubClase extends SuperClase{...}
Toda subclase hereda el estado (en la forma de declaracion de variables) y los metodos de la super-
clase. Sin embargo, las subclases no estan limitadas al estado y comportamiento de su superclase, ya
que las subclases pueden:
Anadir nuevas variables miembro.
Dar implementaciones particulares a los metodos heredados, anulando la definicion original de los
metodos, dada por la superclase, y sustituyendola por otra.
Clase Camion
void Carga(float c) {
PesoCarga= PesoCarga+c; }
void Descarga(float c) {
PesoCarga= PesoCarga-c; }
void Para(){
12
super.Para();
PesoCarga=0; }
}
Implementar interfases
Una interfase declara un conjunto de metodos y constantes, sin especificar la implementacion para los
metodos. De forma que la clase que implementa dicha interfase debe implementarlos.
Clase publica
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
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
protected: solo las subclases y las clases del mismo paquete pueden crear objetos de esta clase.
Rectangulo r1;
r1=new Rectangulo(p1,p2);
System.out.println("distancia de
p1 a p2= "+p1.distancia(p2));
r1.calcula();
System.out.println("diagonal
del rectangulo "+ r1.diagonal);
System.out.println("ancho
del rectangulo "+ r1.ancho);
System.out.println("alto
del rectangulo "+ r1.alto);
}
}
Ejemplo: Clase final y privada
private final class Libro{
int paginas;
public Libro(int numPaginas){
paginas=numPaginas;
}
public void mensajePaginas(){
System.out.println("Numero de
paginas="+paginas);
}
}
class Diccionario extends
Libro{ //no permitido
int definiciones;
public Diccionario(int numPaginas,
int numDef){
super(numPaginas);
definiciones=numDef;
}
public void mensajeDef(){
System.out.println("Numero de
definiciones="+definiciones);
System.out.println("Numero de
paginas="+paginas);
}
}
public class PrincipalLibro{
public static void
main(String args[]){
Libro lib1;
lib1=new Libro(50);//no permitido
Diccionario dicc1;
dicc1=new Diccionario(60,1000);
15
lib1.mensajePaginas();
dicc1.mensajeDef();
}
}
Acceso privado
Un miembro con este tipo de acceso es accesible solo en la clase en la cual esta definido.
Ejemplo:
class AClase{
private int privVar;
private void privMetodo(){
privVar=5;//permitido
System.out.println("La variable
privVar toma el valor="+privVar);
}
public void pubMetodo(){
privVar=15;//permitido
privMetodo();//permitido
}
}
class BClase{
void accMetodo(){
AClase a=new AClase();
a.privVar=10;//no permitido
a.privMetodo();//no permitido
a.pubMetodo();//permitido
}
}
Acceso protegido
En este nivel de acceso se permite a la propia clase, a sus subclases y a todas las clases que
esten en el mismo paquete, acceder a los miembros.
16
Ejemplo:
package Ejemplo;
class AClase {
protected int protVar;
protected void protMetodo(){
protVar=1; //permitido
}
}
class BClase{
void accMetodo(){
AClase ap=new AClase();
ap.protVar=2; //permitido
ap.protMetodo(); //permitido
System.out.println("var1="+
ap.protVar); }}
------------
import Ejemplo.*;
package EjemploPrueba;
class CClase extends AClase{
void metodo3(AClase a,
CClase d){
a.protVar=2; //no permitido
d.protVar=2; //permitido
a.metodo1(); //no permitido
d.metodo1(); //permitido
}
}
Acceso publico
Cualquier clase en cualquier paquete tiene acceso a las variables y metodos publicos de una
clase.
Ejemplo:
package Ejemplo;
class AClase {
public int protVar;
public void protMetodo(){
protVar=1; //permitido
}}
package EjemploPrueba;
class BClase{
void accMetodo(){
AClase ap=new AClase();
ap.protVar=2; //permitido
17
ap.protMetodo(); //permitido
System.out.println("var1="+
ap.protVar);
}
}
Acceso no especificado
Las clases definidas en el mismo paquete tiene acceso a las variables y metodos de una clase
cuyo acceso es no especificado.
El valor de una variable es constante si esta se declara final, un metodo no puede ser
redefinido si se declara final.
Ejemplo:
class Entero{
int x;
public int x(){
return x;
}
public void cambiarX(int nuevoX){
x=nuevoX;
}
18
}
class Principal{
public static void main(String
args[]){
Entero x1=new Entero();
Entero x2=new Entero();
x1.cambiarX(1);
x2.x=2;
System.out.println("x1.x="+x1.x());
System.out.println("x2.x="+x2.x());
}}
Salida: x1.x=1, x2.x=2
Ejemplo:
class Entero{
static int x;
public int x(){
return x;// permitido
}
public void cambiarX(int nuevoX){
x=nuevoX;
}
}
class Principal{
public static void main(String
args[]){
Entero x1=new Entero();
Entero x2=new Entero();
x1.cambiarX(1);
x2.x=2;
System.out.println("x1.x="+x1.x());
System.out.println("x2.x="+x2.x());
}
}
Salida: x1.x=2, x2.x=2
Ejemplo:
class Entero{
int x;
static public int x(){
return x;//no permitido
}
public void cambiarX(int nuevoX){
x=nuevoX;
}
}
class Principal{
19
Entero.cambiarX(1);
Entero.x=2;
System.out.println("El valor final
es "+ Entero.x());
}
}
Herencia
Una subclase hereda las variables y los metodos de su superclase y de todas sus antecesoras:
hereda los miembros declarados sin ningun acceso si esta en el mismo paquete que su superclase.
no heredan un miembro si lo declaran con el mismo nombre que en la superclase. En este caso se
ocultan variables y se redefinen metodos.
Ejemplo:
class ASuper{
int var1;
void metodo(){
var=1;
}
}
class BSub extends ASuper{
int var;
void metodo(){
var=2;
super.metodo();
System.out.println(var);
System.out.println(super.var);
}
}
Paquete java.lang
Paquete java.io
Paquete java.applet
Paquete java.util
Posee clases que:
Paquete java.net
Soporta todo lo relacionado con la red. Es util para construir applets que necesitan utilizar
los servicios de la red. Contiene la clase URL, sin la cual los applets no podrian cargar nada
de el servidor, lo cual significaria que no se podrian cargar ficheros con imagenes o sonido.
22
Paquete java.awt
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 java.awt.peer
Paquete java.awt.geom
En este paquete se encuentran clases y metodos para trabajar con objetos geometricos en
2D.
Paquete javax.swing
En este paquete se encuentran clases y metodos para crear una interfase de usuario. Este
paquete se puede considerar como una version actualizada del paquete java.awt, pues las
nuevas clases ofrecen mayores posibilidades que las que ofrece el paquete java.awt.
Paquete javax.swing.event
Suministra las clases necesarias para controlar todos los sucesos que ocurren sobre los com-
ponentes swing.
Paquete javax.swing.table
Suministra las clases e interfases necesarias para trabajar con objetos javax.swing.JTable.
Paquete javax.swing.text
Suministra las clases e interfases necesarias para trabajar con componentes de texto, editables
y no-editables.
Paquete javax.swing.border
Suministra las clases e interfases necesarias para dibujar bordes alrededor de las componentes
swing.
import paquete.nombreclase
import paquete.*
Por ejemplo, para cargar todas las clases del paquete java.awt:
import java.awt.*
Clase Lista
Se crea la lista
*/
Clase Complejo
import java.io.*;
import java.lang.*;
(a, b) + (c, d) = (a + c, b + d)
ac + bd ad bc
(a, b)/(c, d) = ( , ).
c2 + d2 c2 + d2
(1,2)
(3,4)
(-3,-4)
(-3,4)
(-2,6)
El modulo de la suma es = 6.32456
El argumento de la suma es = -1.24905 radianes
(-14,-22)
El argumento de c2 es = 0 radianes
Al calcular el cociente se ha producido una excepcion
class ZerodivisorException
con el mensaje: Divide por cero
Programa de Prueba
import java.io.*;
import java.applet.*;
//import Complejo;
ENTORNO JDK
29
PROGRAM A
JAVA
MiPrograma.java
MiPrograma.class
0010110100
MI
PROGRAMA
Creacion de aplicaciones
Las aplicaciones son programas autonomos que no necesitan de un navegador para ejecutarse.
Ejemplo 1:
El nombre de dicho fichero debe ser el mismo que el de la clase con el metodo main() pero con la
terminacion .java.
javac MiAplicacion.java
En caso de estar en un directorio diferente al que contiene el codigo fuente debe indicarse el camino
(path) completo para llegar a el.
Esto tambien puede resolverse anadiendo a la variable Path, el camino donde se halla el compi-
lador. Para ello basta con escribir en el fichero autoexec.bat,
3 Ejecucion de la aplicacion La ejecucion se puede hacer con un editor de Java (Kawa, JCreator,
etc.), en particular, utilizando la opcion Run del menu Build. Tambien se puede hacer desde el
DOS, para ello se utiliza el fichero .class asociado a la clase que tiene el metodo main()
La orden debe darse desde el DOS:
java MiAplicacion
Para poder ejecutar una aplicacion, el directorio actual debe ser el que contiene el codigo objeto
(el fichero MiAplicacion.class).
Ejemplo 2:
Los argumentos se pasan desde la lnea de comandos del DOS, al mismo tiempo que se ordena la
ejecucion de la aplicacion:
Creacion de applets
31
import java.applet.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.
<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.
Ejemplo aplicacion
PrimeraAplicacion.java
Ejemplo applet
MiPrimerApplet.java
MiPrimerApplet.html
EJEMPLO
import java.awt.*;
public EjemploAplicacion(){
boton=new Button("OK");
add("South",boton);
}
Variables
Las variables son zonas o espacios de memoria en las que se almacena la informacion. Son los pilares
de la programacion y los elementos sobre los que se actua. Es necesario especificar su nombre y su tipo.
el nombre sirve para saber a que zona de memoria se esta uno refiriendo.
el tipo sirve para saber el tamano de la memoria necesario para almacenarla y como debe inter-
pretarse la informacion. La informacion se almacena en binario, es decir, en forma de bits (ceros
y unos), por lo que hay que transformarla tanto para almacenarla como para interpretarla.
Toda variable y toda expresion tienen un tipo. Esto limita los valores que pueden tomar las variables
y producir las expresiones, limita las operaciones que pueden realizarse con las variables y expresiones
y determina el significado de las operaciones que las afectan.
Al declarar una variable, debe especificarse su tipo y su nombre.
int a,b;
String nombre,domicilio;
long d;
boolean f;
1. Debe comenzar siempre con una letra (mayuscula o minuscula) o con un signo de subrayado (_).
2. El resto del nombre puede estar formado por combinaciones de letras, numeros y signos de sub-
rayado. Por ejemplo miEdad, Edad_1,A1
4. Debe ser un identificador legal de Java formado por una serie de caracteres unificados (Unicode).
6. Tampoco debe coincidir con el nombre de otra variable declarada en su mismo campo de accion,
pudiendo hacerlo con variables declaradas en diferente campo.
Tipos de Datos
Hay tres tipos de variables o expresiones:
Observaciones:
El tipo double tiene mas precision y puede almacenar mas cifras decimales.
En la mayora de los ordenadores, los enteros se procesan mucho mas rapido que los numeros
almacenados en coma flotante.
Los numeros en coma flotante pueden almacenar valores mas grandes y mas pequenos que los
enteros.
Campo de Accion de una Variable
Se denomina campo de accion de una variable al bloque de codigo en el que dicha variable es accesible.
Ademas, este campo determina cuando la variable se crea y se destruye.
Atendiendo al campo de accion, se pueden clasificar las variables en las clases siguientes:
Variable de clase. Se declara dentro de la definicion de una clase o interfase, usando la palabra
clave static. Estas variables son creadas e iniciadas, a valores determinados o por defecto, al
construirse la clase, dejando de existir cuando desaparece dicha clase y tras completar el proceso
previo a la destruccion del objeto.
37
Variables miembro de una clase. Se declaran en la definicion de una clase sin usar la palabra clave
static. Si a es una variable miembro de una clase A, cada vez que se construye un nuevo objeto
de la clase A o una subclase de A se crea una nueva variable a y se inicia dandole un valor concreto
o por defecto. La variable deja de existir cuando desaparece la clase a la que pertenece y tras
completar el proceso previo a la des truccion del objeto.
Componentes de una matriz. Son variables sin nombre que se crean e inician a valores concretos
o por defecto cuando se crea un objeto nuevo de tipo matriz. Las componentes de la matriz dejan
de existir cuando desaparece la misma.
Variable local. Se declara dentro de un bloque de codigo y solo es accesible dentro del mismo. Las
variables locales no se inician hasta que se ejecuta la sentencia de declaracion correspondiente.
Las variables locales dejan de existir cuando se termina el bloque en el que estan declaradas.
Iniciacion de Variables
Al declarar las variables locales, las de clase y las que son miembros de clases pueden darse valores
iniciales. Por ejemplo:
int edad=30;
double estatura=1.78;
boolean Terminado=true;
Ademas de reservar espacio en memoria para ellas, se almacenan los valores indicados.
Los parametros de los metodos y los de los manipuladores de excepciones no pueden iniciarse de
este modo. El valor de estos parametros es fijado por el metodo que los llama.
Constantes
Las constantes en Java son como las variables, pero su valor no se altera durante la ejecucion del pro-
grama. Se las precede del adjetivo final. Por convenio, las constantes se escriben todas en mayusculas.
Por ejemplo:
Comentarios
Existen tres clases de comentarios:
/* texto */. El texto comprendido entre /* y */ es ignorado por el compilador. Se utiliza para
comentarios de mas de una lnea.
// texto. El texto desde // hasta el final de lnea es ignorado. Se utiliza para comentarios de
una sola lnea.
/** documentacion */. El texto comprendido entre /** y */ puede ser procesado por otra
herramienta para preparar documentacion de la siguiente
declaracion de clase, constructor, interfase, metodo o campo.
Operadores
Existen operadores unarios y binarios que requieren uno o dos operandos, respectivamente.
Los operadores unarios pueden aparecer antes o despues del operando, aunque, en ese caso, la accion
que realizan puede ser diferente.
x++;
++y;
Los operadores binarios siempre aparecen entre los dos operandos:
5*6;
a+b;
Todo operador devuelve siempre un valor. Dicho valor y su tipo dependen del operador y del tipo
de los operandos.
Los operadores pueden clasificarse en las siguientes
categoras:
aritmeticos
relacionales y condicionales
bit-a-bit y logicos
de asignacion
Operadores Aritmeticos
Los operadores aritmeticos binarios, salvo el operador %, que solo actua con enteros, manejan indis-
tintamente los tipos enteros y los de coma flotante.
Cuando un operador tiene operandos de diferente tipo, estos se convierten a un tipo comun siguiendo
las reglas:
la categora de los tipos, de mayor a menor, es la siguiente: double, float, long, int,
short,char.
39
Operadores Binarios
Operador Operacion Descripcion
+ a + b Adicion
- a - b Diferencia
* a * b Producto
/ a / b Division
% a % b resto de dividir a entre b
en cualquier operacion en la que aparezcan operandos de tipos diferentes, se eleva la categora del
que la tenga menor.
en una sentencia de asignacion, el resultado final se convierte al tipo de la variable a la que son
asignados.
Operadores Unarios
Operador Operacion Descripcion
+y- +a y -a Fijan el signo del operando
++x Suma 1 a x antes de usarla
++
x++ Suma 1 a x despues de usarla
--x Resta 1 a x antes de usarla
--
x-- Resta 1 a x despues de usarla
Ejemplos:
int i=7;
4 * i++;
i+2;
int i=7;
4 * ++i;
i+2;
Operadores Relacionales
Operador Empleo Descripcion
true si a es mayor que b,
> a > b
false en caso contrario.
true si a es mayor o igual que b,
>= a >= b
false en caso contrario.
true si a es menor que b,
< a < b
false en caso contrario.
true si a es menor o igual que b,
<= a <= b
false en caso contrario.
true si a y b son iguales,
== a == b
false en caso contrario.
true si a y b son diferentes,
!= a != b
false en caso contrario.
Operadores Condicionales
Operador Empleo Descripcion
true si a y b son true,
&& a && b
false en caso contrario.
false si a y b son false,
|| a || b
true en caso contrario.
false si a es true y
! !a
true si a es false
Operadores de Asignacion
El operador = asigna a la variable de la izquierda el valor que toma la expresion de la derecha:
float i = 3.5;
Ademas:
n = n*5;
41
Operadores de Asignacion
Operador Empleo Descripcion
+= a += b a = a + b
-= a -= b a = a - b
*= a *= b a = a * b
/= a /= b a = a / b
%= a %= b a = a % b
&= a &= b a = a & b
|= a |= b a = a | b
^= a ^= b a = a ^ b
<<= a <<= b a = a << b
>>= a >>= b a = a >> b
>>>= a >>>= b a = a >>> b
es equivalente a:
n *= 5;
El operador cast
A veces se necesita almacenar valores de un tipo en variables de tipo diferente. Como Java no
permite almacenar a cada variable mas que valores de su tipo, es necesario transformarlos previamente.
Para ello, se recurre al operador cast, que transforma un tipo de dato en otro compatible, tal como
se ve en el siguiente ejemplo:
float a;
int b;
b = (int) a;
Matrices
Considerense los 100 primeros multiplos de 2. Estos podran almacenarse as:
int m1 = 2;
int m2 = 4;
int m3 = 6;
...
int m100 = 200;
Para ello, se dispone de las matrices (arrays), cuya declaracion se hace como sigue:
42
int mult[];
mult = new int[100];
En la primera sentencia se especifica el tipo de los elementos de la matriz (int en este caso) y se
da un nombre a la matriz, seguido de un doble corchete [], el cual indica al compilador que lo que se
declara es una matriz.
Pero la declaracion int mult[]; no asigna memoria para almacenar los elementos de la matriz, de
manera que si se intenta acceder a alguno de ellos o asignarle un valor, el compilador dara un mensaje
de error. Para evitar esto y asignar la memoria necesaria se recurre al operador new.
A partir de ese instante ya se pueden dar valores a todos los elementos de la matriz:
Ejemplo:
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.
Otra forma:
43
"Hola"
Tambien se pueden unir dos cadenas de caracteres mediante el operador de concatenacion +. Por
ejemplo:
Expresiones
Toda expresion es una combinacion de variables, operadores y llamadas a metodos, que calculen un
valor.
Las expresiones se utilizan para calcular y asignar valores a variables y para controlar la ejecucion
de un programa. Realizan las operaciones indicadas por sus elementos y devuelven algun valor.
Existen dos tipos de expresiones:
Expresiones Numericas
int i
i+10
--n;
a = 100
b* = 2
Expresiones Booleanas
n != m
a < b
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;
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;
Sentencias estructuradas o de control de flujo: while, if-else, switch, etc., que se analizan en
la seccion siguiente.
45
Un bloque es un conjunto de dos o mas sentencias agrupadas y encerradas entre llaves, no existiendo
punto y coma tras la llave de cierre. Por ejemplo, el programa que sigue contiene un bloque.
for(i=0;i<100;i++) {
mult[i] = 2*(i+1);
System.out.println("Elemento i"+mult[i]);
}
Control de Flujo
Puede determinarse el orden de ejecucion de las sentencias segun convenga. Para ello nos servimos
de las sentencias estructuradas o de control de flujo.
Sentencia if-else
if(expresion)
{sentencias}
if(expresion)
{sentencias1}
else
{sentencias2}
Sentencia else-if
Expresin booleana
Bloque else
if(expresion1)
{sentencias1}
else if(expresion2)
{sentencias2}
...
else
{sentenciasN}
Las expresiones se evaluan en orden; si alguna es cierta, se ejecuta la sentencia o bloque asociado a ella,
y se concluye la ejecucion de la sentencia else-if. Solo se ejecuta el ultimo else en el caso de que
todas las expresiones sean falsas.
Pudiera ocurrir que fueran ciertas dos o mas expresiones. En este caso, se ejecutaran solo las
sentencias correspondientes a la primera de ellas y se saldra del bloque else-if.
Ejemplo:
Ejercicio: Escribir un applet o aplicacion que escriba en la salida estandar si un ano es bisiesto o no
lo es, dado un ano cualquiera.
Nota: Una ano es bisiesto si es divisible por 4 pero no por 100. Un ano que es divisible por 4 y 100
es bisiesto si es tambien divisible por 400.
class Bisiesto{
public static void main(String args[]){
int anio=Integer.parseInt(args[0]);
if((anio%4==0)&&(anio%100!=0))
System.out.println("El anio " + anio+" es bisiesto");
else if((anio%4==0)&&(anio%100==0)&&(anio%400==0))
System.out.println("El anio " + anio+" es bisiesto");
else
System.out.println("El anio " + anio+" no es bisiesto");
}}
Sentencia switch
switch(expresion) {
case {expresion1_constante1}:
{sentencias1}
case {expresion2_constante2}:
{sentencias2}
...
case {expresionN_constanteN}:
{sentenciasN}
default {sentencias}
Cada case lleva una o mas constantes enteras o expresiones constantes enteras. Si un case coincide
con el valor de expresion, la ejecucion comienza ah. Todas las expresiones de los case deben ser
diferentes. Si ninguna de ellas coincide con expresion, se ejecutan las sentencias correspondientes a
default. El default es optativo; si no esta y ninguno de los casos coincide, no se ejecuta ninguna
accion.
Ejemplo:
class Califica{
static void calificacion(int nota){
switch (nota){
case 3:
System.out.println("S"); break;
case 5:
System.out.println("A"); break;
case 7:
System.out.println("N"); break;
case 9:
48
Expresin Aritmtica
char, byte, short, int
switch ( nota ){
expresion1_constante1 case 3 :
System.out.println("S"); break;
expresion2_constante2 case 5 :
System.out.println("A"); break;
expresion3_constante3 case 7 :
System.out.println("N"); break;
expresion4_constante4 case 9 :
System.out.println("SB"); break;
default: System.out.println("Ser
calificado posteriormente");
}
System.out.println("SB"); break;
default: System.out.println("Sera
calificado posteriormente");
}
}
public static void
main(String args[]){
calificacion(5);
calificacion(8);
}
}
Ejercicio: Escribir una aplicacion que devuelva el numero de das de cada mes en un ano cualquiera.
Expresin booleana
while ( numero<=100 ) {
sum=sum+numero;
numero=numero+1;
}
Cuerpo del bucle
break;
case 4:
case 6:
case 9:
case 11:
numDias=30;
break;
case 2:
if(((a%4==0) && !(a%100==0))||
(a%400==0))
numDias=29;
else
numDias=28;
break;
}
System.out.println("Numero de
dias= "+numDias);
}
}
Ciclo while
while(expresion)
{sentencias}
Se ejecuta el bloque {sentencias} mientras el valor de la expresion es true. El ciclo se repite hasta
que el valor de expresion toma el valor false. Entonces, el compilador sale del ciclo.
Ejemplo: Supongamos que queremos sumar los primeros 100 numeros enteros.
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");
while(numero<=ultimoNumero){
producto=producto*numero;
numero=numero+2;
}
System.out.println("Resultado="+
producto);
}
}
Ciclo do-while
do{
sentencias
}while({expresion});
51
Mientras en los ciclos while y for, las condiciones de termino se evaluan al principio de cada iteracion,
en el ciclo do-while se comprueban al final, despues de cada repeticion del ciclo, por lo que el bloque
{sentencias} se ejecuta siempre, al menos una vez.
As, primero se ejecutan las sentencias del bloque sentencias y despues se evalua expresion.
Si es verdadera, se vuelve a ejecutar el bloque sentencias, y as sucesivamente.
Cuando expresion toma el valor false se acaba el ciclo.
El bloque while:
int a = 1;
while ( a != 15 ) {
a = a + 1;
}
equivale al bloque con do-while:
int a = 1;
do {
a = a + 1;
} while (a != 14);
Ciclo for
Actua hasta un cierto lmite impuesto por el programador. Su sintaxis es la siguiente:
for(iniciacion;limite;incremento)
{sentencias}
El ciclo for es equivalente a:
iniciacion
while(limite) {
{sentencias}
incremento
}
iniciacion e incremento suelen ser asignaciones o llamadas a una funcion, que en el caso de ser
mas de una, se separan por comas, y limite, una expresion relacional.
La expresion iniciacion se ejecuta al comienzo del bucle.
La expresion limite indica cuando se ejecuta el bucle y se evalua al comienzo de cada iteracion,
de manera que cuando su valor es true se ejecuta el bloque {sentencia} y si es false, el ciclo
for concluye.
Las sentencias del bloque sentencias se ejecutan en cada ciclo.
Las sentencias del bloque incremento se ejecutan al final de cada iteracion o ciclo.
El ciclo for es frecuente en la iniciacion de los elementos de un matriz:
int mult[];
mult = new int[100];
for(int i=0;i<100;i++) {
mult[i] = 2*(i+1);
}
52
Definiciones Recursivas
Sentencias de Bifurcacion
Permiten alterar el flujo de ejecucion normal del programa. Por ejemplo, la sentencia break en un
ciclo obliga al programa a abandonar el ciclo y continuar con la ejecucion de las sentencias que siguen.
La sentencia continue se usa dentro de un ciclo para iniciar la siguiente iteracion del ciclo que la
contiene. De esta manera se evita ejecutar las sentencias del ciclo siguientes a continue. Por ejemplo,
con las sentencias:
53
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); }
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
Por ejemplo, haciendo la llamada al metodo main() de la clase Collatz al mismo tiempo que se
pasa el valor inicial n = 56, se obtiene un resultado como el que se muestra a continuacion:
Iter. 1:56
Iter. 2:28
Iter. 3:14
Iter. 4:7
Iter. 5:11
Iter. 6:17
55
Iter. 7:26
Iter. 8:13
Iter. 9:20
Iter. 10:10
Iter. 11:5
Iter. 12:8
Iter. 13:4
Iter. 14:2
SE ALCANZA EL 1 TRAS 15 ITERACIONES
1
232
34543
4567654
567898765
67890109876
7890123210987
890123454321098
90123456765432109
0123456789876543210
123456789010987654321
23456789012321098765432
3456789012345432109876543
456789012345676543210987654
56789012345678987654321098765
int altura=12;
if(args.length>=1)
{
Integer argumento=new Integer(args[0]);
altura=argumento.intValue();
}
else
altura=10;
for(i=1,m=1;i<=altura;i++,m+=2)
{
for (j=1;j<=altura-i;j++)
System.out.print(" ");
for (k=i;k<=m;k++)
System.out.print(k%10);
for (j=m-1;j>=i;j--)
System.out.print(j%10);
System.out.println("");
}
}
}
El Metodo main()
El metodo main() es el metodo de arranque de toda aplicacion en lenguaje Java.
Puede ejecutarse una clase cualquiera sin mas que incluir en ella el metodo main(). Cuando se trata
de aplicaciones, bastara implementarlo en una de las clases (la que se arranca).
El metodo main() es la herramienta de que dispone el lenguaje Java para decirle al ordenador que
hacer tras arrancar una aplicacion o clase. Por ello, es llamado automaticamente por el entorno Java
al arrancar la clase o aplicacion, controla el flujo del programa desde su comienzo, asigna los recursos
que se necesiten y se encarga de llamar a cualquier otro metodo que se requiera.
Forma de declarar el metodo main():
57
Arranca el
intrprete de Java
Carga la clase o
aplicacin
Arranca la clase
o aplicacin
No Existe el Si
mtodo main?
args[]: es una matriz de objetos de la clase String en la que el usuario pasa la informacion a la
clase. Se trata de los argumentos del metodo main().
El metodo main() es un metodo de clase, por lo que si se quieren invocar metodos de la clase, se
debe crear un ejemplar de la misma.
Si se disena una interfase de usuario en una aplicacion, se debe crear en el metodo main() un
espacio y una ventana donde colocar dicha interfase.
Cuando el entorno Java ejecuta la clase o aplicacion, lo primero que hace es llamar al metodo main(),
el cual invoca al resto de metodos necesarios para hacer funcionar la aplicacion.
Si la clase a compilar no tiene implementado un metodo main(), el proceso se detiene y se enva el
mensaje de error:
In class NombreClase:
void main(String args[]) is not defined
Los programas pueden necesitar informacion para poder ejecutarse segun los deseos del usuario.
Una de las herramientas que lo permiten son los argumentos de la lnea de comandos. Son caracteres o
cadenas de caracteres que el usuario teclea y que permiten modificar el comportamiento de la aplicacion
sin necesidad de recompilarla.
El metodo main() acepta como unico argumento una matriz de elementos de la clase String, que
se llaman argumentos de la lnea de comandos, puesto que se les puede dar valores al comienzo de la
ejecucion, mediante un cuadro de dialogo que se muestra al usuario al ejecutar el programa Java o en
el comando de arranque de la aplicacion (entornos UNIX y WINDOWS). Mediante estos argumentos
se puede enviar informacion a la aplicacion.
Por tanto, el programa Java debe ser capaz de leer los argumentos y programarlos. El proceso es
el siguiente: al ejecutar una aplicacion, el sistema pasa los argumentos tecleados por el usuario a su
metodo main(), y los almacena en una matriz de objetos de tipo String. Cada uno de los argumentos
es uno de los elementos de la matriz.
Practica 1
public class Matriz {
public int nfilas, ncolumnas;
public float x[][];
Practica 2
class Persona{
int edad, telefono;
String nombre;
public Persona(){
nombre="No ha sido dado";
edad=0;
telefono=0;
}
public Persona(String nombre, int edad, int telefono){
this.nombre=nombre;
this.edad=edad;
this.telefono=telefono;
}
}
class Agenda{
Persona[] entradas;
int contador;
public Agenda(int tamano){
contador=0;
entradas=new Persona[tamano];
System.out.println("Se ha creado una matriz de tamano "+tamano);
}
void anadir(Persona nuevaPersona){
if(contador==entradas.length) aumentarTamano();
entradas[contador]=nuevaPersona;
contador++;
}
void aumentarTamano(){
int nuevaLongitud=2*entradas.length;
Persona[] entradasAux=new Persona[nuevaLongitud];
for(int i=0;i<entradas.length;i++){
entradasAux[i]=entradas[i];
}
entradas=entradasAux;
System.out.println("La nueva matriz de tamano "+entradas.length);
}
Persona busqueda(String buscarNombre){
Persona encontrarPersona;
int localizador=0;
while((localizador<contador) &&
!(buscarNombre.equals(entradas[localizador].nombre)))
localizador++;
if(localizador==contador)
encontrarPersona=null;
61
else
encontrarPersona=entradas[localizador];
return encontrarPersona;
}
}
class PrincipalAgenda{
public static void main(String args[]){
Agenda miAgenda;
Persona persona,personaBuscar;
miAgenda=new Agenda(4);
for(int i=0;i<4;i++){
persona=new Persona("X"+i,10+i,677888+i);
System.out.println("La persona anadida es "+persona.nombre);
miAgenda.anadir(persona);
}
persona=new Persona("X5",15,5555788);
miAgenda.anadir(persona);
System.out.println("La persona anadida es "+persona.nombre);
personaBuscar=miAgenda.busqueda("X2");
if(personaBuscar==null)
System.out.println("No se encuentra la persona indicada");
else
System.out.println("La persona indicada se encuentra en la agenda");
}
}
EXCEPCIONES
63
Excepciones
Conceptos basicos
Los errores forman parte de todo programa. El lenguaje Java usa las excepciones para su tratamiento
y manipulacion.
Una excepcion es un suceso que ocurre durante la ejecucion del programa, y que rompe el flujo
normal del mismo.
Cuando ocurre uno de estos sucesos, se crea una excepcion y el control del programa pasa desde
el punto donde el error se produjo a otro punto especificado por el programador.
Se dice que la excepcion es lanzada (thrown) desde el punto donde se crea y es recogida
(caught) en el punto donde se transfiere el control
Java hereda la terminologa y la sintaxis del tratamiento de excepciones del lenguaje C++.
Toda excepcion es representada por un objeto de la clase Throwable o cualquier subclase suya.
Para dar respuesta a las excepciones se utilizan los manipuladores de excepciones (exception
handler).
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
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.
Permiten separar el codigo especfico de tratamiento de errores del resto del codigo.
Tipos de Excepciones
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 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.
Quedan exentas de esta imposicion todas las excepciones de la clase RuntimeException o cualquiera
de sus subclases.
CloneNotSupportedException: error al hacer una copia del objeto con el metodo clone() de la
clase Object.
IllegalAccessException: intento fallido de cargar una clase desde un metodo que no tiene
acceso a ella porque no es de tipo public y se encuentra en otro paquete.
java.net.MalformedURLException
java.net.ProtocolException
java.net.SocketException
java.net.UnknownHostException
java.net.UnknownServiceException
ArithmeticException: provocada por una operacion aritmetica ilegal. Por ejemplo, la division
por cero.
ArrayStoreException: intento de asignar a uno de los elementos de una matriz un valor con un
tipo no compatible.
IllegalMonitorException.
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);
}
}
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
2. Declarandola y dejando que sea alguno de los metodos de los que provino quien se encargue de
responderla.
El bloque try: agrupa todas las sentencias que pueden provocar excepciones.
El bloque try define el alcance del manipulador de excepciones y debe ir acompanado de al menos un
bloque catch o el bloque finally.
try{
...
} catch (...) {
...
} catch (...) {
...
} ...
} finally {
...
}
}
Cuando existen varias sentencias del metodo que potencialmente pueden provocar una excepcion, hay
dos posibilidades:
(a) Agrupar todas las sentencias en un solo bloque try con varios bloques catch para responder a
cada una de las excepciones.
(b) Agrupar cada sentencia individual en un bloque try con su bloque catch correspondiente.
Cada bloque catch requiere un argumento que indica el tipo de excepcion que trata, este argumento
pertenece siempre a una subclase de la clase Throwable. Puede utilizarse el metodo getMessage() de
este argumento para mostrar informacion adicional sobre el error que provoco la excepcion.
69
3. El sistema busca el primer bloque catch cuyo tipo de excepcion se ajusta al de la que se ha
producido. La busqueda comienza en el mismo metodo en el que se produjo la excepcion y
continua por los metodos de los que provena la llamada.
5. Si existe bloque finally se ejecutan sus sentencias, en otro caso se da por concluida la ejecucion
del programa.
Solucion 1:
Solucion 2:
import java.io.*;
class Division{
public static void main(String args[]){
BufferedReader f;
float x,y;
try{
f=new BufferedReader
(new FileReader("Datos"));
x=new Float(f.readLine()).floatValue();
y=new Float(f.readLine()).floatValue();
System.out.println("Resultado = " + x/y);
} catch(Exception e){
System.err.
println("Error: "+ e.toString());
}
}
}
Declaracion de Excepciones
Ejemplo:
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;
La sentencia throw es utilizada implcitamente por el sistema cuando detecta algunos errores
estandar.
El programador puede utilizarla para lanzar sus propias excepciones de forma explcita.
Practica de Excepciones
Terminar de escribir el siguiente programa realizando el tratamiento de las excepciones. (Nota: No
olvidar introducir los argumentos para ejecutar la aplicacion. Hay que introducir los nombres de 2
ficheros.)
import java.io.*;
class LeerEscribir{
Solucion 1
import java.io.*;
class LeerEscribir1{
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{
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();
}
}
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.
eventSourceObject.
addEventListener(eventListenerObject);
Ejemplo:
El objeto es avisado cuando tiene lugar un suceso de accion en el boton, (presionar el boton, en este
caso).
Por tanto, la clase a la que pertenece el objeto (el receptor) debe implementar la interfase apropiada:
ActionListener, en este caso.
Para implementar ActionListener, la clase del receptor debe poseer un metodo (actionPerformed)
que recibe un objeto de la clase ActionEvent como parametro.
En el paquete java.awt.Event aparecen once interfases receptoras:
ActionListener KeyListener
AdjustmentListener MouseListener
ComponentListener MouseMotionListener
ContainerListener TextListener
FocusListener WindowListener
ItemListener
Volvamos al ejemplo de partida y veamos como cerrar la ventana. Para ello, en primer lugar
redefinimos la clase Marco1. Si queremos cerrar la ventana, el suceso que se va a crear es un objeto de
la clase WindowEvent.
marco.addWindowListener(x);
import java.awt.*;
import java.awt.event.*;
class Marco extends Frame
implements WindowListener{
public Marco(){
addWindowListener(this);
}
}
Pero implementar una interfase no es suficiente. Se deben implementar los metodos necesarios para
la interfase
WindowListener en la clase Marco. Nuestra clase debe implementar todos los metodos definidos en
la interfase WindowListener. Existen siete metodos. Java los llama como respuestas a siete sucesos
diferentes que pueden ocurrir en una ventana:
76
void windowClosed(WindowEvent e)
void windowIconified(WindowEvent e)
void windowOpened(WindowEvent e)
void windowClosing(WindowEvent e)
void windowDeiconified(WindowEvent e)
void windowActivated(WindowEvent e)
void windowDeactivated(WindowEvent e)
Ejemplo:
import java.awt.*;
import java.awt.event.*;
public class Marco extends Frame
implements WindowListener{
public Marco(){
setTitle("Marco");
setSize(300,300);
addWindowListener(this);
}
public void windowClosing(WindowEvent e){
System.exit(0);
}
public void windowClosed(WindowEvent e){}
public void windowIconified(WindowEvent e){}
public void windowOpened(WindowEvent e){}
public void windowDeiconified(WindowEvent e){}
public void windowActivated(WindowEvent e){}
public void windowDeactivated(WindowEvent e){}
Se han implementado seis metodos que no realizan ninguna accion. Simplifiquemos el programa
anterior.
Cada interfase receptora viene acompanada de una clase adaptadora que implementa todos los
metodos de la interfase pero no hace nada con ellos. Existe una clase adaptadora para cada una de las
siete interfases receptoras con mas de un metodo:
ComponentAdapter MouseAdapter
ContainerAdapter MouseMotionAdapter
FocusAdapter WindowAdapter
KeyAdapter
77
Ejemplo:
import java.awt.*;
import java.awt.event.*;
}
public static void main(String[] args){
MarcoSimplificado m=new MarcoSimplificado();
m.show();
}
}
Ejemplo:
import java.awt.*;
import java.awt.event.*;
}
public static void main(String[] args){
MarcoSimplificadoAltern m=
new MarcoSimplificadoAltern();
m.show();
}
}
78
Sucesos
La superclase que engloba todos los sucesos es la clase EventObject implementada en el paquete
java.util
Event
Object
AW T E v e n t
Key Mouse
Event Event
Esto sucede automaticamente una vez que se registra el receptor con la fuente.
A continuacion se muestra una lista con aquellos sucesos que pasan a los receptores:
Ejemplo 1
import java.awt.*;
import java.applet.Applet;
Ejemplo 2
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
Ejemplo 3
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
82
Ejemplo 4
import java.awt.*;
import java.applet.Applet;
83
import java.awt.event.*;
List mensajes;
Button boton;
Choice colores;
Label etiqueta1,etiqueta2,etiqueta3,etiqueta4;
TextField nombre;
TextArea acciones;
int x,y,w,h;
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);
}
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");
}
}
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
Una interfase para manejar los sucesos que ocurran sobre esa componente
Todas las componentes, excepto los menus, se implementan como subclases de la clase Component y
por tanto, heredan de esta todos los procedimientos, que son los que permiten darles funcionalidad en
un programa.
Cuando se crea una componente, esta se anade a un contenedor para lo cual se utiliza el metodo
add() definido en la clase Container.
Este metodo tiene las tres definiciones siguientes:
Algunos de los metodos definidos en la clase Component y que pueden ser utilizados por toda subclase
son:
Botones
La clase Button
public Button()
String getLabel()
Ejemplo:
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
Button a, b,c,d;
d.addActionListener(this);
setLayout(new GridLayout(2,2,10,10));
add(a);
add(b);
add(c);
add(d);
}
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
public Checkbox()
void setCheckboxGroup(CheckboxGroup g)
CheckboxGroup getCheckboxGroup()
String getLabel()
boolean getState()
91
void addItemListener(ItemListener l)
void removeItemListener(ItemListener l)
La clase CheckboxGroup
public CheckboxGroup()
Checkbox getSelectedCheckbox()
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;
f.addItemListener(this);
add(a);
add(b);
add(c);
add(d);
add(e);
add(f);
}
Canvas
Cuando se empieza a llenar una ventana con muchos elementos de interfase y multiples paneles, lo
mejor es no dibujar directamente sobre la superficie de la ventana puesto que el dibujo puede interferir
con las componentes que se han colocado en la ventana. Un Canvas es un area rectangular en la cual
se puede dibujar.
Ejemplo:
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
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()
addTextListener(TextListener tl)
La clase TextArea
public TextArea()
TextArea.SCROLLBARS BOTH
TextArea.SCROLLBARS NONE
int getColumns()
int getRows()
La clase TextField
Un campo de texto es una componente con una unica lnea de texto editable.
Los constructores de un campo de texto son:
public TextField()
Ejemplo
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
Etiquetas
public Label()
96
public Frame()
MenuBar getMenuBar()
String getTitle()
Menus
Existen las siguientes clases que permiten construir menus y barras de menus:
MenuItem
Los objetos MenuItem representan las opciones de un menu.
CheckboxMenuItem
Subclase de MenuItem. Estos objetos hacen referencia a las opciones que actuan como
botones de marca.
Menu
Subclase de MenuItem. Los menus se representan mediante los objetos de tipo Menu, que
solo existen en barras de menu.
MenuBar
Hace referencia al menu principal. Las barras de menu estan ligadas unicamente a los
contenedores de tipo Frame.
La clase MenuItem
public MenuItem()
String getLabel()
boolean isEnabled()
void setEnabled(boolean b)
MenuShorcut getShortcut()
void setShortcut(MenuShortcut s)
void getActionCommand()
La clase Menu
public Menu()
int getItemCount()
void addSeparator()
void removeAll()
La clase MenuBar
public MenuBar()
Menu add(Menu m)
int getMenuCount()
Menu getMenu(int i)
La clase CheckboxMenuItem
public CheckboxMenuItem()
boolean getState()
void setState(boolean b)
void addItemListener(ItemListener l)
La clase MenuShortcut
int getKey()
boolean useShiftModifier()
Ejemplo:
import java.awt.*;
import java.awt.event.*;
public Menus() {
barra = new MenuBar();
setMenuBar(barra);
m1 = new Menu("Menu1");
barra.add(m1);
m2 = new Menu("Menu2");
barra.add(m2);
menus.setSize(200,200);
menus.setVisible(true);
}
}
Elecciones
La clase Choice construye menus de tipo flotante. El constructor de esta clase es:
public Choice()
La primera opcion que se anade al menu se considera como la opcion seleccionada por defecto, hasta
que el usuario elija otra.
Entre los metodos de la clase Choice destacan:
Ejemplo:
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
Ejercicio:
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
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()
String getSelectedItem ()
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
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
106
total=d1*d2;
t3.setText(Double.toString(total));
ta.append("La operacion realizada ha sido
un producto"+"\n");
}else if(str=="Divisi\on"){
total=d1/d2;
t3.setText(Double.toString(total));
ta.append("La operacion realizada ha sido
una divisi\on"+"\n");
}
}
}
Cuadros de Dialogo
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.
Ejemplo:
import java.awt.*;
import java.awt.event.*;
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);
}});
}
TextField campo;
VentanaDialog parent;
Button b1;
setSize(600,100);
}
Criterios de Colocacion
Criterio BorderLayout
BorderLayout es el gestor de colocacion por defecto para todas las ventanas(Windows), tales como
marcos (Frames) y dialogos (Dialogs).
Utiliza cinco areas: norte, sur, este, oeste y centro.
Todo el espacio extra se coloca en el area del centro.
La clase BorderLayout posee los constructores:
110
public BorderLayout()
import java.awt.*;
import java.applet.Applet;
Criterio CardLayout
Se utiliza la disposicion CardLayout cuando se tiene una zona que puede contener diferentes com-
ponentes en diferentes instantes.
Para anadir y mostrar una componente se utilizan los metodos:
add(String name, Component comp)
Con el primer argumento se identifica la componente que se esta anadiendo.
Panel cl;
final String MES1 = "Panel1 con tres botones ";
final String MES2 = "Panel2 con tres botones";
final String MES3 = "Panel3 con tres botones";
cl = new Panel();
cl.setLayout(new CardLayout());
cl.add(MES1, panel1);
cl.add(MES2, panel2);
cl.add(MES3, panel3);
add(cl);
}
Criterio FlowLayout
FlowLayout es el gestor de colocacion por defecto para los paneles (Panels). Coloca sus componentes
en una fila.
La clase FlowLayout tiene tres constructores:
public FlowLayout();
1. FlowLayout.LEFT
2. FlowLayout.CENTER
3. FlowLayout.RIGHT.
113
Ejemplo:
import java.awt.*;
import java.applet.Applet;
Criterio GridLayout
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;
Label lab;
Paquete javax.swing
apariencia mejorada
mayor control por parte del programador sobre el aspecto y funcionamiento de la interfaz.
Se incorporan todos los aspectos utiles de Awt. En algunos casos se han extendido las clases o
implementado interfases de Awt.
Swing forma parte de las cinco libreras que constituyen las JFC (Java Foundation Classes), que
facilitan la creacion de interfaces graficas de usuario (GUIs). Engloban las siguientes caractersticas:
Awt
Java 2DT M API: es posible incorporar graficos en dos dimensiones de elevada calidad, texto e
imagenes en aplicaciones y applets.
Se pueden implementar elementos que transfieren informacion entre aplicaciones Java y aplica-
ciones nativas.
se pueden agregar o cambiar los bordes de casi todas las 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:
Swing vs Awt
Ejemplo Awt
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
Ejemplo Swing
//clase Container
import java.awt.*;
//clase ActionEvent
import java.awt.event.*;
//componentes de Swing y JApplet
import javax.swing.*;
Principales diferencias:
Para cada elemento de Awt existe un equivalente en Swing. El nombre es el mismo precedido de
la letra J.
En Awt, los componentes se pueden colocar directamente sobre el applet, con el metodo add. En
Swing, el JApplet no actua como contenedor de sus componentes; contiene un objeto Container,
panel de contenido, en el cual se colocan todos los componentes del applet con el metodo add. Se
puede obtener referencia de dicho panel usando el metodo getContentPane de la clase JApplet.
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:
son contenedores Swing de alto nivel y, por tanto, tienen un panel raz, que permite agregar una
barra de menus.
Funcionamiento:
Si el navegador reconoce las clases Swing, se puede usar una <APPLET> tag. En caso contrario,
es necesario un Java plug-in. Por lo que es necesario incluir un <OBJECT> o <EMBED> tag.
Se puede bajar una herramienta gratis que genera automaticamente los tags necesarios. Para obten-
erla junto con el Plug-in:
http://java.sun.com/products/plugin/.
Requiere tiempo bajarse el Plug-in, por lo que es aconsejable avisar a los posibles usuarios de que
la pagina contiene un applet.
Metodos nuevos que incorpora la clase JApplet:
JRootPane createRootPane():Es llamado por el constructor para crear el rootPane por defecto.
Contenedores y Componentes
Todos los elementos que configuran una interfaz grafica de usuario en Swing se pueden clasificar en:
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 revalidate()
Ejemplo:
import java.awt.*;
import javax.swing.*;
JPanel panel;
contenedor.add(panel);
}
}
contenedor superior: en nuestro caso es un applet (JApplet). Tambien contamos con las ventanas
de dialogo (JDialog) y los marcos (JFrame).
Pero todo contenedor de alto nivel contiene un panel de contenido que alberga todos los componentes
visibles de la interfaz, salvo las barras de menu.
Veamos a continuacion ejemplos ilustrativos de algunos contenedores.
Paneles divididos
Un objeto de la clase JSplitPane esta formado por dos componentes separados por una barra divisoria
que puede manipularse con el raton.
El procedimiento es colocar cada componente en un panel desplazable que, a su vez, se incluye en
el panel dividido.
Ejemplo:
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
120
lista=new JList(titulos);
lista.setSelectionMode(
ListSelectionModel.SINGLE_SELECTION);
lista.setSelectedIndex(0);
lista.addListSelectionListener(this);
ImageIcon foto1=
new ImageIcon("Fotos/"+titulos[0]);
foto=new JLabel(foto1);
foto.setPreferredSize(
new Dimension(foto1.getIconWidth(),
foto1.getIconHeight()));
panel=
new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,pd1,pd2);
panel.setOneTouchExpandable(true);
panel.setDividerLocation(150);
panel.setPreferredSize(new Dimension(400,200));
contenedor.add(panel);
}
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)
JSplitPane.HORIZONTAL_SPLIT
JSplitPane.VERTICAL_SPLIT
Metodos
Componentes Basicos
Menus desplegables.
Los objetos de la clase JComboBox pueden ser editables o no editables. Por defecto son no editables.
Los editables tienen la apariencia de un campo de texto.
Ejemplo:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
Container contenedor=getContentPane();
String[] titulos=
{"foto1.gif","foto2.gif","foto3.gif"};
Constructores:
public JComboBox()
public JComboBox(ComboBoxModel aModel)
public JComboBox(Object[] items)
public JComboBox(Vector items)
Metodos:
Tablas
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
{"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"}
};
if (DEBUG) {
tabla.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
imprimirDatos(tabla);
}
});
}
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("-----");
}
}
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
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;
accionEtiqueta =
new JLabel("Escribe y dale Return en un campo");
accionEtiqueta.setBorder(
127
BorderFactory.createEmptyBorder(10,0,0,0));
panel.setLayout(gridbag);
JLabel[] etiquetas =
{campoTextoEtiqueta , passwordEtiqueta};
JTextField[] campos = {campoTexto , password};
ponerEtiquetas(etiquetas, campos, gridbag, panel);
c.gridwidth = GridBagConstraints.REMAINDER;
c.anchor = GridBagConstraints.WEST;
c.weightx = 1.0;
gridbag.setConstraints(accionEtiqueta, c);
panel.add(accionEtiqueta);
panel.setBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Campos de texto"),
BorderFactory.createEmptyBorder(5,5,5,5)));
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)));
c.gridwidth = GridBagConstraints.REMAINDER;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1.0;
gridbag.setConstraints(ct[i], c);
cont.add(ct[i]);
}
}
return editorPane;
}
String[] initStyles =
{ "italic", "bold", "small", "large",
"regular", "button", "icon", "regular",
"regular"
};
initStylesForTextPane(textPane);
try {
for (int i=0; i < initString.length; i++) {
doc.insertString(
doc.getLength(), initString[i],
textPane.getStyle(initStyles[i]));
}
131
return textPane;
}
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
void setDisabledTextColor(Color c)
void setMargin(Insets m)
void setEditable(boolean b)
String getSelectedText()
void selectAll()
void select(int selectionStart,
int selectionEnd)
void setSelectedTextColor(Color c)
void setSelectionColor(Color c)
void cut()
void copy()
void paste()
Ayuda
Se puede crear un pequeno menu de ayuda para cualquier objeto de la clase JComponent
Ejemplo:
import java.awt.*;
import javax.swing.*;
new ImageIcon("Imagenes/right.gif"),
p2,"Aparece un campo de texto");
contenedor.add(panel,BorderLayout.CENTER);
}
}
Criterios de Colocacion
Todo contenedor posee un criterio de colocacion por defecto. Los cinco mas usados son: BorderLayout,
BoxLayout, FlowLayout, GridBagLayout y GridLayout.
BorderLayout: es la disposicion por defecto de todo panel de contenido, (el contenedor principal
de los marcos, applets y ventanas de dialogo). Se dispone de cinco areas: norte, sur, este, oeste y
centro. El espacio extra ocupa el centro del area.
BoxLayout: coloca los componentes en una sola fila o columna. Respeta las medidas maximas
requeridas de los componentes y permite alinearlos.
FlowLayout: es la disposicion por defecto de los jpaneles. Coloca los componentes uno detras
de otro, de izquierda a derecha.
GridBagLayout: agrupa los componentes en una red de celdas, permitiendo que tengan dife-
rentes dimensiones.
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.*;
BoxLayout
Se agrupan los componentes uno sobre otro, comenzando en la parte superior de la ventana, o en
fila, de izquierda a derecha.
A diferencia del resto de disposiciones de Awt, la BoxLayout respeta el tamano maximo y la alin-
eacion de cada componente.
Constructor:
public BoxLayout(Container,int)
Metodos:
Component createRigidArea(Dimension)
Component createHorizontalGlue()
Component createVerticalGlue
Ejemplo:
Ejemplo:
import java.awt.*;
import javax.swing.*;
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);
}
}
Separamos la etiqueta y el panel desplazable con un area rgida, que permite agregar espacio entre
componentes. En este caso, no tiene anchura y fija cinco pixels entre ambas componentes. De forma
analoga ocurre con los botones.
Para desplazar los botones a la derecha de su contenedor, la primera componente que se anade es lo
que se conoce como pegamento: una componente invisible que crece lo necesario para absorber cualquier
espacio extra en su contenedor.
Como alternativa a las componentes invisibles, se pueden usar bordes vacos para crear espacios
alrededor de las componentes.
Componentes invisibles
En una disposicion BoxLayout es conveniente anadir espacio entre las componentes. Una opcion es
insertar componentes invisibles, con la ayuda de la clase Box.
area rgida: para insertar un espacio de tamano fijo entre dos componentes. Para anadir 5 pixels
entre dos componentes dispuestas en horizontal:
contenedor.add(primeraComponente);
contenedor.add(Box.createRigidArea(new Dimension(5,0)));
contenedor.add(segundaComponente);
pegamento: para especificar que exceso de espacio debera desaparecer. Por ejemplo, para que en
una disposicion en horizontal el espacio extra dejado por dos componentes no quede a la derecha
si no en el centro:
contenedor.add(primeraComponente);
contenedor.add(Box.createHorizontalGlue());
contenedor.add(segundaComponente);
Problemas de alineacion
137
import java.awt.*;
import javax.swing.*;
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.*;
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.*;
p=new JPanel();
p.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(Color.red),
p.getBorder()));
contenedor.add(p);
}
}
Ejemplo:
import java.awt.*;
import javax.swing.*;
contenedor.setLayout(
new BoxLayout(contenedor,BoxLayout.Y_AXIS));
p=new JPanel();
p.setBorder(BorderFactory.
createCompoundBorder(
BorderFactory.createLineBorder(Color.red),
p.getBorder()));
p.setAlignmentX(LEFT_ALIGNMENT);
contenedor.add(p);
}
}
Por defecto, la mayora de las componentes poseen alineacion en el centro para X e Y. Sin embargo, los
botones, combo boxes, etiquetas y opciones de menu poseen para X la alineacion izquierda.
agregar un borde a las componentes en cuestion. Esto permite apreciar que tamano realmente
tienen:
componente.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(Color.red),
componente.getBorder()));
Usar el System.out.println para imprimir los tamanos maximo, mnimo y preferible de las
componentes.
componente.setMinimumSize(new Dimension(50,25));
componente.setPreferredSize(new Dimension(50,25));
componente.setMaximumSize(new Dimension(
Short.MAX_VALUE,Short.MAX_VALUE));
140
CardLayout
Permite manejar dos o mas componentes, (normalmente objetos de la clase JPanel) que comparten un
mismo espacio. Una opcion es usar un panel con solapas.
Ejemplo 1
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
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());
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.*;
panel.addTab(BOTONES,p1);
contenedor.add(panel,BorderLayout.CENTER);
}
}
FlowLayout
Ejemplo:
import java.awt.*;
import javax.swing.*;
}
}
GridLayout
Ejemplo:
import java.awt.*;
import javax.swing.*;
GridBagLayout
Ejemplo:
import java.awt.*;
import javax.swing.*;
//c.fill=GridBagConstraints.BOTH;
//c.weightx=1.0;
colocaBoton("Boton 1",gridbag,c,contenedor);
colocaBoton("Boton 2",gridbag,c,contenedor);
//c.gridx=0;
colocaBoton("Boton 3",gridbag,c,contenedor);
//c.gridx=GridBagConstraints.RELATIVE;
143
c.gridwidth=GridBagConstraints.REMAINDER;
colocaBoton("Boton 4",gridbag,c,contenedor);
//c.weightx=0.0;
colocaBoton("Boton 5",gridbag,c,contenedor);
c.gridwidth=GridBagConstraints.RELATIVE;
colocaBoton("Boton 6",gridbag,c,contenedor);
c.gridwidth=GridBagConstraints.REMAINDER;
colocaBoton("Boton 7",gridbag,c,contenedor);
c.gridwidth=1;
c.gridheight=2;
//c.weighty=1.0;
colocaBoton("Boton 8",gridbag,c,contenedor);
//c.weighty=0.0;
c.gridwidth=GridBagConstraints.REMAINDER;
c.gridheight=1;
colocaBoton("Boton 9",gridbag,c,contenedor);
colocaBoton("Boton 10",gridbag,c,contenedor);
}
public void colocaBoton(String nombre,
GridBagLayout gridbag,GridBagConstraints c,
Container contenedor){
JButton boton=new JButton(nombre);
gridbag.setConstraints(boton,c);
contenedor.add(boton);
}
}
Acciones
Si dos o mas componentes realizan la misma accion, es conveniente usar un objeto de la interfase Action
del paquete
javax.swing, que extiende ActionListener. Esta interfase centraliza el manejo de texto, iconos y
botones de barras de herramientas y menus.
El primer ejemplo muestra la forma tradicional de implementar una interfaz formada por un area
de texto, una barra de menus y una barra de botones. La accion de seleccionar una opcion del primer
menu o pulsar un boton de la barra se ve reflejada en el area de texto. Seleciconar una opcion del
segundo menu activa o desactiva un boton o una opcion del primer menu.
El segundo ejemplo utiliza la interfase Action para centralizar la gestion de la accion pulsar o
seleccionar opcion o boton.
Ejemplo:
import javax.swing.*;
144
import java.awt.*;
import java.awt.event.*;
m11.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
areaTexto.append(
"AccionEvent en: "
+ "primera opcion"
+ "\n"
+ " Event source: " + e.getSource()
+ "\n");
}
});
m12.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
areaTexto.append(
"AccionEvent en: "
+ "segunda opcion"
+ "\n"
+ " Event source: " + e.getSource()
+ "\n");
}
});
m13.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
areaTexto.append(
"AccionEvent en: "
+ "tercera opcion"
+ "\n"
+ " Event source: " + e.getSource()
+ "\n");
}
});
menuPrincipal.add(m11);
menuPrincipal.add(m12);
menuPrincipal.add(m13);
JCheckBoxMenuItem m21=
new JCheckBoxMenuItem("Primera accion");
m21.setSelected(true);
JCheckBoxMenuItem m22=
146
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.*;
+ "segundo boton/item"
+ "\n"
+ " Event source: " + e.getSource()
+ "\n");
}
};
boton=barra.add(accCentr);
boton.setText("");
m=menuPrincipal.add(accCentr);
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();
}
return estado;
}
}
Bordes
import java.awt.*;
import javax.swing.*;
Podemos implementar nuestros propios bordes. Deberemos crear una subclase de AbstractBorder
e jmplementar los metodos paintBorder y getBorderInsets.
Tambien es posible anadir un borde adicional alrededor de una componente ya enmarcada. Por
ejemplo, crear espacio extra alrededor de una componente.
Ejemplo:
import java.awt.*;
import javax.swing.*;
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 createEtchedBorder()
Border createEtchedBorder(Color highlight,
Color shadow)
Border createLoweredBevelBorder()
Border createRaisedBevelBorder()
Border createEmptyBorder()
Border createEmptyBorder(int top,int left,
int bottom,int right)
CompoundBorder createCompoundBorder(Border
outsideBorder,Border insiderBorder)
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.*;
Graficos en Java
Dentro del paquete java.awt se encuentra definida la clase Graphics, que incorpora al lenguaje
Java la posibilidad de anadir elementos graficos.
Principios basicos
Al iniciar la ejecucion del programa, el sistema se encarga de visualizar graficamente todas las
componentes de su interfase.
La manera mas simple de dibujar una componente es insertar el codigo de dibujo en su metodo
paint().
El metodo paint() recibe como unico argumento un objeto de tipo Graphics (contexto grafico).
Estos objetos soportan dos tipos de procesos de dibujo:
Cada componente tiene su propio sistema de coordenadas referidas a la esquina superior izquierda
de su area de dibujo.
Para las operaciones graficas sobre una componente se tiene en cuenta su sistema de coordenadas.
Primitivas Graficas
La clase Graphics es una clase abstracta que dispone de metodos para dibujar lneas, rectangulos,
rectangulos redondeados, ovalos, arcos, polgonos, texto...
Lneas
Rectangulos
Dibuja un rectangulo cuya esquina superior izquierda esta en el punto de coordenadas (x,y)
con las dimensiones en puntos especificadas.
Ejemplo:
import java.awt.*;
import java.applet.*;
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 void
fill3DRect (int x, int y, int ancho,
int alto, boolean elev)
Borra el area especificada por el rectangulo, rellenandola con el color del fondo de la com-
ponente.
Ovalos
Arcos
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.
Polgonos
Dibuja un polgono cerrado uniendo los n puntos cuyas coordenadas son (x[i],y[i]).
Ejemplo:
import java.applet.*;
import java.awt.*;
int polyg1_x[]={40,80,0,40};
int polyg1_y[]={5,45,45,5};
int polyg2_x[]={140,180,180,140,100,100,140};
int polyg2_y[]={5,25,45,65,45,25,5};
int polyg3_x[]={240,260,220,260,220,240};
int polyg3_y[]={5,65,85,25,25,5};
El punto de posicionamiento del texto es el de inicio de la lnea de base sobre la que se apoya.
public void
drawBytes (byte datos[], int offset, int l,
int x, int y)
Dibuja el texto dado en la matriz de bytes con el tipo y color vigente en la posicion dada
por el punto (x,y). El parametro l indica el numero de caracteres a dibujar y offset es el
ndice de la matriz correspondiente al primer caracter a dibujar.
public void
drawChars (char datos[], int offset, int l,
int x, int y)
Metodos para gestionar los tipos de letra y aspectos metricos del texto:
public abstract Font getFont ()
Devuelve un objeto de la clase Font con la informacion del tipo de letra vigente en el contexto
grafico.
Devuelve un objeto de la clase FontMetrics con la informacion de tipo metrico del tipo de
letra vigente del contexto grafico.
Devuelve un objeto de la clase FontMetrics con la informacion del tipo de fuente especifi-
cado en el parametro f.
Ejemplo:
import java.awt.*;
import java.applet.*;
Todas las operaciones graficas que se realicen sobre un contexto grafico unicamente tienen
efecto si quedan dentro de una cierta region rectangular. Este metodo permite establecer
esta region.
Efectua una copia del area rectangular. El vector de desplazamiento del area es (dx,dy).
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.
Efectua la llamada al metodo dispose() cuando el contexto grafico no vuelve a ser utilizado.
A partir de ese momento, cuando se realice una operacion grafica, los puntos que se encuen-
tren en el color actual del contexto cambiaran al color c y viceversa.
162
import java.awt.*;
import java.applet.*;
Ejemplo de Utilizacion de
Primitivas Graficas
import java.awt.*;
import java.applet.Applet;
g.fillRect(20,0,ancho,5);
g.drawString("ESTADIO JAVA",ancho/2-10,17);
g.translate(20,20);
g.drawRect(0, 0, ancho, alto);
g.drawLine(ancho/2, 0, ancho/2, alto);
g.fillOval(ancho/2-2, alto/2-2, 4, 4);
g.drawOval(ancho/2-alto/6, alto/3, alto/3,
alto/3);
g.drawRect(0, alto/4, ancho/6, alto/2);
g.drawRect(0, 2*alto/5, ancho/15, alto/5);
g.drawArc(ancho/6-alto/10,2*alto/5,alto/5,
alto/5,-90,180);
g.drawRect(ancho-ancho/6, alto/4,
ancho/6, alto/2);
g.drawRect(14*ancho/15, 2*alto/5,
ancho/15, alto/5);
g.drawArc(5*ancho/6-alto/10,2*alto/5,
alto/5, alto/5,90,180);
}
}
Uso de Imagenes
Para el uso de imagenes Java dispone de varias clases repartidas por los paquetes java.applet,
java.awt y
java.awt.image.
Las imagenes deben encontrarse en ficheros con formato GIF o JPEG.
Las imagenes deben ser cargadas con los metodos definidos para ello en las clases Applet o
Toolkit.
Una vez cargada, toda imagen es representada mediante un objeto de la clase Image.
Para que la imagen sea visualizada es preciso dar la orden correspondiente.
164
La llamada a estos metodos solo puede hacerse en un applet y siempre dentro de un metodo
y no dentro de un constructor.
Estas dos variantes pueden ser usadas tanto por applets como por aplicaciones. Para obtener
un objeto de la clase Toolkit puede utilizarse el metodo getDefaultToolkit() de la propia
clase Toolkit, o el metodo getToolkit() de la propia componente.
Visualizacion de imagenes
Observaciones:
El metodo drawImage() devuelve una variable boolean que indica si el proceso de dibujo ha sido
realizado correctamente.
El objeto que actua de observador debe pertenecer a una clase que implemente la interfase
ImageObserver. La clase Component implementa dicha interfase, es por eso que normalmente
se utiliza la propia componente (this) como observador de la imagen.
Cuando a una imagen se le asocia un observador, cualquier informacion disponible sobre la imagen
provoca la llamada al metodo imageUpdate() del observador.
Ejemplo:
import java.awt.*;
import java.applet.Applet;
public class Figura extends Applet
{
Image fondo, fig;
public void init () {
fondo = getImage(getDocumentBase(),
"Fondo.gif");
fig = getImage(getDocumentBase(),"Logo.gif");
}
public void paint( Graphics g ) {
int ancho, alto;
Dimension d = getSize();
ancho = fig.getWidth(this);
alto = fig.getHeight(this);
g.drawImage(fondo, 0, 0, d.width, d.height,
this);
g.drawImage(fig,(d.width-ancho)/2,
(d.height-alto-20)/2,this);
}
}
Imagenes Off-screen
Los pasos a seguir para crear y visualizar imagenes off-screen son los siguientes:
166
Ejemplo:
import java.awt.*;
import java.applet.Applet;
Manipulando Imagenes
Uso de Filtros
Toda imagen lleva asociados dos objetos importantes:
Productor: Crea todos los datos que el sistema necesita para visualizar la imagen y se los pasa al
consumidor. Debe ser un objeto que implemente la interfase ImageProducer.
Consumidor: Produce la visualizacion. Debe ser un objeto que implemente la interfase ImageConsumer.
Un filtro es un objeto de la clase ImageFilter que intercepta y modifica los datos que el productor
enva al consumidor.
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;
Va Internet pueden obtenerse filtros para manipular imagenes (por ejemplo el filtro RotateFilter).
CropImageFilter: se utiliza para obtener una nueva imagen formada por una parte rectan-
gular de la imagen inicial. Para utilizar este filtro no es necesario crear una subclase de la
CropImageFilter, se puede utilizar su constructor:
CropImageFilter(int x,int y,int width,int height) Construye un objeto CropImageFilter
que extrae la region rectangular indicada en pixels, de la imagen dada.
RGBImageFilter: sirve para modificar el color o la transparencia de todos los puntos de la
imagen. Para utilizar este filtro se crea una subclase de la clase RGBImageFilter y se redefine
el metodo
169
public int filterRGB(int x, int y, int argb) Este metodo debe ser implementado por toda
subclase de la clase RGBImageFilter. En este metodo se convierte cada pixel de entrada
(modelo de color RGB), en un pixel de salida.
El programador puede crear sus propios filtros creando subclases de la clase ImageFilter definida
dentro del paquete java.awt.image.
Ejemplo:
import java.awt.*;
import java.awt.image.ImageFilter.*;
import java.awt.image.*;
import java.applet.Applet;
Ejemplo:
import java.awt.*;
import java.awt.image.*;
import java.applet.Applet;
32 bits
TT RR VV AA
32 24 16 8 0
0xTTRRVVAA
La clase MemoryImageSource
Esta clase produce una imagen desde un array de enteros. Un objeto MemoryImageSource es un
productor, se puede obtener la imagen utilizando el metodo createImage de la clase Component o
Toolkit.
El constructor de esta clase es:
Ejemplo:
import java.applet.*;
import java.awt.*;
import java.awt.image.*;
0xFF007F7F,0,0xFF007F7F,0,
0,0xFFFF00FF,0xFFFF00FF,0,0,
0,0xFF007F7F,0,0};
La clase PixelGrabber
Esta clase permite obtener los pixels de una imagen y colocarlos en un array.
Uno de los constructores de esta clase es:
public PixelGrabber(Image image,int x,int y,
int width,int height,boolean forceRGB)
Algunos de los metodos de esta clase son:
boolean grabPixels()
int getWidth()
int getHeight()
Object getPixels()
Ejemplo:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
public 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);
}
Utilizacion de colores
El tratamiento del color en los procesos graficos se realiza por medio de la clase Color definida en
el paquete java.awt.
Todo color se identifica mediante su formato RGB que consta de tres valores enteros en el rango
comprendido entre 0 y 255, cada valor representa la contribucion de cada uno de los tres colores
primarios (rojo, verde y azul).
Crea un color como combinacion de los tres colores primarios. Cada argumento es un numero
entero entre 0 y 255.
Crea un color como combinacion de los tres colores primarios. Cada argumento es un numero
entre 0.0 y 1.0.
Devuelve una version mas brillante del color sobre el que se hace la llamada al metodo.
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.
Crea un color a partir de su matiz, saturacion y brillo (formato HSB). Cada una de las tres
componentes debe ser un numero de tipo float entre 0.0 y 1.0.
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;
Tipos de Letra
La clase Font
La clase Font se utiliza para representar las diferentes fuentes de letra con sus diferentes estilos.
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:
Constructor de la clase:
public Font (String nom, int est, int tam)
Para obtener una matriz con los nombres de los tipos de letra disponibles puede usarse el metodo
getFontList() de la clase Toolkit.
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
El argumento n es tratado como el nombre de una propiedad del sistema. El valor de esta
propiedad debera ser de una de las formas siguientes:
nombre-estilo-tamano
nombre-tamano
nombre-estilo
nombre
Igual que el metodo anterior, con la unica diferencia de devolver el tipo de letra f si no se
encuentra la propiedad indicada.
Devuelve una representacion del tipo de letra en forma de una cadena de caracteres.
Ejemplo:
179
import java.awt.*;
import java.applet.Applet;
Lnea superior
a
b
Programacin en Lnea de base
Lnea inferior
d
c Lnea superior
Lnea superior : la que indica la altura maxima que pueden alcanzar los caracteres de la fuente.
Lnea inferior : indica la distancia maxima que los caracteres pueden descender por debajo de la
lnea de base. Por ejemplo, un caracter como la p, aunque se apoye en la lnea de base, parte de
el quedara por debajo de la misma.
Para obtener las diferentes distancias entre las lneas, la clase FontMetrics dispone de los siguientes
metodos:
public int getAscent ()
Determina la distancia entre las lneas de base de dos lneas consecutivas de texto (distancia
c en la Figura).
Determina la distancia entre la lnea inferior del texto y la superior de la siguiente (distancia
d en la Figura).
Cada caracter tiene ademas una anchura que influye en la posicion del siguiente caracter, ya que si
un caracter tiene una anchura a y se coloca en la posicion (x, y), el caracter siguiente debe ir colocado
en la posicion (x + a, y). Para medir esas anchuras, la clase FontMetrics dispone de varios metodos.
Logicamente, esas distancias dependen del tipo de letra asociado:
public int bytesWidth (byte data[], int inicio,
int longitud)
181
Devuelve una matriz con la anchura de los primeros 256 caracteres en el tipo asociado.
Determina la longitud maxima a la que un caracter puede llegar por encima de la lnea de
base en el correspondiente tipo de letra.
Determina la longitud maxima a la que un caracter puede descender por debajo de la lnea
de base en el correspondiente tipo de letra.
Ejemplo
import java.awt.*;
import java.applet.*;
int longitud=getFontMetrics(f1).stringWidth(str);
g.drawString(str,5,30);
g.drawLine(5,
30+getFontMetrics(f1).getDescent(),5+longitud,
30+getFontMetrics(f1).getDescent());
g.drawLine(5,
30-getFontMetrics(f1).getAscent(),5+longitud,
30-getFontMetrics(f1).getAscent());
g.drawLine(5,30,5+longitud,30);
}
}
Practica 1
import java.applet.*;
import java.awt.event.*;
import java.util.*;
import java.awt.*;
class Circulo{
static public final int r=20;
Color color=Color.red;
int x,y;
void draw(Graphics g){
g.setColor(color);
g.fillOval(x-r,y-r,2*r,2*r);
}
Practica 2
import java.applet.*;
import java.awt.event.*;
import java.util.*;
import java.awt.*;
s.draw(g);
}
}
public void mouseClicked(MouseEvent e){
Circulo s;
s=new Circulo();
s.x=e.getX(); s.y=e.getY();
vectorFiguras.addElement(s);
repaint();
}
public void mouseReleased(MouseEvent e){
Circulo s=new Circulo();
s.x=e.getX();
s.y=e.getY();
if(e.getComponent()==c)
s.draw(gra1);
else
s.draw(gra2);
}
public void mouseExited(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mousePressed(MouseEvent e){}
}
class Circulo{
static public final int r=20;
Color color=Color.red;
int x,y;
void draw(Graphics g){
g.setColor(color);
g.fillOval(x-r,y-r,2*r,2*r);
}
Practica 3
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();
}
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);
}
}
Practica 4
import java.applet.*;
import java.awt.event.*;
import java.util.*;
import java.awt.*;
}
public void paint(Graphics g){
Circulo s;
int numFiguras;
numFiguras=vectorFiguras.size();
for(int i=0;i<numFiguras;i++){
s=(Circulo)vectorFiguras.elementAt(i);
s.draw(g);
}
}
public void mouseClicked(MouseEvent e){
Circulo s;
s=new Circulo();
s.x=e.getX(); s.y=e.getY();
vectorFiguras.addElement(s);
repaint();
}
public void mouseReleased(MouseEvent e){
Circulo s=new Circulo();
s.x=e.getX();
s.y=e.getY();
if(e.getComponent()==c)
s.draw(gra1);
else
s.draw(gra2);
}
public void mouseExited(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mousePressed(MouseEvent e){}
} class Circulo{
static public final int r=20;
Color color=Color.red;
int x,y;
void draw(Graphics g){
g.setColor(color);
g.fillOval(x-r,y-r,2*r,2*r);
}
}
188
Graficos 2-D
En la version 1.2 de Java se incluyen paquetes que permiten trabajar con graficos en 2-D, ademas
tambien aparecen paquetes que extienden las posibilidades de trabajo con texto como entidad grafica
y con imagenes.
En la Java 2D API, se pueden encontrar paquetes nuevos como:
java.awt.color
java.awt.font
java.awt.print
Ademas, en los paquetes java.awt y java.awt.image se han incluido nuevas clases que permiten
trabajar en 2D.
java.awt
java.awt.AlphaComposite
java.awt.BasicStroke
java.awt.Color
java.awt.Composite
java.awt.CompositeContext
java.awt.Font
java.awt.GradientPaint
java.awt.Graphics2D
java.awt.GraphicsConfiguration
java.awt.GraphicsDevice
java.awt.GraphicsEnvironment
java.awt.Paint
java.awt.PaintContext
java.awt.Rectangle
java.awt.Shape
java.awt.Stroke
java.awt.TexturePaint
java.awt.Toolkit
java.awt.Transparency
189
java.awt.image
java.awt.image.AffineTransformOp
java.awt.image.BandCombineOp
java.awt.image.BandedSampleModel
java.awt.image.BufferedImage
java.awt.image.BufferedImageFilter
java.awt.image.BufferedImageOp
java.awt.image.ByteLookupTable
java.awt.image.ColorConvertOp
java.awt.image.ColorModel
java.awt.image.ComponentColorModel
java.awt.image.ComponentSampleModel
java.awt.image.ConvolveOp
java.awt.image.DataBuffer
java.awt.image.DataBufferByte
java.awt.image.DataBufferInt
java.awt.image.DataBufferShort
java.awt.image.DirectColorModel
java.awt.image.IndexColorModel
java.awt.image.Kernel
java.awt.image.LookupOp
java.awt.image.LookupTable
java.awt.image.MultiPixelPackedSampleModel
java.awt.image.PackedColorModel
java.awt.image.Raster
java.awt.image.RasterformatException
java.awt.image.RasterOp
java.awt.image.RenderedImage
java.awt.image.RescaleOp
java.awt.image.SampleModel
java.awt.image.ShortLookupTable
java.awt.image.SinglePixelPackedSampleModel
java.awt.image.WritableRaster
A continuacion se presenta una coleccion de ejemplos donde se muestran algunas de estas posibili-
dades.
190
import java.awt.*;
import java.awt.geom.*;
import java.applet.*;
Ejemplo:
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
Ellipse2D.Double circle =
new Ellipse2D.Double(10, 10, 350, 350);
Rectangle2D.Double square =
new Rectangle2D.Double(10, 10, 350, 350);
void clear(Graphics g) {
super.paintComponent(g);
}
jf.setVisible(true);
}
}
Ejemplo:
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
public class RotationExample1 extends JPanel {
void clear(Graphics g) {
super.paintComponent(g);
}
obj.setBackground(Color.white);
jf.setSize(200, 200);
jf.setContentPane(obj);
jf.setVisible(true);
}
}
import java.awt.*;
Ejemplo:
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
public FontExample1() {
GraphicsEnvironment env =GraphicsEnvironment.getLocalGraphicsEnvironment();
env.getAvailableFontFamilyNames();
setFont(new Font("Goudy Handtooled BT",
Font.PLAIN, 100));
}
void clear(Graphics g) {
super.paintComponent(g);
}
Ejemplo:
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
void clear(Graphics g) {
super.paintComponent(g);
}
Un proceso ligero es una parte de codigo o miniprograma que puede ser ejecutada independien-
temente, de forma que una aplicacion o un applet puede tener varios procesos ligeros ejecutandose
simultaneamente y efectuando diferentes tareas.
Esto constituye una alternativa a los programas secuenciales en los que existe un principio, una
secuencia de instrucciones y un final, habiendo en cada instante un unico punto de ejecucion.
Los procesos ligeros, a veces tambien llamados contextos de ejecucion, pueden ser utilizados para la
implementacion de algoritmos paralelos o procesos concurrentes, sin ser necesario disponer de equipos
con estructura multiprocesador. En el caso de un solo procesador, los procesos ligeros incorporan
mecanismos para compartirlo, estableciendose prioridades entre ellos.
Los procesos ligeros son implementados por medio de una clase especial definida en el paquete
java.lang: la clase Thread. Para construir un proceso ligero debe crearse una subclase de la clase
Thread.
Ejemplo:
import java.applet.Applet;
public class EjemploThreads extends Applet {
public void init () {
new PotenciaThread("Primer
proceso ligero",2).start();
new PotenciaThread("Segundo
proceso ligero",3).start();
new PotenciaThread("Tercer
proceso ligero",5).start();
}
}
class PotenciaThread extends Thread {
long num;
public PotenciaThread(String nombre,long n) {
super(nombre);num=n;
}
public void run() {
long aux=1;
for(int i=1; i<=3; i++) {
aux*=num;
System.out.println(num +
"^" + i + "=" + aux);
}
}
}
198
Salida:
2^1=2
3^1=3
5^1=5
2^2=4
3^2=9
5^2=25
2^3=8
3^3=27
5^3=125
El Metodo run()
El metodo run() constituye el cuerpo del proceso ligero; en el se indica la accion para la que esta
programado el proceso ligero. Frecuentemente esta accion es un ciclo o una operacion que lleva mucho
tiempo.
En la definicion de la clase Thread del paquete java.lang se incluye el metodo run(). El progra-
mador debe adaptar dicho metodo a los objetivos de cada uno de sus procesos ligeros, y puede hacerse
de dos formas diferentes:
Redefiniendo el metodo en una subclase de Thread, igual que se hizo en el ejemplo anterior.
Creando el proceso ligero y asociandole un objeto de una clase que implemente la interfase
Runnable (tambien definida en el paquete java.lang). Una clase implementa esta interfase
cuando define un metodo sin argumentos que se llame run(). De esta manera, el metodo run()
del objeto que implementa la interfase Runnable pasara a ser el metodo run() del proceso ligero.
La segunda de las opciones es la que debera usarse cuando se quieran integrar procesos ligeros en applets.
A continuacion se presenta el programa que calcula de manera simultanea las potencias de tres
numeros usando esta nueva variante.
Ejemplo:
import java.applet.Applet;
public class EjemploThreads extends Applet{
public void init () {
PotenciaRun p1 = new PotenciaRun(2);
PotenciaRun p2 = new PotenciaRun(3);
PotenciaRun p3 = new PotenciaRun(5);
new Thread(p1).start();
new Thread(p2).start();
new Thread(p3).start();
}
}
class PotenciaRun implements Runnable {
199
long num;
public PotenciaRun(long n) {
num=n;
}
public void run() {
long aux=1;
for(int i=1; i<=10; i++) {
aux*=num;
System.out.println(num+"^"+i+"="+aux);
}
}
}
Un proceso ligero puede estar, en cada instante, en uno de los siguientes estados desde el momento
de su creacion:
Disponible: El proceso ligero ha sido creado con la sentencia new, pero el sistema no ha asignado
ningun recurso para el y no se ha utilizado el metodo start() para iniciar su ejecucion. En
tal estado, lo unico que podra hacerse es efectuar una llamada al metodo start() o stop().
Cualquier otra operacion causara una excepcion del tipo IllegalThreadStateException.
No ejecutable: El proceso ligero no puede ejecutarse, un proceso ligero entra en este estado por
varios motivos: se ha efectuado una llamada a los metodos sleep(), suspend() o wait() o porque
esta a la espera de realizar una operacion de entrada o salida.
Desactivado: Se alcanza este estado cuando, o bien todas las instrucciones de su metodo run()
se han ejecutado con normalidad, o bien el proceso ligero ha recibido un mensaje stop().
Desde su creacion, un proceso ligero puede cambiar de un estado a otro, tal como se indica en la
siguiente figura. Dichos cambios de estado pueden ser provocados por la utilizacion de algunos metodos
que se encuentran implementados en la clase Thread del paquete java.lang. En esta seccion se ex-
plicaran en detalle algunos de los mas importantes.
La Clase Thread
La clase Thread dispone de los constructores siguientes:
public Thread()
200
Ejecutable
yield()
suspend()
start sleep()
wait()
resume()
Stop notify()
fin notifyAll()
Disponible No ejecutable
Stop Stop
fin fin
Desactivado
public Thread(String n)
Un proceso ligero pasa al estado no ejecutable cuando esta en espera de una operacion de en-
trada/salida o se ha llama a uno de los metodos:
suspend(): provoca la suspension del metodo run() hasta recibir la orden de continuar.
wait(): el proceso ligero entre en estado no ejecutable hasta que se produzca una condicion.
Paso a ejecutable
Un proceso ligero puede pasar de no ejecutable a ejecutable de una unica forma, que depende
de como entro en el estado no ejecutable. Cualquier otro intento provocara una excepcion del tipo
IllegalThreadStateException:
Si entro con el metodo suspend(): entonces recuperara el estado ejecutable con una llamada al
metodo resume().
Si entro con el metodo sleep(long t): debe transcurrir ese tiempo para que el proceso ligero
vuelva al estado ejecutable.
Si entro con el metodo wait(): es preciso que otro proceso ligero invoque a su metodo notify()
o al metodo notifyAll().
201
El ultimo estado en el que se puede encontrar un proceso ligero es desactivado. Puede llegar a el
desde cualquiera de los otros tres estados por dos motivos:
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.
Todo proceso ligero tiene una prioridad, de forma que cuando varios procesos ligeros deben compartir
un procesador (como ocurre en la mayora de los casos) el sistema sepa a quien asignarlo.
Los procesos ligeros con prioridad mas alta tienen preferencia sobre los de prioridad mas baja. La
prioridad esta definida por un numero en el rango determinado por MIN PRIORITY y MAX PRIORITY
(constantes definidas en la clase Thread con los valores 1 y 10, respectivamente). De acuerdo con este
sistema de prioridades, en maquinas con un unico procesador, siempre se estara ejecutando el proceso
ligero con mas alta prioridad que este en estado ejecutable.
El metodo setPriority() asigna al proceso ligero como prioridad el valor mas pequeno entre ese
entero y la prioridad maxima permitida para el grupo al que pertenece. En el caso de que el metodo
setPriority() reciba un valor fuera del rango MIN PRIORITY, MAX PRIORITY se produce una excepcion
del tipo IllegalArgumentException.
El metodo getPriority() devuelve un entero con la prioridad del proceso ligero correspondiente.
Ejemplo:
import java.applet.Applet;
public class Prioridades extends Applet{
public void init () {
new AThread("Primero",1,0).start();
new AThread("Segundo",2,0).start();
new AThread("Tercero",3,10).start();
}
}
class AThread extends Thread {
int delay;
public AThread(String nombre,int pr,int time) {
super(nombre);
setPriority(pr);
delay=time;
}
public void run() {
try {for(int i=1; i<=5; i++) {
System.out.println("Ejecutando "+getName());
202
sleep(delay);
}
} catch (InterruptedException e) {
System.out.println("Interrupcion incorrecta");
}
}
}
Salida: Trabajando sobre un sistema de un solo procesador, la salida en la ventana stdout del programa
anterior debera ser similar a la siguiente:
Ejecutando Tercero
Ejecutando Segundo
Ejecutando Segundo
Ejecutando Tercero
Ejecutando Segundo
Ejecutando Segundo
Ejecutando Tercero
Ejecutando Segundo
Ejecutando Tercero
Ejecutando Primero
Ejecutando Tercero
Ejecutando Primero
Ejecutando Primero
Ejecutando Primero
Ejecutando Primero
En Java, los procesos ligeros pueden agruparse de manera que cada uno de ellos pertenezca a un
grupo. El uso de grupos permite manipular de forma conjunta todos sus procesos ligeros en lugar de
hacerlo individualmente.
La clase ThreadGroup
public ThreadGroup(ThreadGroup g,
String nombre)
String getName()
ThreadGroup getParent()
boolean parentOf(ThreadGroup g)
int getMaxPriority()
203
boolean isDaemon()
void stop()
void suspend()
void destroy()
void checkAccess()
En tales casos es preciso que los procesos ligeros actuen de manera sincronizada.
xn + xn1 + xn2 + . . . + x2 + x + 1
x(x(. . . (x(x + 1) + 1) . . .) + 1) + 1
Practica 1
class Carrera{
static Animal laLiebre;
static Animal laTortuga;
public static void main(String args[]){
laLiebre=new Animal(5,"L");
laTortuga=new Animal(1,"T");
laTortuga.run();
laLiebre.run();
}
}
class Animal{
int miVelocidad;
String miNombre;
public Animal(int laVelocidad, String elNombre){
miNombre=elNombre;
miVelocidad=laVelocidad;
}
public void duerme(int tiempo){
for(int i=0;i<tiempo;i++){;}
}
public void run(){
for(int i=0;i<10;i++){
System.out.print(miNombre);
duerme(1000/miVelocidad);
}
System.out.println("\n"+miNombre+" ha llegado");
}
}
206
Practica 2
class CarreraHilos{
static Animal laLiebre;
static Animal laTortuga;
}
207
y permita:
y permita:
y permita:
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);
Clase Productor
class Productor extends Thread {
private Almacen almacen;
public Productor(Almacen a) {
almacen = a;
}
Clase Consumidor
class Consumidor extends Thread {
private Almacen almacen;
private int numero;
Clase Almacen
class Almacen {
public int stock=100;
private boolean necesitareponer;
public boolean cerrado=false;
final int MAXCOMPRA=30;
final int LIMITEREPONER=50;
final int CANTIDADREPONER=100;
final long TIEMPOAPERTURA=3000;
long hora=System.currentTimeMillis();
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);
public Productor(Almacen a) {
almacen = a;
}
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
Animacion de Graficos
Debe utilizarse un proceso ligero (thread) que se encargue de ejecutar el ciclo de la animacion.
animacionThread: es un objeto de la clase Thread, que representa el proceso ligero que se encarga
de la animacion.
run(): que contiene el ciclo de la animacion dentro del bucle while, en el que se incrementa en
una unidad el numero del fotograma, se llama al metodo repaint() por defecto y se interrumpe su
ejecucion durante el tiempo de demora. El metodo repaint() llama automaticamente al metodo
paint() y este a su vez utiliza el metodo paintAnimation() para dibujar el grafico que se muestra
en la Figura, girandolo un grado, en el sentido de las agujas del reloj, en cada fotograma.
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
int radio=100,radio1=80;
float angulo;
for(int i=0;i<20;i++){
angulo=
(float)((numFotograma+10*i)*0.0174533);
g.fillOval((int)(150+
radio*Math.cos(angulo)),(int)(150+radio*
Math.sin(angulo)),ovalWidth, ovalHeight);
g.drawOval((int)(150+radio1*
Math.cos(angulo)), (int)(150+
radio1*Math.sin(angulo)),ovalWidth,
ovalHeight);
}
}
}
Observese que el programa anterior produce la animacion, pero se genera un parpadeo de la imagen
debido a varias razones:
1. Por defecto, antes de llamar al metodo paint() se borra el fondo de la animacion, por lo que se
ve un fotograma blanco entre fotogramas sucesivos.
2. Se van mostrando en pantalla distintas partes del dibujo hasta mostrarse el dibujo completo de
un fotograma, dando esa impresion de parpadeo.
Vamos a eliminar dicho parpadeo, creando una imagen del tamano apropiado fuera de la pantalla y
enviandola a la misma mediante el metodo drawImage(), solo cuando la imagen este completa.
import java.awt.*;
import java.applet.Applet;
import java.applet.event.*;
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);
}
Este metodo consiste en mover una imagen sobre otra que esta en el fondo.
En este programa tambien se utiliza un doble amortiguador para eliminar el parpadeo. Los cambios
con respecto al programa anterior son:
1. Se crean las variables mar y barco para almacenar las imagenes del mar y del barco, respectiva-
mente.
Image mar;
Image barco;
mar=getImage(getDocumentBase(),
"ejemplo/mar.gif");
barco=getImage(getDocumentBase(),
"ejemplo/barco.gif");
En el ejemplo siguiente se crea una matriz de imagenes que se van mostrando una a una. Se utiliza
de nuevo un doble regulador para eliminar el parpadeo. El metodo paintAnimation() se limita a
mostrar la imagen correspondiente.
Ejemplo:
}});
}
public void start() {
thread = new Thread(this);
thread.start();
}
public void stop() {
thread = null;
}
public void run() {
long time=System.currentTimeMillis();
while (Thread.currentThread() == thread) {
time+=tiempoDemora;
numFotograma++;
repaint();
try {
Thread.sleep(Math.max(
0,time-System.currentTimeMillis()));
} catch (InterruptedException e) {
break;
}
}
}
public void paint(Graphics g) {
update(g);
}
public void update(Graphics g) {
Dimension d = getSize();
if ( (grafic == null)||(d.width != dimen.width)
|| (d.height != dimen.height) ) {
dimen = d;
imag = createImage(d.width, d.height);
grafic = imag.getGraphics();
}
grafic.setColor(getBackground());
grafic.fillRect(0,0,d.width,d.height);
grafic.setColor(Color.black);
paintAnimation(grafic);
g.drawImage(imag,0,0,this);
}
public void paintAnimation(Graphics g){
if(numFotograma>7)
numFotograma=0;
g.drawImage(imagenes[numFotograma],0,0,null);
}
}
222
Utilizacion de la Clase
MediaTracker
Los metodos checkAll() y checkID(int id) permiten saber si las imagenes ya han sido cargadas.
Los metodos getErrorsAny() y getErrorsID(int id) muestran los errores que se cometen du-
rante la carga de las imagenes.
Los metodos statusAll() y statusID(int id) devuelven los estados en que se encuentran las
imagenes que se estan cargando.
Los metodos waitForAll() y waitForID(int id) cargan todas las imagenes o la indicada por
su id, esperando a que se complete la carga.
Para incorporar el control de las imagenes mediante la clase MediaTracker, al codigo anterior se le
anaden las lneas siguientes:
MediaTracker tracker;
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)
play(URL url)
play()
Emite este sonido una sola vez. Cada vez que se llama a este metodo, el sonido se emite
desde su comienzo.
stop()
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.*;
Ejemplo:
import java.applet.*;
import java.awt.*;
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();
}
Introduccion
Es de sobra conocido que las diferentes maquinas y sistemas operativos utilizan diferentes repre-
sentaciones para almacenar la informacion en la memoria del ordenador (memoria RAM, discos duros,
etc.). Cuando se quiere acceder a esta informacion (datos) se necesita conocer como esta almacenada.
Lo malo es que al cambiar de maquina, tambien cambia la forma de almacenamiento, por lo que los
programas de lectura y escritura de datos dependen de la maquina. Ello da lugar a la existencia de
notables problemas de compatibilidad entre plataformas y conduce a la necesidad de transformar unos
sistemas en otros mediante programas adecuados.
Una de las ideas centrales del lenguaje Java es la creacion de un sistema de trabajo independiente
de la maquina. El paquete Java.io permite trabajar con los datos con esa independencia. Se trata,
por tanto, de transformar todo a un mismo sistema de forma que el usuario no tenga que preocuparse
de que tipo de maquina o sistema esta utilizando. Ello naturalmente conduce a una utilizacion facil y
comoda y a una compatibilidad muy deseables.
Las clases del paquete java.io hacen referencia al concepto de flujo, (stream). Corrientes que permiten
la lectura o escritura de datos desde o en un archivo o pantalla. De esta forma tendremos flujos de
entrada y de salida con sus correspondientes metodos de lectura y escritura. Todas las clases derivadas
de las clases InputStream o Reader poseen metodos read() para leer un byte o un array de bytes. Y las
derivadas de las clases OutputStream o Writer tienen metodos write() para escribir un byte o un array
de bytes.
Entrada
InputStream
FilterInputStream
BufferedInputStream
DataInputStream
PushbackInputStream
ByteArrayInputStream
FileInputStream
ObjectInputStream
PipedInputStream
SequenceInputStream
Reader
BufferedReader
LineNumberedReader
CharArrayReader
FilterReader
228
PushbackReader
InputStreamReader
FileReader
PipedReader
StringReader
Una clase para flujos de datos (InputStream) y otra para caracteres Unicode (16 bits) para soportar
internacionalizacion
(Reader).
Salida
OutputStream
FilterOutputStream
BufferedOutputStream
DataOutputStream
PushbackOutputStream
ByteArrayOutputStream
FileOutputStream
ObjectOutputStream
PipedOutputStream
Writer
BufferedWriter
CharArrayWriter
FilterWriter
OutputStreamWriter
FileWriterr
PipedWriter
StringWriter
Una clase para flujos de datos (OutputStream) y otra para caracteres Unicode (16 bits) para soportar
internacionalizacion (Writer).
Ejemplo 1
Lee los datos del fichero Fichero1.txt (caracteres o numeros) y los escribe en Fichero2.txt.
229
import java.io.*;
class LeerEscribir {
public static void main(String args[]) {
try {
Se crean dos objetos de la clase File que representan los dos ficheros que se van a manejar. El constructor
toma como argumento el nombre del fichero correspondiente. La corriente FileInputStream permite
leer datos del fichero dado como argumento en su construc tor. La corriente FileOutputStream permite
escribir datos en el fichero dado como argumento en su constructor. Leemos los datos de Fichero1.txt
a traves de su corriente asociada gracias al metodo int read() de la clase FileInputStream que lee un
byte cada vez que es llamado y devuelve -1 si se alcanza final de fichero. Cada byte c ledo se escribe en
el fichero Fichero2.txt a traves de su corriente asociada mediante el metodo public void write(int
b) de la clase FileOutputStream que escribe el byte dado como argumento en la corriente f2, y por
tanto en el segundo fichero. Por ultimo, el metodo public void close() cierra ambas corrientes.
Ejemplo 2
import java.io.*;
class LeerEscribir {
public static void main(String args[]) {
int aux;
System.out.println("Escribir un numero entero:");
try {
FileOutputStream fos =
new FileOutputStream("Lista");
aux=System.in.read();
230
aux+=2;
fos.write(aux);
fos.close();
} catch (IOException e) {
System.out.println("LeerEscribir: " + e);
}
}
}
El metodo int read(byte[] b) de la clase InputStream lee bytes de la corriente in (de pantalla) y
los almacena en el array aux dado como argumento. Lee tantos bytes como elementos pueda almacenar
su array argumento. El metodo void write(byte[] b) de la clase FileOutputStream escribe los bytes
del array aux dado como argumento en f1 y, por tanto, en el fichero.
Ejemplo 3
Escribe y lee datos formateados.
import java.io.*;
class LeerEscribir {
public static void main(String args[]) {
int aux=0;
try {
DataOutputStream sum =
new DataOutputStream(
new FileOutputStream("Suma"));
for(int i=0;i<6;i++){
sum.writeInt(i+1);
sum.writeChar(\n);
}
sum.close();
DataInputStream dat =
new DataInputStream(
new FileInputStream("Suma"));
while(aux!=5){
aux=dat.readInt();
dat.readChar();
System.out.println(aux);
}
dat.close();
} catch (IOException e) {
System.out.println("LeerEscribir: " + e);}}}
Las clases DataOutputStream y DataInputStream permiten escribir y leer datos primitivos for
mateados. En primer lugar creamos una corriente de escritura formateada sum dando como argu-
mento al constructor un objeto de la clase FileOutputStream asociado al chero sum.txt. De esta
forma el metodo final void writeInt(int v) de la clase DataOutputStream escribe en el fichero, a
traves de las corrientes intermedias, los enteros 0,1,2,3,4,5 en formato de cuatro bytes; el metodo void
231
writeChar(int v) de la clase DataOutputStream escribe el caracter cambio de lnea tras cada entero,
en formato de dos bytes. Escrita la columna de enteros en el fichero sum.txt se realiza el proceso
inverso. A traves de una corriente dat de lectura, (construida mediante un objeto FileInputStream
asociado al fichero), vamos leyendo cada entero y cada caracter cambio de lnea del fichero gracias a
los metodos int readInt() y char readChar() de la clase DataInputStream. y los imprimimos en
pantalla.
Ejemplo 4
import java.io.*;
class LeerEscribir {
public static void main(String args[]) {
try {
String str1="Esto es una prueba");
String str2="Utilizo la clase FileWriter";
int aux1=1;
double aux2=2.3;
File f=new File("Lista");
FileWriter dat=new FileWriter(f);
dat.write(str1);
dat.write(\n);
dat.write(str2);
dat.write(" "+aux1);
dat.write(\n);
dat.write(" "+aux2);
dat.close();
}
} catch (IOException e) {
System.out.println("LeerEscribir: " + e);
}
}
}
La clase FileWriter es adecuada para escribir ficheros de caracteres. Creamos un objeto de dicha
clase dando como argumento al constructor el objeto File que representa el fichero que queramos es-
cribir. Los metodos void write(String str) y void write(int c) de la superclase Writer escriben
en el fichero cadenas de caracteres o un unico caracter.
Ejemplo 5
import java.io.*;
class LeerEscribir {
232
La clase FileReader es adecuada para leer ficheros de caracteres. Creamos un objeto de dicha
clase dando como argumento al constructor el objeto File que representa el fichero que queramos leer.
Los metodos int read(char b[]) y int read() de la superclase Reader leen del fichero cadenas de
caracteres o un unico caracter.
Ejemplo 6
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
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
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
import java.io.*;
import java.awt.*;
import java.awt.event.*;
public FileViewer(){
textarea=new TextArea("",24,80);
textarea.setFont(
new Font("MonoSpaced", Font.PLAIN,12));
textarea.setEditable(false);
add("Center",textarea);
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
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();
}
}