Por favor, activa JavaScript y desactiva tu adblock para este sitio

El Javatar

Blog dedicado a la Programación en Java, C, PHP, Phyton, HTML, SQL y Mucho Más

lunes, 23 de octubre de 2017

SwingUtils - Crear JTable con Modelo de Datos Genérico (Java Swing)

Hace tiempo publiqué un artículo en el que enseñaba Cómo crear un modelo de datos personalizado para un JTable en Java Swing, en el cual podemos ver cómo el API de Java Swing separa la vista de un JTable y su modelo de datos. Teniendo en cuenta lo que enseño en dicho artículo, decidí crear un Modelo de datos Pseudo-genérico dentro de la librería SwingUtils, de tal forma que los modelos de datos que creemos para nuestras tablas sean lo menos verbosos posible.

No me expandiré mucho en los detalles acerca de cómo funciona un modelo de datos en un JTable de Java Swing, ya que eso lo explico en este artículo; así que veamos directamente qué es lo que nos provee la librería SwingUtils para crear los modelos de datos de los JTable de forma rápida y sencilla.
Lo primero que debemos hacer es importar la librería SwingUtils a nuestro proyecto. Puedes ver las instrucciones en el siguiente enlace:

==> SwingUtils - Librería de Utilidades para Java Swing

La librería SwingUtils nos provee la clase TableModelGeneric de la cual podemos extender los modelos de datos que creemos para nuestros JTable. Así que veamos primero la clase modelo que usaremos para nuestro ejemplo:

public class Pais {
    
    private Integer id;
    private String codigo;
    private String nombre;

    public Pais(Integer id, String codigo, String nombre) {
        this.id = id;
        this.codigo = codigo;
        this.nombre = nombre;
    }

    public Pais() {
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getCodigo() {
        return codigo;
    }

    public void setCodigo(String codigo) {
        this.codigo = codigo;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 13 * hash + Objects.hashCode(this.id);
        hash = 13 * hash + Objects.hashCode(this.codigo);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Pais other = (Pais) obj;
        if (!Objects.equals(this.codigo, other.codigo)) {
            return false;
        }
        if (!Objects.equals(this.id, other.id)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return nombre;
    }
    
}

Éste será el tipo de dato que ocuparán los datos de nuestro JTable. Ahora veamos el modelo de datos que usará el JTable de nuestro modelo:

public class MiModeloTabla extends TableModelGeneric<Pais> {
    
    /**
     * Este Constructor sin parámetros lo usaríamos para el comportamiento por
     * defecto de un JTable el cual deseemos inicializar con las propiedades
     * de tipo de dato y título de columnas predefinidas pero sin lista de datos
     */
    public MiModeloTabla() {
        super(
                new Class[]{Integer.class, String.class, String.class}, 
                new String[]{"Id", "Código", "Nombre"}, 
                new ArrayList<>()
        );
    }
    
    /**
     * Este Constructor lo usaríamos para el comportamiento de un JTable el cual
     * deseemos inicializar con las propiedades de tipo de dato y título de
     * columnas predefinidas, pero con una lista de datos proveída por nosotros
     * desde la creación del modelo de datos
     * @param listElements 
     */
    public MiModeloTabla(List<Pais> listElements) {
        super(
                new Class[]{Integer.class, String.class, String.class}, 
                new String[]{"Id", "Código", "Nombre"}, 
                listElements
        );
    }
    
    /**
     * Este Constructor lo usaríamos para el caso en que deseemos proporcionar
     * todas las propiedades de un JTable desde el momento en que creamos
     * nuestro modelo de datos
     * @param typeColumns
     * @param titleColumns
     * @param listElements 
     */
    public MiModeloTabla(Class[] typeColumns, String[] titleColumns, List<Pais> listElements) {
        super(typeColumns, titleColumns, listElements);
    }
    
    /**
     * Este método es necesario que lo sobre-escribamos, ya que mediante éste
     * indicamos los datos que se muestran en cada columna y fila del JTable
     * @param rowIndex
     * @param columnIndex
     * @return 
     */
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        switch (columnIndex) {
            case 0:
                return getListElements().get(rowIndex).getId();
            case 1:
                return getListElements().get(rowIndex).getCodigo();
            case 2:
                return getListElements().get(rowIndex).getNombre();
            default:
                return null;
        }
    }
    
}

En nuestro modelo de datos sólo necesitamos de tres cosas:

1. Extender de la clase TableModelGeneric la cual nos provee la librería SwingUtils.

2. Crear un constructor que llame al constructor de la clase TableModelGeneric. En este ejemplo vemos tres ejemplos, aunque en verdad sólo bastaría con un constructor; todo depende de cómo necesitemos crear nuestros JTable e inicializar sus respectivos modelos de datos.

3. Sobre-escribir el método getValueAt() el cual pertenece a la interface TableModel, ya que mediante éste método indicamos los datos que se muestran en cada columna y fila del JTable.

Con ésto sólo nos resta inicializar nuestro modelo de datos y asignarlo al JTable.

Implementar nuestro modelo de datos en un JTable de Java Swing

Mediante la librería SwingUtils podemos implementar nuestro modelo de datos de forma rápida, ya que nos provee algunos métodos a través de la clase JTableUtils, aunque en este caso sólo haremos uso de uno de ellos. Veamos entonces como quedaría nuestro ejemplo:

public class MiVista extends javax.swing.JFrame {
   
    private javax.swing.JTable jTable1;
       
    public MiVista() {
        initComponents();
         
        List<Pais> listaPaises = new ArrayList<>();
        listaPaises.add(new Pais(1, "CO", "Colombia"));
        listaPaises.add(new Pais(2, "AR", "Argentina"));
        listaPaises.add(new Pais(3, "VE", "Venezuela"));
        listaPaises.add(new Pais(4, "EC", "Ecuador"));
        listaPaises.add(new Pais(5, "PE", "Perú"));
        listaPaises.add(new Pais(6, "BO", "Bolivia"));
        listaPaises.add(new Pais(7, "MX", "México"));
         
        JTableUtils.setProperties(jTable1, new Font("Arial", Font.BOLD, 13), new MiModeloTabla(listaPaises));
    }

    private void initComponents() {
        // Código generado por NetBeans
    }
       
}

En este caso, usamos uno de los métodos estáticos setProperties() de la clase JTableUtils; cabe aclarar que esta clase sobrecarga varias veces éste método, así que para este ejemplo ocupamos el que recibe tres parámetros: El JTable que usaremos, la fuente de los títulos del JTable y la inicialización del modelo de datos que creamos.

SwingUtils - Crear JTable con Modelo de Datos Genérico (Java Swing)

Esta es la captura de pantalla de nuestro ejemplo. Como hemos visto, es muy sencillo crear modelos de datos pseudo-genéricos e implementarlos en nuestros JTable a través de la librería SwingUtils.

No hay comentarios.:

Publicar un comentario