Tutorial Java

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.

Transcript of Tutorial Java

Page 1: Tutorial Java

Universidad Tecnológica de Nezahualcóyotl

Sistemas de

Información en

Java

Por:M. en C. Gilberto Pacheco Gallegos.

Academia de ProgramaciónAcademia de Ingeniería de Software.

Page 2: Tutorial Java
Page 3: Tutorial Java

Índice de Contenido1. Introducción a Java................................................................................................................................2

1.1. Objetos y Clases.............................................................................................................................21.2. Tipos de Datos Primitivos..............................................................................................................21.3. Comentarios....................................................................................................................................21.4. Estructuras de Control....................................................................................................................31.5. Terminación de Ciclos y Funciones...............................................................................................41.6. Precedencia de Operadores............................................................................................................51.7. Un Programa en Java......................................................................................................................6

1.7.1. Diagrama de Clases de UML..................................................................................................61.7.2. Código de “ Ejemplo.java” ......................................................................................................61.7.3. Salida en Pantalla....................................................................................................................71.6.4. Comentarios............................................................................................................................7

2. Acceso a Bases de Datos......................................................................................................................102.1. Tablas...........................................................................................................................................102.2. Llaves...........................................................................................................................................112.3. Manipulación de una Tabla..........................................................................................................11

2.3.1. Vista Lógica..........................................................................................................................112.3.2. Vista de Datos.......................................................................................................................112.3.3. Creación de la tabla (“ alumno.sql” )......................................................................................122.3.4. Inserción de datos en la tabla (“ insert_alumno.sql”) ............................................................122.3.5. Modificación de datos en la tabla (“update_alumno.sql”). ...................................................122.3.6. Consulta de datos en la tabla (“select_alumno.sql”). ...........................................................122.3.7. Resultado de la Consulta......................................................................................................122.3.8. Eliminación de datos en la tabla...........................................................................................122.3.9. Código de “ ctrlAccesoAlumno.java”. ..................................................................................122.3.10. Salida en Pantalla................................................................................................................172.3.11. Comentarios........................................................................................................................17

2.4. Restricciones................................................................................................................................182.4.1. Vista Lógica..........................................................................................................................182.4.2. Vista de Datos.......................................................................................................................192.4.3. Datos en las Tablas...............................................................................................................192.4.4. Creación de la Tabla Material (“material.sql”). ....................................................................192.4.5. Ejemplo de Inserción de Datos (“insert_material.sql ”). .......................................................192.4.6. Una Consulta de Dos Tablas (“select_ alumno_y_material.sql”). ........................................202.4.7. Resultado de la Consulta......................................................................................................202.4.8. Código de “ ctrlAccesoMaterial.java”. ..................................................................................202.4.9. Salida en Pantalla..................................................................................................................232.4.8. Comentarios..........................................................................................................................23

2.5. Manejo de cadenas.......................................................................................................................242.5.1. Ejemplo de Manejo de Texto (“Caden as.java” )...................................................................242.5.2. Salida en Pantalla..................................................................................................................252.5.3. Comentarios..........................................................................................................................25

3. Interfaces Gráficas...............................................................................................................................27

i

Page 4: Tutorial Java

3.1. Un Ejemplo Simple......................................................................................................................273.1.1. Especificación.......................................................................................................................273.1.2. Vista Lógica..........................................................................................................................273.1.3.  Código de “ frmSencilla.java”. .............................................................................................283.1.4. Comentarios..........................................................................................................................29

3.2. Acceso a Bases de Datos Desde Interfaces Gráficas....................................................................303.2.1. Especificación.......................................................................................................................303.2.2. Vista Lógica..........................................................................................................................303.2.3. Código de “ frmInsertaAlumno.java”. ...................................................................................313.2.4. Código de “ ctrlInsertaAlumno.java”. ...................................................................................333.2.5. Comentarios..........................................................................................................................33

4. Consultas y Manejo de Restricciones..................................................................................................354.1. Una Consulta Simple....................................................................................................................35

4.1.1. Especificación.......................................................................................................................354.1.2. Vista Lógica..........................................................................................................................354.1.3. Diagrama de Secuencia.........................................................................................................364.1.4. Código de “ frmBuscaAlumno.java”. ....................................................................................374.1.5. Código de “ ctrlBuscaAlumno.java”. ....................................................................................394.1.6. Comentarios..........................................................................................................................39

4.2. Manejo de Restricciones..............................................................................................................404.2.1. Especificación.......................................................................................................................404.2.2. Código de “ frmRestricciones.java”. .....................................................................................404.2.3. Código de “ ctrlRestricciones.java”. ......................................................................................444.2.4. Comentarios..........................................................................................................................44

5. Uso de JTable.......................................................................................................................................465.1. Un Ejemplo Sencillo....................................................................................................................46

5.1.1. Especificación.......................................................................................................................465.1.2. Código de “ frmTablaSencilla”. ............................................................................................465.1.3. Código de “ ctrlTablaSencilla”. .............................................................................................47

5.2. Un Ejemplo más Completo..........................................................................................................485.2.1. Especificación.......................................................................................................................485.2.2. Código de “ frmTablaCompleta.java”. ..................................................................................49

6. Java en Internet....................................................................................................................................536.1. Un Applet Sencillo.......................................................................................................................53

6.1.1. Código de “ AppletDePrueba.html”. .....................................................................................536.1.2. Código de “ AppletDePrueba.java”. ......................................................................................53

6.2. Otro Applet...................................................................................................................................546.2.1. Código de “ AppletSencillo.html” .........................................................................................546.2.2. Código de “ AppletSencillo .java”. ........................................................................................55

6.3. Un JSP..........................................................................................................................................556.3.1. Código de “ AppletConsulta.html”. .......................................................................................55

7. Un Ejemplo de Aplicación...................................................................................................................587.1. La Especificación.........................................................................................................................587.2. Diseño...........................................................................................................................................63

7.2.1. Vista Lógica..........................................................................................................................64

ii

Page 5: Tutorial Java

7.2.2. Carta de Estados para “frmClientes”. ...................................................................................647.3. Implementación............................................................................................................................65

7.3.1. Código de “ factura.sql”. .......................................................................................................657.3.2. Código de “ GridBagPanel.java”. ..........................................................................................657.3.3. Código de “ frmProductos.java” ............................................................................................677.3.4. Código de “ ctrlProductos.java” ............................................................................................687.3.5. Código de “ frmClientes.java”. ..............................................................................................697.3.6. Código de “ ctrlClientes.java” ...............................................................................................737.3.7. Código de “ frmFactura.java”. ...............................................................................................747.3.8. Código de “ ctrlFactura.java” ................................................................................................777.3.9. Código de “ frmLogin.java”. .................................................................................................817.3.10. Código de “ ctrlLogin.java”. ................................................................................................847.3.11. Código de “ frmMenu.java”. ...............................................................................................85

7.4. Generación del Ejecutable............................................................................................................887.4.1. Código de “ manifest.txt” ......................................................................................................88

iii

Page 6: Tutorial Java

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

iv

Page 7: Tutorial Java

1.Introducción

a Java.

1

Page 8: Tutorial Java

1. Introducción a Java.Java  es  un  lenguaje  de  programación orientado  a  objetos(oopl).  Eso   significa  que  al  escribir  unprograma, 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  porvariables  internas,  que les sirven para almacenar  información y por operaciones internas, llamadasmétodos que les permiten realizar labores.

Para organizar más fácilmente el código, lo dividimos en  clases. Estas son conjuntos de objetos quetienen 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 aobjetos. Empezaremos haciendo programas sencillos de una sola clase y terminaremos detallando laarquitectura 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  acontinuació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 representarsimultá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, perosirven para explicar o aclarar alguna sección.

2

Page 9: Tutorial Java

F

V

V

F

F Ve == c1

e == c2

e == c3

Otro valor de e

En Java hay dos formas de utilizar comentarios. Los comentarios de una o más líneas empiezan con lasecuencia /* y terminan con */. Los comentarios de una sola línea empiezan con // y terminan con elfinal 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 semuestran a continuación.

if(cond) {

ins

}

if(cond) {

ins1

} else {

ins2

}

cond? expr1: expr2

if (cond1){

ins1

} else if (cond2) {

ins2

} else if (cond3) {

ins3

}

if (cond1) {

ins1

} else if (cond2) {

ins2

} else if (cond3) {

ins3

} else {

ins4

}

switch (e) {

case c1:

case c2:

ins1

break;

case c3:

ins2

break;

default:

ins3

}

while (condición) {

instrucciones

}

do {

instrucciones

} while(condición);

for (ini;cond;inc) {

instrucciones

}

3

V

F V

F

F V F V

F

F

V

V

F V

F

F

V

V

Page 10: Tutorial Java

1.5. Terminación de Ciclos y Funciones.Ciclo {

while (cond) {

instrs1

break;

instrs2

}

instrs3

}

Ciclo {

do { instrs1

break;

instrs2

} while(cond);

instrs3

}

Ciclo {

for (ini;cond;inc) {

instrs1

break;

instrs2

}

instrs3

}

Etiqueta:

while (cond) {

ciclo {

instrs1

break Etiqueta;

instrs2

}

instrs3

}

Etiqueta:

do {

ciclo {

instrs1

break Etiqueta;

instrs2

}

instrs3

} while(cond);

Etiqueta:

for (ini;cond;inc) {

ciclo {

instrs1

break Etiqueta;

instrs2

}

instrs3

}

Ciclo {

while (cond) {

instrs1

continue;

instrs2

}

instrs3

}

Ciclo {

do {

instrs1

continue;

instrs2

} while (cond);

instrs3

}

Ciclo {

for (ini;cond;inc) {

instrs1

continue;

instrs2

}

instrs3

}

Eti:

while(cond) {

ciclo {

instrs1

continue Eti;

instrs2

}

instrs3

}

Eti:

do {

ciclo {

instrs1

continue Eti;

instrs2

}

instrs3

} while (cond);

Eti:

for (ini;cond;inc) {

ciclo {

instrs1

continue Eti;

instrs2

}

instrs3

}

4

Page 11: Tutorial Java

void función(args) {

instrs1

return;

instrs2

}

tipo función(args) {

instrs1

return expresión;

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 losrenglones 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ónexpresió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ónexpresión *=  expresión     expresión  /=  expresión     expresión %=  expresiónexpresión &=  expresión      expresión ^=  expresión      expresión  |=  expresiónexpresión   <<=  expresión       expresión   >>=  expresiónexpresión >>>= expresión

5

Page 12: Tutorial Java

1.7. Un Programa en Java.

1.7.1. Diagrama de Clases de UML.

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 delos objetos que pertenecen a ella. El primero es el nombre de la clase. El segundo indica las variablesde los objetos.  Finalmente,  el   tercero muestra  los métodos de los objetos.  Aquellos elementos queaparecen subrayados pertenecen a  la  clase  y no forman parte de  los objetos,  como en el  caso delmétodo main.

1.7.2. Código de “Ejemplo.java”.123456789

101112131415161718192021222324252627282930313233

/** * Declaración de la clase "Ejemplo". La palabra "public" indica que esta * clase es visible desde cualquier parte de la aplicación. Cada archivo de * Java debe contener a lo más una clase pública y su nombre coincidir con el * nombre de esa clase pública, exceptuando la extensión ".java". Las * mayúsculas y minúsculas deben coincidir. Esta clase debe capturarse en un * archivo que se llame "Ejemplo.java". */public class Ejemplo { /** * Se define un método que se llama max. Recibe dos números y devuelve el * mayor de ellos. Todos los objetos que pertenecen a la clase * "Ejemplo" contienen una copia de esta operación. La palabra * "public" se puede usar con variables y métodos. Se conoce como nivel * de acceso. Ver 1.6.4 para una descripción de los niveles * de acceso. */ public int max(int a, int b) { if (a > b) { return a; } else { return b; } } /** * Operación pública que calcula la suma de dos números. Una clase puede * tener varias operaciones. */ public int suma(int a, int b) { return (a + b); }

6

Ilustración 1. Ejemplo de Clase.

Ejemplo

+max(a: int, b: int): int+suma(a: int, b: int): int+main(args: String[])

Page 13: Tutorial Java

3435363738394041424344454647484950515253545556575859606162636465666768697071

/** * La palabra "static" indica que esta operación pertenece a la clase y * no forma parte de objetos. Este es el punto de entrada a la * aplicación. En este método se crea un objeto de la clase y se prueba * su comportamiento para asegurar que sea correcto. Los métodos que * realizan esto son conocidos como "pruebas de unidad", y son muy útiles * en la ingeniería de software. Se recomienda que todos los * componentes de una aplicación tengan una prueba de unidad. */ public static void main (String[] args) { // AQUI EMPIEZA LA EJECUCION DEL PROGRAMA. // Se crea un objeto con ayuda del operador "new". Dicho objeto tiene // una copia de los métodos "max" y "suma". Esta es la primera línea // de código que se ejecuta. Ejemplo e = new Ejemplo();

// Se invoca el método "max" contenido en "e". Nota que el operador // "." sirve para pedirle a un objeto que haga algo. Se realiza // sustitución de parámetros. El primer parámetro de la línea 18, o // sea "a", toma como valor el primer parámetro de la línea 61, que // es "1". El segundo parámetro de (18), o sea "b", toma el valor el // segundo parámetro de (61), que es "8", y así sucesivamente. A // continuación se ejecutan las líneas 19 a 24. El resultado se envía // de regreso a (61), donde se muestra en la pantalla de salida de la // aplicación, que es representada por la variable de clase "out", // localizada en la clase "System". El objeto tiene una operación // llamada "println" que utiliza para desplegar información. System.out.println(e.max(1, 8)); // El comportamiento de (65) y (66) es parecido al descrito // previamente. System.out.println(e.max(5, 3)); System.out.println(e.max(3, 3)); // Sucederá algo parecido, pero se ejecutarán las líneas (30) a (32). System.out.println(e.suma(4, 7)); } // Se termina el método main, con lo cual termina la aplicación.}

1.7.3. Salida en Pantalla.Línea Salida en Pantalla

61656669

85311

1.6.4. Comentarios.Las aplicaciones en Java normalmente están compuestos de varias clases, pero empiezan su ejecuciónes una operación de clase (también llamada  estática) que se llame main y que reciba un arreglo deelementos “ 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   losnombres de clases inician en mayúscula.

7

Page 14: Tutorial Java

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

Page 15: Tutorial Java

2.Acceso

a Bases

de Datos.

9

Page 16: Tutorial Java

2. Acceso a Bases de Datos.

Cuando desarrollas un sistema de información,  la base de todo el trabajo es el almacenamiento dedatos,   que   generalmente   son   tablas   de   una   base   de   datos   relacional.   Por   ello   es   necesario   quecomprendas como funcionan y también como se utilizan desde un programa.  Empezaremos con lamanipulació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 seorganizan de la manera que se esquematiza a continuación

Cada tupla representa un objeto. Los atributos representan características del mismo. Todas las tuplastienen varios  atributos. Cada atributo tiene un valor asociado. El conjunto de los valores que puedetomar un atributo se conoce como dominio. Los valores de un dominio no tienen estructura interna (esdecir que son atómicos) y no contienen estructuras repetitivas (univaluados). Un conjunto de tuplas sepueden   juntar   para   formar   una  relación.   En   ella,   todas   las   tuplas   tienen   los   mismos   nombres   ydominios para un número dado de atributo, pero pueden tener distintos valores. Así mismo, todas lastuplas 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,   quenormalmente 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 estudiaa continuación es como manipularlas usando MySQL.

10

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

Nombre de la relaciónAtributo 1 Atributo 2 ............... Atributo nValor 1 Valor 2 ............... Valor n Tupla 1 Xxxxxxx xxxxxxxx ............... Xxxxxxxx Tupla 2 . . . . . . . . . . . . . . .Xxxxxxx xxxxxxxx ............. Xxxxxxxxx Tupla m

Page 17: Tutorial Java

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 comooficial.

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

2.3. Manipulación de una Tabla.

2.3.1. Vista Lógica.

La vista   lógica  muestra   las  clases  que  utilizará   la  aplicación. En  la  arquitectura  que  emplearemosdurante el curso se emplea una clase para manejar la base de datos. En este caso es “ctrlAlumno”.  Lasclases que manipulan datos y realizan el flujo principal de una aplicación se conocen como clases decontrol y llevan el prefijo “ctrl”.  También se les asocia el ícono que se muestra para “ctrlAlumno”.  Laclase   “alumno”   representa   un   almacén   de   datos.   Cada   objeto   de   ella   representa   un   registro   deinformació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 representacon la flecha unidireccional. Cuando el acceso se puede realizar en los dos sentidos, se pone una flechabidireccional, o bien una línea sin flechas.

2.3.2. Vista de Datos.

11

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

alumno

PK matricula: INTEGERNN nombre: VARCHAR(30)NN fecha_de_nacimiento: DATE

Ilustración 3. Vista Lógica de un Ejemplo que Manipula una Tabla.

*ctrlAccesoAlumno

- url: String = "jdbc:mysql://localhost/test" {frozen}- usuario: String = "root" {frozen}- password :String password = "" {frozen}- formato: DateFormat = getDateInstance( )

+ insercionSimple( )+ inserta(matricula: int, nombre: String, fecha: java.sql.Date )+ main(args: String[])

alumnomatricula: intnombre: Stringfecha_de_nacimiento: Date

Page 18: Tutorial Java

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”).12345

CREATE TABLE alumno( matricula INTEGER PRIMARY KEY, nombre VARCHAR(30) NOT NULL, fecha_de_nacimiento DATE NOT NULL) TYPE = InnoDB;

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

2.3.5. Modificación de datos en la tabla (“upd ate_alumno.sql”).123

UPDATE alumno SETnombre = 'Zoila Vaca del Corral', fecha_de_nacimiento = '1987-02-03'WHERE matricula = 200141;

2.3.6. Consulta de datos en la tabla (“s elect_alumno.sql”).12SELECT * FROM alumnoWHERE 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.12DELETE FROM alumnoWHERE matricula = 200141;

2.3.9. Código de “c trlAccesoAlumno.java”.123456

// "import" sirve para tener acceso a clases de la librería base// de Java. Las clases se organizan en "paquetes", que son como// carpetas.import java.sql.*; // Para interactuar con la base de datos.import java.text.*; // Para la clase "DateFormat".

12

Page 19: Tutorial Java

78910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455

public class ctrlAccesoAlumno { /** * Variable que identifica a una base de datos. URL significa "Universal * Resource Locator" y es una cadena que sirve para ubicar un recurso * en una red. Consta de 3 partes: protocolo, host y recurso. * El protocolo en este caso es "jdbc:mysql"; el host es "localhost" y * el recurso es "test". El valor "localhost" representa a la * computadora donde estás ejecutando este programa. El valor "test" es * la base de datos que crea MySQL al instalarse. MySQL también crea un * usuario que se llama "root" y no tiene password. Si utilizas mysql en * la misma computadora donde se está ejecutando esta aplicación y * quieres usar la base de datos "test", debes usar la siguiente * definición. */ private static final String url = "jdbc:mysql://localhost/test"; /* * Si prefieres usar MySQL en un servidor, quita el comentario de la * siguiente definición y cambia test por la base de datos que tengas * asignada. Existe una sola copia de esta variable (por eso es static) * y está localizada en la clase. No forma parte de los objetos. La * palabra final indica que no se puede cambiar (O sea que es una * constante. */ // private static final String url = "jdbc:mysql://192.168.7.251/test"; /* * Para Oracle quita el comentario de la siguiente definición. */ // private static final String url = // "jdbc:oracle:thin:@192.168.7.99:1521:oracledb"; /** * Usuario con el que te conectarás a la base de datos. */ private static final String usuario = "root"; /** * Password con el que te conectarás a la base de datos. */ private static final String password = ""; /** * Este objeto se utilizará para capturar y mostrar fechas en el formato * e idioma correctos de acuerdo a la configuración de idiomas de la * computadora donde se ejecuta este programa. */ private static DateFormat formato = DateFormat.getDateInstance();

13

Page 20: Tutorial Java

5657585960616263646566676869707172737475767778798081828384858687888990919293949596979899

100101102103104

/** * Inserta un registro cuando los datos ya se conocen de antemano. * Esta rutina no se puede utilizar para insertar datos diferentes. * Siempre inserta los mismos datos. La expresión "throws Exception" * significa que se pueden producir errores en la ejecución, los cuales * serán procesados por el método que mande llamar a este. */ public void insercionSimple() throws Exception { // Intenta conectarse al url indicado con el usuario y password // definido en la clase. Si por alguna razón no se puede conectar a // la base de datos, se crea un objeto de la clase "Exception". Se // aborta la ejecución del programa. El objeto de la clase // "Exception" lleva una descripción de los que falló y se pasa al // método que mando llamar a "inserción" para que procese el error. // Es caso de que la conexión si se pueda establecer, se obtiene el // objeto conexion, que representa la sesión de trabajo. Connection conexion = DriverManager.getConnection(url, usuario, password); // Transaction Isolation representa el comportamiento de la // conexión en un ambiente concurrente. // TRANSACTION_SERIALIZABLE significa que nuestros datos se // mantendrán sin daño. Para lograrlo, se establecen bloqueos, // por lo cual en algunas ocasiones las transacciones pueden ser // abortadas por el manejador de bases de datos para evitar daños // a la integridad de la información. conexion.setTransactionIsolation( Connection.TRANSACTION_SERIALIZABLE); // Crea una instrucción en SQL para insertar un registro. Como los // manejadores manejan las fechas de formas muy diferentes, Java te // permite usar la instrucción "{d 'AAAA-MM-DD'}", que será cambiada // por la instrucción correcta para tu DBMS. "AAAA" son 4 dígitos // para el año. "MM" son 2 dígitos para el mes y "DD", 2 dígitos // para el día. PreparedStatement ps = conexion.prepareStatement( "INSERT INTO alumno " + "VALUES(200141, 'Zoila Vaca', {d '1978-02-03'})"); // Ejecuta la consulta. ps.executeUpdate(); // Da por terminada la consulta y libera los recursos que ocupó ps.close(); // Termina la conexión y libera los recursos que ocupó conexion.close(); }

14

Page 21: Tutorial Java

105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168

/** * Esta rutina permite insertar un registro en la base de datos * que contenga la información que se recibe como parámetro. * Se puede utilizar siempre que se necesite. */ public void inserta(int matricula, String nombre, java.sql.Date fecha) throws Exception { Connection conexion = DriverManager.getConnection(url, usuario, password); conexion.setTransactionIsolation( Connection.TRANSACTION_SERIALIZABLE); // Los signos "?" representan los valores que pueden cambiar cada // vez que se ejecute la consulta. PreparedStatement ps = conexion.prepareStatement( "INSERT INTO alumno VALUES(?, ?, ?)"); ps.setInt(1, matricula);// El primer signo "?" será la matrícula. ps.setString(2, nombre);// El segundo signo "?" será el nombre. ps.setDate(3, fecha); // El tercer signo "?" será la fecha. ps.executeUpdate(); ps.close(); conexion.close(); } /** * Muestra los datos que se encuentran almacenados en la tabla "alumno". */ public void muestraRegistros() throws Exception { Connection conexion = DriverManager.getConnection(url, usuario, password); conexion.setTransactionIsolation( Connection.TRANSACTION_SERIALIZABLE); PreparedStatement ps = conexion.prepareStatement( "SELECT * FROM alumno"); // Al ejecutar una consulta se utiliza executeQuery, que regresa // un objeto de la clase "ResultSet", el cual representa el // resultado de la consulta. ResultSet rs = ps.executeQuery(); // Cada vez que se ejecuta rs.next(), se recupera el siguiente // renglón de la consulta. Cuando ya no hay más registros, esta // expresión regresa "false" y por lo tanto el ciclo termina. while (rs.next()) { System.out.println("-----------------------------------------");

// rs.getString("matricula") recupera el campo matrícula // del registro que mandó traer rs.next(). Si el nombre del // campo está mal tecleado, se genera una excepción. System.out.println("MATRICULA : " + rs.getString("matricula")); System.out.println("NOMBRE : " + rs.getString("nombre"));

// Nota el uso del objeto "formato" para convertir un texto en // fecha. System.out.println("FECHA DE NACIMIENTO : " + formato.format(rs.getDate("fecha_de_nacimiento"))); } rs.close(); ps.close(); conexion.close(); }

15

Page 22: Tutorial Java

169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210220221222223224225

public static void main(String[] args) { // AQUI EMPIEZA LA EJECUCION DEL PROGRAMA. // La instrucción "try" indica que algunas instrucciones del // bloque de instrucciones siguiente puede generar excepciones, las // cuales se van a procesar con la instrucción "catch". try { // Carga las clases encargadas de conectar el programa con // el una base de datos Oracle. Normalmente están localizadas // en un archivo con extensión ".jar", que puede ubicarse // en el subdirectorio "jre/ext/lib" dentro del directorio de // java o en alguna de las localidades indicadas por la // variable de ambiente "CLASSPATH". Class.forName("oracle.jdbc.OracleDriver"); // Carga las clases encargadas de conectar el programa con // el una base de datos MySQL. Estas clases se pueden // localizar de igual forma que las clases para Oracle. Class.forName("com.mysql.jdbc.Driver"); ctrlAccesoAlumno a = new ctrlAccesoAlumno();

// Ejecuta las líneas 63 - 103 para el objeto "a". a.insercionSimple(); // Ejecuta las líneas 110 a 128 para el objeto "a" y toma los // siguientes valores: // matricula --> 200142 // nombre --> "Rolando Mota" // fecha -->valor correspondiente a {d '1973-08-07} // Nota el uso de "formato" para convertir el texto en fecha. Si // el texto no tiene el formato correcto se genera una // excepción. a.inserta(200142, "Rolando Mota", new java.sql.Date(formato.parse("07/08/1973").getTime())); a.inserta(200143, "Armando Pacheco", new java.sql.Date(formato.parse("02/08/1982").getTime())); a.inserta(200144, "Pancracio Wellington", new java.sql.Date(formato.parse("30/02/1985").getTime())); a.muestraRegistros(); } catch (Exception e) { // Muestra la razón del error, así como las funciones se estaban // ejecutando y en cual linea en el momento de que sucedió // el fallo. e.printStackTrace(); } }}

16

Page 23: Tutorial Java

2.3.10. Salida en Pantalla.Línea Salida en Pantalla

149154 y 155156 y 157161 y 162

149154 y 155156 y 157161 y 162

149154 y 155156 y 157161 y 162

149154 y 155156 y 157161 y 162

-----------------------------------------MATRICULA : 200141NOMBRE : Zoila VacaFECHA DE NACIMIENTO : 3/02/1978-----------------------------------------MATRICULA : 200142NOMBRE : Rolando MotaFECHA DE NACIMIENTO : 7/08/1973-----------------------------------------MATRICULA : 200143NOMBRE : Armando PachecoFECHA DE NACIMIENTO : 2/08/1982-----------------------------------------MATRICULA : 200144NOMBRE : Pancracio WellingtonFECHA DE NACIMIENTO : 2/03/1985

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

Cuando varias transacciones traten de usar los mismos datos simultáneamente, tenemos un ambienteconcurrente.  Si   las   transacciones   actúan  de   forma desordenada,   la   integridad  de   los  datos  puedecorromperse.   Decimos   que   un   método   de   administración   de   transacciones   es  serializable,  alpresentarse 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 lossiguientes tipos de bloqueos:

• Compartidos. Al accesar al mismo dato varias transacciones solamente los pueden consultar, perono 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 registrosque 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.  Sipreviamente se ha establecido un bloqueo exclusivo sobre los datos, la transacción aborta. Cuando elbloque preestablecido es compartido, la transacción puede continuar. Si se quiere establecer un bloqueoexclusivo 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 unatransacción.  La   instrucción  “ commit”   indica  que   la   transacción  se  ha   realizado  con  éxito  y  hacevisibles   a   otras   transacciones   las  modificaciones   realizadas   a   los   datos.   Por   su  parte,  “ rollback”deshace todos los cambios que la transacción haya realizado.

17

Page 24: Tutorial Java

Las conexiones de Java están configuradas para realizar automáticamente “commit”  o “ rollback”  encada 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, puedesindicar 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.

En este caso la clase de control verificará que los datos a insertar en la tabla “material”  cumplan conalgunas 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

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

*

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)

alumnomatricula: intnombre: Stringfecha_de_nacimiento: Date

materialdescripcion: Stringestado: String

1 *

*

Page 25: Tutorial Java

2.4.2. Vista de Datos.

La llave foránea la estamos indicando con FK.

2.4.3. Datos en las Tablas.

2.4.4. Creación de la Tabla Material (“material.sql”).12345678910111213141516171819202122232425

CREATE TABLE material(id INTEGER PRIMARY KEY AUTO_INCREMENT,descripcion VARCHAR(30) NOT NULL,

/** Este campo es llave foránea. Su definición debe coincidir con la llave* primaria de la tabla con la que enlaza*/matricula INTEGER NOT NULL,

/* El atributo “estado” solo puede tomar uno de los valores que están entre* los paréntesis. No puede tomar ningún otro.*/estado ENUM('OK','DESCOMPUESTO','EN REPARACION','BAJA') NOT NULL,

/** Las llaves foráneas deben indexarse en MySQL.*/INDEX(matricula),

/** Las llaves foráneas siempre apuntan a una llave primaria.*/FOREIGN KEY(matricula) REFERENCES alumno(matricula)) TYPE = InnoDB;

2.4.5. Ejemplo de Inserción de Datos (“ insert_material.sql”).1234567

/** Como el campo “id” es auto numérico, no se le pone valor. Por esto se* pone entre paréntesis los nombres de los campos cuyos valores se* proporcionan. Las listas de campos y de valores se relacionan por el orden.*/INSERT INTO material(descripcion, matricula, estado)VALUES('Banca con paleta', 200141, 'OK');

19

Ilustración 6. Vista de Dato para un Ejemplo que Realiza Validaciones.

alumno

PK matricula: INTEGERNN nombre: VARCHAR(30)NN fecha_de_nacimiento: DATE

materialPK id: INTEGER {AUTO_INCREMENT}NN descripcion: VARCHAR(30)FK matricula INTEGERNN estado ENUM('OK','DESCOMPUESTO','EN REPARACION','BAJA')

*1

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

alumno matricula nombre fecha de nacimiento 200141 Zoila Vaca 1978 – 02 – 03 200142 Rolando Mota 1973 – 08 – 07 200143 Armando Pacheco 1982 – 08 – 02 200144 Pancracio Wellington 1985 – 03 – 02

material id descripcion matricula estado 1 Banca con paleta 200141 OK 2 Banca sin paleta 200142 DESCOMPUESTO 3 Paleta sin banca 200143 BAJA

Page 26: Tutorial Java

2.4.6. Una Consulta de Dos Tablas (“se lect_alumno_y_material.sql”).1234567

/** Nota como se igualan la llave primaria de la tabla “alumno” con la llave* foránea de la tabla “material”.*/SELECT alumno.matricula, nombre, id, descripcionFROM alumno, materialWHERE 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”.123456789101112131415161718192021222324252627282930313233343536373839

import java.sql.*;import java.text.*;import java.util.*;

public class ctrlAccesoMaterial { private static final String url = "jdbc:mysql://localhost/test"; private static final String usuario = "root"; private static final String password = ""; public int inserta(String descripcion, int matricula, String estado) throws Exception { Connection conexion = DriverManager.getConnection(url, usuario, password); // Se van a realizar varias instrucciones de SQL, por lo cual tenemos // una transacción con más de una instrucción. Es necesario ejecutar // explícitamente la instrucción "commit" o "rollback". conexion.setAutoCommit(false); conexion.setTransactionIsolation( Connection.TRANSACTION_SERIALIZABLE); validaInsercion(conexion, descripcion, matricula, estado); PreparedStatement ps = conexion.prepareStatement( "INSERT INTO material(descripcion, matricula, estado)" + "VALUES(?, ?, ?)"); ps.setString(1, descripcion); ps.setInt(2, matricula); ps.setString(3, estado); ps.executeUpdate(); ResultSet rs = ps.getGeneratedKeys(); rs.next(); int id = rs.getInt(1); rs.close(); ps.close(); conexion.commit(); conexion.close(); return id; }

20

Page 27: Tutorial Java

404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293

void validaInsercion(Connection conexion, String descripcion, int matricula, String estado) throws Exception { validaDescripcion(conexion, descripcion); validaMatricula(conexion, matricula); validaEstado(conexion, estado); }

void validaDescripcion(Connection conexion, String descripcion) throws Exception { if (descripcion.length() == 0) { abortaConexion(conexion, "Descripción Incorrecta."); } }

void validaMatricula(Connection conexion, int matricula) throws Exception { PreparedStatement ps = conexion.prepareStatement( "SELECT matricula FROM alumno " + "WHERE matricula = ?"); ps.setInt(1, matricula); ResultSet rs = ps.executeQuery(); // Si la primera vez que se ejecuta rs.next() es falso, entonces no // tenemos datos en la consulta; o sea que no hay alumnos con esa // matrícula. if (!rs.next()) { ps.close(); abortaConexion(conexion, "Matrícula Incorrecta."); } }

void validaEstado(Connection conexion, String estado) throws Exception { String[] estados = {"BAJA","DESCOMPUESTO","EN REPARACION","OK"};

// Realiza una búsqueda binaria del estado buscado en el arreglo. // Los datos del arreglo deben estar ordenados o no funcionará. // Si encuentra el dato, regresa su posición en el arreglo. Cuando // no lo encuentra regresa un valor negativo. Cuando tienes muchos // valores posibles es más eficiente realizar una búsqueda que // poner un if por cada valor que deseas validar. if (Arrays.binarySearch(estados, estado) < 0) { abortaConexion(conexion, "Estado Incorrecto."); } }

void abortaConexion(Connection conexion, String causa) throws Exception { conexion.rollback(); conexion.close(); throw new Exception(causa); }

21

Page 28: Tutorial Java

949596979899

100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135

public void muestraRegistros() throws Exception { Connection conexion = DriverManager.getConnection(url, usuario, password); conexion.setTransactionIsolation( Connection.TRANSACTION_SERIALIZABLE); PreparedStatement ps = conexion.prepareStatement("SELECT * FROM material"); ResultSet rs = ps.executeQuery(); System.out.println("------------------------------------------"); while (rs.next()) { System.out.println(rs.getString("id") + "|" + rs.getString("descripcion") + "|" + rs.getString("matricula") + "|" + rs.getString("estado")); } rs.close(); ps.close(); conexion.close(); }

public void muestraJoin() throws Exception { Connection conexion = DriverManager.getConnection(url, usuario, password); conexion.setTransactionIsolation( Connection.TRANSACTION_SERIALIZABLE); PreparedStatement ps = conexion.prepareStatement( "SELECT alumno.matricula, nombre, id, descripcion " + "FROM alumno, material " + "WHERE alumno.matricula = material.matricula"); ResultSet rs = ps.executeQuery(); System.out.println("------------------------------------------"); while (rs.next()) { System.out.println(rs.getString(1) + "|" + rs.getString("nombre") + "|" + rs.getString("id") + "|" + rs.getString("descripcion")); } rs.close(); ps.close(); conexion.close(); }

22

Page 29: Tutorial Java

136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168

public static void main(String[] args) { try { Class.forName("com.mysql.jdbc.Driver"); ctrlAccesoMaterial a = new ctrlAccesoMaterial(); int id =a.inserta("Banca con paleta", 200141, "OK"); System.out.println("id = " + id); a.inserta("Banca sin paleta", 200142, "DESCOMPUESTO"); a.inserta("Paleta sin banca", 200143, "BAJA");

// Es importante que una prueba de unidad verifique el // comportamiento de la clase en situaciones de error. try { //un ejemplo de error a.inserta("", 200141, "OK"); } catch (Exception e) { System.out.println(e.getMessage()); } try { //un ejemplo de error a.inserta("Banca", 2001, "EN REPARACION"); } catch (Exception e) { System.out.println(e.getMessage()); } try { //un ejemplo de error a.inserta("Banca", 200141, "MAL"); } catch (Exception e) { System.out.println(e.getMessage()); } a.muestraRegistros(); a.muestraJoin(); } catch (Exception e) { e.printStackTrace(); } }}

2.4.9. Salida en Pantalla.Línea Salida en Pantalla

141150155160102

104 – 1007104 – 1007104 – 1007

124126 – 129126 – 129126 – 129

id = 1Descripción Incorrecta.Matrícula Incorrecta.Estado Incorrecto.------------------------------------------1|Banca con paleta|200141|OK2|Banca sin paleta|200142|DESCOMPUESTO3|Paleta sin banca|200143|BAJA------------------------------------------200141|Zoila Vaca|1|Banca con paleta200142|Rolando Mota|2|Banca sin paleta200143|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 losdatos en aquellas tablas que no manejan llaves foráneas y después debes insertar  en las tablas queapuntan hacia datos ya insertados.

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

23

Page 30: Tutorial Java

los mensajes de error sean más claros.  Por otro lado, los datos no siempre son manipulados desdeprograma y los programas pueden tener errores en las validaciones. Por eso es importante poner reglasde 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”).12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849

public class Cadenas { public static void main(String[] args) { String base = "Cadena base";

// Pega dos cadenas. System.out.println("prefijo" + base);

// Obtiene una subcadena que va desde el caracter 2 hasta el 5. System.out.println(base.substring(2,6));

// Regresa verdadero si las dos cadenas son el mismo texto. System.out.println(base.equals("Cadena base")); System.out.println(base.equals("inicio"));

// Regresa // > 0 si "a" > "sala" // < 0 si "a" < "sala" // == 0 si "a" == "sala" System.out.println("a".compareTo("sala")<0); System.out.println(base.compareTo("Cadena base")==0);

// Verdadero si la cadena termina con "ase". System.out.println(base.endsWith("ase"));

// Verdadero si la cadena comienza con ase. System.out.println(base.startsWith("Cad"));

// Regresa el caracter en la posición 7, empezando desde 0. System.out.println(base.charAt(7));

// Es como "equals", pero no hace distinción de mayúsculas y // minúsculas. System.out.println("tela".equalsIgnoreCase("TELA"));

// Busca el caracter 'a' desde el inicio de la cadena y regresa la // posición donde lo encontró. Si no aparece, regresa un valor // negativo. System.out.println(base.indexOf('a'));

// Igual que el anterior, pero busca a partir de la posición 3. System.out.println(base.indexOf('a', 3));

// Busca subcadenas. Tambén hay una variante que busca a partir de // cierta posición. System.out.println(base.indexOf("de"));

// Busca desde el final. Tiene las mismas variantes que "indexOf". System.out.println(base.lastIndexOf('a'));

24

Page 31: Tutorial Java

505152535455565758596061626364656667

// Regresa el número de posiciones que ocupa la cadena; o sea, su // longitud. System.out.println(base.length());

// Convierte todas las letras de la cadena en su equivalente en // minúscula. El resto de los caracteres no se modifican. System.out.println(base.toLowerCase());

// Convierte todas las letras de la cadena en su equivalente en // mayúscula. El resto de los caracteres no se modifican. System.out.println(base.toUpperCase());

System.out.println(" espacios " + "hola");

// Remueve los espacios al inicio y al final de una cadena. System.out.println(" trim ".trim() + "hola"); }}

2.5.2. Salida en Pantalla.Línea Salida en Pantalla

69

1213192023242933384145485256606265

prefijoCadena basedenatruefalsetruetruetruetruebtrue152811cadena baseCADENA BASE espacios holatrimhola

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

¿Por qué  no comparar las cadenas con el signo “ ==”?  Este signo compara que dos objetos sean elmismo. 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 losobjetos.

¿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. Elvalor más pequeño es el que aparece primero en el diccionario. Nota que al comparar cadenas sucedeque “10”  < “2”. ¿ Entiendes por qué?

25

Page 32: Tutorial Java

3.InterfacesGráficas.

26

Page 33: Tutorial Java

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.

El usuario debe proporcionar el valor de “nombre”.  Al oprimir el botón “Púchale”  el contenido de estecampo se copia a “dirección ” .

3.1.2. Vista Lógica.

Java tiene ya construidas clases para en desarrollo de interfaces gráficas. La clase JPanel representaformas 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 quela   clase   “ frmSencilla”   tiene   todos   los  miembros   (variables  y  métodos)  de  un   “JPanel”,   pero  queextiende   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 bienclase derivada. A su vez, JPanel es clase padre de frmSencilla.

27

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

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 8. frmSencilla.

Page 34: Tutorial Java

“ JPanel”  es un conjunto de objetos. “frmSencilla”  es un subconjunto de esta. En cualquier parte decó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”.1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556

import javax.swing.*; // Para todos los componentes gráficos.import java.awt.*; // Para la clase "GridLayout".import java.awt.event.*; // Para los eventos de los botones.

/** * La palabra extends indica que "frmSencilla" es clase hija de * JPanel. */public class frmSencilla extends JPanel { /** * Esto es necesario por una característica de los objetos en Java que se * conoce como serialización. */ private static final long serialVersionUID = 1L; // Definición de los componentes gráficos en Java. /** * Etiqueta. Al crearla se le pasa el texto que despliega. */ private JLabel lblNombre = new JLabel("Nombre:"); /** * Cuadro de texto. Se le pasa el número de caracteres a mostrar. */ private JTextField txtNombre = new JTextField(10); private JLabel lblDireccion = new JLabel("Dirección:"); private JTextField txtDireccion = new JTextField(10); /** * Botón. Se le pasa el texto a mostrar. */ private JButton btnPuchale = new JButton("Púchale"); /** * Constructor de la clase "frmSencilla". Se invoca en el momento de * crear un objeto de esta clase. Permite inicializar valores y realizar * procesos. */ public frmSencilla() { agregaEventos(); // A los objetos de JPaneles hay que ponerles un layout. // Este les indica como organizar los componentes. En este caso el // objeto de clase "GridLayout" indica que se usarán tres renglones // y dos columnas. setLayout(new GridLayout(3, 2)); // Agrega los componentes en orden de izquierda a derecha hasta // llenar el renglón, continuando con el renglón inferior add(lblNombre); add(txtNombre); add(lblDireccion); add(txtDireccion); add(btnPuchale); }

28

Page 35: Tutorial Java

575859606162636465666768697071727374757677787980818283848586878889909192939495969798

void agregaEventos() { // Liga el método "clickEnPuchale" con la acción de apretar el // botón btnPuchale. btnPuchale.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { clickEnPuchale(); } }); } public void clickEnPuchale() { // Toma el contenido del cuadro de texto "txtNombre" y lo deja en la // variable "nombre". String nombre = txtNombre.getText(); // Cambia el contenido al cuadro de texto "txtDireccion". txtDireccion.setText(nombre); }

public static void main(String[] args) { // JFrame representa a las ventanas principales de una aplicación. // Al construir el objeto se le pasa el texto a desplegar en la // barra de título. JFrame frame = new JFrame("Interfaz Simple"); // Crea un objeto de "frmSencilla", o sea una forma, y le pone // barras de desplazamiento que se desplegarán cuando sea necesario. // Para ello, se coloca en un JscrollPane. Finalmente este objeto // se agrega a la ventana principal. frame.add(new JScrollPane(new frmSencilla())); // Se configura la ventana principal para que termina la aplicación // al cerrarse. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Calcula el tamaño y coordenadas de todos los componentes gráficos // que contiene la ventana principal. frame.pack(); // Muestra la ventana principal. frame.setVisible(true); }}

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

La serialización es un mecanismo que permite a Java almacenar objetos y transportarlos a través deredes.   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

Page 36: Tutorial Java

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.

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.

En este caso dividimos las funciones en dos objetos:

30

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

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[])

*ctrlInsertaAlumno

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

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

alumnomatricula: intnombre: Stringfecha_de_nacimiento: Date

1 control

Ilustración 10. frmInsertaAlumno.

Page 37: Tutorial Java

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 elobjeto   de   interacción,   se   destruye   el   objeto   de   control.   Esta   relación   de   pertenencia   se   llamaagregació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”.123456789101112131415161718192021222324252627282930313233343536373839

import javax.swing.*;import java.awt.*;import java.awt.event.*;import java.text.*;

public class frmInsertaAlumno extends JPanel { private static final long serialVersionUID = 1L; private static DateFormat formato = DateFormat.getDateInstance();

private JLabel lblMatricula = new JLabel("Matrícula:"); private JTextField txtMatricula = new JTextField(10); private JLabel lblNombre = new JLabel("Nombre:"); private JTextField txtNombre = new JTextField(10); private JLabel lblFecha = new JLabel("Fecha:"); private JTextField txtFecha = new JTextField(10); private JButton btnGuardar = new JButton("Guardar");

/** * Crea el objeto de control y establece la relación con él. */ private ctrlInsertaAlumno control = new ctrlInsertaAlumno();

public frmInsertaAlumno() { agregaEventos(); setLayout(new GridLayout(4, 2)); add(lblMatricula); add(txtMatricula); add(lblNombre); add(txtNombre); add(lblFecha); add(txtFecha); add(btnGuardar); }

void agregaEventos() { btnGuardar.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { clickEnGuardar(); } }); }

31

Page 38: Tutorial Java

4041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889

public void clickEnGuardar() { int matricula = 0; boolean datosOk = true; try { // parseInt convierte texto en un número entero. Si el contenido // de la cadena no es un número, se genera una excepción. matricula = Integer.parseInt(txtMatricula.getText()); } catch (Exception e) { muestraMensaje("La matricula debe ser numerica."); datosOk = false; } String nombre = txtNombre.getText(); java.sql.Date fecha = null; try { fecha = new java.sql.Date( formato.parse(txtFecha.getText()).getTime()); } catch (Exception e) { muestraMensaje("Fecha en formato incorrecto."); datosOk = false; } if (datosOk) { try { control.inserta(matricula, nombre, fecha); muestraMensaje("Registro Insertado."); } catch (Exception e) { muestraMensaje(e.getMessage()); e.printStackTrace(); } } }

public void muestraMensaje(String mensaje) { // Muestra un cuadro de diálogo modal que despliega “mensaje”. // El valor null se refiere al JFrame que debe bloquear. JOptionPane.showMessageDialog(null, mensaje); }

public static void main(String[] args) { try { Class.forName("com.mysql.jdbc.Driver"); JFrame frame = new JFrame("Inserta Alumno"); frame.add(new JScrollPane(new frmInsertaAlumno())); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } }}

32

Page 39: Tutorial Java

3.2.4. Código de “c trlInsertaAlumno.java”.123456789101112131415161718192021222324

import java.sql.*;import java.text.*;

public class ctrlInsertaAlumno { private static final String url = "jdbc:mysql://localhost/test"; private static final String usuario = "root"; private static final String password = "";

public void inserta(int matricula, String nombre, java.sql.Date fecha) throws Exception { Connection conexion = DriverManager.getConnection(url, usuario, password); conexion.setTransactionIsolation( Connection.TRANSACTION_SERIALIZABLE); PreparedStatement ps = conexion.prepareStatement( "INSERT INTO alumno VALUES(?, ?, ?)"); ps.setInt(1, matricula); ps.setString(2, nombre); ps.setDate(3, fecha); ps.executeUpdate(); ps.close(); conexion.close(); }}

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

Los  cuadros de  diálogo  normalmente   se  utilizan  para  obtener   información complementaria  y  paramostrar los resultados de algún proceso. El flujo normal debe realizarse a través de la ventana principalde 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

Page 40: Tutorial Java

4.Consultas

yManejo

deRestricciones.

34

Page 41: Tutorial Java

4. Consultas y Manejo de Restricciones.

4.1. Una Consulta Simple.

4.1.1. Especificación.

El usuario debe introducir un valor para matrícula. Al oprimir el botón “ Buscar”  se extrae de la base dedatos la información del alumno que corresponde a esa matrícula.

4.1.2. Vista Lógica.

35

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

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[])

*ctrlBuscaAlumno

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

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

infoAlumnomatricula: intnombre: Stringfecha_de_nacimiento: Date

1 control

Ilustración 12. frmBuscaAlumno.

Page 42: Tutorial Java

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

Aquí tenemos el flujo principal de la aplicación. El control de errores se incorpora en el código. Notaque cada flecha es recibida por el objeto que va a realizar la operación. Este diagrama funciona comopseudocó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 elnúmero que le corresponde en el diagrama..

36

Dibujo 1. Diagrama de Secuencia para frmBuscaAlumno.

: frmBuscaAlumno

3. busca(matricula: int)

5. get(matricula): ResultSet

8. respuesta

4. estableceConexion( )

7. terminaConexion( )

: infoAlumno

1. lee(id)

2. clickEnBuscar( )

6. guardaValores()

control: ctrlBuscaAlumno

9. muestraRegistro(respuesta)

Page 43: Tutorial Java

4.1.4. Código de “f rmBuscaAlumno.java”.123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263

import java.awt.event.*;import javax.swing.*;import java.awt.*;import java.text.*;import java.util.*; // Para la clase "LinkedHashMap".

public class frmBuscaAlumno extends JPanel { private static final long serialVersionUID = 1L; private static final DateFormat formato = DateFormat.getDateInstance();

private JLabel lblMatricula = new JLabel("Matrícula:"); private JTextField txtMatricula = new JTextField(10); private JLabel lblNombre = new JLabel("Nombre:"); private JTextField txtNombre = new JTextField(10); private JLabel lblFecha = new JLabel("Fecha:"); private JTextField txtFecha = new JTextField(10); private JButton btnBuscar = new JButton("Buscar"); private ctrlBuscaAlumno control = new ctrlBuscaAlumno(); public frmBuscaAlumno() { agregaEventos(); setLayout(new GridLayout(4,2)); add(lblMatricula); add(txtMatricula); add(lblNombre); add(txtNombre); add(lblFecha); add(txtFecha); add(btnBuscar); } void agregaEventos() { btnBuscar.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { clickEnBuscar(); //D2 } }); } public void clickEnBuscar() { //D2 int matricula = 0; boolean datosOk = true; try { matricula = Integer.parseInt(txtMatricula.getText()); } catch (NumberFormatException e) { muestraMensaje("La matricula debe ser numerica."); datosOk = false; } if (datosOk) { try { // El objeto de control busca en la base de datos los datos // del alumno con la matrícula introducida. Si no encuentra // ningún alumno con esa matrícula, lanza una excepción. Si // encuentra el registro, regresa una tabla que tiene como // campo llave el nombre del atributo y como valor asociado // el valor de ese atributo. Todas las clases son hijas de // la clase Object. LinkedHashMap<String,Object> respuesta = //D3 control.busca(matricula); //D3 muestraRegistro(respuesta); //D9 } catch (Exception e) { muestraMensaje(e.getMessage()); } } }

37

Page 44: Tutorial Java

6465666768697071727374757677787980818283848586878889909192939495

public void muestraRegistro(LinkedHashMap<String,Object> respuesta) {//D9 // get recupera el valor asociado con el nombre del campo. // Todos los objetos tienen una operación llamada toString que // permite obtener su representación como cadena. txtMatricula.setText(respuesta.get("matricula").toString()); //D9 txtNombre.setText(respuesta.get("nombre").toString()); //D9 // De todas formas las fechas se tienen que manejar con el objeto // formateador. La expresión "(java.sql.Date)" verifica si el objeto // pertenece a esa clase. En caso de que no, se genera una excepción. // Si el objeto si pertenece a esa clase, recupera ese tipo. txtFecha.setText( //D9 formato.format((java.sql.Date)respuesta.get("fecha"))); //D9 } public void muestraMensaje(String mensaje) { JOptionPane.showMessageDialog(null, mensaje); } public static void main(String[] args) { try { Class.forName("com.mysql.jdbc.Driver"); JFrame frame = new JFrame("Busca Alumno"); frame.add(new JScrollPane(new frmBuscaAlumno())); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } }}

38

Page 45: Tutorial Java

4.1.5. Código de “c trlBuscaAlumno.java”.1234567891011121314151617181920212223242526272829303132333435363738394041424344454647

import java.sql.*;import java.util.*;

public class ctrlBuscaAlumno { private static final String url = "jdbc:mysql://localhost/test"; private static final String usuario = "root"; private static final String password = ""; public LinkedHashMap<String,Object> busca(int id) throws Exception {//D3 Connection conexion = //D4 DriverManager.getConnection(url, usuario, password);//D4 conexion.setTransactionIsolation( //D4 Connection.TRANSACTION_SERIALIZABLE); //D4 PreparedStatement ps = conexion.prepareStatement( //D5 "SELECT * FROM alumno WHERE matricula = ?");//D5 ps.setInt(1, id); //D5 ResultSet rs = ps.executeQuery(); //D5 LinkedHashMap<String,Object> respuesta = //D6 new LinkedHashMap<String,Object>(); //D6 // Si el dato se encuentra, la consulta tiene un registro. En ese // caso, rs.next() es positivo. Como solo queremos un campo usamos // if. if (rs.next()) { Integer matricula = //D6 new Integer(rs.getInt("matricula"));//D6 String nombre = rs.getString("nombre"); //D6 java.sql.Date fecha_de_nacimiento = //D6 rs.getDate("fecha_de_nacimiento"); //D6 // Agrega un registro a la tabla. El campo llave es el nombre // del campo y el valor asociado es el valor del campo. respuesta.put("matricula", matricula); //D6 respuesta.put("nombre", nombre); //D6 respuesta.put("fecha", fecha_de_nacimiento); //D6 } else { // El dato no se encontró. Flujo alterno. rs.close(); ps.close(); conexion.close(); throw new Exception("Registro no encontrado."); } rs.close(); //D7 ps.close(); //D7 conexion.close(); //D7 return respuesta; //D8 }}

4.1.6. Comentarios.Se recomienda que realices los diagramas de análisis antes de programar, porque te ayudan a clarificartus 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   paramanejar parejas de información.

39

Page 46: Tutorial Java

4.2. Manejo de Restricciones.

4.2.1. Especificación.

Este ejemplo trabaja con las tablas “alumno”  y “ material”.  La interfaz gráfica debe ayudar al usuario arealizar su trabajo. Al capturar llaves foráneas, en este ejemplo debes proporcionar la matrícula de sudueño,  pero,   ¿te  acuerdas  de  ellas?  Para   ayudar   al  usuario   le   presentamos   en  un   combo  box   lasmatrículas registradas y el nombre del alumno correspondiente. Esto es más fácil de manejar. Si tefijas,   la  relación entre matrícula y nombre funciona como un diccionario.  Por ello utilizaremos unLinkedHashMap 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”.  Porotro lado el botón “Modificar”  muestra un cuadro de diálogo con la información que se enviaría a labase 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”.12345678910111213141516171819

import java.awt.event.*;import java.awt.*;import javax.swing.*;import java.util.*;

public class frmRestricciones extends JPanel { private static final long serialVersionUID = 1L; private JLabel lblId = new JLabel("Id:"); private JTextField txtId = new JTextField(10); private JLabel lblDescripcion = new JLabel("Descripción:"); private JTextField txtDescripcion = new JTextField(10); private JLabel lblMatricula = new JLabel("Responsable:"); private JComboBox cmbMatricula = new JComboBox(); private JLabel lblEstado = new JLabel("Estado:"); private JComboBox cmbEstado = new JComboBox(); private JButton btnBuscar = new JButton("Buscar"); private JButton btnModificar = new JButton("Modificar");

40

Ilustración 14. frmRestricciones.

Page 47: Tutorial Java

202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576

/** * El campo llave contiene la matrícula y el valor asociado es el nombre. */ private LinkedHashMap<String, String> matriculas; private ctrlRestricciones control = new ctrlRestricciones(); public frmRestricciones() { configuraComponentes(); agregaEventos(); setLayout(new GridLayout(5, 2)); add(lblId); add(txtId); add(lblDescripcion); add(txtDescripcion); add(lblMatricula); add(cmbMatricula); add(lblEstado); add(cmbEstado); add(btnBuscar); add(btnModificar); } void configuraComponentes() { // Los campos numéricos se justifican a la derecha. txtId.setHorizontalAlignment(JTextField.RIGHT); // Se añaden renglones al combo box cmbEstado.addItem("BAJA"); cmbEstado.addItem("DESCOMPUESTO"); cmbEstado.addItem("EN REPARACION"); cmbEstado.addItem("OK"); // hay que llenar cmbMatricula con la información de la base de // datos. cargaMatriculas(); } void cargaMatriculas() { try { matriculas = control.cargaMatriculas(); agregaMatriculas(); } catch (Exception e) { muestraMensaje(e.getMessage()); } } void agregaMatriculas() { // Borra todos los renglones del combo box. cmbMatricula.removeAllItems(); int i = 0;

// entrySet() nos proporciona una lista de las parejas almacenadas // en el LinkedHashMap. for (Map.Entry<String,String> e: matriculas.entrySet()) { String matricula = e.getKey(); // Recupera el valor llave. String nombre = e.getValue(); // Recupera el valor asociado. cmbMatricula.addItem(matricula + " - " + nombre); } }

41

Page 48: Tutorial Java

7778798081828384858687888990919293949596979899

100101102103104105106107108109110111112113114115116117118119

void agregaEventos() { btnBuscar.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { clickEnBuscar(); } }); btnModificar.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { clickEnModificar(); } }); }

public void clickEnBuscar() { int id = 0; boolean datosOk = true; try { id = Integer.parseInt(txtId.getText()); } catch (Exception e) { muestraMensaje("El id debe ser numerico."); datosOk = false; } if (datosOk) { try { LinkedHashMap<String,Object> respuesta = control.busca(id); muestraRegistro(respuesta); } catch (Exception e) { muestraMensaje(e.getMessage()); } } } public void clickEnModificar() { int id = 0; boolean datosOk = true; try { id = Integer.parseInt(txtId.getText()); } catch (NumberFormatException e) { muestraMensaje("El id debe ser numerico."); datosOk = false; } String descripcion = txtDescripcion.getText();

42

Page 49: Tutorial Java

120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174

// Recupera la combinación de matrícula y nombre seleccionadas. // Con “split” separa la matrícula del nombre, usando " - " como // separación. Seleccion[0] es la matrícula y seleccion[1] el // nombre. String[] seleccion = cmbMatricula.getSelectedItem().toString().split(" - "); int matricula = 0; try { matricula = Integer.parseInt(seleccion[0]); } catch (NumberFormatException e) { muestraMensaje("La matricula debe ser numerica."); datosOk = false; } String estado = cmbEstado.getSelectedItem().toString(); if (datosOk) { muestraMensaje("Se quiere modificar\n" + "id = " + id + "\n" + "descripcion = " + descripcion + "\n" + "matricula = " + matricula + "\n" + "estado = " + estado); control.modifica(id, descripcion, matricula, estado); } } public void muestraRegistro(LinkedHashMap<String,Object> respuesta) { txtDescripcion.setText(respuesta.get("descripcion").toString()); String matricula = respuesta.get("matricula").toString(); // En la base de datos solo está almacenada la matrícula, pero para // seleccionar en cmbMatricula necesitas también el nombre. Para // ello podemos recurrir al LinkedHashMap llamado "matriculas". // Con get(matricula) recuperas el nombre. cmbMatricula.setSelectedItem( matricula + " - " + matriculas.get(matricula)); cmbEstado.setSelectedItem(respuesta.get("estado").toString()); } public void muestraMensaje(String mensaje) { JOptionPane.showMessageDialog(null, mensaje); } public static void main(String[] args) { try { Class.forName("com.mysql.jdbc.Driver"); JFrame frame = new JFrame("Manejo de Restricciones"); frame.add(new JScrollPane(new frmRestricciones())); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } }}

43

Page 50: Tutorial Java

4.2.3. Código de “c trlRestricciones.java”.1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556

import java.sql.*;import java.util.*;

public class ctrlRestricciones { private static final String url = "jdbc:mysql://localhost/test"; private static final String usuario = "root"; private static final String password = "";

public LinkedHashMap<String, String> cargaMatriculas() throws Exception { Connection conexion = DriverManager.getConnection(url, usuario, password); conexion.setTransactionIsolation( Connection.TRANSACTION_SERIALIZABLE); PreparedStatement matriculas = conexion.prepareStatement( "SELECT matricula, nombre FROM alumno"); ResultSet rs = matriculas.executeQuery(); LinkedHashMap<String,String> respuesta = new LinkedHashMap<String,String>(); while (rs.next()) { respuesta.put(rs.getString("matricula"), rs.getString("nombre")); } rs.close(); matriculas.close(); conexion.close(); return respuesta; }

public LinkedHashMap<String,Object> busca(int id) throws Exception { Connection conexion = DriverManager.getConnection(url, usuario, password); conexion.setTransactionIsolation( Connection.TRANSACTION_SERIALIZABLE); PreparedStatement busca = conexion.prepareStatement( "SELECT * FROM material WHERE id = ?"); busca.setInt(1, id); ResultSet rs = busca.executeQuery(); LinkedHashMap<String,Object> respuesta = new LinkedHashMap<String,Object>(); if (rs.next()) { //Solo queremos un elemento respuesta.put("matricula", new Integer(rs.getInt("matricula"))); respuesta.put("descripcion", rs.getString("descripcion")); respuesta.put("estado", rs.getString("estado")); } else { rs.close(); busca.close(); conexion.close(); throw new Exception("Registro no encontrado."); } rs.close(); busca.close(); conexion.close(); return respuesta; } public void modifica(int id, String descripcion, int matricula, String estado) {}}

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

44

Page 51: Tutorial Java

5.Uso

deJTable.

45

Page 52: Tutorial Java

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

5.1. Un Ejemplo Sencillo.

5.1.1. Especificación.

Despliega los datos almacenados en la tabla “ alumno”  en el momento de ejecutar la aplicación. Lasmodificaciones realizadas mientras la ventana se despliega no se muestran.

La tabla está estructurada como un arreglo bidimensional. La funcionalidad de desplegarla se divide endos   clases   de  objetos.  Los  datos   se   guardan   en  objetos  de   la   clase   “DefaultT ableModel”   .  Estospermiten realizar cualquier tipo de modificaciones a la información. Los datos pueden conectarse a unoo 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, sepueden colocar dentro de un JScrollPane para que agregue barras de desplazamiento.

5.1.2. Código de “f rmTablaSencilla”.12345678910111213

import javax.swing.*;import java.awt.event.*;import java.awt.*; // Para "Dimension".import javax.swing.table.*; // Para "DefaultTableModel".

public class frmTablaSencilla extends JPanel { private static final long serialVersionUID = 1L; JTable tblResultado = new JTable(); JScrollPane scroll = new JScrollPane(tblResultado);

ctrlTablaSencilla control = new ctrlTablaSencilla();

46

Ilustración 15. frmTablaSencilla.

Page 53: Tutorial Java

1415161718192021222324252627282930313233343536373839404142434445464748495051525354

public frmTablaSencilla() { configuraComponentes(); add(scroll); }

void configuraComponentes() { // Define el tamaño de la tabla. Para ello se utilizan objetos // de la clase Dimension. Su primer parámetro indica los pixeles // de ancho y el segundo parámetro es la altura. scroll.setPreferredSize(new Dimension(400, 100));

cargaAlumnos(); }

void cargaAlumnos() { try { DefaultTableModel alumnos = control.obtenDatos(); tblResultado.setModel(alumnos); } catch (Exception e) { muestraMensaje(e.getMessage()); e.printStackTrace(); } }

public void muestraMensaje(String mensaje) { JOptionPane.showMessageDialog(null, mensaje); }

public static void main(String[] args) { try { Class.forName("com.mysql.jdbc.Driver"); JFrame frame = new JFrame("Consulta"); frame.add(new JScrollPane(new frmTablaSencilla())); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } }}

5.1.3. Código de “c trlTablaSencilla”.12345678910111213

import java.sql.*;import java.util.*;import java.text.*;import javax.swing.table.*;

class ctrlTablaSencilla { private static DateFormat formato = DateFormat.getDateInstance(); private static final String url = "jdbc:mysql://localhost/test"; private static final String usuario = "root"; private static final String password = ""; private static Object[] encabezados = {"Matrícula", "Nombre", "Fecha de Nacimiento"};

47

Page 54: Tutorial Java

14151617181920212223242526272829303132333435363738394041424344454647

public DefaultTableModel obtenDatos() throws Exception { DefaultTableModel modelo = new DefaultTableModel() { private static final long serialVersionUID = 1L;

public boolean isCellEditable(int renglon, int columna) { return false; } }; // Le pone encabezado a las columnas del modelo. modelo.setColumnIdentifiers(encabezados); Connection conexion = DriverManager.getConnection(url, usuario, password); conexion.setTransactionIsolation( Connection.TRANSACTION_SERIALIZABLE); PreparedStatement consulta = conexion.prepareStatement( "SELECT * FROM alumno"); ResultSet rs = consulta.executeQuery(); while (rs.next()) { String matricula = rs.getString("matricula"); String nombre = rs.getString("nombre"); String fecha = formato.format( rs.getDate("fecha_de_nacimiento")); Object[] datos = {matricula, nombre, fecha}; // Agrega un renglón al final del modelo. modelo.addRow(datos); } consulta.close(); conexion.close(); return modelo; }}

5.2. Un Ejemplo más Completo.

5.2.1. Especificación.

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 eldato se ha modificado aparece un cuadro indicando que campo se quiere modificar en cual renglón. Alseleccionar un renglón y oprimir “Borrar ”,  se elimina la línea seleccionada. El botón “Total”  muestra lasuma de los goles.

48

Ilustración 16. frmTablaCompleta.

Page 55: Tutorial Java

5.2.2. Código de “f rmTablaCompleta.java”.123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960

import javax.swing.*;import java.awt.event.*;import javax.swing.table.*;import java.awt.*;

public class frmTablaCompleta extends JPanel{ private static final long serialVersionUID = 1L;

/** * Se crea un DefaultTableModel, pero se le cambian algunas funciones, */ DefaultTableModel modelo = new DefaultTableModel() { private static final long serialVersionUID = 1L;

/** * Regresa una clase que representa el tipo de datos de * cada columna. La numeración empieza en 0. */ public Class getColumnClass(int columna) { switch (columna) { case 0: return String.class; case 1: return Integer.class; case 2: return Boolean.class; case 3: return String.class; default: return Object.class; } } /** * Esta función se invoca cada vez que se quiere * modificar una celda. El JTable le envía el * nuevo valor que el usuario quiere colocar en la * celda. */ public void setValueAt(Object valor, int renglon, int columna) { // La palabra super representa a la clase padre. // En este caso es DefaultTableModel. Aqu? se // inserta el nuevo valor en el modelo. super.setValueAt(valor, renglon, columna); // Ahora invocaremos un evento dependiendo de la // columna que se está modificando. switch (columna) { case 0: cambiarNombre((String)valor, renglon); break; case 1: cambiarGoles((Integer)valor, renglon); break; case 2: cambiarActivo((Boolean)valor, renglon); break; case 3: cambiarPosicion((String)valor, renglon); break; } } };

49

Page 56: Tutorial Java

616263646566676869707172737475767778798081828384858687888990919293949596979899

100101102103104105116107108109110111112113114115

JTable tblJugadores = new JTable(); JScrollPane scroll = new JScrollPane(tblJugadores); JButton btnNuevo = new JButton("Nuevo"); JButton btnBorrar = new JButton("Borrar"); JButton btnTotal = new JButton("Total");

public frmTablaCompleta() { configuraComponentes(); agregaEventos(); add(scroll); add(btnNuevo); add(btnBorrar); add(btnTotal); }

void configuraComponentes() { Object[] encabezados = {"Nombre", "Goles", "Activo", "Posici?n"}; modelo.setColumnIdentifiers(encabezados); tblJugadores.setModel(modelo); scroll.setPreferredSize(new Dimension(300, 100));

// Asigna un combo box para capturar la columna 3. TableColumn posiciones = tblJugadores.getColumnModel().getColumn(3); JComboBox comboBox = new JComboBox(); comboBox.addItem("Portero"); comboBox.addItem("Defensa"); comboBox.addItem("Medio"); comboBox.addItem("Delantero"); posiciones.setCellEditor(new DefaultCellEditor(comboBox)); }

void agregaEventos() { btnNuevo.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { clickEnNuevo(); } }); btnBorrar.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { clickEnBorrar(); } }); btnTotal.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { clickEnTotal(); } }); }

public void clickEnNuevo() { Object[] nuevo = {}; modelo.addRow(nuevo); }

50

Page 57: Tutorial Java

116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172

public void clickEnBorrar() { int renglon = tblJugadores.getSelectedRow(); if (renglon != -1) { String nombre = (String)modelo.getValueAt(renglon, 0); Integer goles = (Integer)modelo.getValueAt(renglon, 1); Boolean activo = (Boolean)modelo.getValueAt(renglon, 2); String posicion = (String)modelo.getValueAt(renglon, 3); borrar(nombre, goles, activo, posicion); modelo.removeRow(renglon); } else { muestraMensaje("No has seleccionado renglon."); } }

public void clickEnTotal() { //El numero de columnas se obtiene con getColumnCount() int total = 0; for (int renglon=0; renglon < modelo.getRowCount(); renglon++) { int subtotal = (Integer)modelo.getValueAt(renglon,1); total += subtotal; } muestraMensaje("Total de goles: " + total); }

public void muestraMensaje(String mensaje) { JOptionPane.showMessageDialog(null, mensaje); }

public void cambiarNombre(String nombre, int renglon) { muestraMensaje("Quieres cambiar el nombre del renglon " + renglon); }

public void cambiarGoles(Integer goles, int renglon) { muestraMensaje("Quieres cambiar los goles del renglon " + renglon); }

public void cambiarActivo(Boolean activo, int renglon) { muestraMensaje("Quieres cambiar activo del renglon " + renglon); }

public void cambiarPosicion(String posicion, int renglon) { muestraMensaje("Quieres cambiar la posicion del renglon " + renglon); }

public void borrar(String nombre, Integer goles, Boolean activo, String posicion) { muestraMensaje("Quieres borrar a " + nombre); }

public static void main(String[] args) { JFrame frame = new JFrame("Tabla Completa"); frame.add(new JScrollPane(new frmTablaCompleta())); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); }}

51

Page 58: Tutorial Java

6.Java

enInternet.

52

Page 59: Tutorial Java

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 quese pueden insertar en una página HTML. Para ello, necesitas que tu navegador tenga registrada comoplug­in  una  máquina  virtual  de   Java  compatible  con  la  versión  de  código  que  estás  usando.  Esteejemplo muestra el mensaje “Hola”  en un renglón y “Adios”  inmediatamente abajo. Cada vez quesucede un evento en el applet, se despliega en la consola de Java.

6.1.1. Código de “AppletDePrueba.html”.12345678910111213141516171819

<html><head> <title>Applet de Prueba</title></head><body> <h1>Applet de Prueba</h1> <hr> <applet code="AppletDePrueba.class" width=100 height=120 alt="Tu navegador soporta applets pero no est&aacute; ejecutando." > <PARAM NAME = parametro1 VALUE = Hola> <PARAM NAME = parametro2 VALUE = Adios> Tu navegador no soporta applets. </applet> <hr></body></html>

6.1.2. Código de “AppletDePrueba.java”.12345678910111213141516171819202122

import javax.swing.*;import java.awt.*;

public class AppletDePrueba extends JApplet { private static final long serialVersionUID = 1L;

public AppletDePrueba() { System.out.println("Constructor"); }

public void init() { // Se ejecuta al entrar a la página. System.out.println("init"); }

public void start() { // Se ejecuta al entrar a la página. System.out.println("start"); }

public void stop() { // Se ejecuta al salir de la página. System.out.println("stop"); }

53

Page 60: Tutorial Java

2324252627282930313233343536373839404142434445464748495051

public void destroy() { // Se ejecuta al salir de la página. System.out.println("destroy"); }

public void paint(Graphics g) { // Dibuja al componente gráfico. // drawString permite desplegar un texto. Las coordenadas son // x = 0 y y = 80. // getParameter recupera los parámetros que se pasaron desde // el código en HTML. g.drawString(getParameter("parametro1"), 0, 80); g.drawString(getParameter("parametro2"), 0, 100); System.out.println("paint"); }

// Proporciona información sobre el applet. public String getAppletInfo() { return "Titulo: AppletDePrueba\n" + "Un applet de prueba."; }

// Regresa una descripción de los parámetros. public String[][] getParameterInfo() { String paramInfo[][] = { {"parametro1", "texto1", "cualquier dato1"}, {"parametro2", "texto2", "cualquier dato2"} }; return paramInfo; }}

6.2. Otro Applet.Este Applet muestra “frmSencilla”  en tu navegador.

6.2.1. Código de “AppletSencil lo.html”.1234567891011121314151617

<html><head> <title>Applet Sencillo</title></head><body> <h1>Applet Sencillo</h1> <hr> <applet code="AppletSencillo.class" width=250 height=100 alt="Tu navegador soporta applets pero no lo est&aacute; ejecutando." > Tu navegador no soporta applets. </applet> <hr></body></html>

54

Page 61: Tutorial Java

6.2.2. Código de “AppletSencil lo .java”.123456789

import javax.swing.*;

public class AppletSencillo extends JApplet { private static final long serialVersionUID = 1L;

public void init() { add(new JScrollPane(new frmSencilla())); }}

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

6.3.1. Código de “AppletConsul ta.html”.1234567891011121314151617181920212223242526272829303132333435

<%-- Este es un comentario.--%>

<%-- Los imports van separados por comas y la lista de ellos va entre comillas.--%>

<%@ page import = "java.sql.*" %>

<HTML> <HEAD><TITLE>Reporte de Alumnos</TITLE></HEAD><BODY><%! int n=0; %><% try { Class.forName("com.mysql.jdbc.Driver"); Connection con = DriverManager.getConnection( "jdbc:mysql://localhost/test", "otro", "akt"); PreparedStatement alumnos = con.prepareStatement( "SELECT * FROM alumno"); ResultSet rs = alumnos.executeQuery();%> <TABLE BORDER = "1" WIDTH="3"> <THEAD><TR><TH>MATRICULA<TH>NOMBRE<TH>FECHA DE NACIMIENTO <TBODY><% while (rs.next()) {%> <%-- esta expresion funciona como print --%> <TR><TD> <%= rs.getString("matricula")%> <TD> <%=rs.getString("nombre")%> <TD> <%=rs.getString("fecha_de_nacimiento")%><% }%> </TABLE>

55

Page 62: Tutorial Java

3637383940414243444546

<% rs.close(); alumnos.close(); con.close(); } catch(Exception e) {%> <%= e.getMessage() %><% }%></BODY></HTML>

56

Page 63: Tutorial Java

7.Un

Ejemplode

Aplicación.

57

Page 64: Tutorial Java

7. Un Ejemplo de Aplicación.¿Cómo se pueden integrar todos los temas que hemos estudiado para desarrollar una aplicación mascompleja? 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 sedefinen   los   casos  de  uso  y   se  define   el   funcionamiento  de  cada  uno de  ellos.  A continuación   tepresentamos el   funcionamiento  base  que deseamos  implementar.  Es una  parte  de  la   funcionalidadcompleta.

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

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

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

58

Ilustración 17. Portada.

Ilustración 18. Control de Acceso.

Page 65: Tutorial Java

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

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

59

Ilustración 19. Menú de Supervisor.

Ilustración 20. Reporte de Productos.

Page 66: Tutorial Java

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

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

El comportamiento de esta ventana lo describiremos por estados. Un estado es cada una de las posiblescombinaciones 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   estadoINESERTANDO.

Cerrar – habilitado.

Cierra la ventana.

Guardar – deshabilitado. Cancelar – deshabilitado.

60

Ilustración 21. Catálogo de Clientes.

Page 67: Tutorial Java

En el estado INSERTANDO tenemos lo siguiente:

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

Cerrar – deshabilitado. Guardar – habilitado.

Inserta   en   la   base   de   datos   unregistro   con   la   informaciónmostrada   en   la   ventana.   Si   lainserción   es   válida,   regresa   alestado BASE.

Cancelar – deshabilitado.

Regresa al estado BASE.

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

Se debe  introducir  el  número de  folio  de  la   factura,  valor  que  normalmente  se   toma de   la   formacontinua a imprimir. Después se introduce el RFC o parte del mismo y se oprime el botón RFC. Serecupera 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 elcódigo del producto. Este se busca en la base de datos y se recupera tanto la descripción como elprecio. Se añade el valor de cantidad. Para registrar la información en la base de datos se oprime elbotón guardar. Si  se quiere  imprimir  la factura, se oprime el botón “Imprimir”.  A continuación sepresenta un ejemplo de factura impresa.

61

Ilustración 22. Menú del Vendedor.

Page 68: Tutorial Java

El botón “ Cerrar”  cierra la ventana.

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

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

62

Ilustración 24. Menú Archivo.

Ilustración 23. Ejemplo de Factura Impresa.

folio: 19 fecha: 30/04/2004

RFC: PHNombre: Usuario

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

Page 69: Tutorial Java

El menú Ayuda es el siguiente.

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

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

Ilustración 25. Menú Ayuda.

Ilustración 26. Acerca De.

Page 70: Tutorial Java

7.2.1. Vista Lógica.

7.2.2. Carta de Estados para “frmClient es”.

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 yproporcionan 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   hanestudiado.

64

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

frmLogin

infoUsuario

frmMenu

ctrlClientes

frmClientes frmProductosfrmFactura

ctrlFactura ctrlProductos

ctrlLogin

infoCliente infoFactura infoProducto

*

1 control

1 control 1 control 1 control

* * *

1clientes

1 factura 1 productos

** *1

Ilustración 28. Carta de Estados para frmClientes.

Base

entry/ base( )

Insertando

entry/ insertando( )

insertar

guardar/insertar

cancelar

Cerrado

entry/ close( )

showcerrar

Page 71: Tutorial Java

7.3. Implementación.

7.3.1. Código de “f actura.sql”.123456789101112131415161718192021222324252627282930313233343536373839404142

CREATE TABLE usuario( usu_nombre VARCHAR(13) PRIMARY KEY, usu_rol ENUM('SUPERVISOR','VENDEDOR') NOT NULL)TYPE = InnoDB;

CREATE TABLE cliente( cli_rfc VARCHAR(13) PRIMARY KEY, cli_nombre VARCHAR(30) NOT NULL)TYPE = InnoDB;

CREATE TABLE producto( pr_id INTEGER PRIMARY KEY AUTO_INCREMENT, pr_descripcion VARCHAR(30) NOT NULL, pr_cantidad DECIMAL(10,2) NOT NULL, pr_precio DECIMAL(10,2) NOT NULL)TYPE = InnoDB;

CREATE TABLE factura(fac_folio INTEGER PRIMARY KEY,fac_fecha DATE NOT NULL,cli_rfc VARCHAR(13),INDEX(cli_rfc),FOREIGN KEY(cli_rfc) REFERENCES cliente(cli_rfc))TYPE = InnoDB;

CREATE TABLE detalle( pr_id INTEGER NOT NULL, fac_folio INTEGER NOT NULL, det_cantidad DECIMAL(10, 2) NOT NULL, det_precio DECIMAL(10, 2) NOT NULL, PRIMARY KEY(pr_id, fac_folio), INDEX(pr_id), FOREIGN KEY(pr_id) REFERENCES producto(pr_id), INDEX(fac_folio), FOREIGN KEY(fac_folio) REFERENCES factura(fac_folio))TYPE = InnoDB;

INSERT INTO producto (pr_descripcion, pr_cantidad, pr_precio)VALUES ('Chocolate', 100, 3.50);

INSERT INTO producto (pr_descripcion, pr_cantidad, pr_precio)VALUES ('Dulce', 300, 1.0);

7.3.2. Código de “Grid BagPanel.java”.123456789101112

/** * Un panel que permite colocar componentes fácilmente. */import java.awt.*;import javax.swing.*;

public class GridBagPanel extends JPanel { private static final long serialVersionUID = 1L; private GridBagLayout gridbag = new GridBagLayout(); private GridBagConstraints c = new GridBagConstraints();

65

Page 72: Tutorial Java

13141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686980818283848586

public GridBagPanel() { // De entrada los componentes se alínean a la izquierda. c.anchor = GridBagConstraints.WEST; setLayout(gridbag); } public void add(int y, int x, int alto, int ancho, Component componente) { c.gridy = y; c.gridx = x; c.gridheight = alto; c.gridwidth = ancho; gridbag.setConstraints(componente, c); add(componente); } public void setFill(int pFill) { c.fill = pFill; } public int getFill() { return c.fill; } public void setIpadx(int pIpadx) { c.ipadx = pIpadx; } public int getIpadx() { return c.ipadx; } public void setIpady(int pIpady) { c.ipadx = pIpady; } public int getIpady() { return c.ipady; } public void setInsets(Insets pInsets) { c.insets = pInsets; }

public Insets getInsets() { return c.insets; } public void setAnchor(int pAnchor) { c.anchor = pAnchor; }

public int getAnchor() { return c.anchor; } public void setWeightx(double pWeightx) { c.weightx = pWeightx; } public double getWeightx() { return c.weightx; }

66

Page 73: Tutorial Java

8788899091929394

public void setWeighty(double pWeighty) { c.weighty = pWeighty; } public double getWeighty() { return c.weighty; } }

7.3.3. Código de “f rmProductos.java”1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950

import javax.swing.*;import java.awt.event.*;import java.awt.*;import javax.swing.table.*;import java.text.*;

/** * Un JInternalFrame es una ventana que se abre de forma no modal dentro * de una ventana de aplicación. */public class frmProductos extends JInternalFrame { private static final long serialVersionUID = 1L; /** * Usamos un objeto de la clase GridBagPanel para colocar componentes. */ private GridBagPanel grid = new GridBagPanel();

ctrlProductos control = new ctrlProductos(); JTable tblResultado = new JTable(); JScrollPane scroll = new JScrollPane(tblResultado); JButton btnImprimir = new JButton("Imprimir");

public frmProductos() { // La palabra "super" se refiere al constructor de la clase padre, // que en este caso es JInternalFrame. Los valores "true" hacen // referencia a 4 características: se le puede cambiar el tamaño, // se puede cerrar, se puede maximizar y se puede minimizar. Si no // quieres alguna de ellas, ponla en "false". super("Reporte de Productos", true, true, true, true); configuraComponentes(); agregaEventos(); // coloca "scroll" en la columna 0, renglón 0, ocupando 10 // renglones de alto y 4 columnas de ancho. grid.add(0,0,10,4, scroll); // coloca "btnImprimir" en la columna 10, renglón 0, ocupando 1 // renglón de alto y 1 columna de ancho. grid.add(10,0,1,1, btnImprimir);

add(new JScrollPane(grid)); init(); pack(); } void configuraComponentes() { scroll.setPreferredSize(new Dimension(400, 100)); }

67

Page 74: Tutorial Java

51525354555657585960616263646566676869707172737475767778798081828384858687888990

/** * Esta rutina se invoca para reiniciar el estado de la ventana cada * vez que se vuelve a abrir. */ void init() { try { DefaultTableModel clientes = control.obtenDatos(); tblResultado.setModel(clientes); } catch (Exception e) { muestraMensaje(e.getMessage()); e.printStackTrace(); } } void agregaEventos() { btnImprimir.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { clickEnImprimir(); } }); } public void clickEnImprimir() { try { // Imprime el contenido de "tblResultado" sin hacer // modificaciones en la apariencia de sus celdas. El segundo // par?metro es el encabezado y el tercero es el pie de // página. {0} se refiere al n?mero de página. tblResultado.print(JTable.PrintMode.NORMAL, new MessageFormat("Reporte_de_Productos"), new MessageFormat("pagina - {0}")); } catch (Exception e) { muestraMensaje(e.getMessage()); } } public void muestraMensaje(String mensaje) { JOptionPane.showMessageDialog(null, mensaje); }}

7.3.4. Código de “c trlProductos.java”123456789

import java.sql.*;import java.util.*;import java.text.*;import javax.swing.table.*;

class ctrlProductos { private static final Object[] encabezados = {"Clave", "Descripcion", "Cantidad", "Precio"};

68

Page 75: Tutorial Java

10111213141516171819202122232425262728293031323334353637383940414243

public DefaultTableModel obtenDatos() throws Exception { DefaultTableModel modelo = new DefaultTableModel() { private static final long serialVersionUID = 1L; public boolean isCellEditable(int renglon, int columna) { return false; } public Class getColumnClass(int columna) { switch (columna) { case 0: return Integer.class; case 1: return String.class; case 2: return Double.class; case 3: return Double.class; default: return Object.class; } } }; modelo.setColumnIdentifiers(encabezados); Connection conexion = ctrlLogin.conecta(); PreparedStatement consulta = conexion.prepareStatement( "SELECT * FROM producto"); ResultSet rs = consulta.executeQuery(); while (rs.next()) { Integer id = new Integer(rs.getInt("pr_id")); String descripcion = rs.getString("pr_descripcion"); Double cantidad = new Double(rs.getDouble("pr_cantidad")); Double precio = new Double(rs.getDouble("pr_precio")); Object[] datos = {id, descripcion, cantidad, precio}; modelo.addRow(datos); } consulta.close(); conexion.close(); return modelo; }}

7.3.5. Código de “f rmClientes.java”.1234567891011121314151617181920212223

import javax.swing.*;import java.text.*;import javax.swing.table.*;import javax.swing.border.*;// Para "EtchedBorder" y "LineBorder"import java.awt.*; // Para "Color", "Font" e "Insets".import java.awt.event.*; // Para "KeyEvent".import java.util.*;

public class frmClientes extends JInternalFrame { private static final long serialVersionUID = 1L; private static DateFormat formato = DateFormat.getDateInstance(); private static java.sql.Date hoy = new java.sql.Date(new java.util.Date().getTime());

/** * Define constantes para cada uno de los estados que puede tomar esta * ventana. */ private enum Estado {BASE, INSERTANDO};

// Para un mejor control del contenido de la ventana, los componentes // se agrupan en páneles.

69

Page 76: Tutorial Java

2425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788

/** * El objeto gridInfo incluye a los componentes * que manejan datos. */ private GridBagPanel gridInfo = new GridBagPanel(); private JLabel lblRfc = new JLabel("RFC"); private JTextField txtRfc = new JTextField(13); private JLabel lblNombre = new JLabel("Nombre"); private JTextField txtNombre = new JTextField(30);

/** * Controla los botones que realizan operaciones. */ private GridBagPanel gridLateral = new GridBagPanel(); private JButton btnGuardar = new JButton("Guardar"); private JButton btnCancelar = new JButton("Cancelar");

/** * Controla los botones de mayor jerarquía. */ private GridBagPanel gridInferior = new GridBagPanel(); private JButton btnInsertar = new JButton("Insertar", new ImageIcon("cara.gif")); private JButton btnCerrar = new JButton("Cerrar", new ImageIcon("cara.gif"));

/** * Agrupa a los demás páneles. */ private GridBagPanel gridFondo = new GridBagPanel(); private JLabel lblHola = new JLabel("Hola", new ImageIcon("cara.gif"), JLabel.CENTER);

/** * Es el estado de operación en el cual se encuentra la ventana. */ private Estado estado;

private ctrlClientes control = new ctrlClientes();

public frmClientes() { super("Catalogo de Clientes", true, true, true, true); configuraComponentes(); agregaEventos(); gridInfo.add(0,0,1,1, lblRfc); gridInfo.add(0,1,1,2, txtRfc); gridInfo.add(1,0,1,1, lblNombre);gridInfo.add(1,1,1,4, txtNombre); gridLateral.add(0,0,1,1, btnGuardar); gridLateral.add(1,0,1,1, btnCancelar); gridInferior.add(0,0,1,1, btnInsertar); gridInferior.add(0,1,1,1, btnCerrar); gridFondo.add(0,0,1,1, gridInfo); gridFondo.add(0,1,1,1, gridLateral); gridFondo.add(1,0,1,1, gridInferior); gridFondo.add(1,1,1,1, lblHola);

add(new JScrollPane(gridFondo)); setDefaultCloseOperation(JInternalFrame.DO_NOTHING_ON_CLOSE); pack(); }

70

Page 77: Tutorial Java

8990919293949596979899

100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153

void configuraComponentes() { // "Selecciona el font "Century Gothic" normal de 16 puntos para // los componentes "lblRfc" y "txtRfc". Font centuryGothic = new Font("Century Gothic", Font.PLAIN, 16); lblRfc.setFont(centuryGothic); txtRfc.setFont(centuryGothic);

// "Selecciona el font "Impact" normal de 16 puntos para // los componentes "lblNombre" y "txtNombre". Font impact = new Font("Impact", Font.PLAIN, 16); lblNombre.setFont(impact); txtNombre.setFont(impact);

// "Selecciona el font "SansSerif" en negrillas e itálica. Font sansSerif = new Font("SansSerif", Font.BOLD|Font.ITALIC, 18); btnGuardar.setFont(sansSerif); // El botón "btnGuardar" se puede activar con la combinación de // teclas "ALT+G". "KeyEvent.VK_G" representa a la tecla "G". btnGuardar.setMnemonic(KeyEvent.VK_G);

btnCancelar.setFont(sansSerif); // Pone como color de letra un color con 200 de intensidad de // rojo, 145 de verde y 180 de azul. El valor mayor es 255. btnCancelar.setForeground(new Color(200, 145, 180)); // Usa un blanco predefinido para el fondo. btnCancelar.setBackground(Color.WHITE); // Define el texto a mostrar cuando el cursor del mouse se coloca // sobre el botón. btnCancelar.setToolTipText("Cierra el Catalogo");

// El botón "btnCancelar" se puede activar con la combinación de // teclas "ALT+C". "KeyEvent.VK_C" representa a la tecla "C". btnCancelar.setMnemonic(KeyEvent.VK_C);

// El botón "btnInsertar" se puede activar con la combinación de // teclas "ALT+I". "KeyEvent.VK_I" representa a la tecla "I". btnInsertar.setMnemonic(KeyEvent.VK_I);

// El botón "btnCerrar" se puede activar con la combinación de // teclas "ALT+R". "KeyEvent.VK_R" representa a la tecla "R". btnCerrar.setMnemonic(KeyEvent.VK_R);

// Pone un borde donde el panel se muestra hundido. gridLateral.setBorder(new EtchedBorder(EtchedBorder.LOWERED)); // La separación entre los componentes del panel se pone de 4 // pixeles. Al hacer esto se puede ver el efecto del borde. // Si no lo pones, los bordes no se ven. gridLateral.setInsets(new Insets(4,4,4,4)); gridLateral.setBackground(Color.BLUE); // Pone un borde dibujado con una línea en negro, y si el "look // and feel" lo permite, las esquinas redondeadas. gridInferior.setBorder(new LineBorder(Color.BLACK, 2, true));

gridInferior.setInsets(new Insets(3,3,3,3));

// Pone el estado inicial. base();

71

Page 78: Tutorial Java

154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207

} public void init() { // Estado inicial al abrir la ventana. base(); } public void base() { estado = Estado.BASE; txtRfc.setText(""); txtNombre.setText(""); txtRfc.setEnabled(false); // Deshabilita el componente. txtNombre.setEnabled(false); btnGuardar.setEnabled(false); btnCancelar.setEnabled(false); btnInsertar.setEnabled(true); // Habilita el componente. btnCerrar.setEnabled(true); btnInsertar.requestFocus(); // Posiciona el cursor del teclado. } public void insertando() { estado = Estado.INSERTANDO; txtRfc.setEnabled(true); txtNombre.setEnabled(true); btnGuardar.setEnabled(true); btnCancelar.setEnabled(true); btnInsertar.setEnabled(false); btnCerrar.setEnabled(false); txtRfc.requestFocus(); } void agregaEventos() { btnGuardar.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { clickEnGuardar(); } }); btnCancelar.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { clickEnCancelar(); } }); btnInsertar.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { clickEnInsertar(); } }); btnCerrar.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { clickEnCerrar(); } }); }

72

Page 79: Tutorial Java

208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245

public void clickEnGuardar() { if (estado == Estado.INSERTANDO) { String rfc = txtRfc.getText(); String nombre = txtNombre.getText(); try { control.inserta(rfc, nombre); base(); } catch (Exception e) { muestraMensaje(e.getMessage()); } } } public void clickEnCancelar() { // Cada botón puede realizar una función diferente dependiendo // del estado en que se encuentre. Por ello utilizamos una // condición. if (estado == Estado.INSERTANDO) { base(); } } public void clickEnInsertar() { if (estado == Estado.BASE) { insertando(); } } public void clickEnCerrar() { if (estado == Estado.BASE) { dispose(); } } public void muestraMensaje(String mensaje) { JOptionPane.showMessageDialog(null, mensaje); }}

7.3.6. Código de “c trlClientes.java”.123456789101112131415

import java.sql.*;import java.text.*;

public class ctrlClientes { public void inserta(String rfc, String nombre) throws Exception { Connection conexion = ctrlLogin.conecta(); PreparedStatement ps = conexion.prepareStatement( "INSERT INTO cliente VALUES(?, ?)"); ps.setString(1, rfc); ps.setString(2, nombre); ps.executeUpdate(); ps.close(); conexion.close(); }}

73

Page 80: Tutorial Java

7.3.7. Código de “f rmFactura.java”.1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950

import javax.swing.*;import java.text.*;import javax.swing.table.*;import java.awt.*;import java.awt.event.*;import java.util.*;

public class frmFactura extends JInternalFrame { private static final long serialVersionUID = 1L; private static DateFormat formato = DateFormat.getDateInstance(); private static java.sql.Date hoy = new java.sql.Date(new java.util.Date().getTime()); private GridBagPanel grid = new GridBagPanel(); private JLabel lblFolio = new JLabel("No.de Folio"); private JTextField txtFolio = new JTextField(11); private JLabel lblFecha = new JLabel("Fecha"); private JLabel lblRfc = new JLabel("RFC"); private JTextField txtRfc = new JTextField(13); private JButton btnBusca = new JButton("Busca RFC"); private JLabel lblNombre = new JLabel("Nombre"); private JTextField txtNombre = new JTextField(30); private DefaultTableModel detalle = new DefaultTableModel() { private static final long serialVersionUID = 1L; public Class getColumnClass(int columna) { switch (columna) { case 0: return Integer.class; case 1: return String.class; case 2: return Double.class; case 3: return Double.class; default: return Object.class; } } public void setValueAt(Object valor, int renglon, int columna) { super.setValueAt(valor, renglon, columna); switch (columna) { case 0: cambiarCodigo((Integer)valor, renglon); break; } } }; private JTable tblDetalle = new JTable(); private JScrollPane scroll = new JScrollPane(tblDetalle); private JButton btnNuevo = new JButton("Nuevo"); private JButton btnGuardar = new JButton("Guardar"); private JButton btnImprimir = new JButton("Imprimir"); private JButton btnCerrar = new JButton("Cerrar");

private ctrlFactura control = new ctrlFactura();

74

Page 81: Tutorial Java

51525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899

100101102103104105106107108109110111112113114115

public frmFactura() { super("Elaboracion de Factura", true, //resizable true, //closable true, //maximizable true);//iconifiable configuraComponentes(); agregaEventos(); grid.add(0,0,1,1, lblFolio); grid.add(0,1,1,2, txtFolio); grid.add(0,3,1,1, lblFecha); grid.add(1,0,1,1, lblRfc); grid.add(1,1,1,2, txtRfc); grid.add(1,3,1,1, btnBusca); grid.add(2,0,1,1, lblNombre);grid.add(2,1,1,4, txtNombre); grid.add(3,0,10,5, scroll); grid.add(13,0,1,1, btnNuevo);grid.add(13,1,1,1, btnGuardar); grid.add(13,2,1,1, btnImprimir);grid.add(13,3,1,1, btnCerrar); add(new JScrollPane(grid)); setFrameIcon(new ImageIcon("icono.jpg")); pack(); }

void configuraComponentes() { txtFolio.setHorizontalAlignment(JTextField.RIGHT); lblFecha.setHorizontalAlignment(JTextField.RIGHT); lblFecha.setText("fecha : " + formato.format(hoy)); Object[] encabezados = {"Codigo","Descripcion","Cantidad","Precio"}; detalle.setColumnIdentifiers(encabezados); tblDetalle.setModel(detalle); scroll.setPreferredSize(new Dimension(400, 100)); }

public void init() { txtFolio.setText(""); txtRfc.setText(""); txtNombre.setText(""); while (detalle.getRowCount() > 0) { detalle.removeRow(0); } }

void agregaEventos() { btnBusca.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { clickEnBusca(); } }); btnNuevo.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { clickEnNuevo(); } }); btnGuardar.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { clickEnGuardar(); } }); btnImprimir.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { clickEnImprimir(); } }); btnCerrar.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { clickEnCerrar(); } });

75

Page 82: Tutorial Java

116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177

}

public void clickEnNuevo() { Object[] nuevo = {}; detalle.addRow(nuevo); }

public void clickEnBusca() { try { String rfc = txtRfc.getText(); LinkedHashMap<String, Object> respuesta = control.buscaCliente(rfc); muestraCliente(respuesta); } catch (Exception e) { muestraMensaje(e.getMessage()); e.printStackTrace(); } }

public void clickEnGuardar() { int folio = 0; boolean datosOk = true; try { folio = Integer.parseInt(txtFolio.getText()); } catch (Exception e) { muestraMensaje("El folio debe ser numerico."); datosOk = false; } String rfc = txtRfc.getText(); if (datosOk) { try { control.guarda(folio, hoy, rfc, detalle); } catch (Exception e) { muestraMensaje(e.getMessage()); } } }

public void clickEnImprimir() { int folio = 0; boolean datosOk = true; try { folio = Integer.parseInt(txtFolio.getText()); } catch (Exception e) { muestraMensaje("El folio debe ser numerico."); datosOk = false; } String rfc = txtRfc.getText(); String nombre = txtNombre.getText(); if (datosOk) { try { control.imprime(folio, hoy, rfc, nombre, detalle); } catch (Exception e) { muestraMensaje(e.getMessage()); } } }

public void clickEnCerrar() { dispose(); }

76

Page 83: Tutorial Java

178179180181182183184185186187188189190191192193194195196197198199200201202203204205206

public void clickEnCerrar() { dispose(); }

public void cambiarCodigo(Integer codigo, int renglon) { try { LinkedHashMap<String, Object> respuesta = control.buscaProducto(codigo.intValue()); muestraProducto(respuesta, renglon); } catch (Exception e) { muestraMensaje(e.getMessage()); }

}

public void muestraCliente(LinkedHashMap<String,Object> respuesta) { txtRfc.setText(respuesta.get("rfc").toString()); txtNombre.setText(respuesta.get("nombre").toString()); }

void muestraProducto(LinkedHashMap<String,Object>respuesta,int renglon) { detalle.setValueAt(respuesta.get("descripcion"), renglon, 1); detalle.setValueAt(respuesta.get("precio"), renglon, 3); }

public void muestraMensaje(String mensaje) { JOptionPane.showMessageDialog(null, mensaje); }}

7.3.8. Código de “c trlFactura.java”12345678910

import java.sql.*;import java.util.*;import javax.swing.table.*;import java.io.*;import javax.print.*;import javax.print.attribute.*;import javax.print.attribute.standard.*;import java.awt.print.*;

public class ctrlFactura {

77

Page 84: Tutorial Java

11121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162

public LinkedHashMap<String,Object> buscaCliente(String rfc) throws Exception { LinkedHashMap<String, Object> respuesta = new LinkedHashMap<String, Object>(); Connection conexion = ctrlLogin.conecta(); PreparedStatement busca = conexion.prepareStatement( "SELECT * FROM cliente WHERE cli_rfc LIKE ?"); busca.setString(1, '%' + rfc + '%'); ResultSet rs = busca.executeQuery(); if (rs.next()) { //Solo queremos un elemento rfc = rs.getString("cli_rfc"); String nombre = rs.getString("cli_nombre"); respuesta.put("nombre", nombre); respuesta.put("rfc", rfc); } else { rs.close(); busca.close(); conexion.close(); throw new Exception("Cliente no encontrado."); } rs.close(); busca.close(); conexion.close(); return respuesta; } public LinkedHashMap<String,Object> buscaProducto(int id) throws Exception { LinkedHashMap<String, Object> respuesta = new LinkedHashMap<String, Object>(); Connection conexion = ctrlLogin.conecta(); PreparedStatement busca = conexion.prepareStatement( "SELECT * FROM producto WHERE pr_id = ?"); busca.setInt(1, id); ResultSet rs = busca.executeQuery(); if (rs.next()) { //Solo queremos un elemento String descripcion = rs.getString("pr_descripcion"); double precio = rs.getDouble("pr_precio"); respuesta.put("descripcion", descripcion); respuesta.put("precio", new Double(precio)); } else { rs.close(); busca.close(); conexion.close(); throw new Exception("Producto no encontrado."); } rs.close(); busca.close(); conexion.close(); return respuesta; }

78

Page 85: Tutorial Java

63646566676869707172737475767778798081828384858687888990919293949596

public void guarda(int folio, java.sql.Date hoy, String rfc, DefaultTableModel detalle) throws Exception { Connection conexion = ctrlLogin.conecta(); conexion.setAutoCommit(false); PreparedStatement ps; ps = conexion.prepareStatement( "INSERT INTO factura(fac_folio,fac_fecha,cli_rfc)" + "VALUES(?,?,?)"); ps.setInt(1, folio); ps.setDate(2, hoy); ps.setString(3, rfc); ps.executeUpdate(); ps.close(); ps = conexion.prepareStatement( "INSERT INTO detalle " + "(pr_id,fac_folio,det_cantidad,det_precio)" + "VALUES(?, ?, ?, ?)"); for (int renglon = 0; renglon < detalle.getRowCount(); renglon++) { Integer codigo = (Integer)detalle.getValueAt(renglon, 0); Double cantidad = (Double)detalle.getValueAt(renglon, 2); Double precio = (Double)detalle.getValueAt(renglon, 3); ps.setInt(1, codigo.intValue()); ps.setInt(2, folio); ps.setDouble(3, cantidad); ps.setDouble(4, precio); ps.executeUpdate(); } ps.close(); conexion.commit(); conexion.close(); }

}

79

Page 86: Tutorial Java

979899

100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156

public void imprime(int folio, java.sql.Date hoy, String rfc, String nombre, DefaultTableModel detalle) throws Exception { // Abre el archivo "salida.txt" para impresión. PrintWriter salida = new PrintWriter( new BufferedWriter( new FileWriter("salida.txt"))); // Esto funciona como el printf del lenguaje C. // "%d" representa a "folio". La "d" significa entero. // "%2$te" es el día del segundo parámetro("hoy"). // "%2$tm" es el mes del segundo parámetro("hoy"). // "%2$tY" es el año en cuatro dígitos de "hoy". imprime(salida, "folio: %d fecha: %2$te/%2$tm/%2$tY", folio, hoy); imprime(salida, ""); imprime(salida, ""); // "%s" significa que se evalua la operacion toString() del // objeto. imprime(salida, "RFC: %s", rfc); imprime(salida, "Nombre: %s", nombre); imprime(salida, ""); double total = 0; for (int renglon = 0; renglon < detalle.getRowCount(); renglon++) { String descripcion = (String)detalle.getValueAt(renglon, 1); Double cantidad = (Double)detalle.getValueAt(renglon, 2); Double precio = (Double)detalle.getValueAt(renglon, 3); // "%10.2f" despliega un flotante con 10 cifras y 2 decimales y // justificación a la derecha. // "%30s" despliega un texto en 30 espacios y justificación a // la derecha. // "%.2f" despliega un flotante con 2 decimales. imprime(salida, "%10.2f|%30s|$%.2f", cantidad, descripcion, precio);

total += cantidad * precio; } imprime(salida, "Total: %.2f", total); salida.close(); // Realiza la impresión del archivo "salida.txt". PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet(); PrinterJob pj = PrinterJob.getPrinterJob(); if(pj.printDialog(aset)) { FileInputStream textStream = new FileInputStream("salida.txt"); DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE; Doc myDoc = new SimpleDoc(textStream, flavor, null); DocPrintJob job = pj.getPrintService().createPrintJob(); job.print(myDoc, aset); } }

public void imprime(PrintWriter salida, String texto, Object ... datos) { salida.println(String.format(texto, datos)); }}

80

Page 87: Tutorial Java

7.3.9. Código de “f rmLogin.java”.1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162

/** * Una clase para controlar el acceso a bases de datos */import javax.swing.*;import java.awt.*;import java.awt.event.*;import java.util.*;

/** * Clase de acceso a la aplicación. JDialog representa cuadros de diálogo. */public class frmLogin extends JDialog { private static final long serialVersionUID = 1L; /** * Esta tabla de búsqueda se usar? para almacenar parejas del tipo * <<nombre - URL>>. El nombre de un URL puede ser difícil de * recordar. Mejor lo asociamos con un nombre corto, más representativo * y por lo mismo más fácil de recordar. */ private static LinkedHashMap<String, String> basesDeDatos = new LinkedHashMap<String, String>(); private GridBagPanel panel = new GridBagPanel(); private JLabel lblUsuario = new JLabel("Usuario: "); private JTextField txtUsuario = new JTextField(10); private JLabel lblPassword = new JLabel("Password: "); private JPasswordField txtPassword = new JPasswordField(10); private JLabel lblBaseDeDatos = new JLabel("Base de datos: "); private JComboBox cmbBaseDeDatos = new JComboBox(); private JButton btnConectar = new JButton("Conectar"); private JButton btnCancelar = new JButton("Cancelar");

private ctrlLogin control = new ctrlLogin();

public frmLogin() { // Aquí se invoca el constructor de la clase padre. En este caso // JDialog. El parámetro null indica el frame a bloquear. El // segundo es el texto de la barra de título y finalmente se // usa "true" para indicar que es "modal" y "false" para indicar // que es "no modal". super((JFrame)null, "Login", true); configuraComponentes(); agregaEventos(); panel.add(0,0,1,1, lblUsuario); panel.add(0,1,1,1, txtUsuario); panel.add(1,0,1,1, lblPassword); panel.add(1,1,1,1, txtPassword); panel.add(2,0,1,1, lblBaseDeDatos); panel.add(2,1,1,1, cmbBaseDeDatos); panel.add(3,0,1,1, btnConectar); panel.add(3,1,1,1, btnCancelar); // No hace nada al oprimir el botón para cerrar en la barra de // título setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);

add(new JScrollPane(panel)); pack(); }

81

Page 88: Tutorial Java

63646566676869707172737475767778798081828384858687888990919293949596979899

100101102103104105106107108

public static void registra(String nombre, String url) { basesDeDatos.put(nombre, url); } void configuraComponentes() { cmbBaseDeDatos.removeAllItems(); for (String s: basesDeDatos.keySet()) { cmbBaseDeDatos.addItem(s); } } void agregaEventos() { btnCancelar.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { clickEnCancelar(); } }); btnConectar.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { clickEnConectar(); } }); } public void clickEnCancelar() { System.exit(0); } public void clickEnConectar() { String bd = cmbBaseDeDatos.getSelectedItem().toString(); String url = basesDeDatos.get(bd); String usuario = txtUsuario.getText(); String password = new String(txtPassword.getPassword()); try { String rol = control.obtenRol(url, usuario, password); dispose(); // Cierra el cuadro de di?logo. frmMenu menu = new frmMenu(rol); } catch (Exception e) { muestraMensaje(e.getMessage()); } } public void muestraMensaje(String mensaje) { JOptionPane.showMessageDialog(null, mensaje); }

82

Page 89: Tutorial Java

109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171

/** * Muestra una imagen de presentación durante el tiempo especificado. * @param nombre Nombre de la imagen a presentar. * @param tiempo Tiempo en milisegundos que se mostrar? la imagen. */ public static void showSplash(String nombre, int tiempo) { JFrame d = new JFrame(); d.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); // El frame no lleva barra de t?tulo ni m?rgenes. d.setUndecorated(true); d.add(new JLabel(new ImageIcon(nombre))); d.pack(); // Obtiene la resoluci?n del monitor. Dimension max = Toolkit.getDefaultToolkit().getScreenSize(); Dimension t = d.getSize(); d.setLocation((max.width / 2) - (t.width / 2), (max.height / 2) - (t.height / 2)); d.setVisible(true); try { // Suspende la ejecuci?n de la aplicaci?n durante el tiempo // indicado. Thread.sleep(tiempo); } catch(InterruptedException e) {} d.dispose(); } public static void main(String[] args) { // Si quitas los comentarios a las lineas 102 - 105 la apariencia // de la aplicación cambiar? y se ver? como si fuera nativa de tu // sistema operativo. VALE LA PENA QUE HAGAS LA PRUEBA. // try { // UIManager.setLookAndFeel( // UIManager.getSystemLookAndFeelClassName()); // } catch (Exception e) {} showSplash("portada.jpg", 5000); try { // Esta aplicaci?n funciona con MySQL o con Oracle. Class.forName("com.mysql.jdbc.Driver"); Class.forName("oracle.jdbc.OracleDriver"); // Registra los diferentes URL a los que puede comunicarse tu // aplicación. Esto evita que tengas que modificarla y // recompilarla para cambiar la base de datos. El primer // par?metro es un nombre corto que se despliega en el cuadro // de login en vez del URL para que no tengas que aprendértelo. frmLogin.registra("MySQL", "jdbc:mysql://localhost/test"); frmLogin.registra("MySQL Remoto", "jdbc:mysql://192.168.7.251/test"); frmLogin.registra("Oracle", "jdbc:mysql://192.168.7.251/test"); frmLogin login = new frmLogin(); // Los cuadros de di?logo se abren con setVisible(true): login.setVisible(true); } catch (Exception e) { e.printStackTrace(); } }}

83

Page 90: Tutorial Java

7.3.10. Código de “c trlLogin.java”.123456789101112131415161718192021222324252627282930313233343536373839404142434445464748

import java.sql.*;import java.util.*;

public class ctrlLogin { private static String url; private static String usuario; private static String password; public String obtenRol(String pUrl, String pUsuario, String pPassword) throws Exception { guarda(pUrl, pUsuario, pPassword); Connection conexion = conecta(); PreparedStatement ps = conexion.prepareStatement( "SELECT usu_rol FROM usuario WHERE usu_nombre = ?"); ps.setString(1, usuario); ResultSet rs = ps.executeQuery(); String rol = null; if (rs.next()) { rol = rs.getString("usu_rol"); } rs.close(); validaRol(conexion, rol); conexion.close(); return rol; } public void guarda(String pUrl, String pUsuario, String pPassword) { url = pUrl; usuario = pUsuario; password = pPassword; } public static Connection conecta() throws SQLException { Connection conexion = DriverManager.getConnection(url, usuario, password); conexion.setTransactionIsolation( Connection.TRANSACTION_SERIALIZABLE); return conexion; } void validaRol(Connection conexion, String rol) throws Exception { if (rol == null) { conexion.close(); throw new Exception("Usuario Incorrecto."); } }}

84

Page 91: Tutorial Java

7.3.11. Código de “f rmMenu.java”.1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859

import javax.swing.*;import java.awt.*;import java.awt.event.*;

public class frmMenu extends JFrame { private static final long serialVersionUID = 1L; private JMenuBar menuBar = new JMenuBar(); private JDesktopPane desktop = new JDesktopPane();

private frmFactura factura = new frmFactura(); private frmClientes clientes = new frmClientes(); private frmProductos reporte = new frmProductos(); public frmMenu(String rol) { super("Facturaci?n"); configuraFrame(); desktop.add(factura); desktop.add(clientes); desktop.add(reporte); // Dependiendo del Rol cambia la barra de men?. if (rol.equals("VENDEDOR")) { menuDeVendedor(); } else if (rol.equals("SUPERVISOR")) { menuDeSupervisor(); } setVisible(true); }

public void menuDeVendedor() { menuArchivo(); menuFacturacion(); menuBar.add(Box.createHorizontalGlue()); menuAyuda(); }

public void menuDeSupervisor() { menuArchivo(); menuSupervisor(); menuBar.add(Box.createHorizontalGlue()); menuAyuda(); }

public void menuArchivo() { JMenu archivo = addMenu("Archivo", "icono.jpg", KeyEvent.VK_A); JMenuItem salir = addItem(archivo, "Salir", "icono.jpg", KeyEvent.VK_S, KeyEvent.VK_S); salir.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { clickEnSalir(); } }); }

public void clickEnSalir() { System.exit(0); }

85

Page 92: Tutorial Java

60616263646566676869707172737475767778798081828384858687888990919293949596979899

100101102103104105106107108109110111112113114115116117118119120121122123124

public void menuSupervisor() { JMenu supervisor = addMenu("Supervisor","icono.jpg",KeyEvent.VK_S); JMenuItem catalogoDeClientes = addItem(supervisor, "Catalogo de Clientes...", "icono.jpg", KeyEvent.VK_C, KeyEvent.VK_C); JMenuItem reporteDeProductos = addItem(supervisor, "Reporte de Productos...", "icono.jpg", KeyEvent.VK_R, KeyEvent.VK_R); catalogoDeClientes.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { clickEnCatalogoDeClientes(); } }); reporteDeProductos.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { clickEnReporteDeProductos(); } }); }

public void clickEnCatalogoDeClientes() { if (clientes.isClosed()) { clientes.init(); } showFrame(clientes); }

public void clickEnReporteDeProductos() { if (reporte.isClosed()) { reporte.init(); } showFrame(reporte); }

public void menuFacturacion() { JMenu facturacion = addMenu("Facturacion","icono.jpg",KeyEvent.VK_F); JMenuItem facturar = addItem(facturacion, "Facturar...", "icono.jpg", KeyEvent.VK_F, KeyEvent.VK_F); facturar.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { clickEnFacturar(); } }); }

public void clickEnFacturar() { if (factura.isClosed()) { factura.init(); } showFrame(factura); }

public void menuAyuda() { JMenu ayuda = addMenu("Ayuda", "icono.jpg", KeyEvent.VK_Y); JMenuItem acercaDe = addItem(ayuda,"Acerca De...", "icono.jpg", KeyEvent.VK_A, KeyEvent.VK_A); acercaDe.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { clickEnAcercaDe(); } }); }

86

Page 93: Tutorial Java

125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188

public void clickEnAcercaDe() { JOptionPane.showMessageDialog(null, "<html>Ejemplo de Menu<br>por: <i>Yo</i></html>"); }

public JMenu addMenu(String nombre, String icono, int nemonico) { JMenu menu = new JMenu(nombre); menu.setIcon(new ImageIcon(icono)); menu.setMnemonic(nemonico); menuBar.add(menu); return menu; }

public static JMenuItem addItem(JMenu menu, String texto, String icono, int nemonico, int acelerador) { JMenuItem item = new JMenuItem(texto, new ImageIcon(icono)); menu.add(item); item.setMnemonic(nemonico); item.setAccelerator(KeyStroke.getKeyStroke( acelerador, ActionEvent.CTRL_MASK)); return item; }

public static JMenu addSubMenu(JMenu menu, String texto, String icono, int nemonico) { JMenu submenu = new JMenu(texto); menu.add(submenu); submenu.setIcon(new ImageIcon(icono)); submenu.setMnemonic(nemonico); return submenu; }

public void showFrame(JInternalFrame frame) { try { if (frame.isClosed()) { frame.setLocation(0, 0); desktop.add(frame); frame.show(); } else if (frame.isVisible()) { frame.setSelected(true); } else { frame.show(); } } catch (java.beans.PropertyVetoException e) {} }

public void configuraFrame() { setContentPane(desktop); desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE); setJMenuBar(menuBar); desktop.setPreferredSize(new Dimension(600, 300)); desktop.setBackground(Color.WHITE); setIcono("icono.jpg"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); pack(); agregaImagenDeFondo("portada.jpg"); }

void setIcono(String nombre) { Image icono = Toolkit.getDefaultToolkit().getImage("icono.jpg"); setIconImage(icono); }

87

Page 94: Tutorial Java

189190191192193194195196197198199200201202

void agregaImagenDeFondo(String nombre) { ImageIcon imagen = new ImageIcon(nombre); JLabel label = new JLabel(imagen);// setExtendedState(JFrame.MAXIMIZED_BOTH);// Dimension max = Toolkit.getDefaultToolkit().getScreenSize(); Dimension max = desktop.getSize(); int iheight = imagen.getIconHeight(); int iwidth = imagen.getIconWidth(); label.setBounds((max.width / 2) - (iwidth / 2), (max.height / 2) - (iheight / 2), iwidth, iheight); desktop.add(label, new Integer(-1)); }}

7.4. Generación del Ejecutable.

7.4.1. Código de “m anifest.txt”.123

Main-Class: frmLoginClass-Path: (3)mysql-connector-java-3.0.11-stable-bin.jar (4)ojdbc14.jar

Este código se utiliza para crear el ejecutable de java. Si tienes el directorio de ejecutables de Java en turuta 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”.  Paraejecutar 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