Cur So Java Completo
Cur So Java Completo
Temas
Applets y aplicaciones con interfaz grfica AWT y Swing Excepciones, Hilos y Flujos Acceso a base de datos Aplicaciones distribuidas en Internet y WEB
Conexin a redes Servlets, JSPs Cookies y sesiones
Introduccin
Java
Java is a simple, object oriented, distributed, interpreted, architecture neutral, portable, robusto, secure, high-performance, multi threaded, and dynamic language Sun Microsystems
Java es un lenguaje simple, orientado a objetos, distribuido, interpretado, de arquitectura neutral, transportable, robusto, seguro, de alto rendimiento, multiproceso y dinmico
Caractersticas de Java
Simple y familiar Orientado a Objetos Distribuido Interpretado Arquitectura Neutral Transportable Robusto Seguro Alto Rendimiento Multiproceso Dinmico
Programa Fuente
Compilador
Interpretador
Ejecucin
Byte-Codes
Primer programa
j2sdk
Bajar la ltima versin del JDK del sitio de SUN (JDK 1.7.2) www.javasoft.com Instalar el JDK en la mquina Bajar la documentacin Instalar la documentacin Comenzar a programar en Java
El primer programa
public class Primero{ public static void main (String[] args){ System.out.println("Hola que tal!"); } }
Compilacin y ejecucin
Compilacin
javac Primero.java genera Primero.class
Ejecucin
java Primero
Objetos
Estado
Nombre, color, raza, contento
Comportamiento
Ladrando, durmiendo, corriendo
Objetos
Perro
Representa
Objetos de Software
Objetos reales
Objeto (Software)
Estado
Representado por sus Variables
Comportamiento
Modificado por sus Mtodos
Los objetos en programacin representan objetos reales y objetos abstractos (conceptos), ej. Eventos
Objetos de Software
Detalles de la implementacin
API pblica
El Objeto Perro
cambiaColor nombre color raza ladrando durmiendo ladra
brinca
duerme
Encapsulacin
Ocultar las Variables y acceder a ellas solamente por medio de los Mtodos
Encapsulacin
Modularidad Transparencia
Facilidad del uso de un objeto Puede cambiar la implementacin sin afectar su utilizacin
A veces se hacen pblicas las variables y se esconden algunos mtodos por razones de eficiencia
Mensajes
Permiten la interaccin entre objetos Mandar a ejecutar un mtodo
Mensaje
Acelera, frena, etc.
Parmetros
A veces los mtodos necesitan ms informacin para realizar una accin Esta informacin adicional se pasa en forma de parmetros
enciende
enciende (%)
Mensajes
Expresan el comportamiento de un objeto, cambiando el estado de ste Ocultan la necesidad de exponer las variables Los objetos pueden estar en procesos y/o mquinas diferentes
Mensajes
Objeto destino Nombre del mtodo a ejecutar Parmetros necesarios
focoSala.enciende(porcentaje)
Clases
Prototipo de objetos Definen sus variables y mtodos Los objetos son ejemplares de clases (instancias) Los objetos de una clase comparten las caractersticas generales de la clase a que pertenecen
Clases y Objetos
Los objetos de una clase comparten el comportamiento (mtodos) Cada objeto tiene su propio estado (variables)
Clase Perro
Clases y Objetos
Prototipo de los objetos
Clases y Objetos
Clases y Objetos
Variables y Mtodos
De ejemplar
Se crea una copia particular de las variables y se tiene acceso a los mtodos
De clase
Todos los objetos de una clase comparten la misma copia No se necesita crear un objeto para el acceso a variables y mtodos Si un objeto cambia una variable de clase, esa variable se cambia para todos los objetos de la clase
Herencia
Definicin de clases con base en otras clases Subclases se definen con base en Superclases La subclase hereda las variables y mtodos de la superclase La subclase define sus propias variables y mtodos los cuales se agregan a los de la superclase
Herencia
Figura
Tringulo
Rectngulo
Ovalo
Rombo
Una subclase puede redefinir (override) mtodos heredados, para que realicen algo diferente o en diferente forma
Herencia
Esquema jerrquico Reutilizacin de cdigo Definicin de clases abstractas que definen un comportamiento genrico, el cual es implementado en las subclases
No se pueden crear objetos de clases abstractas
Ejemplo
Definicin de la clase Rectangulo Compilacin de la clase Programa que utilice objetos Rectangulo
Creacin de un ejemplar de Rectangulo Llamadas a mtodos del objeto
posicin (x , y)
alto
tamao
posicin
La clase Rectangulo
public class Rectangulo{ int x, y; int ancho, alto; public Rectangulo(){ x = 0; y = 0; ancho = 100; alto = 100; }
Programa
public class EjemploRectangulo{
public static void main(String args[]){ Rectangulo r; int area = 0;
r = new Rectangulo(); area = r.calculaArea(); System.out.println("Area = "+area); r.cambiaTamano(200,300); area = r.calculaArea(); System.out.println("Area = "+area); }
}
Rectangulo ms completa
public class Rectangulo{ int x, y; int ancho, alto; public Rectangulo(){ x = 0; y = 0; ancho = 100; alto = 100; } public Rectangulo(int x, int y){ this.x = x; this.y = y; ancho = 100; alto = 100; } public Rectangulo(int x, int y, int ancho, int alto){ this.x = x; this.y = y; this.ancho = ancho; this.alto = alto; } public void mueve(int x, int y){ this.x = x; this.y = y; } public void cambiaTamano(int ancho, int alto){ this.ancho = ancho; this.alto = alto; } public int calculaArea(){ return ancho*alto; } }
Programa
public class EjemploRectangulo{ public static void main(String args[]){ Rectangulo r1,r2; int area1, area2; r1 = new Rectangulo(100,100); r2 = new Rectangulo(50,50,100,200); area1 = r1.calculaArea(); area2 = r2.calculaArea(); System.out.println("Area1 = "+ area1 + " , Area2 = " + area2); r1.cambiaTamano(200,300); area1 = r1.calculaArea(); area2 = r2.calculaArea(); System.out.println("Area1 = "+ area1 + " , Area2 = " + area2);
}
}
Mejoras
Modificar el programa del rectngulo para que no utilice las coordenadas como dos enteros En su lugar definir una clase que sea un punto en el espacio, la cual internamente maneje coordenadas x , y
public void mueve(Punto p){ posicion = p; } public void cambiaTamano(int ancho, int alto){ this.ancho = ancho; this.alto = alto; } public int calculaArea(){ return ancho*alto; }
Lenguaje
Java
entero complementos a 2 entero complementos a 2 entero complementos a 2 entero complementos a 2 punto flotante prec. sencilla punto flotante prec. doble Unicode true/false
56
x xyz
Variables
Identificador legal con carcteres unicode (65,536 posibles, 34,168 asignados) letras y dgitos unicode, la primera debe ser letra No debe ser palabra reservada Convencin:
Primera letra minscula y cada palabra subsiguiente comienza con mayscula, sin espacios (variableDeVariasPalabras)
Palabras reservadas
Operadores
Unitarios
Un operando, prefijo o postfijo
Binarios
Dos operandos, infijo
Ternarios
expresin ? op1 : op2
Operadores aritmticos
Operador + * / % + ++ ++ --Uso
op1+op2
Descripcin Suma Resta Multiplicacin Divisin Residuo de op1 / op2 Promueve a int si es byte, short o char Aritmticamente niega op Incrementa a op en 1, se evalua antes del incremento Incrementa a op en 1, se evalua despus del incremento Decrementa a op en 1, se evalua antes del decremento Decrementa a op en 1, se evalua despus del decremento
Ejemplos
class Aritmeticos { public static void main int x = 17, y = 5; System.out.println("x System.out.println("y System.out.println("x System.out.println("x System.out.println("x System.out.println("x System.out.println("x } }
(String args[]) {
= = + * / % " " y y y y y + + = = = = = x); y); " + " + " + " + " +
(x (x (x (x (x
+ * / %
Salida a pantalla
Ejemplos
class Incrementos { public static void main (String args[]) { int x = 8, y = 13; System.out.println("x = " + x); System.out.println("y = " + y); System.out.println("++x = " + ++x); System.out.println("y++ = " + y++); System.out.println("x = " + x); System.out.println("y = " + y); } } x = y = ++x y++ x = y = 8 13 = 9 = 13 9 14
Salida a pantalla
Operadores relacionales
Regresan un valor booleano (true o
Operador > < >= <= == != Uso
op1>op2 op1<op2 op1>=op2 op1<=op2 op1==op2 op1!=op2
false)
Descripcin Regresa verdadero si op1 es mayor que op2 Regresa verdadero si op1 es menor que op2 Regresa verdadero si op1 es mayor o igual que op2 Regresa verdadero si op1 es menor o igual que op2 Regresa verdadero si op1 es igual a op2 Regresa verdadero si op1 es diferente a op2
Ejemplos
class Relacionales { public static void main (String args[]) { int x = 7, y = 11, z = 11; System.out.println("x = " + x); System.out.println("y = " + y); System.out.println("z = " + z); System.out.println("x < y = " + (x < y)); System.out.println("x > z = " + (x > z)); System.out.println("y <= z = " + (y <= z)); System.out.println("x >= y = " + (x >= y)); System.out.println("y == z = " + (y == z)); System.out.println("x != y = " + (x != z)); } }
Salida a pantalla
x y z x x y x y x
= 7 = 11 = 11 < y = true > z = false <= z = true >= y = false == z = true != y = true
Operadores condicionales
Regresan un valor booleano (true o
Operador && || ! & | ?:
int int int int int int a b c d e f = = = = = =
false)
Uso
op1&&op2 op1||op2
Descripcin
AND lgico, condicionalmente evalua op2 OR lgico, condicionalmente evalua op2 !op Niega lgicamente a op op1&op2 AND lgico, siempre evalua op2 op1|op2 OR lgico, siempre evalua op2 Evalua exp y regresa op1 si es verdadera exp?op1:op2 o regresa op2 si exp es falsa
28; 4; 45; 0; (b == 0) ? 0 : (a / b); (d == 0) ? 0 : (c / d);
e=7 f =0
Operadores de bit
Operador Uso
op1>>op2 op1<<op2 op1>>>op2 op1&op2 op1|op2 op1^op2
Descripcin
~op
Recorre los bits de op1 hacia la derecha op2 bits Recorre los bits de op1 hacia la izquierda op2 bits Recorre a la derecha, pero sin signo AND lgico, bit a bit OR lgico, bit a bit XOR lgico, bit a bit Complementa op, bit a bit
Ejemplos
class Shift { public static void main int x = 7; System.out.println("x System.out.println("x System.out.println("x System.out.println("x } }
(String args[]) {
= " + x); >> 2 = " + (x >> 2)); << 1 = " + (x << 1)); >>> 1 = " + (x >>> 1));
Salida a pantalla
Operadores de asignacin
Operador = += -= *= /= %= &= |= ^= <<= >>= >>>= Uso
op1=op2
Equivalente a
op1+=op2 op1-=op2 op1*=op2 op1/=op2 op1%=op2 op1&=op2 op1|=op2 op1^=op2 op1<<=op2 op1>>=op2 op1>>>=op2
op1 = op1 + op2 op1 = op1 - op2 op1 = op1 * op2 op1 = op1 / op2 op1 = op1 % op2 op1 = op1 & op2 op1 = op1 | op2 op1 = op1 ^ op2 op1 = op1 << op2 op1 = op1 >> op2 op1 = op1 >>> op2
Expresiones
Conjunto de variables, operadores y llamadas a mtodos, construido de acuerdo a la sintaxis del lenguaje, y que al evaluarla produce un slo valor Los operadores tienen precedencia, la cual se puede modificar por el uso de parntesis Las asignaciones se realizan al final Operadores con igual precedencia se evaluan de izquierda a derecha
Precedencia de operadores
. ++ * + << < == & ^ | && || ?: [] () -- ! ~ / % >> >>> > <= >= !=
Estatutos
Decisin
if - else switch
Ciclos
while do - while for
if - else
if (Condicin) Estatuto1; else Estatuto2;
if (Condicin){ _____; _____; : : }else{ _____; _____; : : }
if (Condicin) Estatuto1;
Ejemplos
boolean a,b; : : if (a && b) { x += y * 5; y -= 10; z = (x - 3) / y; }
int calificacin; char nota; if (calificacin >= 90) nota = 'A'; } else if (calificacin nota = 'B'; } else if (calificacin nota = 'C'; } else if (calificacin nota = 'D'; } else { nota = 'F'; } { >= 80) { >= 70) { >= 60) {
switch
switch (Expresin) { case Constante1: Estatutos1; break; case Constante2: Estatutos2; break; : : default: Estatutos; break; }
Expresin debe ser char, byte, short o int Las constantes deben de ser del mismo tipo que expresin break es opcional, si no se utiliza se ejecutan todos los estatutos despus del primer case que coincida con la expresin default maneja todos los casos que no estn contamplados en los case, es opcional No puede haber dos constantes iguales Solamente puede existir un default
Ejemplo
int mes;
. . . . . . switch (mes) { case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: }
System.out.println(Enero"); break; System.out.println(Febrero"); break; System.out.println(Marzo"); break; System.out.println(Abril"); break; System.out.println(Mayo"); break; System.out.println(Junio"); break; System.out.println(Julio"); break; System.out.println(Agosto"); break; System.out.println(Septiembre"); break; System.out.println(Octubre"); break; System.out.println(Noviembre"); break; System.out.println(Diciembre"); break;
while
while (condicin) estatuto;
Condicin
Estatutos
do - while
do estatuto; while (condicin);
Estatutos
Condicin
Ejemplos
int i = 0; int n = 10; while (i<n){ System.out.println(i= +i); i++; } i= 0 i= 1 : : i= 9
i= 0 i= 1 : : i= 9
for
for (asignacin inicial; condicin booleana; actualizacin de variables) estatuto; for (asignacin inicial; condicin booleana; actualizacin de variables){ estatuto1; estatuto2; : : }
La asignacin inicial se realiza una sola vez La condicin se evalua al principio de cada ciclo, si es verdadera ejecuta los estatutos y vuelve a hacer la evaluzacin, si es falsa termina y se sale Cualquiera de los componentes puede ser estatuto vacio
Ejemplos
int i; int n=10; for (i=1;i<n;i++) System.out.println(i= "+i); i= 1 i= 2 : : i= 9
int i,j; int n=10; for (i=j=1;i*j<n;i++,j++){ System.out.println("i= "+i+" j= "+j); System.out.println("i*j= "+i*j); }
j= 1 1 j= 2 4 j= 3 9
break
brinca al final de los estatutos del ciclo y continua con la siguiente instruccin
int i=0; int n=10; do{ System.out.println(i= "+i); if (i>n) break; i++; }while(true);
i= 0 i= 1 : : i= 11
continue
brinca al final del ciclo, pero evalua la condicin para saber si continua iterando
int i=0; int n=10; do{ i++; if (i%2!=0) continue; System.out.println(i= "+i); }while(i<n);
i= i= i= i= i=
2 4 6 8 10
Segunda aplicacin
public class Segundo{ public static void main (String[] args){ int cont = Integer.parseInt(args[0]); for (int i=1; i<=cont; i++) System.out.println("Hola que tal!"); } }
Creacin de Objetos
Declaracin
No crea el objeto, slo notifica al compilador el tipo de la variable
Creacin
Crear un ejemplar de una clase
Declaracin
Tipo nombre;
Clase o interfaz
Constructores
Mtodos con el mismo nombre de la clase No tienen tipo de regreso, no regresan ningn valor Una clase puede tener varios constructores, todos con el mismo nombre, pero diferente cantidad y/o tipo de parmetros Java provee un constructor por omisin (default): Clase ()
Utilizacin de objetos
Los objetos se pueden usar despus de que son creados Manipular sus variables
objeto.variable
Utilizacin de objetos
public class Algo; : public int var1; :
: Algo a1 = new Algo(); Algo a2 = new Algo(); : i = a1.var1 + a2.var1
: Algo
Objetos diferentes
Variables diferentes
Garbage Collection
La creacin y destruccin de objetos es tediosa y propensa a errores El proceso de liberacin de memoria es automatizado en Java Ms prctico y libera al programador de esta tarea Disminucin de errores de programacin (bugs)
Garbage Collection
Responsable: La mquina virtual Un objeto es elegible para ser eliminado por el recolector de basura cuando ya no existen referencias a l Cuando una variable se sale de alcance o se le asigna explcitamente el valor null
unaVariable = null;
Alcance de i
finalize()
Mtodo que se ejecuta antes de que la mquina virtual destruya al objeto Todos los objetos tienen uno por default Util para liberar recursos del sistema No se puede asegurar que se ejecutar en un momento determinado
finalize()
protected void finalize () throws Throwable{ x = null; y.close(); super.finalize(); }
Clases
public class Rectangulo{ int x, y; int ancho, alto; public Rectangulo(){ x = 0; y = 0; ancho = 100; alto = 100; } public void mueve(int x, int y){ this.x = x; this.y = y; } public void cambiaTamano(int ancho, int alto){ this.ancho = ancho; this.alto = alto; }
Declaracin
Variables
Cuerpo
Constructor
Mtodos
Limpieza
}
Declaracin
modificador class UnaClase extends Superclase implements Interfaz{}
Modificadores
nada, public, abstract, final
extends
identifica superclase
implements
identifica interfaz que se debe de implementar
Convenciones
Nombres de clases
Primera letra mayscula y cada palabra subsiguiente comienza con mayscula, sin espacios Sustantivos cosas ClaseDeVariasPalabras
Cuerpo
Constructores Mtodos Variables finalize()
Las variables y mtodos de una clase son llamados miembros de la clase. Los constructores no son mtodos, no son miembros
Constructores
Mismo nombre de la clase Puede haber ms de uno (sobrecarga) Inicializacin del objeto Opcional. El compilador crea uno en caso de que no se especifique en forma explcita Pueden tener variables locales, ciclos y otros estatutos
protected
Slo subclases de esta clase pueden crear objetos de esta clase
public
Todas las clases pueden crear objetos de esta clase
package
Slo clases del mismo paquete (package) puede crear instancias de esta clase
Declaracin de variables
[nivel de acceso] [atributos] tipo nobre;
Nivel de acceso
public, protected, package, private Discutidos en control de acceso a miembros de una clase . . . . .
Atributos
static, final, transient, volatile
protected
Slo la clase donde son definidas, subclases de sta y clases del mismo paquete pueden acceder a estas variables
public
Todas las clases pueden acceder a estas variables
package
Slo clases del mismo paquete pueden acceder estas variables, no subclases, es especificador por omisin
final
Valor de la variable no puede cambiar (constante)
transient
Variable no debe ser serializada
volatile
El compilador no efectua ciertas optimizaciones
Mtodos
Nivel de Acceso Tipo que regresa Parmetros
Throws Exceptions
Atributos
Nombre
protected
Slo la clase donde son definidos, subclases de sta y clases del mismo paquete pueden acceder a estos mtodos
public
Todas las clases pueden acceder a estos mtodos
package
Slo clases del mismo paquete pueden acceder estos mtodos, no sublclases, es especificador por omisin
Atributos de mtodos
static
mtodo de clase y no de ejemplar
abstract
No tiene implementacin. Debe de pertencer a una clase abstract
final
No puede ser reprogramado (overriden)
native
escrito en otro lenguaje, cdigo especfico para una plataforma
synchronized
para ser usado por threads y no causar problemas tpicos de multiproceso
Sobrecarga de mtodos
Varios mtodos pueden compartir el mismo nombre, deben de diferir en el nmero y/o tipo de parmetros
public int suma (int a, int b){}
public double suma (double a, double b){}
Redefinicin de mtodos
Una clase puede reemplazar (override) un mtodo de su superclase El mtodo debe ser exactamente igual (tipo de regreso, nombre y parmetros), slo cambia la programacin Casi todas las clases reprograman toString() Para agregar cdigo a un mtodo se puede llamar super.nombre(...) Los mtodos final y static no se pueden reprogramar Los mtodos abstract de una superclase se deben de reprogramar
Parmetros de un mtodo
Se usan para pasar informacin a un mtodo Se debe declarar el tipo y nombre de cada uno, separados por coma Pueden ser de cualquier tipo vlido en Java (primitivos, objetos, arreglos) No se pueden pasar mtodos como parmetros, pero se puede pasar un objeto y llamar a uno de sus mtodos Si tienen el mismo nombre que una variable de la clase, el parmetro esconde a la variable dentro del cuerpo del mtodo, para accesar a la variable es necesario usar this No pueden tener el mismo nombre que otro parmetro, variable local o parmetro de un catch
Ejemplo
public cambiaValor (int x, Button b){ x = 5; b.setLabel(Otro letrero); }
int edad = 25; Button boton = new Button (Letrero original); cambiaValor (edad, boton);
edad = 25
cambiaValor(edad,boton)
edad = 25
Mtodos
this
se refiere al objeto en ejecucin, el ejemplar al cual pertenece el mtodo
super
Para acceder a variables y mtodos de la superclase
variables locales
Declaradas en el cuerpo del mtodo, estn vivas durante la ejecucin del mtodo
Existe slo una copia en memoria, compartida por todas los ejemplares de la clase No pueden acceder a variables de ejemplar
Miembros de ejemplar
Se utilizan a travs de un objeto (objeto.variable u objeto.mtodo(...))
Existe una copia separada por cada objeto Pueden acceder a variables de clase
Introduccin a Applets
Servidor de Web
Primer Applet
import java.applet.*; import java.awt.*; public class PrimerApplet extends Applet{ public void paint(Graphics g){ g.drawString("Hola que tal!!!!!",50,20); } }
Grabarlo y compilarlo
Cdigo del Applet archivo .class Etiqueta applet de html indica que se cargar un Applet
paint()
Ejecutado automticamente cuando el Applet se necesita desplegar, al cargarse o al descubrirse por el movimiento de ventanas Se necesita reprogramar para que el Applet despliegue algo especial Los objetos de AWT no necesitan dibujarse en forma explcita
La clase Graphics
Contiene mtodos para dibujar en un contexto grfico, inicialmente para nosotros ser el applet Las coordenadas comienzan en 0,0 en la esquina superior izquierda
drawString
drawRect
width+1
(x+width,y)
(x,y)
height+1
(x,y+height)
(x+width,y+height)
fillRect
width
(x+width-1,y)
(x,y)
height
(x,y+height-1)
(x+width-1,y+height-1)
Segundo Applet
import java.applet.*; import java.awt.*;
public class SegundoApplet extends Applet{ public void paint(Graphics g){ g.setColor(Color.black); g.drawRect(50,50,50,100); g.setColor(Color.red); g.fillRect(50+1,50+1,50-1,100-1); g.fillOval(110,110,50,70); } }
Segundo Applet
Browsers y Java
Netscape
Shift-reload para cargar las clases de nuevo
IExplorer
Control-reload para cargar las clases de nuevo
Mtodos de un Applet
init()
Se ejecuta cada vez que se carga el applet (reload?)
start()
Despus de init() y cada vez que se regresa a la pgina
stop()
Cuando se va a otra pgina o se termina la ejecucin del browser
destroy()
Despus de stop() cuando se cierra el browser, o la mquina virtual mata al Applet
Mtodos de un Applet
init()
Inicializacin de variables y recursos que usar el Applet a travs de su vida
start()
Comienzo de la ejecucin del Applet, y reinicio en caso de haberse detenido por stop()
stop()
Interrupcin de la ejecucin, para no consumir CPU (parar animaciones, ciclos)
destroy()
Liberacin general de los recursos
import java.applet.Applet; import java.awt.Graphics; public class TercerApplet extends Applet { String letrero = ""; public void init() { letrero += "en init() "; } public void start() { letrero += "en start() "; } public void stop() { letrero += "en stop() "; } public void destroy() { letrero += "en destroy() "; }
Ejemplo
import java.applet.Applet; import java.awt.Graphics; public class CuartoApplet extends Applet { public void init() { System.out.println("en init()"); } public void start() { System.out.println("en start()"); } public void stop() { System.out.println("en stop()"); } public void destroy() { System.out.println("en destroy()"); } }
Debugging
System.out.println() es til para el rastreo de problemas en un Applet La salida de System.out.println() va a la consola En IExplorer es necesario activarla
Prctica
Subir una pgina con un applet a un servidor y ejecutarlo desde un browser en alguna mquina remota Sigue las instrucciones del instructor
AWT
Nos da acceso a muchos componentes estndar de interfaces grficas. Botones, Listas, campos de texto, mens, etc. Tambin define un modelo de eventos para darle funcionamiento a los componentes El nuevo ambiente grfico es JFC (Java Foundation Classes, Swing) Los browsers no traen soporte directo para Swing, se necesita un plug-in de 5 Mbytes aprox.
Label
List
Button
La clase Button
La clase Button
La clase TextField
TextField
getText()
Administradores de Layout
Sirven para distribuir los objetos en el contexto grfico Siguen reglas estrictas para el acomodo de los objetos Hay que agregar los objetos a contenedores A los contenedores se les asigna un administrador de Layout Existe el administrador nulo (null) que sirve para utilizar posicionamiento absoluto
Administradores de Layout
Objetos de GUI
Le dan funcionalidad a la aplicacin (botones, campos de texto, listas, etc.)
Contenedores
Le dan hospedaje fsico a los objetos GUI
Administradores
Ordenan los objetos dentro de los contenedores
Contenedores
Frame
Applet
Panel
Administradores de Layout
Los objetos se agregan a los contenedores:
contenedor.add(objeto)
contenedor.setLayout(..)
Administradores de Layout
FlowLayout
El default para los applets, acomoda los objetos de izquierda a derecha y agrega renglones a medida que los va necesitando
BorderLayout
Usa cinco reas predeterminadas, Norte, Sur, Este, Oeste y Centro. El Centro es que usa todo el espacio que sobra despus de acomodar las dems reas
GridLayout
Acomoda los componentes en una cuadrcula, se especifica las dimensiones de la cuadrcula cuando se crea este Layout
CardLayout GridbagLayout
FlowLayout
Ejemplo FlowLayout
import java.applet.*; import java.awt.*;
public class LayoutFlow extends Applet { Button boton1, boton2, boton3; public void init() { boton1 = new Button("Ok"); boton2 = new Button("Cancelar"); boton3 = new Button("Aceptar alguna cosa"); add(boton1); add(boton2); add(boton3); } }
Ejemplo FlowLayout
import java.applet.*; import java.awt.*; public class LayoutFlow extends Applet { Button boton1, boton2, boton3; public void init() { boton1 = new Button ("Ok, pero ahora ms largo a ver que pasa con el Layout"); boton2 = new Button("Cancelar"); boton3 = new Button("Aceptar alguna cosa"); add(boton1); add(boton2); add(boton3); } }
Ejemplo FlowLayout
import java.applet.*; import java.awt.*; public class LayoutFlow extends Applet { Button boton1, boton2, boton3; public void init() { setLayout(new FlowLayout(FlowLayout.LEFT ,0,0)); boton1 = new Button("Ok"); boton2 = new Button("Cancelar"); boton3 = new Button("Aceptar alguna cosa"); add(boton1); add(boton2); add(boton3); } }
BorderLayout
Para agregar componentes a este Layout se usa una variante de add. add(Componente, Posicin) Donde Posicin indica las cinco posibles que tiene BorderLayout: North, South, East, West, Center Posicin es una constante String No se recomienda usar add(Posicin, Componente)
Ejemplo BorderLayout
import java.awt.*; import java.applet.Applet; public class LayoutBorder extends Applet { public void init() { setLayout(new BorderLayout()); add(new Button("Norte"),"North"); add(new Button("Sur"),"South"); add(new Button("Este"),"East"); add(new Button("Oeste"),"West"); add(new Button("Centro"),"Center"); } }
Ejemplo BorderLayout
import java.awt.*; import java.applet.Applet; public class LayoutBorder extends Applet { public void init() { setLayout(new BorderLayout(20,20)); add(new Button("Norte"),"North"); add(new Button("Sur"),"South"); add(new Button("Este"),"East"); add(new Button("Oeste"),"West"); add(new Button("Centro"),"Center"); } }
GridLayout
Divide el rea grfica en una cuadrcula rectangular con un nmero especificado de rectngulos de igual tamao
Ejemplo GridLayout
import java.awt.*; import java.applet.Applet; public class LayoutGrid extends Applet { public void init() { setLayout(new GridLayout(3,2)); add(new Button("1")); add(new Button("2")); add(new Button("3")); add(new Button("4")); add(new Button("5")); add(new Button("6")); } }
Ejemplo GridLayout
import java.awt.*; import java.applet.Applet; public class LayoutGrid extends Applet { public void init() { setLayout(new GridLayout(2,3)); add(new Button("1")); add(new Button("2")); add(new Button("3")); add(new Button("4")); add(new Button("5")); add(new Button("6")); } }
Ejemplo GridLayout
import java.awt.*; import java.applet.Applet; public class LayoutGrid extends Applet { public void init() { setLayout(new GridLayout(2,3)); add(new Button("1")); add(new Button("2")); add(new Button("3")); add(new Button("4")); } }
Si se especifica nmero de columnas y renglones, el nmero de columnas se ignora y se ajusta a las que se necesiten
Ejemplo GridLayout
import java.awt.*; import java.applet.Applet; public class LayoutGrid extends Applet { public void init() { setLayout(new GridLayout(2,3)); add(new Button("1")); add(new Button("2")); add(new Button("3")); add(new Button("4")); add(new Button("5")); add(new Button("6")); add(new Button(7")); } }
Si se especifica nmero de columnas y renglones, el nmero de columnas se ignora y se ajusta a las que se necesiten
Ejemplo GridLayout
import java.awt.*; import java.applet.Applet; public class LayoutGrid extends Applet { public void init() { setLayout(new GridLayout(0,4)); add(new Button("1")); add(new Button("2")); add(new Button("3")); add(new Button("4")); add(new Button("5")); add(new Button("6")); } }
El nmero de columnas tiene sentido solamente cuando se especifica un nmero de renglones igual a cero
TextArea
Regin de texto multilnea De la clase TextComponent hereda la capacidad de establecer y obtener todo el texto contenido o solamente el seleccionado, adems de poder establecer el color y font del texto desplegado, color del fondo, hacer el texto editable o no (read only)
Constructores de TextArea
La clase Panel
Interfaces adecuadas
Ejemplo
public class Layouts extends Applet{ Panel botones = new Panel(new GridLayout(8,0,0,10)); Button boton1 = new Button("Insertar"); Button boton2 = new Button("Borrar"); Button boton3 = new Button("Imprimir"); Button boton4 = new Button("Cancelar"); TextArea texto = new TextArea(); public void init(){ setLayout(new BorderLayout(10,0)); botones.add(new Label("Esta es una Demostracin")); botones.add(new Label()); botones.add(new Label()); botones.add(new Label()); botones.add(boton1); botones.add(boton2); botones.add(boton3); botones.add(boton4); add(texto,"Center"); add(botones,"East"); } }
Prctica
Haz un applet que despliegue la siguiente interfaz
Fuentes y Escuchadores
Objeto Fuente (Source) Evento Objeto Escuchador (Listener)
Las fuentes son objetos que originan o disparan eventos. Cada fuente define el conjunto de eventos que puede emitir con: set<TipoEvento>Listener o add<TipoEvento>Listener Los escuchadores son objetos que implementan interfaces especficas que definen uno o ms mtodos para la atencin de eventos particulares
Propagacin de eventos
Fuente
Eventos que se generan
Escuchador
Evento
Escuchadores registrados
Los objetos fuente cuando disparan un evento llaman al mtodo indicado en los objetos escuchadores que esten registrados. Al llamar al mtodo correspondiente en el escuchador, tambin va como parmetro una instancia de la subclase que define el tipo de evento generado
Fuente Button
Evento ActionEvent
Escuchador ActionListener
Ejemplo
public class Beep extends Applet{ Button fuente = new Button("Presiname"); EventoAccion escuchador = new EventoAccion(); public void init() { add(fuente); fuente.addActionListener(escuchador); } } class EventoAccion implements ActionListener{ public void actionPerformed(ActionEvent e) { Toolkit.getDefaultToolkit().beep(); } }
Modelo de delegacin
Usado en JDK 1.1 y JDK 1.2 (Java 2) Ya no se usa el modelo de AWT 1.0, modelo basado en herencia Existen fuentes (sources) que generan o disparan eventos y escuchadores (listeners) Permite delegar el manejo de eventos a objetos escuchadores El modelo permite manejar y generar eventos
Eventos
Escuchador de Eventos
Generador de Eventos
Evento
Escuchador de Eventos
Escuchador de Eventos
Eventos
Generador de Eventos
Generador de Eventos
Evento
Escuchador de Eventos
Generador de Eventos
add . . . . Listener
objeto1.add . . . . Listener (objeto2);
Generador de eventos
addActionListener
ActionListener
Ejemplo sencillo
import java.applet.Applet; import java.awt.*; import java.awt.event.*;
public class Eventos1 extends Applet implements ActionListener { public Button boton = new Button("Presiname"); public TextArea texto = new TextArea("**** Programacin en Java ****"); public void init(){ setLayout(new BorderLayout(10,10)); add(boton,"North"); add(texto,"Center"); boton.addActionListener(this); }
Ejemplo sencillo
Ejemplo
Ejemplo
public class Eventos2 extends Applet implements ActionListener { public Button botonArriba = new Button("Arriba"); public Button botonAbajo = new Button("Abajo"); public TextArea texto = new TextArea("**** Programacin en Java ****");
public void init(){ setLayout(new BorderLayout(10,10)); add(botonArriba,"North"); add(botonAbajo,"South"); add(texto,"Center"); botonArriba.addActionListener(this); botonAbajo.addActionListener(this); } public void actionPerformed(ActionEvent e){ if (botonArriba.equals(e.getSource())) texto.append("Se tecle el botn de ARRIBA\n"); else if (botonAbajo.equals(e.getSource())) texto.append("Se tecle el botn de ABAJO\n"); } }
Ejemplo
public class Eventos3 extends Applet implements MouseListener{ public Button boton = new Button("Hazme algo......."); public TextArea texto = new TextArea("**** Programacin en Java ****\n"); public void init(){ setLayout(new BorderLayout(10,10)); add(boton,"North"); add(texto,"Center"); boton.addMouseListener(this); } public void mousePressed(MouseEvent event) { texto.append("Se presion el mouse\n"); } public void mouseClicked(MouseEvent event) { texto.append("Se di click al mouse\n"); } public void mouseReleased(MouseEvent event) { texto.append("Se solt el mouse\n"); } public void mouseEntered(MouseEvent event) { texto.append("Entr el mouse\n"); } public void mouseExited(MouseEvent event) { texto.append("Se sali el mouse\n"); } }
Ejemplo
Manejadores de Eventos
Listeners
Son interfaces Se tienen que programar todos los mtodos definidos
Adapters
Son clases abstractas Los mtodos no hacen nada por omisin No se necesitan programar todos los mtodos
Paquete java.awt.event
MouseAdapter
Ejemplo
public class Eventos4 extends Applet{ public Button boton = new Button("Hazme algo......."); public TextArea texto = new TextArea("**** Programacin en Java ****\n"); public void init(){ setLayout(new BorderLayout(10,10)); add(boton,"North"); add(texto,"Center"); ManejaMouse mm = new ManejaMouse(texto); boton.addMouseListener(mm); } }
Choice
Es un estilo de men pop-up Te despliega una lista de opciones de las cuales puedes seleccionar una La lista de opciones no est constantemente desplegada como en el caso de List, se despliega al presionar un botn que es parte del choice El elemento seleccionado es el que queda desplegado
Mtodos de Choice
Se agrega un item con add(String) o addItem(String) al final de la lista de opciones Se quita un item de la lista con remove(int) o remove(String) select(String) y select(int) seleccionan un item de la lista getItem(int) regresa un String con el item correspondiente al ndice dado como parmetro getItemCount() regresa la cantidad de items que existen en el choice
Evento de Choice
Genera un evento ItemEvent cuando se selecciona alguna de sus opciones (item) Se puede obtener el item seleccionado con getSelectedItem() Tambin se puede obtener el ndice del item seleccionado con getSelectedIndex() Es necesario implementar ItemListener para capturar la seleccin de items
Ejemplo
public class ChoiceDemo extends Applet implements ItemListener{ Choice choice; Label etiqueta; public void init() { choice = new Choice(); choice.addItem("Uno"); choice.addItem("Dos"); choice.addItem("Tres"); choice.addItem("Cuatro"); choice.addItemListener(this); etiqueta = new Label("Selecciona un elemento"); add(etiqueta); add(choice); } public void itemStateChanged(ItemEvent e) { etiqueta.setText(choice.getSelectedItem()+ " "+ choice.getSelectedIndex()); } }
Ejemplo
List
Despliega una lista de items seleccionables Se configura la cantidad de items visibles en una ventana con scroll Se seleccionan los items en forma similar al choice Se puede establecer que se soporten selecciones mltiples, varios items seleccionados simultneamente
List
Adems de ItemEvent, la lista puede generar ActionEvent La manera de agregar items es similar a Choice, add(String) y addItem(String), adems soporta add(String,int) y addItem(String,int) La manera de obtener los items seleccionados es similar a Choice con getSelectedIndex() y getSelectedItem(), adems soporta getSelectedIndexes() y getSelectedItems() los cuales regresan arreglos
Ejemplo
public class ListDemo extends Applet implements ItemListener { List lista; TextArea texto = new TextArea(10,30); public void init() { lista = new List(5); lista.addItem("Uno"); lista.addItem("Dos"); lista.addItem("Tres"); lista.addItem("Cuatro"); lista.addItem("Cinco"); lista.addItem("Seis"); lista.addItem("Siete"); lista.addItemListener(this); add(texto); add(lista); } public void itemStateChanged(ItemEvent e) { texto.append("Se seleccion "+lista.getSelectedItem()+"\n"); }
Ejemplo
Eventos que representan interaccin directa del usuario Presionar una tecla, movimiento del ratn, presin y liberacin del botn del ratn
java.awt.event.FocusEvent
Componente tom el foco (gotFocus) o perdi el foco (lostFocus)
java.awt.event.KeyEvent
tecla presionada o liberada
java.awt.event.MouseEvent
botn del ratn presionado, liberado, movimiento del ratn, arrastre
java.awt.event.ContainerEvent
adicin y eliminacin de componentes de un contenedor
java.awt.event.WindowEvent
ventana activada, desactivada, abierta, cerrada, minimizada, etc.
Eventos semnticos
java.lang.Object | +---java.util.EventObject | +---java.awt.AWTEvent | +---java.awt.event.ActionEvent | +---java.awt.event.AdjustmentEvent | +---java.awt.event.ItemEvent | +---java.awt.event.TextEvent
Encapsulan la semntica (el significado) de un componente de interfaz grfica No estn asociados con ningn componente especfico Button, List, MenuItem disparan eventos de accin (ActionEvent)
Eventos semnticos
java.awt.event.ActionEvent Ejecutar un comando java.awt.event.AdjustmentEvent Se ajust un valor java.awt.event.ItemEvent Cambi el estado de un item java.awt.event.TextEvent Cambi el valor de un objeto de texto
Ejemplo: Cuando el usario hace click con el ratn sobre un botn, el botn recibe dos (o hasta tres) eventos de bajo nivel, mousePressed y mouseReleased, sin embargo el botn dispara un evento de alto nivel (semntico), el evento de accin (ActionEvent)
Listener (escuchadores)
Son interfaces Definen mtodos para cada evento que puedan generar los diferentes componentes Se registran con un componente que genera determinados tipos de eventos (add.....Listener) Existe una relacin de uno a uno entre los eventos que genera un componente y los mtodos que define una interface Listener Java trata de obtener un balance en la definicin de eventos y sus correspondientes mtodos. Suficiente granularidad sin caer en la definicin de todos los tipos de eventos
Listeners (escuchadores)
Listeners de bajo nivel
java.awt.event.ComponentListener java.awt.event.ContainerListener java.awt.event.FocusListener java.awt.event.KeyListener java.awt.event.MouseListener java.awt.event.MouseMotionListener java.awt.event.WindowListener
Listener semnticos
java.awt.event.ActionListener java.awt.event.AdjustmentListener java.awt.event.ItemListener java.awt.event.TextListener
ActionListener
MouseListener
MouseMotionListener
Interfaz separada ya que el arrastre y movimiento del ratn son demasiado comunes y resultara en demasiadas llamadas innecesarias Si no registras este tipo de Listener con algn objeto generador de eventos, dicho objeto no disparar los eventos de movimiento y arrastre
MouseEvent
Variables de MouseEvent
Mtodos de MouseEvent
public class Puntos extends Applet implements MouseListener{ Vector puntos = new Vector(); public void init() { this.addMouseListener(this); } public void mouseClicked(MouseEvent e){ puntos.addElement(e.getPoint()); this.repaint(); } public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {}
public void paint(Graphics g) { g.setColor(Color.red); Enumeration e = puntos.elements(); while (e.hasMoreElements()) { Point p = (Point) e.nextElement(); g.drawOval(p.x, p.y, 5, 5); } } }
Ejemplo
KeyListener
KeyEvent
public char getKeyChar() Regresa el carcter UNICODE de la tecla presionada public int getKeyCode() Regresa el cdigo de la tecla presionada, no el carcter
public static String getKeyText(int keyCode) Convierte a una representacin string el cdigo de la tecla presionada tales como END, F4, etc.
public long getWhen() Regresa la hora en que sucedi el evento en milisegundos transcurridos desde Enero 1, 1970
Teclas modificadoras
Regresan el estado de las teclas modificadoras: public boolean isShiftDown() public boolean isControlDown() public boolean isMetaDown() public boolean isAltDown()
public class PuntosModificados extends Applet implements MouseListener { Vector puntos = new Vector(); Vector colores = new Vector(); public void init() { this.addMouseListener(this); } public void mouseClicked(MouseEvent e) { puntos.addElement(e.getPoint()); int tecla = e.getModifiers(); if ((tecla & InputEvent.SHIFT_MASK) != 0) colores.addElement(Color.red); else colores.addElement(Color.blue); this.repaint(); }
Ejemplo
public void paint(Graphics g) { Enumeration e = puntos.elements(); Enumeration c = colores.elements(); while (e.hasMoreElements()) { Point p = (Point) e.nextElement(); Color color = (Color) c.nextElement(); g.setColor(color); g.fillOval(p.x-5, p.y-5, 10, 10); } }
}
Adapters (Adaptadores)
Implementan a la mayora de los Listener Los mtodos de los Listeners implementados no hacen nada En lugar de implementar un Listener se crea una subclase de un adaptador, de esta manera no se necesita programar todos los mtodos del Listener Reducen escritura de cdigo, programando solamente los mtodos necesarios
MouseAdapter
Ejemplo
Ejemplo
import java.applet.Applet; import java.awt.*; import java.awt.Toolkit; import java.awt.event.*;
public class Beep1 extends Applet{ Button fuente = new Button("Presiname"); ManejaMouse escuchador = new ManejaMouse(); public void init() { add(fuente); fuente.addMouseListener(escuchador); } } class ManejaMouse extends MouseAdapter{ public void mouseClicked(MouseEvent e){ Toolkit.getDefaultToolkit().beep(); } }
Consumiendo eventos
Evita el proceso normal de un evento por el componente que lo genera El evento es despachado a todos los escuchadores Slo se aplica a los eventos de bajo nivel de entrada (input events) public void consume() Ejemplo: Botn en un ambiente grfico
Ejemplo
TextField que solamente acepte nmeros Podemos filtrar las letras y otras teclas, pero ests de todas maneras sern procesadas en forma normal por el componente textField (se desplegarn a medida que se vayan tecleando) Si consumimos alguno de los eventos generados (letras tecleadas), ya no sern procesados por el componente
Ejemplo
import java.awt.*; import java.awt.event.*; import java.applet.*; public class ConsumeTeclas extends Applet{ TextField texto = new TextField(20); public void init(){ add(new Label("Teclea Slo nmeros:")); add(texto); texto.addKeyListener(new ManejaTeclas()); } } class ManejaTeclas extends KeyAdapter{ public void keyPressed(KeyEvent e) { int c = e.getKeyCode(); if (c<e.VK_0 || c>e.VK_9) e.consume(); } }
Listeners y Adapters
Listener Adapter Mtodos
MiBotn
Requisitos de MiBoton
Funcionalidad independiente
Retroalimentacin grfica al click sobre el botn, independiente del contexto donde se ponga
Tamao variable
Para poder utilizarlo en cualquier contexto grfico (Layout)
Funcionalidad
Poder asignarle un Listener, para que sirva de algo!!!!
MiBotn (1)
import java.awt.*; import java.awt.event.*;
public class MiBoton1 extends Canvas implements MouseListener{ boolean presionado = false; Color color;
public MiBoton1(Color color){ super(); this.color = color; addMouseListener(this); }
public void paint(Graphics g){ int diametro; Dimension tamano = new Dimension(getSize()); if (tamano.width < tamano.height) diametro = tamano.width; else diametro = tamano.height; setSize(diametro,diametro); g.setColor(color); if (presionado) g.setColor(color.darker()); g.fillOval(0,0,diametro-1,diametro-1); if (presionado) g.setColor(Color.white); else g.setColor(Color.black); g.drawOval(0,0,diametro-1,diametro-1); g.drawOval(1,1,diametro-3,diametro-3); }
public void mousePressed(MouseEvent e){ presionado=true; repaint(); } public void mouseClicked(MouseEvent e){ } public void mouseReleased(MouseEvent e){ presionado=false; repaint(); } public void mouseEntered(MouseEvent e){ } public void mouseExited(MouseEvent e){ } }
MiBotn (1)
import java.applet.*; import java.awt.event.*; import java.awt.*; public class MisBotones1 extends Applet{ MiBoton1 boton1 = new MiBoton1(Color.red); MiBoton1 boton2 = new MiBoton1(Color.blue); public void init(){ setLayout(new BorderLayout()); add(boton1,"Center"); add(boton2,North"); } }
Problemas con el tamao cuando el applet no puede deducir que tamao asignarle
import java.awt.*; import java.awt.event.*; public class MiBoton2 extends Canvas implements MouseListener{ boolean presionado = false; Color color; public MiBoton2(Color color){ super(); this.color = color; addMouseListener(this); } public void paint(Graphics g){ int diametro; Dimension tamano = new Dimension(getSize());
MiBoton (2)
diametro = Math.min(tamano.width,tamano.height);
setSize(diametro,diametro); g.setColor(color); if (presionado) g.setColor(color.darker()); g.fillOval(0,0,diametro-1,diametro-1); if (presionado) g.setColor(Color.white); else g.setColor(Color.black); g.drawOval(0,0,diametro-1,diametro-1); g.drawOval(1,1,diametro-3,diametro-3); }
public Dimension getPreferredSize(){ return new Dimension(50,50); }
public void mousePressed(MouseEvent e){ presionado=true; repaint(); } public void mouseClicked(MouseEvent e){ } public void mouseReleased(MouseEvent e){ presionado=false; repaint(); } public void mouseEntered(MouseEvent e){ } public void mouseExited(MouseEvent e){ } }
MiBoton (2)
import java.applet.*; import java.awt.event.*; import java.awt.*; public class MisBotones2 extends Applet{ MiBoton2 boton1 = new MiBoton2(Color.blue); MiBoton2 boton2 = new MiBoton2(Color.red); public void init(){ setLayout(new BorderLayout()); add(boton1,"Center"); add(boton2,"North"); } }
Problema: el rea que responde al ratn cubre terreno que est fuera del crculo Solucionarlo
Usando Miboton
import java.applet.*; import java.awt.event.*; import java.awt.*; public class MisBotones extends Applet{ MiBoton botonTextoAzul = new MiBoton(Color.blue); MiBoton botonTextoRojo = new MiBoton(Color.red); MiBoton botonTextoVerde = new MiBoton(Color.green); MiBoton botonFondoAzul = new MiBoton(Color.blue); MiBoton botonFondoRojo = new MiBoton(Color.red); MiBoton botonFondoVerde = new MiBoton(Color.green); TextArea texto = new TextArea(); Panel botonesTexto = new Panel(new FlowLayout(FlowLayout.CENTER)); Panel botonesFondo = new Panel(new FlowLayout(FlowLayout.CENTER)); : : :
Usando Miboton
: : public void init(){ setLayout(new BorderLayout()); botonesTexto.add(botonTextoAzul); botonesTexto.add(botonTextoRojo); botonesTexto.add(botonTextoVerde); botonesFondo.add(botonFondoAzul); botonesFondo.add(botonFondoRojo); botonesFondo.add(botonFondoVerde); add(botonesTexto,"North"); add(texto,"Center"); add(botonesFondo,"South"); ClickRaton c = new ClickRaton(); botonTextoAzul.addMouseListener(c); botonTextoRojo.addMouseListener(c); botonTextoVerde.addMouseListener(c); botonFondoAzul.addMouseListener(c); botonFondoRojo.addMouseListener(c); botonFondoVerde.addMouseListener(c); } : : :
Usando Miboton
: : : class ClickRaton extends MouseAdapter{ public void mouseClicked(MouseEvent e){ MiBoton b = new MiBoton(Color.black); b = (MiBoton) e.getSource(); if (b.equals(botonTextoAzul)) texto.setForeground(Color.blue); else if (b.equals(botonTextoRojo)) texto.setForeground(Color.red); else if (b.equals(botonTextoVerde)) texto.setForeground(Color.green); else if (b.equals(botonFondoAzul)) texto.setBackground(Color.blue); else if (b.equals(botonFondoRojo)) texto.setBackground(Color.red); else if (b.equals(botonFondoVerde)) texto.setBackground(Color.green); } }
}
CardLayout
Similar a las cartas en una baraja, de la cual puedes ver una sola a la vez Se pueden mostrar cada una de las cartas:
Pidiendo la primera o ltima carta del Layout (en el orden en que fueron agregadas al contenedor) Pidiendo carta siguiente o anterior en forma secuencial Especificando una de las cartas con un nombre especfico
CardLayout
Para agregar componentes se debe usar:
add(componente,nombre)
Mtodos de acceso:
public public public public public void void void void void first(Container parent) next(Container parent) previous(Container parent) last(Container parent) show(Container parent, String name)
import java.awt.*; import java.awt.event.*; import java.applet.*; public class TarjetaLayout extends Applet implements ActionListener, ItemListener{ Panel p1 = new Panel(); Panel p2 = new Panel(); Panel p3 = new Panel(); Panel c = new Panel(); Panel botones = new Panel(); Button b1 = new Button("Primero"); Button b2 = new Button("Ultimo"); Button b3 = new Button(">>"); Button b4 = new Button("<<"); Choice opcion = new Choice(); CardLayout tarjeta = new CardLayout();
Ejemplo
public void init(){ setLayout(new BorderLayout()); opcion.addItem(""); opcion.addItem("Primera"); opcion.addItem("Segunda"); opcion.addItem("Tercera"); botones.add(b1); botones.add(b4); botones.add(b3); botones.add(b2); p1.add(new Label("Este es la primera")); p1.add(new Button("Botn")); p2.add(new Label("Este es la segunda")); p2.add(new TextField(20)); p3.add(new Label("Este es la tercera")); c.setLayout(tarjeta); c.add(p1,"uno"); c.add(p2,"dos"); c.add(p3,"tres"); add(opcion,"North"); add(c,"Center"); add(botones,"South"); b1.addActionListener(this); b2.addActionListener(this); b3.addActionListener(this); b4.addActionListener(this); opcion.addItemListener(this); }
public void actionPerformed(ActionEvent e){ if (e.getSource().equals(b3)) tarjeta.next(c); else if (e.getSource().equals(b4)) tarjeta.previous(c); else if (e.getSource().equals(b1)) tarjeta.first(c); else if (e.getSource().equals(b2)) tarjeta.last(c); opcion.select(0); }
public void itemStateChanged(ItemEvent e){ switch (opcion.getSelectedIndex()){ case 1: ((CardLayout)c.getLayout()).show(c,"uno"); break; case 2: ((CardLayout)c.getLayout()).show(c,"dos"); break; case 3: ((CardLayout)c.getLayout()).show(c,"tres"); break; } } }
Ejemplo
GridBagLayout
Despliega componentes en un enrejado de renglones y columnas A diferencia del GridLayout las celdas no estn restringidas a ser de igual tamao No necesita que los componentes sean del mismo tamao Mantiene un enrejado rectangular dinmico de celdas, en el cual los componentes puede ocupar una o ms celdas
GridBagConstrains
Cada componente de un GridBagLayout tiene asociada una instancia de esta clase (GridBagConstrains) Especifica la manera en que ser desplegado un componente particular Tiene varias variables de instancia que especifican como se desplegar un objeto que tenga asociado una instancia de esta clase
Variables de GridBagConstrains
gridx, gridy
Especifica la celda de la esquina superior izquierda del componente (gridx=0 y gridy=0 celda de la esquina superior izquierda del Layout). Default es GridBagConstrains.RELATIVE que define que el componente se coloque a la izquierda (gridx) o abajo (gridy) del componente agregado justo antes.
gridwidth, gridheight
Define el nmero de celdas que ocupa el componente horizontal (gridwidth) y verticalmente (gridheight). El default es 1. GridBagConstrains.REMAINDER (default) indica que el componente es el ltimo de su rengln (gridwidth) o columna (gridheight). GridBagConstrains.RELATIVE indica que el componente es el penltimo de su rengln (gridwidth) o columna (gridheight).
Variables de GridBagConstrains
fill
Para especificar como el componente llenar el rea asignada, en caso de que sta sea de mayor tamao que el componente. GridBagConstrains.NONE (default), GridBagConstrains.HORIZONTAL (el componente llena su rea horizontal, pero no cambia su altura, GridBagConstrains.VERTICAL (llena su rea vertical, pero no cambia su ancho), GridBagConstrains.BOTH (llena su rea completamente)
insets
Define el espacio mnimo entre componentes
ipadx, ipady
Especifica el relleno interno del componente, es decir cuanto se le aadir al tamao mnimo de ste (minumum size), tanto horizontal (ipadx) como horizontalmente (ipady)
Variables de GridBagConstrains
anchor
Alineacin del componente dentro del su rea definida, en caso de el componente sea ms pequeo que el rea asignada a l. GridBagConstrains.CENTER (default), GridBagConstrains.NORTH, GridBagConstrains..NORTHEAST, GridBagConstrains.EAST, GridBagConstrains.SOUTEAST, GridBagConstrains.SOUTH, GridBagConstrains.SOUTHWEST, GridBagConstrains.WEST, GridBagConstrains.NORTHWEST
weightx, weighty
Especifica como se distribuye el rea total del Layout por componente (valor entre 0.0 y 1.0), es importante en caso de que se cambie el tamao del Layout. Default para ambos es 0.0
import java.awt.*; public class LayoutGridBag1 extends Frame{ Label lApellido = new Label("Apellido: "); Label lNombre = new Label("Nombre: "); TextField tApellido = new TextField(); TextField tNombre = new TextField(); GridBagLayout g = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints();
Ejemplo
public LayoutGridBag1(){ setLayout(g); c.fill = GridBagConstraints.BOTH; c.gridx = 0; c.gridy = 0; c.gridwidth = 1; c.gridheight = 1; c.weightx = 0.0; c.weighty = 0.0; g.setConstraints(lApellido,c); add(lApellido); c.gridy = 1; g.setConstraints(lNombre,c); add(lNombre); c.gridx = 1; c.gridy = 0; c.weightx = 1.0; g.setConstraints(tApellido,c); add(tApellido); c.gridy = 1; g.setConstraints(tNombre,c); add(tNombre); pack(); show(); }
Ejemplo
Ejemplo (LayoutGridBag2)
Label letrero = new Label("Ejemplo 2 de GriBagLayout"); Button boton1 = new Button("Botn 1"); Button boton2 = new Button("Botn 2"); Button boton3 = new Button("Botn 3"); TextField texto = new TextField(); Choice choice = new Choice(); List lista = new List(); TextArea area = new TextArea(); GridBagLayout g = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints();
setLayout(g); c.fill = GridBagConstraints.BOTH; c.weightx = 1.0; c.gridwidth = GridBagConstraints.REMAINDER; g.setConstraints(letrero,c); letrero.setAlignment(Label.CENTER); add(letrero); c.gridwidth = 1; c.weightx = 0.0; c.fill = GridBagConstraints.NONE; g.setConstraints(boton1,c); add(boton1); g.setConstraints(boton2,c); add(boton2); c.gridwidth = GridBagConstraints.REMAINDER; g.setConstraints(boton3,c); add(boton3); c.gridwidth = 2; c.gridheight = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.BOTH; c.weightx = 1.0; c.weighty = 1.0; g.setConstraints(area,c); add(area); c.weightx = 0.0; c.gridwidth = GridBagConstraints.REMAINDER; c.gridheight = 1; g.setConstraints(lista,c); add(lista); c.weighty = 0.0; c.gridheight = GridBagConstraints.REMAINDER; g.setConstraints(choice,c); add(choice); pack(); show();
Ejemplo
(LayoutGridBag2)
Ejemplo (LayoutGridBag2)
Ejemplo (LayoutGridBag3)
Label letrero = new Label("Ejemplo 3 de GriBagLayout"); Button boton1 = new Button("Botn 1"); Button boton2 = new Button("Botn 2"); Button boton3 = new Button("Botn 3"); TextField texto = new TextField(); Choice choice = new Choice(); List lista = new List(); TextArea area = new TextArea(); GridBagLayout g = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints();
Ejemplo (LayoutGridBag3)
setBackground(Color.lightGray); setSize(500,300); letrero.setBackground(Color.blue); letrero.setForeground(Color.white); letrero.setFont(new Font("Serif",Font.BOLD,14)); letrero.setAlignment(Label.CENTER); area.setBackground(Color.red); lista.setBackground(Color.yellow);
Ejemplo (LayoutGridBag3)
public void estableceDefaults(GridBagConstraints c){ c.gridx = GridBagConstraints.RELATIVE; c.gridy = GridBagConstraints.RELATIVE; c.gridwidth = 1; c.gridheight = 1; c.fill = GridBagConstraints.NONE; c.ipadx = 0; c.ipady = 0; c.anchor = GridBagConstraints.CENTER; c.weightx = 0.0; c.weighty = 0.0; }
Ejemplo
(LayoutGridBag3)
estableceDefaults(c); c.weighty = 1.0; c.fill = GridBagConstraints.BOTH; c.gridwidth = GridBagConstraints.REMAINDER; g.setConstraints(lista,c); add(lista); estableceDefaults(c); c.gridwidth = GridBagConstraints.REMAINDER; c.gridheight = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.HORIZONTAL; g.setConstraints(choice,c); add(choice);
Ejemplo
(LayoutGridBag3)
Cubriremos las clases Frame, Menu, MenuBar, WindowAdapter Adems veremos como se puede ejecutar la aplicacin desde Windows sin la necesidad de que se abra un ventana de DOS
Frame
Un Frame es una ventana con un ttulo y un borde Generan los siguientes eventos: WindowOpened, WindowClosing, WindowClosed, WindowIconified, WindowDeiconified, WindowActivated, WindowDeactivated. Todas las aplicaciones con interfaz grfica necesitan crear un frame para poder desplegarse Los applets tambin pueden abrir frames, estos se abren como ventanas independientes El Layout por default de un frame es BorderLayout
Aplicacin
: : Panel botones = new Panel(new GridLayout(8,0,0,10)); Button boton1 = new Button("Insertar"); Button boton2 = new Button("Borrar"); Button boton3 = new Button("Imprimir"); Button boton4 = new Button("Terminar"); TextArea texto = new TextArea(); : : botones.add(new Label("Opciones")); botones.add(new Label()); botones.add(new Label()); botones.add(new Label()); botones.add(boton1); botones.add(boton2); botones.add(boton3); botones.add(boton4); add(texto,"Center"); add(botones,"East"); : :
Aplicacin
Aplicacin
public class Aplicacion extends Frame implements ActionListener{ : : boton4.addActionListener(this); : : public void actionPerformed(ActionEvent e){ dispose(); System.exit(0); } : :
dispose() Destruye el frame, libera los recursos que tiene System.exit(0) Termina la ejecucin de la mquina virtual, por convencin un valor diferente de cero indica condicin de error
WindowListener
WindowAdapter
: : ManejaVentana mv = new ManejaVentana(this); addWindowListener(mv); : : class ManejaVentana extends WindowAdapter{ Frame f; public ManejaVentana(Frame f){ this.f = f; } public void windowClosing(WindowEvent e){ f.dispose(); System.exit(0); }
Aplicacin
Menu y MenuBar
Mens pueden existir slo en Barras de Men (MenuBar) Y las barras de men pueden existir slo en frames Items se agregan a Menu con add() Menu se agrega a MenuBar con add() La barra de men se agrega al Frame con setMenuBar()
: : MenuBar barraMenu = new MenuBar(); Menu menu1 = new Menu("Menu 1"); Menu menu2 = new Menu("Menu 2"); : : menu1.add("Opcin 1"); menu1.add("Opcin 2"); menu1.add("Opcin 3"); menu2.add("Opcin I"); menu2.add("Opcin II"); menu2.add("Opcin III"); barraMenu.add(menu1); barraMenu.add(menu2); setMenuBar(barraMenu);
Aplicacin
: : MenuBar barraMenu = new MenuBar(); Menu menu1 = new Menu("Menu 1"); Menu menu2 = new Menu("Menu 2"); MenuItem m11 = new MenuItem("Opcin 1"); MenuItem m12 = new MenuItem("Opcin 2"); MenuItem m13 = new MenuItem("Opcin 3"); MenuItem m21 = new MenuItem("Opcin I"); MenuItem m22 = new MenuItem("Opcin II"); MenuItem m23 = new MenuItem("Opcin III"); Menu m24 = new Menu("Opcin IV"); MenuItem m241 = new MenuItem("SubOpcin IV"); : : menu1.add(m11); menu1.add(m12); menu1.add(m13); m21.setEnabled(false); menu2.add(m21); m22.setShortcut(new MenuShortcut(KeyEvent.VK_5)); menu2.add(m22); menu2.addSeparator(); menu2.add(m23); m24.add(m241); menu2.add(m24); barraMenu.add(menu1); barraMenu.add(menu2); setMenuBar(barraMenu); :
Aplicacin
Aplicacin
: MenuItem m13 = new MenuItem("Salir"); : m13.addActionListener(this); : public void actionPerformed(ActionEvent e){ dispose(); System.exit(0); } :
Aplicacin
import java.awt.*; import java.awt.event.*; public class Aplicacion extends Frame implements ActionListener{ Panel botones = new Panel(new GridLayout(8,0,0,10)); Button boton1 = new Button("Insertar"); Button boton2 = new Button("Borrar"); Button boton3 = new Button("Imprimir"); Button boton4 = new Button("Terminar"); TextArea texto = new TextArea(); MenuBar barraMenu = new MenuBar(); Menu menu1 = new Menu("Menu 1"); Menu menu2 = new Menu("Menu 2"); MenuItem m11 = new MenuItem("Opcin 1"); MenuItem m12 = new MenuItem("Opcin 2"); MenuItem m13 = new MenuItem("Salir"); MenuItem m21 = new MenuItem("Opcin I"); MenuItem m22 = new MenuItem("Opcin II"); MenuItem m23 = new MenuItem("Opcin III"); Menu m24 = new Menu("Opcin IV"); MenuItem m241 = new MenuItem("SubOpcin IV");
public Aplicacion(){ setTitle("Aplicacin"); setSize(300,300); setLocation(100,100); botones.add(new Label("Opciones")); botones.add(new Label()); botones.add(new Label()); botones.add(new Label()); botones.add(boton1); botones.add(boton2); botones.add(boton3); botones.add(boton4); add(texto,"Center"); add(botones,"East"); menu1.add(m11); menu1.add(m12); menu1.add(m13); m21.setEnabled(false); menu2.add(m21); m22.setShortcut(new MenuShortcut(KeyEvent.VK_5)); menu2.add(m22); menu2.addSeparator(); menu2.add(m23); m24.add(m241); menu2.add(m24); barraMenu.add(menu1); barraMenu.add(menu2); setMenuBar(barraMenu); m13.addActionListener(this); boton4.addActionListener(this); ManejaVentana mv = new ManejaVentana(this); addWindowListener(mv); show(); }
Aplicacin
Aplicacin
public void actionPerformed(ActionEvent e){ dispose(); System.exit(0); } public static void main(String args[]){ System.out.println("Inicio"); new Aplicacion(); System.out.println("Final"); }
}
class ManejaVentana extends WindowAdapter{ Frame f;
Manejo de Excepciones
Excepciones
Una excepcin es un evento que sucede durante la ejecucin normal de un programa y ocasiona que se cambie el flujo normal de instrucciones Java maneja excepciones para indicar que ha ocurrido una condicin anormal Los mtodos arrojan excepciones
Excepciones
Java obliga a utilizar excepciones para evitar caer en errores que ocasionen que el programa termine en forma anormal y/o afecte el funcionamiento del sistema Java provee un mecanismo para atrapar excepciones, el cual nos da un puerta de escape en caso de que ocurra algn error y poder continuar con la ejecucin del programa
Excepciones
Nos ahorran cdigo, ya que no tenemos que realizar toda la verificacin de una posible accin (ej. abrir un archivo) Java establece una serie de excepciones que tienen que arrojar ciertos mtodos Podemos programar nuestros mtodos para que arrojen excepciones creadas por nosotros
import java.io.*; public class NoCompila { private FileReader entrada; public NoCompila(String nombreArchivo) { entrada = new FileReader(nombreArchivo); } }
Ejemplo
import java.io.*;
public class SiCompila {
try /catch
La forma de verificar si es posible realizar alguna instruccin sin problemas, en caso contrario se atrapa la excepcin arrojada
Ejemplo
import java.io.*;
public class Excepciones { public static void main (String[] args){ FileReader entrada; String nombreArchivo = args[0]; try{ entrada = new FileReader(nombreArchivo); System.out.println("Archivo abierto sin problemas"); }catch (FileNotFoundException e){ System.out.println("Archivo no existe"); } System.out.println("Programa termin normalmente"); } }
throws
Indica que un mtodo arroja una excepcin determinada y sta debe ser atrapada con catch para poder utilizarlo
Excepciones
Se pueden atrapar todas las excepciones particulares de cada mtodo o agrupar varias llamadas a mtodos y atrapar las excepciones en bloque Depende del diseo de tu programa y de la legibilidad de cdigo que quieras
Ejemplo
import java.io.*;
public class Excepcion { public static void main (String[] args){ FileReader entrada; try{ String nombreArchivo = args[0]; String entero = args[1]; entrada = new FileReader(nombreArchivo); System.out.println("Archivo abierto sin problemas"); System.out.println(Integer.parseInt(entero)*2); }catch (FileNotFoundException e){ System.out.println("Archivo no existe"); }catch (NumberFormatException e){ System.out.println("Nmero no adecuado"); }catch (ArrayIndexOutOfBoundsException e){ System.out.println("Faltan argumentos"); } System.out.println("Programa termin normalmente"); } }
Ejemplo
import java.io.*;
public class ExcepcionF { public static void main (String[] args){ FileReader entrada; try{ String nombreArchivo = args[0]; String entero = args[1]; entrada = new FileReader(nombreArchivo); System.out.println("Archivo abierto sin problemas"); System.out.println(Integer.parseInt(entero)*2); }catch (FileNotFoundException e){ System.out.println("Archivo no existe"); }catch (NumberFormatException e){ System.out.println("Nmero no adecuado"); }finally{ System.out.println("Siempre se ejecuta"); } System.out.println("Programa termin normalmente"); } }
finally
finally
finally siempre se ejecuta Nos permite hacer una limpieza de los recursos que un mtodo pudo haber dejado abiertos o en uso por la finalizacin abrupta debido a una excepcin Eso nos evita el tener que duplicar cdigo en cada catch para hacer la limpieza
Programacin de Hilos
(Threads)
Hilos (Threads)
Contexto de ejecucin, proceso liviano (lightweight) Un flujo secuencial de instrucciones dentro de un programa
Hilo
Programa
Multiprocesos vs Multihilos
Multiproceso:
Dos o ms programas (procesos) independientes ejecutndose en forma paralela Cada proceso tiene su propio espacio de memoria, su propio conjunto de variables, su propia pila, etc. El control lo tiene el sistema operativo
Multihilo:
Dos o ms tareas ejecutndose en forma paralela dentro de un programa Comparten los recursos del programa El control lo tiene el programa
Programa
Multihilo
Recursos variables, pila, archivos, sockets, etc.
Hilos
Hilos
Multihilos en Java
Java tiene un soporte natural para multihilos main, Garbage Collection, actualizaciones de pantalla; todos corren en su propio hilo Al contrario de multiproceso en el cual cada programa es independiente, en multihilo el programador tiene la responsabilidad de que los hilos se ejecuten en forma adecuada, ya que todos comparten los recursos del programa, y se tiene que poner especial atencin en no caer en problemas como dead-lock y starvation
Programas ms adecuados
Desplegar barra de progreso mientras se realiza alguna tarea tardada
El mtodo run()
Mtodo de la clase Thread, es el que realiza el trabajo, el que se llama para que arranque un hilo su ejecucin Est mtodo es el que se tiene que redefinir (override) para que tu hilo haga algo El mtodo run en la clase Thread no hace nada Cuando un objeto tiene en ejecucin el mtodo run(), ese hilo est compitiendo con los dems hilos activos por recursos del sistema (CPU) Cuando un objeto termina la ejecucin de su mtodo run(), el hilo se muere
La clase Thread
Comentarios preliminares
El arranque de hilos se realiza en dos pasos: Crear una instancia de la clase Thread Llamar al mtodo run() del objeto creado La llamada al mtodo run() no se hace directamente, sino que se llama al mtodo start() del objeto, esto causa que la mquina virtual llame a run() El mtodo sleep(long x) de la clase Thread, ocasiona que el hilo deje de competir por los recursos durante x milisegundos, despus de ese tiempo, comienza a pelear por recursos otra vez Al llamar a start, automticamente hay dos hilos corriendo, el que se arranc con start() y el que ejecut la llamada
Implementando Runnable
public class Hilos2{ public static void main(String[] args){ Hilo1 h1 = new Hilo1("Uno"); Hilo1 h2 = new Hilo1("Dos"); Thread t1 = new Thread(h1); Thread t2 = new Thread(h2); t1.start(); t2.start(); } } class Hilo1 implements Runnable{ String s; public Hilo1(String s){ this.s = s; } public void run(){ for(int i=0; i<10; i++){ System.out.println(s+" "+i); try{ Thread.sleep(Math.round(Math.random()*1000)); }catch(InterruptedException e){} } } }
Estados de un hilo
Hilo nuevo
Hilo recin creado
Ejecutable
Compitiendo por CPU
Detenido
No compitiendo por CPU
Muerto
Estados de un hilo
New Thread() start() yield() - sleep(x) - wait() - bloqueado en I/O - suspend()
Nuevo
- El mtodo run() termin su ejecucin - stop()
Ejecutable
Detenido
- Transcurrieron x msegs - notify() o notifyAll() - se complet I/O - resume()
Muerto
Estados de un hilo
new Tread(...)
Creado, pero no todava no comienza ejecucin
start()
crea los recursos necesarios para su ejecucin, lo deja listo para que la mquina virtual lo ponga a correr llamando al mtodo run(), compite por los recursos del sistema
Muerto
Termin run(), una vez muerto un hilo no puede volver a ejecucin
import java.awt.*; import java.applet.*; import java.awt.event.*; public class Hilos3 extends Applet implements ActionListener{
Ejemplo
Button boton1 = new Button boton2 = new Button boton3 = new TextField cuenta1 = TextField cuenta2 = TextField cuenta3 = Cuenta t1, t2, t3;
Button("Para el 1"); Button("Para el 2"); Button("Para el 3"); new TextField("0"); new TextField("0"); new TextField("0");
public void init(){ setLayout(new GridLayout(2,3)); add(cuenta1); add(cuenta2); add(cuenta3); add(boton1); add(boton2); add(boton3); boton1.addActionListener(this); boton2.addActionListener(this); boton3.addActionListener(this); }
public void start(){ t1 = new Cuenta(500,cuenta1); t2 = new Cuenta(1000,cuenta2); t3 = new Cuenta(2000,cuenta3); t1.start(); t2.start(); t3.start(); } public void stop(){ t1.contando = false; t2.contando = false; t3.contando = false; } public void actionPerformed(ActionEvent e){ if (e.getSource().equals(boton1)) t1.contando = false; else if (e.getSource().equals(boton2)) t2.contando = false; else if (e.getSource().equals(boton3)) t3.contando = false; } }
Ejemplo
class Cuenta extends Thread{ long deltaT; int cuenta=0; TextField caja; boolean contando = true;
public Cuenta(long deltaT, TextField caja){ this.deltaT = deltaT; this.caja = caja; } public void run(){ while(contando){ cuenta ++; caja.setText(Integer.toString(cuenta)); try{ sleep(deltaT); } catch (InterruptedException e){} } caja.setText("Ya se muri"); } }
Ejemplo
Prioridades
Todos los hilos tienen una prioridad relativa a otros hilos La mquina virtual selecciona al hilo de mayor prioridad en estado ejecutable y lo pone a correr El hilo que est en ejecucin hasta:
llama a yield() Pasa a estado no ejecutable (parado) otro hilo de mayor prioridad pasa a estado ejecutable
Un hilo hereda su prioridad del hilo que lo crea La prioridad de un hilo se puede modificar con setPriority(int) Las constantes disponibles MIN_PRIORITY, NORM_PRIORITY, MAX_PRIORITY Si un hilo de alta prioridad se pone en ejecucin y no tiene nada de I/O puede acaparar todo el CPU (hilos egoistas, selfish threads) Es conveniente que el hilo ejecute yield() o sleep() a intervalos regulares para dar la oportunidad de que otros hilos puedan correr yield() slo cede el CPU a hilos de igual prioridad
Constructores
Sincronizacin de hilos
Es necesario sincronizar el acceso a recursos compartidos para evitar inconsistencias en los resultados Si dos hilos acceden a un mismo recurso, el orden de ejecucin es impredecible, depende de la mquina virtual y otros factores del sistema (carga, ejecucin de otros hilos, etc) Java implementa un mecanismo de monitores, si un objeto es identificado con synchronized se le asocia un candado (lock)
Un monitor permite el acceso serializado y no simultneo a un objeto
synchronized
Hilos que quieran acceder a un objeto sincronizado se ponen en fila de espera hasta que el objeto quede desocupado (unlock) Slo un hilo puede estar dentro de un objeto sincronizado Se recomienda utilizar synchronized a nivel mtodo, pero puede sincronizar cualquier seccin de cdigo (seccin crtica) Cada objeto tiene un solo candado, si un hilo entra a un mtodo sincronizado, el objeto pone el candado a todos los mtodos sincronizados, es decir ningn otro hilo puede ejecutar ningn mtodo sincronizado del objeto, hasta que el hilo poseedor del candado lo libere La manera de liberar el candado en un objeto es cuando se termina la ejecucin del un mtodo sincronizado No vale la pena sincronizar asignaciones de algunos datos primitivos porque son atmicas Excesiva sincronizacin tiene un impacto relevante en el rendimiento
Ejemplo
Contador
contador
Incrementa Imprime
Decrementa Imprime
Suma
Resta
public class NoSincronizado{ public static void main(String args[]){ Contador c = new Contador(); Suma s = new Suma(c); Resta r = new Resta(c); s.start(); r.start(); } }
class Contador{ public int contador = 0; public void sumaUno(){ contador++; System.out.print("Suma: "); System.out.println(contador); } public void restaUno(){ contador--; System.out.print("Resta: "); System.out.println(contador); }
Ejemplo
class Suma extends Thread{ Contador c; public Suma(Contador c){ this.c = c; } public void run(){ for(int i=0;i<10;i++) c.sumaUno(); } } class Resta extends Thread{ Contador c; public Resta(Contador c){ this.c = c; } public void run(){ for(int i=0;i<10;i++) c.restaUno(); } }
Ejemplo
public class Sincronizado{ public static void main(String args[]){ Contador c = new Contador(); Suma s = new Suma(c); Resta r = new Resta(c); s.start(); r.start(); } }
Ejemplo
class Suma extends Thread{ Contador c;
public Suma(Contador c){ this.c = c; } public void run(){ for(int i=0;i<10;i++) c.sumaUno(); } }
class Resta extends Thread{ Contador c; public Resta(Contador c){ this.c = c; } public void run(){ for(int i=0;i<10;i++) c.restaUno(); } }
Ejemplo
wait() y notify()
Son miembros de la clase java.lang.Object Se llaman desde mtodos o bloques sincronizados wait() hace que un hilo ceda su candado sobre un objeto y para su ejecucin notify() elige un hilo que este esperando (en wait) y lo despierta Si hay varios hilos esperando se despertar al de prioridad ms alta Si hay varios hilos de igual prioridad esperando no se garantiza cual es que ser despertado Los hilos se ponen en fila de espera para accesar un objeto con monitor si:
tratan de llamar un mtodo sincronizado mientras otro hilo est usando el objeto llaman explcitamente a wait() dentro de un mtodo sincronizado
Recomendaciones
No usar stop(), suspend() o resume() Cuidado con la sincronizacin excesiva Usar notifyAll() en lugar de notify() Reducir las prioridades de los hilos de tarea en el fondo o animaciones
Manejo de Grficas
Imgenes y Animacin
La clase Canvas
La clase Canvas debe ser extendida, es decir debe ser superclase de alguna clase que programes, ya que no hace nada por si sola Es una manera de que puedas implementar tu propio componente, dndole el funcionamiento que desees (un ejemplo ms adelante) Tambin es til como rea de dibujo y para desplegar imgenes Cuando se utiliza Canvas hay que tener mucho cuidado con programar los mtodos minimumSize() y preferredSize(), para que reflejan el tamao que deseas en tu objeto tipo Canvas, porque corres el peligro de que tu canvas tome un tamao muy pequeo o definitivamente sea invisible Lo anterior depende de que Layout utilices dentro de tu contenedor para asignarle espacio a tu objeto Canvas
Coordenadas de un componente
(0,0)
x
Componente
(ancho-1,alto-1)
width height
minimumSize() y preferredSize() Cuando un layout trata de desplegar sus componentes ejecuta estos mtodos en todos los objetos que tiene para acomodarlos adecuadamente Importante especificar para Canvas ya que no tienen un tamao definido cuando son creados Regresan un objeto tipo Dimension
repaint()
Para indicarle a un componente que se debe de redibujar La llamada a este mtodo ocasiona que AWT ejecute el mtodo update() del componente, el cual a su vez llama a paint()
repaint()
public void repaint()
Peticin a AWT que ejecute el mtodo update() (paint()) del componente lo ms pronto posible
public void repaint(long time, int x, int y, int width, int height)
Peticin a AWT que ejecute el mtodo update() (paint()) del componente time milisegundos ms tarde, pero que rdibuje slo la porcin especificada por el rea rectangular
Necesitamos un Canvas para hacer todo el dibujo (el cuadro azul y la bola roja) Necesitamos un ciclo para que redibuje todo el Canvas con la bola en diferente posicin cada vez (incrementando la coordenada horizontal) El ciclo puede ir dentro del paint(), pero eso hara que nuestro objeto consumiera todo el CPU, adems de que una vez que se llamara a paint() jams se saldra y nuestro applet no podra hacer otra cosa.
Entonces es conveniente que el ciclo de pintado sea un hilo, de esta manera nuestro objeto podra estar en un applet con otros objetos sin consumir todos los recursos Es adecuado que la prioridad del hilo sea la ms baja ya que generalmente una animacin NO ES lo ms importante dentro de una applet o aplicacin Adems tenemos que hacer una verificacin de las coordenadas para hacer algo cuando la bola llega al extremo izquierdo (que se regrese o aparezca del lado izquierdo nuevamente)
Haremos que aparezca del lado izquierdo Adems nuestro applet tendr que comportarse adecuadamente, es decir debe de jugar alegremente y sin pelearse mucho con los otros nios (applets e hilos) Lo anterior incluye parar su ejecucin cuando ya no este visible y continuar su movimiento cuando el usuario revisita nuestra pgina Controlar el movimiento con los mtodos start() y stop() del applet Asi es que adelante.................
class CuadroConBola1 extends Canvas implements Runnable{ Color colorCuadro,colorBola; int posicion = 0; boolean vivo = true; boolean moviendo = true; boolean derecha = true; int diametroBola; Dimension tamano = new Dimension();
Ejemplo
Ejemplo
public void paint(Graphics g){ tamano = getSize(); El tamao no es fijo, depende diametroBola = tamano.height/2; g.setColor(colorCuadro); del tamao del contexto grfico g.fillRect(0,0,tamano.width,tamano.height); donde insertemos nuestra figura g.setColor(colorBola); g.fillOval(posicion,tamano.height/4,diametroBola-1,diametroBola-1); g.setColor(Color.black); g.drawOval(posicion,tamano.height/4,diametroBola-1,diametroBola-1); g.drawOval(posicion+1,tamano.height/4+1,diametroBola-3,diametroBola-3); } }
import java.awt.event.*; public class BolaMovil1 extends Applet{ CuadroConBola1 x; Thread t; public void init(){ setLayout(new BorderLayout()); x = new CuadroConBola1(Color.yellow,Color.red); t = new Thread(x,"bola1"); add(x,"Center"); t.start(); } public void start(){ x.moviendo = true; } public void stop(){ x.moviendo = false; } public void destroy(){ x.vivo = false; }
Ejemplo
Para que tome un tamao, dado que un Canvas no tiene un tamao por default
Problema
El problema es inmediatamente visible y es un molesto parpadeo, esto ocurre por la forma en que AWT maneja el dibujo de componentes. Cada vez que AWT detecta que un componente necesita redibujarse por una llamada a repaint() del componente, AWT llama a update() de ese componente Y update() borra el fondo del componente antes de llamar a paint() que es la rutina que normalmente tu reprogramas para dibujar algo
Proceso de repaint()
objeto.repaint()
objeto.paint()
Solucin
Reprogramar el mtodo update() para que no borre el fondo y dibuje directamente lo que queremos, es decir hacer en update() lo que normalmente hacemos en paint() El mtodo paint() de todas maneras se necesita porque AWT lo llama directamente cuando necesita actualizar los objetos por el despliegue de ventanas
import java.awt.*; import java.applet.*; import java.awt.event.*; public class BolaMovil2 extends Applet{ CuadroConBola2 x; Thread t; public void init(){ setLayout(new BorderLayout()); x = new CuadroConBola2(Color.blue,Color.red); t = new Thread(x,"bola1"); add(x,"Center"); t.start(); } public void start(){ x.moviendo = true; } public void stop(){ x.moviendo = false; } public void destroy(){ x.vivo = false; } }
Ejemplo
Ejemplo
public void paint(Graphics g){ update(g); } public void update(Graphics g){ tamano = getSize(); diametroBola = tamano.height/2; g.setColor(colorCuadro); g.fillRect(0,0,tamano.width,tamano.height); g.setColor(colorBola); g.fillOval(posicion,tamano.height/4,diametroBola-1,diametroBola-1); g.setColor(Color.black); g.drawOval(posicion,tamano.height/4,diametroBola-1,diametroBola-1); g.drawOval(posicion+1,tamano.height/4+1,diametroBola-3,diametroBola-3); }
Problemita
Ya se elimin el parpadeo del rectngulo grande, pero todava vemos parpadeo en el crculo, esto inicialmente ya no lo podemos evitar ya que reprogramamos el update(), el parpadeo del crculo se debe a que se limpia el crculo por el dibujo del rectngulo, es el mismo problema que tenamos con el update() original pero ahora nosotros somos los que borramos el fondo del crculo
Solucin
Una tcnica que se utiliza mucho en el manejo de grficas es conocidad como Double Buffering La idea es manejar un rea de memoria intermedia para hacer toda la manipulacin grfica fuera de pantalla, y una vez que este completa vaciar esa rea a pantalla Nos tardamos lo mismo en dibujar todo, pero el despliegue es mucho ms rpido ya que es movimiento de memoria a memoria
Double Buffering
Buffer intermedio
Pantalla
hacer dibujo fuera de pantalla
class CuadroConBola3 extends Canvas implements Runnable{ : : Dimension offTamano; Image offImagen; Graphics offGraphics;
Ejemplo
Declaracin de nuevas variables: Tamao del buffer Imagen que guardar el buffer Contexto grfico del buffer
public void update(Graphics g){ tamano = getSize(); if ( (offGraphics == null) ||(tamano.width != offTamano.width) || (tamano.height != offTamano.height) ) { offTamano = tamano; offImagen = createImage(tamano.width, tamano.height); offGraphics = offImagen.getGraphics(); }
diametroBola = offTamano.height/2; offGraphics.setColor(colorCuadro); offGraphics.fillRect(0,0,tamano.width,tamano.height); offGraphics.setColor(colorBola); offGraphics.fillOval(posicion,tamano.height/4,diametroBola-1,diametroBola-1); offGraphics.setColor(Color.black); offGraphics.drawOval(posicion,tamano.height/4,diametroBola-1,diametroBola-1); offGraphics.drawOval(posicion+1,tamano.height/4+1,diametroBola-3,diametroBola-3); g.drawImage(offImagen,0,0,this); }
}
class CuadroConBola3 extends Canvas implements Runnable{ : : Dimension offTamano; Image offImagen; Graphics offGraphics;
Ejemplo
Averiguar si tamao ha cambiado o si el buffer todava no ha sido creado
public void update(Graphics g){ tamano = getSize(); if ( (offGraphics == null) ||(tamano.width != offTamano.width) || (tamano.height != offTamano.height) ) { offTamano = tamano; offImagen = createImage(tamano.width, tamano.height); offGraphics = offImagen.getGraphics(); }
diametroBola = offTamano.height/2; offGraphics.setColor(colorCuadro); offGraphics.fillRect(0,0,tamano.width,tamano.height); offGraphics.setColor(colorBola); offGraphics.fillOval(posicion,tamano.height/4,diametroBola-1,diametroBola-1); offGraphics.setColor(Color.black); offGraphics.drawOval(posicion,tamano.height/4,diametroBola-1,diametroBola-1); offGraphics.drawOval(posicion+1,tamano.height/4+1,diametroBola-3,diametroBola-3); g.drawImage(offImagen,0,0,this); }
}
class CuadroConBola3 extends Canvas implements Runnable{ : : Dimension offTamano; Image offImagen; Graphics offGraphics;
Ejemplo
Dibujar imagen fuera de pantalla
public void update(Graphics g){ tamano = getSize(); if ( (offGraphics == null) ||(tamano.width != offTamano.width) || (tamano.height != offTamano.height) ) { offTamano = tamano; offImagen = createImage(tamano.width, tamano.height); offGraphics = offImagen.getGraphics(); }
diametroBola = offTamano.height/2; offGraphics.setColor(colorCuadro); offGraphics.fillRect(0,0,tamano.width,tamano.height); offGraphics.setColor(colorBola); offGraphics.fillOval(posicion,tamano.height/4,diametroBola-1,diametroBola-1); offGraphics.setColor(Color.black); offGraphics.drawOval(posicion,tamano.height/4,diametroBola-1,diametroBola-1); offGraphics.drawOval(posicion+1,tamano.height/4+1,diametroBola-3,diametroBola-3); g.drawImage(offImagen,0,0,this); }
}
class CuadroConBola3 extends Canvas implements Runnable{ : : Dimension offTamano; Image offImagen; Graphics offGraphics;
Ejemplo
public void update(Graphics g){ tamano = getSize(); if ( (offGraphics == null) ||(tamano.width != offTamano.width) || (tamano.height != offTamano.height) ) { offTamano = tamano; offImagen = createImage(tamano.width, tamano.height); offGraphics = offImagen.getGraphics(); }
diametroBola = offTamano.height/2; offGraphics.setColor(colorCuadro); offGraphics.fillRect(0,0,tamano.width,tamano.height); offGraphics.setColor(colorBola); offGraphics.fillOval(posicion,tamano.height/4,diametroBola-1,diametroBola-1); offGraphics.setColor(Color.black); offGraphics.drawOval(posicion,tamano.height/4,diametroBola-1,diametroBola-1); offGraphics.drawOval(posicion+1,tamano.height/4+1,diametroBola-3,diametroBola-3); g.drawImage(offImagen,0,0,this); }
}
Cargando imgenes
Dos mtodos de la clase Applet: Image getImage(URL url) Image getImage(URL url, String name) Dos mtodos de la clase Toolkit: Image getImage(URL url) Image getImage(String filename)
Desplegando imgenes
boolean drawImage(Image img, int x, int y, ImageObserver observer) boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer) boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer)
Image img : La imagen a dibujar int x, int y : Coordenadas de la esquina superior izquierda int width, int height : El ancho y el alto (en pixels) de la imagen Color bgcolor : Color del fondo ImageObserver observer : El objeto que desplegar la imagen, para la mayora de los casos basta especificar this
Ejemplo
import java.awt.*; import java.applet.Applet; public class DespliegaImagen extends Applet { Image imagen; public void init() { imagen = getImage(getCodeBase(), "mundo.gif"); } public void paint(Graphics g) { g.drawImage(imagen, 0, 0, this); g.drawImage(imagen, 90, 200, 200, 100, this); } }
Animacin
Desplegar secuencialmente una serie de imgenes Con un reatrdo preestablecido entre imagen e imagen Es conveniente que el despliegue se encuentre en un hilo
import java.awt.*; import java.applet.Applet; public class Animacion extends Applet implements Runnable { int cuadro = -1; Thread hilo; Dimension offTamano; Image offImagen; Graphics offGraphics; Image[] imagenes;
Ejemplo
public void init() { imagenes = new Image[10]; for (int i = 1; i <= 10; i++) { imagenes[i-1] = getImage(getCodeBase(),"circum"+i+".gif"); } } public void start() { if (hilo == null) { hilo = new Thread(this); } hilo.start(); } public void stop() { hilo = null; offGraphics = null; offImagen = null; }
Ejemplo
public void run() { Thread.currentThread().setPriority(Thread.MIN_PRIORITY); while (Thread.currentThread() == hilo) { cuadro++; repaint(); try { Thread.sleep(200); } catch (InterruptedException e) { break; } } }
Ejemplo
public void paint(Graphics g) { update(g); } public void update(Graphics g) { Dimension d = getSize(); if ( (offGraphics == null) || (d.width != offTamano.width) || (d.height != offTamano.height) ) { offTamano = d; offImagen = createImage(d.width, d.height); offGraphics = offImagen.getGraphics(); } offGraphics.setColor(getBackground()); offGraphics.fillRect(0, 0, d.width, d.height); offGraphics.setColor(Color.black); offGraphics.drawImage(imagenes[cuadro % 10], 0, 0, this); g.drawImage(offImagen, 0, 0, this); } }
Problemas
Si pones atencin al comienzo de la animacin se ve un efecto donde las imgenes no se despliegan completas al principio, esto se debe a que las imgenes se van cargando en el momento del despliegue La carga de imgenes se realiza en un hilo que comienza a ejecutarse en forma independiente, dejando que el programa continue con su ejecucin
Problemas
El problema es muho ms grave cuando ests bajando las imgenes en la red, ya que el tiempo de transferencia se incrementa tremendamente Esto puede ocasionar que intentes desplegar imgenes que todava no lleguen o imgenes incompletas, y a pesar de que no marca errores y el programa sigue funcionando, el efecto visual no es el que pretendes obtener
Solucin
La solucin es usar la clase MediaTracker que sirve para rastrear la carga de archivos (en nuestro caso, imgenes) desde la red MediaTracker te permite verificar que todas las imgenes esten cargadas antes de comenzar la animacin En caso de que no esten todas las imgenes puedes desplegar un letrero de espera
MediaTracker
Mtodos importantes
Ejemplo
public void init() { imagenes = new Image[10]; rastreador = new MediaTracker(this); for (int i = 1; i <= 10; i++) { imagenes[i-1] = getImage(getCodeBase(),"circum"+i+".gif"); rastreador.addImage(imagenes[i-1],0); } } public void start() { if (hilo == null) { hilo = new Thread(this); } hilo.start(); }
Ejemplo
public void run() { try{ rastreador.waitForAll(); }catch (InterruptedException e){} Thread.currentThread().setPriority(Thread.MIN_PRIORITY); while (Thread.currentThread() == hilo) { cuadro++; repaint(); try { Thread.sleep(200); } catch (InterruptedException e) { break; } } }
Ejemplo
public void paint(Graphics g) { update(g); }
public void update(Graphics g) { Dimension d = getSize(); if (!rastreador.checkAll()){ g.clearRect(0,0,d.width, d.height); g.drawString("Imagenes cargando . . . .",0,d.height/2); } if ( (offGraphics == null) || (d.width != offTamano.width) || (d.height != offTamano.height) ) { offTamano = d; offImagen = createImage(d.width, d.height); offGraphics = offImagen.getGraphics(); } offGraphics.setColor(getBackground()); offGraphics.fillRect(0, 0, d.width, d.height); offGraphics.setColor(Color.black); offGraphics.drawImage(imagenes[cuadro % 10], 0, 0, this); g.drawImage(offImagen, 0, 0, this); } }
Introduccin a Swing
Introduccin a Swing
Es el heredero de AWT Incrementa considerablemente la capacidad (funcional y cosmtica) de los componentes javax.swing es el paquete que contiene las nuevas clases La transicin no es muy difcil, la filosofa sigue siendo la misma, sobretodo en la manipulacin de eventos
Componentes Swing
Los componentes de Swing son livianos (lightweigt) Estn construidos completamente en Java, ya no dependen de un "peer" nativo, es decir son completamente independientes de la plataforma Ya no estn limitados al mnimo comn denominador de los objetos en las diferentes plataformas Se puede especificar la forma grfica que tomar tu programa o applet ("look and feel") Puedes agregar o cambiar la apariencia y funcionalidad de cualquier componente sin mayores problemas
Ejemplo
public class EjemploSwing1 extends JFrame{ JButton b1 = new JButton("Correo",new ImageIcon("correo.gif")); JButton b2 = new JButton("Msica",new ImageIcon("musica.gif")); JButton b3 = new JButton("Duerme",new ImageIcon("duerme.gif")); public EjemploSwing1() { b2.setHorizontalTextPosition(JButton.LEFT); b3.setHorizontalTextPosition(JButton.CENTER); b1.setToolTipText("Este es el botn 1"); getContentPane().setLayout(new FlowLayout()); getContentPane().add(b1); getContentPane().add(b2); getContentPane().add(b3); pack(); show(); } public static void main(String s[]) { new EjemploSwing1(); } }
import java.awt.*; import java.awt.event.*; import javax.swing.*; public class EjemploSwing2 extends Frame implements ActionListener{ JButton botonMetal; JButton botonMotif; JButton botonWindows; public EjemploSwing2() { setLayout(new FlowLayout()); botonMetal = new JButton("Metal"); botonMotif = new JButton("Motif"); botonWindows = new JButton("Windows"); botonMetal.addActionListener(this); botonMotif.addActionListener(this); botonWindows.addActionListener(this);
Ejemplo
Clase annima
add(botonMetal); add(botonMotif); add(botonWindows); pack(); show(); addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ System.exit(0);}}); }
Ejemplo
public void actionPerformed(ActionEvent e) { String lf; if (e.getSource().equals(botonWindows)) lf = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"; else if (e.getSource().equals(botonMetal)) lf = "javax.swing.plaf.metal.MetalLookAndFeel"; else lf = "com.sun.java.swing.plaf.motif.MotifLookAndFeel"; try{ UIManager.setLookAndFeel(lf); SwingUtilities.updateComponentTreeUI(this); pack(); }catch(Exception ex){} }
public static void main(String s[]) { new EjemploSwing2(); } }
Ejemplo
import java.awt.*; import java.awt.event.*; import javax.swing.*; public class EjemploSwing3 extends JFrame implements ActionListener{ JLabel figura; JRadioButton r1 = new JRadioButton("Mariposa"); JRadioButton r2 = new JRadioButton("Pollo"); JRadioButton r3 = new JRadioButton("Canino"); JRadioButton r4 = new JRadioButton("Rana"); JRadioButton r5 = new JRadioButton("Tortuga"); JPanel botones = new JPanel();
Ejemplo
public EjemploSwing3() { r1.setActionCommand("Mariposa"); r1.setMnemonic(KeyEvent.VK_M); r1.setSelected(true); r2.setActionCommand("Pollo"); r2.setMnemonic(KeyEvent.VK_P); r3.setActionCommand("Canino"); r3.setMnemonic(KeyEvent.VK_C); r4.setActionCommand("Rana"); r4.setMnemonic(KeyEvent.VK_R); r5.setActionCommand("Tortuga"); r5.setMnemonic(KeyEvent.VK_T);
Ejemplo
figura = new JLabel(new ImageIcon("Mariposa.gif")); figura.setPreferredSize(new Dimension(200,200)); getContentPane().setLayout(new BorderLayout()); getContentPane().add(botones,BorderLayout.EAST); getContentPane().add(figura, BorderLayout.CENTER);
Ejemplo
Ejemplo
public class EjemploSwing4 extends JFrame implements ChangeListener{ JLabel figura; JSlider figuras = new JSlider(JSlider.HORIZONTAL,1,10,1);
public EjemploSwing4() { figura = new JLabel("Figura 1",new ImageIcon("circum1.gif"),JLabel.CENTER); figura.setVerticalTextPosition(JLabel.BOTTOM); figura.setHorizontalTextPosition(JLabel.CENTER); figura.setPreferredSize(new Dimension(200,200)); figuras.setMinorTickSpacing(1); figuras.setMajorTickSpacing(3); figuras.setPaintTicks(true); figuras.setPaintLabels(true); figuras.setSnapToTicks(true); figuras.addChangeListener(this); getContentPane().setLayout(new BorderLayout()); getContentPane().add(figuras,BorderLayout.SOUTH); getContentPane().add(figura, BorderLayout.CENTER);
Ejemplo
try{ UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); SwingUtilities.updateComponentTreeUI(this); }catch(Exception ex){} pack(); show(); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0);}}); } public void stateChanged(ChangeEvent e){ figura.setIcon(new ImageIcon("circum" + String.valueOf(figuras.getValue())+".gif")); figura.setText("figura "+ String.valueOf(figuras.getValue())); } public static void main(String s[]) { new EjemploSwing4(); }
Ejemplo
Flujos
Streams y Readers/Writers
Flujo
Es una secuencia de bytes (carcteres) que se mueve desde una fuente hacia un destino a travs de una trayectoria de comunicacin
Fuente
Destino
Programa
Programa
Escritura
Destino
Lectura/Escritura de flujos
Abrir flujo Abrir flujo
Cerrar flujo
Cerrar flujo
Ejemplo
import java.io.*; public class LeeArchivo1 { public static void main(String[] args) throws IOException { FileInputStream leeArchivo = new FileInputStream(args[0]); int caracter; while ((caracter = leeArchivo.read()) != -1) System.out.print((char) caracter); leeArchivo.close(); } }
Ejemplo
A3 5C 23 DD 4A 2D 21 8F BC A3 34
65
B2 CC
leeArchivo.read()
import java.io.*; public class LeeArchivo1 { public static void main(String[] args) throws IOException { FileInputStream leeArchivo = new FileInputStream(args[0]); int caracter; while ((caracter = leeArchivo.read()) != -1) System.out.print((char) caracter); leeArchivo.close(); } }
Jerarqua de flujos
La mayora de las clases de flujos se derivan de InputStream y OutputStream Esto permite utilizar clases que son ms adecuadas a una tarea particular, como en el ejemplo anterior, en lugar de utilizar un flujo genrico y nosotros adecuarlo por programacin InputStream y OutputStream nos dan algunos mtodos genricos para lectura y escritura de bytes. Las subclases nos dan los mtodos particulares que son ms apropiados dependiendo de la fuente o destino
InputStream
Object InputStream (abstract) FileInputStream PipedInputStream FilterInputStream (abstract) DataInputStream BufferedInputStream LineNumberInputStream PushbackInputStream ByteArrayInputStream SequenceInputStream StringBufferInputStream
OutputStream
Object OutputStream (abstract) FileOutputStream PipedOutputStream FilterOutputStream (abstract) DataOutputStream BufferedOutputStream PrintStream ByteArrayOutputStream
Mtodos de InputStream
read()
public int read() throws IOException
Lee un byte del flujo de entrada y lo regresa Regresa -1 si se alcanza el final del flujo Se bloquea (espera) hasta que existan datos disponibles Arroja la excepcin IOException si ocurre un error durante la lectura Normalmente reprogramado por las subclases
read(byte[])
public int read(byte[] b) throws IOException
Lee una secuencia de bytes del flujo de entrada y los pone en el arreglo especificado Regresa la cantidad de bytes leidos Regresa -1 si es que se alcanz el final del flujo de entrada Se bloquea hasta que existan datos disponibles Arroja la excepcin IOException si ocurre un error durante la lectura
read(byte[],int,int)
public int read(byte[] b,int des,int lon) throws IOException
Lee una secuencia de lon bytes y los pone en el arreglo b a partir del ndice des Regresa el nmero de bytes leidos Regresa -1 si es que se alcanz el final del flujo de entrada Se bloquea hasta que encuentre datos disponibles Arroja la excepcin IOException si ocurre un error durante la lectura
skip(long)
public long skip(long n) throws IOException
Se brinca (y descarta) un nmero de bytes especificado por n Regresa el nmero de bytes que realmente se descartaron Regresa -1 si se alcanz el final del flujo de entrada Arroja la excepcin IOException si ocurre un error durante el salto
available()
public int available() throws IOException
Regresa el nmero de bytes que se pueden leer del flujo de entrada sin que la operacin de lectura bloquee la secuencia del programa Se utiliza para "ver", sin leer, cuantos datos hay disponibles En algunos sistemas el resultado arrojado no es confiable Arroja la excepcin IOException si ocurre un error durante la operacin
close()
public void close() throws IOException
Cierra el flujo de entrada y libera todos los recursos asociados (asignados por el sistema operativo) con el flujo Siempre es conveniente cerrar los flujos para asegurarse que el procesamiento del flujo por parte del sistema termine correctamente Arroja la excepcin IOException si ocurre un error durante la operacin
mark(int)
public synchronized void mark(int readlimit)
Marca la posicin actual en el flujo de entrada, para posteriormente regresar a ella en caso necesario Regresa el nmero de bytes que se pueden leer despus de la marca antes de que la marca sea invalidada por la capacidad del buffer boolean markSupported() indica si el flujo de entrada permite marcas void reset() reposiciona al flujo en la ltima posicin marcada
Mtodos de OutputStream
write(...)
public void write(int b) throws IOException
Se bloquean hasta que el o los datos sean escritos Arrojan IOException en caso de error durante la escritura
flush()
public void flush() throws IOException
Ocasiona que todo dato que est en el buffer sea escrito inmediatamente al flujo de salida Se tiene que reprogramar en las subclases porque en OutputStream no hace nada
close()
public void close() throws IOException
Clases de flujos
FileInputStream
Subclase de InputStream que lee datos de un archivo especificado por nombre, o por un objeto de tipo File o Filedescriptor, para leer archivos es mejor utilizar DataInputStream que es de tipo FilterInputStream, la cual permite leer lneas de texto y datos primitivos de Java de una manera ms adecuada. Se puede crear un DataInputStream especificando el InputStream que ser filtrado
Clases de flujos...
FileOutputStream
Subclase de OutputStream que escribe datos a un archivo especificado por nombre, o por un objeto de tipo File o Filedescriptor, para escribir archivos es mejor utilizar DataOutputStream o PrintOutputStream PipedInputStream y PipedOutputStream Util para la comunicacin entre hilos (threads). Un PipedInputStream se debe conectar a un objeto PipedOutputStream
Clases de flujos...
ByteArrayInputStream y ByteArrayOutputStream
Para leer o escribir datos de un arreglo como si viniera de un archivo o socket, los datos del arreglo se pueden obtener con toByteArray() o toString(), el mtodo reset() deshecha los datos que estn guardados en el arreglo y posiciona el apuntador al comienzo
SequenceInputStream
Nos da un medio de concatenar datos de dos o ms flujos de entrada, los datos son leidos en el orden en el cual se especifican los flujos
Clases de flujos...
StringBufferInputStream
Los datos vienen de un string especificado Util cuando se quiere leer datos de memoria como si viniera de una archivo o socket Similar a ByteArrayInputStream
BufferedInputStream
Incrementa la eficiencia de lectura, leyendo mayores cantidades de informacin y guardndola en un buffer interno
PushBackInputStream
Da la capacidad de regresar un byte leido al flujo original, el cual ser leido con la siguiente llamada a read()
PrintStream
Agrega funcionalidad a otro flujo de salida dando la posibilidad de escribir representaciones de los diferentes tipos de datos de Java. A pesar de su nombre no es imprescindible que la salida sea a impresora
DataInputStream
DataInputStream
DataInputStream
DataOutputStream
DataOutputStream
Ejemplo
import java.io.*; public class LeeArchivo2 { public static void main(String[] args) throws IOException { FileInputStream leeArchivo = new FileInputStream(args[0]); DataInputStream leeFiltrado = new DataInputStream(leeArchivo); String linea; while ((linea = leeFiltrado.readLine()) != null) System.out.println(linea); leeArchivo.close(); leeFiltrado.close(); } }
mtodo desaprobado
import java.io.*; public class LeeArchivo2 { public static void main(String[] args) throws IOException { FileInputStream leeArchivo = new FileInputStream(args[0]); DataInputStream leeFiltrado = new DataInputStream(leeArchivo); String linea; while ((linea = leeFiltrado.readLine()) != null) System.out.println(linea); leeArchivo.close(); leeFiltrado.close(); } }
leeFiltrado.readLine()
A3
34
65
CC
21
10110011 10011110
1100
Readers y Writers
JDK 1.1 nos da dos tipos diferentes de flujos (streams):
Orientados a byte (8 bits, Ascii) Orientados a caracter (16 bits, Unicode)
Los dos tipos de flujos se organizan en dos jerarquas, una que consiste en clases de flujos orientados a byte y la otra en clases de flujos orientados a caracter
Readers y Writers
Las dos jeraquas son funcionalmente casi idnticas y contienen clases y subclases equivalentes difiriendo solamente en la parte final (sufijo) del nombre Las orientadas a byte terminan en InputStream u OutputStream las orientadas a caracter terminan en Reader o Writer
Flujos de entrada
Flujos de salida
Ejemplo
import java.io.*; public class LeeArchivo3 { public static void main(String[] args) throws IOException { FileReader leeArchivo = new FileReader(args[0]); BufferedReader leeFiltrado = new BufferedReader(leeArchivo); String linea; while ((linea = leeFiltrado.readLine()) != null) System.out.println(linea); leeArchivo.close(); leeFiltrado.close(); } }
FileDescriptor
El equivalente a una manija de bajo nivel para un archivo o socket
java.awt.FileDialog
Despliega una ventana del sistema para que el usuario seleccione un archivo Debe de pertenecer a un Frame Es una ventana modal, es decir cuando se le da show() bloquea el resto de la aplicacin hasta que el usuario seleccione un archivo o cancele la operacin
FileDialog
FileDialog
show()
Hace la ventana de FileDialog visible y bloquea la ejecucin de la aplicacin hasta que se seleccione un archivo
setMode(int)
Establece si la ventana de FileDialog es para leer un archivo (LOAD) o para escribir un archivo (SAVE)
FileDialog
getFile()
Regresa como String el archivo seleccionado
getDirectory()
Regresa como String el directorio al cual pertenece el archivo seleccionado
public class Archivo1 extends Frame implements ActionListener{ static Archivo1 f; Button boton = new Button("Abrir"); TextArea despliega = new TextArea(); FileDialog dialogo = new FileDialog(this); Image figura; String nombreArchivo, nombreDirectorio; File archivo;
Ejemplo
public Archivo1(){ super(); setTitle("Archivero"); setSize(200,200); setLocation(300,300); figura = Toolkit.getDefaultToolkit().getImage("canino.gif"); setIconImage(figura); add(despliega,"Center"); add(boton,"South"); addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ f.dispose(); System.exit(0); }}); boton.addActionListener(this); pack(); show(); }
public void actionPerformed(ActionEvent e){ Button b = (Button) e.getSource(); if(boton.getLabel()=="Abrir"){ dialogo.setMode(FileDialog.LOAD); dialogo.show(); nombreArchivo = dialogo.getFile(); nombreDirectorio = dialogo.getDirectory(); if (nombreDirectorio!=null && nombreArchivo!= null){ archivo = new File(nombreDirectorio,nombreArchivo); despliegaArchivo(archivo); boton.setLabel("Guardar"); } }else{ dialogo.setMode(dialogo.SAVE); dialogo.setFile(nombreArchivo); dialogo.setDirectory(nombreDirectorio); dialogo.show(); nombreArchivo = dialogo.getFile(); nombreDirectorio = dialogo.getDirectory(); if (nombreDirectorio!=null && nombreArchivo!= null){ archivo = new File(nombreDirectorio,nombreArchivo); guardaArchivo(archivo); } boton.setLabel("Abrir"); } }
Ejemplo
Ejemplo
public void despliegaArchivo(File f){ FileReader archivo; BufferedReader filtrado; despliega.setText(""); try{ archivo = new FileReader(f); filtrado = new BufferedReader(archivo); String linea; while ((linea = filtrado.readLine()) != null) despliega.append(linea+"\n"); archivo.close(); filtrado.close(); }catch(FileNotFoundException e){ despliega.append(e.getMessage()); }catch(IOException e){ despliega.append(e.getMessage()); } }
Ejemplo
public void guardaArchivo(File f){ FileWriter archivo; BufferedWriter filtrado; String contenido="nada"; try{ archivo = new FileWriter(f); filtrado = new BufferedWriter(archivo); contenido = despliega.getText(); filtrado.write(contenido,0,contenido.length()); filtrado.flush(); archivo.close(); filtrado.close(); }catch(FileNotFoundException e){ despliega.append(e.getMessage()); }catch(IOException e){ despliega.append(e.getMessage()); } despliega.setText(""); }
Ejemplo
Mtodos de File
Ejemplo
public void despliegaPropiedades(File f){ despliega.setText("Propiedades del Archivo: "+f.getName()+"\n"); despliega.append("canRead()>> "+String.valueOf(f.canRead())+"\n"); despliega.append("canWrite()>> "+String.valueOf(f.canWrite())+"\n"); despliega.append("exists()>> "+String.valueOf(f.exists())+"\n"); despliega.append("getAbsolutePath()>> "+f.getAbsolutePath()+"\n"); despliega.append("getPath()>> "+f.getPath()+"\n"); despliega.append("length()>> "+String.valueOf(f.length())+"\n"); }
Entendiendo
System.out.println(...)
System.out.println()
System.out.println()
PrintStream
PrintStream
System.out.println()
out variable de la clase System del paquete lang out variable de tipo PrintStream La clase PrintStream tiene una serie de mtodos print y println para poder escribir una representacin legible para cada tipo de dato primitivo en Java No arroja excepciones
PrintStream desaprobado
PrintStream ya est desaprobado (deprecated) Es recomendable utilizar PrintWriter Asi se tiene el soporte para escribir carcteres Unicode Los mtodos de PrintStream eliminan la parte alta de los carcteres para transformarlos en cdigo Ascii de 8 bits
import java.io.*;
public class Teclado { public static void main(String[] args){ String linea=""; InputStreamReader entrada = new InputStreamReader(System.in); BufferedReader teclado = new BufferedReader(entrada); System.out.println("Teclea lneas de texto"); System.out.println("Teclea q y <enter> para terminar"); try{ while(linea.compareTo("q")!=0){ linea = teclado.readLine(); System.out.println(">> "+linea); } }catch(IOException e){ System.out.println(e.getMessage()); } System.out.println("Fin del Programa"); try{ teclado.close(); entrada.close(); }catch(IOException e){ System.out.println(e.getMessage()); } } }
Ejemplo
Redes en Java
Introduccin
Adems del manejo implcito de redes que tiene (carga de applets, clases, imgenes, etc.), Java tiene la posibilidad de manejar la comunicacin por medio de redes usando el modelo de referencia TCP/IP Esta comunicacin se realiza utilizando sockets, los cuales son la parte fundamental del manejo de redes con TCP/IP Es un conjunto de protocolos para comunicaciones de redes, son los que le dan vida a Internet y por consiguiente al Web
TCP/IP vs OSI
Aplicacin Presentacin Sesin Transporte Red Enlace Fsica
Aplicacin
TCP/IP
Acceso a la red
Fsica
TCP/IP
TCP IP
UDP
Acceso a la red
TCP
Protocolo orientado a conexin que maneja un canal de comunicacin confiable entre dos computadoras Garantiza que los mensajes llegarn al destino en forma correcta y ordenada Verificacin de errores, reconocimientos (ACK), retransmisin, secuenciacin de paquetes HTTP, FTP, Telnet
UDP
Protocolo orientado a no-conexin que enva paquetes de datos independientes (datagramas), sin garanta de la llegada o del orden de los paquetes No incurre en el gasto extra de mantener una conexin y hacer la verificacin de cada paquete por medio de ACKs y timeouts Diseado para aplicaciones donde la prdida parcial de datos no es importante
Direcciones IP y puertos
Cuando enviamos informacin en Internet necesitamos identificar la mquina destino y el proceso que queremos maneje los datos enviados Una direccin IP identifica una mquina en Internet, son de 32 bits: 131.178.14.14,
192.9.48.9
192.9.48.9
Direcciones IP y puertos
Paquete
Internet
Aplicacin Servidor WEB Servidor FTP : Miprograma : Puerto 80 21 : 5999 :
131.178.14.14
Direcciones IP y puertos
Prog1 Prog2
Datos
Puerto1 Puerto2 PuertoN
ProgN
Sistema Operativo
#Puerto Datos
Paquete
Dir IP #Puerto Datos
Sockets
Un socket es un extremo de un enlace de comunicacin bidireccional A un socket se le asocia un nmero de puerto, para que el sistema identifique a que aplicacin mandar algn paquete Tambin se le asocia una direccin IP para que un paquete mandado por el socket pueda viajar por la red hacia un destino Las aplicaciones escriben y leen de sockets
131.178.2.25
Puerto 5000
Socket
Sockets
Socket
Puerto 6000
131.178.2.25, 5000,"Hola"
131.178.14.14
Peticin de conexin
131.178.2.25
Puerto 5000
Puerto 6000
131.178.14.14
Peticin de conexin
131.178.2.25
Puerto 5000
Puerto 6000
131.178.14.14
Establecimiento de la conexin
131.178.2.25
Puerto 5000
Puerto 6000
131.178.14.14
Establecimiento de la conexin
131.178.2.25
Puerto 7867
Puerto 5000
55.78.34.56
Puerto 6000
131.178.14.14
192.9.48.9
UDP
Internet
34.56.89.54, 5000,"Hola"
131.178.14.14
La clase InetAddress
Representa un direccin de IP No tiene constructor Para crear un ejemplar de esta clase es necesario llamar a los mtodos:
getLocalHost() getByName(String) getAllByName(String)
Mtodos de InetAddress
public static InetAddress getLocalHost()
Regresa la direccin IP de la mquina local
Mtodos de InetAddress
public String getHostName()
Regresa el nombre de la mquina con esta direccin de IP
Ejemplo
import java.net.*; public class PruebaInetAddress{ public static void main(String args[]){ String argumento; InetAddress direccion=null; try{ argumento = args[0]; }catch (ArrayIndexOutOfBoundsException e){ argumento = null; } try{ if (argumento!=null) direccion = InetAddress.getByName(args[0]); else direccion = InetAddress.getLocalHost(); }catch (UnknownHostException e){ System.out.println(e.getMessage()); System.exit(0); }
System.out.println(direccion.getHostAddress()); System.out.println(direccion.getHostName()); System.out.println(direccion.toString()); byte[] dir = direccion.getAddress(); for (int i=0;i<dir.length;i++){ int b = dir[i] < 0 ? dir[i]+256 : dir[i]; System.out.print(b +"."); } System.out.println(); try{ InetAddress[] direcciones = InetAddress.getAllByName(direccion.getHostName()); for (int i=0;i<direcciones.length;i++) System.out.println(direcciones[i].toString()); }catch (UnknownHostException e){}
Ejemplo
Ejemplo
La clases de sockets
Existen tres clases de sockets en Java
Socket: sockets TCP (streams) ServerSocket: para escuchar por conexiones DatagramSocket: sockets UDP (datagramas)
La decisin de utilizar Socket o DatagramSocket depende de la aplicacin especfica Cuando manejas datagramas no necesitas escuchar por peticiones de conexin
La clase Socket
Socket(String host,int port)
Crea un socket TCP y lo conecta a la mquina especificada por host en el puerto port Arroja UnknownHostException, IOException
La clase Socket
Socket(String host,int port, InetAddress localAddr,int localPort) Crea un socket TCP conectado a la mquina host en el puerto port, el socket queda enlazado a la mquina local en la direccin localAddr al puerto local localPort Socket(InetAddress address,int port, InetAddress localAddr,int localPort)
Crea un socket TCP conectado a la mquina con direccin IP address al puerto port, el socket queda enlazado a la mquina local en la direccin localAddr al puerto local localPort
Mtodos de Socket
InetAddress getInetAddress()
Regresa la direccin remota a la cual est conectada el socket
InetAddress getLocalAddress()
Regresa la direccin local a la cual el socket est enlazado
int getPort()
Regresa el puerto remoto al cual est conectado el socket
int getLocalPort()
Regresa el puerto local al cual est enlazado el socket
Mtodos de Socket
close()
Cierra el socket
InputStream getInputStream()
Regresa el flujo de entrada de este socket
OutputStream getOutputStream()
Regresa el flujo de salida de este socket
La clase ServerSocket
ServerSocket(int port)
Crea un socket servidor en el puerto especificado, port = 0 crea un socket en cualquier puerto libre La fila de espera para peticiones de conexiones se establece en 50
La clase ServerSocket
ServerSocket(int port,int backlog, InetAddress bindAddr)
Crea un socket servidor en el puerto port, con una fila para espera de conexiones de tamao backlog y con la direccin IP bindAddr Este constructor se utiliza en el caso de que se tengan servidores con mltiples direcciones IP asignadas
InetAddress getInetAddress()
Regresa la direccin local a la cual est conectada el socket
int getLocalPort()
Regresa el puerto local al cual est enlazado el socket
close()
Cierra el socket
Ejemplo
Ejemplo
Ejemplo
Servidor
Cliente
Servidor
Cliente/Servidor
Normalmente queremos algo ms que conectarnos a un servidor El servidor nos va a dar un servicio la comunicacin entre el cliente y el servidor, despus de que se establece la conexin, tiene que respetar un protocolo. Tanto en el orden de la transmisin de los datos como en el tipo de datos que uno transmite y el otro espera recibir, o vamos a tener serios problemas.
Esquema Servidor
Abre un socket para esperar por conexiones Al llegar una conexin crea otro socket para comunicarse con el cliente Asocia uno o ms flujos al socket de comunicacin Lee/escribe a los flujos de acuerdo al protocolo establecido Termina la comunicacin Cierra los flujos y cierra los sockets
Esquema Cliente
Abre un socket para conectarse y comunicarse con el servidor Establece conexin con el servidor Asocia uno o ms flujos al socket de comunicacin Lee/escribe al flujo de acuerdo al protocolo establecido Termina la comunicacin Cierra los flujos y cierra los sockets
Ejemplo Cliente/Servidor
En el siguiente ejemplo el cliente se conecta al servidor y le comienza a mandar una serie de strings, y el servidor le responde con la longitud de cada string (como un entero!) Ambos programas terminan cuando el cliente le enva al servidor un string nulo El cliente debe de teclear la direccin o nombre del servidor en la lnea de comandos
Ejemplo Servidor2.java
ServerSocket yo = null; Socket cliente = null; BufferedReader entrada; DataOutputStream salida; String llego; yo = new ServerSocket(5000); cliente = yo.accept(); entrada = new BufferedReader (new InputStreamReader(cliente.getInputStream())); salida = new DataOutputStream(cliente.getOutputStream()); do{
Ejemplo Cliente2.java
Socket yo = null; PrintWriter alServidor; BufferedReader delTeclado; DataInputStream delServidor; String tecleado;
yo = new Socket(comandos[0],5000);
delTeclado = new BufferedReader(new InputStreamReader(System.in)); alServidor = new PrintWriter(yo.getOutputStream(),true); delServidor = new DataInputStream(yo.getInputStream()); do{ System.out.print("Teclea un string: "); tecleado = delTeclado.readLine(); alServidor.println(tecleado); System.out.println("Longitud = "+delServidor.readInt()); }while(tecleado.length()!=0); delServidor.close(); delTeclado.close(); alServidor.close(); yo.close();
Ejemplo
Aplicaciones Clientes/Servidor
Aunque a veces es suficiente tener un servidor para que atienda a UN cliente, normalmente no es el caso Necesitamos que el servidor pueda atender a mltiples clientes en forma simultnea Para eso basta arrancar un hilo para atender a cada cliente En el hilo principal el servidor siempre estar escuchando por peticiones de conexin
Crear ServerSocket
Peticin de Conexin?
SI
Atender conexin Con el socket creado
Atencin de la conexin en un HILO Atencin de la conexin Atencin de en un la conexin HILO en un HILO Atencin de la conexin en un Atencin de HILO la conexin en un HILO
Ejemplo ServidorM2.java
ServerSocket yo = null; Socket cliente = null; boolean escuchando = true; yo = new ServerSocket(5000); while(escuchando){ cliente = yo.accept(); System.out.println("Ya se conecto un cliente desde: " + cliente.getInetAddress().getHostName() + "("+cliente.getPort()+")"); new Atiende(cliente).start(); } yo.close();
Ejemplo ServidorM2.java
class Atiende extends Thread{ public Atiende(Socket cliente){ this.cliente = cliente; nombreyDirIP = this.cliente.getInetAddress().toString(); } public void run(){ entrada = new BufferedReader (new InputStreamReader(cliente.getInputStream())); salida = new DataOutputStream(cliente.getOutputStream()); do{ llego = entrada.readLine(); System.out.println("("+nombreyDirIP+") Llego: " + llego); salida.writeInt(llego.length()); }while(llego.length()!=0); entrada.close(); cliente.close();
System.out.println("Ya se desconecto"+"("+nombreyDirIP+")");
}
Ejemplo ServidorM2.java
Ejemplo Cliente2A.java
host = getCodeBase().getHost(); yo = new Socket(host,5000); alServidor = new PrintWriter(yo.getOutputStream(),true); delServidor = new DataInputStream(yo.getInputStream()); envia.setLabel("Envia"); envia.setEnabled(true); : : : public void mandaMensaje(String mensaje){ alServidor.println(mensaje); int l = delServidor.readInt(); llega.setText(String.valueOf(l)); if (l==0){ envia.setLabel("Desconectado"); envia.setEnabled(false); validate(); } }
Datagramas
Un socket de tipo datagrama es un punto de enlace orientado a no conexin El enlace no es confiable. No existe seguridad de que los paquetes llegarn ni en que orden lo harn Cada paquete enviado o recibido es direccionado y ruteado en forma individual Los paquetes enviados por una misma mquina puede seguir rutas diferentes
La clase DatagramSocket
Mtodos de DatagramSocket
Adems de close(), getLocalPort() y getLocalAddress(), que funcionan igual que los mtodos en la clase Socket, existen: void receive(DatagramPacket p)
Para recibir paquetes (datagramas) El paquete recibido queda en p
void send(DatagramPacket p)
Para enviar paquetes (datagramas) El paquete enviado es el que estaba en p
DatagramPacket
byte[]
DatagramSocket yo = null; DatagramPacket paquete; InetAddress dirCliente = null; int puertoCliente; byte[] buffer = new byte[80]; String aMandar, recibido;
Ejemplo ServidorD1
yo = new DatagramSocket(5000); System.out.println("Socket escuchando en puerto 5000"); while(true){ buffer = new byte[80]; paquete = new DatagramPacket(buffer, buffer.length); yo.receive(paquete); recibido = new String(paquete.getData()); dirCliente = paquete.getAddress(); System.out.println(dirCliente.toString()+" me mand >"+recibido); aMandar = new String(recibido.toUpperCase()); buffer = new byte[80]; buffer = aMandar.getBytes(); puertoCliente = paquete.getPort(); paquete = new DatagramPacket(buffer,buffer.length, dirCliente, puertoCliente); yo.send(paquete); } //yo.close();
DatagramSocket yo = null; InetAddress dir = null; DatagramPacket paquete; byte[] buffer = new byte[80]; String recibido, tecleado=" "; BufferedReader delTeclado = new BufferedReader (new InputStreamReader(System.in));; dir = InetAddress.getByName(args[0]); yo = new DatagramSocket(); while(tecleado.length()!=0){ System.out.print("Teclea un mensaje: "); tecleado = delTeclado.readLine(); buffer = tecleado.getBytes(); paquete = new DatagramPacket(buffer, buffer.length, dir, 5000); yo.send(paquete); buffer = new byte[80]; paquete = new DatagramPacket(buffer, buffer.length); yo.receive(paquete); recibido = new String(paquete.getData()); System.out.println(">> "+recibido); } yo.close();
Ejemplo ClienteD1
Multicasting
Es enviar el mismo paquete a varios destinatarios simultneamente Slo se puede hacer con datagramas, de hecho MulticastSocket extiende a DatagramSocket un paquete multicast se enva a un grupo de direcciones IP clase D :
224.0.0.1 - 239.255.255.255
Ejemplo ServidorMul
public static void main(String[] comandos) throws IOException { DatagramSocket yo = new DatagramSocket(); while (true) { byte[] buf = new byte[256]; String aMandar = new String(new Date().toString()); buf = aMandar.getBytes(); InetAddress group = InetAddress.getByName("230.0.0.1"); DatagramPacket paquete = new DatagramPacket(buf, buf.length, group, 5000); yo.send(paquete); System.out.println("Ya mand "+aMandar); long ahora = System.currentTimeMillis(); while(ahora+1000>System.currentTimeMillis()); } // yo.close(); }
Ejemplo ClienteMul
public static void main(String[] args) throws IOException { MulticastSocket yo = new MulticastSocket(5000); InetAddress dir = InetAddress.getByName("230.0.0.1"); yo.joinGroup(dir); DatagramPacket paquete; while (true) { byte[] buf = new byte[256]; paquete = new DatagramPacket(buf, buf.length); yo.receive(paquete); String recibido = new String(paquete.getData()); System.out.println("Recibido " + recibido); } // yo.leaveGroup(address); // yo.close(); }
Transferencia de objetos
Los flujos (streams y readers/writers) nos permiten mandar objetos por medio de la red sin problemas Capacidad de mandar estructuras de datos complejas Capacidad de mandar un objeto para procesamiento en una mquina ms potente ServidorM3.java y Cliente3.java
JDBC
Es un API de Java para ejecutar estatutos de SQL (Structured Query Language) Aunque no es un acrnimo, sino una marca registrada, es comn darle el significado de Java DataBase Connectivity Programando con JDBC se puede acceder a casi cualquier Base de Datos comercial por medio de comandos SQL
JDBC
Lo ms importante es que no necesitamos un programa diferente para cada tipo de Base de Datos que manejemos Un mismo programa puede accesar la misma estructura en Bases de Datos comerciales diferentes Extiende la universalidad de Java a Bases de Datos adems de las plataformas
ODBC
Open DataBase Connectivity Es la respuesta de Microsoft al mismo problema, acceso a diferentes Bases de Datos con una misma API Se puede usar ODBC directamente desde Java pero: est programada en C y necesita llamar a mtodos nativos, problemas de seguridad y transportabilidad adems de otros factores
Puente JDBC-ODBC
Se puede usar el puente para que los programas sigan siendo 100% Java El acceso a la Base de Datos se hace por medio de ODBC El programador slo desarrolla en Java y accede a las Bases de Datos por medio del API JDBC, no tiene necesidad de aprender a manejar ODBC, slo necesita configurarlo
Modelo de 2 capas
Servidor BD
Driver JDBC
Modelo de 3 capas
Interfaz Grfica "Bussiness Logic"
Servidor BD
Drivers
(Tipo 1) Puente JDBC-ODBC y driver ODBC
La aplicacin necesita cargar el cdigo nativo del driver ODBC
Pasos previos
Tener instalado JDK con JDBC
JDK ya viene con JDBC, puedes conseguir ejemplos en: http://www.javasoft.com/products/jdbc/book.html
Configuracin de ODBC
En el panel de control seleccionar ODBC
Configuracin de ODBC
Ya tenemos en disco una base de datos llamada "curso1.mdb" Seleccionar agregar Selecionar el tipo de driver que queremos agregar, en nuestro caso ser "Microsoft Access Driver (*.mdb) Presionar Terminar
Configuracin de ODBC
Asignar un nombre (data source name) para hacer referencia a ella desde Java
Configuracin de ODBC
En la opcin avanzado se puede asignar usuario y password para el acceso de la base de datos
Configuracin de ODBC
Despus presionar seleccionar para ubicar la base de datos en el disco o en la red
Ejemplos
Para los siguientes ejemplos tendremos una base de datos ya existente (la que acabamos de configurar) curso1.mdb, el "data source name" tambin es curso1 pero no es necesario que coincidan curso1 tiene una tabla que se llama lista, la cual es una lista de alumnos con nombre y matrcula y las calificaciones de tres parciales
Pasos de un programa
Cargar driver
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
La instruccin anterior crea un ejemplar del driver y lo registra con el DriverManager en una sola instruccin
Crear un estatuto asociado a la conexin para poder hacer accesos a la base de datos
Statement estatuto = conexion.createStatement();
Donde el query tpicamente es un estatuto SELECT de SQL El query es mandado en forma de String y regresa un objeto de la clase ResultSet que guarda todos los registros obtenidos con el query
ResultSet rs = estatuto.executeQuery("SELECT...");
rs tiene un apuntador que inicialmente apunta antes del primer registro del grupo obtenido, la forma de avanzar en los registros dentro del grupo es con el mtodo next() del ResultSet que regresa un valor booleano indicando si es que todava quedan ms registros en el ResutSet
public static void main(String[] args){ try{ Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); }catch(ClassNotFoundException e){ System.out.println(e.getMessage()); } try{ Connection conexion = DriverManager.getConnection("jdbc:odbc:curso1"); Statement estatuto = conexion.createStatement(); ResultSet rs = estatuto.executeQuery("select * FROM lista"); while(rs.next()){ String matricula = rs.getString("MATRICULA"); String nombre = rs.getString("NOMBRE"); int ex1 = rs.getInt("EX1"); int ex2 = rs.getInt("EX2"); int ex3 = rs.getInt("EX3"); System.out.println(matricula+" "+nombre+" "+ex1+" "+ex2+" "+ex3); } estatuto.close(); conexion.close(); }catch(SQLException e){ System.out.println(e.getMessage()); } } }
Ejemplo
Ejemplo
Ejemplo BaseDeDatos2.java
Connection conexion = DriverManager.getConnection("jdbc:odbc:curso1","jdbc","jdbc"); Statement estatuto = conexion.createStatement(); ResultSet rs = estatuto.executeQuery("select MATRICULA,NOMBRE "+ "from lista where NOMBRE>'b' and NOMBRE<'f' "+ "order by NOMBRE DESC"); while(rs.next()){ String matricula = rs.getString("MATRICULA"); String nombre = rs.getString(2); System.out.println(matricula+" "+nombre); }
Ejemplo BaseDeDatos3.java
estatuto.executeUpdate("update lista set EX1 = EX1 + 10,EX2 = EX2 + 5");
estatuto.executeUpdate("update lista set EX1=100,EX2=100,EX3=100 "+ "where NOMBRE>'a' AND NOMBRE<'b'"); estatuto.executeUpdate("delete from lista where MATRICULA>'7'");
estatuto.executeUpdate("insert into lista values('49052','Pablo Daz',"+ "100,100,100)"); estatuto.executeUpdate("insert into lista (MATRICULA,NOMBRE,EX3) "+ "values ('123456','Tonto',50)");
Ejemplo
Ejemplo BaseDeDatos4.java
Statement estatuto = conexion.createStatement(); Statement estatuto1 = conexion.createStatement(); //estatuto.executeUpdate("create table final (MATRICULA text(6), NOTA number)"); //estatuto.executeUpdate("create table final (MATRICULA varchar(6), NOTA int)"); estatuto.executeUpdate("create table final (MATRICULA varchar(6), NOTA double)"); ResultSet rs = estatuto.executeQuery("select * FROM lista"); while(rs.next()){ String matricula = rs.getString("MATRICULA"); int ex1 = rs.getInt("EX1"); int ex2 = rs.getInt("EX2"); int ex3 = rs.getInt("EX3"); double nota = (double)(ex1+ex2+ex3)/3; estatuto1.executeUpdate("insert into final values("+matricula+"," +String.valueOf(nota)+")"); } rs = estatuto.executeQuery("select * FROM final"); while(rs.next()){ String mat = rs.getString("MATRICULA"); double not = rs.getDouble("NOTA"); System.out.println(mat+" "+Math.round(not)); }
Ejemplo
PreparedStatement
Es una manera de pasar parmetros a estatutos de query y update Se usa para tener estatutos preparados que se utilizan con frecuencia y que posiblemente ya estn compilados en el servidor de BdeD. Eficiencia! Los parmetros se especifican con ? y mantienen un orden (ndice) que se va incrementando a medida que usas los ? El valor de los parmetros se especifica con las funciones set...(ndice, valor), donde la versin de set depende del tipo de dato que asignars al parmetro El estatuto se llama sin el tpico parmetro String
Ejemplo BaseDeDatos5.java
PreparedStatement estatuto = conexion.prepareStatement("select * from final "+ "where NOTA > ? and NOTA < ?"); estatuto.setDouble(1,70); estatuto.setDouble(2,80); ResultSet rs = estatuto.executeQuery(); while(rs.next()){ String matricula = rs.getString("MATRICULA"); double nota = rs.getDouble("NOTA"); System.out.println(matricula+" "+nota); }
Ejemplo BaseDeDatos6.java
ResultSet rs = estatuto.executeQuery("select lista.NOMBRE from lista, "+ "final where final.NOTA>70 and final.NOTA<80 "+ "and lista.MATRICULA = final.MATRICULA"); while(rs.next()){ String nombre = rs.getString("NOMBRE"); System.out.println(nombre); }
Stored Procedures
Un stored procedure es un grupo de estatutos SQL que ejecutan una tarea particular y se toman como una unidad (es como una rutina en SQL) La mayora de los manejadores de Bases de Datos tiene la capacidad de programar stored procedures, pero la sintaxis vara de una a otra, adems de otras particularidades
Stored Procedures
Es conveniente que los programes en la Base de Datos que uses y los llames desde Java, a pesar de que los puedes crear en Java El llamado a un stored procedure es:
CallableStatement estatuto=conexion.prepareCall("{call SP}"); ResultSet rs = estatuto.executeQuery();
Servlets
Servlets
Es Java en el servidor Applets en browsers, Servlets en el servidor Aplicar todas las ventajas de Java Apoya la idea de ejecutar el trabajo en el servidor (back end) y dejar el cliente como interfaz (front end) Soporte directo para desarrollar pginas de Web "dinmicas"
javax.servlet.*
Es una extensin de java (por eso la x), es decir no pertence al ncleo de APIs A pesar de que los servlets no son especificamente para servidores de Web, es en el Web donde han recibido la mayor atencin inicial javax.servlet.http.HttpServlet
Servlets vs CGIs
Common gateway Interface Estndar para desarrollar el lado del servidor en aplicaciones de Web (generalmente programados en Perl) Ventajas de servlets familiaridad: es Java! transportabilidad: la mayora de los vendedores de servidores soportan servlets seguridad: por Java eficiencia: El servidor arranca un proceso nuevo por cada peticin a un CGI
javax.servlet.Servlet
Interfaz genrica para servlets service(): es el motor de un servlet, atiende peticiones, recibe dos parmetros (objetos del tipo ServletRequest y ServletResponse), el primero encapsula la peticin de un cliente y el segundo la respuesta que se regresa init(): Mtodo para inicializar al servlet, acepta un parmetro de tipo ServletConfig destroy(): Donde se hace la limpieza del servlet getServletConfig(): regresa el objeto tipo ServletConfig que se pasa a init() getServletInfo(): regresa un String con informacin que se programa previamente
Ejemplo
import javax.servlet.http.*; import javax.servlet.*; import java.io.*; public class Servlet0 extends HttpServlet{ protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException{ String s = ; s += "<HTML>\n"; s += "<HEAD>\n"; s += "<TITLE>Primer Servlet</TITLE>\n"; s += "</HEAD>\n"; s += "<H1>Hola que tal!</H1>\n"; s += "</HTML>"; resp.setContentType("text/html"); resp.setContentLength(s.length()); resp.getOutputStream().print(s); } }
Ejemplo
HTML
HyperText Markup Language Lenguaje de Marcacin de Hipertexto Hiper Superior Markup Marcar Es un lenguaje para:
FORMATEO VISUALIZACIN
No es un lenguaje de Programacin
HTML
<B> Este </B> es un <U>ejemplo</U> de <EM>HTML</EM>
HTML
Existen etiquetas y elementos Etiquetas indican la funcin y/o formato de los elementos <ETIQUETA>.....</ETIQUETA> Palabra <U>subrayada</U>
Palabra subrayada
Encabezado (HEAD)
Contiene informacin acerca del documento (pgina)
Ttulo (<TITLE>.....</TITLE>). Debe de existir Autor, palabras clave, lenguaje, etc. <META...........>
Informacin que no se considera contenido Encabezados HTTP
Documento (BODY)
Es el contenido del documento que se despliega en el navegador. Es la parte que se despliega en el navegador o explorador. Contiene etiquetas para formato, visualizacin y enlaces.
Anidacin de etiquetas
Para producir mltiples efectos en un elemento Tanto la etiqueta inicial como final deben de quedar anidadas
<B><U>Hola que tal!</U></B>
<B><U>Hola que tal!</B></U>
Atributos de etiquetas
Son parte de las etiquetas Pueden ser opcionales Extienden o modifican la accin de una etiqueta <ETIQUETA atributo1=valor1 atributo2=valor2>.......... </ETIQUETA> <BODY bgcolor=yellow text=color link=blue>..... </BODY>
Hiperenlaces
Etiqueta Anchor con atributo href
<A href=direccin> texto </A>
Visita Yahoo
Servlet0.java
import javax.servlet.http.*; import javax.servlet.*; import java.io.*; public class Servlet0 extends HttpServlet { protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException{ StringBuffer buffer = new StringBuffer(); buffer.append("<HTML>\n"); buffer.append("<HEAD>\n"); buffer.append("<TITLE>Primer Servlet</TITLE>\n"); buffer.append("</HEAD>\n"); buffer.append("<H1>Hola que tal!</H1>\n"); buffer.append("</HTML>"); resp.setContentType("text/html"); resp.setContentLength(buffer.length()); resp.getOutputStream().print(buffer.toString()); } }
Funcionamiento
"Servlet engine"
R E Q
R E S P
service(req,resp) : :
ServletX
Browser
Preparacin
Agregar servlet.jar al classpath para poder compilar servlets
Copiar el archivo al directorio: /dir_java/jre/lib/ext
Bajar servlet.jar del sitio de SUN o utilizar el que venga con la maquinaria de Servlets Instalar un servidor de Web Instalar una maquinaria de servlets TOMCAT tiene ambos
Tomcat 5
Subproyecto de Jakarta, el cual es un proyecto de Apache (ASF). www.apache.org El proyecto Jakarta se encarga de crear y mantener soluciones open source para Java en el servidor Tomcat es excelente maquinaria de servlets y JSPs, actualizada y de buen rendimiento Si viene de Apache......... Ant, Cocoon, Struts, Axis..........
Instalacin de Tomcat 5
Necesita j2sdk Bajar Tomcat del sitio http://jakarta.apache.org Establecer JAVA_HOME (variable de ambiente) Activar servlet reloading (para desarrollo) Puerto 8080 (default) o el 80? Habilitar invoker servlet Cambiar la memoria de DOS (Win98) Establecer CATALINA_HOME (opcional) Arrancar Tomcat (standalone) o servicio Probar ejemplos (http://localhost:8080)
Creacin de un Servlet
Compilar el archivo del servlet (ServletX.java) Poner el cdigo obtenido (ServletX.class) en el directorio correspondiente (classes) de la aplicacin de Web
miAplicacionDeWeb/WEB-INF/classes
Llamar al servlet
http://mquina/miAplicacionDeWeb/servlet/ServletX
Servlets HTTP
Son los ms usados hasta el momento Para la creacin de pginas de Web dinmicas Dos maneras de llamar a un servlet (o a cualquier recurso)
POST GET
GET y POST
GET
Es el default para todas las conexiones Pasa los parmetros dentro del URL Hay que reprogramar doGet(req,resp)
POST
Slo disponible en formas (form) Pasa los parmetros independiente del URL ("escondidos") Hay que reprogramar doPost(req,resp)
Formularios (Forms)
Qu son? Contenedores de informacin. Cul es su objetivo? Proporcionan interactividad a
las pginas de hipertexto.
Para qu se usan?
Recolectar (registrar) informacin. Generar respuestas exclusivas (customized) Construir pginas al vuelo (on the fly)
Formularios (Forms)
Etiqueta <FORM>
El contendedor <FORM>...</FORM> se utiliza para encasillar elementos dentro de un formulario. Una forma tiene propiedades:
ACTION, METHOD
y elementos:
TEXT, BUTTON, CHECKBOX, etc
Elementos en un formulario
Botn
<INPUT TYPE=BUTTON>
NAME=string VALUE=string
Conjunto de opciones
CHECKED NAME=string VALUE=text
<INPUT TYPE=CHECKBOX>
Elementos en un formulario
Archivo
<INPUT TYPE=FILE>
Oculto
<INPUT TYPE=HIDDEN>
NAME=string VALUE=string
Elementos en un formulario
Texto
<INPUT TYPE=TEXT>
Password
Elementos en un formulario
Conjunto de seleccin
CHECKED NAME=string VALUE=string
<INPUT TYPE=RADIO>
Borrardo de datos
<INPUT TYPE=RESET>
Elementos en un formulario
Envo de datos
rea de texto
<INPUT TYPE=SUBMIT>
Elementos en un formulario
SELECT
<SELECT>...</SELECT>
OPTION
<OPTION>...</OPTION>
SELECTED VALUE=string
... separadas por el caracter &. Los caracters especiales se traducen al formato %HH (cdigos ASCII en HEX) y el espacio en blanco se convierte al signo + Existen dos mtodos para enviar la informacin ... GET y POST.
Mtodo GET
En este formato la informacin se enva junto con el URL
HTTP://maquina/directorio/servlet/MiServlet ?texto1=algo&texto2=otro&texto3=ms
Mtodo POST
En este formato la informacin se enva junto con el URL
HTTP://maquina/directorio/servlet/MiServlet
Propiedad ACTION
Indica el URL de programa en el servidor (servlet) que se debe ejectuar para procesar los datos de una forma. Adems del URL del programa especifica el mtodo a utilizar para el envio: GET o POST
Servlet1.html
<HTML> <HEAD> <TITLE>Servlets: Ejemplo 1</TITLE> </HEAD> <BODY BGCOLOR="white" TEXT="black" LINK="blue" VLINK="purple"> <H1>Lod dos tipos de llamadas a un Servlet</H1> <H2>"Form"</H2> <P>Esta forma usa el mtodo POST, el default es GET </P> <FORM ACTION="http://131.178.14.14:8080/curso/servlet/Servlet1" METHOD="POST"> <INPUT TYPE="SUBMIT" VALUE="Presiname"> </FORM> <H2>"Hyperlink"</H2> <P>El enlace usa el mtodo GET </P> <A HREF="http://131.178.14.14/curso/servlet/Servlet1">Servlet1</A> </BODY> </HTML>
Servlet1.java
import javax.servlet.http.*; import javax.servlet.*; import java.io.*; public class Servlet1 extends HttpServlet{
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException{ StringBuffer buffer = new StringBuffer(); buffer.append("<HTML>\n"); buffer.append("<HEAD>\n"); buffer.append("<TITLE>Resultado con POST</TITLE>\n"); buffer.append("</HEAD>\n"); buffer.append("<BODY BGCOLOR=\"blue\" TEXT=\"white\">\n"); buffer.append("<H1>Servlet atendi POST</H1>\n"); buffer.append("<P>Hola que tal!!!!\n"); buffer.append("</BODY>\n"); buffer.append("</HTML>"); resp.setContentType("text/html"); resp.setContentLength(buffer.length()); resp.getOutputStream().print(buffer.toString()); }
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException{ StringBuffer buffer = new StringBuffer(); buffer.append("<HTML>\n"); buffer.append("<HEAD>\n"); buffer.append("<TITLE>Resultado con GET</TITLE>\n"); buffer.append("</HEAD>\n"); buffer.append("<BODY BGCOLOR=\"red\" TEXT=\"white\">\n"); buffer.append("<H1>Servlet atendi GET</H1>\n"); buffer.append("<P>Hola que tal!!!!\n"); buffer.append("</BODY>\n"); buffer.append("</HTML>"); resp.setContentType("text/html"); resp.setContentLength(buffer.length()); resp.getOutputStream().print(buffer.toString()); }
Analizando parmetros
Los nombres de los parmetros y sus valores se transmiten como strings Se obtienen con el mtodo getParameter() del objeto de tipo HttpServletRequest
valor = req.getParameter("nombre");
String
Servlet2.html
<H1>Lod dos tipos de llamadas a un Servlet</H1> <P>Esta forma usa el mtodo POST, el default es GET </P> <FORM ACTION="http://131.178.14.14:8080/curso/servlet/Servlet2" METHOD="POST"> <INPUT NAME="caja1"> <INPUT NAME="caja2"> <INPUT TYPE="SUBMIT" VALUE="Enva"> <INPUT TYPE="RESET" VALUE="Borra"> </FORM> <HR> <P>Esta forma usa el mtodo GET, el default </P> <FORM ACTION="http://131.178.14.14:8080/curso/servlet/Servlet2"> <INPUT NAME="caja1"> <INPUT NAME="caja2"> <INPUT TYPE="SUBMIT" VALUE="Enva"> <INPUT TYPE="RESET" VALUE="Borra"> </FORM>
Servlet2.html
Servlet2.java
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException{ String caja1 = req.getParameter("caja1"); String caja2 = req.getParameter("caja2"); caja1=caja1.toUpperCase(); caja2=caja2.toLowerCase(); StringBuffer buffer = new StringBuffer(); buffer.append("<HTML>\n"); buffer.append("<HEAD>\n"); buffer.append("<TITLE>Resultado con POST</TITLE>\n"); buffer.append("</HEAD>\n"); buffer.append("<BODY BGCOLOR=\"blue\" TEXT=\"white\">\n"); buffer.append("<H1>Servlet 2 atendi POST</H1>\n"); buffer.append("<P>Me mandaron:\n"); buffer.append("<P>"+caja1+"\n"); buffer.append("<P>"+caja2+"\n"); buffer.append("</BODY>\n"); buffer.append("</HTML>"); resp.setContentType("text/html"); resp.setContentLength(buffer.length()); resp.getOutputStream().print(buffer.toString()); }
Servlet2
http://131.178.14.14:8080/curso/servlet/Servlet2
Servlet2.java
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException{ String caja1 = req.getParameter("caja1"); String caja2 = req.getParameter("caja2"); caja1=caja1.toLowerCase(); caja2=caja2.toUpperCase(); StringBuffer buffer = new StringBuffer(); buffer.append("<HTML>\n"); buffer.append("<HEAD>\n"); buffer.append("<TITLE>Resultado con GET</TITLE>\n"); buffer.append("</HEAD>\n"); buffer.append("<BODY BGCOLOR=\red\" TEXT=\"white\">\n"); buffer.append("<H1>Servlet 2 atendi GET</H1>\n"); buffer.append("<P>Me mandaron:\n"); buffer.append("<P>"+caja1+"\n"); buffer.append("<P>"+caja2+"\n"); buffer.append("</BODY>\n"); buffer.append("</HTML>"); resp.setContentType("text/html"); resp.setContentLength(buffer.length()); resp.getOutputStream().print(buffer.toString()); }
Servlet2
http://131.178.14.14:8080/curso/servlet/Servlet2?caja1=CuRsO&caja2=JaVa
Ejemplo prctico
Aplicacin de Base de datos de 3 capas El cliente es un browser
Alta disponibilidad Adecuada interfaz grfica No hay necesidad de distribuir la aplicacin
El servidor es un servlet
Java Se puede cambiar en cualquier momento No hay necesidad de configurar ODBC en el cliente
Modelo de 3 capas
Consulta Respuesta
Query Respuesta
Ejemplo
Proceso de inscripcin y consulta de alumnos Base de datos que almacena a los alumnos La inscripcin se realiza en un browser! El servlet maneja las peticiones y regresa las respuestas en forma de una pgina de Web En cualquier momento se puede cambiar el "look and feel" de la pgina de inscripcin y los clientes siguen ejecutndose desde un browser
Ejemplo
Inscripcion.html Pgina de Web que es el front end de la inscripcin Inscripcion.class Servlet que procesa la inscripcin dando de alta al alumno en una Base de Datos, regresa una pgina de Web con el resultado de la inscripcin Despliega.class Servlet que hace la consulta de todos los alumnos inscritos y regresa una pgina de Web con todos los alumnos desplegados Cursojava.mdb Base de datos con los datos de los alumnos, contiene la tabla Alumnos
Inscripcion.html
Inscripcion.html
<FORM ACTION="http://131.178.14.14:8080/curso/servlet/Inscripcion" METHOD="POST"> <P><B>Apellidos:</B><INPUT TYPE="TEXT" NAME="apellidos" SIZE="25"></P> <P><B>Nombres:</B><INPUT TYPE="TEXT" NAME="nombres" SIZE="25"></P> <P><B>Correo:</B><INPUT TYPE="TEXT" NAME="correo" SIZE="25"> <SELECT NAME="puesto"> <OPTION SELECTED> </OPTION> <OPTION>Programador</OPTION> <OPTION>Desarrollador</OPTION> <OPTION>Líder proyecto</OPTION> <OPTION>Jefe</OPTION> <OPTION>Big Chief</OPTION> </SELECT> <P ALIGN="CENTER"><A HREF="http://131.178.14.14:8080/curso/servlet/Despliega"> <FONT COLOR="yellow">Ver a los demás inscritos</FONT></A>
Inscripcion.java
import import import import javax.servlet.http.*; javax.servlet.*; java.io.*; java.sql.*;
public class Inscripcion extends HttpServlet{ private Connection conexion; private String baseDeDatos ="jdbc:odbc:cursojava"; private PreparedStatement inscribeAlumno; public void init(ServletConfig config) throws ServletException{ super.init(config); try{ Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); conexion = DriverManager.getConnection(baseDeDatos,"",""); inscribeAlumno = conexion.prepareStatement("INSERT INTO alumnos "+ "(apellidos, nombres, puesto, correo) values (?,?,?,?)"); }catch(Exception e){} }
Inscripcion.java doPost(...)
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException{ Alumno inscrito = new Alumno(req); try{ inscribeAlumno.setString(1,inscrito.getApellidos()); inscribeAlumno.setString(2,inscrito.getNombres()); inscribeAlumno.setString(3,inscrito.getPuesto()); inscribeAlumno.setString(4,inscrito.getCorreo()); inscribeAlumno.executeUpdate(); }catch(Exception e){}
Inscripcion.java doPost(...)
StringBuffer buffer = new StringBuffer(); buffer.append("<HTML>\n"); buffer.append("<HEAD>\n"); buffer.append("<TITLE>Aviso de Inscripcin</TITLE>\n"); buffer.append("</HEAD>\n"); buffer.append("<BODY BGCOLOR=\"blue\" TEXT=\"white\">\n"); buffer.append("<H1>"+inscrito.getNombres()+" "+ inscrito.getApellidos()+"</H1>\n"); buffer.append("<P>Ya ests inscrito\n"); buffer.append("<P><A HREF=http://131.178.14.14/servlet/Despliega> Quieres ver a los otros?</A>\n"); buffer.append("</BODY>\n"); buffer.append("</HTML>"); resp.setContentType("text/html"); resp.setContentLength(buffer.length()); PrintWriter salida = new PrintWriter(resp.getOutputStream()); salida.println(buffer.toString()); salida.close(); }
class Alumno{ String nombres; String apellidos; String puesto; String correo;
La clase Alumno
public Alumno(HttpServletRequest req){ apellidos = req.getParameter("apellidos"); if (apellidos.equals("")) apellidos = "sin appellidos"; nombres = req.getParameter("nombres"); if (nombres.equals("")) nombres = "sin nombres"; puesto = req.getParameter("puesto"); if (puesto.equals("")) puesto = "sin puesto"; correo = req.getParameter("correo"); if (correo.equals("")) correo = "sin correo"; }
public Alumno(String apellidos, String nombres, String puesto, String correo){ this.apellidos = apellidos; this.nombres = nombres; this.puesto = puesto; this.correo = correo; }
La clase Alumno
public void setNombres(String nombres){ this.nombres = nombres; } public void setApellidos(String apellidos){ this.apellidos = apellidos; } public void setPuesto(String puesto){ this.puesto = puesto; } public void setCorreo(String correo){ this.correo = correo; } public String getNombres(){ return nombres; } public String getApellidos(){ return apellidos; } public String getPuesto(){ return puesto; } public String getCorreo(){ return correo; }
Ejemplo
Despliega.java
import import import import javax.servlet.http.*; javax.servlet.*; java.io.*; java.sql.*;
public class Despliega extends HttpServlet{ private Connection conexion; private String baseDeDatos ="jdbc:odbc:cursojava"; private Statement estatuto;
public void init(ServletConfig config) throws ServletException{ super.init(config); try{ Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); conexion = DriverManager.getConnection(baseDeDatos,"",""); estatuto = conexion.createStatement(); }catch(Exception e){} }
Despliega.java
protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException{ Alumno inscrito; ResultSet rs=null; StringBuffer buffer = new StringBuffer(); buffer.append("<HTML>\n"); buffer.append("<HEAD>\n"); buffer.append("<TITLE>Curso de Java</TITLE>\n"); buffer.append("</HEAD>\n"); buffer.append("<BODY><CENTER>\n"); buffer.append("<H1>Lista de Alumnos</H1>\n"); buffer.append("<HR></CENTER><P>\n"); buffer.append("<CENTER><TABLE BORDER WIDTH=100% CELLPADDING=5>\n"); buffer.append("<TR>\n"); buffer.append("<TH></TH>\n"); buffer.append("<TH>Nombre</TH>\n"); buffer.append("<TH>Puesto</TH>\n"); buffer.append("<TH>Correo</TH>\n"); buffer.append("</TR>\n");
Despliega.java
try{ rs = estatuto.executeQuery("SELECT * FROM alumnos ORDER BY apellidos"); int cont = 1; while(rs.next()){ inscrito = new Alumno(rs); buffer.append("<TR>\n"); buffer.append("<TD>"+String.valueOf(cont)+"</TD>\n"); buffer.append("<TD>"+inscrito.getApellidos()+", "+ inscrito.getNombres()+"</TD>\n"); buffer.append("<TD>"+inscrito.getPuesto()+"</TD>\n"); buffer.append("<TD><A HREF=mailto:"+inscrito.getCorreo()+ "> "+inscrito.getCorreo()+"</TD>\n"); buffer.append("</TR>\n"); cont++; } }catch(SQLException e){} buffer.append("</TABLE></CENTER>\n"); buffer.append("</BODY>\n"); buffer.append("</HTML>"); resp.setContentType("text/html"); resp.setContentLength(buffer.length()); PrintWriter salida = new PrintWriter(resp.getOutputStream()); salida.println(buffer.toString()); salida.close();
La clase Alumno
public Alumno(ResultSet rs){ try{ apellidos = rs.getString("apellidos"); nombres = rs.getString("nombres"); correo = rs.getString("correo"); puesto = rs.getString("puesto"); }catch(SQLException e){} }
La clase Despliega
public void destroy(){ try{ conexion.close(); }catch(SQLException e){} }
Cuidado!!!!!!!
Variables init()
service()
service()
service()
service()
destroy()
Cuidado!!!!!!!
En init se abre una conexin a la base de datos y se crea un estatuto Cuando hay peticiones simultneas, stas comparten la conexin y el estatuto Esto lo hicimos por cuestiones de eficiencia, ya que crear conexiones consume recursos Pero . . . . . .
Posibles soluciones
Sincronizar el acceso a la Base de Datos Implementar la interfaz SingleThreadModel
Un solo service() en ejecucin en cualquier momento
Dejar que el manejador de la Base de Datos haga uso de sus capacidades de pool de conexiones......... Si las tiene
Cookies
Las famosas galletitas
Galletas
Cookies Informacin que se guarda en la mquina del cliente en un archivo de texto En su forma ms sencilla:
Nombre=valor
Por qu?
HTTP es un protocolo que no mantiene estados (Stateless) Cada peticin es servida en forma independiente por el servidor Incluso dentro de una misma pgina Las cookies nos permiten mantener un estado con un cliente especfico
Ejemplos
Contador de visitas Login y password Gustos (hbitos de navegacin) Carrito de compras
Buenas o malas?
Muy tiles Puro texto No ejecucin No virus Publicacin de mis hbitos y costumbres de navegacin Se pueden desactivar
Uso de cookies
Se usan para guardar datos en el cliente Todava estn en proceso de estandarizacin javax.servlet.http.Cookie
Mtodos importantes
getCookies() Mtodo de HttpServletRequest Regresa un arreglo de tipo Cookie con las cookies que existen en el cliente getName() y getValue() De la clase Cookie Regresan el nombre y el valor de una cookie setMaxAge(int expiry) y getMaxAge(int expiry) Establecen y regresan el tiempo de duracin de una cookie en segundos. expiry = 0 la cookie se borra, expiry < 0 durante la sesin del navegador addCookie(Cookie) Mtodo de HttpServletResponse Agrega una cookie en el cliente al cual va la respuesta
InscripcionC.java
public class InscripcionC extends HttpServlet{ String paginaInscripcion; String paginaReinscripcion; public void init(ServletConfig config) throws ServletException{ super.init(config); paginaInscripcion = leeArchivo("f:\\www\\curso\\InscripcionCN.html"); paginaReinscripcion = leeArchivo("f:\\www\\curso\\InscripcionCR.html"); } private String leeArchivo(String archivo){ StringBuffer pagina = new StringBuffer(); try{ FileReader leeArchivo = new FileReader(archivo); BufferedReader leeFiltrado = new BufferedReader(leeArchivo); String linea; while ((linea = leeFiltrado.readLine()) != null) pagina.append(linea+"\n"); leeArchivo.close(); leeFiltrado.close(); }catch(FileNotFoundException e){ }catch(IOException e){ } return pagina.toString(); }
InscripcionC.java
protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException{ String pagina=paginaInscripcion; Cookie[] cookies = req.getCookies(); try{ for(int i=0; i < cookies.length; i++) { if (cookies[i].getName().equals("galletita") && cookies[i].getValue().equals("galletita")){ pagina = paginaReinscripcion; break; } } }catch(Exception e){ } Cookie galletita = new Cookie("galletita","galletita"); galletita.setMaxAge(-1); resp.addCookie(galletita); resp.setContentType("text/html"); resp.setContentLength(pagina.length()); PrintWriter salida = new PrintWriter(resp.getOutputStream()); salida.println(pagina); salida.close(); }
public class Identifica extends HttpServlet{ Enumeration nombres; String parametro; String valor;
Identifica.java
protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException{ String escrito = req.getParameter("escrito"); StringBuffer buffer = new StringBuffer(); buffer.append("<HTML>\n"); buffer.append("<HEAD>\n"); buffer.append("<TITLE>Resultado con POST</TITLE>\n"); buffer.append("</HEAD>\n"); buffer.append("<BODY BGCOLOR=\"blue\" TEXT=\"white\">\n"); buffer.append("<H1>Variables de Ambiente</H1>\n"); nombres = req.getHeaderNames(); while (nombres.hasMoreElements()) { parametro = (String)nombres.nextElement(); buffer.append(parametro + " = "); valor = req.getHeader(parametro); buffer.append(valor); buffer.append("<BR>"); } buffer.append("</BODY>\n"); buffer.append("</HTML>"); resp.setContentType("text/html"); resp.setContentLength(buffer.length()); resp.getOutputStream().print(buffer.toString()); }
Documentacin de Servlets
Se baja del sitio de SUN, del mismo lugar donde bajamos las clases de servlets Algunos mtodos adicionales de la clase Cookie Mtodos para obtener parmetros (encabezados) de HttpServletRequest
Manejo de Sesiones
HTTP es un protocolo que no mantiene estado (stateless) Cada conexin es completamente independiente de la anterior Un problema para manejar peticiones en diferentes pginas de un mismo cliente
Soluciones al problema
Cookies
La mejor solucin pero el usuario las puede deshabilitar
Campos ocultos
Cualquier persona puede ver el cdigo...
Sesiones en Servlets
Servlets maneja la clase HTTPSession Es una abstraccin poderosa que nos permite despreocuparnos de los detalles del manejo de estado Primero intenta utilizar cookies y si no se puede usa la reescritura de URL Todo es transparente al programador
Objeto Session
HttpSession sesion = request.getSession(true) Es tan usado que en caso de no exista una sesin asociada con el cliente crea una en forma atutomtica
SetAttribute(nombre, valor)
Antes se usaba putValue(...) (deprecated)
Ejemplos
Veremos dos ejemplos:
Vista de pginas slo a usuarios autorizados (Pgina de Login)
JSPs
JSPs
Desarrollo en Web
Servlets
Programa en Java produce una pgina en HTML
Java
Html
Pgina de Web
JSPs
Pgina en Html con scripts de Java
Html
Java
Pgina de Web
public class Fecha extends HttpServlet { public void doGet (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException{ ServletOutputStream out = res.getOutputStream(); res.setContentType("text/html"); out.println("<HTML>"); out.println("<HEAD><TITLE> Servlet de Fecha </TITLE></HEAD>"); out.println("<BODY>"); out.println("<h1> La fecha es: "+ new Date().toString() +"</h1>"); out.println("</BODY>"); out.println("</HTML>"); out.close(); }
<HTML> <%@ page language import = %> <HEAD><TITLE> JSP <BODY> <H1> La fecha es: </BODY> </HTML>
= "java" "java.util.*"
de Fecha </TITLE></HEAD> <%= new Date().toString() %> </H1>
JSPs
Java/Html
P R O G R A M A D O R A
D I S E A D O R
Pginas de Web
HTML (Estticas) CGI (Perl, Php, C) Servlets (java) ASPs (vbscript) JSPs (Java)
JSPs
Cdigo de Java embebido en pgina HTML HTML con etiquetas adicionales especcificas para JSPs Tres tipos de etiquetas
Elementos de cdigo (scripting) Elementos de accin Elementos directivos
Etiquetas de Scripting
Comentarios
<%-- .... --%> <!- .... -->
Declaraciones
<%! ..... %>
Expresiones
<%= ..... %>
Scriptles
<% ..... %>
Comentarios
<! comentario [<%= expresin %>] -->
Genera un comentario que se enva al cliente y se puede visualizar en el cdigo fuente de HTML
<HTML> <%@ page language = "java %> <HEAD><TITLE> Jsp1.jsp </TITLE></HEAD> <BODY> <!-- Este comentario aparecerá en el fuente de la página --> <H1> Página generada con JSP</H1> </BODY> </HTML>
Comentarios
<%-- Comentario -->
Comentario que no se enva al cliente (escondido) Para documentar la pgina JSP
<HTML> <HEAD><TITLE> Jsp2.jsp </TITLE></HEAD> <BODY> <!-- Este comentario aparecerá en el fuente de la página --> <%-- Este comentario no aparecer en el cliente --%> <H1> Página generada con JSP</H1> </BODY> </HTML>
Declaraciones
<%! Declaraciones %> Para declarar variables o mtodos vlidos en el lenguaje, para ser utilizados dentro de la pgina Debe de contener por lo menos un estatuto de declaracin vlido Cada estatuto debe terminar con ; Se deben declarar las variables y mtodos antes de ser usados en la pgina Se pueden usar variables y mtodos de los paquetes importados con la directiva Page, sin necesidas de declararlos explcitamente
<%! Int i, j; String s; Date fecha = new Date(); %>
Expresiones
<%= expresin %>
Expresin vlida en el lenguaje de script (Java) La expresin se evalua, se convierte a String y se inserta en la pgina, en el lugar donde aparece No debe de terminar con ;
<HTML> <%@ page language = "java" import = "java.util.*" %> <%! Date fecha = new Date(); %> <HEAD><TITLE> Jsp3.jsp </TITLE></HEAD> <BODY> <B><FONT COLOR=blue> Hoy es <%= fecha.toString() %></FONT></B> </BODY> </HTML>
Scriptlets
<% estatutos %>
Puede contener estatutos, declaracin de variables o mtodos Se pueden usar los objetos implcitos de JSP
request, response, out, . . . . .
Se ejecutan en el momento de la peticin de la pgina, al igual que las expresiones Las declaraciones se ejecutan una sola vez, al momento de cargar la pgina por primera vez . . . . . .
Scriptlets
<HTML> <%@ page language = "java" import = "java.util.*" %> <%! int accesos = 0; String tipo; %> <HEAD><TITLE> Jsp4.jsp </TITLE></HEAD> <BODY> <% accesos++; if ((accesos%2) != 0) tipo = "impar"; else tipo = "par"; %> <BR>La página se ha cargado <%= accesos %> <BR>Que quiere decir un número <%= tipo %> de veces <BR> <% out.print("<FONT COLOR=\"red\">"); out.print(new Date().toString()); out.println("</FONT>"); %> <BR>Fin de la página </BODY> </HTML>
Declaracin de mtodos
Los mtodos se declaran dentro de una etiqueta de declaracin (<%! ...... %>) Se pueden usar en toda la pgina
<HTML> <%@ page language = "java" %> <%! int accesos = 0; String tipo; public String tipo(int n){ if ((n%2) != 0) return "impar"; else return "par"; } %> <HEAD><TITLE> Jsp5.jsp </TITLE></HEAD> <BODY> <% accesos++; %> <BR>La página se ha cargado <%= accesos %> veces <BR>Que quiere decir un número <%= tipo(accesos) %> de veces </BODY> </HTML>
La directiva Page
<%@ page [ language [ extends [ import [ session [ buffer [ autoFlush [ isThreadSafe [ info [ errorPage [ contentType [ isErrorPage %> = = = = = = = = = = java ] package.clase ] {package.class | package.*},...] true|false ] none|8kb|sizeKb ] true|false ] true|false ] text ] relativeURL ] mimeType [;charset=charSet]| text/html ; charset = ISO-8859-1 ] = true|false ]
Objetos implcitos
request response out session application config pageContext page
<HTML> <HEAD> <TITLE>Jsp6.html</TITLE> </HEAD> <BODY BGCOLOR="white" TEXT="black" LINK="blue" VLINK="purple"> <H1>Formulario</H1> <P>Esta forma llamar a una JSP y regreser el primer dato en minsculas y el segundo en maysculas <BR><FORM ACTION="Jsp6.jsp" METHOD="GET"> <BR> Dato1: <INPUT NAME="caja1"> <BR> Dato2: <INPUT NAME="caja2"> <BR><INPUT TYPE="SUBMIT" VALUE="ENVIA"> </FORM> </BODY> </HTML>
request
<%@ page language="java" %> <HTML> <HEAD><TITLE>Jsp6.jsp</TITLE></HEAD> <BODY> <% String s1 = request.getParameter("caja1"); String s2 = request.getParameter("caja2"); %> <BR> Dato1: <%= s1.toLowerCase() %> <BR> Dato2: <%= s2.toUpperCase() %> </BODY> </HTML>
request
<html> <head> <title>Despliega.jsp</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> </head> <%@ page languaje = "java" import = "java.sql.*" errorPage = "Error.jsp" %> <%! Connection conexion; Statement estatuto; ResultSet rs; String nombres, apellidos, puesto, correo; int cont; %> <% Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); conexion = DriverManager.getConnection("jdbc:odbc:cursojava"); %> <body bgcolor="#000099"> <h1 align="center"><font color="#FFFF00">Lista de Alumnos</font></h1>
<table width="100%" border="1"> <tr> <th width="5%"><font color="#00FF00"><b></b></font></th> <th width="49%"><font color="#00FF00"><b>Nombre</b></font></th> <th width="17%"><font color="#00FF00"><b>Puesto</b></font></th> <th width="29%"><font color="#00FF00"><b>Correo</b></font></th> </tr> <% estatuto = conexion.createStatement(); rs = estatuto.executeQuery("SELECT * FROM alumnos ORDER by apellidos"); cont = 0; while(rs.next()){ cont++; nombres = rs.getString("nombres"); apellidos = rs.getString("apellidos"); puesto = rs.getString("puesto"); correo = rs.getString("correo"); %> <tr> <td width="5%"><b><font color="#FFFFFF"><%= cont %></font></b></td> <td width="49%"><b><font color="#FFFFFF"><%= nombres +" "+ apellidos %> </font></b></td> <td width="17%"><b><font color="#FFFFFF"><%= puesto %></font></b></td> <td width="29%"><b><font color="#FFFFFF"> <A HREF=mailto:<%= correo %> > <font color="#FF0033"><%= correo %></font></A></font></b></td> </tr> <% } rs.close(); estatuto.close(); conexion.close(); %> </table>
<table width="100%" border="1"> <tr> <th width="5%"><font color="#00FF00"><b></b></font></th> <th width="49%"><font color="#00FF00"><b>Nombre</b></font></th> <th width="17%"><font color="#00FF00"><b>Puesto</b></font></th> <th width="29%"><font color="#00FF00"><b>Correo</b></font></th> </tr> <% estatuto = conexion.createStatement(); rs = estatuto.executeQuery("SELECT * FROM alumnos ORDER by apellidos"); cont = 0; while(rs.next()){ cont++; nombres = rs.getString("nombres"); apellidos = rs.getString("apellidos"); puesto = rs.getString("puesto"); correo = rs.getString("correo"); %> <tr> <td width="5%"><b><font color="#FFFFFF"><%= cont %></font></b></td> <td width="49%"><b><font color="#FFFFFF"><%= nombres +" "+ apellidos %> </font></b></td> <td width="17%"><b><font color="#FFFFFF"><%= puesto %></font></b></td> <td width="29%"><b><font color="#FFFFFF"> <A HREF=mailto:<%= correo %> > <font color="#FF0033"><%= correo %></font></A></font></b></td> </tr> <% } rs.close(); estatuto.close(); conexion.close(); %> </table>
GET Archivo.jsp
Pgina HTML
Archivo.class
Archivo.java
jspInit() y jspDestroy()
<%! Connection conexion; Statement estatuto; ResultSet rs; String nombres, apellidos, puesto, correo; int cont;
public void jspInit(){ try{ Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); conexion = DriverManager.getConnection("jdbc:odbc:cursojava"); }catch(ClassNotFoundException e1){ System.err.println("Error en la clase"); }catch(SQLException e2){ System.err.println("Error en SQL"); } }
public void jspDestroy(){ try{ conexion.close(); }catch(SQLException e2){} }
%>
Rendimiento
Impacto inicial
Generacin del .class
Produccin!!!!!!!!!!
Ms rpida y adecuada
JavaBeans
Son componentes Clases que eventualmente se convertirn en objetos Siguen ciertas reglas un poco ms estrictas que las clases normales Nacieron como componentes grficos para IDEs
JavaBeans
Si se usan bien realmente nos dan la separacin entre diseo y contenido que tanto se necesita No hay que olvidar que en ltima instancia un bean es una clase, de la cual se pueden crear objetos
Reglas
Debe de tener un constructor sin parmetros No debe de tener variables de ejemplar pblicas Las variables (propiedades) del bean se deben de obtener o modificar por medio de mtodos llamados getXxx y setXxx
Ejemplo
import java.util.*; import java.text.*; public class FechasBean{ private Locale local = new Locale("es","MX");
public FechasBean(){}
public String getFechaLarga(){ DateFormat f = DateFormat.getDateInstance(DateFormat.FULL, local); return f.format(new Date()); } public String getHoraCorta(){ DateFormat f = DateFormat.getTimeInstance(DateFormat.SHORT, local); return f.format(new Date()); } }
Fecha.jsp
<html>
<%@ page language = "java" %>
<body> <H1> La fecha de es: <jsp:getProperty name="fecha" property="fechaLarga" /> </H1> <H1> La hora es: <jsp:getProperty name="fecha" property="horaCorta" /> </H1> </body>
</html>
Alcance de un bean
Tiempo de vida dado por scope page
Se crea cada vez que se carga la pgina (Fecha3.jsp)
session
Dura toda la sesin de peticiones (requests) (Fecha3a.jsp)
application
Para compartir los beans con otros servlets y jsps con sesiones diferentes (Fecha4.jsp)
Un mejor Despliega
<HTML> <HEAD> <TITLE>DespliegaConBean.jsp</title> </HEAD> <%@ page %> <jsp:useBean id="despliega" scope="application" class="DespliegaBean" /> <BODY> <H1 align="center">Lista de Alumnos</H1> <jsp:getProperty name="despliega" property="participantes" /> <H1 align="center">Fin de la lista </H1> </BODY> </HTML> language = "java" errorPage = "Error.jsp"
DespliegaBean.java
import java.util.*; import java.sql.*;
public class DespliegaBean{ private Connection conexion; private String baseDeDatos ="jdbc:odbc:cursojava"; private Statement estatuto; private ResultSet rs;
public DespliegaBean(){ try{ Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); }catch(ClassNotFoundException e){} }
DespliegaBean.java
synchronized public String getParticipantes(){ Alumno inscrito; StringBuffer buffer = new StringBuffer(500); buffer.append("<CENTER><TABLE BORDER WIDTH=100% CELLPADDING=5>\n"); buffer.append("<TR>\n"); buffer.append("<TH></TH>\n"); buffer.append("<TH>Nombre</TH>\n"); buffer.append("<TH>Puesto</TH>\n"); buffer.append("<TH>Correo</TH>\n"); buffer.append("</TR>\n");
DespliegaBean.java
try{
conexion = DriverManager.getConnection(baseDeDatos,"",""); estatuto = conexion.createStatement(); rs = estatuto.executeQuery("SELECT * FROM alumnos ORDER BY apellidos"); int cont = 1; while(rs.next()){ inscrito = new Alumno(rs); buffer.append("<TR>\n"); buffer.append("<TD>"+String.valueOf(cont)+"</TD>\n"); buffer.append("<TD>"+inscrito.getApellidos()+", "+ nscrito.getNombres()+"</TD>\n"); buffer.append("<TD>"+inscrito.getPuesto()+"</TD>\n"); buffer.append("<TD><A HREF=mailto:"+inscrito.getCorreo()+ "> "+inscrito.getCorreo()+"</TD>\n"); buffer.append("</TR>\n"); cont++; } rs.close(); estatuto.close(); conexion.close(); }catch(SQLException e){} buffer.append("</TABLE>"); return buffer.toString();
Manejo de Sesiones
A veces el usuario inhibe las cookies Tenemos que tener mtodos alternos para manejar estado del cliente Existen mtodos ya probados:
URLrewriting y campos escondidos
Manejo de sesiones
Java implement una clase que maneja sesiones Inicialmente trata de usar cookies y si no puede lo hace a travs de URLrewriting Pero es completamente transparente Ver ejemplos
Modelos I y II
Son modelos para el desarrollo de aplicaciones en Web Inicialmente nos vemos tentados a utilizar solamente JSPs (por su facilidad) Pero acabamos con cdigo muy difcil de mantener, nuestros JSPs se hacen cada vez ms complicados
Modelo 1
Peticin
JSP Respuesta Base De Datos
JavaBean
Modelo 2
Peticin
servlet
JSP
JavaBean
Ejemplo de la red
Ananalizaremos un ejemplo de la revista JavaWorld Nos dar un diferente enfoque al desarrollo de estas aplicaciones Adems manejaremos sesiones
http://javax.mty.itesm.mx/puce