martes, 27 de marzo de 2012

Personalización de un JTable en Java

El JTable es un componente del API Swing de Java para desplegar datos en dos dimensiones. Este componente que está desarrollado bajo el patrón MVC (como el resto de componentes de Java Swing) presenta un modelo y un renderizador los cuales se encargan de mostrar los registros de una forma determinanda, sin embargo en muchas de nuestras aplicaciones queremos personalizar los datos mostrados por lo que se hace necesario escribir nuestras propias clases para renderizar y gestionar la información que queremos mostrar. A lo largo de este artículo les mostraré la forma de cómo hacerlo con unos cuantos sencillos pasos.
Lo primero que debemos hacer es crearnos un proyecto en Netbeans nombrándolo como mejor nos paresca. Luego crear un paquete que en nuestro caso le hemos llamado com.blogspot.rolandopalermo.bean y a continuación crear en ese mismo paquete una clase Cliente tal como se muestra en la figura a continuación:


Y el código de esta clase debe quedar como se muestra  a continuación:

package com.blogspot.rolandopalermo.bean;

/**
 *
 * @author Rolando
 */
public class Cliente {

    private int id;
    private int edad;
    private String nombre;
    private String nombreEmpresa;
    private String nombreContacto;
    private String direccion;

    public Cliente(int id, int edad, String nombre, String nombreEmpresa, String nombreContacto, String direccion) {
        this.id = id;
        this.edad = edad;
        this.nombre = nombre;
        this.nombreEmpresa = nombreEmpresa;
        this.nombreContacto = nombreContacto;
        this.direccion = direccion;
    }

    public String getDireccion() {
        return direccion;
    }

    public void setDireccion(String direccion) {
        this.direccion = direccion;
    }

    public int getEdad() {
        return edad;
    }

    public void setEdad(int edad) {
        this.edad = edad;
    }

    public int getId() {
        return id;
    }

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

    public String getNombre() {
        return nombre;
    }

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

    public String getNombreContacto() {
        return nombreContacto;
    }

    public void setNombreContacto(String nombreContacto) {
        this.nombreContacto = nombreContacto;
    }

    public String getNombreEmpresa() {
        return nombreEmpresa;
    }

    public void setNombreEmpresa(String nombreEmpresa) {
        this.nombreEmpresa = nombreEmpresa;
    }
}

Ahora debemos crear una JFrame el cuál se encargará de contener tanto a nuestra tabla como al resto de nuestros componentes Swing de nuestra aplicación. Creamos el JFrame VentanaPrincipal.java como se muestra en el figura siguiente:


Es el turno de nuestro modelo, quién se encargá de manejar las propiedades de tabulación de nuestra tabla  Para esto creamos la clase TablaModeloCliente como se muestra en la figura:


Y su código respectivo:

package com.blogspot.rolandopalermo.gui;

import com.blogspot.rolandopalermo.bean.Cliente;
import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;

/**
 *
 * @author Rolando
 */
public class TablaModeloCliente extends AbstractTableModel {

    private String[] columnNames = {"DNI", "Nombre", "Edad", "Dirección", "Empresa", "Contacto"};
    private List<cliente> clientes = new ArrayList<cliente>();

    public void agregarCliente(Cliente cliente) {
        clientes.add(cliente);
        fireTableDataChanged();
    }

    public void eliminarCliente(int rowIndex) {
        clientes.remove(rowIndex);
        fireTableDataChanged();
    }
    
    public void limpiarClientes() {
        clientes.clear();
        fireTableDataChanged();
    }

    @Override
    public String getColumnName(int columnIndex) {
        return columnNames[columnIndex];
    }

    @Override
    public int getRowCount() {
        return clientes.size();
    }

    @Override
    public int getColumnCount() {
        return 6;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        switch (columnIndex) {
            case 0:
                return clientes.get(rowIndex).getId();
            case 1:
                return clientes.get(rowIndex).getNombre();
            case 2:
                return clientes.get(rowIndex).getEdad();
            case 3:
                return clientes.get(rowIndex).getDireccion();
            case 4:
                return clientes.get(rowIndex).getNombreEmpresa();
            case 5:
                return clientes.get(rowIndex).getNombreContacto();
            default:
                return null;
        }
    }

    @Override
    public Class getColumnClass(int columnIndex) {
//        return getValueAt(0, columnIndex).getClass();
        return String.class;
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return false;
    }

    @Override
    public void setValueAt(Object value, int rowIndex, int columnIndex) {
        Cliente cliente = clientes.get(rowIndex);
        switch (columnIndex) {
            case 0:
                cliente.setId((Integer) value);
            case 1:
                cliente.setNombre((String) value);
            case 2:
                cliente.setEdad((Integer) value);
            case 3:
                cliente.setDireccion((String) value);
            case 4:
                cliente.setNombreEmpresa((String) value);
            case 5:
                cliente.setNombreContacto((String) value);
        }
        fireTableCellUpdated(rowIndex, columnIndex);
    }
}

Y para renderizar los datos en la grilla, crearemos la clase TablaRenderizadorCliente la cuál determinará las propiedades gráficas y el comportamiento gráfico de las celdas que van a componer la tabla.


Lo que debemos hacer es implementar la interfaz TableCellRenderer.
package com.blogspot.rolandopalermo.gui;

import java.awt.Color;
import java.awt.Component;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;

/**
 *
 * @author Rolando
 */
public class TablaRenderizadorCliente implements TableCellRenderer {

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        JLabel etiqueta = new JLabel();
        etiqueta.setOpaque(true);
        if (row % 2 == 0) {
            etiqueta.setBackground(new Color(255, 255, 200));
        } else {
            etiqueta.setBackground(Color.white);
        }
        if (column == 1) {
            String nombre = (String) value;
            etiqueta.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
            if (nombre.startsWith("#")) { //Hombre
                etiqueta.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/blogspot/rolandopalermo/recursos/user.png"))); // NOI18N
            } else if (nombre.startsWith("&")) { //Mujer
                etiqueta.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/blogspot/rolandopalermo/recursos/user2.png"))); // NOI18N
            }
            etiqueta.setText(value.toString().substring(1, nombre.length()));
        } else {
            etiqueta.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
            etiqueta.setText(value.toString());
        }
        if (isSelected) {
            etiqueta.setBackground(new Color(151, 193, 215));
        }
        return etiqueta;
    }
}

Con esto ya deberiamos tener la tabla como se muestra en la siguiente figura:


Para establecer el modelo y el renderizador a nuestra tabla deberíamos hacer lo siguiente:

TablaModeloCliente modelo = new TablaModeloCliente();
TablaRenderizadorCliente renderizador = new TablaRenderizadorCliente();
tablaClientes.setModel(modelo);
tablaClientes.setDefaultRenderer(String.class, renderizador);

Y para finalizar les dejo el enlace del proyecto para descargar.

Photobucket

12 comentarios:

  1. Gracias.

    El siguiente paso sería hacerlo más genérico, algo como public class TablaModelo extends AbstractTableModel. Has avanzado algo en este aspecto?

    ResponderEliminar
  2. Claro amigo, es justamente lo que he usado para este ejemplo.
    Saludos.

    ResponderEliminar
  3. Gracias... quería hacer algo similar.

    ResponderEliminar
  4. Gracias por el ejercicio . . ... . . ahi te dejo uno mas basico que tambien me sirvio: http://darwinomartics.blogspot.com/2013/04/ejercicio-basico-netbenas-java.html

    ResponderEliminar
  5. Muchas gracias we
    es lo que andaba buscando
    =)

    ResponderEliminar
  6. Muchas gracias por tu aporte, fue de gran ayuda :)

    ResponderEliminar
  7. Gracias!!! eres Un genio llevo Horas queriendo aprender y no había hecho absolutamente nada muchas gracias amigo desde ya te considero mi amigo que dios te bendiga :)!!!

    ResponderEliminar
  8. Y como se puede hacer por ejemplo en tu tabla para que el nombre de la empresa figure como un "subtitulo" (como un jlabel con formato distinto) y los datos ordenados debajo de ese "subtitulo"? Muchas gracias!

    ResponderEliminar
  9. Muy bueno tu material, sirve de mucho. Gracias

    ResponderEliminar
  10. Sos un genio!!!!! muchisimas gracias!!!!

    ResponderEliminar