Sie sind auf Seite 1von 94

Universidad Tecnológica de Nezahualcóyotl

Sistemas
de
Información
en
Java
Por:
M. en C. Gilberto Pacheco Gallegos.
Academia de Programación
Academia de Ingeniería de Software.
Índice de Contenido
1. Introducción a Java................................................................................................................................2
1.1. Objetos y Clases.............................................................................................................................2
1.2. Tipos de Datos Primitivos..............................................................................................................2
1.3. Comentarios....................................................................................................................................2
1.4. Estructuras de Control....................................................................................................................3
1.5. Terminación de Ciclos y Funciones...............................................................................................4
1.6. Precedencia de Operadores............................................................................................................5
1.7. Un Programa en Java......................................................................................................................6
1.7.1. Diagrama de Clases de UML..................................................................................................6
1.7.2. Código de “ Ejemplo.java” ......................................................................................................6
1.7.3. Salida en Pantalla....................................................................................................................7
1.6.4. Comentarios............................................................................................................................7
2. Acceso a Bases de Datos......................................................................................................................10
2.1. Tablas...........................................................................................................................................10
2.2. Llaves...........................................................................................................................................11
2.3. Manipulación de una Tabla..........................................................................................................11
2.3.1. Vista Lógica..........................................................................................................................11
2.3.2. Vista de Datos.......................................................................................................................11
2.3.3. Creación de la tabla (“ alumno.sql” )......................................................................................12
2.3.4. Inserción de datos en la tabla (“ insert_alumno.sql”) ............................................................12
2.3.5. Modificación de datos en la tabla (“update_alumno.sql”). ...................................................12
2.3.6. Consulta de datos en la tabla (“select_alumno.sql”). ...........................................................12
2.3.7. Resultado de la Consulta......................................................................................................12
2.3.8. Eliminación de datos en la tabla...........................................................................................12
2.3.9. Código de “ ctrlAccesoAlumno.java”. ..................................................................................12
2.3.10. Salida en Pantalla................................................................................................................17
2.3.11. Comentarios........................................................................................................................17
2.4. Restricciones................................................................................................................................18
2.4.1. Vista Lógica..........................................................................................................................18
2.4.2. Vista de Datos.......................................................................................................................19
2.4.3. Datos en las Tablas...............................................................................................................19
2.4.4. Creación de la Tabla Material (“material.sql”). ....................................................................19
2.4.5. Ejemplo de Inserción de Datos (“insert_material.sql ”). .......................................................19
2.4.6. Una Consulta de Dos Tablas (“select_ alumno_y_material.sql”). ........................................20
2.4.7. Resultado de la Consulta......................................................................................................20
2.4.8. Código de “ ctrlAccesoMaterial.java”. ..................................................................................20
2.4.9. Salida en Pantalla..................................................................................................................23
2.4.8. Comentarios..........................................................................................................................23
2.5. Manejo de cadenas.......................................................................................................................24
2.5.1. Ejemplo de Manejo de Texto (“Caden as.java” )...................................................................24
2.5.2. Salida en Pantalla..................................................................................................................25
2.5.3. Comentarios..........................................................................................................................25
3. Interfaces Gráficas...............................................................................................................................27

i
3.1. Un Ejemplo Simple......................................................................................................................27
3.1.1. Especificación.......................................................................................................................27
3.1.2. Vista Lógica..........................................................................................................................27
3.1.3.  Código de “ frmSencilla.java”. .............................................................................................28
3.1.4. Comentarios..........................................................................................................................29
3.2. Acceso a Bases de Datos Desde Interfaces Gráficas....................................................................30
3.2.1. Especificación.......................................................................................................................30
3.2.2. Vista Lógica..........................................................................................................................30
3.2.3. Código de “ frmInsertaAlumno.java”. ...................................................................................31
3.2.4. Código de “ ctrlInsertaAlumno.java”. ...................................................................................33
3.2.5. Comentarios..........................................................................................................................33
4. Consultas y Manejo de Restricciones..................................................................................................35
4.1. Una Consulta Simple....................................................................................................................35
4.1.1. Especificación.......................................................................................................................35
4.1.2. Vista Lógica..........................................................................................................................35
4.1.3. Diagrama de Secuencia.........................................................................................................36
4.1.4. Código de “ frmBuscaAlumno.java”. ....................................................................................37
4.1.5. Código de “ ctrlBuscaAlumno.java”. ....................................................................................39
4.1.6. Comentarios..........................................................................................................................39
4.2. Manejo de Restricciones..............................................................................................................40
4.2.1. Especificación.......................................................................................................................40
4.2.2. Código de “ frmRestricciones.java”. .....................................................................................40
4.2.3. Código de “ ctrlRestricciones.java”. ......................................................................................44
4.2.4. Comentarios..........................................................................................................................44
5. Uso de JTable.......................................................................................................................................46
5.1. Un Ejemplo Sencillo....................................................................................................................46
5.1.1. Especificación.......................................................................................................................46
5.1.2. Código de “ frmTablaSencilla”. ............................................................................................46
5.1.3. Código de “ ctrlTablaSencilla”. .............................................................................................47
5.2. Un Ejemplo más Completo..........................................................................................................48
5.2.1. Especificación.......................................................................................................................48
5.2.2. Código de “ frmTablaCompleta.java”. ..................................................................................49
6. Java en Internet....................................................................................................................................53
6.1. Un Applet Sencillo.......................................................................................................................53
6.1.1. Código de “ AppletDePrueba.html”. .....................................................................................53
6.1.2. Código de “ AppletDePrueba.java”. ......................................................................................53
6.2. Otro Applet...................................................................................................................................54
6.2.1. Código de “ AppletSencillo.html” .........................................................................................54
6.2.2. Código de “ AppletSencillo .java”. ........................................................................................55
6.3. Un JSP..........................................................................................................................................55
6.3.1. Código de “ AppletConsulta.html”. .......................................................................................55
7. Un Ejemplo de Aplicación...................................................................................................................58
7.1. La Especificación.........................................................................................................................58
7.2. Diseño...........................................................................................................................................63
7.2.1. Vista Lógica..........................................................................................................................64

ii
7.2.2. Carta de Estados para “frmClientes”. ...................................................................................64
7.3. Implementación............................................................................................................................65
7.3.1. Código de “ factura.sql”. .......................................................................................................65
7.3.2. Código de “ GridBagPanel.java”. ..........................................................................................65
7.3.3. Código de “ frmProductos.java” ............................................................................................67
7.3.4. Código de “ ctrlProductos.java” ............................................................................................68
7.3.5. Código de “ frmClientes.java”. ..............................................................................................69
7.3.6. Código de “ ctrlClientes.java” ...............................................................................................73
7.3.7. Código de “ frmFactura.java”. ...............................................................................................74
7.3.8. Código de “ ctrlFactura.java” ................................................................................................77
7.3.9. Código de “ frmLogin.java”. .................................................................................................81
7.3.10. Código de “ ctrlLogin.java”. ................................................................................................84
7.3.11. Código de “ frmMenu.java”. ...............................................................................................85
7.4. Generación del Ejecutable............................................................................................................88
7.4.1. Código de “ manifest.txt” ......................................................................................................88

iii
Índice de Ilustraciones
Ilustración 1. Ejemplo de Clase.   6
Ilustración 2. Estructura Genérica de una Relación.   10
Ilustración 3. Vista Lógica de un Ejemplo que Manipula una Tabla.   11
Ilustración 4. Vista de Datos de la Tabla alumno.   11
Ilustración 5. Vista Lógica para ctrlAccesoMaterial.   18
Ilustración 6. Vista de Dato para un Ejemplo que Realiza Validaciones.   19
Ilustración 7. Ejemplo de datos para el ejemplo 2.4.   19
Ilustración 8. frmSencilla.   27
Ilustración 9. Vista Lógica de frmSencilla.   27
Ilustración 10. frmInsertaAlumno.   30
Ilustración 11. Vista Lógica para frmInsertaAlumno.   30
Ilustración 12. frmBuscaAlumno.   35
Ilustración 13. Vista Lógica para frmBuscaAlumno.   35
Ilustración 14. frmRestricciones.   40
Ilustración 15. frmTablaSencilla.   46
Ilustración 16. frmTablaCompleta.   48
Ilustración 17. Portada.   58
Ilustración 18. Control de Acceso.   58
Ilustración 19. Menú de Supervisor.   59
Ilustración 20. Reporte de Productos.   59
Ilustración 21. Catálogo de Clientes.   60
Ilustración 22. Menú del Vendedor.   61
Ilustración 23. Ejemplo de Factura Impresa.   62
Ilustración 24. Menú Archivo.   62
Ilustración 25. Menú Ayuda.   63
Ilustración 26. Acerca De.   63
Ilustración 27. Vista Lógica del Ejemplo.   64
Ilustración 28. Carta de Estados para frmClientes.   64

iv
1.
Introducción
a
Java.

1
1. Introducción a Java.
Java   es   un  lenguaje   de   programación   orientado   a   objetos(oopl).   Eso   significa   que   al   escribir   un
programa, se crean objetos y se hace que estos interactúen para realizar las funciones que desees.

1.1. Objetos y Clases.


Los   objetos   son  piezas   de  software  que  tienen   asociadas   responsabilidades.  Están  compuestos   por
variables  internas, que les sirven para almacenar información y por operaciones internas, llamadas
métodos que les permiten realizar labores.

Para organizar más fácilmente el código, lo dividimos en  clases. Estas son conjuntos de objetos que
tienen las mismas variables y métodos.

A lo largo del curso iremos detallando más y más las características de la programación orientada a
objetos. Empezaremos haciendo programas sencillos de una sola clase y terminaremos detallando la
arquitectura completa de una sistema de información.

1.2. Tipos de Datos Primitivos.


La  forma  más  sencilla  de variables internas  son los  tipos de datos  primitivos  que se  muestran  a
continuación.
Nombre Mínimo Valor Negativo Máximo Valor Negativo Mínimo Valor Positivo Máximo Valor Positivo
byte ­128 ­1 0 127
short ­32,768 ­1 0 32,767
int ­2,147,483,648 ­1 0 2,147,483,647
long  ­9,223,372,036,854,755,808 ­1 0  9,223,372,036,854,755,808
float ­3.40282347E+38 ­1.40239846E­45 1.40239846E­45 3.40282347E+38
double ­1.7976931348623147E+30 8 ­4.94065645841246544e­ 324 4.94065645841246544e­324 1.7976931348623147E+308
char
boolean false true

Para el tipo de datos char se utiliza el código de 16 bits llamado  Unicode, que permite representar
simultáneamente juegos de caracteres de muchos idiomas.

1.3. Comentarios.
Para hacer más legible el código, se le agregan comentarios, que son ignorados por el compilador, pero
sirven para explicar o aclarar alguna sección.

2
En Java hay dos formas de utilizar comentarios. Los comentarios de una o más líneas empiezan con la
secuencia /* y terminan con */. Los comentarios de una sola línea empiezan con // y terminan con el
final de la línea.

1.4. Estructuras de Control.


Los métodos de un objeto son secuencias de instrucciones y estructuras de control como las que se
muestran a continuación.
if(cond) { if(cond) { if (cond1){ if (cond1) {
V F V F V F V
F ins ins1 ins1 ins1
} } else { } else if (cond2) { } else if (cond2) {
F V F V
ins2 ins2 ins2
} } else if (cond3) { } else if (cond3) {
F V F V
ins3 ins3
} } else {
V
cond? expr1: expr2 ins4
F
}

switch (e) { while (condición) { do {


F V
case c1: e == c1 instrucciones instrucciones for (ini;cond;inc) {
F V
case c2: } } while(condición); instrucciones
e == c2 F V
ins1 }
break;
case c3:
e == c3
ins2
break;
default:
ins3 Otro 
valor de e
}

3
1.5. Terminación de Ciclos y Funciones.
Ciclo { Ciclo { Ciclo {
while (cond) { do { for (ini;cond;inc) {
instrs1 instrs1 instrs1
break; break; break;
instrs2 instrs2 instrs2
} } while(cond); }
instrs3 instrs3
instrs3
} } }
Etiqueta: Etiqueta: Etiqueta:
while (cond) { do { for (ini;cond;inc) {
ciclo { ciclo { ciclo {
instrs1 instrs1 instrs1
break Etiqueta; break Etiqueta; break Etiqueta;
instrs2 instrs2 instrs2
} } }
instrs3 instrs3 instrs3
} } while(cond); }

Ciclo { Ciclo { Ciclo {


while (cond) { do { for (ini;cond;inc) {
instrs1 instrs1 instrs1
continue; continue; continue;
instrs2 instrs2 instrs2
} } while (cond); }
instrs3 instrs3 instrs3
} } }
Eti: Eti: Eti:
while(cond) { do { for (ini;cond;inc) {
ciclo { ciclo { ciclo {
instrs1 instrs1 instrs1
continue Eti; continue Eti; continue Eti;
instrs2 instrs2 instrs2
} } }
instrs3 instrs3 instrs3
} } while (cond); }

4
void función(args) { tipo función(args) {
instrs1 instrs1
return; return expresión;
instrs2 instrs2
} }

1.6. Precedencia de Operadores.


En la tabla siguiente se muestra el orden de evaluación de operadores en Java. Los que aparecen en los
renglones superiores se evalúan primero.
Posfijos arreglo[ínidice]  ref.miembro   función(parámetros)    expresión++
expresión­­
Unarios ++expresión    ­­expresión   +expresión   ­expresión   ~expresión   ! expresión 
Creación y Cast new Clase(parámetros)    (tipo)expresión
Multiplicativos expresión * expresión     expresión % expresión      expresión / expresión 
Aditivos expresión + expresión     expresión ­ expresión
Corrimientos expresión << expresión     expresión >> expresión      expresión >>> expresión 
Relacionales expresión  <  expresión         expresión  >  expresión           expresión  <=  expresión
expresión >= expresión    referencia instanceof expresión
De Igualdad expresión == expresión     expresión != expresión
Y de Bits expresión & expresión
O exclusiva de Bits expresión ^ expresión
O de Bits expresión | expresión
Y Lógica expresión && expresión
O Lógica expresión || expresión
Condicional expresión? Expresión: expresión
Asignación expresión  =  expresión       expresión   +=  expresión       expresión   ­=  expresión
expresión  *=  expresión      expresión  /=  expresión       expresión  %=  expresión
expresión  &=  expresión       expresión   ^=  expresión       expresión   |=  expresión
expresión   <<=  expresión       expresión   >>=  expresión
expresión >>>= expresión

5
1.7. Un Programa en Java.

1.7.1. Diagrama de Clases de UML.
Ejemplo

+max(a: int, b: int): int


+suma(a: int, b: int): int
+main(args: String[])
Ilustración 1. Ejemplo de Clase.

El diagrama de clases muestra en un dibujo la estructura de las clases que conforman una aplicación.
Las clases se representan como una caja con tres compartimientos que describen su estructura y la de
los objetos que pertenecen a ella. El primero es el nombre de la clase. El segundo indica las variables
de los objetos. Finalmente, el tercero  muestra los métodos de los objetos. Aquellos elementos que
aparecen  subrayados pertenecen  a la clase  y no forman parte de los objetos, como en el caso  del
método main.

1.7.2. Código de “Ejemplo.java”.
1 /**
2 * Declaración de la clase "Ejemplo". La palabra "public" indica que esta
3 * clase es visible desde cualquier parte de la aplicación. Cada archivo de
4 * Java debe contener a lo más una clase pública y su nombre coincidir con el
5 * nombre de esa clase pública, exceptuando la extensión ".java". Las
6 * mayúsculas y minúsculas deben coincidir. Esta clase debe capturarse en un
7 * archivo que se llame "Ejemplo.java".
8 */
9 public class Ejemplo {
10 /**
11 * Se define un método que se llama max. Recibe dos números y devuelve el
12 * mayor de ellos. Todos los objetos que pertenecen a la clase
13 * "Ejemplo" contienen una copia de esta operación. La palabra
14 * "public" se puede usar con variables y métodos. Se conoce como nivel
15 * de acceso. Ver 1.6.4 para una descripción de los niveles
16 * de acceso.
17 */
18 public int max(int a, int b) {
19 if (a > b) {
20 return a;
21 } else {
22 return b;
23 }
24 }
25
26 /**
27 * Operación pública que calcula la suma de dos números. Una clase puede
28 * tener varias operaciones.
29 */
30 public int suma(int a, int b) {
31 return (a + b);
32 }
33

6
34 /**
35 * La palabra "static" indica que esta operación pertenece a la clase y
36 * no forma parte de objetos. Este es el punto de entrada a la
37 * aplicación. En este método se crea un objeto de la clase y se prueba
38 * su comportamiento para asegurar que sea correcto. Los métodos que
39 * realizan esto son conocidos como "pruebas de unidad", y son muy útiles
40 * en la ingeniería de software. Se recomienda que todos los
41 * componentes de una aplicación tengan una prueba de unidad.
42 */
43 public static void main (String[] args) {
44 // AQUI EMPIEZA LA EJECUCION DEL PROGRAMA.
45 // Se crea un objeto con ayuda del operador "new". Dicho objeto tiene
46 // una copia de los métodos "max" y "suma". Esta es la primera línea
47 // de código que se ejecuta.
48 Ejemplo e = new Ejemplo();
49
50 // Se invoca el método "max" contenido en "e". Nota que el operador
51 // "." sirve para pedirle a un objeto que haga algo. Se realiza
52 // sustitución de parámetros. El primer parámetro de la línea 18, o
53 // sea "a", toma como valor el primer parámetro de la línea 61, que
54 // es "1". El segundo parámetro de (18), o sea "b", toma el valor el
55 // segundo parámetro de (61), que es "8", y así sucesivamente. A
56 // continuación se ejecutan las líneas 19 a 24. El resultado se envía
57 // de regreso a (61), donde se muestra en la pantalla de salida de la
58 // aplicación, que es representada por la variable de clase "out",
59 // localizada en la clase "System". El objeto tiene una operación
60 // llamada "println" que utiliza para desplegar información.
61 System.out.println(e.max(1, 8));
62
63 // El comportamiento de (65) y (66) es parecido al descrito
64 // previamente.
65 System.out.println(e.max(5, 3));
66 System.out.println(e.max(3, 3));
67
68 // Sucederá algo parecido, pero se ejecutarán las líneas (30) a (32).
69 System.out.println(e.suma(4, 7));
70 } // Se termina el método main, con lo cual termina la aplicación.
71 }

1.7.3. Salida en Pantalla.
Línea Salida en Pantalla
61 8
65 5
66 3
69 11

1.6.4. Comentarios.
Las aplicaciones en Java normalmente están compuestos de varias clases, pero empiezan su ejecución
es una operación de clase (también llamada  estática) que se llame main y que reciba un arreglo de
elementos “ String”.  

En este caso, nuestra aplicación tiene una sola clase, la cual se debe capturar en un archivo que se llame
“Ejemplo.java”.   Respeta   las   mayúsculas   y   minúsculas   o   no   funcionará.   Normalmente   en   Java   los
nombres de clases inician en mayúscula.

7
Los niveles de acceso permitidos en Java son los siguientes:

UML Java Descripción


# protected Los miembros se pueden utilizar en la clase donde se definen, en las clases hijas y
en las clases que pertenezcan al mismo paquete.
­ private Los miembros se pueden utilizar solo en la clase donde se definen.
+ public Los miembros se pueden utilizar en cualquier lugar del código.
~ Los miembros se pueden utilizar en la clase donde se definen y en las clases que
pertenezcan al mismo paquete.

8
2.
Acceso
a
Bases
de
Datos.

9
2. Acceso a Bases de Datos.

Cuando desarrollas un sistema de información, la base de todo el trabajo es el almacenamiento de
datos,   que   generalmente   son   tablas   de   una   base   de   datos   relacional.   Por   ello   es   necesario   que
comprendas como funcionan y también como se utilizan desde un programa. Empezaremos con la
manipulación de tablas aisladas.

2.1. Tablas.
El modelo más difundido para implementar bases de datos en el relacional. En el, todos los datos se
organizan de la manera que se esquematiza a continuación
Nombre de la relación
Atributo 1 Atributo 2 ............... Atributo n
Valor 1 Valor 2 ............... Valor n Tupla 1
Xxxxxxx xxxxxxxx ............... Xxxxxxxx Tupla 2
. . . . .
. . . . .
. . . . .
Xxxxxxx xxxxxxxx ............. Xxxxxxxxx Tupla m

Ilustración 2. Estructura Genérica de una Relación.

Cada tupla representa un objeto. Los atributos representan características del mismo. Todas las tuplas
tienen varios  atributos. Cada atributo tiene un valor asociado. El conjunto de los valores que puede
tomar un atributo se conoce como dominio. Los valores de un dominio no tienen estructura interna (es
decir que son atómicos) y no contienen estructuras repetitivas (univaluados). Un conjunto de tuplas se
pueden   juntar   para   formar   una  relación.   En   ella,   todas   las   tuplas   tienen   los   mismos   nombres   y
dominios para un número dado de atributo, pero pueden tener distintos valores. Así mismo, todas las
tuplas de una relación tienen el mismo número de atributos.

En   la   práctica   los   sistemas   de   bases   de   datos   relacionales   utilizan   objetos   llamados  tablas,   que
normalmente se manejan como si fueran relaciones.

La forma de obtener el diseño de tablas está fuera de los alcances del presente texto. Lo que se estudia
a continuación es como manipularlas usando MySQL.

10
2.2. Llaves.
• Candidatas. Conjunto no vacío de atributos que identifican unívoca y mínimamente cada tupla, las
llaves representan la identidad de un objeto.

• Primarias. De entre todas las llaves candidatas para una relación, hay una que se escoge como
oficial.

• Alternativas. Toda las claves candidatas que no se seleccionaron como primaria.

2.3. Manipulación de una Tabla.

2.3.1. Vista Lógica.

ctrlAccesoAlumno alumno
* matricula: int
nombre: String
- url: String = "jdbc:mysql://localhost/test" {frozen}
fecha_de_nacimiento: Date
- usuario: String = "root" {frozen}
- password :String password = "" {frozen}
- formato: DateFormat = getDateInstance( )

+ insercionSimple( )
+ inserta(matricula: int, nombre: String, fecha: java.sql.Date )
+ main(args: String[])
Ilustración 3. Vista Lógica de un Ejemplo que Manipula una Tabla.

La  vista   lógica  muestra  las  clases  que   utilizará  la  aplicación. En la  arquitectura  que  emplearemos
durante el curso se emplea una clase para manejar la base de datos. En este caso es “ctrlAlumno”.  Las
clases que manipulan datos y realizan el flujo principal de una aplicación se conocen como clases de
control y llevan el prefijo “ctrl”.  También se les asocia el ícono que se muestra para “ctrlAlumno”.  La
clase   “alumno”   representa   un   almacén   de   datos.   Cada   objeto   de   ella   representa   un   registro   de
información.   La   clase   “ctrl Alumno”   puede   manipular   a   muchos   registros   del   almacén   alumno
(representado con “*”),  pero por su parte “alumno”  no tiene acceso a la otra clase. Eso se representa
con la flecha unidireccional. Cuando el acceso se puede realizar en los dos sentidos, se pone una flecha
bidireccional, o bien una línea sin flechas.

2.3.2. Vista de Datos.

alumno
PK matricula: INTEGER
NN nombre: VARCHAR(30)
NN fecha_de_nacimiento: DATE

Ilustración 4. Vista de Datos de la Tabla alumno.

11
Se ha elegido implementar la clase alumno como una tabla relacional. Es por ello que se la ha puesto el
ícono que se muestra en la Ilustración 4. El símbolo PK significa que el campo es una llave primaria.
NN significa que el campo no puede ser nulo. N significa que si puede ser nulo.

2.3.3. Creación de la tabla (“alumno.s ql”).
1 CREATE TABLE alumno(
2 matricula INTEGER PRIMARY KEY,
3 nombre VARCHAR(30) NOT NULL,
4 fecha_de_nacimiento DATE NOT NULL
5 ) TYPE = InnoDB;

2.3.4. Inserción de datos en la tabla (“in sert_alumno.sql” ).
1 INSERT INTO alumno
2 VALUES(200141, 'Zoila Vaca', '1978-02-03');

2.3.5. Modificación de datos en la tabla (“upd ate_alumno.sql”).
1 UPDATE alumno SET
2 nombre = 'Zoila Vaca del Corral', fecha_de_nacimiento = '1987-02-03'
3 WHERE matricula = 200141;

2.3.6. Consulta de datos en la tabla (“s elect_alumno.sql”).
1 SELECT * FROM alumno
2 WHERE matricula = 200141;

2.3.7. Resultado de la Consulta.
matricula nombre fecha_de_nacimiento
200141 Zoila Vaca del Corral 1978-02-03

2.3.8. Eliminación de datos en la tabla.
1 DELETE FROM alumno
2 WHERE matricula = 200141;

2.3.9. Código de “c trlAccesoAlumno.java”.
1 // "import" sirve para tener acceso a clases de la librería base
2 // de Java. Las clases se organizan en "paquetes", que son como
3 // carpetas.
4 import java.sql.*; // Para interactuar con la base de datos.
5 import java.text.*; // Para la clase "DateFormat".
6

12
7 public class ctrlAccesoAlumno {
8 /**
9 * Variable que identifica a una base de datos. URL significa "Universal
10 * Resource Locator" y es una cadena que sirve para ubicar un recurso
11 * en una red. Consta de 3 partes: protocolo, host y recurso.
12 * El protocolo en este caso es "jdbc:mysql"; el host es "localhost" y
13 * el recurso es "test". El valor "localhost" representa a la
14 * computadora donde estás ejecutando este programa. El valor "test" es
15 * la base de datos que crea MySQL al instalarse. MySQL también crea un
16 * usuario que se llama "root" y no tiene password. Si utilizas mysql en
17 * la misma computadora donde se está ejecutando esta aplicación y
18 * quieres usar la base de datos "test", debes usar la siguiente
19 * definición.
20 */
21 private static final String url = "jdbc:mysql://localhost/test";
22
23 /*
24 * Si prefieres usar MySQL en un servidor, quita el comentario de la
25 * siguiente definición y cambia test por la base de datos que tengas
26 * asignada. Existe una sola copia de esta variable (por eso es static)
27 * y está localizada en la clase. No forma parte de los objetos. La
28 * palabra final indica que no se puede cambiar (O sea que es una
29 * constante.
30 */
31 // private static final String url = "jdbc:mysql://192.168.7.251/test";
32
33 /*
34 * Para Oracle quita el comentario de la siguiente definición.
35 */
36 // private static final String url =
37 // "jdbc:oracle:thin:@192.168.7.99:1521:oracledb";
38
39 /**
40 * Usuario con el que te conectarás a la base de datos.
41 */
42 private static final String usuario = "root";
43
44 /**
45 * Password con el que te conectarás a la base de datos.
46 */
47 private static final String password = "";
48
49 /**
50 * Este objeto se utilizará para capturar y mostrar fechas en el formato
51 * e idioma correctos de acuerdo a la configuración de idiomas de la
52 * computadora donde se ejecuta este programa.
53 */
54 private static DateFormat formato = DateFormat.getDateInstance();
55

13
56 /**
57 * Inserta un registro cuando los datos ya se conocen de antemano.
58 * Esta rutina no se puede utilizar para insertar datos diferentes.
59 * Siempre inserta los mismos datos. La expresión "throws Exception"
60 * significa que se pueden producir errores en la ejecución, los cuales
61 * serán procesados por el método que mande llamar a este.
62 */
63 public void insercionSimple() throws Exception {
64 // Intenta conectarse al url indicado con el usuario y password
65 // definido en la clase. Si por alguna razón no se puede conectar a
66 // la base de datos, se crea un objeto de la clase "Exception". Se
67 // aborta la ejecución del programa. El objeto de la clase
68 // "Exception" lleva una descripción de los que falló y se pasa al
69 // método que mando llamar a "inserción" para que procese el error.
70 // Es caso de que la conexión si se pueda establecer, se obtiene el
71 // objeto conexion, que representa la sesión de trabajo.
72 Connection conexion =
73 DriverManager.getConnection(url, usuario, password);
74
75 // Transaction Isolation representa el comportamiento de la
76 // conexión en un ambiente concurrente.
77 // TRANSACTION_SERIALIZABLE significa que nuestros datos se
78 // mantendrán sin daño. Para lograrlo, se establecen bloqueos,
79 // por lo cual en algunas ocasiones las transacciones pueden ser
80 // abortadas por el manejador de bases de datos para evitar daños
81 // a la integridad de la información.
82 conexion.setTransactionIsolation(
83 Connection.TRANSACTION_SERIALIZABLE);
84
85 // Crea una instrucción en SQL para insertar un registro. Como los
86 // manejadores manejan las fechas de formas muy diferentes, Java te
87 // permite usar la instrucción "{d 'AAAA-MM-DD'}", que será cambiada
88 // por la instrucción correcta para tu DBMS. "AAAA" son 4 dígitos
89 // para el año. "MM" son 2 dígitos para el mes y "DD", 2 dígitos
90 // para el día.
91 PreparedStatement ps = conexion.prepareStatement(
92 "INSERT INTO alumno " +
93 "VALUES(200141, 'Zoila Vaca', {d '1978-02-03'})");
94
95 // Ejecuta la consulta.
96 ps.executeUpdate();
97
98 // Da por terminada la consulta y libera los recursos que ocupó
99 ps.close();
100
101 // Termina la conexión y libera los recursos que ocupó
102 conexion.close();
103 }
104

14
105 /**
106 * Esta rutina permite insertar un registro en la base de datos
107 * que contenga la información que se recibe como parámetro.
108 * Se puede utilizar siempre que se necesite.
109 */
110 public void inserta(int matricula, String nombre, java.sql.Date fecha)
111 throws Exception {
112 Connection conexion =
113 DriverManager.getConnection(url, usuario, password);
114 conexion.setTransactionIsolation(
115 Connection.TRANSACTION_SERIALIZABLE);
116
117 // Los signos "?" representan los valores que pueden cambiar cada
118 // vez que se ejecute la consulta.
119 PreparedStatement ps = conexion.prepareStatement(
120 "INSERT INTO alumno VALUES(?, ?, ?)");
121
122 ps.setInt(1, matricula);// El primer signo "?" será la matrícula.
123 ps.setString(2, nombre);// El segundo signo "?" será el nombre.
124 ps.setDate(3, fecha); // El tercer signo "?" será la fecha.
125 ps.executeUpdate();
126 ps.close();
127 conexion.close();
128 }
129
130 /**
131 * Muestra los datos que se encuentran almacenados en la tabla "alumno".
132 */
133 public void muestraRegistros() throws Exception {
134 Connection conexion =
135 DriverManager.getConnection(url, usuario, password);
136 conexion.setTransactionIsolation(
137 Connection.TRANSACTION_SERIALIZABLE);
138 PreparedStatement ps = conexion.prepareStatement(
139 "SELECT * FROM alumno");
140 // Al ejecutar una consulta se utiliza executeQuery, que regresa
141 // un objeto de la clase "ResultSet", el cual representa el
142 // resultado de la consulta.
143 ResultSet rs = ps.executeQuery();
144
145 // Cada vez que se ejecuta rs.next(), se recupera el siguiente
146 // renglón de la consulta. Cuando ya no hay más registros, esta
147 // expresión regresa "false" y por lo tanto el ciclo termina.
148 while (rs.next()) {
149 System.out.println("-----------------------------------------");
150
151 // rs.getString("matricula") recupera el campo matrícula
152 // del registro que mandó traer rs.next(). Si el nombre del
153 // campo está mal tecleado, se genera una excepción.
154 System.out.println("MATRICULA : "
155 + rs.getString("matricula"));
156 System.out.println("NOMBRE : "
157 + rs.getString("nombre"));
158
159 // Nota el uso del objeto "formato" para convertir un texto en
160 // fecha.
161 System.out.println("FECHA DE NACIMIENTO : "
162 + formato.format(rs.getDate("fecha_de_nacimiento")));
163 }
164 rs.close();
165 ps.close();
166 conexion.close();
167 }
168

15
169 public static void main(String[] args) {
170 // AQUI EMPIEZA LA EJECUCION DEL PROGRAMA.
171 // La instrucción "try" indica que algunas instrucciones del
172 // bloque de instrucciones siguiente puede generar excepciones, las
173 // cuales se van a procesar con la instrucción "catch".
174 try {
175 // Carga las clases encargadas de conectar el programa con
176 // el una base de datos Oracle. Normalmente están localizadas
177 // en un archivo con extensión ".jar", que puede ubicarse
178 // en el subdirectorio "jre/ext/lib" dentro del directorio de
179 // java o en alguna de las localidades indicadas por la
180 // variable de ambiente "CLASSPATH".
181 Class.forName("oracle.jdbc.OracleDriver");
182
183 // Carga las clases encargadas de conectar el programa con
184 // el una base de datos MySQL. Estas clases se pueden
185 // localizar de igual forma que las clases para Oracle.
186 Class.forName("com.mysql.jdbc.Driver");
187
188 ctrlAccesoAlumno a = new ctrlAccesoAlumno();
189
190 // Ejecuta las líneas 63 - 103 para el objeto "a".
191 a.insercionSimple();
192
193 // Ejecuta las líneas 110 a 128 para el objeto "a" y toma los
194 // siguientes valores:
195 // matricula --> 200142
196 // nombre --> "Rolando Mota"
197 // fecha -->valor correspondiente a {d '1973-08-07}
198 // Nota el uso de "formato" para convertir el texto en fecha. Si
199 // el texto no tiene el formato correcto se genera una
200 // excepción.
201 a.inserta(200142, "Rolando Mota",
202 new java.sql.Date(formato.parse("07/08/1973").getTime()));
203
204 a.inserta(200143, "Armando Pacheco",
205 new java.sql.Date(formato.parse("02/08/1982").getTime()));
206 a.inserta(200144, "Pancracio Wellington",
207 new java.sql.Date(formato.parse("30/02/1985").getTime()));
208 a.muestraRegistros();
209 } catch (Exception e) {
210 // Muestra la razón del error, así como las funciones se estaban
220 // ejecutando y en cual linea en el momento de que sucedió
221 // el fallo.
222 e.printStackTrace();
223 }
224 }
225 }

16
2.3.10. Salida en Pantalla.
Línea Salida en Pantalla
149 -----------------------------------------
154 y 155 MATRICULA : 200141
156 y 157 NOMBRE : Zoila Vaca
161 y 162 FECHA DE NACIMIENTO : 3/02/1978
149 -----------------------------------------
154 y 155 MATRICULA : 200142
156 y 157 NOMBRE : Rolando Mota
161 y 162 FECHA DE NACIMIENTO : 7/08/1973
149 -----------------------------------------
154 y 155 MATRICULA : 200143
156 y 157 NOMBRE : Armando Pacheco
161 y 162 FECHA DE NACIMIENTO : 2/08/1982
149 -----------------------------------------
154 y 155 MATRICULA : 200144
156 y 157 NOMBRE : Pancracio Wellington
161 y 162 FECHA DE NACIMIENTO : 2/03/1985

2.3.11. Comentarios.
En   SQL   una   transacción   es   un   conjunto   de   instrucciones,   las   cuales   deben   ejecutarse   todas
correctamente para surtir efecto. Si alguna de ellas falla, el efecto obtenido es como si ninguna de ellas
se hubiera ejecutado. El efecto es o todas o ninguna.

Cuando varias transacciones traten de usar los mismos datos simultáneamente, tenemos un ambiente
concurrente.   Si   las   transacciones   actúan   de   forma   desordenada,   la   integridad   de   los   datos   puede
corromperse.   Decimos   que   un   método   de   administración   de   transacciones   es  serializable,  al
presentarse concurrencia garantiza la integridad de la información almacenada.

Para poder asegurar que la transacción se serializable, los manejadores de bases de datos utilizan los
siguientes tipos de bloqueos:

• Compartidos. Al accesar al mismo dato varias transacciones solamente los pueden consultar, pero
no modificar.
• Exclusivos. Los datos se pueden modificar y consultar pero solo los puede usar una transacción.

Las instrucciones de modificación establecen automáticamente bloqueos exclusivos sobre los registros
que afectan. Si previamente ya hay un bloqueo sobre esos datos, se aborta.

En  el caso  del “select”,  este establece un bloqueo compartido sobre  los registros que recupera.  Si


previamente se ha establecido un bloqueo exclusivo sobre los datos, la transacción aborta. Cuando el
bloque preestablecido es compartido, la transacción puede continuar. Si se quiere establecer un bloqueo
exclusivo al consultar, se puede usar la opción “for  update”  de esta instrucción.

Los bloqueos se liberan en el momento de ejecutar las instrucciones “ commit”  o “ rollback”  en una


transacción.   La   instrucción  “ commit”   indica   que   la   transacción   se   ha   realizado   con   éxito   y   hace
visibles   a   otras   transacciones   las   modificaciones   realizadas   a   los   datos.   Por   su   parte,  “ rollback”
deshace todos los cambios que la transacción haya realizado.

17
Las conexiones de Java están configuradas para realizar automáticamente “commit”  o “ rollback”  en
cada instrucción SQL que realizan, pero este comportamiento se puede cambiar.

2.4. Restricciones.
El modelo relacional permite incorporar información adicional sobre los datos. Por ejemplo, puedes
indicar los valores exactos que un campo puede tomar. También puedes indicar que un registro está
relacionado con registros de otra tabla.

2.4.1. Vista Lógica.

ctrlAccesoMaterial
- url: String = "jdbc:mysql://localhost/test" {frozen}
- usuario: String = "root" {frozen}
- password :String password = "" {frozen}

+ inserta(descripcion: String, matricula: int, estado: String): int


~ validaInsercion(conexion:Connection, descripcion: String, matricula: int , estado: String)
~ validaDescripcion(conexion: Connection, descripcion: String)
~ validaMatricula(conexion: Connection, matricula: int)
~ validaEstado(conexion: Connection, estado: String)
~ abortaConexion(conexion: Connection, causa: String)
+ muestraRegistros()
+ muestraJoin()
+ main(String[] args)

* *

1 *
alumno material
matricula: int descripcion: String
nombre: String estado: String
fecha_de_nacimiento: Date

Ilustración 5. Vista Lógica para ctrlAccesoMaterial.

En este caso la clase de control verificará que los datos a insertar en la tabla “material”  cumplan con
algunas reglas de negocio:
• La descripción no puede ser nula.
• La matrícula debe ser la de algún alumno registrado.
• El estado debe ser exclusivamente alguno de los siguientes valores: “OK”,   “DESCOM PUESTO” ,
“EN R EPARACION” , “BAJA”.

El diseño de la base de datos de este ejemplo realiza las mismas validaciones.

18
2.4.2. Vista de Datos.

alumno material
1 * PK id: INTEGER {AUTO_INCREMENT}
PK matricula: INTEGER
NN descripcion: VARCHAR(30)
NN nombre: VARCHAR(30)
FK matricula INTEGER
NN fecha_de_nacimiento: DATE
NN estado ENUM('OK','DESCOMPUESTO','EN REPARACION','BAJA')
Ilustración 6. Vista de Dato para un Ejemplo que Realiza Validaciones.

La llave foránea la estamos indicando con FK.

2.4.3. Datos en las Tablas.
alumno
material matricula nombre fecha de
id descripcion matricula estado nacimiento
1 Banca con paleta 200141 OK 200141 Zoila Vaca 1978 – 02 – 03
2 Banca sin paleta 200142 DESCOMPUESTO 200142 Rolando Mota 1973 – 08 – 07
3 Paleta sin banca 200143 BAJA 200143 Armando Pacheco 1982 – 08 – 02
200144 Pancracio Wellington 1985 – 03 – 02

Ilustración 7. Ejemplo de datos para el ejemplo 2.4.

2.4.4. Creación de la Tabla Material (“material.sql”).
1 CREATE TABLE material(
2 id INTEGER PRIMARY KEY AUTO_INCREMENT,
3 descripcion VARCHAR(30) NOT NULL,
4
5 /*
6 * Este campo es llave foránea. Su definición debe coincidir con la llave
7 * primaria de la tabla con la que enlaza
8 */
9 matricula INTEGER NOT NULL,
10
11 /* El atributo “estado” solo puede tomar uno de los valores que están entre
12 * los paréntesis. No puede tomar ningún otro.
13 */
14 estado ENUM('OK','DESCOMPUESTO','EN REPARACION','BAJA') NOT NULL,
15
16 /*
17 * Las llaves foráneas deben indexarse en MySQL.
18 */
19 INDEX(matricula),
20
21 /*
22 * Las llaves foráneas siempre apuntan a una llave primaria.
23 */
24 FOREIGN KEY(matricula) REFERENCES alumno(matricula)
25 ) TYPE = InnoDB;

2.4.5. Ejemplo de Inserción de Datos (“ insert_material.sql”).
1 /*
2 * Como el campo “id” es auto numérico, no se le pone valor. Por esto se
3 * pone entre paréntesis los nombres de los campos cuyos valores se
4 * proporcionan. Las listas de campos y de valores se relacionan por el orden.
5 */
6 INSERT INTO material(descripcion, matricula, estado)
7 VALUES('Banca con paleta', 200141, 'OK');

19
2.4.6. Una Consulta de Dos Tablas (“se lect_alumno_y_material.sql”).
1 /*
2 * Nota como se igualan la llave primaria de la tabla “alumno” con la llave
3 * foránea de la tabla “material”.
4 */
5 SELECT alumno.matricula, nombre, id, descripcion
6 FROM alumno, material
7 WHERE alumno.matricula = material.matricula

2.4.7. Resultado de la Consulta.
alumno.matricula nombre id Material
200141 Zoila Vaca 1 Banca con paleta
200142 Rolando Mota 2 Banca sin paleta
200143 Armando Pacheco 3 Paleta sin banca

2.4.8. Código de “c trlAccesoMaterial.java”.
1 import java.sql.*;
2 import java.text.*;
3 import java.util.*;
4
5 public class ctrlAccesoMaterial {
6 private static final String url = "jdbc:mysql://localhost/test";
7 private static final String usuario = "root";
8 private static final String password = "";
9
10 public int inserta(String descripcion, int matricula, String estado)
11 throws Exception {
12 Connection conexion =
13 DriverManager.getConnection(url, usuario, password);
14
15 // Se van a realizar varias instrucciones de SQL, por lo cual tenemos
16 // una transacción con más de una instrucción. Es necesario ejecutar
17 // explícitamente la instrucción "commit" o "rollback".
18 conexion.setAutoCommit(false);
19
20 conexion.setTransactionIsolation(
21 Connection.TRANSACTION_SERIALIZABLE);
22 validaInsercion(conexion, descripcion, matricula, estado);
23 PreparedStatement ps = conexion.prepareStatement(
24 "INSERT INTO material(descripcion, matricula, estado)" +
25 "VALUES(?, ?, ?)");
26 ps.setString(1, descripcion);
27 ps.setInt(2, matricula);
28 ps.setString(3, estado);
29 ps.executeUpdate();
30 ResultSet rs = ps.getGeneratedKeys();
31 rs.next();
32 int id = rs.getInt(1);
33 rs.close();
34 ps.close();
35 conexion.commit();
36 conexion.close();
37 return id;
38 }
39

20
40 void validaInsercion(Connection conexion, String descripcion,
41 int matricula, String estado)
42 throws Exception {
43 validaDescripcion(conexion, descripcion);
44 validaMatricula(conexion, matricula);
45 validaEstado(conexion, estado);
46 }
47
48 void validaDescripcion(Connection conexion, String descripcion)
49 throws Exception {
50 if (descripcion.length() == 0) {
51 abortaConexion(conexion, "Descripción Incorrecta.");
52 }
53 }
54
55 void validaMatricula(Connection conexion, int matricula)
56 throws Exception {
57 PreparedStatement ps = conexion.prepareStatement(
58 "SELECT matricula FROM alumno " +
59 "WHERE matricula = ?");
60 ps.setInt(1, matricula);
61 ResultSet rs = ps.executeQuery();
62
63 // Si la primera vez que se ejecuta rs.next() es falso, entonces no
64 // tenemos datos en la consulta; o sea que no hay alumnos con esa
65 // matrícula.
66 if (!rs.next()) {
67 ps.close();
68 abortaConexion(conexion, "Matrícula Incorrecta.");
69 }
70 }
71
72 void validaEstado(Connection conexion, String estado)
73 throws Exception {
74 String[] estados = {"BAJA","DESCOMPUESTO","EN REPARACION","OK"};
75
76 // Realiza una búsqueda binaria del estado buscado en el arreglo.
77 // Los datos del arreglo deben estar ordenados o no funcionará.
78 // Si encuentra el dato, regresa su posición en el arreglo. Cuando
79 // no lo encuentra regresa un valor negativo. Cuando tienes muchos
80 // valores posibles es más eficiente realizar una búsqueda que
81 // poner un if por cada valor que deseas validar.
82 if (Arrays.binarySearch(estados, estado) < 0) {
83 abortaConexion(conexion, "Estado Incorrecto.");
84 }
85 }
86
87 void abortaConexion(Connection conexion, String causa)
88 throws Exception {
89 conexion.rollback();
90 conexion.close();
91 throw new Exception(causa);
92 }
93

21
94 public void muestraRegistros() throws Exception {
95 Connection conexion =
96 DriverManager.getConnection(url, usuario, password);
97 conexion.setTransactionIsolation(
98 Connection.TRANSACTION_SERIALIZABLE);
99 PreparedStatement ps =
100 conexion.prepareStatement("SELECT * FROM material");
101 ResultSet rs = ps.executeQuery();
102 System.out.println("------------------------------------------");
103 while (rs.next()) {
104 System.out.println(rs.getString("id") + "|" +
105 rs.getString("descripcion") + "|" +
106 rs.getString("matricula") + "|" +
107 rs.getString("estado"));
108 }
109 rs.close();
110 ps.close();
111 conexion.close();
112 }
113
114 public void muestraJoin() throws Exception {
115 Connection conexion =
116 DriverManager.getConnection(url, usuario, password);
117 conexion.setTransactionIsolation(
118 Connection.TRANSACTION_SERIALIZABLE);
119 PreparedStatement ps = conexion.prepareStatement(
120 "SELECT alumno.matricula, nombre, id, descripcion " +
121 "FROM alumno, material " +
122 "WHERE alumno.matricula = material.matricula");
123 ResultSet rs = ps.executeQuery();
124 System.out.println("------------------------------------------");
125 while (rs.next()) {
126 System.out.println(rs.getString(1) + "|" +
127 rs.getString("nombre") + "|" +
128 rs.getString("id") + "|" +
129 rs.getString("descripcion"));
130 }
131 rs.close();
132 ps.close();
133 conexion.close();
134 }
135

22
136 public static void main(String[] args) {
137 try {
138 Class.forName("com.mysql.jdbc.Driver");
139 ctrlAccesoMaterial a = new ctrlAccesoMaterial();
140 int id =a.inserta("Banca con paleta", 200141, "OK");
141 System.out.println("id = " + id);
142 a.inserta("Banca sin paleta", 200142, "DESCOMPUESTO");
143 a.inserta("Paleta sin banca", 200143, "BAJA");
144
145 // Es importante que una prueba de unidad verifique el
146 // comportamiento de la clase en situaciones de error.
147 try { //un ejemplo de error
148 a.inserta("", 200141, "OK");
149 } catch (Exception e) {
150 System.out.println(e.getMessage());
151 }
152 try { //un ejemplo de error
153 a.inserta("Banca", 2001, "EN REPARACION");
154 } catch (Exception e) {
155 System.out.println(e.getMessage());
156 }
157 try { //un ejemplo de error
158 a.inserta("Banca", 200141, "MAL");
159 } catch (Exception e) {
160 System.out.println(e.getMessage());
161 }
162 a.muestraRegistros();
163 a.muestraJoin();
164 } catch (Exception e) {
165 e.printStackTrace();
166 }
167 }
168 }

2.4.9. Salida en Pantalla.
Línea Salida en Pantalla
141 id = 1
150 Descripción Incorrecta.
155 Matrícula Incorrecta.
160 Estado Incorrecto.
102 ------------------------------------------
104 – 1007 1|Banca con paleta|200141|OK
104 – 1007 2|Banca sin paleta|200142|DESCOMPUESTO
104 – 1007 3|Paleta sin banca|200143|BAJA
124 ------------------------------------------
126 – 129 200141|Zoila Vaca|1|Banca con paleta
126 – 129 200142|Rolando Mota|2|Banca sin paleta
126 – 129 200143|Armando Pacheco|3|Paleta sin banca

2.4.8. Comentarios.
Cuando manejas llaves foráneas el orden de inserción es muy importante. Primero debes insertar los
datos en aquellas tablas que no manejan llaves foráneas y después debes insertar  en las tablas que
apuntan hacia datos ya insertados.

Parecería que el revisar las cuestiones de integridad en el programa y en la base de datos es un trabajo
repetitivo, y así es, pero existe una razón para ello. Al hacer la validación desde el programa haces que

23
los mensajes de error sean más claros. Por otro lado, los datos no siempre son manipulados desde
programa y los programas pueden tener errores en las validaciones. Por eso es importante poner reglas
de negocio en la base de datos.

2.5. Manejo de cadenas.


Tal vez te has preguntado como comparar y manipular cadenas. He aquí la respuesta.

2.5.1. Ejemplo de Manejo de Texto (“Cadenas.java”).
1 public class Cadenas {
2 public static void main(String[] args) {
3 String base = "Cadena base";
4
5 // Pega dos cadenas.
6 System.out.println("prefijo" + base);
7
8 // Obtiene una subcadena que va desde el caracter 2 hasta el 5.
9 System.out.println(base.substring(2,6));
10
11 // Regresa verdadero si las dos cadenas son el mismo texto.
12 System.out.println(base.equals("Cadena base"));
13 System.out.println(base.equals("inicio"));
14
15 // Regresa
16 // > 0 si "a" > "sala"
17 // < 0 si "a" < "sala"
18 // == 0 si "a" == "sala"
19 System.out.println("a".compareTo("sala")<0);
20 System.out.println(base.compareTo("Cadena base")==0);
21
22 // Verdadero si la cadena termina con "ase".
23 System.out.println(base.endsWith("ase"));
24
25 // Verdadero si la cadena comienza con ase.
26 System.out.println(base.startsWith("Cad"));
27
28 // Regresa el caracter en la posición 7, empezando desde 0.
29 System.out.println(base.charAt(7));
30
31 // Es como "equals", pero no hace distinción de mayúsculas y
32 // minúsculas.
33 System.out.println("tela".equalsIgnoreCase("TELA"));
34
35 // Busca el caracter 'a' desde el inicio de la cadena y regresa la
36 // posición donde lo encontró. Si no aparece, regresa un valor
37 // negativo.
38 System.out.println(base.indexOf('a'));
39
40 // Igual que el anterior, pero busca a partir de la posición 3.
41 System.out.println(base.indexOf('a', 3));
42
43 // Busca subcadenas. Tambén hay una variante que busca a partir de
44 // cierta posición.
45 System.out.println(base.indexOf("de"));
46
47 // Busca desde el final. Tiene las mismas variantes que "indexOf".
48 System.out.println(base.lastIndexOf('a'));
49

24
50 // Regresa el número de posiciones que ocupa la cadena; o sea, su
51 // longitud.
52 System.out.println(base.length());
53
54 // Convierte todas las letras de la cadena en su equivalente en
55 // minúscula. El resto de los caracteres no se modifican.
56 System.out.println(base.toLowerCase());
57
58 // Convierte todas las letras de la cadena en su equivalente en
59 // mayúscula. El resto de los caracteres no se modifican.
60 System.out.println(base.toUpperCase());
61
62 System.out.println(" espacios " + "hola");
63
64 // Remueve los espacios al inicio y al final de una cadena.
65 System.out.println(" trim ".trim() + "hola");
66 }
67 }

2.5.2. Salida en Pantalla.
Línea Salida en Pantalla
6 prefijoCadena base
9 dena
12 true
13 false
19 true
20 true
23 true
24 true
29 b
33 true
38 1
41 5
45 2
48 8
52 11
56 cadena base
60 CADENA BASE
62 espacios hola
65 trimhola

2.5.3. Comentarios.
Las operaciones sobre cadenas no modifican la cadena base. El resultado siempre se obtiene en una
nueva cadena.

¿Por qué no comparar las cadenas con el signo “ ==”?  Este signo compara que dos objetos sean el


mismo. Pero puede suceder que dos cadenas sean objetos diferentes, pero contengan el mismo texto.
Las operaciones de comparación que se mostraron en el programa trabajan con el contenido de los
objetos.

¿Qué significa que una cadena sea menor que otra? La cadena que aparece primero en el diccionario.
En el caso de que tengas que comparar caracteres que no sean letras, utiliza su código Unicode. El
valor más pequeño es el que aparece primero en el diccionario. Nota que al comparar cadenas sucede
que “10”  < “2”. ¿ Entiendes por qué?

25
3.
Interfaces
Gráficas.

26
3. Interfaces Gráficas.
El mecanismo principal que tiene Java para interactuar con el usuario es el uso de interfaces gráficas.

3.1. Un Ejemplo Simple.


3.1.1. Especificación.

Ilustración 8. frmSencilla.

El usuario debe proporcionar el valor de “nombre”.  Al oprimir el botón “Púchale”  el contenido de este


campo se copia a “dirección ” .

3.1.2. Vista Lógica.
JPanel

frmSencilla
- serialVersionUID: long = 1L {frozen}
- lblNombre: JLabel = new JLabel("Nombre:")
- txtNombre: JTextField = new JtextField(10)
- lblDireccion: JLabel = new JLabel("Direccion:")
- txtDireccion: JTextField = new JTextField(10)
- btnPuchale: JButton = new JButton("Puchale")

+ frmSencilla( )
+ agregaEventos()
+ clickEnPuchale()
+ main(args: String[])

Ilustración 9. Vista Lógica de frmSencilla.

Java tiene ya construidas clases para en desarrollo de interfaces gráficas. La clase JPanel representa
formas en blanco a las cuales se pueden agregar componentes gráficos. Como el trabajo ya está hecho,
vamos a utilizar un mecanismo que se conoce como generalización. La flecha del diagrama indica que
la   clase   “ frmSencilla”   tiene   todos   los   miembros   (variables   y   métodos)   de   un   “JPanel”,   pero   que
extiende   su   funcionalidad   añadiéndole   los   miembros   que   se   muestran.   Se   dice   que   “frm Sencilla”
hereda todos los miembros de JPanel. En este esquema, “frmSencilla”  es clase hija de JPanel o bien
clase derivada. A su vez, JPanel es clase padre de frmSencilla.

27
“ JPanel”  es un conjunto de objetos. “frmSencilla”  es un subconjunto de esta. En cualquier parte de
código donde se requiera un objeto de la clase padre, puedes usar un objeto de la clase hija.

3.1.3.  Código de “f rmSencilla.java”.
1 import javax.swing.*; // Para todos los componentes gráficos.
2 import java.awt.*; // Para la clase "GridLayout".
3 import java.awt.event.*; // Para los eventos de los botones.
4
5 /**
6 * La palabra extends indica que "frmSencilla" es clase hija de
7 * JPanel.
8 */
9 public class frmSencilla extends JPanel {
10 /**
11 * Esto es necesario por una característica de los objetos en Java que se
12 * conoce como serialización.
13 */
14 private static final long serialVersionUID = 1L;
15
16 // Definición de los componentes gráficos en Java.
17
18 /**
19 * Etiqueta. Al crearla se le pasa el texto que despliega.
20 */
21 private JLabel lblNombre = new JLabel("Nombre:");
22
23 /**
24 * Cuadro de texto. Se le pasa el número de caracteres a mostrar.
25 */
26 private JTextField txtNombre = new JTextField(10);
27
28 private JLabel lblDireccion = new JLabel("Dirección:");
29 private JTextField txtDireccion = new JTextField(10);
30
31 /**
32 * Botón. Se le pasa el texto a mostrar.
33 */
34 private JButton btnPuchale = new JButton("Púchale");
35
36 /**
37 * Constructor de la clase "frmSencilla". Se invoca en el momento de
38 * crear un objeto de esta clase. Permite inicializar valores y realizar
39 * procesos.
40 */
41 public frmSencilla() {
42 agregaEventos();
43
44 // A los objetos de JPaneles hay que ponerles un layout.
45 // Este les indica como organizar los componentes. En este caso el
46 // objeto de clase "GridLayout" indica que se usarán tres renglones
47 // y dos columnas.
48 setLayout(new GridLayout(3, 2));
49
50 // Agrega los componentes en orden de izquierda a derecha hasta
51 // llenar el renglón, continuando con el renglón inferior
52 add(lblNombre); add(txtNombre);
53 add(lblDireccion); add(txtDireccion);
54 add(btnPuchale);
55 }
56

28
57 void agregaEventos() {
58 // Liga el método "clickEnPuchale" con la acción de apretar el
59 // botón btnPuchale.
60 btnPuchale.addActionListener(new ActionListener() {
61 public void actionPerformed(ActionEvent evt) {
62 clickEnPuchale();
63 }
64 });
65 }
66
67 public void clickEnPuchale() {
68 // Toma el contenido del cuadro de texto "txtNombre" y lo deja en la
69 // variable "nombre".
70 String nombre = txtNombre.getText();
71
72 // Cambia el contenido al cuadro de texto "txtDireccion".
73 txtDireccion.setText(nombre);
74 }
75
76 public static void main(String[] args) {
77 // JFrame representa a las ventanas principales de una aplicación.
78 // Al construir el objeto se le pasa el texto a desplegar en la
79 // barra de título.
80 JFrame frame = new JFrame("Interfaz Simple");
81
82 // Crea un objeto de "frmSencilla", o sea una forma, y le pone
83 // barras de desplazamiento que se desplegarán cuando sea necesario.
84 // Para ello, se coloca en un JscrollPane. Finalmente este objeto
85 // se agrega a la ventana principal.
86 frame.add(new JScrollPane(new frmSencilla()));
87
88 // Se configura la ventana principal para que termina la aplicación
89 // al cerrarse.
90 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
91
92 // Calcula el tamaño y coordenadas de todos los componentes gráficos
93 // que contiene la ventana principal.
94 frame.pack();
95 // Muestra la ventana principal.
96 frame.setVisible(true);
97 }
98 }

3.1.4. Comentarios.
Al   usar   un   “G ridLayout”  todos  los  componentes  quedan  del  mismo  tamaño. En compensación,   la
colocación en un JPanel es muy simple. Más adelante se tocará la forma de construir interfaces con una
mejor apariencia.

La serialización es un mecanismo que permite a Java almacenar objetos y transportarlos a través de
redes.   Todos   los   objetos   que   implementen   ese   mecanismo   deben   declarar   la   constante
“serialV ersionUID”.  La clase JPanel es serializable y por lo tanto, la clase “frmSencilla”  también lo es,
pues hereda todas las características de su clase padre.

En Java las clases pueden tener a lo más una clase padre.

29
3.2. Acceso a Bases de Datos Desde Interfaces Gráficas.
Ahora vamos a integrar lo estudiado en este capítulo y en los anteriores.

3.2.1. Especificación.

Ilustración 10. frmInsertaAlumno.

El   usuario   debe   proporcionar   el   valor   de   “matrícula” ,   “nom bre”   y   “fecha ”.   Al   oprimir   el   botón
“Guarda r”  se toma el contenido de  los tres campos para insertar un registro en la tabla “ alumno” .

3.2.2. Vista Lógica.

frmInsertaAlumno
- serialVersionUID: long = 1L {frozen}
- formato: DateFormat = getDateInstance( )
- lblMatricula: Jlabel = new JLabel("Matricula:")
- txtMatricula: JTextField = new JTextField(10)
- lblNombre: JLabel = new JLabel("Nombre:")
- txtNombre JTextField = new JTextField(10)
- lblFecha: JLabel = new JLabel("Fecha:")
- txtFecha: JtextField = new JTextField(10)
- btnGuardar: JButton = new JButton("Guardar")

- frmInsertaAlumno( )
~agregaEventos( )
+clickEnGuardar( )
~muestraMensaje(String mensaje)
+ main(args: String[])

1 control

ctrlInsertaAlumno alumno
* matricula: int
- url: String = "jdbc:mysql://localhost/test" {frozen} nombre: String
- usuario: String = "root" {frozen} fecha_de_nacimiento: Date
- password :String password = "" {frozen}

+ inserta(matricula: int, nombre: String, fecha: java.sql.Date )

Ilustración 11. Vista Lógica para frmInsertaAlumno.

En este caso dividimos las funciones en dos objetos:

30
Por un lado, se usa un objeto de la clase “ ctrlInsertaAlumno”,  al cual llamaremos objeto de control,
puesto que se encargará del control de transacciones y acceso al almacén de datos.

Por otro lado, se usa un objeto de la clase “frmInserta Alumno”,  que llamaremos objeto de interacción.


Este se encargará de la interfaz de usuario. Creará el objeto de control y será su dueño. Al destruir el
objeto   de   interacción,   se   destruye   el   objeto   de   control.   Esta   relación   de   pertenencia   se   llama
agregación y está representada por el rombo negro que une ambas clases.

El encargado de validar la integridad de los registros a insertar, es la base de datos.

3.2.3. Código de “f rmInsertaAlumno.java”.
1 import javax.swing.*;
2 import java.awt.*;
3 import java.awt.event.*;
4 import java.text.*;
5
6 public class frmInsertaAlumno extends JPanel {
7 private static final long serialVersionUID = 1L;
8 private static DateFormat formato = DateFormat.getDateInstance();
9
10 private JLabel lblMatricula = new JLabel("Matrícula:");
11 private JTextField txtMatricula = new JTextField(10);
12 private JLabel lblNombre = new JLabel("Nombre:");
13 private JTextField txtNombre = new JTextField(10);
14 private JLabel lblFecha = new JLabel("Fecha:");
15 private JTextField txtFecha = new JTextField(10);
16 private JButton btnGuardar = new JButton("Guardar");
17
18 /**
19 * Crea el objeto de control y establece la relación con él.
20 */
21 private ctrlInsertaAlumno control = new ctrlInsertaAlumno();
22
23 public frmInsertaAlumno() {
24 agregaEventos();
25 setLayout(new GridLayout(4, 2));
26 add(lblMatricula); add(txtMatricula);
27 add(lblNombre); add(txtNombre);
28 add(lblFecha); add(txtFecha);
29 add(btnGuardar);
30 }
31
32 void agregaEventos() {
33 btnGuardar.addActionListener(new ActionListener() {
34 public void actionPerformed(ActionEvent evt) {
35 clickEnGuardar();
36 }
37 });
38 }
39

31
40 public void clickEnGuardar() {
41 int matricula = 0;
42 boolean datosOk = true;
43 try {
44 // parseInt convierte texto en un número entero. Si el contenido
45 // de la cadena no es un número, se genera una excepción.
46 matricula = Integer.parseInt(txtMatricula.getText());
47 } catch (Exception e) {
48 muestraMensaje("La matricula debe ser numerica.");
49 datosOk = false;
50 }
51 String nombre = txtNombre.getText();
52 java.sql.Date fecha = null;
53 try {
54 fecha = new java.sql.Date(
55 formato.parse(txtFecha.getText()).getTime());
56 } catch (Exception e) {
57 muestraMensaje("Fecha en formato incorrecto.");
58 datosOk = false;
59 }
60 if (datosOk) {
61 try {
62 control.inserta(matricula, nombre, fecha);
63 muestraMensaje("Registro Insertado.");
64 } catch (Exception e) {
65 muestraMensaje(e.getMessage());
66 e.printStackTrace();
67 }
68 }
69 }
70
71 public void muestraMensaje(String mensaje) {
72 // Muestra un cuadro de diálogo modal que despliega “mensaje”.
73 // El valor null se refiere al JFrame que debe bloquear.
74 JOptionPane.showMessageDialog(null, mensaje);
75 }
76
77 public static void main(String[] args) {
78 try {
79 Class.forName("com.mysql.jdbc.Driver");
80 JFrame frame = new JFrame("Inserta Alumno");
81 frame.add(new JScrollPane(new frmInsertaAlumno()));
82 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
83 frame.pack();
84 frame.setVisible(true);
85 } catch (Exception e) {
86 e.printStackTrace();
87 }
88 }
89 }

32
3.2.4. Código de “c trlInsertaAlumno.java”.
1 import java.sql.*;
2 import java.text.*;
3
4 public class ctrlInsertaAlumno {
5 private static final String url = "jdbc:mysql://localhost/test";
6 private static final String usuario = "root";
7 private static final String password = "";
8
9 public void inserta(int matricula, String nombre, java.sql.Date fecha)
10 throws Exception {
11 Connection conexion =
12 DriverManager.getConnection(url, usuario, password);
13 conexion.setTransactionIsolation(
14 Connection.TRANSACTION_SERIALIZABLE);
15 PreparedStatement ps = conexion.prepareStatement(
16 "INSERT INTO alumno VALUES(?, ?, ?)");
17 ps.setInt(1, matricula);
18 ps.setString(2, nombre);
19 ps.setDate(3, fecha);
20 ps.executeUpdate();
21 ps.close();
22 conexion.close();
23 }
24 }

3.2.5. Comentarios.
Aunque la clase de control no muestra la prueba de unidad, es conveniente que la incluyas. Tampoco se
incluyó la función de validación; agrégala.

Los   cuadros  de   diálogo   normalmente   se   utilizan   para   obtener  información   complementaria   y   para
mostrar los resultados de algún proceso. El flujo normal debe realizarse a través de la ventana principal
de tu aplicación.

Los cuadros de diálogo pueden ser de dos tipos:
• Modales. Bloquean la aplicación mientras están abiertos.
• No Modales. Permiten que la aplicación funcione normalmente cuando están abiertos.

Nota que la interfaz gráfica debe coincidir con la base de datos.

33
4.
Consultas
y
Manejo
de
Restricciones.

34
4. Consultas y Manejo de Restricciones.

4.1. Una Consulta Simple.

4.1.1. Especificación.

Ilustración 12. frmBuscaAlumno.

El usuario debe introducir un valor para matrícula. Al oprimir el botón “ Buscar”  se extrae de la base de


datos la información del alumno que corresponde a esa matrícula.

4.1.2. Vista Lógica.

frmBuscaAlumno
- serialVersionUID: long = 1L {frozen}
- formato: DateFormat = getDateInstance( )
- lblMatricula: Jlabel = new JLabel("Matricula:")
- txtMatricula: JTextField = new JTextField(10)
- lblNombre: JLabel = new JLabel("Nombre:")
- txtNombre JTextField = new JTextField(10)
- lblFecha: JLabel = new JLabel("Fecha:")
- txtFecha: JtextField = new JTextField(10)
- btnBuscar: JButton = new JButton("Buscar")

- frmBuscaAlumno( )
~agregaEventos( )
+clickEnBuscar( )
~muestraMensaje(String mensaje)
+ main(args: String[])

1 control

ctrlBuscaAlumno infoAlumno
* matricula: int
- url: String = "jdbc:mysql://localhost/test" {frozen} nombre: String
- usuario: String = "root" {frozen} fecha_de_nacimiento: Date
- password :String password = "" {frozen}

+busca(int id): LinkedHashMap<String, Object>

Ilustración 13. Vista Lógica para frmBuscaAlumno.

35
En este caso la clase de control regresa el contenido de un registro en una estructura que se llama
LinkedHashMap. Esta estructura es como una tabla de dos campos. El primero se conoce como llave y
es como una llave primaria. El segundo se conoce como valor asociado.
4.1.3. Diagrama de Secuencia.

: frmBuscaAlumno control: ctrlBuscaAlumno : infoAlumno

1. lee(id)

2. clickEnBuscar( )
3. busca(matricula: int)

4. estableceConexion( )
5. get(matricula): ResultSet

6. guardaValores()

7. terminaConexion( )
8. respuesta

9. muestraRegistro(respuesta)

Dibujo 1. Diagrama de Secuencia para frmBuscaAlumno.

Aquí tenemos el flujo principal de la aplicación. El control de errores se incorpora en el código. Nota
que cada flecha es recibida por el objeto que va a realizar la operación. Este diagrama funciona como
pseudocódigo y establece el diseño. Al implementarse, la clase infoAlumno se convierte en la tabla
“alumno”.

En el código, las instrucciones llevan comentarios que empiezan con una letra “D ” , seguida por el
número que le corresponde en el diagrama..

36
4.1.4. Código de “f rmBuscaAlumno.java”.
1 import java.awt.event.*;
2 import javax.swing.*;
3 import java.awt.*;
4 import java.text.*;
5 import java.util.*; // Para la clase "LinkedHashMap".
6
7 public class frmBuscaAlumno extends JPanel {
8 private static final long serialVersionUID = 1L;
9 private static final DateFormat formato = DateFormat.getDateInstance();
10
11 private JLabel lblMatricula = new JLabel("Matrícula:");
12 private JTextField txtMatricula = new JTextField(10);
13 private JLabel lblNombre = new JLabel("Nombre:");
14 private JTextField txtNombre = new JTextField(10);
15 private JLabel lblFecha = new JLabel("Fecha:");
16 private JTextField txtFecha = new JTextField(10);
17 private JButton btnBuscar = new JButton("Buscar");
18
19 private ctrlBuscaAlumno control = new ctrlBuscaAlumno();
20
21 public frmBuscaAlumno() {
22 agregaEventos();
23 setLayout(new GridLayout(4,2));
24 add(lblMatricula); add(txtMatricula);
25 add(lblNombre); add(txtNombre);
26 add(lblFecha); add(txtFecha);
27 add(btnBuscar);
28 }
29 void agregaEventos() {
30 btnBuscar.addActionListener(new ActionListener() {
31 public void actionPerformed(ActionEvent evt) {
32 clickEnBuscar(); //D2
33 }
34 });
35 }
36
37 public void clickEnBuscar() { //D2
38 int matricula = 0;
39 boolean datosOk = true;
40 try {
41 matricula = Integer.parseInt(txtMatricula.getText());
42 } catch (NumberFormatException e) {
43 muestraMensaje("La matricula debe ser numerica.");
44 datosOk = false;
45 }
46 if (datosOk) {
47 try {
48 // El objeto de control busca en la base de datos los datos
49 // del alumno con la matrícula introducida. Si no encuentra
50 // ningún alumno con esa matrícula, lanza una excepción. Si
51 // encuentra el registro, regresa una tabla que tiene como
52 // campo llave el nombre del atributo y como valor asociado
53 // el valor de ese atributo. Todas las clases son hijas de
54 // la clase Object.
55 LinkedHashMap<String,Object> respuesta = //D3
56 control.busca(matricula); //D3
57 muestraRegistro(respuesta); //D9
58 } catch (Exception e) {
59 muestraMensaje(e.getMessage());
60 }
61 }
62 }
63

37
64 public void muestraRegistro(LinkedHashMap<String,Object> respuesta) {//D9
65 // get recupera el valor asociado con el nombre del campo.
66 // Todos los objetos tienen una operación llamada toString que
67 // permite obtener su representación como cadena.
68 txtMatricula.setText(respuesta.get("matricula").toString()); //D9
69 txtNombre.setText(respuesta.get("nombre").toString()); //D9
70
71 // De todas formas las fechas se tienen que manejar con el objeto
72 // formateador. La expresión "(java.sql.Date)" verifica si el objeto
73 // pertenece a esa clase. En caso de que no, se genera una excepción.
74 // Si el objeto si pertenece a esa clase, recupera ese tipo.
75 txtFecha.setText( //D9
76 formato.format((java.sql.Date)respuesta.get("fecha"))); //D9
77 }
78
79 public void muestraMensaje(String mensaje) {
80 JOptionPane.showMessageDialog(null, mensaje);
81 }
82
83 public static void main(String[] args) {
84 try {
85 Class.forName("com.mysql.jdbc.Driver");
86 JFrame frame = new JFrame("Busca Alumno");
87 frame.add(new JScrollPane(new frmBuscaAlumno()));
88 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
89 frame.pack();
90 frame.setVisible(true);
91 } catch (Exception e) {
92 e.printStackTrace();
93 }
94 }
95 }

38
4.1.5. Código de “c trlBuscaAlumno.java”.
1 import java.sql.*;
2 import java.util.*;
3
4 public class ctrlBuscaAlumno {
5 private static final String url = "jdbc:mysql://localhost/test";
6 private static final String usuario = "root";
7 private static final String password = "";
8
9 public LinkedHashMap<String,Object> busca(int id) throws Exception {//D3
10 Connection conexion = //D4
11 DriverManager.getConnection(url, usuario, password);//D4
12 conexion.setTransactionIsolation( //D4
13 Connection.TRANSACTION_SERIALIZABLE); //D4
14 PreparedStatement ps = conexion.prepareStatement( //D5
15 "SELECT * FROM alumno WHERE matricula = ?");//D5
16 ps.setInt(1, id); //D5
17 ResultSet rs = ps.executeQuery(); //D5
18 LinkedHashMap<String,Object> respuesta = //D6
19 new LinkedHashMap<String,Object>(); //D6
20
21 // Si el dato se encuentra, la consulta tiene un registro. En ese
22 // caso, rs.next() es positivo. Como solo queremos un campo usamos
23 // if.
24 if (rs.next()) {
25 Integer matricula = //D6
26 new Integer(rs.getInt("matricula"));//D6
27 String nombre = rs.getString("nombre"); //D6
28 java.sql.Date fecha_de_nacimiento = //D6
29 rs.getDate("fecha_de_nacimiento"); //D6
30
31 // Agrega un registro a la tabla. El campo llave es el nombre
32 // del campo y el valor asociado es el valor del campo.
33 respuesta.put("matricula", matricula); //D6
34 respuesta.put("nombre", nombre); //D6
35 respuesta.put("fecha", fecha_de_nacimiento); //D6
36 } else { // El dato no se encontró. Flujo alterno.
37 rs.close();
38 ps.close();
39 conexion.close();
40 throw new Exception("Registro no encontrado.");
41 }
42 rs.close(); //D7
43 ps.close(); //D7
44 conexion.close(); //D7
45 return respuesta; //D8
46 }
47 }

4.1.6. Comentarios.
Se recomienda que realices los diagramas de análisis antes de programar, porque te ayudan a clarificar
tus ideas. El repartir el código en clases te ayuda a hacerlo más fácil de manejar.

Los   objetos   de   la   clase   LinkedHashMap   funcionan   como   diccionarios   y   son   muy   prácticos   para
manejar parejas de información.

39
4.2. Manejo de Restricciones.

4.2.1. Especificación.

Ilustración 14. frmRestricciones.

Este ejemplo trabaja con las tablas “alumno”  y “ material”.  La interfaz gráfica debe ayudar al usuario a


realizar su trabajo. Al capturar llaves foráneas, en este ejemplo debes proporcionar la matrícula de su
dueño,   pero,   ¿te   acuerdas   de   ellas?   Para   ayudar   al   usuario   le   presentamos   en   un   combo   box   las
matrículas registradas y el nombre del alumno correspondiente. Esto es más fácil de manejar. Si te
fijas, la relación entre matrícula y nombre funciona como un diccionario. Por ello utilizaremos un
LinkedHashMap para guardar las matrículas y el nombre que le corresponde.

En el caso del “estado” , tenemos un dominio bien definido. Por ello usamos un combo box con los
únicos valores permitidos.

El botón “ Buscar”  sirve para recuperar la los datos del material que corresponde al campo “Id”.  Por


otro lado el botón “Modificar”  muestra un cuadro de diálogo con la información que se enviaría a la
base de datos. En el caso del responsable solo se muestra la matrícula y se elimina en nombre.

4.2.2. Código de “f rmRestricciones.java”.
1 import java.awt.event.*;
2 import java.awt.*;
3 import javax.swing.*;
4 import java.util.*;
5
6 public class frmRestricciones extends JPanel {
7 private static final long serialVersionUID = 1L;
8
9 private JLabel lblId = new JLabel("Id:");
10 private JTextField txtId = new JTextField(10);
11 private JLabel lblDescripcion = new JLabel("Descripción:");
12 private JTextField txtDescripcion = new JTextField(10);
13 private JLabel lblMatricula = new JLabel("Responsable:");
14 private JComboBox cmbMatricula = new JComboBox();
15 private JLabel lblEstado = new JLabel("Estado:");
16 private JComboBox cmbEstado = new JComboBox();
17 private JButton btnBuscar = new JButton("Buscar");
18 private JButton btnModificar = new JButton("Modificar");
19

40
20 /**
21 * El campo llave contiene la matrícula y el valor asociado es el nombre.
22 */
23 private LinkedHashMap<String, String> matriculas;
24
25 private ctrlRestricciones control = new ctrlRestricciones();
26
27 public frmRestricciones() {
28 configuraComponentes();
29 agregaEventos();
30 setLayout(new GridLayout(5, 2));
31 add(lblId); add(txtId);
32 add(lblDescripcion); add(txtDescripcion);
33 add(lblMatricula); add(cmbMatricula);
34 add(lblEstado); add(cmbEstado);
35 add(btnBuscar); add(btnModificar);
36 }
37
38 void configuraComponentes() {
39 // Los campos numéricos se justifican a la derecha.
40 txtId.setHorizontalAlignment(JTextField.RIGHT);
41
42 // Se añaden renglones al combo box
43 cmbEstado.addItem("BAJA");
44 cmbEstado.addItem("DESCOMPUESTO");
45 cmbEstado.addItem("EN REPARACION");
46 cmbEstado.addItem("OK");
47
48 // hay que llenar cmbMatricula con la información de la base de
49 // datos.
50 cargaMatriculas();
51 }
52
53 void cargaMatriculas() {
54 try {
55 matriculas = control.cargaMatriculas();
56 agregaMatriculas();
57 } catch (Exception e) {
58 muestraMensaje(e.getMessage());
59 }
60 }
61
62 void agregaMatriculas() {
63 // Borra todos los renglones del combo box.
64 cmbMatricula.removeAllItems();
65
66 int i = 0;
67
68 // entrySet() nos proporciona una lista de las parejas almacenadas
69 // en el LinkedHashMap.
70 for (Map.Entry<String,String> e: matriculas.entrySet()) {
71 String matricula = e.getKey(); // Recupera el valor llave.
72 String nombre = e.getValue(); // Recupera el valor asociado.
73 cmbMatricula.addItem(matricula + " - " + nombre);
74 }
75 }
76

41
77 void agregaEventos() {
78 btnBuscar.addActionListener(new ActionListener() {
79 public void actionPerformed(ActionEvent evt) {
80 clickEnBuscar();
81 }
82 });
83 btnModificar.addActionListener(new ActionListener() {
84 public void actionPerformed(ActionEvent evt) {
85 clickEnModificar();
86 }
87 });
88 }
89
90 public void clickEnBuscar() {
91 int id = 0;
92 boolean datosOk = true;
93 try {
94 id = Integer.parseInt(txtId.getText());
95 } catch (Exception e) {
96 muestraMensaje("El id debe ser numerico.");
97 datosOk = false;
98 }
99 if (datosOk) {
100 try {
101 LinkedHashMap<String,Object> respuesta = control.busca(id);
102 muestraRegistro(respuesta);
103 } catch (Exception e) {
104 muestraMensaje(e.getMessage());
105 }
106 }
107 }
108
109 public void clickEnModificar() {
110 int id = 0;
111 boolean datosOk = true;
112 try {
113 id = Integer.parseInt(txtId.getText());
114 } catch (NumberFormatException e) {
115 muestraMensaje("El id debe ser numerico.");
116 datosOk = false;
117 }
118 String descripcion = txtDescripcion.getText();
119

42
120 // Recupera la combinación de matrícula y nombre seleccionadas.
121 // Con “split” separa la matrícula del nombre, usando " - " como
122 // separación. Seleccion[0] es la matrícula y seleccion[1] el
123 // nombre.
124 String[] seleccion =
125 cmbMatricula.getSelectedItem().toString().split(" - ");
126 int matricula = 0;
127 try {
128 matricula = Integer.parseInt(seleccion[0]);
129 } catch (NumberFormatException e) {
130 muestraMensaje("La matricula debe ser numerica.");
131 datosOk = false;
132 }
133 String estado = cmbEstado.getSelectedItem().toString();
134 if (datosOk) {
135 muestraMensaje("Se quiere modificar\n"
136 + "id = " + id + "\n"
137 + "descripcion = " + descripcion + "\n"
138 + "matricula = " + matricula + "\n"
139 + "estado = " + estado);
140 control.modifica(id, descripcion, matricula, estado);
141 }
142 }
143
144 public void muestraRegistro(LinkedHashMap<String,Object> respuesta) {
145 txtDescripcion.setText(respuesta.get("descripcion").toString());
146 String matricula = respuesta.get("matricula").toString();
147
148 // En la base de datos solo está almacenada la matrícula, pero para
149 // seleccionar en cmbMatricula necesitas también el nombre. Para
150 // ello podemos recurrir al LinkedHashMap llamado "matriculas".
151 // Con get(matricula) recuperas el nombre.
152 cmbMatricula.setSelectedItem(
153 matricula + " - " + matriculas.get(matricula));
154
155 cmbEstado.setSelectedItem(respuesta.get("estado").toString());
156 }
157
158 public void muestraMensaje(String mensaje) {
159 JOptionPane.showMessageDialog(null, mensaje);
160 }
161
162 public static void main(String[] args) {
163 try {
164 Class.forName("com.mysql.jdbc.Driver");
165 JFrame frame = new JFrame("Manejo de Restricciones");
166 frame.add(new JScrollPane(new frmRestricciones()));
167 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
168 frame.pack();
169 frame.setVisible(true);
170 } catch (Exception e) {
171 e.printStackTrace();
172 }
173 }
174 }

43
4.2.3. Código de “c trlRestricciones.java”.
1 import java.sql.*;
2 import java.util.*;
3
4 public class ctrlRestricciones {
5 private static final String url = "jdbc:mysql://localhost/test";
6 private static final String usuario = "root";
7 private static final String password = "";
8
9 public LinkedHashMap<String, String> cargaMatriculas() throws Exception {
10 Connection conexion =
11 DriverManager.getConnection(url, usuario, password);
12 conexion.setTransactionIsolation(
13 Connection.TRANSACTION_SERIALIZABLE);
14 PreparedStatement matriculas = conexion.prepareStatement(
15 "SELECT matricula, nombre FROM alumno");
16 ResultSet rs = matriculas.executeQuery();
17 LinkedHashMap<String,String> respuesta =
18 new LinkedHashMap<String,String>();
19 while (rs.next()) {
20 respuesta.put(rs.getString("matricula"), rs.getString("nombre"));
21 }
22 rs.close();
23 matriculas.close();
24 conexion.close();
25 return respuesta;
26 }
27
28 public LinkedHashMap<String,Object> busca(int id) throws Exception {
29 Connection conexion =
30 DriverManager.getConnection(url, usuario, password);
31 conexion.setTransactionIsolation(
32 Connection.TRANSACTION_SERIALIZABLE);
33 PreparedStatement busca = conexion.prepareStatement(
34 "SELECT * FROM material WHERE id = ?");
35 busca.setInt(1, id);
36 ResultSet rs = busca.executeQuery();
37 LinkedHashMap<String,Object> respuesta =
38 new LinkedHashMap<String,Object>();
39 if (rs.next()) { //Solo queremos un elemento
40 respuesta.put("matricula", new Integer(rs.getInt("matricula")));
41 respuesta.put("descripcion", rs.getString("descripcion"));
42 respuesta.put("estado", rs.getString("estado"));
43 } else {
44 rs.close();
45 busca.close();
46 conexion.close();
47 throw new Exception("Registro no encontrado.");
48 }
49 rs.close();
50 busca.close();
51 conexion.close();
52 return respuesta;
53 }
54 public void modifica(int id, String descripcion, int matricula,
55 String estado) {}
56 }

4.2.4. Comentarios.
En muchos ambientes de desarrollo hay componentes especialmente diseñados para el manejo de llaves
foráneas. Úsalos.

44
5.
Uso
de
JTable.

45
5. Uso de JTable.
Al manejar tablas surge la necesidad de desplegar el resultado de consultas o manipular relaciones de
uno a muchos objetos. En esos casos, el componente JTable permite usar simultáneamente muchos
registros con los mismos atributos.

5.1. Un Ejemplo Sencillo.

5.1.1. Especificación.

Ilustración 15. frmTablaSencilla.

Despliega los datos almacenados en la tabla “ alumno”  en el momento de ejecutar la aplicación. Las


modificaciones realizadas mientras la ventana se despliega no se muestran.

La tabla está estructurada como un arreglo bidimensional. La funcionalidad de desplegarla se divide en
dos   clases   de   objetos.   Los   datos   se   guardan   en   objetos   de   la   clase   “DefaultT ableModel”   .   Estos
permiten realizar cualquier tipo de modificaciones a la información. Los datos pueden conectarse a uno
o   más  objetos  de  la clase   “JTable”.   Estos  se  encargan   exclusivamente  de  mostrar  la   información.
Ambos tipos de objetos están en constante comunicación. 

En caso de que los datos no puedan desplegase en su totalidad dentro del espacio que ocupa la tabla, se
pueden colocar dentro de un JScrollPane para que agregue barras de desplazamiento.

5.1.2. Código de “f rmTablaSencilla”.
1 import javax.swing.*;
2 import java.awt.event.*;
3 import java.awt.*; // Para "Dimension".
4 import javax.swing.table.*; // Para "DefaultTableModel".
5
6 public class frmTablaSencilla extends JPanel {
7 private static final long serialVersionUID = 1L;
8
9 JTable tblResultado = new JTable();
10 JScrollPane scroll = new JScrollPane(tblResultado);
11
12 ctrlTablaSencilla control = new ctrlTablaSencilla();
13

46
14 public frmTablaSencilla() {
15 configuraComponentes();
16 add(scroll);
17 }
18
19 void configuraComponentes() {
20 // Define el tamaño de la tabla. Para ello se utilizan objetos
21 // de la clase Dimension. Su primer parámetro indica los pixeles
22 // de ancho y el segundo parámetro es la altura.
23 scroll.setPreferredSize(new Dimension(400, 100));
24
25 cargaAlumnos();
26 }
27
28 void cargaAlumnos() {
29 try {
30 DefaultTableModel alumnos = control.obtenDatos();
31 tblResultado.setModel(alumnos);
32 } catch (Exception e) {
33 muestraMensaje(e.getMessage());
34 e.printStackTrace();
35 }
36 }
37
38 public void muestraMensaje(String mensaje) {
39 JOptionPane.showMessageDialog(null, mensaje);
40 }
41
42 public static void main(String[] args) {
43 try {
44 Class.forName("com.mysql.jdbc.Driver");
45 JFrame frame = new JFrame("Consulta");
46 frame.add(new JScrollPane(new frmTablaSencilla()));
47 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
48 frame.pack();
49 frame.setVisible(true);
50 } catch (Exception e) {
51 e.printStackTrace();
52 }
53 }
54 }

5.1.3. Código de “c trlTablaSencilla”.
1 import java.sql.*;
2 import java.util.*;
3 import java.text.*;
4 import javax.swing.table.*;
5
6 class ctrlTablaSencilla {
7 private static DateFormat formato = DateFormat.getDateInstance();
8 private static final String url = "jdbc:mysql://localhost/test";
9 private static final String usuario = "root";
10 private static final String password = "";
11 private static Object[] encabezados =
12 {"Matrícula", "Nombre", "Fecha de Nacimiento"};
13

47
14 public DefaultTableModel obtenDatos() throws Exception {
15 DefaultTableModel modelo = new DefaultTableModel() {
16 private static final long serialVersionUID = 1L;
17
18 public boolean isCellEditable(int renglon, int columna) {
19 return false;
20 }
21 };
22
23 // Le pone encabezado a las columnas del modelo.
24 modelo.setColumnIdentifiers(encabezados);
25
26 Connection conexion =
27 DriverManager.getConnection(url, usuario, password);
28 conexion.setTransactionIsolation(
29 Connection.TRANSACTION_SERIALIZABLE);
30 PreparedStatement consulta = conexion.prepareStatement(
31 "SELECT * FROM alumno");
32 ResultSet rs = consulta.executeQuery();
33 while (rs.next()) {
34 String matricula = rs.getString("matricula");
35 String nombre = rs.getString("nombre");
36 String fecha = formato.format(
37 rs.getDate("fecha_de_nacimiento"));
38 Object[] datos = {matricula, nombre, fecha};
39
40 // Agrega un renglón al final del modelo.
41 modelo.addRow(datos);
42 }
43 consulta.close();
44 conexion.close();
45 return modelo;
46 }
47 }

5.2. Un Ejemplo más Completo.

5.2.1. Especificación.

Ilustración 16. frmTablaCompleta.

De inicio la tabla está vacía. Cada vez que se oprime el botón “Nuevo”  se agrega un renglón en blanco.
Cada vez que se oprime “F2”  se puede modificar el contenido de cada celda de la tabla. Una vez que el
dato se ha modificado aparece un cuadro indicando que campo se quiere modificar en cual renglón. Al
seleccionar un renglón y oprimir “Borrar ”,  se elimina la línea seleccionada. El botón “Total”  muestra la
suma de los goles.

48
5.2.2. Código de “f rmTablaCompleta.java”.
1 import javax.swing.*;
2 import java.awt.event.*;
3 import javax.swing.table.*;
4 import java.awt.*;
5
6 public class frmTablaCompleta extends JPanel{
7 private static final long serialVersionUID = 1L;
8
9 /**
10 * Se crea un DefaultTableModel, pero se le cambian algunas funciones,
11 */
12 DefaultTableModel modelo = new DefaultTableModel() {
13 private static final long serialVersionUID = 1L;
14
15 /**
16 * Regresa una clase que representa el tipo de datos de
17 * cada columna. La numeración empieza en 0.
18 */
19 public Class getColumnClass(int columna) {
20 switch (columna) {
21 case 0: return String.class;
22 case 1: return Integer.class;
23 case 2: return Boolean.class;
24 case 3: return String.class;
25 default: return Object.class;
26 }
27 }
28
29 /**
30 * Esta función se invoca cada vez que se quiere
31 * modificar una celda. El JTable le envía el
32 * nuevo valor que el usuario quiere colocar en la
33 * celda.
34 */
35 public void setValueAt(Object valor, int renglon,
36 int columna) {
37 // La palabra super representa a la clase padre.
38 // En este caso es DefaultTableModel. Aqu? se
39 // inserta el nuevo valor en el modelo.
40 super.setValueAt(valor, renglon, columna);
41
42 // Ahora invocaremos un evento dependiendo de la
43 // columna que se está modificando.
44 switch (columna) {
45 case 0:
46 cambiarNombre((String)valor, renglon);
47 break;
48 case 1:
49 cambiarGoles((Integer)valor, renglon);
50 break;
51 case 2:
52 cambiarActivo((Boolean)valor, renglon);
53 break;
54 case 3:
55 cambiarPosicion((String)valor, renglon);
56 break;
57 }
58 }
59 };
60

49
61 JTable tblJugadores = new JTable();
62 JScrollPane scroll = new JScrollPane(tblJugadores);
63 JButton btnNuevo = new JButton("Nuevo");
64 JButton btnBorrar = new JButton("Borrar");
65 JButton btnTotal = new JButton("Total");
66
67 public frmTablaCompleta() {
68 configuraComponentes();
69 agregaEventos();
70
71 add(scroll);
72 add(btnNuevo);
73 add(btnBorrar);
74 add(btnTotal);
75 }
76
77 void configuraComponentes() {
78 Object[] encabezados = {"Nombre", "Goles", "Activo", "Posici?n"};
79 modelo.setColumnIdentifiers(encabezados);
80 tblJugadores.setModel(modelo);
81 scroll.setPreferredSize(new Dimension(300, 100));
82
83 // Asigna un combo box para capturar la columna 3.
84 TableColumn posiciones = tblJugadores.getColumnModel().getColumn(3);
85 JComboBox comboBox = new JComboBox();
86 comboBox.addItem("Portero");
87 comboBox.addItem("Defensa");
88 comboBox.addItem("Medio");
89 comboBox.addItem("Delantero");
90 posiciones.setCellEditor(new DefaultCellEditor(comboBox));
91 }
92
93 void agregaEventos() {
94 btnNuevo.addActionListener(new ActionListener() {
95 public void actionPerformed(ActionEvent evt) {
96 clickEnNuevo();
97 }
98 });
99 btnBorrar.addActionListener(new ActionListener() {
100 public void actionPerformed(ActionEvent evt) {
101 clickEnBorrar();
102 }
103 });
104 btnTotal.addActionListener(new ActionListener() {
105 public void actionPerformed(ActionEvent evt) {
116 clickEnTotal();
107 }
108 });
109 }
110
111 public void clickEnNuevo() {
112 Object[] nuevo = {};
113 modelo.addRow(nuevo);
114 }
115

50
116 public void clickEnBorrar() {
117 int renglon = tblJugadores.getSelectedRow();
118 if (renglon != -1) {
119 String nombre = (String)modelo.getValueAt(renglon, 0);
120 Integer goles = (Integer)modelo.getValueAt(renglon, 1);
121 Boolean activo = (Boolean)modelo.getValueAt(renglon, 2);
122 String posicion = (String)modelo.getValueAt(renglon, 3);
123 borrar(nombre, goles, activo, posicion);
124 modelo.removeRow(renglon);
125 } else {
126 muestraMensaje("No has seleccionado renglon.");
127 }
128 }
129
130 public void clickEnTotal() {
131 //El numero de columnas se obtiene con getColumnCount()
132 int total = 0;
133 for (int renglon=0; renglon < modelo.getRowCount(); renglon++) {
134 int subtotal = (Integer)modelo.getValueAt(renglon,1);
135 total += subtotal;
136 }
137 muestraMensaje("Total de goles: " + total);
138 }
139
140 public void muestraMensaje(String mensaje) {
141 JOptionPane.showMessageDialog(null, mensaje);
142 }
143
144 public void cambiarNombre(String nombre, int renglon) {
145 muestraMensaje("Quieres cambiar el nombre del renglon " + renglon);
146 }
147
148 public void cambiarGoles(Integer goles, int renglon) {
149 muestraMensaje("Quieres cambiar los goles del renglon " + renglon);
150 }
151
152 public void cambiarActivo(Boolean activo, int renglon) {
153 muestraMensaje("Quieres cambiar activo del renglon " + renglon);
154 }
155
156 public void cambiarPosicion(String posicion, int renglon) {
157 muestraMensaje("Quieres cambiar la posicion del renglon " + renglon);
158 }
159
160 public void borrar(String nombre, Integer goles, Boolean activo,
161 String posicion) {
162 muestraMensaje("Quieres borrar a " + nombre);
163 }
164
165 public static void main(String[] args) {
166 JFrame frame = new JFrame("Tabla Completa");
167 frame.add(new JScrollPane(new frmTablaCompleta()));
168 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
169 frame.pack();
170 frame.setVisible(true);
171 }
172 }

51
6.
Java
en
Internet.

52
6. Java en Internet.
6.1. Un Applet Sencillo.
Una de las formas más sencillas de usar Java en Internet es por medio de applets. Son aplicaciones que
se pueden insertar en una página HTML. Para ello, necesitas que tu navegador tenga registrada como
plug­in   una   máquina   virtual  de   Java   compatible   con   la   versión   de   código   que   estás   usando.   Este
ejemplo muestra el mensaje “Hola”  en un renglón y “Adios”  inmediatamente abajo. Cada vez que
sucede un evento en el applet, se despliega en la consola de Java.

6.1.1. Código de “AppletDePrueba.html”.
1 <html>
2 <head>
3 <title>Applet de Prueba</title>
4 </head>
5 <body>
6 <h1>Applet de Prueba</h1>
7 <hr>
8 <applet code="AppletDePrueba.class"
9 width=100
10 height=120
11 alt="Tu navegador soporta applets pero no est&aacute; ejecutando."
12 >
13 <PARAM NAME = parametro1 VALUE = Hola>
14 <PARAM NAME = parametro2 VALUE = Adios>
15 Tu navegador no soporta applets.
16 </applet>
17 <hr>
18 </body>
19 </html>

6.1.2. Código de “AppletDePrueba.java”.
1 import javax.swing.*;
2 import java.awt.*;
3
4 public class AppletDePrueba extends JApplet {
5 private static final long serialVersionUID = 1L;
6
7 public AppletDePrueba() {
8 System.out.println("Constructor");
9 }
10
11 public void init() { // Se ejecuta al entrar a la página.
12 System.out.println("init");
13 }
14
15 public void start() { // Se ejecuta al entrar a la página.
16 System.out.println("start");
17 }
18
19 public void stop() { // Se ejecuta al salir de la página.
20 System.out.println("stop");
21 }
22

53
23 public void destroy() { // Se ejecuta al salir de la página.
24 System.out.println("destroy");
25 }
26
27 public void paint(Graphics g) { // Dibuja al componente gráfico.
28 // drawString permite desplegar un texto. Las coordenadas son
29 // x = 0 y y = 80.
30 // getParameter recupera los parámetros que se pasaron desde
31 // el código en HTML.
32 g.drawString(getParameter("parametro1"), 0, 80);
33 g.drawString(getParameter("parametro2"), 0, 100);
34 System.out.println("paint");
35 }
36
37 // Proporciona información sobre el applet.
38 public String getAppletInfo() {
39 return "Titulo: AppletDePrueba\n" +
40 "Un applet de prueba.";
41 }
42
43 // Regresa una descripción de los parámetros.
44 public String[][] getParameterInfo() {
45 String paramInfo[][] = {
46 {"parametro1", "texto1", "cualquier dato1"},
47 {"parametro2", "texto2", "cualquier dato2"}
48 };
49 return paramInfo;
50 }
51 }

6.2. Otro Applet.


Este Applet muestra “frmSencilla”  en tu navegador.

6.2.1. Código de “AppletSencil lo.html”.
1 <html>
2 <head>
3 <title>Applet Sencillo</title>
4 </head>
5 <body>
6 <h1>Applet Sencillo</h1>
7 <hr>
8 <applet code="AppletSencillo.class"
9 width=250
10 height=100
11 alt="Tu navegador soporta applets pero no lo est&aacute; ejecutando."
12 >
13 Tu navegador no soporta applets.
14 </applet>
15 <hr>
16 </body>
17 </html>

54
6.2.2. Código de “AppletSencil lo .java”.
1 import javax.swing.*;
2
3 public class AppletSencillo extends JApplet {
4 private static final long serialVersionUID = 1L;
5
6 public void init() {
7 add(new JScrollPane(new frmSencilla()));
8 }
9 }

6.3. Un JSP.
Actualmente se requiere que una buena parte de procesamiento sea realizada en el servidor web. Un
JSP  es un listado en HTML que contiene instrucciones de procesamiento en Java, enmarcadas por los
signos “<% ”  y “%> ”.  El servidor web procesa la página y regresa una página en HTML que contiene
las instrucciones originales de HTML, pero ha removido y ejecutado el código en Java. El siguiente
ejemplo despliega una tabla con el contenido de la tabla “alumno”.

6.3.1. Código de “AppletConsul ta.html”.
1 <%--
2 Este es un comentario.
3 --%>
4
5 <%-- Los imports van separados por comas y la lista de ellos va entre
6 comillas.
7 --%>
8
9 <%@ page import = "java.sql.*" %>
10
11 <HTML>
12 <HEAD><TITLE>Reporte de Alumnos</TITLE></HEAD>
13 <BODY>
14 <%! int n=0; %>
15 <% try {
16 Class.forName("com.mysql.jdbc.Driver");
17 Connection con = DriverManager.getConnection(
18 "jdbc:mysql://localhost/test", "otro", "akt");
19 PreparedStatement alumnos = con.prepareStatement(
20 "SELECT * FROM alumno");
21 ResultSet rs = alumnos.executeQuery();
22 %>
23 <TABLE BORDER = "1" WIDTH="3">
24 <THEAD><TR><TH>MATRICULA<TH>NOMBRE<TH>FECHA DE NACIMIENTO
25 <TBODY>
26 <% while (rs.next()) {
27 %>
28 <%-- esta expresion funciona como print --%>
29 <TR><TD> <%= rs.getString("matricula")%>
30 <TD> <%=rs.getString("nombre")%>
31 <TD> <%=rs.getString("fecha_de_nacimiento")%>
32 <%
33 }
34 %>
35 </TABLE>

55
36 <%
37 rs.close();
38 alumnos.close();
39 con.close();
40 } catch(Exception e) {
41 %>
42 <%= e.getMessage() %>
43 <% }
44 %>
45 </BODY>
46 </HTML>

56
7.
Un
Ejemplo
de
Aplicación.

57
7. Un Ejemplo de Aplicación.
¿Cómo se pueden integrar todos los temas que hemos estudiado para desarrollar una aplicación mas
compleja? A continuación te presentamos la base de una y algunas técnicas adicionales.

7.1. La Especificación.
Lo primero por hacer es determinar el objetivo de la aplicación. En nuestro caso, el objetivo es facturar.
A partir de ellos se hace una definición de requerimientos. Después se elabora el análisis, donde se
definen   los   casos   de   uso   y   se   define   el   funcionamiento   de   cada   uno   de   ellos.   A   continuación   te
presentamos   el   funcionamiento  base   que  deseamos  implementar.   Es  una  parte   de  la  funcionalidad
completa.

Al iniciar la aplicación aparece una pantalla de bienvenida.

Ilustración 17. Portada.

Posteriormente se presenta un cuadro de diálogo que controla el acceso.

Ilustración 18. Control de Acceso.

El usuario introduce su nombre de usuario, su password y la base de datos con la que trabajará. Cuando
oprime  conectar,    la  aplicación  se  conecta a la  base de datos, la  cual  verifica que la  información
proporcionada   sea   válida.   El   usuario   solo   puede   usar   las   ventanas   a   las   que   tiene   permiso.   Estos
permisos se asignan en base a un rol. Si el usuario tiene el  rol “ SUPERVISOR”,  tiene acceso al
siguiente menú.

58
Ilustración 19. Menú de Supervisor.

Si   se   elige   “Reporte   de   Productos”  aparece   una  ventana   interna   donde  se   muestran   los   productos
registrados.

Ilustración 20. Reporte de Productos.

Cuando se presiona el botón “Imprimir”,  la información se envía a la impresora.

59
Cuando se selecciona “Catálogo de Clientes”  se muestra la siguiente pantalla.

Ilustración 21. Catálogo de Clientes.

Este   tipo   de   pantallas   se   conoce   como   catálogo   y   permite   manipular   la   información   básica   de   la
aplicación. Esta pantalla solo permite insertar, pero en la práctica también se necesitan opciones para
modificar, borrar y localizar registros.

El comportamiento de esta ventana lo describiremos por estados. Un estado es cada una de las posibles
combinaciones válidas de valores que puede tener. El estado de entrada es el estado “ BASE” .

Para   el   estado  BASE  tenemos   las   siguientes   características.   Los   campos   de   texto   para   “ RFC”   y
“Nombre”  aparecen en blanco. Cada uno de los componentes gráficos están en los siguientes estados.
RFC – deshabilitado. Nombre – deshabilitado. Insertar – habilitado. 
Al   oprimirlo   para   al   estado
INESERTANDO.
Cerrar – habilitado. Guardar – deshabilitado. Cancelar – deshabilitado.
Cierra la ventana.

60
En el estado INSERTANDO tenemos lo siguiente:

RFC – habilitado. Nombre – habilitado. Insertar – deshabilitado. 


Cerrar – deshabilitado. Guardar – habilitado. Cancelar – deshabilitado.
Inserta   en   la   base   de   datos   un Regresa al estado BASE.
registro   con   la   información
mostrada   en   la   ventana.   Si   la
inserción   es   válida,   regresa   al
estado BASE.

Si el usuario tiene el rol “ VENDEDOR”, tendrá  el siguiente menú.

Ilustración 22. Menú del Vendedor.

Se   debe  introducir  el   número  de  folio  de  la  factura,   valor  que  normalmente  se  toma de  la   forma
continua a imprimir. Después se introduce el RFC o parte del mismo y se oprime el botón RFC. Se
recupera el nombre del cliente buscándolo en la base de datos. 

Para registrar productos, se oprime el botón “Nuevo ”  y se agrega un renglón en blanco. Se introduce el
código del producto. Este se busca en la base de datos y se recupera tanto la descripción como el
precio. Se añade el valor de cantidad. Para registrar la información en la base de datos se oprime el
botón guardar. Si se quiere imprimir la factura, se oprime el botón “Imprimir”.  A continuación se
presenta un ejemplo de factura impresa.

61
folio: 19 fecha: 30/04/2004

RFC: PH
Nombre: Usuario

8.00| Chocolate|$3.50
10.00| Dulce|$1.00
Total: 38.00

Ilustración 23. Ejemplo de Factura Impresa.

El botón “ Cerrar”  cierra la ventana.

En cualquiera de los dos roles hay dos menús que son iguales. El menú Archivo.

Ilustración 24. Menú Archivo.

Al seleccionas “Salir”  se cierra la aplicación.

62
El menú Ayuda es el siguiente.

Ilustración 25. Menú Ayuda.

Al seleccionar “Acerc a de...”  aparece el siguiente cuadro de diálogo modal.

Ilustración 26. Acerca De.

7.2. Diseño.
Cada una de las ventanas con acceso a la base de datos se diseñará en tres capas.

• Boundary. Interactúa con el usuario. Estas clases usan el prefijo frm.
• Control. Se encarga del control transaccional.
• Entity. Tablas de la base de datos.

63
7.2.1. Vista Lógica.

frmLogin frmMenu

1 control 1 1 factura 1 productos


clientes

ctrlLogin frmClientes frmFactura frmProductos

* 1 control 1 control 1 control

ctrlClientes ctrlFactura ctrlProductos


infoUsuario

* * *

1 * * *
infoCliente infoFactura infoProducto

Ilustración 27. Vista Lógica del Ejemplo.

7.2.2. Carta de Estados para “frmClient es”.
insertar
Base Insertando
guardar/insertar
entry/ base( ) entry/ insertando( )
cancelar

cerrar show

Cerrado

entry/ close( )

Ilustración 28. Carta de Estados para frmClientes.

Las operaciones “base(  )”  e “insertando ( )” realiz an todas las actividades marcadas en la especificación.


Los diagramas de estado son bastante buenos para diseñar el comportamiento de interfaces de usuario y
proporcionan una buena base para obtener programas claros y fáciles de mantener.

Faltan   los   diagramas   de   secuencia   para   las   interfaces,   pero   son   muy   similares   a   los   que   se   han
estudiado.

64
7.3. Implementación.

7.3.1. Código de “f actura.sql”.
1 CREATE TABLE usuario(
2 usu_nombre VARCHAR(13) PRIMARY KEY,
3 usu_rol ENUM('SUPERVISOR','VENDEDOR') NOT NULL)
4 TYPE = InnoDB;
5
6 CREATE TABLE cliente(
7 cli_rfc VARCHAR(13) PRIMARY KEY,
8 cli_nombre VARCHAR(30) NOT NULL)
9 TYPE = InnoDB;
10
11 CREATE TABLE producto(
12 pr_id INTEGER PRIMARY KEY AUTO_INCREMENT,
13 pr_descripcion VARCHAR(30) NOT NULL,
14 pr_cantidad DECIMAL(10,2) NOT NULL,
15 pr_precio DECIMAL(10,2) NOT NULL)
16 TYPE = InnoDB;
17
18 CREATE TABLE factura(
19 fac_folio INTEGER PRIMARY KEY,
20 fac_fecha DATE NOT NULL,
21 cli_rfc VARCHAR(13),
22 INDEX(cli_rfc),
23 FOREIGN KEY(cli_rfc) REFERENCES cliente(cli_rfc))
24 TYPE = InnoDB;
25
26 CREATE TABLE detalle(
27 pr_id INTEGER NOT NULL,
28 fac_folio INTEGER NOT NULL,
29 det_cantidad DECIMAL(10, 2) NOT NULL,
30 det_precio DECIMAL(10, 2) NOT NULL,
31 PRIMARY KEY(pr_id, fac_folio),
32 INDEX(pr_id),
33 FOREIGN KEY(pr_id) REFERENCES producto(pr_id),
34 INDEX(fac_folio),
35 FOREIGN KEY(fac_folio) REFERENCES factura(fac_folio))
36 TYPE = InnoDB;
37
38 INSERT INTO producto (pr_descripcion, pr_cantidad, pr_precio)
39 VALUES ('Chocolate', 100, 3.50);
40
41 INSERT INTO producto (pr_descripcion, pr_cantidad, pr_precio)
42 VALUES ('Dulce', 300, 1.0);

7.3.2. Código de “Grid BagPanel.java”.
1 /**
2 * Un panel que permite colocar componentes fácilmente.
3 */
4 import java.awt.*;
5 import javax.swing.*;
6
7 public class GridBagPanel extends JPanel {
8 private static final long serialVersionUID = 1L;
9
10 private GridBagLayout gridbag = new GridBagLayout();
11 private GridBagConstraints c = new GridBagConstraints();
12

65
13 public GridBagPanel() {
14 // De entrada los componentes se alínean a la izquierda.
15 c.anchor = GridBagConstraints.WEST;
16 setLayout(gridbag);
17 }
18
19 public void add(int y, int x, int alto, int ancho,
20 Component componente) {
21 c.gridy = y;
22 c.gridx = x;
23 c.gridheight = alto;
24 c.gridwidth = ancho;
25 gridbag.setConstraints(componente, c);
26 add(componente);
27 }
28
29 public void setFill(int pFill) {
30 c.fill = pFill;
31 }
32
33 public int getFill() {
34 return c.fill;
35 }
36
37 public void setIpadx(int pIpadx) {
38 c.ipadx = pIpadx;
39 }
40
41 public int getIpadx() {
42 return c.ipadx;
43 }
44
45 public void setIpady(int pIpady) {
46 c.ipadx = pIpady;
47 }
48
49 public int getIpady() {
50 return c.ipady;
51 }
52
53 public void setInsets(Insets pInsets) {
54 c.insets = pInsets;
55 }
56
57 public Insets getInsets() {
58 return c.insets;
59 }
60
61 public void setAnchor(int pAnchor) {
62 c.anchor = pAnchor;
63 }
64
65 public int getAnchor() {
66 return c.anchor;
67 }
68
69 public void setWeightx(double pWeightx) {
80 c.weightx = pWeightx;
81 }
82
83 public double getWeightx() {
84 return c.weightx;
85 }
86

66
87 public void setWeighty(double pWeighty) {
88 c.weighty = pWeighty;
89 }
90
91 public double getWeighty() {
92 return c.weighty;
93 }
94 }

7.3.3. Código de “f rmProductos.java”
1 import javax.swing.*;
2 import java.awt.event.*;
3 import java.awt.*;
4 import javax.swing.table.*;
5 import java.text.*;
6
7 /**
8 * Un JInternalFrame es una ventana que se abre de forma no modal dentro
9 * de una ventana de aplicación.
10 */
11 public class frmProductos extends JInternalFrame {
12 private static final long serialVersionUID = 1L;
13
14 /**
15 * Usamos un objeto de la clase GridBagPanel para colocar componentes.
16 */
17 private GridBagPanel grid = new GridBagPanel();
18
19 ctrlProductos control = new ctrlProductos();
20 JTable tblResultado = new JTable();
21 JScrollPane scroll = new JScrollPane(tblResultado);
22 JButton btnImprimir = new JButton("Imprimir");
23
24 public frmProductos() {
25 // La palabra "super" se refiere al constructor de la clase padre,
26 // que en este caso es JInternalFrame. Los valores "true" hacen
27 // referencia a 4 características: se le puede cambiar el tamaño,
28 // se puede cerrar, se puede maximizar y se puede minimizar. Si no
29 // quieres alguna de ellas, ponla en "false".
30 super("Reporte de Productos", true, true, true, true);
31 configuraComponentes();
32 agregaEventos();
33
34 // coloca "scroll" en la columna 0, renglón 0, ocupando 10
35 // renglones de alto y 4 columnas de ancho.
36 grid.add(0,0,10,4, scroll);
37
38 // coloca "btnImprimir" en la columna 10, renglón 0, ocupando 1
39 // renglón de alto y 1 columna de ancho.
40 grid.add(10,0,1,1, btnImprimir);
41
42 add(new JScrollPane(grid));
43 init();
44 pack();
45 }
46
47 void configuraComponentes() {
48 scroll.setPreferredSize(new Dimension(400, 100));
49 }
50

67
51 /**
52 * Esta rutina se invoca para reiniciar el estado de la ventana cada
53 * vez que se vuelve a abrir.
54 */
55 void init() {
56 try {
57 DefaultTableModel clientes = control.obtenDatos();
58 tblResultado.setModel(clientes);
59 } catch (Exception e) {
60 muestraMensaje(e.getMessage());
61 e.printStackTrace();
62 }
63 }
64
65 void agregaEventos() {
66 btnImprimir.addActionListener(new ActionListener() {
67 public void actionPerformed(ActionEvent evt) {
68 clickEnImprimir();
69 }
70 });
71 }
72
73 public void clickEnImprimir() {
74 try {
75 // Imprime el contenido de "tblResultado" sin hacer
76 // modificaciones en la apariencia de sus celdas. El segundo
77 // par?metro es el encabezado y el tercero es el pie de
78 // página. {0} se refiere al n?mero de página.
79 tblResultado.print(JTable.PrintMode.NORMAL,
80 new MessageFormat("Reporte_de_Productos"),
81 new MessageFormat("pagina - {0}"));
82 } catch (Exception e) {
83 muestraMensaje(e.getMessage());
84 }
85 }
86
87 public void muestraMensaje(String mensaje) {
88 JOptionPane.showMessageDialog(null, mensaje);
89 }
90 }

7.3.4. Código de “c trlProductos.java”
1 import java.sql.*;
2 import java.util.*;
3 import java.text.*;
4 import javax.swing.table.*;
5
6 class ctrlProductos {
7 private static final Object[] encabezados =
8 {"Clave", "Descripcion", "Cantidad", "Precio"};
9

68
10 public DefaultTableModel obtenDatos() throws Exception {
11 DefaultTableModel modelo = new DefaultTableModel() {
12 private static final long serialVersionUID = 1L;
13 public boolean isCellEditable(int renglon, int columna) {
14 return false;
15 }
16 public Class getColumnClass(int columna) {
17 switch (columna) {
18 case 0: return Integer.class;
19 case 1: return String.class;
20 case 2: return Double.class;
21 case 3: return Double.class;
22 default: return Object.class;
23 }
24 }
25 };
26 modelo.setColumnIdentifiers(encabezados);
27 Connection conexion = ctrlLogin.conecta();
28 PreparedStatement consulta = conexion.prepareStatement(
29 "SELECT * FROM producto");
30 ResultSet rs = consulta.executeQuery();
31 while (rs.next()) {
32 Integer id = new Integer(rs.getInt("pr_id"));
33 String descripcion = rs.getString("pr_descripcion");
34 Double cantidad = new Double(rs.getDouble("pr_cantidad"));
35 Double precio = new Double(rs.getDouble("pr_precio"));
36 Object[] datos = {id, descripcion, cantidad, precio};
37 modelo.addRow(datos);
38 }
39 consulta.close();
40 conexion.close();
41 return modelo;
42 }
43 }

7.3.5. Código de “f rmClientes.java”.
1 import javax.swing.*;
2 import java.text.*;
3 import javax.swing.table.*;
4 import javax.swing.border.*;// Para "EtchedBorder" y "LineBorder"
5 import java.awt.*; // Para "Color", "Font" e "Insets".
6 import java.awt.event.*; // Para "KeyEvent".
7 import java.util.*;
8
9 public class frmClientes extends JInternalFrame {
10 private static final long serialVersionUID = 1L;
11 private static DateFormat formato = DateFormat.getDateInstance();
12 private static java.sql.Date hoy =
13 new java.sql.Date(new java.util.Date().getTime());
14
15 /**
16 * Define constantes para cada uno de los estados que puede tomar esta
17 * ventana.
18 */
19 private enum Estado {BASE, INSERTANDO};
20
21 // Para un mejor control del contenido de la ventana, los componentes
22 // se agrupan en páneles.
23

69
24 /**
25 * El objeto gridInfo incluye a los componentes
26 * que manejan datos.
27 */
28 private GridBagPanel gridInfo = new GridBagPanel();
29 private JLabel lblRfc = new JLabel("RFC");
30 private JTextField txtRfc = new JTextField(13);
31 private JLabel lblNombre = new JLabel("Nombre");
32 private JTextField txtNombre = new JTextField(30);
33
34 /**
35 * Controla los botones que realizan operaciones.
36 */
37 private GridBagPanel gridLateral = new GridBagPanel();
38 private JButton btnGuardar = new JButton("Guardar");
39 private JButton btnCancelar = new JButton("Cancelar");
40
41 /**
42 * Controla los botones de mayor jerarquía.
43 */
44 private GridBagPanel gridInferior = new GridBagPanel();
45 private JButton btnInsertar = new JButton("Insertar",
46 new ImageIcon("cara.gif"));
47 private JButton btnCerrar = new JButton("Cerrar",
48 new ImageIcon("cara.gif"));
49
50 /**
51 * Agrupa a los demás páneles.
52 */
53 private GridBagPanel gridFondo = new GridBagPanel();
54 private JLabel lblHola = new JLabel("Hola",
55 new ImageIcon("cara.gif"),
56 JLabel.CENTER);
57
58 /**
59 * Es el estado de operación en el cual se encuentra la ventana.
60 */
61 private Estado estado;
62
63 private ctrlClientes control = new ctrlClientes();
64
65 public frmClientes() {
66 super("Catalogo de Clientes", true, true, true, true);
67 configuraComponentes();
68 agregaEventos();
69
70 gridInfo.add(0,0,1,1, lblRfc); gridInfo.add(0,1,1,2, txtRfc);
71 gridInfo.add(1,0,1,1, lblNombre);gridInfo.add(1,1,1,4, txtNombre);
72
73 gridLateral.add(0,0,1,1, btnGuardar);
74 gridLateral.add(1,0,1,1, btnCancelar);
75
76 gridInferior.add(0,0,1,1, btnInsertar);
77 gridInferior.add(0,1,1,1, btnCerrar);
78
79 gridFondo.add(0,0,1,1, gridInfo);
80 gridFondo.add(0,1,1,1, gridLateral);
81 gridFondo.add(1,0,1,1, gridInferior);
82 gridFondo.add(1,1,1,1, lblHola);
83
84 add(new JScrollPane(gridFondo));
85 setDefaultCloseOperation(JInternalFrame.DO_NOTHING_ON_CLOSE);
86 pack();
87 }
88

70
89 void configuraComponentes() {
90 // "Selecciona el font "Century Gothic" normal de 16 puntos para
91 // los componentes "lblRfc" y "txtRfc".
92 Font centuryGothic = new Font("Century Gothic", Font.PLAIN, 16);
93 lblRfc.setFont(centuryGothic);
94 txtRfc.setFont(centuryGothic);
95
96 // "Selecciona el font "Impact" normal de 16 puntos para
97 // los componentes "lblNombre" y "txtNombre".
98 Font impact = new Font("Impact", Font.PLAIN, 16);
99 lblNombre.setFont(impact);
100 txtNombre.setFont(impact);
101
102 // "Selecciona el font "SansSerif" en negrillas e itálica.
103 Font sansSerif = new Font("SansSerif", Font.BOLD|Font.ITALIC, 18);
104 btnGuardar.setFont(sansSerif);
105
106 // El botón "btnGuardar" se puede activar con la combinación de
107 // teclas "ALT+G". "KeyEvent.VK_G" representa a la tecla "G".
108 btnGuardar.setMnemonic(KeyEvent.VK_G);
109
110 btnCancelar.setFont(sansSerif);
111
112 // Pone como color de letra un color con 200 de intensidad de
113 // rojo, 145 de verde y 180 de azul. El valor mayor es 255.
114 btnCancelar.setForeground(new Color(200, 145, 180));
115
116 // Usa un blanco predefinido para el fondo.
117 btnCancelar.setBackground(Color.WHITE);
118
119 // Define el texto a mostrar cuando el cursor del mouse se coloca
120 // sobre el botón.
121 btnCancelar.setToolTipText("Cierra el Catalogo");
122
123 // El botón "btnCancelar" se puede activar con la combinación de
124 // teclas "ALT+C". "KeyEvent.VK_C" representa a la tecla "C".
125 btnCancelar.setMnemonic(KeyEvent.VK_C);
126
127 // El botón "btnInsertar" se puede activar con la combinación de
128 // teclas "ALT+I". "KeyEvent.VK_I" representa a la tecla "I".
129 btnInsertar.setMnemonic(KeyEvent.VK_I);
130
131 // El botón "btnCerrar" se puede activar con la combinación de
132 // teclas "ALT+R". "KeyEvent.VK_R" representa a la tecla "R".
133 btnCerrar.setMnemonic(KeyEvent.VK_R);
134
135
136 // Pone un borde donde el panel se muestra hundido.
137 gridLateral.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
138
139 // La separación entre los componentes del panel se pone de 4
140 // pixeles. Al hacer esto se puede ver el efecto del borde.
141 // Si no lo pones, los bordes no se ven.
142 gridLateral.setInsets(new Insets(4,4,4,4));
143
144 gridLateral.setBackground(Color.BLUE);
145
146 // Pone un borde dibujado con una línea en negro, y si el "look
147 // and feel" lo permite, las esquinas redondeadas.
148 gridInferior.setBorder(new LineBorder(Color.BLACK, 2, true));
149
150 gridInferior.setInsets(new Insets(3,3,3,3));
151
152 // Pone el estado inicial.
153 base();

71
154 }
155
156 public void init() {
157 // Estado inicial al abrir la ventana.
158 base();
159 }
160
161 public void base() {
162 estado = Estado.BASE;
163 txtRfc.setText("");
164 txtNombre.setText("");
165 txtRfc.setEnabled(false); // Deshabilita el componente.
166 txtNombre.setEnabled(false);
167 btnGuardar.setEnabled(false);
168 btnCancelar.setEnabled(false);
169 btnInsertar.setEnabled(true); // Habilita el componente.
170 btnCerrar.setEnabled(true);
171 btnInsertar.requestFocus(); // Posiciona el cursor del teclado.
172 }
173
174 public void insertando() {
175 estado = Estado.INSERTANDO;
176 txtRfc.setEnabled(true);
177 txtNombre.setEnabled(true);
178 btnGuardar.setEnabled(true);
179 btnCancelar.setEnabled(true);
180 btnInsertar.setEnabled(false);
181 btnCerrar.setEnabled(false);
182 txtRfc.requestFocus();
183 }
184
185 void agregaEventos() {
186 btnGuardar.addActionListener(new ActionListener() {
187 public void actionPerformed(ActionEvent evt) {
188 clickEnGuardar();
189 }
190 });
191 btnCancelar.addActionListener(new ActionListener() {
192 public void actionPerformed(ActionEvent evt) {
193 clickEnCancelar();
194 }
195 });
196 btnInsertar.addActionListener(new ActionListener() {
197 public void actionPerformed(ActionEvent evt) {
198 clickEnInsertar();
199 }
200 });
201 btnCerrar.addActionListener(new ActionListener() {
202 public void actionPerformed(ActionEvent evt) {
203 clickEnCerrar();
204 }
205 });
206 }
207

72
208 public void clickEnGuardar() {
209 if (estado == Estado.INSERTANDO) {
210 String rfc = txtRfc.getText();
211 String nombre = txtNombre.getText();
212 try {
213 control.inserta(rfc, nombre);
214 base();
215 } catch (Exception e) {
216 muestraMensaje(e.getMessage());
217 }
218 }
219 }
220
221 public void clickEnCancelar() {
222 // Cada botón puede realizar una función diferente dependiendo
223 // del estado en que se encuentre. Por ello utilizamos una
224 // condición.
225 if (estado == Estado.INSERTANDO) {
226 base();
227 }
228 }
229
230 public void clickEnInsertar() {
231 if (estado == Estado.BASE) {
232 insertando();
233 }
234 }
235
236 public void clickEnCerrar() {
237 if (estado == Estado.BASE) {
238 dispose();
239 }
240 }
241
242 public void muestraMensaje(String mensaje) {
243 JOptionPane.showMessageDialog(null, mensaje);
244 }
245 }

7.3.6. Código de “c trlClientes.java”.
1 import java.sql.*;
2 import java.text.*;
3
4 public class ctrlClientes {
5 public void inserta(String rfc, String nombre) throws Exception {
6 Connection conexion = ctrlLogin.conecta();
7 PreparedStatement ps = conexion.prepareStatement(
8 "INSERT INTO cliente VALUES(?, ?)");
9 ps.setString(1, rfc);
10 ps.setString(2, nombre);
11 ps.executeUpdate();
12 ps.close();
13 conexion.close();
14 }
15 }

73
7.3.7. Código de “f rmFactura.java”.
1 import javax.swing.*;
2 import java.text.*;
3 import javax.swing.table.*;
4 import java.awt.*;
5 import java.awt.event.*;
6 import java.util.*;
7
8 public class frmFactura extends JInternalFrame {
9 private static final long serialVersionUID = 1L;
10 private static DateFormat formato = DateFormat.getDateInstance();
11 private static java.sql.Date hoy =
12 new java.sql.Date(new java.util.Date().getTime());
13 private GridBagPanel grid = new GridBagPanel();
14 private JLabel lblFolio = new JLabel("No.de Folio");
15 private JTextField txtFolio = new JTextField(11);
16 private JLabel lblFecha = new JLabel("Fecha");
17 private JLabel lblRfc = new JLabel("RFC");
18 private JTextField txtRfc = new JTextField(13);
19 private JButton btnBusca = new JButton("Busca RFC");
20 private JLabel lblNombre = new JLabel("Nombre");
21 private JTextField txtNombre = new JTextField(30);
22 private DefaultTableModel detalle = new DefaultTableModel() {
23 private static final long serialVersionUID = 1L;
24 public Class getColumnClass(int columna) {
25 switch (columna) {
26 case 0: return Integer.class;
27 case 1: return String.class;
28 case 2: return Double.class;
29 case 3: return Double.class;
30 default: return Object.class;
31 }
32 }
33 public void setValueAt(Object valor, int renglon, int columna) {
34 super.setValueAt(valor, renglon, columna);
35 switch (columna) {
36 case 0:
37 cambiarCodigo((Integer)valor, renglon);
38 break;
39 }
40 }
41 };
42 private JTable tblDetalle = new JTable();
43 private JScrollPane scroll = new JScrollPane(tblDetalle);
44 private JButton btnNuevo = new JButton("Nuevo");
45 private JButton btnGuardar = new JButton("Guardar");
46 private JButton btnImprimir = new JButton("Imprimir");
47 private JButton btnCerrar = new JButton("Cerrar");
48
49 private ctrlFactura control = new ctrlFactura();
50

74
51 public frmFactura() {
52 super("Elaboracion de Factura", true, //resizable
53 true, //closable
54 true, //maximizable
55 true);//iconifiable
56 configuraComponentes();
57 agregaEventos();
58 grid.add(0,0,1,1, lblFolio); grid.add(0,1,1,2, txtFolio);
59 grid.add(0,3,1,1, lblFecha);
60 grid.add(1,0,1,1, lblRfc); grid.add(1,1,1,2, txtRfc);
61 grid.add(1,3,1,1, btnBusca);
62 grid.add(2,0,1,1, lblNombre);grid.add(2,1,1,4, txtNombre);
63 grid.add(3,0,10,5, scroll);
64 grid.add(13,0,1,1, btnNuevo);grid.add(13,1,1,1, btnGuardar);
65 grid.add(13,2,1,1, btnImprimir);grid.add(13,3,1,1, btnCerrar);
66 add(new JScrollPane(grid));
67 setFrameIcon(new ImageIcon("icono.jpg"));
68 pack();
69 }
70
71 void configuraComponentes() {
72 txtFolio.setHorizontalAlignment(JTextField.RIGHT);
73 lblFecha.setHorizontalAlignment(JTextField.RIGHT);
74 lblFecha.setText("fecha : " + formato.format(hoy));
75 Object[] encabezados = {"Codigo","Descripcion","Cantidad","Precio"};
76 detalle.setColumnIdentifiers(encabezados);
77 tblDetalle.setModel(detalle);
78 scroll.setPreferredSize(new Dimension(400, 100));
79 }
80
81 public void init() {
82 txtFolio.setText("");
83 txtRfc.setText("");
84 txtNombre.setText("");
85 while (detalle.getRowCount() > 0) {
86 detalle.removeRow(0);
87 }
88 }
89
90 void agregaEventos() {
91 btnBusca.addActionListener(new ActionListener() {
92 public void actionPerformed(ActionEvent evt) {
93 clickEnBusca();
94 }
95 });
96 btnNuevo.addActionListener(new ActionListener() {
97 public void actionPerformed(ActionEvent evt) {
98 clickEnNuevo();
99 }
100 });
101 btnGuardar.addActionListener(new ActionListener() {
102 public void actionPerformed(ActionEvent evt) {
103 clickEnGuardar();
104 }
105 });
106 btnImprimir.addActionListener(new ActionListener() {
107 public void actionPerformed(ActionEvent evt) {
108 clickEnImprimir();
109 }
110 });
111 btnCerrar.addActionListener(new ActionListener() {
112 public void actionPerformed(ActionEvent evt) {
113 clickEnCerrar();
114 }
115 });

75
116 }
117
118 public void clickEnNuevo() {
119 Object[] nuevo = {};
120 detalle.addRow(nuevo);
121 }
122
123 public void clickEnBusca() {
124 try {
125 String rfc = txtRfc.getText();
126 LinkedHashMap<String, Object> respuesta =
127 control.buscaCliente(rfc);
128 muestraCliente(respuesta);
129 } catch (Exception e) {
130 muestraMensaje(e.getMessage());
131 e.printStackTrace();
132 }
133 }
134
135 public void clickEnGuardar() {
136 int folio = 0;
137 boolean datosOk = true;
138 try {
139 folio = Integer.parseInt(txtFolio.getText());
140 } catch (Exception e) {
141 muestraMensaje("El folio debe ser numerico.");
142 datosOk = false;
143 }
144 String rfc = txtRfc.getText();
145 if (datosOk) {
146 try {
147 control.guarda(folio, hoy, rfc, detalle);
148 } catch (Exception e) {
149 muestraMensaje(e.getMessage());
150 }
151 }
152 }
153
154 public void clickEnImprimir() {
155 int folio = 0;
156 boolean datosOk = true;
157 try {
158 folio = Integer.parseInt(txtFolio.getText());
159 } catch (Exception e) {
160 muestraMensaje("El folio debe ser numerico.");
161 datosOk = false;
162 }
163 String rfc = txtRfc.getText();
164 String nombre = txtNombre.getText();
165 if (datosOk) {
166 try {
167 control.imprime(folio, hoy, rfc, nombre, detalle);
168 } catch (Exception e) {
169 muestraMensaje(e.getMessage());
170 }
171 }
172 }
173
174 public void clickEnCerrar() {
175 dispose();
176 }
177

76
178 public void clickEnCerrar() {
179 dispose();
180 }
181
182 public void cambiarCodigo(Integer codigo, int renglon) {
183 try {
184 LinkedHashMap<String, Object> respuesta =
185 control.buscaProducto(codigo.intValue());
186 muestraProducto(respuesta, renglon);
187 } catch (Exception e) {
188 muestraMensaje(e.getMessage());
189 }
190
191 }
192
193 public void muestraCliente(LinkedHashMap<String,Object> respuesta) {
194 txtRfc.setText(respuesta.get("rfc").toString());
195 txtNombre.setText(respuesta.get("nombre").toString());
196 }
197
198 void muestraProducto(LinkedHashMap<String,Object>respuesta,int renglon) {
199 detalle.setValueAt(respuesta.get("descripcion"), renglon, 1);
200 detalle.setValueAt(respuesta.get("precio"), renglon, 3);
201 }
202
203 public void muestraMensaje(String mensaje) {
204 JOptionPane.showMessageDialog(null, mensaje);
205 }
206 }

7.3.8. Código de “c trlFactura.java”
1 import java.sql.*;
2 import java.util.*;
3 import javax.swing.table.*;
4 import java.io.*;
5 import javax.print.*;
6 import javax.print.attribute.*;
7 import javax.print.attribute.standard.*;
8 import java.awt.print.*;
9
10 public class ctrlFactura {

77
11 public LinkedHashMap<String,Object> buscaCliente(String rfc)
12 throws Exception {
13 LinkedHashMap<String, Object> respuesta =
14 new LinkedHashMap<String, Object>();
15 Connection conexion = ctrlLogin.conecta();
16 PreparedStatement busca = conexion.prepareStatement(
17 "SELECT * FROM cliente WHERE cli_rfc LIKE ?");
18 busca.setString(1, '%' + rfc + '%');
19 ResultSet rs = busca.executeQuery();
20 if (rs.next()) { //Solo queremos un elemento
21 rfc = rs.getString("cli_rfc");
22 String nombre = rs.getString("cli_nombre");
23 respuesta.put("nombre", nombre);
24 respuesta.put("rfc", rfc);
25 } else {
26 rs.close();
27 busca.close();
28 conexion.close();
29 throw new Exception("Cliente no encontrado.");
30 }
31 rs.close();
32 busca.close();
33 conexion.close();
34 return respuesta;
35 }
36
37 public LinkedHashMap<String,Object> buscaProducto(int id)
38 throws Exception {
39 LinkedHashMap<String, Object> respuesta =
40 new LinkedHashMap<String, Object>();
41 Connection conexion = ctrlLogin.conecta();
42 PreparedStatement busca = conexion.prepareStatement(
43 "SELECT * FROM producto WHERE pr_id = ?");
44 busca.setInt(1, id);
45 ResultSet rs = busca.executeQuery();
46 if (rs.next()) { //Solo queremos un elemento
47 String descripcion = rs.getString("pr_descripcion");
48 double precio = rs.getDouble("pr_precio");
49 respuesta.put("descripcion", descripcion);
50 respuesta.put("precio", new Double(precio));
51 } else {
52 rs.close();
53 busca.close();
54 conexion.close();
55 throw new Exception("Producto no encontrado.");
56 }
57 rs.close();
58 busca.close();
59 conexion.close();
60 return respuesta;
61 }
62

78
63 public void guarda(int folio, java.sql.Date hoy, String rfc,
64 DefaultTableModel detalle) throws Exception {
65 Connection conexion = ctrlLogin.conecta();
66 conexion.setAutoCommit(false);
67 PreparedStatement ps;
68 ps = conexion.prepareStatement(
69 "INSERT INTO factura(fac_folio,fac_fecha,cli_rfc)" +
70 "VALUES(?,?,?)");
71 ps.setInt(1, folio);
72 ps.setDate(2, hoy);
73 ps.setString(3, rfc);
74 ps.executeUpdate();
75 ps.close();
76 ps = conexion.prepareStatement(
77 "INSERT INTO detalle "
78 + "(pr_id,fac_folio,det_cantidad,det_precio)"
79 + "VALUES(?, ?, ?, ?)");
80 for (int renglon = 0; renglon < detalle.getRowCount(); renglon++) {
81 Integer codigo = (Integer)detalle.getValueAt(renglon, 0);
82 Double cantidad = (Double)detalle.getValueAt(renglon, 2);
83 Double precio = (Double)detalle.getValueAt(renglon, 3);
84 ps.setInt(1, codigo.intValue());
85 ps.setInt(2, folio);
86 ps.setDouble(3, cantidad);
87 ps.setDouble(4, precio);
88 ps.executeUpdate();
89 }
90 ps.close();
91 conexion.commit();
92 conexion.close();
93 }
94
95 }
96

79
97 public void imprime(int folio, java.sql.Date hoy, String rfc,
98 String nombre, DefaultTableModel detalle)
99 throws Exception {
100 // Abre el archivo "salida.txt" para impresión.
101 PrintWriter salida = new PrintWriter(
102 new BufferedWriter(
103 new FileWriter("salida.txt")));
104
105 // Esto funciona como el printf del lenguaje C.
106 // "%d" representa a "folio". La "d" significa entero.
107 // "%2$te" es el día del segundo parámetro("hoy").
108 // "%2$tm" es el mes del segundo parámetro("hoy").
109 // "%2$tY" es el año en cuatro dígitos de "hoy".
110 imprime(salida, "folio: %d fecha: %2$te/%2$tm/%2$tY",
111 folio, hoy);
112
113 imprime(salida, "");
114 imprime(salida, "");
115
116 // "%s" significa que se evalua la operacion toString() del
117 // objeto.
118 imprime(salida, "RFC: %s", rfc);
119
120 imprime(salida, "Nombre: %s", nombre);
121 imprime(salida, "");
122 double total = 0;
123 for (int renglon = 0; renglon < detalle.getRowCount(); renglon++) {
124 String descripcion = (String)detalle.getValueAt(renglon, 1);
125 Double cantidad = (Double)detalle.getValueAt(renglon, 2);
126 Double precio = (Double)detalle.getValueAt(renglon, 3);
127 // "%10.2f" despliega un flotante con 10 cifras y 2 decimales y
128 // justificación a la derecha.
129 // "%30s" despliega un texto en 30 espacios y justificación a
130 // la derecha.
131 // "%.2f" despliega un flotante con 2 decimales.
132 imprime(salida, "%10.2f|%30s|$%.2f", cantidad, descripcion,
133 precio);
134
135 total += cantidad * precio;
136 }
137 imprime(salida, "Total: %.2f", total);
138 salida.close();
139
140 // Realiza la impresión del archivo "salida.txt".
141 PrintRequestAttributeSet aset =
142 new HashPrintRequestAttributeSet();
143 PrinterJob pj = PrinterJob.getPrinterJob();
144 if(pj.printDialog(aset)) {
145 FileInputStream textStream = new FileInputStream("salida.txt");
146 DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;
147 Doc myDoc = new SimpleDoc(textStream, flavor, null);
148 DocPrintJob job = pj.getPrintService().createPrintJob();
149 job.print(myDoc, aset);
150 }
151 }
152
153 public void imprime(PrintWriter salida, String texto, Object ... datos) {
154 salida.println(String.format(texto, datos));
155 }
156 }

80
7.3.9. Código de “f rmLogin.java”.
1 /**
2 * Una clase para controlar el acceso a bases de datos
3 */
4 import javax.swing.*;
5 import java.awt.*;
6 import java.awt.event.*;
7 import java.util.*;
8
9 /**
10 * Clase de acceso a la aplicación. JDialog representa cuadros de diálogo.
11 */
12 public class frmLogin extends JDialog {
13 private static final long serialVersionUID = 1L;
14
15 /**
16 * Esta tabla de búsqueda se usar? para almacenar parejas del tipo
17 * <<nombre - URL>>. El nombre de un URL puede ser difícil de
18 * recordar. Mejor lo asociamos con un nombre corto, más representativo
19 * y por lo mismo más fácil de recordar.
20 */
21 private static LinkedHashMap<String, String> basesDeDatos =
22 new LinkedHashMap<String, String>();
23
24 private GridBagPanel panel = new GridBagPanel();
25 private JLabel lblUsuario = new JLabel("Usuario: ");
26 private JTextField txtUsuario = new JTextField(10);
27 private JLabel lblPassword = new JLabel("Password: ");
28 private JPasswordField txtPassword = new JPasswordField(10);
29 private JLabel lblBaseDeDatos =
30 new JLabel("Base de datos: ");
31 private JComboBox cmbBaseDeDatos = new JComboBox();
32 private JButton btnConectar = new JButton("Conectar");
33 private JButton btnCancelar = new JButton("Cancelar");
34
35 private ctrlLogin control = new ctrlLogin();
36
37 public frmLogin() {
38 // Aquí se invoca el constructor de la clase padre. En este caso
39 // JDialog. El parámetro null indica el frame a bloquear. El
40 // segundo es el texto de la barra de título y finalmente se
41 // usa "true" para indicar que es "modal" y "false" para indicar
42 // que es "no modal".
43 super((JFrame)null, "Login", true);
44 configuraComponentes();
45 agregaEventos();
46 panel.add(0,0,1,1, lblUsuario);
47 panel.add(0,1,1,1, txtUsuario);
48 panel.add(1,0,1,1, lblPassword);
49 panel.add(1,1,1,1, txtPassword);
50 panel.add(2,0,1,1, lblBaseDeDatos);
51 panel.add(2,1,1,1, cmbBaseDeDatos);
52 panel.add(3,0,1,1, btnConectar);
53 panel.add(3,1,1,1, btnCancelar);
54
55 // No hace nada al oprimir el botón para cerrar en la barra de
56 // título
57 setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
58
59 add(new JScrollPane(panel));
60 pack();
61 }
62

81
63 public static void registra(String nombre, String url) {
64 basesDeDatos.put(nombre, url);
65 }
66
67 void configuraComponentes() {
68 cmbBaseDeDatos.removeAllItems();
69 for (String s: basesDeDatos.keySet()) {
70 cmbBaseDeDatos.addItem(s);
71 }
72 }
73
74 void agregaEventos() {
75 btnCancelar.addActionListener(new ActionListener() {
76 public void actionPerformed(ActionEvent evt) {
77 clickEnCancelar();
78 }
79 });
80 btnConectar.addActionListener(new ActionListener() {
81 public void actionPerformed(ActionEvent evt) {
82 clickEnConectar();
83 }
84 });
85 }
86
87 public void clickEnCancelar() {
88 System.exit(0);
89 }
90
91 public void clickEnConectar() {
92 String bd = cmbBaseDeDatos.getSelectedItem().toString();
93 String url = basesDeDatos.get(bd);
94 String usuario = txtUsuario.getText();
95 String password = new String(txtPassword.getPassword());
96 try {
97 String rol = control.obtenRol(url, usuario, password);
98 dispose(); // Cierra el cuadro de di?logo.
99 frmMenu menu = new frmMenu(rol);
100 } catch (Exception e) {
101 muestraMensaje(e.getMessage());
102 }
103 }
104
105 public void muestraMensaje(String mensaje) {
106 JOptionPane.showMessageDialog(null, mensaje);
107 }
108

82
109 /**
110 * Muestra una imagen de presentación durante el tiempo especificado.
111 * @param nombre Nombre de la imagen a presentar.
112 * @param tiempo Tiempo en milisegundos que se mostrar? la imagen.
113 */
114 public static void showSplash(String nombre, int tiempo) {
115 JFrame d = new JFrame();
116 d.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
117
118 // El frame no lleva barra de t?tulo ni m?rgenes.
119 d.setUndecorated(true);
120 d.add(new JLabel(new ImageIcon(nombre)));
121 d.pack();
122
123 // Obtiene la resoluci?n del monitor.
124 Dimension max = Toolkit.getDefaultToolkit().getScreenSize();
125
126 Dimension t = d.getSize();
127 d.setLocation((max.width / 2) - (t.width / 2),
128 (max.height / 2) - (t.height / 2));
129 d.setVisible(true);
130 try {
131 // Suspende la ejecuci?n de la aplicaci?n durante el tiempo
132 // indicado.
133 Thread.sleep(tiempo);
134 } catch(InterruptedException e) {}
135 d.dispose();
136 }
137
138 public static void main(String[] args) {
139 // Si quitas los comentarios a las lineas 102 - 105 la apariencia
140 // de la aplicación cambiar? y se ver? como si fuera nativa de tu
141 // sistema operativo. VALE LA PENA QUE HAGAS LA PRUEBA.
142 // try {
143 // UIManager.setLookAndFeel(
144 // UIManager.getSystemLookAndFeelClassName());
145 // } catch (Exception e) {}
146
147 showSplash("portada.jpg", 5000);
148 try {
149 // Esta aplicaci?n funciona con MySQL o con Oracle.
150 Class.forName("com.mysql.jdbc.Driver");
151 Class.forName("oracle.jdbc.OracleDriver");
152
153 // Registra los diferentes URL a los que puede comunicarse tu
154 // aplicación. Esto evita que tengas que modificarla y
155 // recompilarla para cambiar la base de datos. El primer
156 // par?metro es un nombre corto que se despliega en el cuadro
157 // de login en vez del URL para que no tengas que aprendértelo.
158 frmLogin.registra("MySQL", "jdbc:mysql://localhost/test");
159 frmLogin.registra("MySQL Remoto",
160 "jdbc:mysql://192.168.7.251/test");
161 frmLogin.registra("Oracle",
162 "jdbc:mysql://192.168.7.251/test");
163 frmLogin login = new frmLogin();
164
165 // Los cuadros de di?logo se abren con setVisible(true):
166 login.setVisible(true);
167 } catch (Exception e) {
168 e.printStackTrace();
169 }
170 }
171 }

83
7.3.10. Código de “c trlLogin.java”.
1 import java.sql.*;
2 import java.util.*;
3
4 public class ctrlLogin {
5 private static String url;
6 private static String usuario;
7 private static String password;
8
9 public String obtenRol(String pUrl, String pUsuario, String pPassword)
10 throws Exception {
11 guarda(pUrl, pUsuario, pPassword);
12 Connection conexion = conecta();
13
14 PreparedStatement ps = conexion.prepareStatement(
15 "SELECT usu_rol FROM usuario WHERE usu_nombre = ?");
16 ps.setString(1, usuario);
17 ResultSet rs = ps.executeQuery();
18 String rol = null;
19 if (rs.next()) {
20 rol = rs.getString("usu_rol");
21 }
22 rs.close();
23 validaRol(conexion, rol);
24 conexion.close();
25 return rol;
26 }
27
28 public void guarda(String pUrl, String pUsuario, String pPassword) {
29 url = pUrl;
30 usuario = pUsuario;
31 password = pPassword;
32 }
33
34 public static Connection conecta() throws SQLException {
35 Connection conexion =
36 DriverManager.getConnection(url, usuario, password);
37 conexion.setTransactionIsolation(
38 Connection.TRANSACTION_SERIALIZABLE);
39 return conexion;
40 }
41
42 void validaRol(Connection conexion, String rol) throws Exception {
43 if (rol == null) {
44 conexion.close();
45 throw new Exception("Usuario Incorrecto.");
46 }
47 }
48 }

84
7.3.11. Código de “f rmMenu.java”.
1 import javax.swing.*;
2 import java.awt.*;
3 import java.awt.event.*;
4
5 public class frmMenu extends JFrame {
6 private static final long serialVersionUID = 1L;
7 private JMenuBar menuBar = new JMenuBar();
8 private JDesktopPane desktop = new JDesktopPane();
9
10 private frmFactura factura = new frmFactura();
11 private frmClientes clientes = new frmClientes();
12 private frmProductos reporte = new frmProductos();
13 public frmMenu(String rol) {
14 super("Facturaci?n");
15 configuraFrame();
16 desktop.add(factura);
17 desktop.add(clientes);
18 desktop.add(reporte);
19
20 // Dependiendo del Rol cambia la barra de men?.
21 if (rol.equals("VENDEDOR")) {
22 menuDeVendedor();
23 } else if (rol.equals("SUPERVISOR")) {
24 menuDeSupervisor();
25 }
26 setVisible(true);
27 }
28
29 public void menuDeVendedor() {
30 menuArchivo();
31 menuFacturacion();
32
33 menuBar.add(Box.createHorizontalGlue());
34
35 menuAyuda();
36 }
37
38 public void menuDeSupervisor() {
39 menuArchivo();
40 menuSupervisor();
41 menuBar.add(Box.createHorizontalGlue());
42 menuAyuda();
43 }
44
45 public void menuArchivo() {
46 JMenu archivo = addMenu("Archivo", "icono.jpg", KeyEvent.VK_A);
47 JMenuItem salir = addItem(archivo, "Salir", "icono.jpg",
48 KeyEvent.VK_S, KeyEvent.VK_S);
49 salir.addActionListener(new ActionListener() {
50 public void actionPerformed(ActionEvent event) {
51 clickEnSalir();
52 }
53 });
54 }
55
56 public void clickEnSalir() {
57 System.exit(0);
58 }
59

85
60 public void menuSupervisor() {
61 JMenu supervisor = addMenu("Supervisor","icono.jpg",KeyEvent.VK_S);
62 JMenuItem catalogoDeClientes = addItem(supervisor,
63 "Catalogo de Clientes...",
64 "icono.jpg",
65 KeyEvent.VK_C, KeyEvent.VK_C);
66 JMenuItem reporteDeProductos = addItem(supervisor,
67 "Reporte de Productos...",
68 "icono.jpg",
69 KeyEvent.VK_R, KeyEvent.VK_R);
70 catalogoDeClientes.addActionListener(new ActionListener() {
71 public void actionPerformed(ActionEvent event) {
72 clickEnCatalogoDeClientes();
73 }
74 });
75 reporteDeProductos.addActionListener(new ActionListener() {
76 public void actionPerformed(ActionEvent event) {
77 clickEnReporteDeProductos();
78 }
79 });
80 }
81
82 public void clickEnCatalogoDeClientes() {
83 if (clientes.isClosed()) {
84 clientes.init();
85 }
86 showFrame(clientes);
87 }
88
89 public void clickEnReporteDeProductos() {
90 if (reporte.isClosed()) {
91 reporte.init();
92 }
93 showFrame(reporte);
94 }
95
96 public void menuFacturacion() {
97 JMenu facturacion = addMenu("Facturacion","icono.jpg",KeyEvent.VK_F);
98 JMenuItem facturar = addItem(facturacion, "Facturar...",
99 "icono.jpg", KeyEvent.VK_F, KeyEvent.VK_F);
100 facturar.addActionListener(new ActionListener() {
101 public void actionPerformed(ActionEvent event) {
102 clickEnFacturar();
103 }
104 });
105 }
106
107 public void clickEnFacturar() {
108 if (factura.isClosed()) {
109 factura.init();
110 }
111 showFrame(factura);
112 }
113
114 public void menuAyuda() {
115 JMenu ayuda = addMenu("Ayuda", "icono.jpg", KeyEvent.VK_Y);
116 JMenuItem acercaDe = addItem(ayuda,"Acerca De...", "icono.jpg",
117 KeyEvent.VK_A, KeyEvent.VK_A);
118 acercaDe.addActionListener(new ActionListener() {
119 public void actionPerformed(ActionEvent evt) {
120 clickEnAcercaDe();
121 }
122 });
123 }
124

86
125 public void clickEnAcercaDe() {
126 JOptionPane.showMessageDialog(null,
127 "<html>Ejemplo de Menu<br>por: <i>Yo</i></html>");
128 }
129
130 public JMenu addMenu(String nombre, String icono, int nemonico) {
131 JMenu menu = new JMenu(nombre);
132 menu.setIcon(new ImageIcon(icono));
133 menu.setMnemonic(nemonico);
134 menuBar.add(menu);
135 return menu;
136 }
137
138 public static JMenuItem addItem(JMenu menu, String texto,
139 String icono, int nemonico,
140 int acelerador) {
141 JMenuItem item = new JMenuItem(texto, new ImageIcon(icono));
142 menu.add(item);
143 item.setMnemonic(nemonico);
144 item.setAccelerator(KeyStroke.getKeyStroke(
145 acelerador, ActionEvent.CTRL_MASK));
146 return item;
147 }
148
149 public static JMenu addSubMenu(JMenu menu, String texto,
150 String icono, int nemonico) {
151 JMenu submenu = new JMenu(texto);
152 menu.add(submenu);
153 submenu.setIcon(new ImageIcon(icono));
154 submenu.setMnemonic(nemonico);
155 return submenu;
156 }
157
158 public void showFrame(JInternalFrame frame) {
159 try {
160 if (frame.isClosed()) {
161 frame.setLocation(0, 0);
162 desktop.add(frame);
163 frame.show();
164 } else if (frame.isVisible()) {
165 frame.setSelected(true);
166 } else {
167 frame.show();
168 }
169 } catch (java.beans.PropertyVetoException e) {}
170 }
171
172 public void configuraFrame() {
173 setContentPane(desktop);
174 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
175 setJMenuBar(menuBar);
176 desktop.setPreferredSize(new Dimension(600, 300));
177 desktop.setBackground(Color.WHITE);
178 setIcono("icono.jpg");
179 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
180 pack();
181 agregaImagenDeFondo("portada.jpg");
182 }
183
184 void setIcono(String nombre) {
185 Image icono = Toolkit.getDefaultToolkit().getImage("icono.jpg");
186 setIconImage(icono);
187 }
188

87
189 void agregaImagenDeFondo(String nombre) {
190 ImageIcon imagen = new ImageIcon(nombre);
191 JLabel label = new JLabel(imagen);
192 // setExtendedState(JFrame.MAXIMIZED_BOTH);
193 // Dimension max = Toolkit.getDefaultToolkit().getScreenSize();
194 Dimension max = desktop.getSize();
195 int iheight = imagen.getIconHeight();
196 int iwidth = imagen.getIconWidth();
197 label.setBounds((max.width / 2) - (iwidth / 2),
198 (max.height / 2) - (iheight / 2),
199 iwidth, iheight);
200 desktop.add(label, new Integer(-1));
201 }
202 }

7.4. Generación del Ejecutable.

7.4.1. Código de “m anifest.txt”.
1 Main-Class: frmLogin
2 Class-Path: (3)mysql-connector-java-3.0.11-stable-bin.jar (4)ojdbc14.jar
3

Este código se utiliza para crear el ejecutable de java. Si tienes el directorio de ejecutables de Java en tu
ruta de ejecutables, solo necesitas cambiarte al directorio de tu proyecto y ejecutar la instrucción

jar cvfm proyecto.jar manifest.txt *.class

donde “proyecto.ja r”  es el nombre que le pondrás a tu ejecutable, manteniendo la extensión “.jar”.  Para


ejecutar el programa debes ejecutar la siguiente instrucción desde la línea de comando

java -jar proyecto.jar

o bien dar doble click al archivo desde el ambiente gráfico.

Tu ambiente de desarrollo puede incorporar algunas facilidades para generar el archivo ejecutable.

88

Das könnte Ihnen auch gefallen