gentoo linux, java, software libre y otras hierbas
may, 02 2008 - 9:40 am

Consultar DB en Java – Mostrar resultados en un JTable

Siguiendo con nuestro tema de conexiones a bases de datos desde Java… Cuando estamos trabajando con bases de datos y aplicaciones que usen Swing, la manera más elegante de presentar los datos a un usuario es usando tablas usando la clase JTable.

tabla swing jdbc

Lo que haremos será básicamente crear una clase que herede de la clase AbstractTableModel:

Esta clase abstracta provee la implementación por defecto de la mayoría de los métodos en la interfaz TableModel. Para crear un TableModel como subclase de AbstractTableModel necesitarás implementar únicamente los sigientes tres métodos:

  public int getRowCount();  public int getColumnCount();public Object getValueAt(int row, int column);

Dicha clase administrará el contenido de nuestra tabla. Ten en cuenta que vamos a trabajar con la base de datos que hicimos aquí. Veamos entonces el código:

import java.sql.*;
import java.util.*;
import javax.swing.table.*;
// Las filas y columnas del objeto ResultSet se cuentan desde 1 y las filas
// y columnas del objeto JTable se cuentan desde 0. Al procesar filas
// o columnas del objeto ResultSet para usarlas en un objeto JTable, es
// necesario sumar 1 al número de fila o columnas para manipular la
// columna apropiada del objeto ResultSet (es decir, la columna 0 del objeto JTable
// es la columna 1 del objeto ResultSet y la fila 0 del objeto JTable es la fila 1 del objeto ResultSet).
public class ModeloTablaResultados extends AbstractTableModel {
    private Connection conexion;
    private Statement instruccion;
    private ResultSet conjuntoResultados;
    private ResultSetMetaData metaDatos;
    private int numeroDeFilas;
    // mantener el registro del estado de la conexión a la base de datos
    private boolean conectadoALaBaseDeDatos = false;
    // inicializar conjuntoResultados y obtener su objeto de meta datos;
    // determinar el número de filas
    public ModeloTablaResultados( String controlador, String url,
            String consulta ) throws SQLException, ClassNotFoundException {
        // cargar clase de controlador de base de datos
        Class.forName( controlador );
        // conectarse a la base de datos
        conexion = DriverManager.getConnection( url );
        // crear objeto Statement para consultar la base de datos
        instruccion = conexion.createStatement(
                ResultSet.TYPE_SCROLL_INSENSITIVE,
                ResultSet.CONCUR_READ_ONLY );
        // actualizar estado de conexión a la base de datos
        conectadoALaBaseDeDatos = true;
        // establecer consulta y ejecutarla
        establecerConsulta( consulta );
    }
    // obtener la clase que representa al tipo de columna
    public Class getColumnClass( int columna ) throws IllegalStateException {
        // asegurar que la conexión a la base de datos esté disponible
        if ( !conectadoALaBaseDeDatos )
            throw new IllegalStateException( "No hay conexion a la base de datos" );
        // determinar la clase de Java de columna
        try {
            String nombreClase = metaDatos.getColumnClassName( columna + 1 );
            // devolver objeto Class que representa a nombreClase
            return Class.forName( nombreClase );
        }
        // atrapar excepciones SQLException y ClassNotFoundException
        catch ( Exception excepcion ) {
            excepcion.printStackTrace();
        }
        // si ocurren problemas arriba, suponer que es tipo Object
        return Object.class;
    }
    // obtener el número de columnas en el objeto ResultSet
    public int getColumnCount() throws IllegalStateException {
        // asegurar que la conexión a la base de datos esté disponible
        if ( !conectadoALaBaseDeDatos )
            throw new IllegalStateException( "No hay conexion a la base de datos" );
        // determinar el número de columnas
        try {
            return metaDatos.getColumnCount();
        }
        // atrapar excepciones SQLException e imprimir mensaje de error
        catch ( SQLException excepcionSQL ) {
            excepcionSQL.printStackTrace();
        }
        // si ocurren problemas arriba, devolver 0 para el número de columnas
        return 0;
    }
    // obtener el nombre de una columna específica en el objeto ResultSet
    public String getColumnName( int columna ) throws IllegalStateException {
        // asegurar que la conexión a la base de datos esté disponible
        if ( !conectadoALaBaseDeDatos )
            throw new IllegalStateException( "No hay conexion a la base de datos" );
        // determinar el nombre de la columna
        try {
            return metaDatos.getColumnName( columna + 1 );
        }
        // atrapar excepciones SQLException e imprimir mensaje de error
        catch ( SQLException excepcionSQL ) {
            excepcionSQL.printStackTrace();
        }
        // si hay problemas, devolver cadena vacía para el nombre de la columna
        return "";
    }
    // devolver el número de filas en el objeto ResultSet
    public int getRowCount() throws IllegalStateException {
        // asegurar que la conexión a la base de datos esté disponible
        if ( !conectadoALaBaseDeDatos )
            throw new IllegalStateException( "No hay conexion a la base de datos" );
        return numeroDeFilas;
    }
    // obtener el valor en una fila y columna específicas
    public Object getValueAt( int fila, int columna ) throws IllegalStateException {
        // asegurar que la conexión a la base de datos esté disponible
        if ( !conectadoALaBaseDeDatos )
            throw new IllegalStateException( "No hay conexion a la base de datos" );
        // obtener un valor en una fila y columna específicas del objeto ResultSet
        try {
            conjuntoResultados.absolute( fila + 1 );
            return conjuntoResultados.getObject( columna + 1 );
        }
        // atrapar excepciones SQLExceptions e imprimir mensaje de error
        catch ( SQLException excepcionSQL ) {
            excepcionSQL.printStackTrace();
        }
        // si hay problemas, devolver objeto cadena vacía
        return "";
    }
    // establecer nueva cadena de consulta para la base de datos
    public void establecerConsulta( String consulta )throws SQLException, IllegalStateException {
        // asegurar que la conexión a la base de datos esté disponible
        if ( !conectadoALaBaseDeDatos )
            throw new IllegalStateException( "No hay conexion a la base de datos" );
        // especificar consulta y ejecutarla
        conjuntoResultados = instruccion.executeQuery( consulta );
        // obtener meta datos para el objeto ResultSet
        metaDatos = conjuntoResultados.getMetaData();
        // determinar el número de filas en el objeto ResultSet
        conjuntoResultados.last();                   // mover a la última fila
        numeroDeFilas = conjuntoResultados.getRow();  // obtener número de fila
        // notificar al objeto JTable que el modelo ha cambiado
        fireTableStructureChanged();
    }
    // cerrar objetos Statement y Connection
    public void desconectarDeLaBaseDeDatos() {
        // cerrar objetos Statement y Connection
        try {
            instruccion.close();
            conexion.close();
        }
        // atrapar excepciones SQLException e imprimir mensaje de error
        catch ( SQLException excepcionSQL ) {
            excepcionSQL.printStackTrace();
        }
        // actualizar estado de conexión a la base de datos
        finally {
            conectadoALaBaseDeDatos = false;
        }
    }
}  // fin de la clase ResultSetTableModel

Cosas por explicar el en código anterior:

  • Si tienes dudas respecto a las operaciones hechas con el API de JDBC significa que debes leer esto primero: Ejemplo Programación con JDBC
  • public Class getColumnClass(); con este método obtendremos el tipo de dato de la columna (Integer, String, Float, etc).
  • public int getColumnCount(); este método devuelve el número de columnas que tendrá la tabla.
  • public String getColumnName(int x); devuelve el nombre de la columna X de la tabla.
  • public int getRowCount(); este método devuelve el número de filas que tendrá la tabla.
  • public Object getValueAt(int f, int c); asigna a la tabla el valor de la celda que se encuentra en la fila f y en la columna c.
  • fireTableStructureChanged(); esto le indica al objeto AbstractTableModel que la estructura de la tabla ha cambiado.

Ahora el código del frame que contiene la tabla:

import java.awt.*;
import java.awt.event.*;
import java.sql.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
public class MostrarResultadosConsulta extends JFrame {
    // controlador JDBC y URL de la base de datos
    static final String CONTROLADOR_JDBC = "com.mysql.jdbc.Driver";
    static final String URL_BASEDEDATOS = "jdbc:mysql://localhost/ejemplo?user=root&password=";
    // la consulta predeterminada recupera todos los datos de la tabla autores
    static final String CONSULTA_PREDETERMINADA = "SELECT * FROM datos";
    private ModeloTablaResultados modeloTabla;
    private JTextArea areaConsulta;
    // crear objeto ModeloTablaResultados y GUI
    public MostrarResultadosConsulta() {
        super( "Mostrando resultados de la consulta" );
        // crear objeto ModeloTablaResultados y mostrar tabla de la base de datos
        try {
            // crear objeto TableModel para los resultados del a consulta SELECT * FROM autores
            modeloTabla = new ModeloTablaResultados( CONTROLADOR_JDBC, URL_BASEDEDATOS,
                    CONSULTA_PREDETERMINADA );
            JTable tablaResultados = new JTable(modeloTabla);

            getContentPane().setLayout(new BorderLayout());
            getContentPane().add( new JScrollPane(tablaResultados) , BorderLayout.CENTER );
            // establecer tamaño de ventana y mostrarla en pantalla
            setSize( 500, 250 );
            setVisible( true );
        }  // fin de bloque try
        // atrapar la excepción ClassNotFoundException lanzada por el
        // objeto ModeloTablaResultados si no se encuentra el controlador de la base de datos
        catch ( ClassNotFoundException claseNoEncontrada ) {
            JOptionPane.showMessageDialog( null,
                    "No se encontro el controlador de la base de datos", "No se encontro el controlador",
                    JOptionPane.ERROR_MESSAGE );
            System.exit( 1 );   // terminar la aplicación
        } // fin de bloque catch
        // atrapar la excepción SQLException lanzada por el objeto ModeloTablaResultados
        // si ocurren problemas al establecer la conexión a la base de datos
        // y realizar la consulta en la misma
        catch ( SQLException excepcionSQL ) {
            JOptionPane.showMessageDialog( null, excepcionSQL.getMessage(),
                    "Error en la base de datos", JOptionPane.ERROR_MESSAGE );
            // asegurar que la conexión a la base de datos esté cerrada
            modeloTabla.desconectarDeLaBaseDeDatos();
            System.exit( 1 );   // terminar la aplicación
        }
        // desechar la ventana cuando el usuario salga de la aplicación
        // (esta opción sobrescribe a la opción predeterminada de HIDE_ON_CLOSE)
        setDefaultCloseOperation( DISPOSE_ON_CLOSE );
        // asegurar que la conexión a la base de datos esté cerrada cuando el usuario salga de la aplicación
        addWindowListener(
                new WindowAdapter() {
            // desconectarse de la base de datos y salir cuando se haya cerrado la ventana
            public void windowClosed( WindowEvent evento ) {
                modeloTabla.desconectarDeLaBaseDeDatos();
                System.exit( 0 );
            }
        }
        );
    }  // fin del constructor de MostrarResultadosConsulta
    // ejecutar la aplicación
    public static void main( String args[] ) {
        JFrame.setDefaultLookAndFeelDecorated(true);
        new MostrarResultadosConsulta();
    }
}  // fin de la clase MostrarResultadosConsulta

Puedes ver un ejemplo más completo, llamado TableExample, en el set de demos que proporciona el JDK (puedes descargarlo abajo).

Descargas

Los ejercicios utilizados en este post están basados en ejemplos del libro Cómo programar en Java de Deitel, y por lo tanto están bajo la licencia que esta editorial disponga.

57 Comentarios | deja el tuyo

Un enlace entrante

56 Comentarios en “Consultar DB en Java – Mostrar resultados en un JTable”

  1. ChXt0 dice:

    Muchas gracias por tu respuesta, ya pregunté hoy con la doctora y me dijo lo mismo. Pero también me dijo que para más fácil primero en el servidor (que en este caso es la interfaz) estableciera la conexión y nadamás le pasara la base de datos a los clientes (hilos) que realizarán las consultas y estas si debes utilizar un mutex para controlar la concurrencia.

    Gracias por tu respuesta y tus temas sobre MySQL que han sido de gran ayuda para mi equipo de BD.

    Saludos.

  2. season2 dice:

    hola quiero se me puede ayudar busque ayuda por todo el mundo el cambio de pais de gunbound latina soy de bolivia quiero pasar a argentina con un hacker que pueda u tilisar en cualquier computadora

  3. Medium dice:

    hola en realidad soy algo nuevo en esto al compilar el primer codigo todo funciona a la perfeccion pero a la hora de correrlo me dice que le falta un main le pongo el main y me marca otro error y asi sucesivamente total que no corre un compañero consiguio que funcionara con el y me dijo que no ocupa main

    alguien que me ayude porfabor

  4. DANIELA dice:

    hola!!!! haber si me pueden ayudar soy principiante, estoy utilizando una tabla y quiero que las celdas de la tabla no se puedan editar pero no estoy programando con modelo tabla, alguien me podria explicar como hago ke no sean editables las celdas de mi tabla ademas de ke las columnas se hagan al tamaño de lo que contiene cada celda

  5. felipe escobar dice:

    hola….tengo una duda haber si me pueden colaborar. resulta que tengo que hacer una aplicacion web que me ingresen una consulta en un area de texto, y sin cambiar de pagina me muestre lo consultado, ademas necesito que me muestre las bases de datos que tengo disponibles para conectarme a una de ellas……. todo esto en una sola pagina

  6. felipe escobar dice:

    lo que necesito es que me den una pequeña orientacion de como hago para obtener las bases de datos disponibles….esto es para netbeans 6.5

  7. Maricruz dice:

    Me parece de muvha ayuda esta pagina, yo me estoy iniciado en java y me gustaria una explicacion del uso del JTable , es que me dejaron hacer u programa que tenga las ocpciones de modifivar, eliminar etc usado mysql y que implemnete una tabala, pero quiero entender primero como se usa JTable.

  8. Bismarck dice:

    Me parece muy interesante tu pagina, Es intuitiva, Muy bien organizada, excelente en cuanto al contenido, si necesita en alguna temática de Java, .Net no dudes en escribirme me encantaría ayudar.

    Continua realizando un excelente trabajo

    • Cristian dice:

      Gracias Bismarck por tu comentario.

      Ten en cuenta que este es un blog abierto a cualquier tipo de colaboración, por lo que si tienes cualquier aporte no dudes en comentármelo.

      Un saludo!

  9. Edgar dice:

    Graicas por el aporte esta muy buena esta clase justo lo ke buscaba

  10. andrew dice:

    [ayuda] primero doy gracias por este exelente espacio xD
    y lo otro es que quisiera saber si es posible cargar en mysql un campo que me guarde una foto y como seria la forma de pedir la imagen osea que objetos usaria ok

    estoy empezando en esto de la programacion
    perdonen mi ignorancia
    gracias!

  11. kain_raziel dice:

    bueno espero no molestar con esto pero quisiera saber si me pudieran ayudar con un ejemplo de JTable en el cual obtenga los datos de una BD y a su vez pueda actualizar dichos datos y guardar los cambios realizados en ella.

  12. andrew dice:

    weno heee…
    Para mi este sitio es Exelente es lo mejor y he aprendido mucho aqui pero quisiera hacer una critica constructiva xD weno no hay criticas constructivas en realidad pero no se si es ami solo que me parece que antes era mejor la forma de mostrar los codigos pues lo digo porque al momento de estuidiar se me dificula un poco pues es mi opinion se nota un poco mas cargado el codigo. …
    saludos

  13. Cristian dice:

    Gracias por tu opinión, lo tendré en cuenta andrew.

    Un saludo!

  14. Yago dice:

    hola!, muchas gracias por tu aporte la verdad q sirve de mucho, pero tengo una duda, si yo quiero almacenar datos en una base de datos y quiero mostrarlos de inmediato en el JTable que metodo debo utilizar o que instruccion habria que agregar?

¡Déjanos tu comentario!