domingo, 25 de septiembre de 2016

054.- La Clase JTable - Ordenación Y Cálculos - Java Y NetBeans

ORDENACIÓN Y CÁLCULOS:

Se van a añadir ciertas mejoras al programa que se viene realizando en las últimas entradas de este blog. En este post programaremos ciertas opciones de ordenación así como realizaremos determinados cálculos sobre la tabla Trabajadores.



EJERCICIO GUIADO Nº 1

  1. Abrir la aplicación de la publicación anterior.

  1. Vamos a modificar el cuadro de diálogo de filtrado de forma que no sólo sea capaz de filtrar, sino que también permita que el listado que se ha filtrado aparezca ordenado según un campo.

Para ello, añade lo siguiente al diálogo de filtrado:


El combo cboCamposOrdenacion contendrá los siguientes elementos: (Sin Ordenación), DNI, Nombres, Apellidos, Sueldo, Fecha_Entrada, Placa:

 


Es necesario añadir un ButtonGroup al programa, al que llamaremos grupoOrdenacion. Los botones de opción radioAsc y radioDesc deben pertenecer a dicho grupo.



  1. La idea es la siguiente. Cuando el usuario quiera hacer un filtrado podrá indicar que el listado aparezca ordenado por algún campo, seleccionándolo en el combo de ordenación. También puede indicar la forma de ordenación (ascendente o descendente) a través de los botones de opción.

Al pulsar Aceptar el listado de trabajadores no solo saldrá filtrado, sino que también saldrá ordenado.

Para ello tendremos que realizar modificaciones en el código del botón Aceptar. Añade el siguiente código en el evento actionPerformed del botón Aceptar (justo antes de la ejecución de la consulta):



Estudiemos el código. Lo primero que se hace es extraer el valor seleccionado del combo cboCamposOrdenacion.

Si este combo no contiene el valor “(Sin Ordenación)” significará que se desea realizar una ordenación por el campo seleccionado. Así pues se concatena a la variable sql la cláusula ORDER BY con el campo que se ha seleccionado en el combo.

Luego se añade a la consulta sql la forma de ordenación teniendo en cuenta el botón de opción que esté activado, y según esto, se añade la cadena “ASC” o “DESC” para ordenar ascendentemente o descendentemente.

  1. Ejecuta el programa y prueba a hacer un filtrado eligiendo un campo para ordenar y observa el resultado:



  1. Una ventaja de esto es que se puede mostrar el listado completo de trabajadores ordenado por el campo que se quiera siempre y cuando no se indique ninguna condición:




  1. Ahora vamos a añadir una nueva mejora al programa. La idea es que se visualice junto al JTable de trabajadores los siguientes datos: el número de trabajadores que se muestra y el promedio de los sueldos.

Para ello, añade las siguientes modificaciones en el diseño de la ventana principal:



  1. Ahora programaremos un método que sea capaz de calcular el número de trabajadores y el sueldo promedio a partir del contenido de un ResultSet.

Este método recibirá un ResultSet como parámetro, y lo que hará será analizar el contenido de este ResultSet para calcular y luego mostrar el número de trabajadores y el sueldo promedio.

Accede al código del programa y añade el siguiente método:



Este código básicamente toma el ResultSet pasado como parámetro y lo recorre aumentando en uno la variable nroTrabajadores cada vez que se pasa al siguiente trabajador.
Por otro lado se calcula la suma de los sueldos de los trabajadores del ResultSet.

Una vez terminado el bucle solo hay que dividir la suma de los sueldos entre el número de trabajadores para obtener el sueldo promedio, y estos datos se colocan en las etiquetas correspondientes.


  1. Interesa que cada vez que se muestren todos los trabajadores en el JTable se realicen estos cálculos, así pues debe añadir la siguiente línea en el método mostrarTodosLosTrabajadores:


Esa línea es una llamada al método que acabamos de programar, y hará que después de que se presenten en el JTable todos los trabajadores se rellenen las etiquetas de los cálculos.


  1. También interesa que cuando se realice un filtrado aparezca el número de trabajadores y el sueldo promedio correspondiente al listado que se acaba de filtrar. Para ello debes añadir la siguiente línea al código del botón Aceptar del cuadro de diálogo de filtrado:


De nuevo se hace una llamada al método realizarCalculos justamente después de colocar en la tabla el listado de trabajadores, en este caso una lista filtrada.


  1. Ejecuta el programa y observa como al iniciar el programa ya aparecen en las etiquetas los cálculos (ya que el método constructor llama al método mostrarTodosLosTrabajadores que a su vez llama al método realizarCalculos).

También puedes comprobar como al hacer un filtrado se muestran los cálculos correspondientes al listado filtrado, ya que en el botón Aceptar del dialogo de filtrado se hace una llamada al método realizarCalculos.





CONCLUSIONES:

Todo programa de gestión de datos de una tabla debería tener opciones de ordenación para mostrar los datos de la tabla ordenados como el usuario desee.

La opción de ordenación puede estar situada junto a las opciones de filtrado para permitir de esta manera que los filtrados aparezcan ordenados según le interese al usuario.

Suele ser habitual que al lado del JTable aparezcan ciertos cálculos estadísticos relativos a los registros mostrados en la tabla.

sábado, 24 de septiembre de 2016

053.- La Clase JTable - Filtrados - Java Y NetBeans

Filtrados sobre una tabla:

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
  1. Abrir la aplicación de la publicación anterior.
  2. Primero debes añadir un botón btnFiltrarTrabajadores a la ventana:



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



  1. 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:



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


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


  1. Ejecuta el programa para ver el funcionamiento de este botón:



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


  1. 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.).



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



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


  1. 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”.


  1. 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: =, >, <, >=, <=, <>.


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


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


  1. 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).



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


  1. 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:



  1. 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:



  1. 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:




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


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


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