Filtrar una tabla en JTable
Un alumno me pregunta cómo filtrar los datos de un JTable, siendo estos datos obtenidos de un query.
La mejor manera no es manipular el JTable a través de su cantidad de columnas, agregando filas, borrando algunas de ellas, modificando las celdas, etc. Eso es realmente un dolor de cabeza.
Recordemos que estamos trabajando en Java que es Orientado a Objetos.. no en VisualBasic.
Así que, si queremos manipular los datos de un JTable, debemos usar una clase que se encargue de manipular los datos, y que el jtable use esa clase.
La interfaz
Simplemente, debemos heredarla:
La clase que estamos creando debe tener un arreglo interno. Este arreglo es el resultado del query en la base de datos.
¿Por qué? Pues, los métodos que estamos implementado deben manipular ese arreglo. No la base de datos, ya que ese arreglo - como dije - es el resultado de un query en la base de datos.
Si se hace una búsqueda (filtrar por nombres por ejemplo), se debe hacer el query en la base de datos, y rehacer la lista. De tal manera que el jtable siempre tomara el valor del mismo modelo y este tiene la nueva lista.
Aquí dejo un ejemplo en NetBeans usando la base de datos TRAVEL. Se debe iniciar el java db del netbeans para que funcione.
El código fuente se encuentra aquí: http://diesil-java.googlecode.com/files/FiltroJTable.tar.gz
La mejor manera no es manipular el JTable a través de su cantidad de columnas, agregando filas, borrando algunas de ellas, modificando las celdas, etc. Eso es realmente un dolor de cabeza.
Recordemos que estamos trabajando en Java que es Orientado a Objetos.. no en VisualBasic.
Así que, si queremos manipular los datos de un JTable, debemos usar una clase que se encargue de manipular los datos, y que el jtable use esa clase.
La interfaz
TableModel
es la indicada. Pero tiene demasiados métodos a implementar. Así que usaremos algo ya casi hecho. Se llama la clase abstracta AbstractTableModel
.Simplemente, debemos heredarla:
public class PersonasTableModel extends AbstractTableModel {....
Y con eso debemos implementar tres métodos: getRowCount()
, getColumnCount()
y getValueAt(int rowIndex, int columnIndex)
.La clase que estamos creando debe tener un arreglo interno. Este arreglo es el resultado del query en la base de datos.
//... private List personas = new ArrayList();//...
¿Por qué? Pues, los métodos que estamos implementado deben manipular ese arreglo. No la base de datos, ya que ese arreglo - como dije - es el resultado de un query en la base de datos.
Si se hace una búsqueda (filtrar por nombres por ejemplo), se debe hacer el query en la base de datos, y rehacer la lista. De tal manera que el jtable siempre tomara el valor del mismo modelo y este tiene la nueva lista.
Aquí dejo un ejemplo en NetBeans usando la base de datos TRAVEL. Se debe iniciar el java db del netbeans para que funcione.
El código fuente se encuentra aquí: http://diesil-java.googlecode.com/files/FiltroJTable.tar.gz
¬¬
ResponderBorrarHola amigo como andas..?
ResponderBorrarPrimero que nada gracias por hacer estos post que ayudan mucho a la gente como yo...
Pero quiero sabes si me podes ayudar a terminar el codigo que hice...
lo que quiero haces es practicamente lo que vos hiciste....
mediante un txtfield y un boton filtar mediante una consulta y traes los resultados que se adecuan con la busqueda...
te muestro lo que hice y despues me contas....
a continuacion el metodo que llamo para que arme la tabla en base a la consulta
..........................
public JTable rellenarTabla(String consulta, int nroColum, String[] NombreColumnas){
try {
modelo = new DefaultTableModel() {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
public boolean isCellEditable(int fila, int columna) {
return false; //Con esto conseguimos que la tabla no se pueda editar
}
};
tabla = new JTable(modelo); //Metemos el modelo dentro de la tabla
for(String unaColumna: NombreColumnas){
modelo.addColumn(unaColumna); //Añadimos las columnas a la tabla (tantas como queramos)
}
TableRowSorter sorter= new TableRowSorter(modelo);
tabla.setRowSorter(sorter);
Conectar();
PreparedStatement pstmt = conn.prepareStatement(consulta); //con es la conexión que hemos creado antes con el patrón singleton
System.out.println(consulta);
ResultSet rs=pstmt.executeQuery();
while(rs.next()){
Object[] fila = new Object[nroColum];//Creamos un Objeto con tantos parámetros como datos retorne cada fila
// de la consulta
for(int i=0; i < nroColum; i++){
fila[i] = rs.getString(NombreColumnas[i]); //Lo que hay entre comillas son los campos de la base de datos
}
modelo.addRow(fila); // Añade una fila al final del modelo de la tabla
}
tabla.updateUI();//Actualiza la tabla
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return tabla;
}
---------------------------------------------------------------
ahi termina el metodo, ahora te muestro como lo llamo y los parametro que le paso
para que se arme solo...
.--------------------------------
DiseniaTabla dt= new DiseniaTabla();
String[] nombreCol= {"MATRICULA", "APELLIDO","NOMBRE","DIRECC","TEL_PART","TEL_MOVIL"};
JTable jTableProfesional=dt.rellenarTabla("SELECT * FROM profesional", 6, nombreCol );
la tabla funciona perfecto cuando hace un select de toda la base...
el problema surge cuando recibe un parametro, por ejemplo de un txtfield
la consulta la hace bien, pero el jtable ni se entera, no hace nada....
----------------------------------------------------------------------------
jButton1.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent evt) {
String busqueda = busquedaProf.getText();
DiseniaTabla dt= new DiseniaTabla();
String[] nombreCol= {"MATRICULA", "APELLIDO","NOMBRE","DIRECC","TEL_PART","TEL_MOVIL"};
JTable jTableProfesional=dt.rellenarTabla("SELECT * FROM profesional WHERE \"NOMBRE\" like '%" + busqueda + "%' ", 6, nombreCol);
}
});
ahi llamo al metodo pero filtrando por lo que me escriben en el txtfield
se ejecuta cuando apreto el boton buscar...
Espero que me puedas ayudar...
Vi tu post pero la verdad que no lo entiendo mucho....
Saludosç
diego