Académique Documents
Professionnel Documents
Culture Documents
Introducción
Este libro, por tanto, resulta especialmente adecuado para los lectores que no
poseen unos conocimientos previos del lenguaje o para aquellos cuyo principal
objetivo es adquirir los fundamentos de Java para, posteriormente, poder afrontar
con una base sólida el aprendizaje de aspectos específicos tales como las
comunicaciones, acceso a bases de datos, presentaciones multimedia, etc.
Capítulo 6: excepciones
LECCIÓN 25: Excepciones predefinidas
LECCIÓN 26: Excepciones definidas por el programador
Capítulo 8: eventos
LECCIÓN 33: Mecanismo de eventos en java
LECCIÓN 34: Eventos de ratón y de movimiento de ratón
LECCIÓN 35: Eventos de teclado y de ventana
LECCIÓN 36: Eventos de acción, enfoque y elemento
05 06
01 02 03 04 07 09 10
08
11
13 14 15 16 17 18 19
12
20 21 22 23 24 25 26 27 28
29 36
31 32 33 34 37 38
30 36
XVI JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
Las lecciones del gráfico que tienen fondo gris pueden ser omitidas en caso
de necesidad; esto es posible debido a que se corresponden con ejercicios de
consolidación de los temas anteriores o porque se refieren a características del
lenguaje que se utilizan con menos frecuencia. En cualquier caso, el estudio de estas
lecciones resulta importante para conseguir una mejor asimilación de los conceptos
explicados, por lo que es muy conveniente acudir a ellas una vez comprendidas las
lecciones que les preceden.
APÉNDICES
Pasos detallados:
1 Abrir un editor de texto (por ejemplo el WordPad)
Habitualmente a través del botón de Inicio: (Inicio → Programas →
Accesorios → WordPad).
2 Introducir el código (sin incluir los números de línea):
1 public class HolaMundo {
2 public static void main (String[] args) {
3 System.out.println("Hola Mundo");
4 }
5 }
Es necesario respetar la condición mayúscula/minúscula de cada letra
del programa, puesto que en este lenguaje una letra en minúscula es
diferente a su correspondiente en mayúsculas.
La línea 1 define la clase (objeto) HolaMundo. Java es un lenguaje
orientado a objetos, donde toda las aplicaciones se estructuran en
grupos de objetos (clases en Java). La clase se define como public
(publica), indicando que será accesible a cualquie r otra clase. El
último carácter de la línea 1 es una llave de comienzo; indica el
comienzo de la clase. La clase termina en la línea 5 (con la llave de
fin).
La línea 2 define un método (procedimiento, subrutina) de la clase
HolaMundo. Este método es espe cial, le indica al entorno de Java el
comienzo de nuestra aplicación. Su nombre (identificador) es: main
(método principal). Este método siempre lleva un parámetro String[]
que identifica un conjunto de literales (textos); por ahora no
emplearemos esta característica, aunque debemos respetar su sintaxis.
El método es público y estático (atributos que veremos en detalle en
los temas siguientes).
El contenido del método main, en nuestro ejemplo, se encuentra
delimitado entre la llave de inicio situada en la línea 2 y la llave de fin
6 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
4 Compilar el programa
En la ventana de MS-DOS, en el directorio donde hemos grabado el
fichero HolaMundo.java, debemos ejecutar el compilador (javac)
poniendo como argumento el nombre del fichero CON LA
EXTENSIÓN .java (javac HolaMundo.java). Si existen errores, se
obtendrá un listado de los mismos. Si no los hay, como en nuestro
caso, no aparece nada:
BOBADILLA CAPÍTULO 1: CONCEPTOS BÁSICOS, VARIABLES, TIPOS DE DATOS Y OPERADORES 7
5 Ejecutar el programa
En el directorio en el que estamos trabajando, ejecutar el intérprete de
java (java) suministrando como parámetro el nombre de la clase
(HolaMundo) SIN la extensión .class (java HolaMundo). Nos
aparecerá el texto “Hola Mundo” correspondiente a la impresión de
datos por consola que codificamos en la línea 3 de nuestro programa:
1.3.1 Variables
Para asentar los conceptos expresados en este apartado, veamos una serie de
casos de identificadores de variables correctos e incorrectos:
LaCasaDeLaPradera → identificador correcto
El Hombre Sin Rostro → identificador incorrecto, no debe existir ningún
espacio en blanco en un nombre de variable
3Deseos → identificador incorrecto, el nombre no empieza por una letra
(sino por un número)
TresDeseos → identificador correcto
_4 → identificador correcto
$ → identificador correcto
BOBADILLA CAPÍTULO 1: CONCEPTOS BÁSICOS, VARIABLES, TIPOS DE DATOS Y OPERADORES 9
TIPOS PRIMITIVOS
Nombre del tipo Tamaño en bytes Rango
Tipos numéricos enteros
byte 1 -128 a 127
10 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
Por ejemplo:
byte EdadPedro = 60;
short SueldoMensual;
float PrecioEnEuros, Cateto1, Cateto2, Hipotenusa;
boolean Adquirido = false, Finalizado = true;
7 }
8 }
Para modificar el tipo de un valor, basta con indicar el nuevo tipo entre
paréntesis antes del valor, por ejemplo:
(byte ) 1 → convierte el 1 (int) a byte
(double) MiVariableDeTipoFloat → convierte a double una variable de
tipo float
(short) (VariableDeTipoByte + VariableDeTipoByte) → convierte a short el
resultado de sumar dos variables de tipo byte. Obsérvese que al sumarse dos
variables de tipo byte, el resultado puede que no “quepa” en otra variable de
tipo byte.
1.4 OPERADORES
1.4.1 Introducción
Los operadores aritméticos más comunes son la suma (+) , resta (-),
multiplicación (*) y división (/) binarios, aunque también se utilizan los operadores
unarios (+) y (-), y el operador binario que obtiene el módulo de una división (%).
Finalmente, disponemos de operadores aritméticos de preincremento,
postincremento, predecremento y postdecremento, que permiten acortar el tamaño
de ciertas instrucciones y facilitar la optimización de código por parte del
compilador.
Operación sintaxis significado
Preincremento ++Variable; Variable = Variable + 1; (antes de asignación)
Postincremento Variable++; Variable = Variable + 1; (después de asignación)
Predecremento --Variable; Variable = Variable – 1; (antes de asignación)
Postdecremento Variable--; Variable = Variable – 1; (después de asignación)
16 System.out.println(Impuesto);
17 System.out.println(Impuesto2);
18 System.out.println(Cociente);
19 System.out.println(Resto);
20 System.out.println(PostIncremento);
21 System.out.println(PreIncremento);
22 System.out.println(PostDecremento);
23 System.out.println(PreDecremento);
24 }
25 }
5 Riego = false;
6
7 Oportunidad = Bueno && Bonito && Barato;
8
9 System.out.println(!Frio);
10 System.out.println(Oportunidad);
11 System.out.println(Llueve || Riego);
12 }
13 }
ESTRUCTURAS DE CONTROL
2.1.1 Sintaxis
En este apartado vamos a ilustrar una serie de actuaciones erróneas que son
muy habituales entre las personas que empiezan a programar. Resulta especialmente
conveniente prestar atención en este apartado para evitar, en la medida de lo posible,
codificar los programas con errores.
La primera situación que vamos a analizar son los bucles infinitos (producto
siempre de un error en la programación). En el siguiente ejemplo (BucleFor5) se
produce esta situación, debido a que la condición de continuidad del bucle nunca se
evalúa como false. Analizando el programa, llegamos fácilmente a la conclusión de
que la variable i albergará únicamente valores pares positivos, por lo que la
condición de continuidad i!=21 nunca se evaluará como false y por lo tanto nunca se
saldrá del bucle.
Las instrucciones que se repiten (1000 veces) son las que se encuentran
entre los delimitadores { } asociados a la instrucción repetitiva for; por ello tanto la
instrucción 5 como la 6 se ejecutan 1000 veces. En cada vuelta del bucle se añade el
valor de i (1,2,3,4, ..., 1000) al resultado de la suma anterior (guardado en la variable
Suma). La evolución de las variables es la siguiente:
Factorial de un número
Solución:
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 2: ESTRUCTURAS DE CONTROL 27
Para hallar el factorial de cualquier otro número, basta con variar el valor
con el que inicializamos la variable Numero, en la línea 6. Obsérvese que el factorial
de 1 (que es cero) no se saca con este método, y sobre todo, que si el valor de
Numero es muy grande, podemos desbordar el rango del tipo int, por lo que sería
conveniente emplear el tipo long.
Problema de logística
En las grandes ciudades el precio del suelo es muy caro, por lo que comprar
o alquilar grandes superficies de almacenamiento de electrodomésticos resulta
prohibitivo en el centro de la ciudad. La solución es alejarse del núcleo urbano, sin
embargo, cuanto más nos alejamos, más nos cuesta el precio de distribución que
cada día hay que abonar a los transportistas que nos trasladan los electrodomésticos
de la periferia al centro (donde se realizan la mayoría de las compras).
Solución:
Para realizar este ejercicio hubiera sido mucho más elegante emplear una
estructura de control de flujo en bucle que nos permitiera iterar mientras (o hasta)
que se cumpla una condición determinada: (que CapacidadTotal >=100000). El
bucle for no nos resuelve esta situación adecuadamente, puesto que está diseñado
para indicar a priori el número de iteraciones, aunque tampoco resulta imposible
utilizarlo de otra manera:
En cualquier caso, para resolver este ejercicio, resulta más apropiado utilizar
las estructuras de control que se explican en el siguiente apartado.
2.2.1 Sintaxis
do {
Instrucciones a ejecutar de forma repetitiva
} while (condición de continuidad);
Este problema lo podemos resolver de forma muy simple haciendo uso del
bucle while:
6 i++;
7 Suma = Suma + i;
8 } while (Suma<100000);
9 System.out.println(i);
10 }
11 }
Problema de logística
En las grandes ciudades el precio del suelo es muy caro, por lo que comprar
o alquilar grandes superficies de almacenamiento de electrodomésticos resulta
prohibitivo en el centro de la ciudad. La solución es alejarse del núcleo urbano, sin
34 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
embargo, cuanto más nos aleja mos, más nos cuesta el precio de distribución que
cada día hay que abonar a los transportistas que nos trasladan los electrodomésticos
de la periferia al centro (donde se realizan la mayoría de las compras).
Solución:
2.3.1 Sintaxis
if (condición)
Instrucción
if (condición) {
Instrucciones
}
if (condición)
Instrucción de la rama “then”
else
Instrucción de la rama “else”
if (condición) {
Instrucciones de la rama “then”
} else {
Instrucciones de la rama “else”
}
En las dos últimas sintaxis de la instrucción if, se introduce una “rama” else,
cuyo significado es: si la condición se evalúa como true se ejecuta el grupo de
instrucciones de la primera rama (llamémosla “then”), en caso contrario (la
condición se evalúa como false) se ejecuta el grupo de instrucciones de la segunda
rama (la rama “else”).
2.3.3 if anidados
Una solución más fácil de entender, pero mucho más costosa en ejecución
(por el número de condiciones a evaluar) es:
2.4.1 Sintaxis
switch (expresión) {
case valor1:
Instrucciones;
break;
case valor1:
Instrucciones;
break;
...........................
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 2: ESTRUCTURAS DE CONTROL 41
default:
Instrucciones;
break;
}
La cláusula default es muy útil, nos sirve para indicar que se ejecuten sus
instrucciones asociadas en el caso de que no se haya ejecutado previamente ningún
otro grupo de instrucciones.
Nuestro primer ejemplo (Switch1) nos muestra una instrucción switch (línea
5) con una expresión de tipo int. Según el valor de la expresión sea 1, 2 ó 3, se
imprimirán diferentes mensajes. Cuando el valor de la expresión es diferente a 1, 2 y
3 (línea 18) se imprime un mensaje genérico (línea 19). En el ejemplo, si la
instrucción 12 no existiera, se imprimirían dos mensajes: “Medalla de plata” y
“Medalla de bronce”.
10 case 2:
11 System.out.println("Medalla de plata");
12 break;
13
14 case 3:
15 System.out.println("Medalla de bronce");
16 break;
17
18 default:
19 System.out.println("Gracias por participar");
20 break;
21
22 }
23
24 }
25 }
22 }
23
24 }
25 }
Podemos ampliar el ejemplo anterior para que admita también los comandos
en mayúsculas. Obsérvese la nueva sintaxis:
7 System.out.println("Primera opcion");
8 break;
9
10 case 1:
11 System.out.println("Segunda opcion");
12 break;
13
14 case 2:
15 System.out.println("Tercera opcion");
16 break;
17
18 }
19
20 }
21 }
Resulta muy habitual tener que realizar selecciones basadas en dos niveles;
el siguiente ejemplo muestra una de estas situaciones: estamos realizando las
páginas Web de un concesionario de vehículos de la marca SEAT y en un momento
dado el usuario puede escoger entre las siguientes opciones:
Para programar la elección de opción por parte del usuario, resulta adecuado
emplear una instrucción switch anidada:
11 break;
12 case 'b':
13 Disponible = true;
14 break;
15 case 'r':
16 Disponible = true;
17 break;
18 default:
19 System.out.println("Opcion no contemplada");
20 break;
21 }
22 break;
23
24 case 'c':
25 switch (Color) {
26 case 'a':
27 Disponible = false;
28 break;
29 case 'b':
30 Disponible = true;
31 break;
32 case 'r':
33 Disponible = false;
34 break;
35 default:
36 System.out.println("Opcion no contemplada");
37 break;
38 }
39 break;
40
41 case 't':
42 switch (Color) {
43 case 'a':
44 Disponible = false;
45 break;
46 case 'b':
47 Disponible = true;
48 break;
49 case 'r':
50 Disponible = true;
51 break;
52 default:
53 System.out.println("Opcion no contemplada");
54 break;
55 }
56 break;
57
58 default:
59 System.out.println("Opcion no contemplada");
46 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
60 break;
61 }
62
63 if (Disponible)
64 System.out.println("Opcion disponible");
65 else
66 System.out.println("Opcion no disponible");
67
68 }
69 }
4 byte Mes = 2;
5 boolean Bisisesto = false;
6
7 switch (Mes) {
8 case FEBRERO:
9 if (Bisisesto)
10 System.out.println(29);
11 else
12 System.out.println(28);
13 break;
14
15 case ABRIL:
16 case JUNIO:
17 case SEPTIEMBRE:
18 case NOVIEMBRE:
19 System.out.println(30);
20 break;
21
22 case ENERO:
23 case MARZO:
24 case MAYO:
25 case JULIO:
26 case AGOSTO:
27 case OCTUBRE:
28 case DICIEMBRE:
29 System.out.println(31);
30 break;
31
32 default:
33 System.out.println("Numero de mes erroneo");
34 break;
35 }
36 }
37 }
2.5 EJEMPLOS
En esta lección se realizan tres ejemplos en los que se combinan buena parte
de los conceptos explicados en las lecciones anteriores. Los ejemplos seleccionados
son:
1. Cálculo de la hipotenusa de un triángulo
2. Soluciones de una ecuación de segundo grado
50 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
Para permitir que el usuario pueda seleccionar, en cada caso, los parámetros
necesarios (longitudes de los catetos, coordenadas de los vectores en las rectas, etc.)
se proporciona una clase de entrada de datos por teclado desarrollada por el autor: la
clase Teclado, que consta de los métodos:
• public static String Lee_String()
• public static long Lee_long()
• public static int Lee_int()
• public static int Lee_short()
• public static byte Lee_byte()
• public static float Lee_float()
• public static double Lee_double()
De esta manera, para leer un valor de tipo byte, podemos utilizar una
instrucción similar a: byte Edad = Teclado.Lee_byte();
H = √ C12 * C22
C1
C2
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 2: ESTRUCTURAS DE CONTROL 51
Ejercicio resuelto
Comentarios
Resultados
X1, Y1
X2, Y2
Cualquier punto de la recta puede obtenerse multiplicando un número real por los
vectores (X2-X1) e (Y2-Y1):
X1, Y1
X2, Y2
Siendo t el valor real a partir del cual podemos obtener cualquier punto de la
recta. Si dibujamos dos rectas no paralelas:
X4, Y4 X = X1 + (X2-X1) * t
Y = Y1 – (Y2-Y1) * t
X1, Y1
El punto de corte es el que cumple que la X y la Y en las dos rectas son los
mismos:
X1 + (X2-X1) * t = X3 + (X4-X3) * r
Y1 – (Y2-Y1) * t = Y4 – (Y4-Y3) * r
Despejando:
Ejercicio resuelto
22 X3 = Teclado.Lee_int();
23 System.out.println();
24
25 System.out.print("Introduce el valor de X4:");
26 X4 = Teclado.Lee_int();
27 System.out.println();
28
29 System.out.print("Introduce el valor de Y3:");
30 Y3 = Teclado.Lee_int();
31 System.out.println();
32
33 System.out.print("Introduce el valor de Y4:");
34 Y4 = Teclado.Lee_int();
35 System.out.println();
36
37 int Denominador = (Y4-Y3)*(X2-X1) - (Y2-Y1)*(X4-X3);
38 if (Denominador == 0)
39 System.out.println("Las rectas son paralelas");
40 else {
41 int Numerador = (Y4-Y3)*(X3-X1) - (Y3-Y1)*(X4-X3);
42 float t = (float) Numerador / (float) Denominador;
43 float CorteX = X1 + (X2-X1)*t;
44 float CorteY = Y1 + (Y2-Y1)*t;
45 System.out.println("Punto de corte: " + CorteX +
46 ", "+ CorteY);
47 }
48
49 }
50 }
Comentarios
Resultados
Una ecuación de grado 2 define una parábola, que puede no cortar el eje x,
cortarlo en un único punto o bien cortarlo en dos puntos.
Ejercicio resuelto
19 if (Auxiliar<0)
20 System.out.println("No existen raices reales");
21 else
22 if (Auxiliar == 0d) {
23 System.out.print("Solo existe una raiz: ");
24 System.out.println(-b/2d*a);
25 } else { // Auxiliar mayor que cero
26 Auxiliar = Math.sqrt(Auxiliar);
27 double Raiz1 = (-b + Auxiliar) / (2 * a);
28 double Raiz2 = (-b - Auxiliar) / (2 * a);
29 System.out.println("Raices: " + Raiz1 +
30 ", "+ Raiz2);
31 }
32
33 }
34 }
Comentarios
Resultados
CAPÍTULO 3
MÉTODOS Y ESTRUCTURAS DE
DATOS
3.1 MÉTODOS
Los métodos (procedimientos, funciones, subrutinas) nos permiten
encapsular un conjunto de instrucciones de manera que puedan ser ejecutadas desde
diferentes puntos de la aplicación. Por ejemplo, puede resultar útil crear un método
que convierta de libras a kilos, de manera que, cada vez que se necesite realizar esta
conversión se pueda invocar al método sin preocuparse de los detalles con los que
está implementado.
3.1.1 Sintaxis
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 3: MÉTODOS Y ESTRUCTURAS DE DATOS 59
Ejemplo:
3.1.2 Ejemplo 1
3.1.4 Ejemplo 2
3.2 STRINGS
Los Strings, también llamados literales o cadenas de caracteres, nos
permiten declarar, definir y operar con palabras y frases. Su utilización es muy
común en los programas, de hecho, nosotros, de una forma implícita los hemos
usado en todos los ejemplos anteriores al escribir frases en consola por medio del
método System.out.println(“El String a imprimir”); también declaramos una
estructura de datos basada en el String como parámetro del método main.
Los Strings no forman parte de los tipos nativos de Java, sino que existe una
clase String (java.lang.String).
3.2.1 Sintaxis
ninguna estructura de datos; su valor es null. Esto es diferente a una instancia del
objeto String que apunta hacia un conjunto de caracteres vacío.
Ejemplo:
boolean Iguales = InstanciaDeString.equals(Greenpeace);
System.out.println(Iguales); → verdadero
3.2.3 Resultado
14 System.out.println(Caracteres3Al8);
15
16 int NumPalabras=0, Posicion=0;
17
18 while(Posicion!=-1) {
19 Posicion = Frase.indexOf(" ",Posicion+1);
20 NumPalabras++;
21 }
22 System.out.println(NumPalabras);
23
24 }
25 }
3.2.5 Resultados
que declarar 1000 variable diferentes, insertar las notas con 1000 instrucciones
diferentes, etc.
3.3.1 Sintaxis
tipo[] Variable; // declara una matriz de variables del tipo indicado (ejemplo:
// float[] Notas;)
tipo Variable[]; // otra alternativa sintáctica para declarar la misma matriz
// que la línea anterior,
// en adelante utilizaremos únicamente la sintaxis de la primera línea
Ejemplos:
float[] TemperaturasMadrid = {3.4f, 5.6f, 17.5f, 19.2f, 21.0f, 25.6f, 35.3f, 39.5f,
25.2f, 10.0f, 5.7f, 4.6f};
String[] Nombres = {“Pinta”,”Niña”,”Santamaría”};
Una de las grandes ventajas que presentan las matrices es la posibilidad que
existe para recorrer sus elementos con una instrucción repetitiva:
for (int i=0; i<12; i++)
System.out.println(Temperaturas[i]);
3.3.3 Ejemplo 1
3.3.5 Ejemplo 2
36 }
37 }
3.3.7 Ejemplo
La matriz se ha definido de tipo String, lo que encaja muy bien con los
campos que tienen que albergar nombres, sin embargo, las notas hay que
transformarlas de String a tipo float, lo que se realiza con facilidad gracias al método
parseFloat de la clase Float (líneas 12 y 13). La operación contraria también nos
resulta necesaria; en la línea 31 se convierte de float a String utilizando el método
toString de la clase Float.
Solución
22 }
23
24 Primo = true;
25 PosiblePrimo++;
26 Indice = 0;
27
28 } while (PrimosHallados<NUM_PRIMOS );
29
30 for (int i=0; i<NUM_PRIMOS;i++) {
31 System.out.print(Primos[i] + " ");
32 if (i % 10 ==0)
33 System.out.println();
34 }
35
36 }
37 }
Del bucle anterior se puede salir por dos causas: que PosiblePrimo haya
pasado todas las comprobaciones de divisibilidad y por lo tanto es primo (Primo es
true), o que no haya pasado las comprobaciones y por lo tanto no es primo (Primo es
false). En el primer caso se actualiza la matriz Primos y el contador asociado:
PrimosHallados (líneas 20 y 21). En cualquier caso, al salir del bucle, se preparan
las variables para comprobar el siguiente valor en secuencia (líneas 24, 25 y 26).
Resultados
Este ejemplo muestra como combinar caracteres, con el fin de generar todas
las posibles claves que se pueden utilizar con un juego de caracteres permitido y un
tamaño máximo establecido. El juego de caracteres que utilizaremos son los
números y letras (mayúsculas y minúsculas), junto a unos pocos caracteres
especiales de uso común.
Solución
37
38 }
39 }
En las líneas 15, 16, 17 y 18 se inician 4 bucles, uno por cada carácter (1º,
2º, 3º, 4º) de cada clave generada, de tal forma que cada carácter va aumentando
(líneas 25, 28, 31 y 34) en cada iteración de su bucle correspondiente. Cada iteración
de un bucle exterior debe inicializar el carácter del bucle inferior (líneas 27, 30 y
33).
Resultado
3.4.3 Estadísticas
Solución
35 float[] TemperaturasGranada =
36 {5.2f, 4.6f, 12.5f, 19.3f, 16.2f, 24.5f,
37.2f, 37.0f, 29.3f, 18.2f, 10.3f, 7.5f};
37 float[] PresionFebrero =
38 {800.2f, 810.5f, 815.2f, 825.6f, 837.4f, 850.2f, 860.4f,
39 855.2f, 847.2f, 820.4f, 810.5f, 805.2f, 790.3f, 795.1f,
40 790.4f, 786.6f, 780.6f, 770.3f, 770.4f, 777.7f, 790.3f,
41 820.2f, 830.7f, 840.1f, 845.6f, 859.4f, 888.2f, 899.4f};
42
43 float[] mM = new float[2]; // Contendra el menor y
// el mayor valor
44 System.out.println("Media temperaturas de Madrid: " +
45 Media(TemperaturasMadrid) );
46 System.out.println("Variacion temperaturas de Madrid:
47 " + Variacion(TemperaturasMadrid) );
48 mM = MenorMayor(TemperaturasMadrid);
49 System.out.println("Menor y mayor temperatura de
50 Madrid: "+ mM[0] + " " + mM[1] );
51 System.out.println();
52
53 System.out.println("Media temperaturas de Granada: " +
54 Media(TemperaturasGranada) );
55 System.out.println("Variacion temperaturas de Granada:
56 " + Variacion(TemperaturasGranada) );
57 mM = MenorMayor(TemperaturasGranada);
58 System.out.println("Menor y mayor temperatura de
59 Granada: "+mM[0] + " " + mM[1] );
60 System.out.println();
61
62 System.out.println("Media presion de febrero:
"+Media(PresionFebrero));
63 System.out.println("Variacion presion de febrero: " +
64 Variacion(PresionFebrero) );
65 mM = MenorMayor(PresionFebrero);
66 System.out.println("Menor y mayor presion de febrero:
67 " + mM[0] + " " + mM[1] );
68 }
69 }
Del método Media (situado entre las líneas 3 y 8) cabe resaltar la utilización
de la propiedad length, asociada al array Matriz. Utilizando esta propiedad, que nos
indica el número de elementos de la matriz lineal, conseguimos que el método
Media sea independiente del tamaño de la matriz: obsérvese como funciona
adecuadamente con TemperaturasMadrid, de 12 elementos y con PresionFebrero,
de 28 elementos. Esta propiedad la utilizamos también en los demás métodos del
ejemplo.
Resultados
CAPÍTULO 4
PROGRAMACIÓN ORIENTADA A
OBJETOS USANDO CLASES
4.1.1 Sintaxis
MiSemaforo
4.1.6 Resultado
Los últimos dos métodos definidos son compatibles con todos los anteriores
y tendrían sentido si suponemos dos métodos adicionales que los complementen:
Dimensiones3D(double Ancho, double Alto, double Profundo)
TipoMedida(String Medida)
4.2.2 Ejemplo
33 Dimensiones(Ancho,Alto,Profundo,Medida);
34 }
35
36 public void Dimensiones(String Medida) {
37 TipoMedida(Medida);
38 }
39
40 public void Dimensiones(double Ancho, double Alto,
double Profundo) {
41 Dimensiones3D(Ancho,Alto,Profundo);
42 }
43
44 public double DimeAncho() {
45 return X;
46 }
47
48 public double DimeAlto() {
49 return Y;
50 }
51
52 public double DimeProfundo() {
53 return Z;
54 }
55
56 public String DimeMedida() {
57 return TipoMedida;
58 }
59
60 } // Fin de la clase Objeto3D
Los dos últ imos métodos sobrecargados Dimensiones (líneas 36 y 40) hacen
llamadas a los métodos más convenientes para realizar su función.
92 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
4.2.3 Resultado
4.2.4 Constructores
Los constructores son métodos que nos sirven para iniciar los objetos al
definirse las instancias de los mismos. Habitualmente, el cometido de los
constructores es asignar valores iniciales a las propiedades de la clase, es decir,
situar a la clase instanciada en un estado concreto.
9 }
10
11 public void TipoMedida(String Medida) {
12 TipoMedida = Medida;
13 }
14
15 Objeto3DConConstructor(double Ancho, double Alto,
16 double Profundo, String Medida) {
17 Dimensiones3D(Ancho,Alto,Profundo);
18 TipoMedida(Medida);
19 }
20
21 Objeto3DConConstructor(String Medida, double Ancho,
22 double Alto, double Profundo) {
23 this(Ancho,Alto,Profundo,Medida);
24 }
25
26 Objeto3DConConstructor(double Ancho, String Medida,
27 double Alto, double Profundo) {
28 this(Ancho,Alto,Profundo,Medida);
29 }
30
31 Objeto3DConConstructor(double Ancho, double Alto,
32 String Medida, double Profundo) {
33 this(Ancho,Alto,Profundo,Medida);
34 }
35
36 Objeto3DConConstructor(String Medida) {
37 TipoMedida(Medida);
38 }
39
40 Objeto3DConConstructor(double Ancho, double Alto,
double Profundo) {
41 Dimensiones3D(Ancho,Alto,Profundo);
42 }
43
44 public double DimeAncho() {
45 return X;
46 }
47
48 public double DimeAlto() {
49 return Y;
50 }
51
52 public double DimeProfundo() {
53 return Z;
54 }
55
BOBADILLA CAPÍTULO 4: PROGRAMACIÓN ORIENTADA A OBJETOS USANDO CLASES 95
Las líneas 15, 21, 26, 31, 36 y 40 definen los constructores de la clase.
Como se puede observar, se omite la palabra void en su definición; tampoco se pone
el atributo de acceso. Por lo demás, se codifican como métodos normales, salvo el
uso de la palabra reservada this: this se refiere a “esta” clase (en nuestro ejemplo
Objeto3DConConstructor). En el ejemplo indicamos que se invoque a los
constructores de la clase cuya firma coincida con la firma de las instrucciones
llamantes.
4.3 EJEMPLOS
En esta lección se presentan tres ejemplos: “figura genérica”, “agenda de
teléfono” y “ejercicio de logística”, en los que se implementan clases que engloban
las propiedades y métodos necesarios para facilitar la resolución de los problemas
planteados.
Este primer ejemplo muestra una clase Figura, en la que se puede establecer
y consultar el color y la posición del centro de cada instancia de la clase.
Código
1 import java.awt.Color;
2
3 public class Figura {
4 private Color ColorFigura;
5 private int[] Posicion = new int[2];
6
7 Figura(Color color) {
8 EstableceColor(color);
9 }
10
11 Figura(Color color, int[] Posicion) {
12 EstableceColor(color);
13 EstableceCentro(Posicion);
14 }
15
16 public void EstableceColor(Color color) {
17 ColorFigura = color;
18 }
19
20 public Color DimeColor() {
21 return ColorFigura;
22 }
23
24 public void EstableceCentro(int[] Posicion) {
25 this.Posicion[0] = Posicion[0];
26 this.Posicion[1] = Posicion[1];
27 }
28
29 public int[] DimeCentro() {
30 return Posicion;
31 }
32
33 }
98 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
Código
Código de prueba
Resultados
Los camioneros o bien llegan con un contenedor (uno solo por camión) o
bien llegan con el camión vacío con la intención de llevarse un contenedor. En
BOBADILLA CAPÍTULO 4: PROGRAMACIÓN ORIENTADA A OBJETOS USANDO CLASES 101
cualquier caso, siempre ha existido un vigilante al comienzo del camino que lleva a
los almacenes que le indicaba a cada camionero a que almacén debía dirigirse a
depositar el contenedor que traía o a recoger un contenedor, en caso de llegar sin
carga.
Código
Sólo hemos programado un constructor (en la línea 5), que nos permite
definir la capacidad (Capacidad) del almacén. En la línea 6 asignamos a la
propiedad Capacidad de la clase(this.Capacidad) el valor que nos indica el
parámetro Capacidad del constructor. En la línea 7 determinamos que el almacén,
inicialmente se encuentra vacío (tantos huecos como capacidad).
Código de prueba
4.4.1 Código
32
33 public void RellenaAlmacen() {
34 NumeroDeElementos = Capacidad;
35 }
36
37 } // clase
La clase Puerta, para sernos útil, tiene que poder actuar sobre cada uno de
los diferentes aparcamientos (para nosotros “almacenes” de vehículos). No nos
interesa tener que implementar una clase Puerta por cada aparcamiento que gestiona
la empresa.
1 class Aparcamiento {
2 public static void main(String[] args){
3 char CPuerta, COperacion;
4 Puerta PuertaRequerida = null;
5
6 Almacen Aparcamiento = new Almacen( (short) 5 );
7 Puerta Puerta1 = new Puerta(Aparcamiento);
8 Puerta Puerta2 = new Puerta(Aparcamiento);
9
10 do {
11 CPuerta = IntroduceCaracter ("Puerta de acceso:
(1, 2): ");
12 switch (CPuerta) {
13 case '1':
14 PuertaRequerida = Puerta1;
15 break;
16 case '2':
17 PuertaRequerida = Puerta2;
18 break;
19 default:
20 System.out.println ("Puerta seleccionada no
valida");
21 break;
22 }
23
24 COperacion = IntroduceCaracter ("Entrar/Salir
vehiculo (e, s): ");
25 switch (COperacion) {
26 case 'e':
27 PuertaRequerida.EntraVehiculo();
28 break;
29 case 's':
30 PuertaRequerida.SaleVehiculo();
108 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
31 break;
32 default:
33 System.out.println ("Operacion seleccionada
no valida");
34 break;
35 }
36
37 } while (true);
38
39 } // main
40
41
42 static public char IntroduceCaracter (String Mensaje) {
43 String Entrada;
44
45 System.out.print (Mensaje);
46 Entrada = Teclado.Lee_String();
47 System.out.println();
48 Entrada = Entrada.toLowerCase();
49 return Entrada.charAt(0);
50 }
51
52 }
4.4.2 Resultados
En este punto es importante resaltar el hecho de que hasta que no se crea una
primera instancia de una clase, no existirá ninguna propiedad visible de la clase.
1 class Sencilla {
2 public int PropiedadDeInstancia;
3 }
1 class PruebaSencilla {
2 public static void main (String[] args) {
3 Sencilla.PropiedadDeInstancia = 8;
4 }
5 }
1 class PruebaSencilla2 {
2 public static void main (String[] args) {
3 Sencilla Instancia1 = new Sencilla();
4 Sencilla Instancia2 = new Sencilla();
5 Instancia1.PropiedadDeInstancia = 8;
6 Instancia2.PropiedadDeInstancia = 5;
7 }
8 }
BOBADILLA CAPÍTULO 4: PROGRAMACIÓN ORIENTADA A OBJETOS USANDO CLASES 111
1 class SencillaEstatica {
2 static public int PropiedadDeClase;
3 }
1 class PruebaSencillaEstatica {
2 public static void main (String[] args) {
3 SencillaEstatica.PropiedadDeClase = 8;
4 }
5 }
1 class PruebaSencillaEstatica {
2 public static void main (String[] args) {
3 SencillaEstatica Instancia1 = new SencillaEstatica();
4 SencillaEstatica Instancia2 = new SencillaEstatica();
5 SencillaEstatica.PropiedadDeClase = 4;
6 Instancia1.PropiedadDeClase = 8;
7 Instancia2.PropiedadDeClase = 5;
8 }
9 }
1 .....................
2 LogisticaAlmacen Almacen1 = new
3 LogisticaAlmacen((byte)2);
4 LogisticaAlmacen Almacen2 = new
5 LogisticaAlmacen((byte)4);
6 LogisticaAlmacen Almacen3 = new
7 LogisticaAlmacen((byte)8);
8
9 String Accion;
10
11 do {
12 Accion = Teclado.Lee_String();
13 if (Accion.equals("m")) // meter contenedor
14 if (Almacen1.HayHueco())
15 Almacen1.MeteContenedor();
16 ............................
referenciarse a través del nombre de la clase (al igual que las propiedades estáticas).
Esta posibilidad es útil en diversas circunstancias:
• Cuando el método proporciona una utilidad general
Esta situación la hemos comprobado con los métodos de la clase
Math . Si queremos, por ejemplo, realizar una raíz cuadrada, no nos es
necesario crear ninguna instancia del método Math; directamente
escribimos Math.sqrt(Valor_double). Esto es posible porque el
método sqrt de la clase Math es estático.
• Cuando el método hace uso de propiedades estáticas u otros métodos
estáticos
Los métodos estáticos referencian propiedades y métodos estáticos.
1 class Error {
2 int Valor = 8;
3
4 public static void main(String[] args){
5 Valor = 6;
6 } // main
7
8 } // clase
1 class NoError {
2 static int Valor = 8;
3
4 public static void main(String[] args){
5 Valor = 6;
6 } // main
7
8 } // clase
La solución que se aporta en este apartado no requiere del uso de una nueva
clase “MasVotado” o similar, ni necesita un número fijo de instanciaciones para
funcionar. La solución propuesta contiene las propiedades y métodos de acceso a la
persona más votada dentro de la propia clase Votacion, en la que se vota a cada
persona.
1 class Votacion {
2 // Persona a la que se vota en esta instancia y el numero
3 // de votos que lleva
4 private String Persona = null;
5 private int Votos = 0;
6
7 // Persona mas votada de todas las instancias y el numero
BOBADILLA CAPÍTULO 4: PROGRAMACIÓN ORIENTADA A OBJETOS USANDO CLASES 117
1 class PruebaVotacion {
2 public static void main (String[] args) {
3
4 System.out.println (Votacion.NombreDelMasVotado() +
5 ": "+ Votacion.VotosDelMasVotado());
6
7 // Tenemos tres candidatos en esta votacion
8 Votacion Juan = new Votacion ("Juan Peire");
9 Votacion Ana = new Votacion ("Ana Garcia");
10 Votacion Adela = new Votacion ("Adela Sancho");
11
12 // empieza la votacion
13 Juan.Voto(); Ana.Voto(); Ana.Voto(); Ana.Voto();
Adela.Voto();
14 System.out.println (Votacion.NombreDelMasVotado() +
15 ": "+ Votacion.VotosDelMasVotado());
16
17 Juan.Voto(); Juan.Voto(); Juan.Voto(); Adela.Voto();
18 System.out.println (Votacion.NombreDelMasVotado() +
19 ": "+ Votacion.VotosDelMasVotado());
20
21 Adela.Voto(); Adela.Voto(); Ana.Voto(); Ana.Voto();
22 System.out.println (Votacion.NombreDelMasVotado() +
23 ": "+ Votacion.VotosDelMasVotado());
24
25 System.out.println (Juan.NombrePersona() + ": " +
Juan.Votos() );
26 System.out.println (Ana.NombrePersona() + ": " +
Ana.Votos() );
27 System.out.println (Adela.NombrePersona() + ": " +
Adela.Votos() );
28
29 }
30 }
En la línea 13 se contabilizan los siguie ntes votos: uno para Juan, tres para
Ana y uno para Adela. En la línea 14 se comprueba que llevamos un seguimiento
correcto de la persona más votada (Ana García, con 3 votos). Seguimos
referenciando a los métodos estáticos a través del nombre de la clase (no de una
instancia), que es la forma de proceder más natural y elegante.
4.5.7 Resultados
Hasta ahora no hemos hecho un uso explícito de los paquetes en las clases
que hemos creado. Cuando no se especifica el nombre del paquete al que pertenece
una clase, esa clase pasa a pertenecer al “paquete por defecto”.
Definir el paquete al que pertenece una clase es muy sencillo: basta con
incluir la sentencia package Nombre_Paquete; como primera sentencia de la clase
(obligatoriamente la primera). Ejemplo:
package Terminal;
public class Telefono {
……….
}
package Terminal;
public class Ordenador {
……….
}
package Terminal;
public class WebTV {
……….
}
Las clases definidas como public son accesibles desde fuera del paquete, las
que no presentan este atributo de acceso sólo son accesibles desde dentro del
paquete (sirven para dar soporte a las clases publicas del paquete).
import Terminal.*;
class TerminalOficinaBancaria {
// podemos utilizar las referencias deseadas a las 3 clases del paquete Terminal
}
import Terminal.Telefono;
import Terminal.Ordenador;
import Terminal.WebTV;
class TerminalOficinaBancaria {
// podemos utilizar las referencias deseadas a las 3 clases del paquete Terminal
Una vez que hemos indicado, con la sentencia import, que vamos a hacer
uso de una serie de clases, podemos referenciar sus propiedades y métodos de
manera directa. Una alternativa a esta posibilidad es no utilizar la sentencia import y
referenciar los objetos con caminos absolutos:
Terminal.Telefono MiTelefono = new Terminal.Telefono(....);
Si bien la manera con la que hemos actuado es, sin duda, la más habitual,
adecuada y aconsejada, existen diferentes posibilidades que tienen que ver con la
existencia de los paquetes, motivo por el cual hemos retrasado a este momento la
explicación detallada de los atributos de acceso.
paquete sólo está permitido si el miembro es público. Los demás atributos de acceso
tienen un mayor sentido cuando utilizamos el mecanismo de herencia, que se
explicará un poco más adelante.
Ejemplo:
package ConversionDeMedidas;
public class ConversionDeDistancias {
final public double LibrasAKilos = ...;
.................
}
package VentaDeProductos;
import ConversionDeMedidas.ConversionDeDistancias;
class VentaDeNaranjas {
........................
double Kilos = Libras * LibrasAKilos;
.......................
}
Cualquiera de los ejemplos que hemos realizado en las últimas lecciones nos
sirve para ilustrar el uso de propiedades privadas situadas en clases pertenecientes a
un mismo paquete. Puesto que no incluíamos ninguna sentencia package, todas
nuestras clases pertenecían al “paquete por defecto”.
26 }
27
28 public float DimePrecioAgua() {
29 return PrecioAgua;
30 }
31
32 public void MostrarEstadoMaquina() {
33 System.out.print("CocaColas: "+
34 DepositoCocaCola.DimeNumeroDeElementos()+ " ");
35 System.out.print("Naranjas: "+
36 DepositoNaranja.DimeNumeroDeElementos() + " ");
37 System.out.println("Agua: "+
38 DepositoAgua.DimeNumeroDeElementos() + " ");
39
40 System.out.print("1 Euro: "+
41 Deposito1Euro.DimeNumeroDeElementos() + " ");
42 System.out.println("0.1 Euro: "+
43 Deposito01Euro.DimeNumeroDeElementos() + " ");
44 System.out.println();
45 }
46
47 }
Los 5 depósitos han sido declarados con el atributo de acceso public, de esta
manera pueden ser referenciados directamente por las clases que instancien a
MaquinaModeloSencillo . Una alternativa menos directa, pero más adaptada a la
programación orientada a objetos sería declararlos como privados e incorporar los
métodos necesarios para obtener sus referencias, por ejemplo:
public MaquinaModeloSencillo DameAlmacenAgua();
public MaquinaModeloSencillo DameAlmacenNaranja();
.......................
o bien
public MaquinaModeloSencillo DameAlmacen(String TipoAlmacen);
BOBADILLA CAPÍTULO 4: PROGRAMACIÓN ORIENTADA A OBJETOS USANDO CLASES 129
Para realizar el control de las monedas introducidas y del cambio que hay
que devolver, se ha implementado la clase MaquinaAutomataEuros: el concepto más
importante que hay que entender en esta clase es el significado de su primer método
IntroducciónMonedas, que admite como parámetros una máquina de tipo
MaquinaModeloSencillo y un precio. Este método, además de realizar todo el
control monetario, devuelve true si el pago se ha realizado con éxito y false si no ha
sido así.
22 Maquina.Deposito1Euro.MeteElemento();
23 Acumulado = Acumulado + 1f;
24 } else
25 System.out.println("Temporalmente esta
26 maquina no cepta monedas de un euro");
27 break;
28
29 case 'd':
30 if (Maquina.Deposito01Euro.HayHueco()) {
31 Maquina.Deposito01Euro.MeteElemento();
32 Acumulado = Acumulado + 0.1f;
33 } else
34 System.out.println("Temporalmente esta
35 maquina no acepta monedas de 0.1 euros");
36 break;
37
38 case 'a':
39 System.out.println("Operación anulada");
40 Anulado = true;
41 break;
42 }
43
44 Maquina.MostrarEstadoMaquina();
45
46 } while (Acumulado<Precio || Anulado);
47
48 if (Anulado)
49 Devolver(Maquina,Acumulado);
50 else
51 if (CambioDisponible(Maquina,Acumulado-Precio)) {
52 Devolver (Maquina,Acumulado-Precio);
53 } else {
54 System.out.println("La maquina no dispone del
cambio necesario");
55 Devolver(Maquina,Acumulado);
56 Anulado = true;
57 }
58 return (!Anulado);
59 }
60
61
62
63 // ******************************************************
64 // * Indica si es posible devolver 'Cantidad' euros en
// * 'Maquina'
65 // ******************************************************
66 private static boolean CambioDisponible
67 (MaquinaModeloSencillo Maquina, float Cantidad) {
132 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
68
69 int Monedas1,Monedas01;
70
71 Cantidad = Cantidad + 0.01f; //Evita problemas de
//falta de precision
72 Monedas1 = (int) Math.floor((double) Cantidad);
73 Cantidad = Cantidad - (float) Monedas1;
74 Monedas01 = (int) Math.floor((double) Cantidad*10f);
75 return {
(Maquina.Deposito1Euro.DimeNumeroDeElementos()>=Monedas1)&&
(Maquina.Deposito01Euro.DimeNumeroDeElementos()>=Monedas01));
76 }
77
78
79
80 // **************************************************
81 // * Devuelve la cantidad de dinero indicada,
82 // * actualizando los almacenes de monedas
83 // **************************************************
84 private static void Devolver (MaquinaModeloSencillo
85 Maquina, float Cantidad) {
86
87 int Monedas1,Monedas01;
88 Cantidad = Cantidad + 0.01f; //Evita problemas de
//falta de precision
89 Monedas1 = (int) Math.floor((double)Cantidad);
90 Cantidad = Cantidad - (float) Monedas1;
91 Monedas01 = (int) Math.floor((double)Cantidad*10f);
92
93 for (int i=1;i<=Monedas1;i++){
94 Maquina.Deposito1Euro.SacaElemento();
95 // Sacar 1 moneda de un euro
96 }
97
98 for (int i=1;i<=Monedas01;i++){
99 Maquina.Deposito01Euro.SacaElemento();
100 // Sacar 1 moneda de 0.1 euro
101 }
102 System.out.println("Recoja el importe: "+Monedas1+"
103 monedas de un euro y "+Monedas01+
104 " monedas de 0.1 euros");
105
106 }
107
108 } // clase
BOBADILLA CAPÍTULO 4: PROGRAMACIÓN ORIENTADA A OBJETOS USANDO CLASES 133
naranja");
43 // Sacar fisicamente la Naranja
44 }
45 }
46 else
47 System.out.println("Producto agotado");
48 break;
49
50 case 'a':
51 System.out.println("Ha seleccionado Agua");
52 if (MiMaquina.DepositoAgua.HayElemento()) {
53 if MaquinaAutomataEuros.IntroduccionMonedas
54 (MiMaquina, MiMaquina.DimePrecioAgua())) {
55 MiMaquina.DepositoAgua.SacaElemento();
56 System.out.println("No olvide coger su
agua");
57 // Sacar fisicamente el agua
58 }
59 }
60 else
61 System.out.println("Producto agotado");
62 break;
63
64 default:
65 System.out.println("Error de seleccion,
intentelo de nuevo");
66 break;
67 }
68 MiMaquina.MostrarEstadoMaquina();
69
70 } while (!Accion.equals("s"));
71 }
72 }
PROGRAMACIÓN ORIENTADA A
OBJETOS USANDO HERENCIA
5.1 HERENCIA
5.1.1 Funcionamiento básico
1 class Publicacion {
2 public int NumeroDePaginas;
3 public float Precio;
4 }
1 class PruebaLibro {
2 public static void main(String[] args) {
3 Libro MiLibro = new Libro();
4 MiLibro.NombreAutor = "Frederick Forsyth";
5 MiLibro.Titulo = "El manifiesto negro";
6 MiLibro.Editorial = "Circulo de lectores";
7 MiLibro.TipoPortada = "Dura";
8 MiLibro.NumeroDePaginas = 575;
9 }
10 }
Publicacion
Libro Periodico
1 class Publicacion2 {
2 private int NumeroDePaginas;
3 private float Precio;
4
5 public int DimeNumeroDePaginas(){
6 return NumeroDePaginas;
7 }
8
9 public void PonNumeroDePaginas(int NumeroDePaginas){
10 this.NumeroDePaginas = NumeroDePaginas;
11 }
12
13 public float DimePrecio(){
14 return Precio;
15 }
16
17 public void PonPrecio(float Precio){
18 this.Precio = Precio;
19 }
20 }
1 class PruebaPeriodico2 {
2 public static void main(String[] args) {
3 Periodico2 MiPeriodico = new Periodico2();
4 MiPeriodico.PonNumeroDePaginas(65);
5 MiPeriodico.PonPrecio(0.9f);
6 MiPeriodico.PonFecha("22/02/2003");
7 System.out.println(MiPeriodico.DimeNumeroDePaginas());
8 }
9 }
Al igual que ocurre con las propiedades, nos podemos referir al método de la
superclase utilizando la palabra reservada super.
1 class Publicacion3 {
2 private int NumeroDePaginas;
3 private float Precio;
4
5 Publicacion3() {
6 NumeroDePaginas = 0;
7 Precio = 0f;
8 }
9
10 Publicacion3(int NumeroDePaginas) {
11 PonNumeroDePaginas(NumeroDePaginas);
12 }
13
14 Publicacion3(float Precio) {
15 PonPrecio(Precio);
16 }
17
18 Publicacion3(int NumeroDePaginas, float Precio) {
19 this(NumeroDePaginas);
20 PonPrecio(Precio);
21 }
22
23 Publicacion3(float Precio, int NumeroDePaginas) {
24 this(NumeroDePaginas,Precio);
25 }
26
27 public int DimeNumeroDePaginas(){
28 return NumeroDePaginas;
29 }
30
31 public void PonNumeroDePaginas(int NumeroDePaginas){
32 this.NumeroDePaginas = NumeroDePaginas;
33 }
34
35 public float DimePrecio(){
36 return Precio;
37 }
38
39 public void PonPrecio(float Precio){
40 this.Precio = Precio;
41 }
42 }
39 return Fecha;
40 }
41
42 public void PonFecha(String Fecha) {
43 this.Fecha = Fecha;
44 }
45 }
1 class PruebaPeriodico3 {
2 public static void main(String[] args) {
3 Periodico3 PeriodicoA = new Periodico3();
4 Periodico3 PeriodicoB = new Periodico3("El Mundo",
"12/08/2003");
5 Periodico3 PeriodicoC = new Periodico3(64, 0.9f);
6 Periodico3 PeriodicoD = new
Periodico3("El Pais","7/6/2003",45,0.9f);
7 Imprimir(PeriodicoA);
8 Imprimir(PeriodicoB);
9 Imprimir(PeriodicoC);
10 Imprimir(PeriodicoD);
11 }
12
13 private static void Imprimir(Periodico3 Periodico) {
14 String Nombre, Fecha;
15 int NumeroDePaginas;
16 float Precio;
17 Nombre = Periodico.DimeNombre();
18 Fecha = Periodico.DimeFecha();
19 NumeroDePaginas = Periodico.DimeNumeroDePaginas();
20 Precio = Periodico.DimePrecio();
21 System.out.println(Nombre+", "+Fecha+",
"+NumeroDePaginas+", "+Precio);
22 }
23 }
BOBADILLA CAPÍTULO 5: PROGRAMACIÓN ORIENTADA A OBJETOS USANDO HERENCIA 145
5.2 EJEMPLOS
En este apartado se muestran dos ejemplos sencillos de herencia. Los
ejemplos son muy parecidos entre sí, con la intención de que el lector pueda realizar
el segundo tomando como referencia el primero de ellos.
Figura
Circulo Rectángulo
1 import java.awt.Color;
2
3 public class Figura {
4 private Color ColorFigura;
5 private int[] Posicion = new int[2];
6
7 Figura() {
8 EstableceColor(Color.black);
9 Posicion[0] = 0;
10 Posicion[1] = 0;
11 }
12
BOBADILLA CAPÍTULO 5: PROGRAMACIÓN ORIENTADA A OBJETOS USANDO HERENCIA 147
13 Figura(Color color) {
14 EstableceColor(color);
15 }
16
17 Figura(Color color, int[] Posicion) {
18 EstableceColor(color);
19 EstableceCentro(Posicion);
20 }
21
22 public void EstableceColor(Color color) {
23 ColorFigura = color;
24 }
25
26 public Color DimeColor() {
27 return ColorFigura;
28 }
29
30 public void EstableceCentro(int[] Posicion) {
31 this.Posicion[0] = Posicion[0];
32 this.Posicion[1] = Posicion[1];
33 }
34
35 public int[] DimeCentro() {
36 return Posicion;
37 }
38
39 }
Una vez creada la clase Figura, podemos definir las diferentes subclases que
especializan y amplían a esta superclase, representando diferentes figuras
geométricas. A modo de ejemplo proporcionamos la clase derivada Circulo :
1 import java.awt.Color;
2
3 public class Circulo extends Figura {
4 private double Radio;
5
6 Circulo(double Radio) {
7 EstableceRadio(Radio);
148 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
8 }
9
10 Circulo(double Radio,Color color) {
11 super(color);
12 EstableceRadio(Radio);
13 }
14
15 Circulo(double Radio, Color color, int[] Posicion) {
16 super(color, Posicion);
17 EstableceRadio(Radio);
18 }
19
20 public void EstableceRadio(double Radio) {
21 this.Radio = Radio;
22 }
23
24 public double DimeRadio() {
25 return Radio;
26 }
27 }
Circulo es una clase derivada de Figura (línea 3) que incorpora una nueva
propiedad Radio (línea 4) a las heredadas de su superclase (ColorFigura y
Posicion). Los métodos públicos EstableceRadio y DimeRadio permiten la
actualización y acceso a la propiedad privada Radio .
1 import java.awt.Color;
2
3 public class Rectangulo extends Figura {
4 private double[] Lados = new double[2];
5
6 Rectangulo(double[] Lados) {
7 EstableceLados(Lados);
8 }
9
BOBADILLA CAPÍTULO 5: PROGRAMACIÓN ORIENTADA A OBJETOS USANDO HERENCIA 149
1 import java.awt.Color;
2
3 public class PruebaFiguras {
4 public static void main(String[] args) {
5 int[] Posicion = {10,20};
6 double[] Lados = {50d,100d};
7 Circulo MiCirculo = new Circulo(3d,Color.red,Posicion);
8 Rectangulo MiRectangulo = new
Rectangulo(Lados,Color.blue,Posicion);
9
10 System.out.println(MiCirculo.DimeRadio());
11 int[] Centro = MiCirculo.DimeCentro();
12 System.out.println(Centro[0]);
13 System.out.println(Centro[1]);
14
150 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
15 System.out.println(MiRectangulo.DimeColor());
16
17 }
18 }
El resultado es:
5.2.2 Vehículos
Vehiculo
Camion Motocicleta
1 import java.awt.Color;
2
3 public class Vehiculo {
4 private Color ColorVehiculo;
5 private byte NumRuedas;
6 private short Cilindrada;
7 private short Potencia;
8
9 Vehiculo(Color color) {
10 EstableceColor(color);
11 }
12
13 Vehiculo (byte NumRuedas) {
14 this.NumRuedas = NumRuedas;
15 }
16
17 Vehiculo (short Cilindrada) {
18 this.Cilindrada = Cilindrada;
19 }
20
21 Vehiculo(Color color, byte NumRuedas) {
22 this(color);
23 this.NumRuedas = NumRuedas;
24 }
25
26 Vehiculo(Color color, byte NumRuedas, short Cilindrada) {
27 this(color,NumRuedas);
28 this.Cilindrada = Cilindrada;
29 }
30
31 Vehiculo(Color color, byte NumRuedas, short Cilindrada,
32 short Potencia) {
33 this(color,NumRuedas,Cilindrada);
34 this.Potencia = Potencia;
152 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
35 }
36
37 public void EstableceColor(Color color) {
38 ColorVehiculo = color;
39 }
40
41 public Color DimeColor() {
42 return ColorVehiculo;
43 }
44
45 public byte DimeNumRuedas() {
46 return NumRuedas;
47 }
48
49 public short DimeCilindrada() {
50 return Cilindrada;
51 }
52
53 public short DimePotencia() {
54 return Potencia;
55 }
56
57 }
1 import java.awt.Color;
2
3 public class Camion extends Vehiculo {
4
5 private byte NumeroDeEjes;
6
7 Camion(byte NumeroDeRuedas) {
8 super(NumeroDeRuedas);
9 }
10
11 Camion(Color color, byte NumeroDeRuedas) {
12 super(color,NumeroDeRuedas);
13 }
14
15 Camion(Color color, byte NumeroDeRuedas,
16 short Cilindrada) {
17 super(color,NumeroDeRuedas,Cilindrada);
18 }
19
20 Camion(Color color, byte NumeroDeRuedas,
21 short Cilindrada, short Potencia) {
22 super(color,NumeroDeRuedas,Cilindrada,Potencia);
BOBADILLA CAPÍTULO 5: PROGRAMACIÓN ORIENTADA A OBJETOS USANDO HERENCIA 153
23 }
24
25 Camion(Color color, byte NumeroDeRuedas,
26 byte NumeroDeEjes, short Cilindrada,
27 short Potencia) {
28 super(color,NumeroDeRuedas,Cilindrada,Potencia);
29 EstableceNumeroDeEjes(NumeroDeEjes);
30 }
31
32 public byte DimeNumeroDeEjes() {
33 return NumeroDeEjes;
34 }
35
36 public void EstableceNumeroDeEjes(byte NumeroDeEjes) {
37 this.NumeroDeEjes = NumeroDeEjes;
38 }
39
40 }
1 import java.awt.Color;
2
3 public class Motocicleta extends Vehiculo {
4
5 private byte NumeroDePlazas;
6
7 Motocicleta() {
8 super((byte)2);
9 }
10
11 Motocicleta(byte NumeroDePlazas) {
12 super((byte)2);
13 EstableceNumeroDePlazas(NumeroDePlazas);
14 }
15
16 Motocicleta(Color color) {
17 super(color,(byte)2);
18 }
19
20 Motocicleta(Color color, short Cilindrada) {
21 super(color,(byte)2,Cilindrada);
22 }
23
24 Motocicleta(Color color, short Cilindrada,
25 short Potencia) {
26 super(color,(byte)2,Cilindrada,Potencia);
27 }
154 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
28
29 public byte DimeNumeroDePlazas() {
30 return NumeroDePlazas;
31 }
32
33 public void EstableceNumeroDePlazas(byte NumeroDePlazas) {
34 this.NumeroDePlazas = NumeroDePlazas;
35 }
36
37 }
1 import java.awt.Color;
2
3 public class PruebaVehiculos {
4 public static void main(String[] args) {
5 Motocicleta MotoBarata = new
6 Motocicleta(Color.red,(short)125,(short)25);
7 Motocicleta MotoBarata2 = new
8 Motocicleta(Color.red,(short)125,(short)25);
9 Motocicleta MotoCara = new
10 Motocicleta(Color.yellow,(short)1000,(short)90);
11
12 Camion CamionNormal = new Camion(Color.red,(byte)4,
13 (byte)2,(short)4000,(short)300);
14 Camion CamionEnorme = new Camion(Color.red,(byte)24,
15 (byte)6,(short)15000,(short)800);
16
17 MotoBarata.EstableceNumeroDePlazas((byte)1);
18 System.out.println(MotoBarata.DimeNumeroDePlazas());
19 System.out.println(MotoBarata2.DimeCilindrada());
20 System.out.println(CamionEnorme.DimeNumeroDeEjes());
21
22 }
23 }
Resultado:
BOBADILLA CAPÍTULO 5: PROGRAMACIÓN ORIENTADA A OBJETOS USANDO HERENCIA 155
5.3 POLIMORFISMO
5.3.1 Conceptos
5.3.2 Ejemplo
1 import java.awt.Color;
2
3 public class PolimorfismoFigura {
4
5 // Los mismos miembros que en la clase Figura,
6 // modificando el nombre de los constructores
7
8 public double Perimetro() {
9 return 0d;
10 }
11
12 }
158 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
1 import java.awt.Color;
2
3 public class PolimorfismoCirculo extends PolimorfismoFigura
{
4
5 // Los mismos miembros que en la clase Circulo,
6 // modificando el nombre de los constructores
7
8 public double Perimetro() {
9 return 2.0d*Math.PI*Radio;
10 }
11
12 }
1 import java.awt.Color;
2
3 public class PolimorfismoRectangulo extends
PolimorfismoFigura {
4
5 // Los mismos miembros que en la clase Rectangulo,
6 // modificando el nombre de los constructores
7
8 public double Perimetro() {
9 return 2d*Lados[0] + 2d*Lados[1];
10 }
11
12 }
1 import java.awt.Color;
2
3 public class PolimorfismoPruebaFiguras {
4 public static void main(String[] args) {
5 int[] Posicion = {10,20};
6 double[] Lados = {50d,100d};
7 PolimorfismoFigura MiCirculo = new
8 PolimorfismoCirculo(3d,Color.red,Posicion);
9 PolimorfismoFigura MiRectangulo = new
10 PolimorfismoRectangulo(Lados,Color.blue,Posicion);
11
12 System.out.println(MiCirculo.Perimetro());
13 System.out.println(MiRectangulo.Perimetro());
14
15 PolimorfismoCirculo InstanciaCirculo =
(PolimorfismoCirculo) MiCirculo;
16 System.out.println(InstanciaCirculo.DimeRadio());
17 System.out.println(((PolimorfismoCirculo)MiCirculo).
18 DimeRadio());
19 }
20 }
160 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
ClaseAbstracta VariableClase;
VariableClase = new ClaseAbstracta();
1 import java.awt.Color;
2
3 abstract public class AbstractoVehiculo {
4
5 // Los mismos constructores y metodos que en la clase
// Vehiculo
6 // Tambien cambiamos el nombre de los constructores
7
8 abstract public float Impuesto();
9
10 }
1 import java.awt.Color;
2
3 public class ACamion extends AbstractoVehiculo {
4
5 // Los mismos constructores y metodos que en la clase
// Camion
6 // Tambien cambiamos el nombre de los constructores
7
8 public float Impuesto(){
9 return (super.DimeCilindrada()/30 +
super.DimePotencia()*20 +
10 super.DimeNumRuedas()*20 +
11 DimeNumeroDeEjes()*50);
12 }
13
14 }
BOBADILLA CAPÍTULO 5: PROGRAMACIÓN ORIENTADA A OBJETOS USANDO HERENCIA 163
1 import java.awt.Color;
2
3 public class AMotocicleta extends AbstractoVehiculo {
4
5 // Los mismos constructores y metodos que en la clase
// Motocicleta
6 // Tambien cambiamos el nombre de los constructores
7
8 public float Impuesto(){
9 return (super.DimeCilindrada()/30 +
super.DimePotencia()*30);
10 }
11
12 }
1 import java.awt.Color;
2
3 public class APruebaVehiculos {
4 public static void main(String[] args) {
5 AbstractoVehiculo MotoBarata =
6 new AMotocicleta(Color.red,(short)125,(short)25);
7 AMotocicleta MotoBarata2 =
8 new AMotocicleta(Color.red,(short)125,(short)25);
9 AbstractoVehiculo MotoCara = new
AMotocicleta(Color.yellow,(short)1000,(short)90);
10
11 AbstractoVehiculo CamionNormal = new
12 ACamion(Color.red,(byte)4,(byte)2,
13 (short)4000,(short)300);
14 AbstractoVehiculo CamionEnorme = new
164 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
15 ACamion(Color.red,(byte)24,(byte)6,
16 (short)15000,(short)800);
17
18 AMotocicleta InstanciaMotoBarata =
19 (AMotocicleta) MotoBarata;
20 InstanciaMotoBarata.EstableceNumeroDePlazas((byte)1);
21 System.out.println(InstanciaMotoBarata.
22 DimeNumeroDePlazas());
23 MotoBarata2.EstableceNumeroDePlazas((byte)1);
24 System.out.println(MotoBarata2.DimeNumeroDePlazas());
25 System.out.println(((ACamion)CamionEnorme).
26 DimeNumeroDeEjes());
27
28 System.out.println(MotoBarata.Impuesto());
29 System.out.println(MotoCara.Impuesto());
30 System.out.println(CamionNormal.Impuesto());
31 System.out.println(CamionEnorme.Impuesto());
32 System.out.println(InstanciaMotoBarata.Impuesto());
33 }
34 }
5.4.3 Interfaces
5.4.4 Ejercicio
EXCEPCIONES
6.1.1 Introducción
....................
Numerador = .............
Denominador = ............
Resultado = Numerador / Denominador;
Si existe excepción
....................
Las excepciones son objetos (clases) que se crean cuando se produce una
situación extraordinaria en la ejecución del programa. Estos objetos almacenan
información acerca del tipo de situación anormal que se ha producido y el lugar
donde ha ocurrido. Los objetos excepción se pasan automáticamente al bloque de
tratamiento de excepciones (el inferior de nuestro gráfico) para que puedan ser
referenciados.
Throwable
Exception Error
AWTError
LinkageError
IOException
ThreadDeat
SQLException
VirtualMachineError
AWTExceptio
RuntimeException
....................
Numerador = .............
Denominador = ............
Resultado = Numerador / Denominador;
Si existe excepción
....................
try {
// instrucciones susceptibles de causar cierto tipo de excepciones
}
La clase Excepcion1 implementa un bucle sin fin (líneas 3 y 18) que recoge
un valor entero suministrado por el usuario (línea 7) y lo utiliza como denominador
en una división (línea 8). Todo ello dentro de un bloque try (líneas 5 y 10).
try {
// instrucciones susceptibles de causar cierto tipo de excepciones
}
catch (TipoDeExcepcion1 Identificador) {
// instrucciones que se deben ejecutar si ocurre la excepcion de tipo
TipoDeExcepcion1
}
catch (TipoDeExcepcion2 Identificador) {
// instrucciones que se deben ejecutar si ocurre la excepcion de tipo
TipoDeExcepcion2
}
................
catch (TipoDeExcepcionN Identificador) {
// instrucciones que se deben ejecutar si ocurre la excepcion de tipo
TipoDeExcepcionN
}
Cuando “se levanta” (ocurre) una excepción en las instrucciones del bloque
try, se recorren en orden los bloques catch hasta que se encuentra uno con el mismo
tipo o un tipo que es superclase de la excepción que ha llegado. Se ejecutan
únicamente las instrucciones del bloque catch que cumple los requisitos (si es que
alguno los cumple).
try {
// instrucciones susceptibles de causar cierto tipo de excepciones
}
catch (NullPointerException e) {
// instrucciones que se deben ejecutar si ocurre la excepcion de tipo
NullPointerException
}
catch (RuntimeException e) {
// instrucciones que se deben ejecutar si ocurre la excepcion de tipo
RunTimeException
}
catch (Exception e) {
// instrucciones que se deben ejecutar si ocurre la excepcion de tipo Exception
}
15
16 catch (ArithmeticException e) {
17 System.out.println("Division por cero");
18 }
19
20 catch(IndexOutOfBoundsException e) {
21 System.out.println("Indice fuera del array");
22 }
23
24 System.out.println("Hola");
25
26 } while (Posicion!=10);
27 }
28 }
Como se puede comprobar, las instrucciones del bloque try pueden generar,
al menos, dos excepciones: ArithmeticException e IndexOutOfBoundsException. Si
introducimos un índice (Posición) mayor que 4 (el vector abarca de 0 a 4) nos
encontramos con una excepción del segundo tipo, mientras que si introducimos
como denominador (valor) un cero, nos encontramos con una excepción aritmética.
Como hemos visto, una vez que llega una excepción dentro de un bloque try,
las instrucciones siguientes (en el bloque) a la que causa la excepción no se ejecutan.
Esto puede dar lugar a que dejemos el sistema en un estado no deseado (ficheros
abiertos, comunicaciones sin terminar, recursos bloqueados, etc.). Para evitar este
tipo de situaciones, Java proporciona la posibilidad de incluir un bloque (finally )
cuyas instrucciones siempre se ejecutan después de las del catch seleccionado.
La sintaxis es:
try {
.............
}
finally {
// instrucciones que siempre se ejecutan
}
try {
// codigo
Origen.CopiaFichero(Destino);
// codigo
}
catch (IOException e) {
System.out.println (“Error de lectura ¿Desea intentarlo de Nuevo?”);
..........
}
Método Descripción
getMessage() Devuelve (como String) el mensaje de error almacenado en este
objeto. Este mensaje se compone del nombre de la excepción más
una breve referencia
printStackTrace() Imprime por el dispositivo de salida de errores (normalmente la
consola) el mensaje y la pila de ejecución almacenados en el objeto
Throwable. Este mismo método está sobrecargado para poder sacar
el resultado por diferentes salidas: printStackTrace(PrintStream s) y
printStackTrace(PrintWriter s)
toString() Devuelve (como String) una descripción corta del objeto
16 catch (ArithmeticException e) {
17 System.out.println("Division por cero");
18 e.printStackTrace();
19 }
20
21 catch(IndexOutOfBoundsException e) {
22 System.out.println("Indice fuera del array");
23 e.printStackTrace();
24 }
6.2.1 Introducción
Nuestro tercer caso nos presenta la situación de que un mismo pase de pistas
ha podido ser duplicado (intencionadamente o por error), puesto que resulta
físicamente imposible hacer uso de un remonte en un instante y volver a utilizarlo en
otro remonte lejano medio minuto después. Probablemente esta situación se presenta
muy rara vez y resultaría muy adecuado tratarla como excepción propia.
A continuación se presenta una clase (ExPropia ) muy simple que define una
excepción propia:
6
7 ExPropia (String s) {
8 super(s);
9 }
10
11 }
7 Instancia.Metodo();
8 }
9 catch(ExPropia e) {
10 System.out.println(e);
11 }
12 while(true);
13 }
14 }
6.2.4 Ejemplo
23 }
24 }
25 while(true);
26 }
27 }
7.1.1 Introducción
Hasta ahora, todos los ejemplos que se han desarrollado se han ejecutado en
modo consola, es decir, las entradas de datos y la visualización de resultados se
realiza a través de una ventana de MS-DOS. Las aplicaciones normalmente
requieren de un interfaz de usuario más sofisticado, basado en ventanas gráficas y
distintos componentes (botones, listas, cajas de texto, etc.) en el interior de estas
ventanas.
Java proporciona una serie de paquetes estándar que nos facilitan la labor de
crear los Interfaces Gráficos de Usuario (GUI) que necesitemos. Estos paquetes se
encuentran englobados dentro de Java Foundation Classes (JFC), que proporciona:
• Soporte de componentes de entrada/salida a través de AWT (Abstract Window
Toolkit) y Swing
• Imágenes 2D
• Servicio de impresión
• Soporte para funciones Drag-and-Drop (arrastrar y pegar)
• Funciones de accesibilidad, etc.
De los paquetes anteriores, los más utilizados, con diferencia, son AWT y
Swing. AWT fue el primero en aparecer y proporciona los componentes básicos de
entrada/salida; Swing recoge la mayor parte de la funcionalidad de AWT, aportando
clases más complejas y especializadas que las ya existentes, así como otras de nueva
creación.
194 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
Object java.lang
Component
Container
java.awt
Window
Frame
JFrame javax.swing
La clase Object es la raíz de toda la jerarquía de clases, por lo que todos los
objetos tienen a Object como superclase. La clase abstracta Component proporciona
una representación gráfica susceptible de ser representada en un dispositivo de
salida; como se puede observar es una clase muy genérica que no utilizaremos
directamente, sino a través de sus clases derivadas.
Nosotros haremos uso de las clases más útiles que nos ofrece AWT,
empezando por la definición de ventanas mediante el objeto Frame.
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 7: INTERFAZ GRÁFICO DE USUARIO 195
1 import java.awt.Frame;
2
3 public class Marco1 {
4
5 public static void main(String[] args) {
6 Frame MiMarco = new Frame();
7 MiMarco.setSize(400,200);
8 MiMarco.setTitle("Mi primera ventana");
9 MiMarco.setVisible(true);
10 }
11 }
1 import java.awt.Frame;
2
3 public class Marco2 extends Frame {
4
5 Marco2(String Titulo) {
196 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
6 this.setTitle(Titulo);
7 this.setVisible(true);
8 }
9
10 Marco2(String Titulo, int Ancho, int Alto) {
11 this(Titulo);
12 this.setSize(Ancho, Alto);
13 }
14
15 Marco2() {
16 this("Mi primera ventana",400,200);
17 }
18
19 }
Los interfaces gráficos de usuario (GUI) no tienen por qué restringirse al uso
de una única ventana para entrada de datos, mostrar información, etc. Siguiendo el
mecanismo explicado en los apartados anteriores podemos crear y hacer uso de un
número ilimitado de ventanas.
Cuando se crean varias ventanas a menudo resulta útil situar cada una de
ellas en diferentes posiciones del dispositivo de salida, de forma que adopten una
configuración práctica y estética, evitándose que se oculten entre sí, etc.
1 import java.awt.Frame;
2 import java.awt.Point;
3
4 public class Marco3 {
5
6 public static void main(String[] args) {
7 Frame MiMarco = new Frame();
8 MiMarco.setSize(400,200);
9 MiMarco.setTitle("Mi primera ventana");
10 MiMarco.setLocation(new Point(100,220));
11 MiMarco.setVisible(true);
12 }
13 }
1 import java.awt.Frame;
2 import java.awt.Point;
3
4 public class Marco4 extends Frame {
5
6 Marco4(String Titulo) {
7 this.setTitle(Titulo);
8 this.setVisible(true);
9 }
10
11 Marco4(String Titulo, int Ancho, int Alto) {
12 this(Titulo);
13 this.setSize(Ancho, Alto);
14 }
15
16 Marco4(String Titulo, int Ancho, int Alto,
17 int PosX, int PosY) {
18 this(Titulo,Ancho, Alto);
19 this.setLocation(new Point(PosX,PosY));
20 }
21
22 Marco4() {
23 this("Mi primera ventana",400,200,100,100);
24 }
25
26 }
7.2.1 Introducción
Component
Button Container
java.awt
Panel Window
Frame
200 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
1 import java.awt.Frame;
2 import java.awt.Button;
3
4 public class Boton1 {
5
6 public static void main(String[] args) {
7 Frame MiMarco = new Frame();
8 Button BotonHola = new Button("Hola");
9
10 MiMarco.add(BotonHola);
11
12 MiMarco.setSize(400,200);
13 MiMarco.setTitle("Ventana con botón");
14 MiMarco.setVisible(true);
15 }
16 }
El ejemplo anterior puede ser ampliado con facilidad para que el marco
incorpore un panel. Usando el panel conseguiremos que los componentes que
añadamos al mismo sigan una disposición establecida (por defecto ordenación
secuencial).
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 7: INTERFAZ GRÁFICO DE USUARIO 201
Marco
Panel
Botón
1 import java.awt.Frame;
2 import java.awt.Button;
3 import java.awt.Panel;
4
5 public class Boton2 {
6
7 public static void main(String[] args) {
8 Frame MiMarco = new Frame();
9 Panel MiPanel = new Panel();
10 Button BotonArea = new Button("Calcular área");
11 Button BotonPerimetro = new Button("Calcular
perímetro");
12
13 MiMarco.add(MiPanel);
14 MiPanel.add(BotonArea);
15 MiPanel.add(BotonPerimetro);
16
17 MiMarco.setSize(400,200);
18 MiMarco.setTitle("Ventana con botones");
19 MiMarco.setVisible(true);
20 }
21 }
202 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
Marco
PanelPrincipal
PanelDcha
BotonDescansar
PanelIzq
BotonSaltar BotonCorrer
1 import java.awt.Frame;
2 import java.awt.Button;
3 import java.awt.Panel;
4
5 public class Panel1 {
6
7 public static void main(String[] args) {
8 Frame MiMarco = new Frame();
9 Panel PanelPrincipal = new Panel();
10 Panel PanelIzq = new Panel();
11 Panel PanelDcha = new Panel();
12
13 Button BotonCorrer = new Button("Correr");
14 Button BotonSaltar = new Button("Saltar");
15 Button BotonDescansar = new Button("Descansar");
16
17 MiMarco.add(PanelPrincipal);
18 PanelPrincipal.add(PanelIzq);
19 PanelPrincipal.add(PanelDcha);
20 PanelIzq.add(BotonCorrer);
21 PanelIzq.add(BotonSaltar);
22 PanelDcha.add(BotonDescansar);
23
24 MiMarco.setSize(400,200);
25 MiMarco.setTitle("Ventana con paneles");
26 MiMarco.setVisible(true);
27 }
28 }
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 7: INTERFAZ GRÁFICO DE USUARIO 203
1 import java.awt.Frame;
2 import java.awt.Button;
3 import java.awt.Panel;
4 import java.awt.FlowLayout;
5
6 public class FlowLayout1 {
7
8 public static void main(String[] args) {
9 Frame MiMarco = new Frame();
10 Panel MiPanel = new Panel();
11 FlowLayout PosicionamientoSecuencial = new
FlowLayout();
12 Button BotonA = new Button("Primer botón");
13 Button BotonB = new Button("Segundo botón");
14 Button BotonC = new Button("Tercer botón");
15 Button BotonD = new Button("Cuarto botón");
16
17 MiPanel.setLayout(PosicionamientoSecuencial);
18
19 MiMarco.add(MiPanel);
20 MiPanel.add(BotonA);
21 MiPanel.add(BotonB);
22 MiPanel.add(BotonC);
23 MiPanel.add(BotonD);
24
25 MiMarco.setSize(300,100);
26 MiMarco.setTitle("Ventana con flow layout");
27 MiMarco.setVisible(true);
28 }
29 }
1 import java.awt.Frame;
2 import java.awt.Button;
3 import java.awt.Panel;
4 import java.awt.BorderLayout;
5
6 public class BorderLayout1 {
7
8 public static void main(String[] args) {
9 Frame MiMarco = new Frame();
10 Panel MiPanel = new Panel();
11 BorderLayout PuntosCardinales = new BorderLayout();
12 Button BotonNorte = new Button("Norte");
13 Button BotonSur = new Button("Sur");
14 Button BotonEste = new Button("Este");
15 Button BotonOeste = new Button("Oeste");
16 Button BotonCentro = new Button("Centro");
17
18 MiPanel.setLayout(PuntosCardinales);
19
206 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
20 MiMarco.add(MiPanel);
21 MiPanel.add(BotonNorte, BorderLayout.NORTH);
22 MiPanel.add(BotonSur, BorderLayout.SOUTH);
23 MiPanel.add(BotonEste, BorderLayout.EAST);
24 MiPanel.add(BotonOeste, BorderLayout.WEST);
25 MiPanel.add(BotonCentro, BorderLayout.CENTER);
26
27 MiMarco.setSize(300,100);
28 MiMarco.setTitle("Ventana con BorderLayout");
29 MiMarco.setVisible(true);
30 }
31 }
Marco
PanelGeneral
PanelMenuNorte
BotonOpcion1
BotonOpcion2
BotonOpcion3
BotonOeste BotonEste
BotonSur
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 7: INTERFAZ GRÁFICO DE USUARIO 207
1 import java.awt.*;
2
3 public class BorderLayout2 {
4
5 public static void main(String[] args) {
6 Frame MiMarco = new Frame();
7 Panel PanelMenuNorte = new Panel();
8 Panel PanelGeneral = new Panel();
9 BorderLayout PuntosCardinales = new BorderLayout();
10 FlowLayout OpcionesMenu = new FlowLayout();
11 Button BotonOpcion1 = new Button("Opción 1");
12 Button BotonOpcion2 = new Button("Opción 2");
13 Button BotonOpcion3 = new Button("Opción 3");
14 Button BotonSur = new Button("Sur");
15 Button BotonEste = new Button("Este");
16 Button BotonOeste = new Button("Oeste");
17 Button BotonCentro = new Button("Centro");
18
19 PanelGeneral.setLayout(PuntosCardinales);
20 PanelMenuNorte.setLayout(OpcionesMenu);
21
22 MiMarco.add(PanelGeneral);
23 PanelGeneral.add(PanelMenuNorte, BorderLayout.NORTH);
24 PanelMenuNorte.add(BotonOpcion1);
25 PanelMenuNorte.add(BotonOpcion2);
26 PanelMenuNorte.add(BotonOpcion3);
27 PanelGeneral.add(BotonSur, BorderLayout.SOUTH);
28 PanelGeneral.add(BotonEste, BorderLayout.EAST);
29 PanelGeneral.add(BotonOeste, BorderLayout.WEST);
30 PanelGeneral.add(BotonCentro, BorderLayout.CENTER);
31
32 MiMarco.setSize(400,150);
33 MiMarco.setTitle("Ventana con BorderLayout");
34 MiMarco.setVisible(true);
35 }
36 }
208 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
1 import java.awt.*;
2
3 public class GridLayout1 {
4
5 public static void main(String[] args) {
6 Frame MiMarco = new Frame();
7 Panel MiPanel = new Panel();
8
9 GridLayout Matriz = new GridLayout(2,3);
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 7: INTERFAZ GRÁFICO DE USUARIO 209
1 import java.awt.*;
2
3 public class GridLayout2 {
4
5 public static void main(String[] args) {
6 Frame MiMarco = new Frame();
7
8 MiMarco.setLayout(new GridLayout(3,2));
9 for (int i=0;i<6;i++)
10 MiMarco.add(new Button("Botón "+i));
11
12 MiMarco.setSize(300,100);
13 MiMarco.setTitle("Ventana con GridLayout");
14 MiMarco.setVisible(true);
15 }
16 }
210 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
1 import java.awt.*;
2
3 public class GridLayout3 {
4
5 public static void main(String[] args) {
6 Frame MiMarco = new Frame();
7 Panel Vertical = new Panel(new BorderLayout());
8 MiMarco.setLayout(new GridLayout(2,3));
9
10 Vertical.add(new Button("Arriba"), BorderLayout.NORTH);
11 Vertical.add(new Button("Centro"),
BorderLayout.CENTER);
12 Vertical.add(new Button("Abajo"), BorderLayout.SOUTH);
13
14 MiMarco.add(Vertical);
15 for (int i=1;i<6;i++)
16 MiMarco.add(new Button("Botón "+i));
17
18 MiMarco.setSize(300,160);
19 MiMarco.setTitle("Ventana con Layouts Grid y Border");
20 MiMarco.setVisible(true);
21 }
22 }
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 7: INTERFAZ GRÁFICO DE USUARIO 211
7.3.1 Introducción
Una vez que somos capaces de crear marcos, añadirles paneles con
diferentes “layouts” e insertar componentes en los mismos, estamos preparados para
realizar diseños de interfaces de usuario, sin embargo, todavía nos falta conocer los
diferentes componentes básicos de entrada/salida que podemos utilizar en Java.
Component
Button Container
Label java.awt
Panel Window
TextComponent
Frame
TextField TextArea
1 import java.awt.Frame;
2 import java.awt.Label;
3
4 public class Etiqueta1 {
5
6 public static void main(String[] args) {
7 Frame MiMarco = new Frame();
8 Label Titulo = new Label("Notas de matemáticas");
9
10 MiMarco.add(Titulo);
11
12 MiMarco.setSize(200,100);
13 MiMarco.setTitle("Ventana con etiqueta");
14 MiMarco.setVisible(true);
15 }
16 }
MiMarco
PanelGeneral
PanelDerecho
PanelIzquierdo
1 import java.awt.*;
2
3 public class Etiqueta2 {
4
5 public static void main(String[] args) {
6 Frame MiMarco = new Frame();
7 Panel PanelGeneral = new Panel(new GridLayout(1,2));
8 Panel PanelIzquierdo = new Panel(new GridLayout(3,1));
9 Panel PanelDerecho = new Panel(new FlowLayout());
10
11 PanelGeneral.add(PanelIzquierdo);
12 PanelGeneral.add(PanelDerecho);
13 PanelIzquierdo.add(new Label("Ford",Label.CENTER));
14 PanelIzquierdo.add(new Label("Opel",Label.CENTER));
15 PanelIzquierdo.add(new Label("Audi",Label.CENTER));
16 PanelDerecho.add(new Label("Coupe"));
17 PanelDerecho.add(new Label("Cabrio"));
18
19 MiMarco.add(PanelGeneral);
20 MiMarco.setSize(250,100);
21 MiMarco.setTitle("Ventana con etiqueta");
22 MiMarco.setVisible(true);
23 }
24 }
214 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
1 import java.awt.*;
2
3 public class Etiqueta3 {
4
5 public static void main(String[] args) {
6 Frame MiMarco = new Frame();
7 Panel Tabla = new Panel(new GridLayout(11,11));
8 Label[] CabeceraFila = new Label[11];
9 Label[] CabeceraColumna = new Label[11];
10
11 Tabla.add(new Label(""));
12 for (int i=1;i<=10;i++) {
13 CabeceraFila[i] = new Label(""+i);
14 CabeceraFila[i].setBackground(Color.red);
15 Tabla.add(CabeceraFila[i]);
16 }
17
18 for (int i=1;i<=10;i++) {
19 CabeceraColumna[i] = new Label(""+i);
20 CabeceraColumna[i].setBackground(Color.red);
21 Tabla.add(CabeceraColumna[i]);
22 for (int j=1;j<=10;j++)
23 Tabla.add(new Label(""+i*j));
24 }
25
26 MiMarco.add(Tabla);
27 MiMarco.setSize(400,400);
28 MiMarco.setTitle("Tabla de multiplicar");
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 7: INTERFAZ GRÁFICO DE USUARIO 215
29 MiMarco.setVisible(true);
30 }
31 }
1 import java.awt.*;
2
3 public class CampoDeTexto1 {
4
5 public static void main(String[] args) {
6 Frame MiMarco = new Frame();
7 Panel EntradaDeDatos = new Panel(new FlowLayout());
8 TextField Nombre = new TextField(15);
9 TextField Apellidos = new TextField(60);
10 TextField Nacionalidad = new TextField("Española",15);
11
12 EntradaDeDatos.add(Nombre);
13 EntradaDeDatos.add(Apellidos);
14 EntradaDeDatos.add(Nacionalidad);
216 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
15
16 MiMarco.add(EntradaDeDatos);
17 MiMarco.setSize(500,130);
18 MiMarco.setTitle("Ventana con campos de texto");
19 MiMarco.setVisible(true);
20 }
21 }
MiMarco
PanelNombre
PanelApellidos
EntradaDeDatos
PanelNacionalidad
1 import java.awt.*;
2
3 public class CampoDeTexto2 {
4
5 public static void main(String[] args) {
6 Frame MiMarco = new Frame();
7 Panel EntradaDeDatos = new Panel(new GridLayout(3,1));
8 Panel PanelNombre = new Panel(new
FlowLayout(FlowLayout.LEFT));
9 Panel PanelApellidos = new Panel(new
FlowLayout(FlowLayout.LEFT));
10 Panel PanelNacionalidad = new Panel(new
FlowLayout(FlowLayout.LEFT));
11
12 TextField CampoNombre = new TextField(12);
13 TextField CampoApellidos = new TextField(50);
14 TextField CampoNacionalidad = new
TextField("Española",12);
15 Label EtiquetaNombre = new Label("Nombre",Label.LEFT);
16 Label EtiquetaApellidos = new
Label("Apellidos",Label.LEFT);
17 Label EtiquetaNacionalidad = new
Label("Nacionalidad",Label.LEFT);
18
19 EntradaDeDatos.add(PanelNombre);
20 EntradaDeDatos.add(PanelApellidos);
21 EntradaDeDatos.add(PanelNacionalidad);
22 PanelNombre.add(EtiquetaNombre);
23 PanelNombre.add(CampoNombre);
24 PanelApellidos.add(EtiquetaApellidos);
25 PanelApellidos.add(CampoApellidos);
26 PanelNacionalidad.add(EtiquetaNacionalidad);
27 PanelNacionalidad.add(CampoNacionalidad);
28
29 MiMarco.add(EntradaDeDatos);
30 MiMarco.setSize(500,130);
31 MiMarco.setTitle("Ventana con campos de texto
y etiquetas");
32 MiMarco.setVisible(true);
33 }
34 }
218 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
El objeto área de texto es una región que representa texto en una o varias
líneas. Se puede configurar para que su contenido se pueda editar o bien sea de solo
lectura.
1 import java.awt.*;
2
3 public class AreaDeTexto {
4
5 public static void main(String[] args) {
6 int FILAS = 3;
7 int COLUMNAS = 20 ;
8
9 Frame MiMarco = new Frame();
10 Panel MiPanel = new Panel();
11 TextArea Comentarios = new TextArea("La
tarta",FILAS,COLUMNAS,
TextArea.SCROLLBARS_VERTICAL_ONLY);
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 7: INTERFAZ GRÁFICO DE USUARIO 219
Las fuentes no son componentes; son clases que heredan de forma directa de
Object (la clase inicial de la jerarquía). El conocimiento de la clase Font es
importante debido a que nos permite variar el aspecto de los textos involucrados en
los componentes que estamos estudiando. Podemos cambiar el tamaño y el tipo de
letra de los caracteres contenidos en una etiqueta, un campo de texto, un área de
texto, etc.
El nombre, que puede ser lógico o físico, indica el tipo de letra con el que se
visualizará el texto (Serif , SansSerif, Monospaced...). El estilo se refiere a letra
itálica, negrilla, normal o alguna combinación de ellas: Font.ITALIC, Font.BOLD,
Font.PLAIN.
1 import java.awt.*;
2
3 public class Fuente {
4
5 public static void main(String[] args) {
6 Frame MiMarco = new Frame();
7 Font UnaFuente = new Font("SansSerif",Font.BOLD,20);
8 Font OtraFuente = new Font("Serif",Font.ITALIC,40);
9
10 Panel Sencillo = new Panel();
11 Label HolaAmigo1 = new Label("Hola amigo");
12 Label HolaAmigo2 = new Label("Hola amigo");
13
14 HolaAmigo1.setFont(UnaFuente);
15 HolaAmigo1.setForeground(Color.red);
16
17 HolaAmigo2.setFont(OtraFuente);
18 HolaAmigo2.setForeground(Color.orange);
19
20 Sencillo.add(HolaAmigo1);
21 Sencillo.add(HolaAmigo2);
22
23 MiMarco.add(Sencillo);
24 MiMarco.setSize(500,130);
25 MiMarco.setTitle("Ventana con etiquetas y fuentes");
26 MiMarco.setVisible(true);
27 }
28 }
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 7: INTERFAZ GRÁFICO DE USUARIO 221
7.4.1 Introducción
TextField TextArea
1 import java.awt.*;
2
3 public class CajaDeVerificacion {
4
5 public static void main(String[] args) {
6 Frame MiMarco = new Frame();
7 Panel Sencillo = new Panel(new GridLayout(6,1));
8
9 Checkbox AireAcondicionado = new Checkbox("Aire
acondicionado",true);
10 Checkbox FarosXenon = new Checkbox("Faros de
xenon",false);
11 Checkbox PinturaMetalizada = new Checkbox("Pintura
metalizada",true);
12 Checkbox LlantasAleacion = new Checkbox("Llantas de
aleación",false);
13 Checkbox TapiceriaCuero = new Checkbox("Tapicería de
cuero",false);
14 Checkbox FarosAntiniebla = new Checkbox("Faros
antiniebla",false);
15
16 Sencillo.add(AireAcondicionado);
17 Sencillo.add(FarosXenon);
18 Sencillo.add(PinturaMetalizada);
19 Sencillo.add(LlantasAleacion);
20 Sencillo.add(TapiceriaCuero);
21 Sencillo.add(FarosAntiniebla);
22
23 MiMarco.add(Sencillo);
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 7: INTERFAZ GRÁFICO DE USUARIO 223
24 MiMarco.setSize(200,200);
25 MiMarco.setTitle("Ventana con cajas de verificación");
26 MiMarco.setVisible(true);
27 }
28 }
1 import java.awt.*;
2
3 public class BotonesDeRadio1 {
4
5 public static void main(String[] args) {
6 Frame MiMarco = new Frame();
7 Panel Sencillo = new Panel(new GridLayout(6,1));
8 CheckboxGroup Colores = new CheckboxGroup();
9
10 Sencillo.add(new Checkbox("Rojo",false,Colores));
11 Sencillo.add(new Checkbox("Azul",false,Colores));
12 Sencillo.add(new Checkbox("Verde",false,Colores));
13 Sencillo.add(new Checkbox("Amarillo",false,Colores));
14 Sencillo.add(new Checkbox("Negro",false,Colores));
15 Sencillo.add(new Checkbox("Gris",false,Colores));
16
17 MiMarco.add(Sencillo);
18 MiMarco.setSize(200,200);
19 MiMarco.setTitle("Ventana con botones de radio");
20 MiMarco.setVisible(true);
21 }
22 }
1 import java.awt.*;
2
3 public class BotonesDeRadio2 {
4
5 private static void EstableceVisualizacion(Checkbox
6 Elemento, Color ColorSeleccionado,
7 Font FuenteSeleccionada){
8 Elemento.setFont(FuenteSeleccionada);
9 Elemento.setForeground(ColorSeleccionado);
10 }
11
12
13 public static void main(String[] args) {
14 Frame MiMarco = new Frame();
15 Panel Sencillo = new Panel(new GridLayout(6,1));
16 CheckboxGroup Colores = new CheckboxGroup();
17
18 Checkbox Rojo = new Checkbox("Rojo",false,Colores);
19 Checkbox Azul = new Checkbox("Azul",false,Colores);
20 Checkbox Verde = new
Checkbox("Verde",false,Colores);
21 Checkbox Amarillo = new
Checkbox("Amarillo",false,Colores);
22 Checkbox Negro = new
Checkbox("Negro",false,Colores);
23 Checkbox Gris = new Checkbox("Gris",false,Colores);
24
25 Font MiFuente = new Font("SansSerif",Font.PLAIN,25);
26
27 EstableceVisualizacion(Rojo,Color.red,MiFuente);
28 EstableceVisualizacion(Azul,Color.blue,MiFuente);
29 EstableceVisualizacion(Verde,Color.green,MiFuente);
30 EstableceVisualizacion(Amarillo,Color.yellow,MiFuente);
31 EstableceVisualizacion(Negro,Color.black,MiFuente);
32 EstableceVisualizacion(Gris,Color.gray,MiFuente);
226 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
33
34 Sencillo.add(Rojo);
35 Sencillo.add(Azul);
36 Sencillo.add(Verde);
37 Sencillo.add(Amarillo);
38 Sencillo.add(Negro);
39 Sencillo.add(Gris);
40
41 MiMarco.add(Sencillo);
42 MiMarco.setSize(200,200);
43 MiMarco.setTitle("Ventana con botones de radio");
44 MiMarco.setVisible(true);
45 }
46 }
1 import java.awt.*;
2
3 public class Lista2 {
4
5 public static void main(String[] args) {
6 Frame MiMarco = new Frame();
7 Panel MiPanel = new Panel();
8 List Islas = new List(3);
9 Islas.setMultipleMode(true);
10
11 Islas.add("Fuerteventura");
12 Islas.add("La Gomera");
13 Islas.add("Gran Canaria");
14 Islas.add("Hierro");
15 Islas.add("Lanzarote");
16 Islas.add("Tenerife");
17 Islas.add("La Palma",5);
18
19 Islas.select(2);
20 Islas.select(4);
21
22 MiPanel.add(Islas);
23 MiMarco.add(MiPanel);
24 MiMarco.setSize(200,200);
25 MiMarco.setTitle("Ventana con lista de selección
múltiple");
26 MiMarco.setVisible(true);
27 }
28 }
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 7: INTERFAZ GRÁFICO DE USUARIO 229
1 import java.awt.*;
2
3 public class ListaDesplegable1 {
4
5 public static void main(String[] args) {
6 Frame MiMarco = new Frame();
7 Panel MiPanel = new Panel();
8 Choice Ciudades = new Choice();
9
10 Ciudades.add("Alicante");
11 Ciudades.add("Avila");
12 Ciudades.add("Granada");
13 Ciudades.add("Segovia");
14 Ciudades.add("Sevilla");
15 Ciudades.add("Toledo");
16
17 MiPanel.add(Ciudades);
18 MiMarco.add(MiPanel);
19 MiMarco.setSize(200,200);
20 MiMarco.setTitle("Ventana con lista desplegable");
21 MiMarco.setVisible(true);
22 }
23 }
230 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
Obtendremos el resultado:
Supongamos que deseamos crear una pantalla de entrada de datos que nos
permita recibir información personal de usuarios, por ejemplo contribuyentes
fiscales residentes en España.
Formulario
Región centro
Región este
Región sur
EtiquetaNombre CampoNombre
PanelDatosPersonales PanelNombre
PanelApellidos
PanelDireccion
EtiquetaDireccion CampoDireccion
232 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
Los botones de radio que sirven para seleccionar el estado civil se pueden
añadir a un único panel “PanelEstadoCivil” asociado a un GridLayout 5 x 1:
PanelEstadoCivil Soltero
Casado
Separado
Divorciado
Otros
1 import java.awt.*;
2
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 7: INTERFAZ GRÁFICO DE USUARIO 233
Checkbox("Separado",false,EstadoCivil);
41 Checkbox Divorciado = new
Checkbox("Divorciado",false,EstadoCivil);
42 Checkbox Otros = new
Checkbox("Otros",false,EstadoCivil);
43
44 PanelEstadoCivil.add(Soltero);
45 PanelEstadoCivil.add(Casado);
46 PanelEstadoCivil.add(Separado);
47 PanelEstadoCivil.add(Divorciado);
48 PanelEstadoCivil.add(Otros);
49 }
50
51 private static void PreparaProvincia() {
52 Choice Ciudades = new Choice();
53
54 Ciudades.add("Alicante");
55 Ciudades.add("Avila");
56 Ciudades.add("Granada");
57 Ciudades.add("Madrid");
58 Ciudades.add("Segovia");
59 Ciudades.add("Sevilla");
60 Ciudades.add("Toledo");
61
62 PanelProvincia.add(Ciudades);
63 }
64
65 public static void main(String[] args) {
66 PreparaDatosPersonales();
67 PreparaEstadoCivil();
68 PreparaProvincia();
69
70 PanelDatosPersonales.setBackground(Color.orange);
71 PanelEstadoCivil.setBackground(Color.yellow);
72 PanelProvincia.setBackground(Color.green);
73
74 Formulario.add(PanelDatosPersonales,
BorderLayout.NORTH);
75 Formulario.add(PanelEstadoCivil,BorderLayout.WEST);
76 Formulario.add(PanelProvincia,BorderLayout.EAST);
77 Formulario.add(new
Button("Enviar"),BorderLayout.SOUTH);
78
79 MiMarco.add(Formulario);
80 MiMarco.setSize(600,250);
81 MiMarco.setTitle("Formulario");
82 MiMarco.setVisible(true);
83 } }
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 7: INTERFAZ GRÁFICO DE USUARIO 235
Para facilitar la reutilización al máximo, crearemos una clase por cada uno
de los paneles principales y después crearemos una o varias clases que hagan uso de
las anteriores. El esquema que seguiremos es el siguiente:
Formulario2main Formulario2main
1 2
La clase tiene un constructor con argumento de tipo Color (línea 7), lo que
nos permite asignar el color seleccionado al panel PanelDatosPersonales (línea 11).
El segundo constructor de la clase (línea 14) no presenta parámetros; internamente
llama al primero con el parámetro de color blanco.
1 import java.awt.*;
2
3 public class Formulario2DatosPersonales {
4
5 private Panel PanelDatosPersonales = new Panel(new
GridLayout(3,1));
6
7 Formulario2DatosPersonales(Color ColorDelPanel){
8
9 // *** Codigo del metodo PreparaDatosPersonales() ***
10
11 PanelDatosPersonales.setBackground(ColorDelPanel);
236 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
12 }
13
14 Formulario2DatosPersonales(){
15 this(Color.white);
16 }
17
18 Panel DamePanel() {
19 return PanelDatosPersonales;
20 }
21
22 }
1 import java.awt.*;
2
3 public class Formulario2EstadoCivil {
4
5 private Panel PanelEstadoCivil = new Panel(new
GridLayout(5,1));
6
7 Formulario2EstadoCivil(Color ColorDelPanel) {
8
9 // *** Codigo del metodo PreparaEstadoCivil() ***
10
11 PanelEstadoCivil.setBackground(ColorDelPanel);
12 }
13
14 Formulario2EstadoCivil(){
15 this(Color.white);
16 }
17
18 Panel DamePanel() {
19 return PanelEstadoCivil;
20 }
21
22 }
1 import java.awt.*;
2
3 public class Formulario2Provincia {
4
5 private Panel PanelProvincia = new Panel();
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 7: INTERFAZ GRÁFICO DE USUARIO 237
6
7 Formulario2Provincia(Color ColorDelPanel){
8
9 // *** Codigo del metodo PreparaProvincia() ***
10
11 PanelProvincia.setBackground(ColorDelPanel);
12 }
13
14 Formulario2Provincia() {
15 this(Color.white);
16 }
17
18 Panel DamePanel() {
19 return PanelProvincia;
20 }
21
22 }
1 import java.awt.*;
2
3 public class Formulario2main1 {
4
5 private static Frame MiMarco = new Frame();
6 private static Panel Formulario = new Panel(new
BorderLayout());
7
8 public static void main(String[] args) {
9 Formulario2DatosPersonales DatosPersonales =
10 new Formulario2DatosPersonales(Color.orange);
11 Formulario2EstadoCivil EstadoCivil =
12 new Formulario2EstadoCivil(Color.yellow);
13 Formulario2Provincia Provincia = new
Formulario2Provincia(Color.green);
14
15 Formulario.add(DatosPersonales.DamePanel(),
BorderLayout.NORTH);
16 Formulario.add(EstadoCivil.DamePanel(),
BorderLayout.WEST);
17 Formulario.add(Provincia.DamePanel(),
BorderLayout.EAST);
18 Formulario.add(new Button("Enviar"),
BorderLayout.SOUTH);
19
20 MiMarco.add(Formulario);
21 MiMarco.setSize(600,250);
22 MiMarco.setTitle("Formulario");
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 7: INTERFAZ GRÁFICO DE USUARIO 239
23 MiMarco.setVisible(true);
24 }
25 }
1 import java.awt.*;
2
3 public class Formulario2main2 {
4
5 private static Frame MiMarco = new Frame();
6 private static Panel Formulario = new Panel(new
GridLayout(3,1));
7
8 public static void main(String[] args) {
9
10 Panel EstadoCivil_Provincia =
11 new Panel(new FlowLayout(FlowLayout.CENTER));
12 Panel BotonEnviar = new Panel();
13
14 Formulario2DatosPersonales DatosPersonales =
15 new Formulario2DatosPersonales();
16 Formulario2EstadoCivil EstadoCivil =
17 new Formulario2EstadoCivil(Color.yellow);
18 Formulario2Provincia Provincia = new
Formulario2Provincia(Color.yellow);
19
240 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
20 EstadoCivil_Provincia.add(EstadoCivil.DamePanel());
21 EstadoCivil_Provincia.add(Provincia.DamePanel());
22 BotonEnviar.add(new Button("Enviar"));
23
24 Formulario.add(DatosPersonales.DamePanel());
25 Formulario.add(EstadoCivil_Provincia);
26 Formulario.add(BotonEnviar);
27
28 MiMarco.add(Formulario);
29 MiMarco.setSize(600,250);
30 MiMarco.setTitle("Formulario");
31 MiMarco.setVisible(true);
32 }
33 }
Este mismo ejercicio se podría haber resuelto con un enfoque más elegante
desde el punto de vista de programación orientada a objetos: podríamos haber
definido las clases Formulario2DatosPersoanles, Formulario2EstadoCivil y
Formulario2Provincia como subclases de Panel. En ese caso no necesitaríamos
crear instancias del objeto Panel dentro de cada una de las tres clases, ni tampoco
haría falta definir y utilizar el método DimePanel().
Los siguie ntes componentes de AWT que vamos a estudiar son los diálogos,
con los que podemos crear ventanas adicionales a la principal, especializadas en
diferentes tipos de interacción con el usuario (por ejemplo selección de un fichero).
También nos centraremos en la manera de crear menús.
Los diálogos los basaremos en las clases Dialog y FileDialog, mientras que
los menús los crearemos con los objetos MenuBar y Menu. El siguiente diagrama
sitúa todas estas clases en la jerarquía que proporciona Java:
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 7: INTERFAZ GRÁFICO DE USUARIO 241
Object java.lang
MenuComponent Component
Container
MenuItem MenuBar
Window java.awt
Menu
Dialog
FileDialog
Un diálogo es una ventana que se usa para recoger información del usuario;
su disposición por defecto es BorderLayout. Para poder crear un diálogo hay que
indicar quién es su propietario (un marco o bien otro diálogo).
La línea 14 invoca al método show del objeto Dialogo para conseguir que la
ventana se haga visible. El diálogo que se obtiene es una ventana vacía y sin
dimensiones.
1 import java.awt.*;
2
3 public class Dialogo1 {
4
5 public static void main(String[] args) {
6 final boolean NO_MODAL = false;
7 Frame MiMarco = new Frame();
8
9 Dialog Dialogo = new Dialog(MiMarco,"Ventana de
diálogo",NO_MODAL);
10
11 MiMarco.setSize(200,100);
12 MiMarco.setTitle("Ventana con diálogo");
13 MiMarco.setVisible(true);
14 Dialogo.show();
15 }
16 }
1 import java.awt.*;
2
3 public class Dialogo2 {
4
5 public static void main(String[] args) {
6 final boolean MODAL = true;
7 Frame MiMarco = new Frame();
8 Panel MiPanel = new Panel();
9 MiPanel.add(new Label("Un elemento en el diálogo"));
10
11 Dialog Dialogo = new Dialog(MiMarco,"Ventana de
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 7: INTERFAZ GRÁFICO DE USUARIO 243
diálogo",MODAL);
12 Dialogo.add(MiPanel);
13 Dialogo.setSize(250,100);
14 Dialogo.setLocation(new Point(50,80));
15
16 MiMarco.setSize(200,100);
17 MiMarco.setTitle("Ventana con diálogo");
18 MiMarco.setVisible(true);
19 Dialogo.show();
20 }
21 }
1 import java.awt.*;
2
3 public class DialogoFichero {
4
5 public static void main(String[] args) {
6 Frame MiMarco = new Frame();
7
8 FileDialog Grabar = new
FileDialog(MiMarco,"Guardar",FileDialog.SAVE);
9 // FileDialog Cargar =
10 new FileDialog(MiMarco,"Cargar",
FileDialog.LOAD);
11
12 MiMarco.setSize(200,100);
13 MiMarco.setTitle("Ventana con diálogo de carga
de fichero");
14 MiMarco.setVisible(true);
15 Grabar.show();
16 }
17 }
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 7: INTERFAZ GRÁFICO DE USUARIO 245
setMenuBar (....)
Frame
MenuBar
add (....)
Menu
String o MenuItem
add (....)
1 import java.awt.*;
2
3 public class Menus {
4
5 public static void main(String[] args) {
6 Frame MiMarco = new Frame();
7
8 MenuBar MenuPrincipal = new MenuBar();
9 Menu Fichero = new Menu("Fichero");
10 Menu Transformaciones = new Menu("Transformación");
11
12 Fichero.add("Abrir");
13 Fichero.add("Cerrar");
14 Fichero.add("Imprimir");
15 Fichero.add("Guardar");
16
17 Transformaciones.add("Rotación");
18 Transformaciones.add("Traslación");
19 Transformaciones.add("Cambio de escala");
20
21 MenuPrincipal.add(Fichero);
22 MenuPrincipal.add(Transformaciones);
23
24 MiMarco.setMenuBar(MenuPrincipal);
25 MiMarco.setSize(200,100);
26 MiMarco.setTitle("Ventana con menú");
27 MiMarco.setVisible(true);
28 }
29 }
CAPÍTULO 8
EVENTOS
Java es un lenguaje orientado a objetos, por lo que los objetos (las clases)
son los elementos más importantes en el diseño y desarrollo de una aplicación.
También podemos afirmar que Java es un lenguaje orientado a eventos, puesto que
nos proporciona todos los elementos necesarios para definirlos y utilizarlos; los
eventos son objetos fundamentales en el desarrollo de la mayor parte de las
aplicaciones.
• etc.
AWT proporciona una ámplia gama de eventos que pueden ser recogidos
por los métodos existentes en las implementaciones que hagamos de los listeners (o
las clases que especializemos a partir de los adaptadores). El siguiente gráfico
muestra los eventos, interfaces y adaptadores más utilizados en las aplicaciones de
carácter general.
MouseListener
MouseAdapter
MouseEvent
MouseMotionListener
MouseMotionAdapter
KeyEvent KeyListener
KeyAdapter
WindowEvent WindowListener
WindowAdapter
ActionEvent ActionListener
ItemEvent ItemListener
Para entender con mayor facilidad la manera con la que se tratan los eventos
en Java, vamos a analizar uno de los interfaces existentes: MouseListener. Este
interfaz contiene los siguientes métodos:
• void mousePressed (MouseEvent e)
252 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
En primer lugar crearemos una clase que asigne las acciones deseadas a los
eventos que hemos determinado. Podemos utilizar el interface MouseListener o la
clase MouseAdapter.
Utilizando el interface:
1 import java.awt.event.*;
2 import java.awt.Color;
3
4 public class EsquemaRaton implements MouseListener {
5
6 public void mouseClicked(MouseEvent EventoQueLlega){
7 // aqui se implementa la accion deseada
8 }
9
10 public void mousePressed(MouseEvent EventoQueLlega){
11 }
12
13 public void mouseReleased(MouseEvent EventoQueLlega){
14 }
15
16 public void mouseEntered(MouseEvent EventoQueLlega){
17 EventoQueLlega.getComponent().setBackground(Color.red);
18 }
19
20 public void mouseExited(MouseEvent EventoQueLlega){
21 EventoQueLlega.getComponent().
setBackground(Color.gray);
22 }
23 }
1 import java.awt.*;
2
3 public class PruebaEsquemaRaton {
4
5 public static void main(String[] args) {
6 Frame MiFrame = new Frame("Esquema de eventos");
7 Panel MiPanel = new Panel();
256 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
ValidaTexto
RecogeCiudad
EstadoCivil ValidaFormulario
RecogeEstadoCivilConTeclado
8.2.1 Introducción
Los dos primeros interfaces y adaptadores se usan mucho más a menudo que
MouseWheelListener, por lo que centraremos las explicaciones en ellos. Como se
puede observar en la tabla anterior, el evento MouseEvent se utiliza en los métodos
pertenecientes a los interfaces MouseListener y MouseMotionListener. El interfaz
258 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
MouseListener
MouseAdapter
MouseEvent
MouseMotionListener
MouseMotionAdapter
MouseWheelEvent MouseWheelListener
MouseListener
MouseMotionListener
MouseWheelListener
MouseEvent
1 import java.awt.event.*;
2
3 // Clase que recoge los eventos de raton mediante sus
// metodos "mousePressed,
4 // mouseReleased, mouseClicked, etc." con parametro
// "MouseEvent"
260 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
5
6 public class InterrupcionDeRaton1 extends Object implements
MouseListener {
7
8 public void mouseClicked(MouseEvent EventoQueLlega){
9 System.out.println("Click de raton");
10 }
11
12 public void mousePressed(MouseEvent EventoQueLlega){
13 System.out.println("Presion de raton");
14 }
15
16 public void mouseReleased(MouseEvent EventoQueLlega){
17 System.out.println("Se ha levantado el boton del
raton");
18 }
19
20 public void mouseEntered(MouseEvent EventoQueLlega){
21 System.out.println("'Focus' de raton");
22 }
23
24 public void mouseExited(MouseEvent EventoQueLlega){
25 System.out.println("'Blur' de raton");
26 }
27 }
1 import java.awt.*;
2
3 public class PruebaEventosRaton1 {
4
5 public static void main(String[] args) {
6 Frame MiFrame = new Frame("Prueba eventos de raton");
7 Panel MiPanel = new Panel();
8 Button Hola = new Button("Saludo");
9 Button Adios = new Button("Despedida");
10 MiPanel.add(Hola); MiPanel.add(Adios);
11 MiFrame.add(MiPanel);
12 MiFrame.setSize(200,100);
13 MiFrame.show();
14
15 Hola.addMouseListener (new InterrupcionDeRaton1());
16 Adios.addMouseListener(new InterrupcionDeRaton1());
17 }
18 }
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 8: EVENTOS 261
1 import java.awt.*;
2
3 public class PruebaEventosRaton2 {
4
5 public static void main(String[] args) {
6 Frame MiFrame = new Frame("Prueba eventos de raton");
7 Panel MiPanel = new Panel();
8 MiFrame.add(MiPanel);
9 MiFrame.setSize(200,100);
10 MiFrame.show();
11
12 MiPanel.addMouseListener (new InterrupcionDeRaton1());
13
14 }
15 }
262 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
1 import java.awt.*;
2
3 public class PruebaEventosRaton3 {
4
5 public static void main(String[] args) {
6 // como en PruebaEventosRaton1
7
8 Hola.addMouseListener (new InterrupcionDeRaton2());
9 Adios.addMouseListener(new InterrupcionDeRaton2());
10
11 }
12 }
Los métodos mouseEntered (línea 23) y mouseExited (línea 29) hacen uso
del método getSource para obtener el objeto que generó el evento. Conociendo el
objeto, podemos cambiar sus propiedades (en este ejemplo su color de fondo). En
este ejemplo, en una serie de dos botones, conseguimos cambiar a azul el color de
fondo del botón sobre el que nos situamos con el ratón, dejándolo en gris al salir del
mismo.
1 import java.awt.event.*;
2 import java.awt.Component;
3 import java.awt.Color;
4
5 public class InterrupcionDeRaton2 extends Object implements
MouseListener {
6
7 public void mouseClicked(MouseEvent EventoQueLlega){
8 System.out.println("Click de raton");
9 }
10
11 public void mousePressed(MouseEvent EventoQueLlega){
12 System.out.println("Presion de raton");
13 System.out.println(EventoQueLlega.getX());
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 8: EVENTOS 263
14 System.out.println(EventoQueLlega.getY());
15 }
16
17 public void mouseReleased(MouseEvent EventoQueLlega){
18 System.out.println("Se ha levantado el boton del
raton");
19 System.out.println(EventoQueLlega.getX());
20 System.out.println(EventoQueLlega.getY());
21 }
22
23 public void mouseEntered(MouseEvent EventoQueLlega){
24 System.out.println("'Focus' de raton");
25 Component Boton = (Component)EventoQueLlega.getSource();
26 Boton.setBackground(Color.blue);
27 }
28
29 public void mouseExited(MouseEvent EventoQueLlega){
30 System.out.println("'Blur' de raton");
31 Component Boton = (Component)EventoQueLlega.getSource();
32 Boton.setBackground(Color.gray);
33 }
34 }
1 import java.awt.event.*;
2 import java.awt.Component;
3 import java.awt.Color;
4
5 public class InterrupcionDeRaton3 extends Object implements
MouseListener {
6
7 // public void mouseClicked(MouseEvent EventoQueLlega){
8 // System.out.println("Click de raton");
9 // }
10
11 // Como en la clase InterrupcionDeRaton2
12 }
264 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
1 import java.awt.event.*;
2 import java.awt.Component;
3 import java.awt.Color;
4
5 public class InterrupcionDeRaton4 extends MouseAdapter {
6
7 public void mouseEntered(MouseEvent EventoQueLlega){
8 System.out.println("'Focus' de raton");
9 Component Boton = (Component)EventoQueLlega.getSource();
10 Boton.setBackground(Color.blue);
11 }
12
13 public void mouseExited(MouseEvent EventoQueLlega){
14 System.out.println("'Blur' de raton");
15 Component Boton = (Component)EventoQueLlega.getSource();
16 Boton.setBackground(Color.gray);
17 }
18 }
1 import java.awt.*;
2
3 public class PruebaEventosRaton5 {
4
5 public static void main(String[] args) {
6 final int NUM_OPCIONES = 12;
7 Label Mensaje = new Label("Mensaje asociado al botón
pulsado");
8 Button[] Botones = new Button[NUM_OPCIONES];
9 for (int i=0;i<NUM_OPCIONES;i++) {
10 Botones[i] = new Button("Opcion " + i);
11 if (i<10)
12 Botones[i].setName("0"+i);
13 else
14 Botones[i].setName(String.valueOf(i));
15 }
16
17 Frame MiFrame = new Frame("Prueba eventos de raton");
18 Panel PanelPrincipal = new Panel(new
GridLayout(NUM_OPCIONES+1,1));
19
20 PanelPrincipal.add(Mensaje);
21 for (int i=0;i<NUM_OPCIONES;i++)
22 PanelPrincipal.add(Botones[i]);
23
24 MiFrame.add(PanelPrincipal);
25 MiFrame.setSize(200,300);
26 MiFrame.show();
27
28 for (int i=0;i<NUM_OPCIONES;i++)
29 Botones[i].addMouseListener(new
InterrupcionDeRaton5(Mensaje));
30
31
32 }
33 }
1 import java.awt.event.*;
2 import java.awt.Component;
3 import java.awt.Label;
4 import java.awt.Color;
5
6 public class InterrupcionDeRaton5 extends MouseAdapter {
7
8 private Label Mensaje;
9 private Component ComponenteQueInvoca;
10
11 public InterrupcionDeRaton5(Label Mensaje) {
12 this.Mensaje = Mensaje;
13 }
14
15 public void mouseClicked(MouseEvent EventoQueLlega){
16 Component ComponenteQueInvoca = (Component)
EventoQueLlega.getSource();
17 String Nombre = ComponenteQueInvoca.getName();
18 String Opcion = Nombre.substring(Nombre.length()
-2,Nombre.length());
19 Mensaje.setText("Ejecutar la accion "+Opcion);
// invocar a un método
20 }
21
22 public void mouseEntered(MouseEvent EventoQueLlega){
23 Component ComponenteQueInvoca = (Component)
EventoQueLlega.getSource();
24 ComponenteQueInvoca.setBackground(Color.red);
25 }
26
27 public void mouseExited(MouseEvent EventoQueLlega){
28 Component ComponenteQueInvoca = (Component)
EventoQueLlega.getSource();
29 ComponenteQueInvoca.setBackground(Color.orange);
30 }
31 }
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 8: EVENTOS 267
1 import java.awt.*;
2
3 public class PruebaEventosMovimientoRaton1 {
4
5 public static void main(String[] args) {
6 Frame MiFrame = new Frame("Prueba eventos de movimiento
de raton");
7 Panel MiPanel = new Panel();
8 MiFrame.add(MiPanel);
9 MiFrame.setSize(200,100);
10 MiFrame.show();
11
12 MiPanel.addMouseMotionListener (new
InterrupcionDeMovimientoDeRaton1());
13 }
14 }
1 import java.awt.event.*;
2
3 public class InterrupcionDeMovimientoDeRaton1 implements
MouseMotionListener {
4
5 public void mouseMoved(MouseEvent EventoQueLlega){
6 System.out.println("Movimiento del raton");
7 }
8
9 public void mouseDragged(MouseEvent EventoQueLlega){
10 System.out.println("Movimiento del raton con un boton
pulsado");
11 }
12
13 }
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 8: EVENTOS 269
1 import java.awt.*;
2
3 public class PruebaEventosMovimientoRaton2 {
4
5 public static void main(String[] args) {
6 Frame MiFrame = new Frame("Prueba eventos de movimiento
de raton");
7 Panel MiPanel = new Panel(new
FlowLayout(FlowLayout.LEFT));
8 MiFrame.add(MiPanel);
9 Label PosicionX = new Label("000");
10 Label PosicionY = new Label("000");
11 MiPanel.add(PosicionX);
12 MiPanel.add(PosicionY);
13
14 MiFrame.setSize(300,200);
15 MiFrame.show();
16 MiPanel.addMouseMotionListener(new
InterrupcionDeMovimientoDeRaton2(PosicionX,PosicionY));
17 }
18 }
270 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
1 import java.awt.event.*;
2 import java.awt.*;
3 import java.lang.String;
4
5 public class InterrupcionDeMovimientoDeRaton2 implements
6 MouseMotionListener {
7
8 private Label EtiquetaX, EtiquetaY;
9
10 InterrupcionDeMovimientoDeRaton2(Label EtiquetaX, Label
EtiquetaY) {
11 this.EtiquetaX = EtiquetaX;
12 this.EtiquetaY = EtiquetaY;
13 }
14
15 private void AsignaPosicion(MouseEvent EventoQueLlega) {
16 String PosicionX =
String.valueOf(EventoQueLlega.getX());
17 EtiquetaX.setText(PosicionX);
18 String PosicionY =
String.valueOf(EventoQueLlega.getY());
19 EtiquetaY.setText(PosicionY);
20 }
21
22 public void mouseMoved(MouseEvent EventoQueLlega){
23 EtiquetaX.setForeground(Color.orange);
24 EtiquetaY.setForeground(Color.orange);
25 AsignaPosicion(EventoQueLlega);
26 }
27
28 public void mouseDragged(MouseEvent EventoQueLlega){
29 EtiquetaX.setForeground(Color.blue);
30 EtiquetaY.setForeground(Color.blue);
31 AsignaPosicion(EventoQueLlega);
32 }
33 }
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 8: EVENTOS 271
1 import java.awt.event.*;
2 import java.awt.*;
3 import java.lang.String;
4
5 public class PruebaEventosMovimientoRaton2b {
6 Frame MiFrame = new Frame("Prueba eventos de movimiento
de raton");
7 Panel MiPanel = new Panel(new
FlowLayout(FlowLayout.LEFT));
8 Label PosicionX = new Label("000");
9 Label PosicionY = new Label("000");
10
11 PruebaEventosMovimientoRaton2b() {
12 MiFrame.add(MiPanel);
13 MiPanel.add(PosicionX);
14 MiPanel.add(PosicionY);
15 MiFrame.setSize(300,200);
16 MiFrame.show();
17 MiPanel.addMouseMotionListener(new
18 InterrupcionDeMovimientoDeRaton2b());
19 } // Constructor
20
21
22 class InterrupcionDeMovimientoDeRaton2b implements
MouseMotionListener {
23
24 private void AsignaPosicion(MouseEvent EventoQueLlega) {
25 String X = String.valueOf(EventoQueLlega.getX());
26 PosicionX .setText(X);
27 String Y = String.valueOf(EventoQueLlega.getY());
28 PosicionY .setText(Y);
29 }
30
31 public void mouseMoved(MouseEvent EventoQueLlega){
32 PosicionX .setForeground(Color.orange);
33 PosicionY .setForeground(Color.orange);
34 AsignaPosicion(EventoQueLlega);
35 }
36
37 public void mouseDragged(MouseEvent EventoQueLlega){
38 PosicionX .setForeground(Color.blue);
39 PosicionY .setForeground(Color.blue);
40 AsignaPosicion(EventoQueLlega);
272 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
41 }
42
43 } // InterrupcionDeMovimientoDeRaton2b
44
45 } // PruebaEventosMovimientoRaton2b
KeyListener
KeyAdapter
KeyEvent
WindowEvent WindowListener
WindowAdapter
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 8: EVENTOS 273
KeyListener
WindowListener
KeyEvent
WindowEvent
En este apartado vamos a desarrollar dos ejemplos que muestran el uso del
interfaz KeyListener, la clase KeyAdapter y el evento KeyEvent.
1 import java.awt.event.*;
2
3 public class InterrupcionDeTeclado1 implements KeyListener
{
4
5 public void keyTyped(KeyEvent EventoQueLlega){
6 System.out.println("Tecla pulsada y soltada");
7 }
8
9 public void keyPressed(KeyEvent EventoQueLlega){
10 System.out.println("Tecla pulsada");
11 }
12
13 public void keyReleased(KeyEvent EventoQueLlega){
14 System.out.println("Tecla soltada");
15 }
16
17 }
1 import java.awt.*;
2
3 public class PruebaEventosTeclado1 {
4
5 public static void main(String[] args) {
6
7 Frame MiFrame = new Frame("Prueba eventos de raton");
8 Panel MiPanel = new Panel();
9 MiFrame.add(MiPanel);
10 MiFrame.setSize(200,300);
11 MiFrame.show();
12
13 MiPanel.addKeyListener(new InterrupcionDeTeclado1());
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 8: EVENTOS 275
14
15 }
16 }
Nuestro segundo ejemplo imprime por consola los caracteres tecleados hasta
que pulsamos el asterisco, momento en el que abandonamos de la aplicación. Para
conseguir esta funcionalidad nos basta con hacer uso de un solo método del interfaz
KeyListener. Para facilitarnos la labor empleamos el adaptador KeyAdapter (línea 3
de la clase InterrupcionDeTeclado2), sobrecargando únicamente el método
keyTyped (cualquiera de los otros dos métodos nos hubiera servido de igual manera).
1 import java.awt.event.*;
2
3 public class InterrupcionDeTeclado2 extends KeyAdapter {
4
5 public void keyTyped(KeyEvent e){
6 System.out.print(e.getKeyChar());
7 if (e.getKeyChar()=='*')
8 System.exit(0);
9 }
10
11 }
1 import java.awt.*;
2
276 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
En este apartado vamos a desarrollar un solo ejemplo que muestra el uso del
interfaz WindowListener y el evento WindowEvent. Simplemente implementamos
los métodos del interfaz WindowListener para que imprima, cada uno, un texto
significativo del evento.
1 import java.awt.event.*;
2
3 public class InterrupcionDeVentana1 implements
WindowListener {
4
5 public void windowOpened(WindowEvent e) {
6 System.out.println("Ventana " + e.getWindow().getName()
+ " abierta");
7 }
8
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 8: EVENTOS 277
1 import java.awt.*;
2
3 public class PruebaEventosVentana1 {
4
5 public static void main(String[] args) {
6
7 Frame MiFrame = new Frame("Prueba eventos de ventana");
8 MiFrame.setSize(200,100);
9 MiFrame.show();
10
278 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
FocusEvent FocusListener
FocusAdapter
ActionEvent ActionListener
ItemEvent ItemListener
ActionListener
FocusListener
ItemListener
ActionEvent
FocusEvent
ItemEvent
En este apartado vamos a desarrollar dos ejemplos que muestran el uso del
interfaz ActionListener y el evento ActionEvent.
1 import java.awt.event.*;
2 import java.awt.*;
3
4 public class InterrupcionDeAccion1 implements
ActionListener {
5
6 public void actionPerformed(ActionEvent Evento){
7 Component Componente = (Component) Evento.getSource();
8 String AccionRealizada = Evento.getActionCommand();
9
10 System.out.println("Componente: " +
Componente.getName());
11 System.out.println("Suceso: " + AccionRealizada);
12 System.out.println();
13 }
14 }
1 import java.awt.*;
2
3 public class PruebaEventosAccion1 {
4
5 public static void main(String[] args) {
6
7 Frame MiFrame = new Frame("Prueba eventos de acción");
8 Panel MiPanel = new Panel(new GridLayout(3,1));
9
10 Button Boton = new Button("Etiqueta del boton");
11 TextField CampoDeTexto = new TextField("Texto del
campo",8);
12 List Lista = new List(3);
13 Lista.add("Opcion 1 de la lista");
Lista.add("Opcion 2 de la lista");
282 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
14 Lista.add("Opcion 3 de la lista");
Lista.add("Opcion 4 de la lista");
15
16 MiPanel.add(Boton);
17 MiPanel.add(CampoDeTexto);
18 MiPanel.add(Lista);
19
20 Boton.addActionListener(new InterrupcionDeAccion1());
21 CampoDeTexto.addActionListener(new
InterrupcionDeAccion1());
22 Lista.addActionListener(new InterrupcionDeAccion1());
23
24 MiFrame.add(MiPanel);
25 MiFrame.setSize(400,200);
26 MiFrame.show();
27
28 }
29 }
1 import java.awt.*;
2
3 public class PruebaEventosAccion2 {
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 8: EVENTOS 283
4
5 public static void main(String[] args) {
6
7 Frame MiFrame = new Frame("Prueba eventos de acción");
8 Panel MiPanel = new Panel();
9
10 Button Rojo = new Button("Rojo");
11 Button Verde = new Button("Verde");
12 Button Azul = new Button("Azul");
13
14 MiPanel.add(Rojo);
15 MiPanel.add(Verde);
16 MiPanel.add(Azul);
17
18 Rojo.addActionListener(new
InterrupcionDeAccion2(MiPanel));
19 Verde.addActionListener(new
InterrupcionDeAccion2(MiPanel));
20 Azul.addActionListener(new
InterrupcionDeAccion2(MiPanel));
21
22 MiFrame.add(MiPanel);
23 MiFrame.setSize(400,200);
24 MiFrame.show();
25
26 }
27 }
1 import java.awt.event.*;
2 import java.awt.*;
3
4 public class InterrupcionDeAccion2 implements
ActionListener {
5
6 private Panel PanelPrincipal;
7
8 InterrupcionDeAccion2 (Panel PanelPrincipal) {
9 this.PanelPrincipal = PanelPrincipal;
10 }
11
12 public void actionPerformed(ActionEvent Evento){
284 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
13
14 Color ColorFondo;
15
16 Button Componente = (Button) Evento.getSource();
17 String ColorSeleccionado = Componente.getLabel();
18
19 if (ColorSeleccionado=="Rojo")
20 ColorFondo = Color.red;
21 else
22 if (ColorSeleccionado=="Verde")
23 ColorFondo = Color.green;
24 else
25 ColorFondo = Color.blue;
26
27 PanelPrincipal.setBackground(ColorFondo);
28 }
29
30
31 }
En este apartado vamos a desarrollar dos ejemplos que muestran el uso del
interfaz FocusListener, el adaptador FocusAdapter y el evento FocusEvent.
1 import java.awt.*;
2
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 8: EVENTOS 285
1 import java.awt.event.*;
2
3 public class InterrupcionDeEnfoque1 implements
FocusListener {
4
5 public void focusGained(FocusEvent Evento){
6 System.out.println("Se ha entrado en el componente");
7 }
8
9 public void focusLost(FocusEvent Evento){
10 System.out.println("Se ha salido del componente");
11 }
12
13 }
1 import java.awt.*;
2
3 public class PruebaEventosEnfoque2 {
4
5 public static void main(String[] args) {
6
7 final int NUM_FILAS = 5;
8 Button[] Boton = new Button[NUM_FILAS];
9 TextField[] Campo = new TextField[NUM_FILAS];
10
11 Frame MiFrame = new Frame("Prueba eventos de enfoque");
12 Panel MiPanel = new Panel(new GridLayout(NUM_FILAS,2));
13
14 for (int i=0;i<NUM_FILAS;i++) {
15 Boton[i] = new Button("Boton "+i);
16 Campo[i] = new TextField(15);
17 MiPanel.add(Boton[i]);
18 MiPanel.add(Campo[i]);
19 Boton[i].addFocusListener(new InterrupcionDeEnfoque2());
20 Campo[i].addFocusListener(new InterrupcionDeEnfoque2());
21 }
22
23 MiFrame.add(MiPanel);
24 MiFrame.setSize(400,200);
25 MiFrame.show();
26
27 }
28 }
1 import java.awt.event.*;
2 import java.awt.*;
3
4 public class InterrupcionDeEnfoque2 extends FocusAdapter {
5
6 public void focusGained(FocusEvent Evento){
7 Component Componente = (Component) Evento.getSource();
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 8: EVENTOS 287
En este apartado vamos a desarrollar dos ejemplos que muestran el uso del
interfaz ItemListener y el evento ItemEvent. En el primer ejemplo utilizamos la clase
PruebaEventosElemento1 que crea cuatro cajas de texto (líneas 10 a 13) y les añade
la funcionalidad implementada en la clase InterrupcionDeElemento1 (líneas 20 a
23).
1 import java.awt.*;
2
3 public class PruebaEventosElemento1 {
4
5 public static void main(String[] args) {
6
7 Frame MiFrame = new Frame("Prueba eventos de
elemento");
288 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
1 import java.awt.event.*;
2 import java.awt.*;
3
4 public class InterrupcionDeElemento1 implements
ItemListener {
5
6 public void itemStateChanged(ItemEvent Evento){
7
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 8: EVENTOS 289
1 import java.awt.*;
2
3 public class PruebaEventosElemento2 {
4
5 public static void main(String[] args) {
6
7 Frame MiFrame = new Frame("Prueba eventos de
elemento");
8 Panel PanelPrincipal = new Panel(new
FlowLayout(FlowLayout.LEFT));
9 Panel PanelIzq = new Panel(new GridLayout(6,1));
10
11 Component[] Componentes = new Component[8];
290 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
12
13 Checkbox Diesel = new Checkbox("Diesel", true);
14 Checkbox AsientosDeportivos = new Checkbox("Asientos
15 deportivos", false);
16 Checkbox TapiceriaCuero = new Checkbox("Tapiceria de
cuero", false);
17 Checkbox LlantasAleacion = new Checkbox("Llantas de
aleación", false);
18 Checkbox PinturaMetalizada = new Checkbox("Pintura
metalizada", true);
19
20 Choice Llantas = new Choice();
21 Llantas.add("Tres radios");
22 Llantas.add("Cinco radios");
23 Llantas.add("Siete radios");
24 Llantas.setEnabled(false);
25
26 List ColoresMetalizados = new List(2);
27 ColoresMetalizados.add("Rojo");
28 ColoresMetalizados.add("Azul");
29 ColoresMetalizados.add("Verde");
30
31 Label Seleccionado = new Label("Seleccionado:");
32 Seleccionado.setForeground(Color.red);
33
34 Componentes[0] = Diesel;
35 Componentes[1] = AsientosDeportivos;
36 Componentes[2] = TapiceriaCuero;
37 Componentes[3] = LlantasAleacion;
38 Componentes[4] = PinturaMetalizada;
39 Componentes[5] = Llantas;
40 Componentes[6] = ColoresMetalizados;
41 Componentes[7] = Seleccionado;
42
43 PanelPrincipal.add(PanelIzq);
44 PanelPrincipal.add(ColoresMetalizados);
45 PanelPrincipal.add(Llantas);
46
47 PanelIzq.add(Diesel);
48 PanelIzq.add(AsientosDeportivos);
49 PanelIzq.add(TapiceriaCuero);
50 PanelIzq.add(LlantasAleacion);
51 PanelIzq.add(PinturaMetalizada);
52 PanelIzq.add(Seleccionado);
53
54 Diesel.addItemListener(new
InterrupcionDeElemento2(Componentes));
55 AsientosDeportivos.addItemListener(new
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 8: EVENTOS 291
InterrupcionDeElemento2(Componentes));
56 TapiceriaCuero.addItemListener(new
InterrupcionDeElemento2(Componentes));
57 LlantasAleacion.addItemListener(new
InterrupcionDeElemento2(Componentes));
58 PinturaMetalizada.addItemListener(new
InterrupcionDeElemento2(Componentes));
59 Llantas.addItemListener(new
InterrupcionDeElemento2(Componentes));
60 ColoresMetalizados.addItemListener(new
InterrupcionDeElemento2(Componentes));
61
62 MiFrame.add(PanelPrincipal);
63 MiFrame.setSize(500,200);
64 MiFrame.show();
65
66 }
1 import java.awt.event.*;
2 import java.awt.*;
3
4 public class InterrupcionDeElemento2 implements
ItemListener {
5
6 Component[] Componentes = new Component[8];
292 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
7
8 InterrupcionDeElemento2(Component[] Componentes) {
9 this.Componentes = Componentes;
10 }
11
12 public void itemStateChanged(ItemEvent Evento){
13
14 int Estado = Evento.getStateChange();
15
16 if (Evento.getItem().equals("Llantas de aleación"))
17 if (Estado==ItemEvent.SELECTED)
18 Componentes[5].setEnabled(true);
19 else
20 Componentes[5].setEnabled(false);
21
22 if (Evento.getItem().equals("Pintura metalizada"))
23 if (Estado==ItemEvent.SELECTED)
24 Componentes[6].setVisible(true);
25 else
26 Componentes[6].setVisible(false);
27
28 if (Evento.getItem().equals("Asientos deportivos")) {
29 Checkbox Asientos = (Checkbox) Componentes[2];
30 if (Estado==ItemEvent.SELECTED) {
31 Asientos.setState(true);
32 Componentes[2].setEnabled(false);
33 }
34 else
35 Componentes[2].setEnabled(true);
36 }
37
38 Label Seleccionado = (Label) Componentes[7];
39 Seleccionado.setText(""+Evento.getItem());
40 }
41
42 }
CAPÍTULO 9
APLICACIONES DE EJEMPLO
-
Operando
Dígito . Dígito
GUICalculadora2
GUICalculadora1
Digitos Resultados
Operadores
1 import java.awt.Button;
2 import java.awt.Panel;
3 import java.awt.GridLayout;
4 import java.awt.Color;
5
6 public class Digitos {
7
8 private Panel MiPanel = new Panel();
9 private final int NUM_DIGITOS=12;
10 private Button[] Digito = new Button[NUM_DIGITOS];
11
12 Digitos(Color ColorBotones) {
13 GridLayout LayoutBotones = new GridLayout(4,3);
14 for (int fila=0;fila<3;fila++)
15 for (int col=0;col<3;col++)
16 Digito[fila*3+col] = new
Button(String.valueOf(fila*3+col));
17 Digito[9] = new Button("9");
18 Digito[10] = new Button(".");
19 Digito[11] = new Button("=");
20 MiPanel.setLayout(LayoutBotones);
21 for (int i=0;i<NUM_DIGITOS;i++) {
22 Digito[i].setBackground(ColorBotones);
23 MiPanel.add(Digito[i]);
24 }
25 }
26
27 Digitos() {
28 this(Color.lightGray);
29 }
30
31 public Panel DamePanel() {
32 return MiPanel;
33 }
34
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 9: APLICACIONES DE EJEMPLO 297
1 import java.awt.Button;
2 import java.awt.Panel;
3 import java.awt.GridLayout;
4 import java.awt.Color;
5
6 public class Operadores {
7
8 private Panel MiPanel = new Panel();
9 private final int NUM_OPERADORES=4;
10 private Button[] Operador = new Button[NUM_OPERADORES];
11
12 Operadores(Color ColorBotones) {
13 GridLayout LayoutBotones = new
GridLayout(NUM_OPERADORES,1);
14 Operador[0] = new Button("+");
15 Operador[1] = new Button("-");
16 Operador[2] = new Button("*");
17 Operador[3] = new Button("/");
18 MiPanel.setLayout(LayoutBotones);
19 for (int i=0;i<NUM_OPERADORES;i++) {
20 Operador[i].setBackground(ColorBotones);
21 MiPanel.add(Operador[i]);
22 }
23 }
24
25 Operadores() {
26 this(Color.lightGray);
27 }
28
29 public Panel DamePanel() {
30 return MiPanel;
31 }
32
33 public Button[] DameBotones() {
34 return Operador;
35 }
36
37 }
298 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
1 import java.awt.*;
2
3 public class Resultados {
4
5 private Panel MiPanel = new Panel();
6 private TextField Resultado = new TextField("",10);
7
8 Resultados(Color ColorEtiqueta) {
9 FlowLayout LayoutResultado = new
FlowLayout(FlowLayout.LEFT);
10 MiPanel.setLayout(LayoutResultado);
11 Resultado.setForeground(ColorEtiqueta);
12 MiPanel.add(Resultado);
13 Resultado.setEnabled(false);
14 }
15
16 Resultados() {
17 this(Color.black);
18 }
19
20 public Panel DamePanel() {
21 return MiPanel;
22 }
23
24 public TextField DameCampo() {
25 return Resultado;
26 }
27
28 }
1 import java.awt.*;
2
3 public class GUICalculadora1 {
4
5 GUICalculadora1() {
6 Frame MiMarco = new Frame();
7 Panel MiPanel = new Panel();
8 BorderLayout PuntosCardinales = new BorderLayout();
9 MiPanel.setLayout(PuntosCardinales);
10
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 9: APLICACIONES DE EJEMPLO 299
1 import java.awt.*;
2
3 public class GUICalculadora2 {
4
5 GUICalculadora2() {
6 Frame MiMarco = new Frame();
7 Panel MiPanel = new Panel();
8 FlowLayout TodoSeguido = new
FlowLayout(FlowLayout.CENTER);
9 MiPanel.setLayout(TodoSeguido);
10
11 Digitos PanelDigitos = new Digitos(Color.cyan);
12 Operadores PanelOperadores = new
Operadores(Color.green);
13 Resultados PanelResultados = new Resultados(Color.red);
14
15 MiMarco.add(MiPanel);
300 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
16 MiPanel.add(PanelOperadores.DamePanel());
17 MiPanel.add(PanelDigitos.DamePanel());
18 MiPanel.add(PanelResultados.DamePanel());
19
20 MiMarco.setSize(250,150);
21 MiMarco.setTitle("Calculadora");
22 MiMarco.setVisible(true);
23 }
24 }
Los dos primeros tipos de eventos van a recibir un tratamiento muy sencillo,
mientras que el tercer tipo, eventos de ratón, va a incorporar la mayor parte del
dinamismo de la aplicación.
1 import java.awt.event.*;
2
3 public class ControlVentana extends WindowAdapter {
4
5 public void windowClosing(WindowEvent EventoQueLlega){
6 System.exit(0);
7 }
8
9 }
1 import java.awt.event.*;
2 import java.awt.*;
3
4 public class ControlFoco implements FocusListener {
5
6 private Color ColorBoton;
7
8 ControlFoco(Color ColorBoton) {
9 this.ColorBoton = ColorBoton;
10 }
11
12 public void focusGained(FocusEvent EventoQueLlega){
13 Button Boton = (Button) EventoQueLlega.getSource();
14 Boton.setBackground(Color.green);
15 }
16
17 public void focusLost(FocusEvent EventoQueLlega){
18 Button Boton = (Button) EventoQueLlega.getSource();
19 Boton.setBackground(ColorBoton);
20 }
21
22 }
métodos mouseEntered (línea 26) y mouseExited (línea 31) realizan en esta clase la
misma acción que focusGained y focusLost en la clase anterior, de esta forma, el
color de los botones también varía al desplazarnos con el ratón.
1 import java.awt.event.*;
2 import java.awt.*;
3
4 public class ControlRaton extends MouseAdapter {
5
6 private TextField Resultado;
7 private Color ColorBoton;
8
9 ControlRaton(TextField Resultado,Color ColorBoton) {
10 this.Resultado = Resultado;
11 this.ColorBoton = ColorBoton;
12 }
13
14 public void mouseClicked(MouseEvent EventoQueLlega){
15 Button Boton = (Button) EventoQueLlega.getSource();
16 char Car = Boton.getLabel().charAt(0);
17 System.out.print(Car);
18 try {
19 Automata.CaracterIntroducido(Car);
20 } catch(OpcionErronea e) {
21 Resultado.setText(e.getMessage());
22 Boton.setBackground(Color.red);
23 }
24 }
25
26 public void mouseEntered(MouseEvent EventoQueLlega){
27 Button Boton = (Button) EventoQueLlega.getSource();
28 Boton.setBackground(Color.green);
29 }
30
31 public void mouseExited(MouseEvent EventoQueLlega){
32 Button Boton = (Button) EventoQueLlega.getSource();
33 Boton.setBackground(ColorBoton);
34 }
35 }
304 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
1 import java.awt.*;
2
3 public class GUICalculadora1 {
4
5 GUICalculadora1() {
6 Frame MiMarco = new Frame();
7 Panel MiPanel = new Panel();
8 BorderLayout PuntosCardinales = new BorderLayout();
9 MiPanel.setLayout(PuntosCardinales);
10
11 Digitos InstanciaDigitos = new Digitos(Color.orange);
12 Operadores InstanciaOperadores = new
Operadores(Color.magenta);
13 Resultados InstanciaResultados = new Resultados();
14
15 MiMarco.add(MiPanel);
16 MiPanel.add(InstanciaOperadores.DamePanel(),
BorderLayout.EAST);
17 MiPanel.add(InstanciaDigitos.DamePanel(),
BorderLayout.CENTER);
18 MiPanel.add(InstanciaResultados.DamePanel(),
BorderLayout.NORTH);
19
20 Button[] BotonesDigitos =
InstanciaDigitos.DameBotones();
21 Button[] BotonesOperadores =
InstanciaOperadores.DameBotones();
22 TextField Resultado = InstanciaResultados.DameCampo();
23 Automata InstanciaAutomata = new Automata(Resultado);
24
25 for (int i=0;i<BotonesDigitos.length;i++) {
26 BotonesDigitos[i].addMouseListener(new
27 ControlRaton(Resultado,Color.orange));
28 BotonesDigitos[i].addFocusListener(new
ControlFoco(Color.orange));
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 9: APLICACIONES DE EJEMPLO 305
29 }
30
31 for (int i=0;i<BotonesOperadores.length;i++) {
32 BotonesOperadores[i].addMouseListener(new
33 ControlRaton(Resultado,Color.magenta));
34 BotonesOperadores[i].addFocusListener(new
ControlFoco(Color.magenta));
35 }
36
37 MiMarco.addWindowListener(new ControlVentana());
38
39 MiMarco.setSize(150,150);
40 MiMarco.setTitle("Calculadora");
41 MiMarco.setVisible(true);
42 }
43
44 }
ControlRaton
Automata
OpcionErronea
306 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
GUICalculadora1
ControlFoco
ControlVentana
Digitos Resultados
ControlRaton
Automata
Operadores
OpcionErronea
... y el de un número:
-
Operando
Dígito . Dígito
pulsación y pulsación del usuario, por lo que debemos emplear propiedades que
tengan existencia durante toda la aplicación: no tendría sentido guardar el estado del
autómata, el valor de los operandos, etc. en variables locales al método
CaracterIntroducido.
Por ejemplo, si estamos en el estado 1 (línea 47) y nos llega un dígito (líneas
49 a 58), pasamos al estado 2 (tal y como marca el grafo de estados) y actualizamos
el visor de la calculadora (línea 60); si nos llega un carácter distinto a un dígito
(línea 62) nos encontramos ante un error del usuario, por lo que volvemos al estado
0 del autómata (línea 63) y levantamos la excepción OpcionErronea (línea 64).
1 import java.awt.TextField;
2
3 public class Automata {
4
5 private static byte Estado=0;
6 private static TextField Visor;
7 private static double Operando1=0d;
8 private static double Operando2=0d;
9 private static char Operador=' ';
10
11 Automata(TextField Visor) {
12 this.Visor = Visor;
13 }
14
15 public static void CaracterIntroducido(char Car) throws
OpcionErronea {
16 if (Visor.getText().equals("No valido"))
17 Visor.setText("");
18
19 switch(Estado) {
20
21 case 0:
22 switch(Car) {
23 case '-':
24 Estado=1;
25 Visor.setText(Visor.getText()+Car);
26 break;
27 case '0':
28 case '1':
29 case '2':
30 case '3':
31 case '4':
32 case '5':
33 case '6':
34 case '7':
310 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
35 case '8':
36 case '9':
37 Estado=2;
38 Visor.setText(Visor.getText()+Car);
39 break;
40 default:
41 Iniciar();
42 throw new OpcionErronea();
43 }
44 break;
45
46
47 case 1:
48 switch(Car) {
49 case '0':
50 case '1':
51 case '2':
52 case '3':
53 case '4':
54 case '5':
55 case '6':
56 case '7':
57 case '8':
58 case '9':
59 Estado=2;
60 Visor.setText(Visor.getText()+Car);
61 break;
62 default:
63 Iniciar();
64 throw new OpcionErronea();
65 }
66 break;
67
68
69 case 2:
70 switch(Car) {
71 case '.':
72 Estado=3;
73 Visor.setText(Visor.getText()+Car);
74 break;
75 case '+':
76 case '-':
77 case '*':
78 case '/':
79 Estado=5;
80 Operador=Car;
81 Operando1=Double.parseDouble(Visor.getText());
82 Visor.setText("");
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 9: APLICACIONES DE EJEMPLO 311
83 break;
84 case '0':
85 case '1':
86 case '2':
87 case '3':
88 case '4':
89 case '5':
90 case '6':
91 case '7':
92 case '8':
93 case '9':
94 Estado=2;
95 Visor.setText(Visor.getText()+Car);
96 break;
97 default:
98 Iniciar();
99 throw new OpcionErronea();
100 }
101 break;
102
103
104 case 3:
105 switch(Car) {
106 case '0':
107 case '1':
108 case '2':
109 case '3':
110 case '4':
111 case '5':
112 case '6':
113 case '7':
114 case '8':
115 case '9':
116 Estado=4;
117 Visor.setText(Visor.getText()+Car);
118 break;
119 default:
120 Iniciar();
121 throw new OpcionErronea();
122 }
123 break;
124
125
126 case 4:
127 switch(Car) {
128 case '+':
129 case '-':
130 case '*':
312 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
179 }
180 break;
181
182
183 case 6:
184 switch(Car) {
185 case '0':
186 case '1':
187 case '2':
188 case '3':
189 case '4':
190 case '5':
191 case '6':
192 case '7':
193 case '8':
194 case '9':
195 Estado=7;
196 Visor.setText(Visor.getText()+Car);
197 break;
198 default:
199 Iniciar();
200 throw new OpcionErronea();
201 }
202 break;
203
204
205 case 7:
206 switch(Car) {
207 case '.':
208 Estado=8;
209 Visor.setText(Visor.getText()+Car);
210 break;
211 case '=':
212 Estado=10;
213 Operando2=Double.parseDouble(Visor.getText());
214 double Resultado=ObtenerResultado();
215 Visor.setText(String.valueOf(Resultado));
216 Operando1=Resultado;
217 break;
218 case '0':
219 case '1':
220 case '2':
221 case '3':
222 case '4':
223 case '5':
224 case '6':
225 case '7':
226 case '8':
314 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
1 import java.awt.*;
2 import java.awt.event.*;
3
4 public class GUIEditor {
5
6 // Propiedades de la clase
7
8 GUIEditor(Color ColorFondoEdicion) {
9
10 PreparaMenus();
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 9: APLICACIONES DE EJEMPLO 319
11 PreparaZonaInferior();
12 Colores ZonaColores = new Colores(NUM_COLORES);
13 Button[][] Botones = ZonaColores.DameBotones();
14
15 // definición del interfaz grafico de usuario (GUI)
16
17 // Enlace de los components con las clases de
// tratamiento de eventos
18
19 }
20
21
22 GUIEditor() {
23 this(Color.white);
24 }
25
26
27 private void PreparaMenus() {
28
29 // Defincion y presentacion de los menus declarados
// previamete
30
31 }
32
33
34 private void PreparaZonaInferior() {
35 // Definicion y presentacion de los botones de radio y
// cajas de texto
36 }
37
38
39 private class CerrarVentana extends WindowAdapter {
40 public void windowClosing(WindowEvent e) {
41 System.exit(0);
42 }
43 }
44
45
46 private class EventosAccion implements ActionListener {
47 public void actionPerformed(ActionEvent e) {
48
49 // Tratamiento de las opciones de menu
50
51 } // actionPerformed
52 } // EventosAccion
53
54
55
320 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
9.2.4 Constructores
1 GUIEditor(Color ColorFondoEdicion) {
2
3 PreparaMenus();
4 PreparaZonaInferior();
5 Colores ZonaColores = new Colores(NUM_COLORES);
6 Button[][] Botones = ZonaColores.DameBotones();
7
8 PanelPrincipal.setBackground(new Color(255,255,128));
9 Buscar.setName("Busca");
10 AreaEdicion.setFont(new
Font("Serif",TipoFuente,TamanioFuente));
11 AreaEdicion.setBackground(ColorFondoEdicion);
12 if (ColorFondo.equals(Color.black))
13 AreaEdicion.setForeground(Color.white);
14 else
15 AreaEdicion.setForeground(Color.black);
16
17 PanelPrincipal.add(AreaEdicion,BorderLayout.CENTER);
18 PanelPrincipal.add(ZonaColores.DamePanel(),
BorderLayout.EAST);
19 PanelPrincipal.add(ZonaInferior,BorderLayout.SOUTH);
20
21 MiMarco.add(PanelPrincipal);
22 MiMarco.setSize(700,400);
23 MiMarco.setTitle("Editor de texto");
24 MiMarco.setVisible(true);
25
26 MiMarco.addWindowListener(new CerrarVentana());
27 Apariencia.addActionListener(new EventosAccion());
28 Tamanio.addActionListener(new EventosAccion());
29 Herramientas.addActionListener(new EventosAccion());
30 Buscar.addActionListener(new EventoBuscaReemplaza());
31 Reemplazar.addActionListener(new
EventoBuscaReemplaza());
32 ColorTexto.addItemListener(new EventosElemento());
33 ColorFondo.addItemListener(new EventosElemento());
34 for (int i=0;i<NUM_COLORES;i++)
35 for (int j=0;j<=3;j++)
36 Botones[i][j].addMouseListener(new EventosRaton());
37 }
38
39
324 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
40 GUIEditor() {
41 this(Color.white);
42 }
Las líneas 2 a 6 se utilizan para definir las opciones del menú Tamanio. Las
líneas 8 a 11 definen las opciones del menú Apariencia; obsérvese como una opción
de menú puede incluir a su vez un nuevo menú (línea 11). En las líneas 13 y 14 se
definen las dos opciones del menú Herramientas.
1 import java.awt.*;
2
3 public class Colores {
4
5 private int NumColores;
6 private Button[][] BotonesColores;
7 private Panel PanelColores = new Panel(new
GridLayout(NumColores,4));
8
9 Colores(int NumColores) {
10 this.NumColores=NumColores;
11 BotonesColores = new Button[NumColores][4];
12
13 for (int c=0;c<NumColores;c++) {
14 for (int col=0;col<=3;col++) {
15 BotonesColores[c][col] = new Button();
16 PanelColores.add(BotonesColores[c][col]);
17 }
18 int Factor = c*(255/NumColores);
19 BotonesColores[c][0].setBackground(new
Color(255,Factor,Factor));
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 9: APLICACIONES DE EJEMPLO 327
20 BotonesColores[c][1].setBackground(new
Color(Factor,255,Factor));
21 BotonesColores[c][2].setBackground(new
Color(Factor,Factor,255));
22 BotonesColores[c][3].setBackground(new
Color(Factor,Factor,Factor));
23 }
24 }
25
26 public Panel DamePanel() {
27 return PanelColores;
28 }
29
30 public Button[][] DameBotones() {
31 return BotonesColores;
32 }
33
34 }
38 return;
39 }
40 if (e.getActionCommand().equals("Muy grande")) {
41 TamanioFuente=30;
42 AreaEdicion.setFont(new
Font("Serif",TipoFuente,TamanioFuente));
43 return;
44 }
45 if (e.getActionCommand().equals("Todo mayúsculas")) {
46 AreaEdicion.setText(AreaEdicion.getText().
toUpperCase());
47 return;
48 }
49 if (e.getActionCommand().equals("Todo minúsculas")) {
50 AreaEdicion.setText(AreaEdicion.getText().
toLowerCase());
51 return;
52 }
53
54 } // actionPerformed
55
56 } // EventosAccion
28 }
29
30 return;
31 }
32 }
33 } // EventoBuscaReemplaza
La clase EventosRaton ha sido utilizada para crear todas las instancias de los
tratamientos de eventos de ratón de los botones de colores. El único método
redefinido del adaptador MouseAdapter (línea 1) ha sido mouseClicked (línea 3).
332 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
1.1 INTRODUCCIÓN
Entre las diversas ventajas que presenta Java, su independencia de la
plataforma en la que se van a ejecutar las aplicaciones resulta de especial utilidad
para servir de soporte a una de sus posibilidades más notables: la distribución de
programas asociándolos a páginas web y su ejecución a través de los navegadores.
La tendencia mostrada nos debe dar una idea de las dificultades por las que
pueden pasar los applets de Java para imponerse en el mercado, dificultades unidas a
la competencia que tienen con otras poderosas tecnologías web:
• El HTML dinámico (DHTML), que ofrece la posibilidad de “animar”
las páginas web e interactuar con todos los objetos del navegador.
• Aplicaciones tipo FLASH, que gracias a la implantación generalizada de
sus plug-in necesarios permiten grandes posibilidades dinámicas en las
páginas Web.
De esta forma, para que una página web visualice el applet “Applet1.class”
con una anchura de 400 pixels y una altura de 100 pixels, podemos crear el siguiente
fichero HTML:
1 <HTML>
2 <BODY>
3 <APPLET CODE="Applet1.class" WIDTH=400 HEIGHT=100>
4 <BODY>
5 </HTML>
Hay que tener en cuenta que el applet de Java se visualiza en la página web
como un elemento más, por lo que habitualmente se encontrará entre otros objetos
HTML:
1 <HTML>
2 <BODY>
3 <TABLE BORDER=1>
4 <TR>
5 <TD> A nuestra derecha tenemos un applet </TD>
6 <TD><APPLET CODE="Applet1.class" WIDTH=400 HEIGHT=100></TD>
7 <TD> A nuestra izquierda tenemos un applet </TD>
8 </TR>
9 </TABLE>
10 <BODY>
11 </HTML>
En el ejemplo mostrado, se crea una página web que contiene una tabla de
una fila y tres columnas. En la primera y la tercera columna se inserta un texto,
reservando la segunda para incluir el applet; el applet imprime el texto “Hola
mundo”.
4 © JESÚS BOBADILLA SANCHO
Una vez que sabemos que los applets deben extender la clase Applet, nuestra
clase Applet1 se definirá de la siguiente manera:
1 import java.applet.Applet;
2 public class Applet1 extends Applet {
3 }
1 import java.applet.Applet;
2 import java.awt.Label;
3
4 public class Applet1 extends Applet {
5
6 public void init() {
7 add(new Label("Hola mundo"));
8 }
9 }
+--java.awt.Container
|
+--java.awt.Panel
|
+--java.applet.Applet
Métodos que pueden ser invocados a lo largo del ciclo de vida de un applet
init() Se llama la primera vez que se carga el applet
start() Se le llama después del método init y cada vez que el navegador regresa a una
página en la que el applet está contenido
stop() Se le llama cada vez que el navegador abandona la página que contiene el
applet y también antes de la invocación del método destroy
destroy() Se llama antes de que se cierre el navegador
Los métodos init y destroy son llamados una sola vez durante el ciclo de
vida del applet. Los métodos start y stop son llamados al menos una vez:
1 import java.applet.Applet;
2 import java.awt.1;
6 © JESÚS BOBADILLA SANCHO
3
4 public class Applet2 extends Applet {
5
6 private String Mensaje="";
7 private Panel PanelSuperior = new Panel();
8 private Panel PanelInferior = new Panel();
9 private Label EtiquetaSuperior=new Label();
10 private Label EtiquetaInferior=new Label();
11
12 public void init() {
13 this.setLayout(new GridLayout(2,1));
14 this.add(PanelSuperior);
15 this.add(PanelInferior);
16 PanelSuperior.add(EtiquetaSuperior);
17 PanelInferior.add(EtiquetaInferior);
18 EtiquetaSuperior.setText("Applet Cargado");
19 }
20
21 public void start() {
22 EtiquetaInferior.setText("Applet Inicializado");
23 }
24
25 }
Una vez que hemos leído el/los parámetros, podemos hacer que el applet se
comporte de manera diferente según sea su valor. Pongamos un ejemplo en el que se
utiliza esta posibilidad: un usuario recibe una página web en la que puede
seleccionar un mes en dos listas desplegables (año y mes); la página se procesa en el
servidor (con servlets, CGI, ASP, PHP, etc.) y le devuelve al usuario una página web
con los dos parámetros numéricos (año y mes) y el applet asociado que mostrará en
forma de calendario el mes seleccionado.
Las etiquetas PARAM se sitúan dentro del ámbito de las etiquetas APPLET.
En el ejemplo del applet calendario (de un mes), una página web podría tener la
siguiente disposición para agosto del 2005:
1 <HTML>
2 <BODY>
3 <APPLET CODE="CalendarioMes.class" HEIGHT=200 WIDTH=200>
4 <PARAM NAME=Mes VALUE=8>
5 <PARAM NAME=Anio VALUE=2005>
6 </APPLET>
7 <BODY>
8 </HTML>
1 import java.applet.Applet;
2 import java.awt.Label;
3
4 public class CalendarioMes extends Applet {
5
6 public void init() {
8 © JESÚS BOBADILLA SANCHO
1 import java.applet.Applet;
2 import java.awt.*;
3 import java.awt.event.*;
4
5 public class PaletaColores extends Applet {
6
7 private Colores Paleta;
8 private Button[][] Botones;
9 private TextArea AreaDeTexto;
10
© JESÚS BOBADILLA SANCHO 9
1 <HTML>
2 <BODY>
3 <APPLET CODE="PaletaColores.class" HEIGHT=300 WIDTH=300>
4 <PARAM NAME=NumeroDeColores VALUE=32>
5 </APPLET>
6 <BODY>
7 </HTML>
8 import java.awt.*;
9
10 public class Colores {
11
12 private int NumColores;
13 private Button[][] BotonesColores;
14 private Panel PanelColores = new
15 Panel(new GridLayout(NumColores,4));
16
17 Colores(int NumColores) {
18 this.NumColores=NumColores;
19 BotonesColores = new Button[NumColores][4];
20
21 for (int c=0;c<NumColores;c++) {
22 for (int col=0;col<=3;col++) {
23 BotonesColores[c][col] = new Button();
24 PanelColores.add(BotonesColores[c][col]);
25 }
26 int Factor = c*(255/NumColores);
27 BotonesColores[c][0].setBackground(new
28 Color(255,Factor,Factor));
29 BotonesColores[c][1].setBackground(new
30 Color(Factor,255,Factor));
31 BotonesColores[c][2].setBackground(new
32 Color(Factor,Factor,255));
33 BotonesColores[c][3].setBackground(new
34 Color(Factor,Factor,Factor));
35 }
36 }
37
38 public Panel DamePanel() {
39 return PanelColores;
40 }
41
42 public Button[][] DameBotones() {
43 return BotonesColores;
44 }
45
46 }
© JESÚS BOBADILLA SANCHO 11
Método Acción
URL getDocumentBase() Devuelve la dirección del directorio donde se
encuentra la página web que contiene el applet
URL getCodeBase() Devuelve la dirección completa (directorio+nombre de
la página web) donde se encuentra la página web que
contiene el applet
void resize(int Anchura, int Altura) Establece dinámicamente el tamaño del applet
void play(URL Direccion) Hace sonar el fichero de audio situado en Direccion
AudioClip getAudioClip (URL d) Devuelve el audio situado en la dirección especificada
Image getImage(URL Direccion) Devuelve la imagen situada en la dirección
especificada
boolean isActive() Indica si el applet está activo
void showStatus(String Mensaje) Sitúa ‘Mensaje’ en la barra de estado del navegador
String getAppletInfo() Devuelve la información que se suministre en el
método que sobrescriba a éste.
CAPÍTULO 2
PROGRAMACIÓN CONCURRENTE:
THREADS
2.1 INTRODUCCIÓN
Todos los programas Java que hemos visto hasta ahora se ejecutan de
manera independiente a otros programas Java que podamos tener en nuestro sistema.
Si quisiéramos, por ejemplo, desarrollar una aplicación Telefono, tendríamos que
programar estas dos actividades:
• Recoger sonidos con un micrófono y enviarlos en tiempo real a otro
ordenador.
• Recibir los sonidos que nos llegan desde otro ordenador y reproducirlos por
los altavoces.
con el programa que los recibe y los manda a los altavoces; de esta manera,
podemos ejecutar toda la funcionalidad desde una sola consola.
Ejemplos:
public class SeEjecutaConcurrentemente extends Thread
public class SeEjecutaConcurrentemente implements Runnable
1 import java.util.Random;
2
3 public class ThreadBasico implements Runnable {
4
5 private String Frase;
6 private Random Aleatorio;
7
8 public ThreadBasico (String Frase) {
9 this.Frase = Frase;
10 Aleatorio = new Random();
11 } // Constructor
12
13 public void run() {
14 try {
15 do {
16 System.out.println (Frase);
17 Thread.sleep( (long) (Math.abs(Aleatorio.nextInt())
18 % 500));
19 } while (true);
20 } catch (InterruptedException e) {}
21 } // run
22
23 } // class
LetrasHilos
CHilo
18 © JESÚS BOBADILLA SANCHO
1 import java.util.Random;
2
3 public class CHilo implements Runnable {
4 private String Caracter;
5
6 public CHilo (String Caracter) {
7 this.Caracter = Caracter;
8 }
9
10 public void run() {
11 try {
12 Thread.sleep( (long)
13 (Math.abs(new Random().nextInt())%1000));
14 System.out.print(Caracter);
15 } catch (InterruptedException e) {}
16 }
17
18 }
1 .....
2 if (Semaforo.equals(”Verde”)) {
3 PermisoPaso();
20 © JESÚS BOBADILLA SANCHO
4 Semaforo=”Rojo”
5 }
6 .......................
Método Acción
void start() Provoca el comienzo de la ejecución del hilo.
void run() Se ejecuta automáticamente tras start, cuando el hilo se ha
construido a partir del interfaz Runnable (o la clase
Thread).
static void sleep(long ms) Detiene la ejecución del hilo durante, al menos, los
milisegundos indicados
void destroy() Elimina el hilo sin liberara recursos
void setPriority(int Prioridad) Establece una prioridad para el hilo (MAX_PRIORITY,
MIN_PRIORITY, NORM_PRIORITY)
int getPriority() Indica la prioridad del hilo
final void join() Espera a que este hilo termine
static Thread currentThread() Devuelve un apuntador al hilo que se está ejecutando
boolean isAlive() Indica si el hilo ha sido arrancado y todavía no ha
terminado
void setDaemon(boolean on) Establece el hilo como demonio o como usuario. Los hilos
demonio están supeditados a los hilos que los han creado,
de tal manera que cuando el creador termina, sus hijos
“demonio” también finalizan
public final bolean isDaemon() Indica si el hilo es de tipo demonio o usuario
void setName(String name) Asigna un nombre al hilo
String getName() Devuelve el nombre del hilo
LECCIÓN 3
STREAMS Y FICHEROS
3.1 INTRODUCCIÓN
Los ficheros y “streams” se utilizan en Java haciendo uso del paquete
java.io , que contiene una gran cantidad de interfaces y clases. En este apartado
trataremos las clases más utilizadas, que nos permitirán realizar lecturas y escrituras
en ficheros secuenciales y aleatorios.
Método Descripción
int read() Lee un byte del fichero
int read(byte[] b) Lee hasta b.length bytes del fichero, depositándolos en
la matriz b (devuelve el número de bytes leidos)
int read(byte[] b, int off, int len) Lee hasta len bytes del fichero, depositándolos en la
matriz b, a partir de off (devuelve el número de bytes
leidos)
void write(int b) Escribe el byte especificadoen el fichero
void write(byte[] b) Escribe b.length bytes en el fichero, tomándolos de la
matriz b
void write(byte[] b, int off, int len) Escribe len bytes en el fichero, obteniéndolos de la
matriz b, a partir de off
close() Cierra el fichero y libera los recursos del sistema
asociados con el stream.
1 import java.io.*;
2
3 public class LeeFichero {
4
5 public static void main(String[] argumentos) {
6 final int TAMANIO_BUFFER = 64;
7 byte buffer[] = new byte[TAMANIO_BUFFER];
8 int NumBytes;
9
10 try {
11 FileInputStream FicheroOrigen =
12 new FileInputStream("LeeFichero.java");
13
14 try {
15 do {
16 NumBytes = FicheroOrigen.read(buffer);
17 System.out.print(new
18 String(buffer,0,NumBytes));
19 } while (NumBytes == TAMANIO_BUFFER);
20 FicheroOrigen.close();
21 } catch (IOException e){
26 © JESÚS BOBADILLA SANCHO
1 import java.io.*;
2
3 public class EscribeFichero {
4
5 public static void main(String[] argumentos) {
6 final int TAMANIO_BUFFER = 64;
7 byte buffer[] = new byte[TAMANIO_BUFFER];
8 int NumBytes;
9
10 try {
11 FileOutputStream FicheroDestino = new
12 FileOutputStream("Salida.txt");
13
14 try {
15 do {
16 NumBytes = System.in.read(buffer);
17 FicheroDestino.write(buffer,0,NumBytes);
18 } while (buffer[0] !=
19 Character.LINE_SEPARATOR);
20 FicheroDestino.close();
21 } catch (IOException e){
22 System.out.println("Error escribiendo
23 los datos o cerrando el fichero");
24 }
25
26
27 } catch (FileNotFoundException e) {
28 System.out.println("Fichero no encontrado");
29 }
30
31 }
32
33 }
28 © JESÚS BOBADILLA SANCHO
Veamos cada una de estas tres clases: CopiaFichero se encarga, ante todo,
de la lectura y escritura de los ficheros. Su constructor (línea 5) admite en sus
parámetros el nombre de los ficheros origen y destino, que serán utilizados en las
líneas 11 a 14 para crear instancias de FileOutputStream y FileInputStream.
1 import java.io.*;
2
3 abstract public class CopiaFichero {
4
5 CopiaFichero(String NombreOrigen, String NombreDestino) {
6 final int TAMANIO_BUFFER = 64;
7 byte buffer[] = new byte[TAMANIO_BUFFER];
8 int NumBytes;
9
10 try {
11 FileOutputStream FicheroDestino = new
12 FileOutputStream(NombreDestino);
13 FileInputStream FicheroOrigen = new
14 FileInputStream(NombreOrigen);
15
16 try {
17 do {
18 NumBytes = FicheroOrigen.read(buffer);
19 buffer = Procesa(buffer,NumBytes);
20 FicheroDestino.write(buffer,0,NumBytes);
21 } while (NumBytes == TAMANIO_BUFFER);
22 FicheroOrigen.close();
23 FicheroDestino.close();
24 } catch (IOException e){
25 System.out.println(e.toString());
26 }
27
28 } catch (FileNotFoundException e) {
29 System.out.println("Fichero no encontrado");
30 }
31
32 }
33
34 abstract public byte[] Procesa(byte[] buffer,
35 int NumBytes);
36
37 }
En este momento, para probar el ejemplo, solo nos resta hacer uso del
método main, creando una instancia de la clase CopiaMayusculas. La clase
CopiaMayusculasPrincipal realiza este sencillo cometido:
El parámetro modo puede tomar 4 valores diferentes, los más utilizados son:
“r” para lectura y “rw” para lectura y escritura.
Método Descripción
void close() Cierra el fichero y libera sus recursos asociados
long getFilePointer() Proporciona el desplazamiento actual de la posición de lectura
/escritura del fichero
long length() Devuelve la longitud del fichero (en bytes)
int read() Lee un byte
int read(byte[] b) Lee hasta b.length() bytes del fichero
int read(byte[] b, int off, Lee hasta len bytes del fichero, empezando a colocarlos a partir
int len) de off
boolean readBoolean() Lee un valor booleano
byte readByte() Lee un byte (con signo)
char readChar() Lee un carácter
double readDouble() Lee un double
float readFloat() Lee un float
int readInt() Lee un entero
long readLong() Lee un long
short readShort() Lee un short
String readLine() Lee un String
void write(int b) Escribe un byte
void write (byte[] b) Escribe b.length() bytes en el fichero
void write (byte[] b, int Escribe len bytes del fichero, empezando a tomarlos a partir de
off, int len) off
void Escribe un valor booleano
writeBoolean(boolean v)
void writeByte(int v) Escribe un byte (con signo)
void writeChar(int v) Escribe un carácter
void writeDouble(double Escribe un double
v)
void writeFloat(float v) Escribe un float
void writeInt(int v) Escribe un entero
32 © JESÚS BOBADILLA SANCHO
Una vez invocado el método GeneraPrimos (línea 11), se crea una instancia
de la clase RandomAccesFile (línea 13) con modo de lectura/escritura (línea 14); tras
ello, nos metemos en un bucle (línea 16) que itera tantas veces como primos se han
calculado. En cada iteración se invoca al método writeInt (línea 17).
1 import java.io.*;
2
3 public class EscribeAleatorio {
4
5 private int NumPrimos;
6 private int[] Primos;
7
8 EscribeAleatorio(int NumPrimos) {
9 this.NumPrimos = NumPrimos;
10 Primos = new int[NumPrimos];
11 GeneraPrimos(NumPrimos);
12 try {
13 RandomAccessFile FicheroPrimos = new
14 RandomAccessFile("Primos.txt", "rw");
15 try {
16 for (int i=0;i<NumPrimos;i++)
17 FicheroPrimos.writeInt(Primos[i]);
18 FicheroPrimos.close();
19 } catch (IOException e){
20 System.out.println("Error escribiendo los
21 datos o cerrando el fichero");
© JESÚS BOBADILLA SANCHO 33
22 }
23 } catch (FileNotFoundException e) {
24 System.out.println("Fichero no encontrado");
25 }
26 }
27
28
29 private void GeneraPrimos(int NumPrimos) {
30 Primos[0] = 2;
31 int PrimosHallados = 1;
32 int PosiblePrimo = 3;
33 int Indice=0;
34 boolean Primo = true;
35
36 do {
37 while (Primo && (Indice<PrimosHallados)) {
38 if (PosiblePrimo % Primos[Indice] == 0)
39 Primo = false;
40 else
41 Indice++;
42 }
43
44 if (Primo) {
45 Primos[PrimosHallados] = PosiblePrimo;
46 PrimosHallados++;
47 }
48
49 Primo = true;
50 PosiblePrimo++;
51 Indice = 0;
52
53 } while (PrimosHallados<NumPrimos ); // while exterior
54
55 } // GeneraPrimos
56
57 } //clase
Para poder leer los últimos 50 números primos que hemos hallado,
escribimos la clase LeeAleatorio :
1 import java.io.*;
2
3 public class LeeAleatorio {
4
5 public static void main(String[] args) {
6 int Primo;
7 long LongitudFichero, Puntero;
8
9 try {
10 RandomAccessFile FicheroPrimos = new
11 RandomAccessFile("Primos.txt", "r");
12 try {
13 LongitudFichero = FicheroPrimos.length();
14 FicheroPrimos.seek(LongitudFichero/2);
15 Puntero = FicheroPrimos.getFilePointer();
16 while (Puntero<LongitudFichero) {
17 Primo = FicheroPrimos.readInt();
18 System.out.print(Primo+" ");
19 Puntero = FicheroPrimos.getFilePointer();
20 }
21 FicheroPrimos.close();
22 } catch (IOException e){
23 System.out.println("Error leyendo los datos
24 o cerrando el fichero");
25 }
26 } catch (FileNotFoundException e) {
27 System.out.println("Fichero no encontrado");
28 }
29 }
30
31 } //clase
© JESÚS BOBADILLA SANCHO 35
1 import java.awt.*;
2 import java.awt.event.*;
3 import java.io.*;
4
5 public class GUISistemaDeFicheros {
6
7 private Choice Ficheros;
8 private File Fichero;
9 private Checkbox PermisoEscritura;
10 private Checkbox PermisoLectura;
11 private Checkbox EsDirectorio;
12 private Checkbox EstaOculto;
13
14 GUISistemaDeFicheros() {
15 Frame MiMarco = new Frame();
16 Panel MiPanel = new Panel(new GridLayout(1,2));
17 Panel PanelInformacion = new
38 © JESÚS BOBADILLA SANCHO
18 Panel(new GridLayout(4,1));
19 PanelInformacion.setBackground(Color.green);
20 PermisoEscritura = new
21 Checkbox("Permiso de escritura");
22 PermisoEscritura.setEnabled(false);
23 PanelInformacion.add(PermisoEscritura);
24 PermisoLectura = new Checkbox("Permiso de lectura");
25 PermisoLectura.setEnabled(false);
26 PanelInformacion.add(PermisoLectura);
27 EsDirectorio = new Checkbox("Directorio");
28 EsDirectorio.setEnabled(false);
29 PanelInformacion.add(EsDirectorio);
30 EstaOculto = new Checkbox("Oculto");
31 EstaOculto.setEnabled(false);
32 PanelInformacion.add(EstaOculto );
33
34 Ficheros = new Choice();
35 Ficheros.setBackground(Color.green);
36
37 Fichero = new File("c:/");
38 EstableceLista(Fichero.list());
39 Ficheros.addItemListener(new ElementoSeleccionado());
40
41 MiPanel.add(Ficheros);
42 MiPanel.add(PanelInformacion);
43 MiMarco.add(MiPanel);
44 MiMarco.setSize(400,200);
45 MiMarco.setTitle("Navegación por el sistema
46 de ficheros");
47 MiMarco.setVisible(true);
48 }
49
50 private void EstableceLista(String[] NombreFicheros) {
51 Ficheros.removeAll();
52 if (Fichero.getParent()!=null)
53 Ficheros.add("../");
54 for (int i=0;i<NombreFicheros.length;i++)
55 Ficheros.add(NombreFicheros[i]);
56 }
57
58 private class ElementoSeleccionado implements
59 ItemListener {
60 public void itemStateChanged(ItemEvent Evento){
61 String Camino=Fichero.getAbsolutePath()+"/"+
62 Ficheros.getSelectedItem();
63 Fichero = new File(Camino);
64 if (Fichero.isDirectory()){
65 EstableceLista(Fichero.list());
66 Ficheros.setBackground(Color.green);
© JESÚS BOBADILLA SANCHO 39
67 }
68 else
69 Ficheros.setBackground(Color.orange);
70
71 PermisoEscritura.setState(Fichero.canWrite());
72 PermisoLectura.setState(Fichero.canRead());
73 EsDirectorio.setState(Fichero.isDirectory());
74 EstaOculto.setState(Fichero.isHidden());
75 }
76
77 }
78
79 }
LECCIÓN 4
COMUNICACIONES BASADAS EN EL
PROTOCOLO TCP
4.1 INTRODUCCIÓN
El protocolo TCP (Transmisión Control Protocol) funciona en el nivel de
transporte, basándose en el protocolo de red IP (Internet Protocol). IP proporciona
comunicaciones no fiables y no basadas en conexión, muy dependientes de
saturaciones en la red, caídas de nodos, etc. Por el contrario, TCP está orientado a
conexión y proporciona comunicaciones fiables basadas en mecanismos de red que
gestionan el control de flujo de paquetes y de congestión en los nodos.
Para identificar el destino de los paquetes de datos, los sockets utilizan los
conceptos de dirección y puerto. La dirección se refiere a la máquina a la que se
dirigen los datos; se determina gracias a la resolución de nombres que proporcionan
los DNS o simplemente aportando al socket, de manera directa, la dirección IP del
nodo destino.
Puesto que una misma máquina (nodo) puede hacerse cargo de recoger
varias comunicaciones diferentes de datos (habitualmente ligadas a distintos
servicios), existe la necesidad de proporcionar un mecanismo que nos permita
distinguir los paquetes que llegan relacionados con los distintos servicios ofrecidos
(correo, news, web, etc.): este mecanismo son los puertos. Los puertos se
representan con valores enteros, que no deben coincidir para diferentes servicios.
GetOutputStream() GetInputStream()
Una vez definidas instancias de este tipo de clases, nos basta con emplear
los métodos de escritura y lectura de datos que mejor se adapten a nuestras
necesidades:
Flujo.writeBytes("Línea de texto");
int BytesLeidos = Flujo.read(Mensaje);
© JESÚS BOBADILLA SANCHO 45
1 import java.net.Socket;
2 import java.io.*;
3 import java.net.UnknownHostException;
4
5 public class TCPClienteHolaMundo {
6
7 public static void main(String[] args) {
8 OutputStream FlujoDeSalida;
9 DataOutputStream Flujo;
10 try {
11 Socket SocketCliente = new Socket("localhost",
12 8000);
13
14 FlujoDeSalida = SocketCliente.getOutputStream();
15 Flujo = new DataOutputStream(FlujoDeSalida);
16 Flujo.writeBytes("Hola Mundo");
17
18 SocketCliente.close();
19 } catch (UnknownHostException e) {
20 System.out.println("Referencia a host
21 no resuelta");
22 } catch (IOException e) {
23 System.out.println("Error en
24 las comunicaciones");
25 } catch (SecurityException e) {
26 System.out.println("Comunicacion no permitida
27 por razones de seguridad");
28 }
29 }
30
31 }
46 © JESÚS BOBADILLA SANCHO
1 import java.net.ServerSocket;
2 import java.net.Socket;
3 import java.io.*;
4
5 public class TCPServidorHolaMundo {
6
7 public static void main(String[] args) {
8 byte[] Mensaje=new byte[80];
9 InputStream FlujoDeEntrada;
10 DataInputStream Flujo;
11 try {
12 ServerSocket SocketServidor = new
13 ServerSocket(8000);
14 Socket ComunicaConCliente = SocketServidor.accept();
15
16 System.out.println("Comunicacion establecida");
17 FlujoDeEntrada =
© JESÚS BOBADILLA SANCHO 47
18 ComunicaConCliente.getInputStream();
19 Flujo = new DataInputStream(FlujoDeEntrada);
20 int BytesLeidos = Flujo.read(Mensaje);
21 System.out.println(new String(Mensaje));
22
23 ComunicaConCliente.close();
24 SocketServidor.close();
25
26 } catch (IOException e) {
27 System.out.println("Error en las comunicaciones");
28 System.exit(0);
29 } catch (SecurityException e) {
30 System.out.println("Comunicacion no permitida por
31 razones de seguridad");
32 System.exit(0);
33 }
34
35 }
36
37 }
Finalmente se imprime por consola (línea 21) el texto que nos llega
(esperamos “Hola Mundo”) y cerramos los sockets utilizados (líneas 23 y 24).
Tras ejecutar cada programa en una consola diferente, las siguientes figuras
muestran el correcto funcionamiento de nuestras clases. Nótese que debemos
ejecutar en primer lugar la clase servidor, o nos encontraremos con una excepción de
tipo IOException en el cliente, tal y como mostramos a continuación.
48 © JESÚS BOBADILLA SANCHO
1 import java.net.Socket;
2 import java.io.*;
3 import java.net.UnknownHostException;
4
© JESÚS BOBADILLA SANCHO 49
1 import java.net.ServerSocket;
2 import java.net.Socket;
3 import java.io.*;
4
5 public abstract class TCPServidor {
6 private DataInputStream Flujo;
7
8 TCPServidor(int Puerto){
9 byte[] Mensaje=new byte[256];
10 InputStream FlujoDeEntrada;
11 try {
12 ServerSocket SocketServidor = new
13 ServerSocket(Puerto);
50 © JESÚS BOBADILLA SANCHO
Para leer frases del teclado creamos un objeto Teclado de tipo InputStream,
asignándolo a System.in (entrada estándar del sistema), todo ello en la línea 12. En la
línea 16 utilizamos el método read para leer una secuencia de hasta 256 caracteres
(línea 10) introducidos por el teclado.
1 import java.io.*;
2
3 public class TCPTeletipoCliente extends TCPCliente {
4
5 TCPTeletipoCliente(String Host, int Puerto) {
6 super(Host, Puerto);
7 }
8
9 public void Comunicacion (DataOutputStream Flujo) {
10 byte[] Valor = new byte[256];
11 int NumBytesLeidos = 0;
12 InputStream Teclado = System.in;
13 String Mensaje;
14 do {
15 try {
16 NumBytesLeidos = Teclado.read(Valor);
17 }
18 catch (IOException e){
19 System.out.println("Error en la entrada de datos
20 por consola");
21 }
22 try {
23 Flujo.write(Valor,0,NumBytesLeidos);
24 }catch (IOException e) {
25 System.out.println("Error en la escritura de
26 datos a la linea");
52 © JESÚS BOBADILLA SANCHO
27 }
28 Mensaje = new String(Valor);
29 Mensaje = Mensaje.substring(0,NumBytesLeidos-2);
30
31 } while (!Mensaje.equals("Fin"));
32 }
33
34 }
1 import java.io.*;
2
3 public class TCPTeletipoServidor extends TCPServidor {
4
5 TCPTeletipoServidor(int Puerto) {
6 super(Puerto);
7 }
8
9 public void Comunicacion (DataInputStream Flujo) {
10 byte[] buffer = new byte[256];
11 int BytesLeidos=0;
12 String Mensaje;
13 do {
14 try {
15 BytesLeidos = Flujo.read(buffer);
16 } catch (IOException e) {
17 System.out.println("Error en la lectura de
18 datos por linea");
19 }
20 Mensaje = new String(buffer);
21 Mensaje = Mensaje.substring(0,BytesLeidos-2);
22 System.out.println(Mensaje);
23
24 } while (!Mensaje.equals("Fin"));
25 }
26
27 }
© JESÚS BOBADILLA SANCHO 53
Para poder ejecutar la aplicación “Teletipo (talk)” únicamente nos falta crear
las clases, cliente y servidor, que instancien a TCPTeletipoCliente y
TCPTeletipoServidor.
1 import java.io.*;
2 import java.awt.TextField;
3 import java.awt.event.*;
4 import java.net.*;
5
6 public class TCPTeletipoClienteConHilos extends Thread{
7
8 TextField AreaEntrada;
9 OutputStream FlujoDeSalida;
10 DataOutputStream Flujo;
11 Socket SocketCliente;
12 String Host;
13 int Puerto;
14
15
16 TCPTeletipoClienteConHilos(String Host, int Puerto,
17 TextField AreaEntrada) {
18 this.AreaEntrada = AreaEntrada;
19 this.Host = Host;
20 this.Puerto = Puerto;
21 }
22
23
24 public void run() {
25 try {
26 SocketCliente = new Socket(Host, Puerto);
27 FlujoDeSalida = SocketCliente.getOutputStream();
28 Flujo = new DataOutputStream(FlujoDeSalida);
29
30 } catch (UnknownHostException e) {
31 System.out.println("Referencia a host no
32 resuelta");
33 } catch (IOException e) {
34 System.out.println("Error en las
35 comunicaciones");
36 }
37 AreaEntrada.addActionListener(new TextoModificado());
38 }
39
40
41 private class TextoModificado implements
42 ActionListener {
43 public void actionPerformed(ActionEvent e) {
44 try {
45 Flujo.write(AreaEntrada.getText().getBytes());
46 } catch (IOException IOe) {
56 © JESÚS BOBADILLA SANCHO
El método Comunicacion recoge los mensajes que le llegan por la red (línea
20), los convierte en String (línea 25) y los visualiza en un campo de texto (línea
26). El objeto de tipo TextField se obtiene a través del constructor de la clase (línea
9). El método Comunicacion finaliza cuando llega el mensaje “Fin” (línea 28).
1 import java.io.*;
2 import java.awt.TextField;
3
4 public class TCPTeletipoServidorConHilos extends
5 TCPServidorConHilos {
6 TextField AreaSalida;
7
8 TCPTeletipoServidorConHilos(int Puerto,
9 TextField AreaSalida) {
10 super(Puerto);
11 this.AreaSalida = AreaSalida;
12 }
13
14 public void Comunicacion (DataInputStream Flujo) {
15 byte[] buffer = new byte[256];
16 int BytesLeidos=0;
17 String Mensaje;
18 do {
19 try {
20 BytesLeidos = Flujo.read(buffer);
21 } catch (IOException e) {
22 System.out.println("Error en la lectura de
23 datos por linea");
24 }
25 Mensaje = new String(buffer,0,BytesLeidos);
26 AreaSalida.setText(Mensaje);
27
28 } while (!Mensaje.equals("Fin"));
© JESÚS BOBADILLA SANCHO 57
29 }
30
31 }
1 import java.awt.*;
2
3 public class TCPTeletipoConHilos {
4
5 public static void main(String[] args) {
6 Frame MiMarco = new Frame();
7 Panel Visor = new Panel(new GridLayout(2,1));
8 Panel AreaEnviar = new Panel(new
9 FlowLayout(FlowLayout.LEFT));
10 Panel AreaRecibir = new Panel(new
11 FlowLayout(FlowLayout.LEFT));
12 TextField Entrada = new TextField(30);
13 TextField Salida = new TextField(30);
14
15 AreaEnviar.add(new Label("Enviado :"));
16 AreaEnviar.add(Entrada);
17 AreaRecibir.add(new Label("Recibido:"));
18 AreaRecibir.add(Salida);
19 Visor.add(AreaEnviar);
20 Visor.add(AreaRecibir);
58 © JESÚS BOBADILLA SANCHO
21 MiMarco.add(Visor);
22 MiMarco.setSize(400,90);
23 MiMarco.setTitle("Talk con TCP");
24 MiMarco.setVisible(true);
25
26 if (args.length==3) {
27 String HostRemoto = args[0];
28 int PuertoLocal = Integer.parseInt(args[2]);
29 int PuertoRemoto = Integer.parseInt(args[1]);
30 TCPTeletipoServidorConHilos InstanciaServidor = new
31 TCPTeletipoServidorConHilos(PuertoLocal,Salida);
32 TCPTeletipoClienteConHilos InstanciaCliente = new
33 TCPTeletipoClienteConHilos(HostRemoto,
34 PuertoRemoto,Entrada);
35 InstanciaServidor.start();
36 InstanciaCliente.start();
37 }
38 else {
39 System.out.println("Es necesario pasar tres
40 argumentos (host remoto, puerto remoto, puerto local)");
41 System.exit(0);
42 }
43
44 }
45
46 }
... Obtenemos
© JESÚS BOBADILLA SANCHO 59
1 import java.io.*;
2
3 public class TCPFicheroCliente extends TCPCliente {
4 private FileInputStream FicheroOrigen;
5
6 TCPFicheroCliente(String Host, int Puerto) {
7 super(Host, Puerto);
8 }
9
10 public void Comunicacion (DataOutputStream Flujo) {
11 final int TAMANIO_BUFFER = 256;
12 byte buffer[] = new byte[TAMANIO_BUFFER];
13 int NumBytesLeidos = 0;
14
15 try {
16 FicheroOrigen = new
17 FileInputStream("TCPCliente.java");
18 } catch (FileNotFoundException e) {
19 System.out.println("Fichero no encontrado");
20 System.exit(0);
21 }
22
23 try {
24 do {
60 © JESÚS BOBADILLA SANCHO
25 NumBytesLeidos = FicheroOrigen.read(buffer);
26 Flujo.write(buffer,0,NumBytesLeidos);
27 } while (NumBytesLeidos == TAMANIO_BUFFER);
28 FicheroOrigen.close();
29 } catch (IOException e){
30 System.out.println(e.getMessage());
31 }
32 }
33 }
1 import java.io.*;
2
3 public class TCPFicheroServidor extends TCPServidor {
4
5 TCPFicheroServidor(int Puerto) {
6 super(Puerto);
7 }
8
9 public void Comunicacion (DataInputStream Flujo) {
10 final int TAMANIO_BUFFER = 256;
11 byte buffer[] = new byte[TAMANIO_BUFFER];
12 int NumBytes=0;
13
14 try {
15 FileOutputStream FicheroDestino = new
16 FileOutputStream("Salida.txt");
17
18 try {
19 do {
20 NumBytes = Flujo.read(buffer);
21 FicheroDestino.write(buffer,0,NumBytes);
22 } while (NumBytes==TAMANIO_BUFFER);
23 FicheroDestino.close();
24 } catch (IOException e){
25 System.out.println("Error de
26 entrada/salida");
27 }
28
29 } catch (FileNotFoundException e) {
30 System.out.println("Fichero no encontrado");
31 }
32
33 }
34 }
© JESÚS BOBADILLA SANCHO 61
Para poder ejecutar estas clases únicamente nos falta instanciarlas desde
sendos métodos main. En la línea 5 de la clase TCPFicheroClientePrincipal
utilizamos directamente la dirección IP del nodo destino de la comunicación.
1 import java.net.*;
2 import java.io.*;
3
4 public class TCPClienteDuplexHolaMundo {
5
6 public static void main(String[] args) {
7 DataInputStream FlujoEntrada;
8 DataOutputStream FlujoSalida;
9 byte[] Mensaje=new byte[80];
10 int BytesLeidos=0, Frases=0;
11
12 try {
13 Socket SocketCliente = new Socket("localhost", 8000);
14
15 OutputStream FlujoDeSalida =
16 SocketCliente.getOutputStream();
17 InputStream FlujoDeEntrada =
18 SocketCliente.getInputStream();
19
20 FlujoEntrada = new DataInputStream(FlujoDeEntrada);
21 FlujoSalida = new DataOutputStream(FlujoDeSalida);
22
23 do {
24 try {
25 FlujoSalida.writeBytes("Hola terricola\n");
26 Frases++;
© JESÚS BOBADILLA SANCHO 63
27
28 BytesLeidos = FlujoEntrada.read(Mensaje);
29 } catch (IOException e) {
30 System.out.println("Error en la lectura de
31 datos");
32 System.exit(0);
33 }
34 System.out.print(new String(Mensaje,0,BytesLeidos));
35 } while (Frases!=20);
36
37 SocketCliente.close();
38
39 } catch (UnknownHostException e) {
40 System.out.println("Referencia a host no resuelta");
41 } catch (IOException e) {
42 System.out.println("Error en las comunicaciones");
43 }
44 }
45
46 }
1 import java.net.ServerSocket;
2 import java.net.Socket;
3 import java.io.*;
4
5 public class TCPServidorDuplexHolaMundo {
6
7 public static void main(String[] args) {
8 DataInputStream FlujoEntrada;
9 DataOutputStream FlujoSalida;
10 byte[] Mensaje=new byte[80];
11 int BytesLeidos=0, Frases=0;
12
13 try {
14 ServerSocket SocketServidor = new ServerSocket(8000);
15 Socket ComunicaConCliente = SocketServidor.accept();
16 System.out.println("Comunicacion establecida");
17
18 OutputStream FlujoDeSalida =
64 © JESÚS BOBADILLA SANCHO
19 ComunicaConCliente .getOutputStream();
20 InputStream FlujoDeEntrada =
21 ComunicaConCliente .getInputStream();
22
23 FlujoEntrada = new DataInputStream(FlujoDeEntrada);
24 FlujoSalida = new DataOutputStream(FlujoDeSalida);
25
26 do {
27 try {
28 BytesLeidos = FlujoEntrada.read(Mensaje);
29 } catch (IOException e) {
30 System.out.println("Error en la lectura de datos");
31 System.exit(0);
32 }
33 System.out.print(new String(Mensaje,0,BytesLeidos));
34 FlujoSalida.writeBytes("Hola humano\n");
35 Frases++;
36 } while (Frases!=20);
37
38
39 ComunicaConCliente.close();
40 SocketServidor.close();
41
42 } catch (IOException e) {
43 System.out.println("Error en las comunicaciones");
44 System.exit(0);
45 }
46
47 }
48
49
50 }
© JESÚS BOBADILLA SANCHO 65
ServerSocket
Métodos principales Acción
Socket accept() Espera a que se realice una conexión y devuelve un socket
para comunicarse con el cliente
void bind(SocketAddress a) Asigna la dirección establecida al socket creado con
accept, si no se utiliza este método se asigna
automáticamente una dirección temporal
void close() Cierra el socket
InetAddress getInetAddress() Devuelve la dirección a la que está conectada el socket
int getLocalPort() Devuelve el número de puerto asociado al socket
int getSoTimeout() Devuelve el valor en milisegundos que el socket espera al
establecimiento de comunicación tras la ejecución de
accept
void setSoTimeout(int ms) Asigna el número de milisegundos que el socket espera al
establecimiento de comunicación tras la ejecución de
accept
Socket
Métodos principales Acción
void bind(SocketAddress a) Asigna la dirección establecida al socket creado con
accept, si no se utiliza este método se asigna
automáticamente una dirección temporal
void close() Cierra el socket
void connect(SocketAddress a) Conecta el socket a la dirección de servidor establecida
void connect(SocketAddress a, Conecta el socket a la dirección de servidor establecida,
int ms) esperando un máximo de ms milisegundos
InetAddress getInetAddress() Devuelve la dirección a la que está conectada el socket
InputStream getInputStream() Devuelve el stream de entrada asociado al socket
int getLocalPort() Devuelve el número de puerto asociado al socket
OutputStream Devuelve el stream de salida asociado al socket
getOutputStream()
int getPort() Devuelve el valor del Puerto remoto al que está conectado
int getSoLinger() Devuelve el número de milisegundos que se espera a los
datos después de cerrar (close) el socket
int getSoTimeout() Devuelve el valor en milisegundos que el socket espera al
establecimiento de comunicación tras la ejecución de
accept
66 © JESÚS BOBADILLA SANCHO
COMUNICACIONES BASADAS EN EL
PROTOCOLO UDP
5.1 INTRODUCCIÓN
En este apartado se explican las características básicas del protocolo UDP
(User Datagram Protocol), que están relacionadas con buena parte de los conceptos
de IP y TCP. Estos conceptos se explican en el primer apartado dedicado a TCP
(Transmission Control Protocol)
Cada mensaje UDP puede albergar hasta 508 bytes, por lo que este
protocolo resulta especialmente adecuado para transmitir información que no ocupe
mucho tamaño; por otra parte, al no ser un protocolo fiable, las aplicaciones deben
tolerar la pérdida de datos, o bien hacerse cargo de las mismas.
1. new DatagramSocket
5. new DatagramPacket (...) 2. new DatagramPacket
(...) (...)
4. new DatagramSocket
(...)
DatagramSocket DatagramSocket
6. send 3. receive
Puerto destino
Puerto destino
Nodo destino
Una vez definidos los datos a enviar (buffer), el sobre con la dirección de
destino de la carta (Paquete) y el buzón de correos (MiSocket), estamos listos para
depositar el sobre en el buzón de correos: método send utilizado en la línea 14.
1 import java.net.*;
2
3 public class UDPEnvia {
4
5 public static void main(String args[]) {
6 try {
7 DatagramSocket MiSocket = new DatagramSocket();
8 byte[] buffer = new byte[15];
9 String Mensaje = "Hola Mundo";
10 buffer=Mensaje.getBytes();
11 DatagramPacket Paquete = new DatagramPacket(buffer,
12 Mensaje.length(),
13 InetAddress.getByName("localhost"),14000);
14 MiSocket.send(Paquete);
15 MiSocket.close();
16 } catch (Exception exc){
17 System.out.println ("Error");
18 } //try
19 }
20
21 } // UDPEnvia
1 import java.net.*;
2
3 public class UDPRecibe {
4
5 public static void main(String[] args) {
6 try {
7 DatagramSocket MiSocket = new DatagramSocket(14000);
8 byte[] buffer = new byte[15];
9 DatagramPacket Paquete = new DatagramPacket(buffer,
10 buffer.length);
11 MiSocket.receive(Paquete);
12 System.out.println(new String(Paquete.getData()));
13 MiSocket.close();
14 } catch (Exception e){
15 System.out.println ("Error");
16 }
17 } //main
18
19 } // UDPRecibe
Nuestros métodos van a estar basados, casi por completo, en las clases
desarrolladas en el apartado anterior (“Hola Mundo”), por lo que resultará muy fácil
su seguimiento. Gráficamente, los métodos Envia y Recibe adoptan el siguiente
esquema:
Mensaje
Mensaje
Tamaño Mensaje
Puerto
Host Destino
Tamaño Mensaje
Puerto Destino
Envia Recibe
1 import java.net.*;
2
3 public class TEnviaUDP {
4
5 public void Envia(String Mensaje, int TamanioMensaje,
6 String HostDestino,int Puerto) {
7 try {
8 DatagramSocket MiSocket = new DatagramSocket();
9 byte[] buffer = new byte[TamanioMensaje];
10 DatagramPacket Paquete;
11 buffer=Mensaje.getBytes();
12 Paquete = new DatagramPacket(buffer, Mensaje.length(),
13 InetAddress.getByName(HostDestino),Puerto);
14 MiSocket.send(Paquete);
15 MiSocket.close();
16 } catch (Exception exc){
17 System.out.println ("Error");
18 }
JESÚS BOBADILLA SANCHO 73
19 } // Envia
20
21 } // TEnviaUDP
1 import java.net.*;
2
3 public class TRecibeUDP {
4
5 DatagramSocket MiSocket;
6 DatagramPacket Paquete;
7 byte[] buffer;
8
9 public String Recibe(int Puerto,
10 int TamanioMaximoMensaje) {
11 try {
12 MiSocket = new DatagramSocket(Puerto);
13 buffer = new byte[TamanioMaximoMensaje];
14 Paquete = new DatagramPacket(buffer, buffer.length);
15 MiSocket.receive(Paquete);
16 MiSocket.close();
17 } catch (Exception e){
18 System.out.println ("Error");
19 } //try
20 return new String(Paquete.getData()).substring
21 (0,Paquete.getLength());
22 } // Recibe
23 } // TRecibeUDP
El método run (línea 94) de la clase TalkEnviar (línea 92) establece una
clase de tratamiento de eventos de acción RespuestaAEnviar (línea 95) asociada al
botón de envío BotonEnviar.
1 import java.awt.*;
2 import java.awt.event.*;
3
4 // ********************************************************
5 // * Servicio Talk *
6 // * nota: los puertos origen y destino se deben cruzar
7 // * en las dos instancias que se creen del *
8 // * talk, usar: java Talk PuertoOrigen PuertoDestino *
9 // ********************************************************
10
11 public class Talk {
12 static final int TamanioMaximoMensaje = 90;
13
14 TextArea AreaRecibir;
76 © JESÚS BOBADILLA SANCHO
15 TextArea AreaEnviar;
16 TextField HostDestino;
17 Button BotonEnviar;
18 String MensajeRecibido;
19 int PuertoOrigen, PuertoDestino;
20
21 TRecibeUDP InstanciaRecibeUDP;
22 TEnviaUDP InstanciaEnviaUDP;
23
24 public Talk(int PuertoOrigen, int PuertoDestino) {
25 this.PuertoOrigen = PuertoOrigen;
26 this.PuertoDestino = PuertoDestino;
27 InstanciaRecibeUDP = new TRecibeUDP();
28 InstanciaEnviaUDP = new TEnviaUDP();
29 Frame Marco = new Frame("Talk");
30 Panel panel = new Panel();
31 Label EtiquetaMensajeSaliente = new Label ("Mensaje
32 Saliente:");
33 Label EtiquetaMensajeEntrante = new Label ("Mensaje
34 Entrante:");
35 Label EtiquetaHostDestino = new Label ("Host destino");
36 AreaRecibir = new TextArea(3,24);
37 AreaEnviar = new TextArea(3,24);
38 HostDestino = new TextField("127.0.0.1");
39 BotonEnviar = new Button("Enviar");
40
41 Marco.setSize(250,280);
42 Marco.setLayout(new BorderLayout());
43 Marco.add("Center",panel);
44 panel.add(EtiquetaHostDestino);
45 panel.add(HostDestino);
46 panel.add(BotonEnviar);
47 panel.add(EtiquetaMensajeSaliente);
48 panel.add(AreaEnviar);
49 panel.add(EtiquetaMensajeEntrante);
50 panel.add(AreaRecibir);
51 Marco.show();
52
53 TalkRecibir HiloRecibir = new TalkRecibir();
54 TalkEnviar HiloEnviar = new TalkEnviar();
55
56 HiloRecibir.start();
57 HiloEnviar.start();
58
59 } // Constructor
60
61
62 public static void main(String[] args) {
63 if (args.length!=2) {
JESÚS BOBADILLA SANCHO 77
1 import java.awt.*;
2 import java.awt.event.*;
3
4 public class PruebaEnvia extends Object {
5
6 static final int TamanioMaximoMensaje = 20;
7 Frame Marco;
8 Panel panel;
9 Label EtiquetaMensaje;
10 TextField CampoMensaje;
11 TextField HostDestino;
12 TextField Puerto;
13 TEnviaUDP EnviaFrase;
14
15 public PruebaEnvia() {
16 Marco = new Frame("EnvioUDP");
17 panel = new Panel();
18 EtiquetaMensaje = new Label ("Mensaje: ");
19 CampoMensaje = new TextField(TamanioMaximoMensaje);
20 HostDestino = new TextField("127.0.0.1",15);
21 Puerto = new TextField("5000",4);
22 Marco.setSize(500,200);
23 Marco.add (panel);
24 panel.add (HostDestino);
25 panel.add (Puerto);
26 panel.add (EtiquetaMensaje);
27 panel.add (CampoMensaje);
28 Marco.show();
29 EnviaFrase = new TEnviaUDP();
30
31 CampoMensaje.addActionListener(new RespuestaAEnviar());
32 panel.addMouseMotionListener(new MovimientoDelRaton());
33 } // constructor
34
35
36 private class RespuestaAEnviar implements ActionListener {
37 public void actionPerformed(ActionEvent e) {
38 String Mensaje = CampoMensaje.getText();
80 © JESÚS BOBADILLA SANCHO
39 EnviaFrase.Envia(Mensaje,Mensaje.length(),
40 HostDestino.getText(),
41 Integer.parseInt(Puerto.getText()));
42 if (Mensaje.length() ==0)
43 System.exit(1); // Al mandar un mensaje vacio se
44 // abandona el programa
45 } // actionPerformed
46 } // RespuestaAEnviar
47
48 private class MovimientoDelRaton implements
49 MouseMotionListener {
50 public void mouseMoved(MouseEvent e) {
51 String Mensaje="*"+String.valueOf(e.getX())+
52 " "+String.valueOf(e.getY());
53 EnviaFrase.Envia(Mensaje,Mensaje.length(),
54 HostDestino.getText(),
55 Integer.parseInt(Puerto.getText()));
56
57 } // mouseMoved
58
59 public void mouseDragged(MouseEvent e) {
60 }
61
62 } // MovimientoDelRaton
63
64 public static void main(String[] args) {
65 PruebaEnvia MiClaseEnvia = new PruebaEnvia();
66 } //main
67
68 } // clase
1 import java.awt.*;
2
3 public class PruebaRecibe extends Object {
4
5 public PruebaRecibe() {
6 final int Puerto = 5000;
7 final int TamanioMaximoMensaje = 20;
8
9 String MensajeRecibido;
10 TRecibeUDP InstanciaRecibeUDP = new TRecibeUDP();
11 Frame Marco = new Frame("RecepcionUDP");
12 Panel panel = new Panel();
13 Label EtiquetaMensaje = new Label ("Mensaje:");
14 Label PosicionXY = new Label("");
15
16 Marco.setSize(200,80);
17 panel.setLayout(new GridLayout(2,1));
18 Marco.add(panel);
19 panel.add(EtiquetaMensaje);
20 panel.add(PosicionXY);
21 Marco.show();
22
23 do {
24 MensajeRecibido = InstanciaRecibeUDP.Recibe
25 (Puerto,TamanioMaximoMensaje);
26 try {
27 int i = MensajeRecibido.indexOf(" ");
28 if (i!=-1&&MensajeRecibido.indexOf("*")==0) {
29 String X = MensajeRecibido.substring(1,i);
30 String Y = MensajeRecibido.substring
31 (i+1,MensajeRecibido.length());
32 PosicionXY.setText("("+X+", "+Y+")");
33 }
34 else
35 EtiquetaMensaje.setText("Mensaje: "+MensajeRecibido);
36 } catch (Exception e){ }
37
38 } while (MensajeRecibido.length()!=0);
39
40 System.exit(1);
41 } // Constructor
42
43 public static void main(String[] args) {
44 PruebaRecibe MiClaseRecibe = new PruebaRecibe();
45 } //main
46
47 } // clase
82 © JESÚS BOBADILLA SANCHO
3
2
5 Servidor
Cliente 1
Lista FIFO
4 Mensaje ‘n'
Mensaje n-1
Mensaje 1
Cliente 2
Los programas cliente hacen peticiones periódicas al servidor (3) con el fin
de recibir todos los mensajes almacenados en la lista FIFO (4 y 5); de esta forma, los
usuarios pueden ver de manera automática los últimos mensajes recibidos en el
servidor del chat.
ChatServidor ChatCliente
Conversación ChatEnviar
ChatRecibir
TRecibeUDP TEnviaUDP
TRecibeUDP
1 import java.net.*;
2
3 public class TRecibeUDP extends Object {
4
5 DatagramSocket MiSocket;
6 DatagramPacket Paquete;
7 byte[] buffer;
8
9 String IPRemota="";
10
11 public synchronized String Recibe(int Puerto, int
12 TamanioMaximoMensaje,int TimeOut) {
13 try {
14 MiSocket = new DatagramSocket(Puerto);
15 MiSocket.setSoTimeout(TimeOut);
16 buffer = new byte[TamanioMaximoMensaje];
17 Paquete = new DatagramPacket(buffer, buffer.length);
18 MiSocket.receive(Paquete);
19
20 IPRemota = Paquete.getAddress().getHostAddress();
21 MiSocket.close();
22 } catch (Exception e){
84 © JESÚS BOBADILLA SANCHO
23 System.out.println ("Error");
24 } //try
25 return new String(Paquete.getData()).
26 substring(0,Paquete.getLength());
27 } // Recibe
28
29
30 public synchronized String DameIPRemota(){
31 return IPRemota;
32 }
33
34 } // TRecibeUDP
ChatServidor
cero) a que se reciba un mensaje (líneas 22 y 23); los mensajes que le llegan al
servidor pueden ser de 2 tipos diferentes:
• Proporcionan texto a insertar en la lista FIFO (caracterizados, en este
ejemplo, por contener un cero en el primer carácter del mensaje)
• Solicitan el envío del contenido de la lista FIFO (caracterizados, en este
ejemplo, por contener un uno en el primer carácter del mensaje)
0Hola Pedro
1xxxx
Servidor
11 Cliente 1
Mensaje1\nMensaje2\n... Lista FIFO
Mensaje ‘n'
Mensaje n-1
Mensaje 1
58 this.NumMensajes = NumMensajes;
59 for (int i=0;i<NumMensajes;i++)
60 Mensajes[i]="";
61 }
62
63 public void InsertarMensaje(String Mensaje) {
64 for (int i=NumMensajes-2;i!=-1;i--)
65 Mensajes[i+1]=Mensajes[i];
66 Mensajes[0] = Mensaje;
67 }
68
69 public String[] DameMensajes() {
70 return Mensajes;
71 }
72
73 public void ImprimeMensajes() {
74 for (int i=0;i<NumMensajes;i++)
75 System.out.println(Mensajes[i]);
76 System.out.println();
77 }
78
79 }
80
81
82 } // ChatServidor
ChatCliente
1 import java.awt.*;
2 import java.awt.event.*;
3 import java.util.*;
4
5 // *******************************************************
6 // * Cliente Chat *
7 // *******************************************************
8 public class ChatCliente {
9 final int TAMANIO_MAX_MENSAJE = 40;
10 final int TIMEOUT=200;
11 final int PUERTO_ORIGEN=5000, PUERTO_DESTINO=5002;
12
13 TextArea AreaRecibir;
14 TextField TextoEnviar;
15 TextField HostDestino;
16 Button BotonEnviar;
17 String MensajeRecibido;
18
JESÚS BOBADILLA SANCHO 89
19 TRecibeUDP InstanciaRecibeUDP;
20 TEnviaUDP InstanciaEnviaUDP;
21
22 public ChatCliente(String Host) {
23 InstanciaRecibeUDP = new TRecibeUDP();
24 InstanciaEnviaUDP = new TEnviaUDP();
25 Frame Marco = new Frame("Chat");
26 Panel PanelSur = new Panel();
27 Label EtiquetaMensajeSaliente =new Label ("Mensaje:");
28 Label EtiquetaHostDestino =new Label ("Host destino");
29 TextoEnviar = new TextField(25);
30 AreaRecibir = new TextArea();
31 HostDestino = new TextField(Host);
32 BotonEnviar = new Button("Enviar");
33
34 Marco.setSize(600,250);
35 Marco.setLayout(new BorderLayout());
36 Marco.add("South",PanelSur);
37 PanelSur.add(EtiquetaHostDestino);
38 PanelSur.add(HostDestino);
39 PanelSur.add(EtiquetaMensajeSaliente);
40 PanelSur.add(BotonEnviar);
41 PanelSur.add(TextoEnviar);
42 Marco.add("Center",AreaRecibir);
43 Marco.show();
44
45 ChatRecibir HiloRecibir = new ChatRecibir();
46 ChatEnviar HiloEnviar = new ChatEnviar();
47
48 HiloRecibir.start();
49 HiloEnviar.start();
50
51 } // Constructor
52
53 public static void main(String[] args) {
54 ChatCliente Instancia = new ChatCliente(args[0]);
55 }
56
57 // *******************************************************
58 // * Thread para recibir datos *
59 // *******************************************************
60
61 private class ChatRecibir extends Thread {
62
63 public void run() {
64 do {
65 InstanciaEnviaUDP.Envia("1",1,HostDestino.getText(),
66 PUERTO_DESTINO);
67 MensajeRecibido = InstanciaRecibeUDP.Recibe(
90 © JESÚS BOBADILLA SANCHO
68 PUERTO_ORIGEN,400,TIMEOUT);
69 AreaRecibir.setText(MensajeRecibido);
70 try {
71 Thread.sleep(5000l);
72 } catch (InterruptedException e) {}
73 } while (true);
74 }
75 } //class ChatRecibir
76
77
78 // *******************************************************
79 // * Thread de envio *
80 // *******************************************************
81
82 private class ChatEnviar extends Thread {
83
84 public void run() {
85 BotonEnviar.addActionListener(new MensajeAEnviar());
86 }
87
88 private class MensajeAEnviar extends Object implements
89 ActionListener {
90 public void actionPerformed(ActionEvent e) {
91 String Mensaje = "0"+TextoEnviar.getText();
92 InstanciaEnviaUDP.Envia(Mensaje,Mensaje.length(),
93 HostDestino.getText(),PUERTO_DESTINO);
94 TextoEnviar.setText("");
95 } // actionPerformed
96 } // MensajeAEnviar
97
98 } //class ChatCliente
99
100 } // clase
DatagramPacket
Métodos principales Acción
InetAddress getAddress() Dirección del nodo remoto en la comunicación
byte[] getData() Devuelve el mensaje que contiene el datagrama
int getLength() Devuelve la longitud del mensaje del datagama
int getOffset() Devuelve el desplazamiento que indica el
comienzo del mensaje (dentro del array de bytes)
int getPort() Devuelve el valor del puerto remoto
void setAddress(InetAddress d) Establece el nodo remoto en la comunicación
void setData(byte[] Mensaje) Establece el mensaje que contiene el datagrama
void setData(byte[] Mensaje, int Establece el mensaje que contiene el datagrama,
Desplazamiento, int Longitud) indicando su desplazamiento en el array de bytes
y su longitud
92 © JESÚS BOBADILLA SANCHO
DatagramSocket
Métodos principales Acción
void bind(SocketAddress a) Asigna la dirección establecida al socket
void close() Cierra el socket
void connect(SocketAddress a) Conecta el socket a la dirección remota
establecida
void connect(InetAddress a, int puerto) Conecta el socket a la dirección establecida y el
puerto especificado
void disconnect() Desconecta el socket
InetAddress getInetAddress() Devuelve la dirección a la que está conectada el
socket
InetAddress getLocalAddress() Devuelve la dirección del socket
int getLocalPort() Devuelve el número de puerto asociado al socket
OutputStream getOutputStream() Devuelve el stream de salida asociado al socket
int getPort() Devuelve el valor del Puerto remoto al que está
conectado
int getSoTimeout() Devuelve el valor en milisegundos que el socket
espera al establecimiento de comunicación
boolean isBound() Indica si el socket está vinculado
boolean isClosed() Indica si el socket está cerrado
boolean isConnected() Indica si el socket está conectado
void setSoTimeout(int ms) Indica el valor en milisegundos que el socket
espera al establecimiento de comu nicación
LECCIÓN 6
6.1 INTRODUCCIÓN
Los servlets de Java proporcionan un mecanismo para ejecutar programas en
equipos servidores, en función de las peticiones que los clientes realicen haciendo
uso de navegadores web. Por lo tanto, los servlets nos permiten crear páginas web
activas, en el sentido de que la respuesta que ofrecen puede variar en función de los
datos que proporcione el cliente y la situación de contexto existente. Por ejemplo,
utilizando servlets, podemos informar a un cliente de los vuelos disponibles en un
momento dado (situación de contexto), para un origen y destino seleccionados
(datos que proporciona el cliente).
6 2
Servidor
Cliente 1 3
Servidor Web
(Apache, IIS,
5 Tomcat)
Contenedor de
servlets (Tomcat)
4
Cliente 2
2 La petición y sus datos asocia dos, que le llegan al equipo servidor a través de
la red, los recoge el programa servidor de web utilizado.
3 El servidor web detecta que hay que ejecutar un servlet y delega esta acción
en el programa “contenedor de servlets”, que se encargará de llevarla a cabo.
Puede darse la circunstancia de que el contenedor de servlets también haga la
función de servidor web.
4 Una vez ejecutado el servlet, se traspasan los resultados (en forma de página
web) al servidor web.
5 El servidor web envía la página web de resultados a través del ordenador
servidor.
6 La página web de respuesta le llega al cliente, que la visualizará haciendo uso
del navegador (cliente web) utilizado.
Los servlets de Java tienen un ciclo de vida marcado por tres métodos del
interfaz javax.servlet.Servlet: init(...), service(...) y destroy(). El método init lo
invoca el contenedor de servlets, una sola vez; resulta útil para inicializar recursos
que serán necesarios en la ejecución del servlet (abrir ficheros, conectar bases de
datos, establecer comunicaciones, etc.). El método destroy se invoca cuando el
servlet va a ser descargado del servidor; en su interior se debería programar la
liberación de recursos utilizados en el método init.
Cuando creamos un sitio web que contiene páginas activas, escribimos las
páginas de consulta y también los programas que responden, desde el servidor, a las
peticiones que los clientes realizan rellenando las páginas web de consulta. En el
ejemplo de peticiones de vuelo, cuando el usuario selecciona los aeropuertos de
origen y de destino, podemos enviar esta información con formato GET o POST. Si
elegimos la primera opción, se ejecutará el método doGet en el servlet del equipo
servidor; si elegimos la segunda opción se ejecutará el método doPost.
</form>
Servlet
doGet(...) { ...... }
6 2
Servidor
Servidor Web 3
(Apache, IIS,
5 Tomcat)
Contenedor
de servlets
4 (Tomcat)
ServletRequest ServletResponse
HttpServletRequest HttpServletResponse
Servlet
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4
5 public class HolaMundo extends HttpServlet {
6
7 public void doGet(HttpServletRequest request,
8 HttpServletResponse response)
9 throws IOException, ServletException {
10
11 response.setContentType("text/html");
12 PrintWriter HaciaCliente = response.getWriter();
13 HaciaCliente.println("<html>");
14 HaciaCliente.println("<body>");
15 HaciaCliente.println("<h1>Hola Mundo</h1>");
16 HaciaCliente.println("</body>");
17 HaciaCliente.println("</html>");
18 }
19 }
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4
5 public class Tabla extends HttpServlet {
6
7 public void doGet(HttpServletRequest request,
8 HttpServletResponse response)
9 throws IOException, ServletException {
10
11 response.setContentType("text/html");
12 PrintWriter out = response.getWriter();
13 out.println("<html>");
14 out.println("<body>");
15 out.println("<table border=1 bgcolor='Salmon'>");
16 for (int Fila=1;Fila<=7;Fila++) {
17 out.println("<tr><td>");
18 out.println("<font size="+Fila+">Tamaño de
19 letra: "+Fila+"</font>");
20 out.println("</td></tr>");
21 }
100 © JESÚS BOBADILLA SANCHO
22 out.println("</table>");
23 out.println("</body>");
24 out.println("</html>");
25 }
26 }
1 <html>
2 <body>
3 <a href="http://localhost:8080/examples/servlet/Tabla">
4 Obtener la Tabla
5 </a>
6 </body>
7 </html>
JESÚS BOBADILLA SANCHO 101
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4
5 public class DirectorioRaiz extends HttpServlet {
6
7 public void doGet(HttpServletRequest request,
8 HttpServletResponse response)
9 throws IOException, ServletException
10 {
11 response.setContentType("text/html");
12 PrintWriter ACliente = response.getWriter();
13 File Fichero = new File("c:/");
14 String[] Contenido = Fichero.list();
15 ACliente.println("<html>");
16 ACliente.println("<body>");
17 ACliente.println("<table border=1
18 bgcolor='Salmon'>");
19 for (int Fich=0;Fich<Contenido.length;Fich++) {
102 © JESÚS BOBADILLA SANCHO
20 ACliente.println("<tr><td>");
21 ACliente.println("<font size=1>");
22 ACliente.println(Contenido[Fich]);
23 ACliente.println("</font>");
24 ACliente.println("</td></tr>");
25 }
26 ACliente.println("</table>");
27 ACliente.println("</body>");
28 ACliente.println("</html>");
29 }
30
31 }
1 <html>
2 <body>
3 <h1> Cuestionario </h1>
4 <form action="http://localhost:8080/examples
5 /servlet/Parametros" method="get">
6 Nombre: <input type="text" name=Nombre> <br>
7 Edad: <input type="text" name=Edad> <br><br>
8 <input type="submit" value="Enviar datos"> <br>
9 </form>
10 </body>
11 </html>
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4
5 public class Parametros extends HttpServlet {
6
7 public void doGet(HttpServletRequest request,
8 HttpServletResponse response)
9 throws IOException, ServletException {
10 response.setContentType("text/html");
11 PrintWriter out = response.getWriter();
12 out.println("<html>");
13 out.println("<body>");
14 String NombreRecibido=request.getParameter("Nombre");
15 String EdadRecibida = request.getParameter("Edad");
16 out.println("<h1> Hola " + NombreRecibido + "</h1>");
17 out.println("<h1> Tienes " + EdadRecibida +
18 " años </h1>");
19 out.println("</body>");
20 out.println("</html>");
21 }
22 }
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4
5 public class Hipotenusa extends HttpServlet {
6
7 public void doGet(HttpServletRequest request,
8 HttpServletResponse response)
9 throws IOException, ServletException
10 {
11 String Cateto1 = request.getParameter("CatetoA");
12 String Cateto2 = request.getParameter("CatetoB");
13 double Cat1 = Double.parseDouble(Cateto1);
14 double Cat2 = Double.parseDouble(Cateto2);
15 double Hipotenusa = Math.sqrt(Cat1*Cat1+Cat2*Cat2);
16
17 response.setContentType("text/html");
18 PrintWriter out = response.getWriter();
19 out.println("<html>");
20 out.println("<body>");
21 out.println("Hipotenusa: " + Hipotenusa);
22 out.println("</body>");
23 out.println("</html>");
24 }
25 }
1 <html>
2 <body>
3 <h3> Cálculo de la hipotenusa </h3>
4 <form action="http://localhost:8080
5 /examples/servlet/Hipotenusa" method="get">
6 Cateto 1: <input type="text" name=CatetoA> <br>
7 Cateto 2: <input type="text" name=CatetoB> <br><br>
8 <input type="submit" value="Enviar datos"> <br>
9 </form>
10 </body>
11 </html>
106 © JESÚS BOBADILLA SANCHO
6.7 CHAT
En este apartado se desarrolla una aplicación que implementa el servicio
chat. Los usuarios podrán acceder al chat haciendo uso de sus programas
navegadores (Explorer, Netscape, Opera, etc.).
..../chat.htm
< html>...
Servidor
Cliente 1
Servidor Web
(Apache, IIS,
Tomcat)
Contenedor de
servlets (Tomcat)
Chat.htm
ChatEnvia.htm ChatVisualiza.htm
ChatInserta ChatVisualiza
ChatConversacion
JESÚS BOBADILLA SANCHO 107
Chat.htm es la página web que utiliza el usuario para tener acceso al chat;
incluye dos marcos, que contienen las páginas ChatEnvia.htm y ChatVisualiza.htm.
ChatEnvia.htm provoca la ejecución del servlet ChatInserta , mientras que
ChatVisualiza.htm provoca la ejecución periódica del servlet ChatVisualiza.
ChatConversacion es una clase que encapsula la estructura de datos que contiene los
mensajes enviados y la forma de acceder a ellos.
6.7.1 ChatConversacion
Los métodos se han definido como estáticos para facilitar su uso desde los
servlets, que no necesitarán crear una instancia de la clase ChatConversacion.
11 Conversacion[0]=Mensaje;
12 }
13
14 public synchronized static String[] DameConversacion() {
15 return Conversacion;
16 }
17
18 }
6.7.2 ChatInserta
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4
5 public class ChatInserta extends HttpServlet {
6
7 synchronized public void doGet(HttpServletRequest rq,
8 HttpServletResponse rp)
9 throws IOException, ServletException {
10 String Apodo = rq.getParameter("Apodo");
11 String Mensaje = rq.getParameter("Mensaje");
12
13 ChatConversacion.InsertaMensaje(Apodo+": "+Mensaje);
14
15 rp.setContentType("text/html");
JESÚS BOBADILLA SANCHO 109
6.7.3 ChatVisualiza
La única instrucción compleja de este servlet es la que abarca las líneas 17,
18 y 19. Su significado se explica un poco más adelante, cuando se detalla el
funcionamiento de la página ChatVisualiza.htm.
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4
5 public class ChatVisualiza extends HttpServlet {
6
7 public synchronized void doGet(HttpServletRequest rq,
8 HttpServletResponse rp)
110 © JESÚS BOBADILLA SANCHO
6.7.4 ChatEnvia.htm
La página web ChatEnvia.htm define dos cajas de texto con los nombres
asociados Apodo y Mensaje (líneas 5 y 6). Cuando el usuario pulsa el botón
“Enviar” (línea 7), los datos se envían con formato get al servlet ChatInserta,
situado en el host “e-ducacion.eui.upm.es” (líneas 3 y 4).
1 <html>
2 <body>
3 <form method="GET" action="http://e-ducacion.eui.upm.es:
4 8080/examples/servlet/ChatInserta">
5 <input type="text" size=10 name="Apodo">
6 <input type="text" size=70 name="Mensaje">
7 <input type="submit" value="Enviar">
8 </form>
9 </body>
10 </html>
JESÚS BOBADILLA SANCHO 111
6.7.5 ChatVisualiza.htm
1 <html>
2 <head>
3 <META HTTP-EQUIV="REFRESH" CONTENT="5;url=http://e-ducacion
4 .eui.upm.es:8080/examples/servlet/ChatVisualiza">
5 </head>
6 <body>
7 </body>
8 </html>
6.7.6 Chat.htm
1 <html>
2 <head>
3 <title>Servicio de Chat</title>
4 </head>
5 <FRAMESET ROWS="*,100">
6 <FRAME SRC="ChatVisualiza.htm">
7 <FRAME SRC="ChatEnvia.htm">
8 </FRAMESET>
9 </html>
6.7.7 Resultados
Sensor de
Temperatura
y presión UDP
Recibe las
Sensor de UDP muestras de
Temperatura los diferentes HTTP
y pres ión lugares
Servidor web
que visualiza
Sensor de UDP periódicamente HTTP
Temperatura las muestras
y presión recogidas
JESÚS BOBADILLA SANCHO 113
TemperaturaYPresion
UDP
TemperaturaYPresion RecibeMedidas
UDP
TemperaturaYPresion MedidasSensores HTTP
PanelDeMedidas
HTTP
TemperaturaYPresion
UDP
HTTP
JVM
RecibeMedidas
TemperaturaYPresion UDP
JVM Internet/intranet
MedidasSensores
UDP HTTP
PanelDeMedidas
TemperaturaYPresion HTTP
JVM JVM
6.8.1 TemperaturaYPresion
1 import java.util.Random;
2 import java.net.*;
3
4 public class TemperaturaYPresion extends Thread{
5
6 public static void main(String[] args) {
7 TemperaturaYPresion Sensor = new
8 TemperaturaYPresion(args[0],args[1],args[2]);
9 }
10
11 TemperaturaYPresion(String Sensor, String HostDestino,
12 String PuertoDestino) {
13 Float Temperatura, Presion;
14 Random SecuenciaAleatoria = new Random();
15 DatagramSocket SocketSensor;
16 DatagramPacket MedidasSensor;
17 byte[] Buffer = new byte[3];
JESÚS BOBADILLA SANCHO 115
18
19 do {
20 Temperatura = new
21 Float(SecuenciaAleatoria.nextFloat()*60);
22 Presion = new
23 Float(SecuenciaAleatoria.nextFloat()*20);
24 Float SegundosEspera = new
25 Float(SecuenciaAleatoria.nextFloat()*5000);
26 System.out.println(Temperatura);
27 System.out.println(Presion);
28
29 Buffer[0] = new Integer(Sensor).byteValue();
30 Buffer[1] = Temperatura.byteValue();
31 Buffer[2] = Presion.byteValue();
32 try {
33 MedidasSensor = new DatagramPacket(Buffer,
34 Buffer.length,InetAddress.getByName(HostDestino),
35 Integer.parseInt(PuertoDestino));
36 SocketSensor = new DatagramSocket();
37 SocketSensor.send(MedidasSensor);
38 SocketSensor.close();
39 } catch (Exception e) {}
40
41 try {
42 this.sleep(SegundosEspera.longValue());
43 } catch (InterruptedException e) {}
44
45 } while (true);
46 }
47
48 }
6.8.2 MedidasSensores
devuelve los últimos datos proporcionados por todos los sensores del sistema.
Debido a que las medidas se almacenan en memoria, es necesario que esta clase se
sitúe en la misma máquina virtual que RecibeMedidas y PanelDeMedidas; de esta
forma, los datos son accesibles a través de memoria.
6.8.3 RecibeMedidas
1 import java.net.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4 import java.io.*;
5
JESÚS BOBADILLA SANCHO 117
6.8.4 PanelDeMedidas
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4
5 public class PanelDeMedidas extends HttpServlet {
6
7 public void doGet(HttpServletRequest rq,
8 HttpServletResponse rp)
9 throws IOException, ServletException {
10
11 int[][] Medidas = MedidasSensores.DameMedidas();
12
13 rp.setContentType("text/html");
14 PrintWriter out = rp.getWriter();
15 out.println("<html>");
16 out.println("<head>");
17 out.println("<meta http-equiv='refresh' content='2;
18 url=http://localhost:8080/examples/
19 servlet/PanelDeMedidas'>");
20 out.println("</head>");
21 out.println("<body>");
22 out.println("<table border=1 bgcolor=salmon>");
23 for (int i=0;i<5;i++) {
24 out.println("<tr><td> Sensor " + i + "</td>");
25 out.println("<td>" + Medidas[i][0] + "</td>");
26 out.println("<td>" + Medidas[i][1] +
27 "</td></tr>");
28 }
29 out.println("</table>");
30 out.println("</body>");
31 out.println("</html>");
32 }
33 }
JESÚS BOBADILLA SANCHO 119
6.8.5 PanelDeMedidas.htm
1 <html>
2 <head>
3 <META HTTP-EQUIV="REFRESH" CONTENT="2;
4 url=http://localhost:8080/examples/servlet/PanelDeMedidas">
5 </head>
6 <body>
7 </body>
8 </html>
Para que actúe cada sensor hay que utilizar el comando: java
TemperaturaYPresion ‘n’ localhost 6000, siendo ‘n’ el número de sensor (en nuestro
ejemplo, de 0 a 4). Para recoger los datos en el servidor usamos el navegador,
escribiendo la URL: http://localhost:8080/examples/servlet/RecibeMedidas. Para
visualizar los datos de los sensores:
http://localhost:8080/examples/servlets/PanelDeMedidas.htm.
BASES DE DATOS
Los campos forman las columnas de las tablas; definen el tipo y variedad de
sus datos. Las filas de datos se denominan tuplas o registros; una tabla puede estar
vacía (sin ninguna tupla) o contener un número variable de las mismas. En el
ejemplo, cada tupla de la tabla Clientes define ciertos datos básicos de una persona
(cliente), mientras que cada tupla de la tabla Productos define los datos necesarios
de cada producto disponible. Por supuesto, cada tabla de una base de datos puede
contener un número de tuplas diferente al de las demás tablas.
Clientes Tabla
Atributos
Productos Pe didos
Producto Nombre Valor DNI Producto Unidades
Además de los datos (explícitos) de una base de datos (los atributos), existe
una información importante: los metadatos. Los metadatos se encuentran
recopilados en un conjunto de tablas del sistema, denominado catálogo. Los
catálogos almacenan información acerca de las bases de datos, las tablas y la
composición de dichas tablas, es decir, de toda la información presentada en el
gráfico anterior, exceptuando los atributos.
Hasta ahora hemos seleccionado todas las tuplas de una tabla, restringiendo
únicamente los campos que obtenemos. Si deseamos, además, poder restringir las
tuplas que nos devuelve una sentencia SELECT, debemos emplear la palabra
WHERE. La siguiente sentencia nos proporciona los números de DNI de los clientes
menores de 30 años:
SELECT DNI FROM Clientes WHERE Edad<30
JESÚS BOBADILLA SANCHO 125
SQL permite incluir en sus condiciones los operadores <, <=, >, >=, <>,
AND, OR, NOT, IS NULL, IS NOT NULL, LIKE, BETWEEN AND, IN, ALL,
ANY, EXISTS, etc. La palabra LIKE funciona en combinación con el carácter ‘%’,
que hace de “comodín”, por ejemplo, la siguiente sentencia selecciona todos los
atributos de la tabla Clientes en los que el campo Nombre comienza con la letra ‘J’.
SELECT * FROM Clientes WHERE Nombre LIKE ‘J%’
Con Sql podemos realizar consultas sobre varias tablas a la vez, para
unificar el contenido de las mismas; esto nos permite no repetir datos en varias
tablas. En nuestra base de datos no es necesario que en la tabla de pedidos esté el
apellido del cliente. Simplemente bastará con que esté el código del cliente. De este
modo, podremos encontrar el resto de los datos buscando en la tabla de clientes el
código correspondiente al pedido.
CLIENTES
Código Nombre Dirección
1 Luis Miguel Guzmán el Bueno, 90
2 Beatriz Zurriaga, 25
3 Jonás Federico Puertas, 3
4 Joaquín Vinateros, 121
5 Pedro Virgen del Cerro, 154
6 Sandra Pablo Neruda, 15
7 Miguel Armadores, 1
8 Sergio Avenida del Ejercito,
9 Alejandro Leonor de76Cortinas, 7
10 Álvaro Fuencarral, 33
11 Rocío Cervantes, 22
12 Joaquín Buenos Aires, 31
13 Jesús Gaztambique, 32
JESÚS BOBADILLA SANCHO 127
PRODUCTOS
Referencia Nombre Precio Concepto
1 Patatas 200 Pta Kilo
2 Melones 500 Pta Kilo
3 Sandías 120 Pta Kilo
4 Zapatos 5.000 Pta Par
5 Chandal 12.000 Pta Unidad
6 Pantalones 2.000 Pta Unidad
7 Camisa 2.500 Pta Unidad
8 Corbata 950 Pta Unidad
9 Aceite 695 Pta Litro
PEDIDOS
Código Referencia Cantidad
1 1 5
9 2 10
4 5 6
12 8 1
7 2 9
8 3 7
7 9 3
2 7 1
6 4 3
3 1 4
La selección la hemos hecho sobre dos tablas, pero Sql nos permite utilizar
más tablas con los operadores booleanos. De este modo podremos seleccionar sobre
varias tablas utilizando distintas condiciones para unirlas entre ellas de dos en dos.
Por ejemplo, si además de los datos que hemos visto en el ejemplo anterior
queremos mostrar el nombre del producto que se pide, tendremos que utilizar una
tercera tabla, la de productos.
Ahora buscaremos tres registros, uno de cada tabla, en los que coincidan por
un lado el campo Código de las tablas Pedidos y Clientes, y por otro el campo
Referencia de las tablas Pedidos y Productos. Como se puede ver, la tabla Pedidos
nos sirve de enlace entre las tablas Productos y Clientes, que no tienen ningún
campo en común.
Esta sentencia buscará las coincidencias de las tablas Pedidos y Clientes por
el campo Código. Cuando encuentre varias veces el mismo cliente lo mostrará solo
una vez.
130 © JESÚS BOBADILLA SANCHO
Una cosa importante que hay que tener en cuenta es que todos los campos
seleccionados deberán ser iguales para todos los registros que unamos. Es decir, si
tenemos en dos registros dos nombres de cliente iguales pero direcciones diferentes,
se mostrarán los dos registros. Hay que tener cuidado con los campos que
seleccionemos, para que aparezcan los registros que deseemos.
Otra forma de seleccionar los clientes que han comprado un cierto producto
es a través del operador EXISTS, de la siguiente forma:
SELECT Nombre, Dirección FROM Clientes WHERE EXIST (SELECT Código
FROM Pedidos WHERE Clie ntes.Código=Pedidos.Código AND Referencia=2)
Nombre Dirección
Alejandro Leonor de Cortinas, 7
Beatriz Zurriaga, 25
Joaquín Buenos Aires, 31
Joaquín Vinateros, 121
Jonás Federico Puertas, 3
Luis Miguel Guzmán el Bueno, 90
Miguel Armadores, 1
Sandra Pablo Neruda, 15
Sergio Avenida del Ejercito, 76
Seleccionar los clientes que todavía no han comprado: vamos a hacer ahora
lo contrario que en el ejemplo anterior. Vamos a buscar los elementos de una tabla
que no se encuentran en otra. Para esto utilizaremos el operador IN que habíamos
visto anteriormente, y más concretamente NOT IN.
JESÚS BOBADILLA SANCHO 131
Una vez que hemos conseguido los códigos, debemos comparar los registros
de la tabla Clientes, viendo en cada momento si el código de cada registro está o no
en la selección previa que hemos realizado. Es decir,
SELECT Nombre, Dirección FROM Clientes WHERE Código NOT IN
(Lista_de_códigos)
Unido con lo anterior, tenemos que la sentencia Sql que utilizaremos será la
siguiente:
SELECT Nombre, Dirección FROM Clientes WHERE Código NOT IN (SELECT
Código FROM Pedidos)
Nótese que en la selección que se hace sobre la tabla Pedidos sólo se emplea
el campo Código, ya que es el que queremos comparar.
Nombre Dirección
Pedro Virgen del Cerro, 154
Álvaro Fuencarral, 33
Rocío Cervantes, 22
Jesús Gaztambique, 32
operador de comparación (<, >, =, <>, ...). Utilizaremos ALL y ANY para
seleccionar valores que sean mayor, menor, igual, etc.. que todos o alguno de los
valores de una selección previa.
De la misma forma que hemos empleado ALL, podemos usar ANY. Este
segundo cuantificador lo utilizaremos para seleccionar valores que se encuentren en
algún campo. Por ejemplo, otra forma de seleccionar los clientes que han comprado
algo sería la siguiente:
SELECT Nombre, Dirección FROM Clientes WHERE Código = ANY (SELECT
Código FROM Pedidos)
Así mismo, para seleccionar los clientes que no tienen ningún pedido
utilizaríamos:
SELECT Nombre, Dirección FROM Clientes WHERE Código <> ALL (SELECT
Código FROM Pedidos)
Aplicación
JVM
Sistema Operativo
ODBC
ResultSet
Statement
ODBC
DriverManager
En este primer ejemplo vamos a utilizar una base de datos de tipo Access,
cuyo nombre físico es EjemploBD.mdb, y está situada en el directorio
C:\Jesus\ProyectosJava\Libro\BD. Hemos decidido asignarle el nombre lógico
NombreLogico, que aunque no identifica su función, tiene el interés didáctico de
remarcar en los programas el hecho de que no emplearemos nombres físicos en el
nivel de aplicación al trabajar con bases de datos.
En los ejemplos del siguiente apartado veremos como extraer los datos
(atributos) del objeto Personas, de tipo ResultSet.
1 import java.sql.*;
2
3 public class PruebaConexion {
4
5 public static void main(String[] args){
6 try{
7 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
8 String BaseDeDatos = "jdbc:odbc:NombreLogico";
9 Connection Conexion =
10 DriverManager.getConnection(BaseDeDatos);
11 Statement SentenciaSQL = Conexion.createStatement();
JESÚS BOBADILLA SANCHO 137
Todos los métodos señalados devuelven un valor de tipo boolean, que nos
indica si el movimiento del cursor ha sido posible. Hay que tener en cuenta que, por
defecto, los objetos RecordSet únicamente pueden ser recorridos incrementalmente,
y que además no son actualizables (no se pueden modificar sus atributos). En los
siguientes apartados realizaremos una leve modificación a nuestros programas para
solventar estas restricciones.
Tanto los métodos “update” como los métodos “get” están sobrecargados
para admitir dos tipos de argumentos: el nombre de la columna o la posición de la
columna; de esta manera disponemos, por ejemplo, de un método getInt(String
NombreColumna), y de otro método getInt(int IndiceColumna). Las columnas se
numeran empezando por 1:
Los métodos “get” se aplican a una gran variedad de tipos de datos: Array,
AsciiStream, BigDecimal, BinaryStream, Boolean, Byte, Bytes, Date, Double, Float,
Int, Long, Object, Ref, Short, String, Time, Timestamp, URL, etc. formando
getArray(...), getByte(...), etc. Los métodos “update” existen para la mayor parte de
estos tipos de datos.
Para iterar por todas las tuplas (filas) del RecordSet Personas, empleamos
un bucle while (línea 16) que finaliza cuando el método next devuelve el valor false,
indicando el final del RecordSet.
Por cada tupla se obtienen los atributos alfanuméricos de los campos DNI,
Nombre y Apellido (líneas 17 a 19), empleando el método getString. También se
obtiene el atributo del campo Edad, de tipo entero, por lo que se utiliza el método
getInt (línea 20).
140 © JESÚS BOBADILLA SANCHO
1 import java.sql.*;
2
3 public class Listado {
4
5 public static void main(String[] args){
6 String Nombre,Apellido,DNI;
7 int Edad;
8 try{
9 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
10 String BaseDeDatos = "jdbc:odbc:NombreLogico";
11 Connection Conexion =
12 DriverManager.getConnection(BaseDeDatos);
13 Statement SentenciaSQL = Conexion.createStatement();
14 ResultSet Personas = SentenciaSQL.executeQuery("SELECT
15 * FROM DatosPersonales");
16 while (Personas.next()) {
17 DNI = Personas.getString("DNI");
18 Nombre = Personas.getString("Nombre");
19 Apellido = Personas.getString("Apellido");
20 Edad = Personas.getInt("Edad");
21 System.out.println(Nombre+" "+Apellido+", "+
22 Edad+", "+DNI);
23 }
24 Personas.close();
25 Conexion.close();
26 SentenciaSQL.close();
27 }
28 catch (ClassNotFoundException e) {
29 System.out.println("Clase no encontrada");
30 }
31 catch (SQLException e) {
32 System.out.println(e);
33 }
34 }
35
36 }
JESÚS BOBADILLA SANCHO 141
7.6.1 Modificación
1 import java.sql.*;
2
3 public class Modificacion {
4
5 public static void main(String[] args){
6 String Nombre,Apellido,DNI;
7 int Edad;
8 try{
9 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
10 String BaseDeDatos = "jdbc:odbc:NombreLogico";
11 Connection Conexion =
12 DriverManager.getConnection(BaseDeDatos);
13 Statement SentenciaSQL = Conexion.createStatement(
14 ResultSet.TYPE_SCROLL_INSENSITIVE,
15 ResultSet.CONCUR_UPDATABLE);
16 ResultSet Personas = SentenciaSQL.executeQuery("SELECT
17 * FROM DatosPersonales");
18
19 while (Personas.next()) {
20 Nombre = Personas.getString("Nombre");
21 Apellido = Personas.getString("Apellido");
22 if (Apellido.equalsIgnoreCase("Moreno")&&
23 Nombre.equalsIgnoreCase("Ana")){
24 // IMPORTANTE: por cada getXxxxx("Campo") hay que
25 // realizar un updateXxxxx("Campo")
26 Personas.updateString("Nombre","Luis");
JESÚS BOBADILLA SANCHO 143
27 Personas.updateString("Apellido","Reverte");
28 Personas.updateInt("Edad",45);
29 Personas.updateString("DNI","47645876F");
30 Personas.updateRow();
31 System.out.println("Registro modificado");
32 break;
33 }
34 }
35
36 Personas.close();
37 Conexion.close();
38 SentenciaSQL.close();
39 }
40 catch (ClassNotFoundException e) {
41 System.out.println("Clase no encontrada");
42 }
43 catch (SQLException e) {
44 System.out.println(e);
45 }
46 }
47
48 }
7.6.2 Inserción
1 import java.sql.*;
2
3 public class Insercion {
4
5 public static void main(String[] args){
6 try{
7 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
8 String BaseDeDatos = "jdbc:odbc:NombreLogico";
9 Connection Conexion =
10 DriverManager.getConnection(BaseDeDatos);
11 Statement SentenciaSQL = Conexion.createStatement(
JESÚS BOBADILLA SANCHO 145
12 ResultSet.TYPE_SCROLL_INSENSITIVE,
13 ResultSet.CONCUR_UPDATABLE);
14 ResultSet Personas = SentenciaSQL.executeQuery("SELECT
15 * FROM DatosPersonales");
16
17 Personas.moveToInsertRow();
18 Personas.updateString("DNI","50839979M");
19 Personas.updateString(2,"Pedro");
20 Personas.updateString("Apellido","Cela");
21 Personas.updateInt("Edad",78);
22 Personas.insertRow();
23 // Personas.moveToCurrentRow();
24
25 Personas.close();
26 Conexion.close();
27 SentenciaSQL.close();
28 }
29 catch (ClassNotFoundException e) {
30 System.out.println("Clase no encontrada");
31 }
32 catch (SQLException e) {
33 System.out.println(e);
34 }
35 }
36
37 }
7.6.3 Borrado
1 import java.sql.*;
2
3 public class Borrado {
4
5 public static void main(String[] args){
6 String Nombre,Apellido;
7 try{
8 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
9 String BaseDeDatos = "jdbc:odbc:NombreLogico";
10 Connection Conexion =
11 DriverManager.getConnection(BaseDeDatos);
12 Statement SentenciaSQL = Conexion.createStatement(
13 ResultSet.TYPE_SCROLL_INSENSITIVE,
14 ResultSet.CONCUR_UPDATABLE);
15 ResultSet Personas = SentenciaSQL.executeQuery("SELECT
16 * FROM DatosPersonales");
17
18 while (Personas.next()) {
19 Nombre = Personas.getString("Nombre");
20 Apellido = Personas.getString("Apellido");
21 if (Apellido.equalsIgnoreCase("Cela")&&
22 Nombre.equalsIgnoreCase("Pedro")){
23 System.out.println("Registro eliminado");
24 Personas.deleteRow();
25 break;
26 }
27 }
28 Personas.close();
29 Conexion.close();
JESÚS BOBADILLA SANCHO 147
30 SentenciaSQL.close();
31 }
32 catch (ClassNotFoundException e) {
33 System.out.println("Clase no encontrada");
34 }
35 catch (SQLException e) {
36 System.out.println(e);
37 }
38 }
39
40 }
Resulta muy adecuado crear una clase que encapsule los campos de la tabla,
con el objetivo de que en cada instancia de esa clase se pueda definir una fila
(registro) del RecordSet. La clase del ejemplo que realiza esta función es
ObRegistro.
PruebaAccesoBD
GUIAccesoBD
ObListado ObConsulta
ObBorrado ObInserccion
ObModificacion
ObPosicionamiento
ObRegistro
7.7.3 Inserción
1 import java.sql.*;
2
3 public class ObInserccion {
4
5 ObInserccion(ObRegistro Datos){
6 try{
7 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
8 String BaseDeDatos = "jdbc:odbc:NombreLogico";
9 Connection Conexion =
10 DriverManager.getConnection(BaseDeDatos);
11 Statement SentenciaSQL = Conexion.createStatement(
12 ResultSet.TYPE_SCROLL_INSENSITIVE,
13 ResultSet.CONCUR_UPDATABLE);
14 ResultSet Personas = SentenciaSQL.executeQuery("SELECT
15 * FROM DatosPersonales");
16
17 Personas.moveToInsertRow();
18 Personas.updateString("DNI", Datos.DameDNI());
19 Personas.updateString("Nombre",Datos.DameNombre());
20 Personas.updateString("Apellido",
21 Datos.DameApellido());
22 Personas.updateInt("Edad",Datos.DameEdad());
23 Personas.insertRow();
24
25 Personas.close();
26 Conexion.close();
27 SentenciaSQL.close();
28 }
29 catch (ClassNotFoundException e) {
30 System.out.println("Clase no encontrada");
31 }
32 catch (SQLException e) {
33 System.out.println(e);
34 }
35 } }
JESÚS BOBADILLA SANCHO 151
7.7.4 Consulta
1 import java.sql.*;
2
3 public class ObConsulta {
4
5 private int Posicion = 0;
6 private ObRegistro DatosPersona;
7
8 ObConsulta(String DNIPedido){
9 try{
10 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
11 String BaseDeDatos = "jdbc:odbc:NombreLogico";
12 Connection Conexion =
13 DriverManager.getConnection(BaseDeDatos);
14 Statement SentenciaSQL = Conexion.createStatement();
15 ResultSet Personas = SentenciaSQL.executeQuery("SELECT
16 * FROM DatosPersonales");
17
18 while (Personas.next()) {
19 String DNI = Personas.getString("DNI");
20 if (DNI.equalsIgnoreCase(DNIPedido)){
21 Posicion = Personas.getRow();
22 String Nombre = Personas.getString("Nombre");
152 © JESÚS BOBADILLA SANCHO
7.7.5 Modificación
1 import java.sql.*;
2
3 public class ObModificacion {
4
5 ObModificacion(int PosicionBuscada, ObRegistro Datos) {
6 try{
7 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
8 String BaseDeDatos = "jdbc:odbc:NombreLogico";
9 Connection Conexion =
10 DriverManager.getConnection(BaseDeDatos);
11 Statement SentenciaSQL = Conexion.createStatement(
12 ResultSet.TYPE_SCROLL_INSENSITIVE,
13 ResultSet.CONCUR_UPDATABLE);
14 ResultSet Personas = SentenciaSQL.executeQuery("SELECT
15 * FROM DatosPersonales");
16
17 Personas.absolute(PosicionBuscada);
18 Personas.updateString("DNI",Datos.DameDNI());
19 Personas.updateString("Nombre",Datos.DameNombre());
20 Personas.updateString("Apellido",Datos.DameApellido());
21 Personas.updateInt("Edad",Datos.DameEdad());
22 Personas.updateRow();
23
24 Personas.close();
25 Conexion.close();
26 SentenciaSQL.close();
27 }
28 catch (ClassNotFoundException e) {
29 System.out.println("Clase no encontrada");
30 }
31 catch (SQLException e) {
32 System.out.println(e);
33 }
34 }
35
36 }
154 © JESÚS BOBADILLA SANCHO
7.7.6 Borrado
1 import java.sql.*;
2
3 public class ObBorrado {
4
5 ObBorrado(int PosicionBuscada){
6 try{
7 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
8 String BaseDeDatos = "jdbc:odbc:NombreLogico";
9 Connection Conexion =
10 DriverManager.getConnection(BaseDeDatos);
11 Statement SentenciaSQL = Conexion.createStatement(
12 ResultSet.TYPE_SCROLL_INSENSITIVE,
13 ResultSet.CONCUR_UPDATABLE);
14 ResultSet Personas = SentenciaSQL.executeQuery("SELECT
15 * FROM DatosPersonales");
16
17 Personas.absolute(PosicionBuscada);
18 Personas.deleteRow();
19
20 Personas.close();
21 Conexion.close();
22 SentenciaSQL.close();
23 }
24 catch (ClassNotFoundException e) {
25 System.out.println("Clase no encontrada");
26 }
27 catch (SQLException e) {
28 System.out.println(e);
29 }
30 }
31
32 }
JESÚS BOBADILLA SANCHO 155
7.7.7 Listado
1 import java.sql.*;
2 import java.awt.TextArea;
3
4 public class ObListado {
5
6 ObListado(TextArea AreaDeListado){
7 String DNI, Nombre, Apellido, Linea;
8 int Edad, Posicion;
9 try{
10 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
11 String BaseDeDatos = "jdbc:odbc:NombreLogico";
12 Connection Conexion =
13 DriverManager.getConnection(BaseDeDatos);
14 Statement SentenciaSQL = Conexion.createStatement();
15 ResultSet Personas = SentenciaSQL.executeQuery("SELECT
16 * FROM DatosPersonales");
17 AreaDeListado.setText("");
18
19 while (Personas.next()) {
20 DNI = Personas.getString("DNI");
21 Nombre = Personas.getString("Nombre");
22 Apellido = Personas.getString("Apellido");
23 Edad = Personas.getInt("Edad");
24 Posicion = Personas.getRow();
25 Linea = DNI+", "+Nombre+" "+Apellido+",
26 "+String.valueOf(Edad);
27 AreaDeListado.append(String.valueOf(Posicion)+":
28 "+Linea+"\n");
29 }
30
31 Personas.close();
32 Conexion.close();
33 SentenciaSQL.close();
34 }
35 catch (ClassNotFoundException e) {
156 © JESÚS BOBADILLA SANCHO
36 System.out.println("Clase no encontrada");
37 }
38 catch (SQLException e) {
39 System.out.println(e);
40 }
41 }
42
43 }
7.7.8 Posicionamiento
En buena parte de las clases anteriores hemos trabajado con la posición del
cursor en la tabla. La clase ObPosicionamiento nos permite modificar dicho cursor a
partir de la posición actual (que suministramos como parámetro en el constructor).
Hay que tener en cuenta que en todas las clases suministradas, la base de datos se
cierra después de realizar las acciones pertinentes (inserción, modificación, ...), por
lo que la posición del cursor de la tabla se pierde; esta es la razón por la que
debemos guardar esta posición en un ámbito superior y pasarla a la clase a través del
parámetro Posicion del constructor (línea 8).
1 import java.sql.*;
2
3 public class ObPosicionamiento {
4
5 private ObRegistro DatosPersona;
6 private int Posicion;
7
8 ObPosicionamiento(String Accion, int Posicion) {
9 int IDAccion,Edad;
10 String DNI,Nombre,Apellido;
11 boolean PosicionCorrecta=false;
12
13 try{
14 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
15 String BaseDeDatos = "jdbc:odbc:NombreLogico";
16 Connection Conexion =
17 DriverManager.getConnection(BaseDeDatos);
18 Statement SentenciaSQL = Conexion.createStatement(
19 ResultSet.TYPE_SCROLL_INSENSITIVE,
20 ResultSet.CONCUR_UPDATABLE);
21 ResultSet Personas = SentenciaSQL.executeQuery("SELECT
22 * FROM DatosPersonales");
23
24 Personas.absolute(Posicion);
25
26 IDAccion = Integer.parseInt(Accion);
27 switch (IDAccion) {
28 case 0: //
29 PosicionCorrecta = Personas.last();
30 break;
31 case 1:
32 PosicionCorrecta = Personas.first();
33 break;
34 case 2:
35 PosicionCorrecta = Personas.relative(-5);
36 break;
37 case 3:
38 PosicionCorrecta = Personas.previous();
39 break;
40 case 4:
41 PosicionCorrecta = Personas.next();
42 break;
43 case 5:
44 PosicionCorrecta = Personas.relative(+5);
45 break;
46 }
47 if (PosicionCorrecta) {
48 this.Posicion = Personas.getRow();
158 © JESÚS BOBADILLA SANCHO
49 DNI = Personas.getString("DNI");
50 Nombre = Personas.getString("Nombre");
51 Apellido = Personas.getString("Apellido");
52 Edad = Personas.getInt("Edad");
53 } else {
54 this.Posicion = Posicion;
55 DNI = "----";
56 Nombre = "----";
57 Apellido = "----";
58 Edad = 0;
59 }
60 DatosPersona = new ObRegistro(DNI,Nombre,Apellido,Edad);
61
62 Personas.close();
63 Conexion.close();
64 SentenciaSQL.close();
65 }
66 catch (ClassNotFoundException e) {
67 System.out.println("Clase no encontrada");
68 }
69 catch (SQLException e) {
70 System.out.println(e);
71 }
72 }
73
74 public int Posicion() {
75 return Posicion;
76 }
77
78 public ObRegistro DameDatos() {
79 return DatosPersona;
80 }
81
82 }
Las clases que hemos desarrollado nos pueden servir para diseñar diferentes
aplicaciones de acceso a la tabla DatosPersonales. Como ejemplo de aplicación que
hace uso de las mismas, se proporciona la clase GUIAccesoBD, que permite a un
usuario realizar consultas, inserciones, borrados, modificaciones y recorridos en
nuestra base de datos.
JESÚS BOBADILLA SANCHO 159
import java.awt.*;
import java.awt.event.*;
GUIAccesoBD() {
// Definicion del interfaz grafico de usuario
// Establecimiento de los “Listeners”
}
24 Panel(new FlowLayout(FlowLayout.CENTER));
25
26 Label EtiquetaDNI = new Label("DNI");
27 Label EtiquetaNombre = new Label("Nombre");
28 Label EtiquetaApellido = new Label("Apellido");
29 Label EtiquetaEdad = new Label("Edad");
30
31 CampoDNI = new TextField(9);
32 CampoNombre = new TextField(15);
33 CampoApellido = new TextField(30);
34 CampoEdad = new TextField(3);
35
36 AreaDeListado = new TextArea();
37
38 Button BotonConsultar = new Button("Consultar");
39 Button BotonInsertar = new Button("Insertar");
40 Button BotonModificar = new Button("Modificar");
41 Button BotonBorrar = new Button("Borrar");
42 Button BotonListar = new Button("Listar");
43
44 Button BotonPrimero = new Button("|<");
45 BotonPrimero.setName("1");
46 Button BotonMenosCinco = new Button("--");
47 BotonMenosCinco.setName("2");
48 Button BotonAnterior = new Button("-");
49 BotonAnterior.setName("3");
50 Button BotonSiguiente = new Button("+");
51 BotonSiguiente.setName("4");
52 Button BotonMasCinco = new Button("++");
53 BotonMasCinco.setName("5");
54 Button BotonUltimo = new Button(">|");
55 BotonUltimo.setName("0");
56
57 PanelIzq .add(PanelDNI);
58 PanelIzq .add(PanelNombre);
59 PanelIzq .add(PanelApellido);
60 PanelIzq .add(PanelEdad);
61 PanelIzq .add(PanelAccion);
62 PanelIzq .add(PanelControles);
63 MiPanel.add(PanelIzq);
64 MiPanel.add(AreaDeListado);
65
66 PanelDNI.add (EtiquetaDNI); PanelDNI.add(CampoDNI);
67 PanelNombre.add (EtiquetaNombre);
68 PanelNombre.add(CampoNombre);
69 PanelApellido.add (EtiquetaApellido);
70 PanelApellido.add(CampoApellido);
71 PanelEdad.add (EtiquetaEdad); PanelEdad.add(CampoEdad);
162 © JESÚS BOBADILLA SANCHO
72 PanelAccion.add(BotonConsultar);
73 PanelAccion.add(BotonInsertar);
74 PanelAccion.add(BotonModificar);
75 PanelAccion.add(BotonBorrar);
76 PanelAccion.add(BotonListar);
77 PanelControles.add(BotonPrimero);
78 PanelControles.add(BotonMenosCinco);
79 PanelControles.add(BotonAnterior);
80 PanelControles.add(BotonSiguiente);
81 PanelControles.add(BotonMasCinco);
82 PanelControles.add(BotonUltimo);
83
84 BotonConsultar.addActionListener(new ConsultarDatos());
85 BotonInsertar.addActionListener(new InsertarDatos());
86 BotonModificar.addActionListener(new ModificarDatos());
87 BotonBorrar.addActionListener(new BorrarDatos());
88 BotonListar.addActionListener(new ListarDatos());
89
90 BotonPrimero.addActionListener(new Controles());
91 BotonMenosCinco.addActionListener(new Controles());
92 BotonAnterior.addActionListener(new Controles());
93 BotonSiguiente.addActionListener(new Controles());
94 BotonMasCinco.addActionListener(new Controles());
95 BotonUltimo.addActionListener(new Controles());
96 }
97
98
99 public Panel DamePanel() {
100 return MiPanel;
101 }
Integer.parseInt(CampoEdad.getText()));
145
146 ObModificacion InstanciaModificacion = new
147 ObModificacion(PosicionBuscada, InstanciaFila);
148 CampoDNI.setText(""); CampoNombre.setText("");
149 CampoApellido.setText(""); CampoEdad.setText("");
150 } else {
151 CampoNombre.setText("------");
152 CampoApellido.setText("------");
153 CampoEdad.setText("---");
154 }
155 }
156 }
171 CampoApellido.setText("------");
172 CampoEdad.setText("---");
173 }
174 }
175 }
Por último se obtienen los datos de la nueva posición y, con ellos, se crea
un objeto de tipo ObRegistro (líneas 191 y 192), actualizando los campos del GUI
(líneas 193 a 197) y la posición del cursor que mantenemos en la aplicación (línea
198).
Los “metadatos” que se utilizan más habitualmente son los que podemos
conseguir utilizando el interfaz ResultSetMetaData. Una vez que disponemos de un
objeto de tipo ResultSet, podemos definir una instancia de la clase
ResultSetMetaData, utilizando el método getMetaData perteneciente al interfaz
ResultSet; en las líneas 14 y 15 del siguiente ejemplo se utiliza este mecanismo.
Información Método
Número de campos int getColumnCount()
Tamaño máximo del campo int getColumnDisplaySize(int Columna)
Nombre de un campo String getColumnName(int Columna)
Tipo SQL de un campo int getColumnType(int Columna)
Denominación del tipo de un campo String getColumnTypeName(int Columna)
Número de dígitos decimales int getPrecision(int Columna)
Indica si el campo puede tomar el valor null int isNullable(int Columna)
Indica si el campo no puede ser escrito boolean isReadOnly(int Columna)
Indica si el campo puede ser usado en una boolean isSearchable(int Columna)
cláusula where
Indica si se puede realizar una escritura en el boolean isWritable(int Columna)
campo
El bucle de la línea 18 nos sirve para recorrer todos los campos de la tabla
DatosPersonales, obteniendo el nombre (getColumnName), tipo
(getColumnTypeName) y tamaño máximo (getColumnDisplaySize) de cada uno de
ellos (líneas 20 a 24).
1 import java.sql.*;
2
3 public class MetaDatos {
4
5 public static void main(String[] args){
6 try{
7 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
8 String BaseDeDatos = "jdbc:odbc:NombreLogico";
9 Connection Conexion =
10 DriverManager.getConnection(BaseDeDatos);
11 Statement SentenciaSQL = Conexion.createStatement();
12 ResultSet Personas = SentenciaSQL.
13 executeQuery("SELECT * FROM DatosPersonales");
14 ResultSetMetaData DatosInternos =
15 Personas.getMetaData();
16 int NumeroDeColumnas= DatosInternos.getColumnCount();
17
18 for (int Columna=1;Columna<=NumeroDeColumnas;
19 Columna++) {
JESÚS BOBADILLA SANCHO 169
20 String Nombre=DatosInternos.getColumnName(Columna);
21 String Tipo =
22 DatosInternos.getColumnTypeName(Columna);
23 int Tamanio =
24 DatosInternos.getColumnDisplaySize(Columna);
25 System.out.println(Nombre+", "+Tipo+", "+Tamanio);
26 }
27
28 Personas.close();
29 Conexion.close();
30 SentenciaSQL.close();
31 }
32 catch (ClassNotFoundException e) {
33 System.out.println("Clase no encontrada");
34 }
35 catch (SQLException e) {
36 System.out.println(e);
37 }
38 }
39
40 }
1 import java.sql.*;
2
3 public class Borrado2 {
4
5 public static void main(String[] args){
6 try{
7 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
8 String BaseDeDatos = "jdbc:odbc:NombreLogico";
9 Connection Conexion =
10 DriverManager.getConnection(BaseDeDatos);
11 Statement SentenciaSQL = Conexion.createStatement(
12 ResultSet.TYPE_SCROLL_INSENSITIVE,
13 ResultSet.CONCUR_UPDATABLE);
14
15 int Borrados = SentenciaSQL.executeUpdate("DELETE FROM
16 DatosPersonales WHERE Nombre='Luis'");
17
18 System.out.println(Borrados+" registros borrados");
19 Conexion.close();
20 SentenciaSQL.close();
21 }
22 catch (ClassNotFoundException e) {
23 System.out.println("Clase no encontrada");
24 }
25 catch (SQLException e) {
26 System.out.println(e);
27 } } }
JESÚS BOBADILLA SANCHO 171
1 import java.sql.*;
2
3 public class SQLInteractivo {
4
5 public static void main(String[] args){
6 String DNI,Nombre,Apellido; int Edad;
7 try{
8 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
9 String BaseDeDatos = "jdbc:odbc:NombreLogico";
10 Connection Conexion =
11 DriverManager.getConnection(BaseDeDatos);
12 Statement SentenciaSQL = Conexion.createStatement(
13 ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
14
15 if (args[0].startsWith("UPDATE")||
16 args[0].startsWith("DELETE")||
17 args[0].startsWith("INSERT")) {
18 int ElementosVariados =
19 SentenciaSQL.executeUpdate(args[0]);
20 System.out.println(ElementosVariados+" elementos han
172 © JESÚS BOBADILLA SANCHO
SvAccesoBD.htm
SvAccesoBD
ObListado ObConsulta
ObBorrado ObInserccion
ObModificacion
ObPosicionamiento
ObRegistro
1 import java.sql.*;
2 import java.awt.TextArea;
3
4 public class ObListado {
5
6 private String Resultado="";
7
8 ObListado(){
9 String DNI, Nombre, Apellido, Linea;
10 int Edad, Posicion;
11 try{
12 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
13 String BaseDeDatos = "jdbc:odbc:NombreLogico";
14 Connection Conexion =
15 DriverManager.getConnection(BaseDeDatos);
16 Statement SentenciaSQL = Conexion.createStatement();
17 ResultSet Personas = SentenciaSQL.executeQuery("SELECT
JESÚS BOBADILLA SANCHO 175
18 * FROM DatosPersonales");
19
20 while (Personas.next()) {
21 DNI = Personas.getString("DNI");
22 Nombre = Personas.getString("Nombre");
23 Apellido = Personas.getString("Apellido");
24 Edad = Personas.getInt("Edad");
25 Posicion = Personas.getRow();
26 Linea = DNI+", "+Nombre+" "+Apellido+",
27 "+String.valueOf(Edad);
28 Resultado=Resultado+String.valueOf(Posicion)+
29 ": "+Linea+"\n";
30 }
31
32 Personas.close();
33 Conexion.close();
34 SentenciaSQL.close();
35 }
36 catch (ClassNotFoundException e) {
37 System.out.println("Clase no encontrada");
38 }
39 catch (SQLException e) {
40 System.out.println(e);
41 }
42 }
43
44 public String DameResultado(){
45 return Resultado;
46 }
47
48 }
<html>
<body>
<table border=1>
<tr>
<td>
176 © JESÚS BOBADILLA SANCHO
<form method="get"
action="http://localhost:8080/examples/
servlet/SvAccesoBD" >
DNI: <input type="text" name="DNI"> <br>
Nombre: <input type="text" name="Nombre"> <br>
Apellido: <input type="text" name="Apellido"> <br>
Edad: <input type="text" name="Edad"> <br><br>
<input type="submit" value="Consultar"
name="BotonConsultar">
<input type="submit" value="Insertar"
name="BotonInsertar">
<input type="submit" value="Modificar"
name="BotonModificar">
<input type="submit" value="Borrar" name="BotonBorrar">
<input type="submit" value="Listar" name="BotonListar">
<br>
<center>
<input type="submit" value=" |< "
name="BotonPrimero">
<input type="submit" value=" -- "
name="BotonMenosCinco">
<input type="submit" value=" - "
name="BotonAnterior">
<input type="submit" value=" + "
name="BotonSiguiente">
<input type="submit" value=" ++ "
name="BotonMasCinco">
<input type="submit" value=" >| "
name="BotonUltimo">
</center>
</td>
<td>
<textarea name="AreaDeListado" rows="10"
cols="35"></textarea>
</td>
</tr>
</form>
</table>
</body>
</html>
JESÚS BOBADILLA SANCHO 177
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4
5 public class SvAccesoBD extends HttpServlet {
6
7 private int PosicionBuscada = 1;
8 private String AreaDeListado="";
9 PrintWriter out;
10
11 synchronized public void doGet(HttpServletRequest request,
12 HttpServletResponse response)
13 throws IOException, ServletException {
14
15 String DNI = request.getParameter("DNI");
16 String Nombre = request.getParameter("Nombre");
17 String Apellido = request.getParameter("Apellido");
18 String Edad = request.getParameter("Edad");
19
20 String BotonConsultar =
21 request.getParameter("BotonConsultar");
22 String BotonInsertar =
23 request.getParameter("BotonInsertar");
24 String BotonModificar =
25 request.getParameter("BotonModificar");
26 String BotonBorrar =
27 request.getParameter("BotonBorrar");
28 String BotonListar =
29 request.getParameter("BotonListar");
30
31 String BotonPrimero =
32 request.getParameter("BotonPrimero");
33 String BotonMenosCinco =
34 request.getParameter("BotonMenosCinco");
35 String BotonAnterior =
36 request.getParameter("BotonAnterior");
37 String BotonSiguiente =
38 request.getParameter("BotonSiguiente");
39 String BotonMasCinco =
40 request.getParameter("BotonMasCinco");
41 String BotonUltimo =
42 request.getParameter("BotonUltimo");
43
44 AreaDeListado = request.getParameter("AreaDeListado");
45
JESÚS BOBADILLA SANCHO 179
46 response.setContentType("text/html");
47 out = response.getWriter();
48 out.println("<html>");
49 out.println("<body>");
50
51 if (BotonConsultar!=null)
52 ConsultarDatos(DNI);
53 if (BotonInsertar!=null)
54 InsertarDatos(DNI,Nombre,Apellido,Edad);
55 if (BotonModificar!=null)
56 ModificarDatos(DNI,Nombre,Apellido,Edad);
57 if (BotonBorrar!=null)
58 BorrarDatos(DNI);
59 if (BotonListar!=null)
60 ListarDatos(DNI);
61
62 if (BotonPrimero!=null)
63 Controles("1");
64 if (BotonMenosCinco!=null)
65 Controles("2");
66 if (BotonAnterior!=null)
67 Controles("3");
68 if (BotonSiguiente!=null)
69 Controles("4");
70 if (BotonMasCinco!=null)
71 Controles("5");
72 if (BotonUltimo!=null)
73 Controles("0");
74
75 out.println("</body>");
76 out.println("</html>");
77 }
78
79
80 private void ConsultarDatos(String DNI) {
81 ObConsulta InstanciaConsulta = new ObConsulta(DNI);
82 PosicionBuscada=InstanciaConsulta.PosicionEncontrada();
83 if (PosicionBuscada!=0) {
84 ObRegistro InstanciaFila =
85 InstanciaConsulta.DameDatos();
86 GenerarRespuesta(InstanciaFila.DameDNI(),
87 InstanciaFila.DameNombre(),
88 InstanciaFila.DameApellido(),
89 String.valueOf(InstanciaFila.DameEdad()));
90 } else {
91 GenerarRespuesta(DNI,"----","-----","---");
92 PosicionBuscada = 1;
93 }
94 }
180 © JESÚS BOBADILLA SANCHO
95
96
97 public void ListarDatos(String DNI) {
98 ObListado InstanciaListado = new ObListado();
99 AreaDeListado = InstanciaListado.DameResultado();
100 ConsultarDatos(DNI);
101 PosicionBuscada = 1;
102 }
103
104
105 public void BorrarDatos(String DNI){
106 ObConsulta InstanciaConsulta = new ObConsulta(DNI);
107 PosicionBuscada =
108 InstanciaConsulta.PosicionEncontrada();
109
110 if (PosicionBuscada!=0) {
111 ObBorrado InstanciaBorrado =
112 new ObBorrado(PosicionBuscada);
113 GenerarRespuesta("","","","");
114 } else {
115 GenerarRespuesta("----","----","----","----");
116 }
117 PosicionBuscada = 1;
118 }
119
120
121 public void ModificarDatos(String DNI, String Nombre,
122 String Apellido, String Edad) {
123 ObConsulta InstanciaConsulta = new ObConsulta(DNI);
124 PosicionBuscada =
125 InstanciaConsulta.PosicionEncontrada();
126
127 if (PosicionBuscada!=0) {
128 ObRegistro InstanciaFila = new ObRegistro(DNI,
129 Nombre, Apellido, Integer.parseInt(Edad));
130 ObModificacion InstanciaModificacion =
131 new ObModificacion(PosicionBuscada, InstanciaFila);
132 GenerarRespuesta(DNI,Nombre,Apellido,Edad);
133 } else {
134 GenerarRespuesta("----","----","----","----");
135 PosicionBuscada = 1;
136 }
137 }
138
139
140 public void InsertarDatos(String DNI, String Nombre,
141 String Apellido, String Edad) {
142 ObRegistro InstanciaFila = new ObRegistro(DNI,
143 Nombre, Apellido, Integer.parseInt(Edad));
JESÚS BOBADILLA SANCHO 181
No Sí No No
Sí Sí No Sí
Sí No Sí Sí
No Sí Sí No
Sí Sí Sí Sí
GeneraTests.htm
<html>
<body>
JESÚS BOBADILLA SANCHO 185
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4 import java.sql.*;
5
6 public class GeneraTests extends HttpServlet {
7
8 public void doGet(HttpServletRequest request,
9 HttpServletResponse response)
10 throws IOException, ServletException {
11 String Leccion = request.getParameter("Leccion");
12
13 response.setContentType("text/html");
14 PrintWriter out = response.getWriter();
15 out.println("<html>");
16 out.println("<body>");
17 out.println("<h1>Lección: "+Leccion+"</h1>");
18 out.println("<form action=GeneraRespuestas
19 method=get>");
20 out.println("<br><input type=hidden name=Leccion
21 value="+Leccion+">");
22 GeneraListado(out,Leccion);
23 out.println("<br><input type=submit>");
24 out.println("</form>");
25 out.println("</body>");
26 out.println("</html>");
27 }
28
29
30 private void GeneraListado(PrintWriter out,
31 String Leccion){
32 String Pregunta,Respuesta1,Respuesta2,
33 Respuesta3,Respuesta4;
34 int NumPregunta;
35 try{
36 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
37 String BaseDeDatos = "jdbc:odbc:Tests";
38 Connection Conexion =
39 DriverManager.getConnection(BaseDeDatos);
40 Statement SentenciaSQL = Conexion.createStatement();
41 ResultSet Preguntas = SentenciaSQL.executeQuery(
42 "SELECT * FROM Test WHERE Leccion="+Leccion);
JESÚS BOBADILLA SANCHO 187
43
44 while (Preguntas.next()) {
45 NumPregunta = Preguntas.getInt("NumPregunta");
46 Pregunta = Preguntas.getString("Pregunta");
47 Respuesta1 = Preguntas.getString("Respuesta1");
48 Respuesta2 = Preguntas.getString("Respuesta2");
49 Respuesta3 = Preguntas.getString("Respuesta3");
50 Respuesta4 = Preguntas.getString("Respuesta4");
51
52 out.println("<h2>"+NumPregunta+". "+
53 Pregunta+"</h2>");
54 out.println("<input type=checkbox value=true
55 name=R"+NumPregunta+"a>"+Respuesta1+"<br>");
56 out.println("<input type=checkbox value=true
57 name=R"+NumPregunta+"b>"+Respuesta2+"<br>");
58 out.println("<input type=checkbox value=true
59 name=R"+NumPregunta+"c>"+Respuesta3+"<br>");
60 out.println("<input type=checkbox value=true
61 name=R"+NumPregunta+"d>"+Respuesta4+"<br>");
62 }
63
64 Preguntas.close();
65 Conexion.close();
66 SentenciaSQL.close();
67 }
68 catch (ClassNotFoundException e) {
69 System.out.println("Clase no encontrada");
70 }
71 catch (SQLException e) {
72 System.out.println(e);
73 }
74 }
75 }
188 © JESÚS BOBADILLA SANCHO
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4 import java.sql.*;
5
6 public class GeneraRespuestas extends HttpServlet {
7
8 public void doGet(HttpServletRequest request,
9 HttpServletResponse response)
10 throws IOException, ServletException {
11 String Leccion = request.getParameter("Leccion");
12
13 response.setContentType("text/html");
14 PrintWriter out = response.getWriter();
15 out.println("<html>");
16 out.println("<body>");
JESÚS BOBADILLA SANCHO 189
17 out.println("<h1>Lección: "+Leccion+"</h1>");
18
19 GeneraRespuestas(request,out,Leccion);
20
21 out.println("</body>");
22 out.println("</html>");
23 }
24
25
26 private void GeneraRespuestas(HttpServletRequest
27 request,PrintWriter out,String Leccion){
28 boolean SolucionA,SolucionB,SolucionC,SolucionD,
29 RaUsuario,RbUsuario,RcUsuario,RdUsuario,Acertado;
30 int NumPregunta;
31 try{
32 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
33 String BaseDeDatos = "jdbc:odbc:Tests";
34 Connection Conexion =
35 DriverManager.getConnection(BaseDeDatos);
36 Statement SentenciaSQL = Conexion.createStatement();
37 ResultSet Preguntas = SentenciaSQL.executeQuery(
38 "SELECT * FROM Test WHERE Leccion="+Leccion);
39
40 while (Preguntas.next()) {
41 NumPregunta = Preguntas.getInt("NumPregunta");
42 SolucionA = Preguntas.getBoolean("Solucion1");
43 SolucionB = Preguntas.getBoolean("Solucion2");
44 SolucionC = Preguntas.getBoolean("Solucion3");
45 SolucionD = Preguntas.getBoolean("Solucion4");
46
47 RaUsuario = new Boolean(request.getParameter(
48 "R"+NumPregunta+"a")).booleanValue();
49 RbUsuario = new Boolean(request.getParameter(
50 "R"+NumPregunta+"b")).booleanValue();
51 RcUsuario = new Boolean(request.getParameter(
52 "R"+NumPregunta+"c")).booleanValue();
53 RdUsuario = new Boolean(request.getParameter(
54 "R"+NumPregunta+"d")).booleanValue();
55
56 Acertado = (SolucionA==RaUsuario &&
57 SolucionB==RbUsuario &&
58 SolucionC==RcUsuario &&
59 SolucionD==RdUsuario);
60
61 out.println("<h2>"+NumPregunta+". "+
62 Acertado+"</h2>");
63 }
64
65 Preguntas.close();
190 © JESÚS BOBADILLA SANCHO
66 Conexion.close();
67 SentenciaSQL.close();
68 }
69 catch (ClassNotFoundException e) {
70 System.out.println("Clase no encontrada");
71 }
72 catch (SQLException e) {
73 System.out.println(e);
74 }
75 }
76
77 }
JESÚS BOBADILLA SANCHO 191
ForoTema.htm
ForoTema
ForoInserccionTema
ForoBorradoTema
ForoAccesoTema
ForoInsertarOpTema
ForoAccesoBD
Existe una base de datos “Foro”, que albergará la lista de los temas abiertos
a discusión en cada momento (en la tabla Temas), además de una tabla por cada
tema de discusión, conteniendo las opiniones de los usuarios; cada registro de la
tabla Temas representa un tema del foro. Sus campos son:
• Identificador: alfanumérico de 10 posiciones
• Descripcion: alfanumérico de 80 posiciones
192 © JESÚS BOBADILLA SANCHO
Cada tema de discusión tendrá asociada una tabla cuyo nombre haremos
coincidir con el identificador elegido en la tabla Temas. Las tablas de temas
contendrán un solo campo Opinion, de tipo alfanumérico de 80 posiciones. Estas
tablas se deben crear dinámicamente, según los usuarios van introduciendo temas de
discusión.
Foro
Temas
Identificador Descripcion
PenaMuerte
Opinion
AbrigoPiel
Opinion
<html>
<body>
<h2> Operaciones sobre temas </h2>
<form action="http://localhost:8080/examples/
servlet/ForoTema" method="get">
<input type="radio" name=Operacion checked
value=Consulta> Consultar temas <br>
<input type="radio" name=Operacion value=Insercion>
Insertar tema <br>
<input type="radio" name=Operacion value=Borrado>
Borrar tema<br>
El método Lista (línea 35) nos proporciona una tabla HTML con los datos
obtenidos tras ejecutar la sentencia SQL de selección que le pasemos como
argumento. Esta ejecución se realiza utilizando el método executeQuery (línea 38),
que nos devuelve un objeto de tipo RecordSet.
Con el fin de listar todos los campos del objeto Personas, de tipo ResultSet,
hacemos uso del método getMetaData, (línea 40) para obtener un objeto
ResultSetMetaData y, a través de él, conocer el número de campos
(getColumnCount, línea 41) y sus nombres (getColumnName, línea 49). Este método
nos sirve para obtener listados de tablas cuyos campos sean de tipo alfanumérico
(siempre usamos el método getString, línea 50).
1 import java.sql.*;
2 import java.io.*;
3 import java.awt.TextArea;
JESÚS BOBADILLA SANCHO 195
4
5 public class ForoAccesoBD {
6
7 private Statement SentenciaSQL;
8 private Connection Conexion;
9
10 ForoAccesoBD(String NombreLogico){
11 try{
12 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
13 String BaseDeDatos = "jdbc:odbc:"+NombreLogico;
14 Conexion = DriverManager.getConnection(BaseDeDatos);
15 SentenciaSQL = Conexion.createStatement(
16 ResultSet.TYPE_SCROLL_INSENSITIVE,
17 ResultSet.CONCUR_UPDATABLE);
18 } catch (ClassNotFoundException e) {
19 System.out.println("Clase no encontrada");
20 } catch (SQLException e) {
21 System.out.println(e);
22 }
23 } // Constructor
24
25
26 synchronized public void Ejecuta(String Sql) {
27 try{
28 int RegistrosInvolucrados =
29 SentenciaSQL.executeUpdate(Sql);
30 } catch (SQLException e) {
31 System.out.println(e);
32 }
33 }
34
35 synchronized public void Lista(String Sql,
36 PrintWriter out) {
37 try{
38 ResultSet Personas = SentenciaSQL.executeQuery(Sql);
39 ResultSetMetaData DatosInternos =
40 Personas.getMetaData();
41 int NumeroDeColumnas=DatosInternos.getColumnCount();
42
43 out.println("<table border=1>");
44 while (Personas.next()) {
45 out.println("<tr>");
46 for (int Columna=1;
47 Columna<=NumeroDeColumnas;Columna++) {
48 String Nombre =
49 DatosInternos.getColumnName(Columna);
50 String Contenido = Personas.getString(Nombre);
51 out.println("<td>"+Contenido+"</td>");
52 }
196 © JESÚS BOBADILLA SANCHO
53 out.println("</tr>");
54 }
55 out.println("</table>");
56 Personas.close();
57 } catch (SQLException e) {
58 System.out.println(e);
59 }
60 }
61
62
63 synchronized public String[] CreaLista(String
64 Tabla,String Campo) {
65 String[] Lista=null;
66 try {
67 String Sql = "SELECT "+Campo+" FROM "+Tabla;
68 ResultSet Personas = SentenciaSQL.executeQuery(Sql);
69 Personas.last();
70 int Registros=Personas.getRow();
71 Lista = new String[Registros];
72 Personas.beforeFirst();
73
74 while (Personas.next())
75 if (!Personas.isAfterLast())
76 Lista[Personas.getRow()-1]=Personas.getString(Campo);
77
78 } catch (SQLException e) {
79 System.out.println(e);
80 }
81 return Lista;
82 }
83
84
85 synchronized public void Cierra() {
86 try{
87 SentenciaSQL.close();
88 Conexion.close();
89 } catch (SQLException e) {
90 System.out.println(e);
91 }
92 }
93
94 }
JESÚS BOBADILLA SANCHO 197
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4
5 public class ForoTema extends HttpServlet {
6
7 synchronized public void doGet(HttpServletRequest
8 request, HttpServletResponse response)
9 throws IOException, ServletException {
10 String Operacion = request.getParameter("Operacion");
11
12 PrintWriter out = response.getWriter();
13 out.println("<html>");
14 out.println("<body>");
15
16 if (Operacion.equals("Insercion")) {
17 out.println("<h2> Insercción de un tema </h2>");
18 out.println("<form action='http://localhost:8080/
19 examples/servlet/ForoInserccionTema' method=get>");
20 out.println("Identificador: <input type=text
21 name=Identificador> <br>");
22 out.println("Descripción: <input type=text
23 name=Descripcion> <br><br>");
24 out.println("<input type=submit value='Enviar tema'>
25 <br>");
26 out.println("</form>");
27 }
28
29 if (Operacion.equals("Borrado")||
30 Operacion.equals("Acceso")||
31 Operacion.equals("InsertarOp")){
32 out.println("<form action='http://localhost:8080/
33 examples/servlet/Foro"+Operacion+"Tema' method=get>");
34 ForoAccesoBD UtilidadesBD = new ForoAccesoBD("Foro");
35 String[] Identificadores =
36 UtilidadesBD.CreaLista("Temas","Identificador");
37 UtilidadesBD.Cierra();
38
39 out.println("<select name=Temas>");
40 for (int i=0;i<Identificadores.length;i++)
JESÚS BOBADILLA SANCHO 199
41 out.println("<option>"+Identificadores[i]+
42 "</option>");
43 out.println("</select><br><br>");
44
45 if (Operacion.equals("InsertarOp")) {
46 out.println("<textarea rows=3 col=20
47 name=Opinion>Escribe tu opinión</textarea><br>");
48 }
49 out.println("<input type=submit value='Enviar'> <br>");
50 out.println("</form>");
51 }
52
53 if (Operacion.equals("Consulta")) {
54 ForoAccesoBD UtilidadesBD = new ForoAccesoBD("Foro");
55 UtilidadesBD.Lista("SELECT * FROM Temas",out);
56 UtilidadesBD.Cierra();
57 }
58
59 out.println("</body>");
60 out.println("</html>");
61 }
62 }
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4
5 public class ForoInserccionTema extends HttpServlet {
6
7 synchronized public void doGet(HttpServletRequest
8 request, HttpServletResponse response)
9 throws IOException, ServletException {
10 String Identificador =
11 request.getParameter("Identificador");
12 String Descripcion =
13 request.getParameter("Descripcion");
14
15 ForoAccesoBD TemasForo= new ForoAccesoBD("Foro");
16 TemasForo.Ejecuta("INSERT INTO Temas VALUES
17 ('"+Identificador+"','"+Descripcion+"')");
18
19 TemasForo.Ejecuta("CREATE TABLE "+Identificador+
20 " (Opinion CHAR(80))");
21
22 response.setContentType("text/html");
23 PrintWriter out = response.getWriter();
24 out.println("<html>");
25 out.println("<body>");
26 out.println("Tema: "+Identificador+" insertado <br>");
27 TemasForo.Lista("SELECT * FROM Temas",out);
28 out.println("</body>");
29 out.println("</html>");
30
31 TemasForo.Cierra();
32 }
33 }
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4
5 public class ForoBorradoTema extends HttpServlet {
6
7 synchronized public void doGet(HttpServletRequest
8 request, HttpServletResponse response)
9 throws IOException, ServletException {
10 String Tema = request.getParameter("Temas");
11
12 ForoAccesoBD TemasForo= new ForoAccesoBD("Foro");
13 TemasForo.Ejecuta("DELETE FROM Temas WHERE
14 Identificador='"+Tema+"'");
15 TemasForo.Ejecuta("DROP TABLE "+Tema);
16
17 response.setContentType("text/html");
18 PrintWriter out = response.getWriter();
19 out.println("<html>");
20 out.println("<body>");
21 out.println("Tema: "+Tema+" borrado <br>");
22 TemasForo.Lista("SELECT * FROM Temas",out);
23 out.println("</body>");
24 out.println("</html>");
25
26 TemasForo.Cierra();
27 }
28 }
Una vez que el usuario ha seleccionado el tema que desea consultar (usando
la lista desplegable generada por la clase ForoTema), el método doGet de
ForoAccesoTema puede recoger el tema escogido (línea 10). Con esta información
nos resulta muy sencillo crear un listado de la tabla correspondiente (líneas 12 y 19).
Como se puede observar, nuestra clase ForoAccesoBD nos simplifica mucho la
programación y evita la repetición innecesaria de código.
202 © JESÚS BOBADILLA SANCHO
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4
5 public class ForoAccesoTema extends HttpServlet {
6
7 synchronized public void doGet(HttpServletRequest
8 request, HttpServletResponse response)
9 throws IOException, ServletException {
10 String Tema = request.getParameter("Temas");
11
12 ForoAccesoBD TemasForo= new ForoAccesoBD("Foro");
13
14 response.setContentType("text/html");
15 PrintWriter out = response.getWriter();
16 out.println("<html>");
17 out.println("<body>");
18 out.println("Tema: "+Tema+"<br>");
19 TemasForo.Lista("SELECT * FROM "+Tema,out);
20 out.println("</body>");
21 out.println("</html>");
22
23 TemasForo.Cierra();
24 }
25 }
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4
5 public class ForoInsertarOpTema extends HttpServlet {
6
7 synchronized public void doGet(HttpServletRequest
8 request, HttpServletResponse response)
9 throws IOException, ServletException {
10 String Tema = request.getParameter("Temas");
11 String Opinion = request.getParameter("Opinion");
12
13 ForoAccesoBD TemaForo= new ForoAccesoBD("Foro");
14 TemaForo.Ejecuta("INSERT INTO "+Tema+" VALUES
15 ('"+Opinion+"')");
16
17 response.setContentType("text/html");
18 PrintWriter out = response.getWriter();
19 out.println("<html>");
20 out.println("<body>");
21 out.println("Opinión: "+Opinion+" añadida <br>");
22 TemaForo.Lista("SELECT * FROM "+Tema,out);
23 out.println("</body>");
24 out.println("</html>");
25
26 TemaForo.Cierra();
27 }
28 }
204 © JESÚS BOBADILLA SANCHO
No debemos olvidar que los clientes que utilizan nuestro servicio de agenda
varían a lo largo del tiempo; es decir, a veces tendremos más clientes y a veces
tendremos menos. Vamos a programar la creación y borrado de agendas utilizando
la aplicación web, de manera que los propios clientes puedan dar de alta y de baja
sus agendas.
Las clases que acceden a las tablas de nuestra base de datos utilizan el objeto
ForoAccesoBD, que fue implementado en el ejemplo “Foro” con la finalidad de
facilitar las operaciones que realicemos sobre bases de datos. La explicación
detallada de su funcionamiento se encuentra en el apartado anterior.
Agenda
AgendaSelecciona
AgendaOpciones
AgendaInCoBo
ForoAccesoBD
206 © JESÚS BOBADILLA SANCHO
La base de datos diseñada para esta aplicación tiene como nombre lógico:
Agenda. Inicialmente contiene una tabla vacía de nombre Agendas, constituida por
el campo Identificador, de tipo alfanumérico.
Agenda
Agendas
Identificador
Alumnos
Profesores
Alumnos
Profesores
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4
5 public class Agenda extends HttpServlet {
6
7 public void doGet(HttpServletRequest request,
8 HttpServletResponse response)
9 throws IOException, ServletException {
10
11 response.setContentType("text/html");
12 PrintWriter out = response.getWriter();
13 out.println("<html>");
14 out.println("<body>");
15
16 out.println("<form action='http://localhost:8080/
17 examples/servlet/AgendaSelecciona' method=get>");
18 out.println("<input type=radio name=Operacion
19 value=Crear> Crear agenda <br>");
20 out.println("<input type=radio name=Operacion
21 value=Borrar> Borrar agenda <br>");
22
23 out.println("<input type=radio name=Operacion
24 value=Consulta> Consultar contacto <br>");
25 out.println("<input type=radio name=Operacion
208 © JESÚS BOBADILLA SANCHO
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4
5 public class AgendaSelecciona extends HttpServlet {
6
7 public void doGet(HttpServletRequest request,
8 HttpServletResponse response)
9 throws IOException, ServletException {
10
11 String Operacion = request.getParameter("Operacion");
12
13 response.setContentType("text/html");
14 PrintWriter out = response.getWriter();
15 out.println("<html>");
16 out.println("<body>");
17
18 out.println("<form action='http://localhost:8080/
19 examples/servlet/AgendaOpciones' method=get>");
20
21 if (Operacion.equals("Crear")) {
22 out.println("Nombre de la agenda: <input type=text
23 size=15 name=Agenda> <br>");
24 } else {
25 ForoAccesoBD UtilidadesBD=new ForoAccesoBD("Agenda");
26 String[] Identificadores =
27 UtilidadesBD.CreaLista("Agendas","Identificador");
28 UtilidadesBD.Cierra();
29
30 out.println("<select name=Agenda>");
31 for (int i=0;i<Identificadores.length;i++)
32 out.println("<option>"+Identificadores[i]+
33 "</option>");
34 out.println("</select><br><br>");
35 }
36
37 out.println("<input type=hidden name=Operacion
38 value="+Operacion+"><br>");
39 out.println("<input type=submit value='Enviar'> <br>");
210 © JESÚS BOBADILLA SANCHO
40 out.println("</form>");
41
42 out.println("</body>");
43 out.println("</html>");
44 }
45 }
Para crear una agenda nueva (línea 17) es necesario realizar dos acciones:
insertar un nuevo registro en la tabla Agendas (líneas 19 y 20) y crear una tabla
vacía con el nombre de la agenda y los campos Nombre, email y Telefono (líneas 21
y 22).
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4
5 public class AgendaOpciones extends HttpServlet {
6
7 synchronized public void doGet(HttpServletRequest
8 request, HttpServletResponse response)
9 throws IOException, ServletException {
10 String Agenda = request.getParameter("Agenda");
11 String Operacion = request.getParameter("Operacion");
12
13 PrintWriter out = response.getWriter();
14 out.println("<html>");
15 out.println("<body>");
16
17 if (Operacion.equals("Crear")) {
18 ForoAccesoBD UtilidadesBD=new ForoAccesoBD("Agenda");
19 UtilidadesBD.Ejecuta("INSERT INTO Agendas VALUES
20 ('"+Agenda+"')");
21 UtilidadesBD.Ejecuta("CREATE TABLE "+Agenda+" (Nombre
22 CHAR(30),email CHAR(30),Telefono CHAR(10))");
23 }
24
25 if (Operacion.equals("Borrar")) {
26 ForoAccesoBD UtilidadesBD=new ForoAccesoBD("Agenda");
27 UtilidadesBD.Ejecuta("DELETE FROM Agendas WHERE
28 Identificador='"+Agenda+"'");
29 UtilidadesBD.Ejecuta("DROP TABLE "+Agenda);
30 }
31
32 if (Operacion.equals("Consulta")||
33 Operacion.equals("Borrado")||
34 Operacion.equals("Insercion")) {
35 out.println("<form action='http://localhost:8080/
36 examples/servlet/AgendaInCoBo' method=get>");
37 out.println("Nombre: <input type=text name=Nombre
212 © JESÚS BOBADILLA SANCHO
38 size=40><br>");
39
40 if (Operacion.equals("Insercion")) {
41 out.println("email: <input type=text name=email
42 size=20><br>");
43 out.println("Teléfono: <input type=text
44 name=Telefono size=10><br><br>");
45 }
46
47 out.println("<input type=hidden name=Agenda
48 value="+Agenda+">");
49 out.println("<input type=hidden name=Operacion
50 value="+Operacion+">");
51 out.println("<input type=submit> <br>");
52 out.println("</form>");
53 }
54
55 if (Operacion.equals("Listar")) {
56 ForoAccesoBD UtilidadesBD=new ForoAccesoBD("Agenda");
57 UtilidadesBD.Lista("SELECT * FROM "+Agenda,out);
58 UtilidadesBD.Cierra();
59 }
60
61 out.println("</body>");
62 out.println("</html>");
63 } }
1 import java.io.*;
2 import javax.servlet.*;
3 import javax.servlet.http.*;
4
5 public class AgendaInCoBo extends HttpServlet {
6
7 synchronized public void doGet(HttpServletRequest
8 request, HttpServletResponse response)
9 throws IOException, ServletException {
10 String Agenda = request.getParameter("Agenda");
11 String Operacion = request.getParameter("Operacion");
12 String Nombre = request.getParameter("Nombre");
13
14 ForoAccesoBD UtilidadesBD= new ForoAccesoBD("Agenda");
15
16 if (Operacion.equals("Insercion")) {
17 String email = request.getParameter("email");
18 String Telefono = request.getParameter("Telefono");
19 UtilidadesBD.Ejecuta("INSERT INTO "+Agenda+" VALUES
20 ('"+Nombre+"','"+email+"','"+Telefono+"')");
21 }
22
23 if (Operacion.equals("Borrado")) {
24 UtilidadesBD.Ejecuta("DELETE FROM "+Agenda+" WHERE
25 Nombre='"+Nombre+"'");
26 }
27
28 if (Operacion.equals("Consulta")) {
29 PrintWriter out = response.getWriter();
30 out.println("<html><body>");
31 UtilidadesBD.Lista("SELECT * FROM "+Agenda+" WHERE
32 Nombre='"+Nombre+"'",out);
33 out.println("</body></html>");
34 }
35 UtilidadesBD.Cierra();
36 }
37 }