Una funcionalidad muy utilizada cuando se desarrollan aplicaciones de gestión es la de formulario maestro-detalle. Un formulario de este tipo realmente está compuesto por dos: maestro y detalle. De tal forma que al introducir los datos de búsqueda en el formulario principal aparecen en el formulario detalle los datos asociados a los primeros.
Por ejemplo, en el formulario principal podemos tener un campo de texto para introducir el DNI y mostrar en el formulario detalle el listado de productos comprados por esa persona.
¿Y como se hace esto en Java? Muy sencillo. Creamos una serie de elementos gráficos que harán las veces de formulario principal (JTextField, JComboBox, etc.) e incluimos debajo de este una tabla donde aparecerán los distintos registros asociados a la búsqueda.
Como no podía ser de otro modo la clase que implementa en Java la tabla es JTable. Mucho hay escrito sobre el manejo de la misma (por ejemplo, aquí, aquí o aquí) por lo que sólo me voy a centrar en cómo «rellenarla» con datos.
Si le has echado un vistazo a los enlaces anteriores habrás visto que asociado al concepto de Tabla está el de Modelo de tabla (del inglés Table Model). Resumiendo, un modelo no es más que una manera de simplificar el acceso a contenido tabular (la típica tabla de datos). De esta manera la tabla queda independiente de la forma en la que se guardan los datos. Como se puede observar en la siguiente imagen JTable no tiene ni idea de la clase que implementa la interfaz TableModel. Lo único que le interesa es que alguien le proporcione los datos, y para ello invoca los métodos de la interfaz que estarán implementados en alguna de las subclases.
¿Qué vamos a hacer nosotros? Pues muy fácil, crear una subclase de DefaultTableModel y sobreescribir los métodos necesarios para que devuelva los datos que nosotros tenemos guardados en un ArrayList. La JTable invocará los métodos que necesite para mostrar los datos pero no se ejecutará la implementación de DefaultTableModel si no el código que nosotros hemos realizado. La estructura de clases quedará de la siguiente forma:
Para que el ejemplo quede un poco más «interesante» he creado una interfaz gráfica donde se muestra un JComboBox con un listado de clientes; de tal forma que al seleccionar uno de ellos se muestren las ventas realizadas por él. Para guardar el listado de ventas de cada cliente se ha utilizado una tabla hash donde cada entrada (identificada por el DNI) contiene un ArrayList con objetos de la clase Venta.
Una vez que sabemos donde guardar el listado de ventas de un cliente ya sólo nos queda mostrarlo en la tabla. Como se ha comentado anteriormente lo único que tenemos que hacer es sobreescribir una serie de métodos de DefaultTableModel en MiTableModel. Veamos cuales:
getColumnCount: nos devuelve el número de columnas del modelo. Ya que el listado de columnas está definido en el array nombreColumnas en la VentanaPrincipal, sólo tendremos que obtener el tamaño de este.
getColumnName(int column): nos devuelve el nombre de una columna. Para obtenerlo sólo tenemos que recuperar del array nombreColumnas el valor de la posición indicada por parámetro ‘column’.
getRowCount: devuelve el número de filas del modelo, que en este caso se corresponden con el listado de ventas del cliente. Dicho listado se encuentra en la tabla hash listadoVentasCliente en la VentanaPrincipal.
getValueAt(int row, int column): devuelve el valor para una celda en concreto identificada por su fila y columna. La primera es la posición row dentro del listado de ventas del cliente y la segunda es el valor de uno de los atributos del objeto Venta.
isCellEditable: devuelve false siempre. Esto hace que la celda no sea editable.
El código comentado de la clase MiTableModel se encuentra dentro del proyecto Eclipse que os dejo en Rellenar Tabla.
La estructura de clases ha quedado de la siguiente forma.
He utilizado la versión 1.6 de Java.