En el post anterior se
realizó una pequeña aplicación de base de datos que permitía realizar altas, bajas y modificaciones
sobre la tabla Trabajadores de
la base de datos AMANUVA.
En todo momento se mostraba
en un JTable el listado de trabajadores de la empresa.
La eliminación y
modificación de un trabajador se podía realizar simplemente haciendo clic sobre
la fila del trabajador correspondiente en el JTable y luego activando el botón Eliminar Trabajador o Modificar Trabajador.
Sin embargo, en el momento
en que tengamos una gran cantidad de trabajadores almacenados en la tabla,
puede resultar un poco complicado encontrar al trabajador en concreto que se
quiere eliminar o modificar.
Aparte, puede ser necesario
a veces ver solo determinados registros de la tabla y no toda la tabla entera.
Se hace necesario pues
añadir al programa ciertas opciones de filtrado que nos permitan visualizar en
el JTable solo aquellos registros que más nos interesen.
En esta entrada se mejorará
el programa del post anterior de forma que permita al usuario ciertas opciones
de filtrado.
EJERCICIO GUIADO Nº 1
- Abrir la aplicación de
la publicación anterior.
- Primero debes añadir
un botón btnFiltrarTrabajadores a
la ventana:
- Al pulsar este botón
aparecerá un cuadro de diálogo que contenga opciones de filtrado, de forma
que el usuario pueda decidir qué trabajadores quiere ver.
Por lo tanto, tendrá que
añadir un nuevo cuadro de diálogo (JDialog) y asígnele el nombre dialogoFiltrarTrabajadores.
- Haz doble clic sobre
este diálogo y diséñalo de la siguiente forma:
NOTA: Los dos combos del
cuadro de diálogo deben contener los siguientes elementos:
= >
< >= <=
<>
Es decir, cuando se
desplieguen aparecerá esto:
- La idea es la
siguiente. Cuando el usuario pulse el botón Filtrar Trabajadores, se mostrará este cuadro de
diálogo. Entonces el usuario introducirá las condiciones de búsqueda y
pulsará Aceptar, y
entonces se visualizarán en el JTable aquellos registros que cumplan las
condiciones.
Si el usuario pulsa el
botón Ver Todos, entonces se
mostrarán en el JTable todos los trabajadores.
Si el usuario pulsa el
botón Cancelar, entonces el
cuadro de diálogo de filtrado se cierra sin más.
- Empezaremos programando
el botón Filtrar Trabajadores
de la ventana principal. Escriba en su evento ActionPerformed el
siguiente código:
Lo que hace este código es
asignar un tamaño al cuadro de diálogo, configurarlo como modal, y finalmente
presentarlo en pantalla.
- Ejecuta el programa para
ver el funcionamiento de este botón:
- Programemos ahora el
botón Cancelar del
cuadro de diálogo de filtrado. La programación de este botón es muy
sencilla:
Como puede ver consiste simplemente en cerrar el cuadro de
diálogo de filtrado.
- Se programará ahora el
botón Aceptar, pero
antes, es necesario entender como funcionará el cuadro de diálogo de
filtrado.
El usuario introducirá los
datos que quiere buscar. Ten en cuenta que no tiene por qué rellenar todas las
casillas. Además, puede hacer uso de los combos asignados a los campos sueldo
y fecha.
Por ejemplo, supongamos que el usuario introdujera los siguientes datos:
Si en este momento el
usuario pulsara el botón Aceptar,
se tendrían que mostrar aquellos trabajadores que cumplan todas las siguientes
condiciones: que tengan en su nombre al palabra JULIO, que ganen más o igual a 6000 soles
de sueldo y que conduzcan un auto cuya placa contenga la cadena “3”.
Las casillas que estén
vacías no se tendrán en cuenta a la hora de hacer el filtrado.
Si el usuario introduce una
cadena en un campo de tipo texto, se buscará a todos aquellos trabajadores que
contengan dicha cadena. Por ejemplo, si introduce “JUAN” en el nombre, el
programa buscará a los trabajadores cuyo nombre contenga la palabra “JUAN”. De
esta manera la búsqueda será mucho más cómoda, al no tener que introducir el
texto completo, y producirá más resultados (se encontrarán a los que se llamen
“JUAN”, “JUAN ANTONIO”,”JUANA”, etc.).
- El botón Aceptar tendrá que
construir una consulta SELECT que incluya estas condiciones, y luego
ejecutarla. Finalmente tendrá que mostrar el resultado de la consulta en
el JTable.
El código de este botón
será largo, así que veamos poco a poco como programarlo. Empiece programando lo
siguiente en el evento ActionPerformed del botón Aceptar:
Como puede ver, empezamos recogiendo el contenido de
los cuadros de texto en distintas variables. También recogemos los valores
seleccionados en los combos del sueldo y fecha.
En el caso de la fecha, recogemos de los cuadros de
texto el día, mes y año y los concatenamos para formar una fecha que el SQL
Server pueda aceptar: día/mes/año.
- Siga programando en el
botón Aceptar de la
siguiente forma:
Es necesario estudiar muy
detenidamente el código que tenemos programado hasta ahora antes de continuar.
Se han añadido dos
variables:
-
La
variable sql es una variable
de cadena que contendrá la instrucción SELECT que efectuará el filtrado (la
consulta).
-
La
variable nroCond (número
de condiciones) es una variable numérica que va contando cuantas condiciones hay.
Ten en cuenta que habrá una condición cada vez que un cuadro de texto esté
relleno con algún dato.
Esta variable es muy
importante, ya que nos permite saber si tenemos que concatenar una condición
con “WHERE” o con “AND”. Ten en cuenta que la primera condición que se añade
vendrá precedida por “WHERE”, pero las demás estarán precedidas por “AND”.
La primera condición que se
añade a la instrucción SELECT tendrá que tener esta forma (en rojo):
SELECT *
FROM Trabajadores WHERE condicion1
La condición 2, condición 3, etc. llevan el “AND”
delante. Por ejemplo, la segunda condición tendría esta forma (en azul):
SELECT *
FROM Trabajadores WHERE condicion1
AND condicion2
Si añadiéramos una tercera condición también llevaría el “AND”
(en verde):
SELECT *
FROM Trabajadores WHERE condicion1
AND condicion2 AND condicion3
Etc.
Resumiendo, la primera condición vendrá antecedida de
“WHERE”, mientras que el resto de las condiciones vendrán antecedidas del “AND”.
Si se observa el código añadido
al final del método, en él se empieza construyendo el comienzo de la consulta
SELECT: “SELECT * FROM Trabajadores”
y luego se añaden condiciones según si el cuadro de texto correspondiente está
vacío o no.
Cada vez que se encuentra
un cuadro de texto no vacío, se añade una condición y se aumenta en 1 el
contador de condiciones, es decir, la variable nroCond.
Observa como cuando se
añade una condición, se comprueba con un if el número de condiciones (nroCond) para saber si hay que
concatenar la condición con el “WHERE” o con el “AND”.
Debes observar también como
nos decantamos por el uso de LIKE ya que este es más versátil. Y se recuerda
una vez más que cuando usemos LIKE desde java usaremos el símbolo tanto por
ciento (%).
Estudia bien este código
para entenderlo. Solo se ha indicado las posibles condiciones para el campo dni
y para el campo nombres. Sin embargo será necesario añadir más if
para el resto de los campos.
- Añade al final del
código anterior el siguiente código:
Este código comprueba si hay algún dato en el cuadro
de texto apellidos, y, si es así, entonces crea una condición para filtrar por
apellidos.
Se incrementa el contador
de condiciones en uno y si estamos ante la primera condición esta se concatena
usando “WHERE”, y si no, esta se concatena usando “AND”.
- Añada al final del
código anterior el siguiente código:
Este es el código que añade una condición para el
sueldo (suponiendo que haya algún dato en el cuadro de texto del sueldo).
Como en los casos
anteriores, se suma uno al contador de condiciones y, si estamos ante la
primera condición se concatena con “WHERE”, y sino, se concatena con “AND”.
Hay que destacar aquí que,
al ser el sueldo un campo numérico, no se usa LIKE, sino que se usa el operador
que el usuario haya escogido dentro del combo del sueldo. Recuerda que ese
operador puede ser uno de los siguientes: =, >, <, >=, <=, <>.
- Añada al final del
código anterior el siguiente código:
Este es el código que añade una condición para la
fecha (suponiendo que haya algún dato en los cuadros de texto correspondientes
a la fecha).
Aquí hay que tener en cuenta que los valores de los
cuadros de texto del día, mes y año se concatenan dentro de una variable fec usando la /
como separador. Si los cuadros de texto del día, mes y año estuvieran vacíos,
la variable fec contendría
la cadena “//”. Por eso preguntamos si la variable fec es distinta de “//” para saber si es necesario
añadir una condición para el campo fecha_entrada.
Como en los casos
anteriores, se suma uno al contador de condiciones y se comprueba si estamos
ante la primera condición. En este caso se concatena la condición usando “WHERE”
y en caso contrario se concatena la condición usando “AND”.
Observa que para crear la
condición se usa el operador que el usuario haya elegido en el combo de la
fecha, el cual puede ser uno de los siguientes: =, >, <, >=, <=, <>.
Ya que la variable fec
es de tipo String hay que ponerla
entre apóstrofos o comillas simples en la condición.
- Añada el siguiente
código al final del código anterior.
En este caso tenemos la construcción de la condición
correspondiente a la placa del auto del trabajador. Por supuesto, esta
condición solo se construye si se ha escrito algo en el cuadro de texto de la placa.
Como en los casos
anteriores se suma uno al contador de condiciones y si estamos ante la primera
condición entonces la condición se construirá usando “WHERE”, y en caso
contrario añadiremos esta condición usando “AND”.
Como en los demás campos de
tipo texto, para construir esta condición se ha preferido usar LIKE junto con
los %, que da más posibilidades de búsqueda.
- El resultado final de
todo este largo código es que la variable sql contendrá una instrucción SELECT que realizará un
filtrado sobre la tabla Trabajadores
de la base de datos de forma que se extraigan a los trabajadores que cumplan
las condiciones indicadas por el usuario en el cuadro de diálogo de
filtrado.
Lo que hay que hacer ahora
es ejecutar dicha instrucción SELECT. Y como ya sabe, esto se hace a través del
objeto sentencia. Programe lo
siguiente a continuación del código anterior:
En este código se ejecuta
la consulta creada y el resultado se introduce en un ResultSet rs.
Ahora hay que mostrar el
contenido del ResultSet rs en el JTable de la ventana
principal.
Como ve, el código da un
error. Esto es debido a que es obligatorio rodear el código con un try...catch,
ya que es susceptible de error. (Esto lo haremos más adelante).
- Ahora mostraremos el ResultSet rs en el JTable, así
que añada el siguiente código a continuación:
Este código ya debe
resultar conocido, ya que se usó también en el método mostrarTodosLosTrabajadores, encargado de mostrar toda la
tabla Trabajadores en el
JTable.
Si observa este código verá
que lo que hace es definir un vector de encabezados para el JTable. A partir de
este vector de encabezados se crea el modelo del JTable (DefaultTableModel).
Posteriormente se construye
un vector vacío de seis elementos llamado fila. A continuación se ubica la
posición del puntero del ResultSet antes de la primera fila usando el método beforeFirst.
Luego se recorre el ResultSet
rs,
que contiene ahora mismo el resultado del filtrado realizado, y se extrae cada
fila almacenándola en el vector llamado fila.
Cada fila extraída se
introduce en el modelo detamo de la tabla.
Finalmente cuando se han
traspasado todas las filas desde el ResultSet rs al modelo detamo,
se asigna dicho modelo al JTable. Esto quiere decir que el JTable debería
mostrar ya el resultado del filtrado.
La razón de que aparezcan
tantos errores es porque aún no hemos añadido el try...catch. Esto lo
haremos al final.
- El código programado
hasta ahora analiza los datos introducidos en el cuadro de diálogo de
filtrado y construye una consulta SELECT que extrae los trabajadores que
cumplan las condiciones indicadas. Estos datos se muestran finalmente en
un JTable. Lo único que queda por hacer es cerrar el cuadro de diálogo.
Añade por tanto el
siguiente código:
- Todo el código
programado en el botón Aceptar
es bastante delicado y pude dar gran cantidad de errores, por lo que será
necesario rodearlo dentro de un try...catch:
- El código que se acaba
de programar es un poco enrevesado y largo, pero le da al programa una
potencia tremenda, ya que permite al usuario realizar fácilmente búsquedas
y filtrados en la tabla Trabajadores.
Ejecuta el programa y haz
lo siguiente:
- Como habrás podido
observar en este ejemplo, se pueden realizar búsquedas en la tabla Trabajadores
gracias al código programado. Esto es muy útil sobre todo en el momento en
que la tabla contenga muchos registros.
Prueba a ejecutar más veces
el programa y realice varios filtrados.
- Solo queda por
programar el botón Ver Todos
del cuadro de diálogo de filtrado. Al pulsar este botón se pretende
que se visualicen todos los registros de la tabla Trabajadores. El código de este botón es bastante
sencillo:
Como ves aprovechamos el
método ya programado mostrarTodosLosTrabajadores
que se encarga de mostrar todos los trabajadores en el JTable. Luego sólo
tenemos que descargar el cuadro de diálogo de filtrado.
- Ejecuta el programa y prueba
lo siguiente:
- Haz
el filtrado que quieras sobre la tabla Trabajadores. Acepta y observa el
filtrado en la tabla.
- Vuelve
a filtrar pero esta vez pulsa el botón Ver
Todos. Observarás como vuelven a verse todos los trabajadores en la
tabla.
Ejemplo:
CONCLUSIONES:
Las tablas que tengan muchos datos son incómodas de manejar, por lo que
resulta muy interesante añadir al programa ciertas opciones de filtrado. Estas opciones
permitirán visualizar solo aquellos registros que cumplan determinadas
condiciones.
Las opciones de filtrado consistirán básicamente en la construcción de
una consulta SELECT a través de concatenaciones de cadenas.
Una vez construida la cadena SELECT según el filtrado que quiera hacer
el usuario, se tendrá que ejecutar dicha consulta y se tendrá que mostrar el resultado.
Generalmente en un JTable.
Hola, tengo una gran duda, hay una manera de filtrar por intervalo de fechas? si sí la hay como sería el código?
ResponderBorrarmuchas gracias por todos tus aportes, espero puedas ayudarme con eso.
mucho éxito!!
Hola Dani:
Borrarpara realizar lo que deseas el código sería así en la cláusula WHERE:
WHERE fecha_analizada > fecha_1 AND fecha_analizada < fecha_2
fíjaque que con el AND obligamos a que los registros que devuelve la consulta estén en el intervalo de la fecha_1 y la fecha_2.