Cambiar el aspecto de las celdas de un JTable

image

Normalmente un JTable en Java viene con un aspecto previamente definido, desde el formato de los textos y números, el color de fondo de las celdas, la alineación del texto, etc. Sin embargo, existen ocasiones en que es necesario cambiar dicho formato, por ejemplo, cambiar el color de fondo de las celdas, filas, columnas, el tipo, color y estilo de las letras, la alineación, etc. Incluso en ocasiones dicho formato es condicional, es decir, solo aplica cuando alguno(s) de los datos cumplen ciertos requisitos.

En esta ocasión dedicaré este artículo a explicar paso a paso cómo cambiar el formato de las celdas en una tabla, para ello, vamos a necesitar de una clase que implemente la interface TableCellRenderer.

 

::La interface TableCellRenderer::

TableCellRenderer es una interface que provee del comportamiento a cada una de las celdas en un JTable, a través de ella, podemos definir los colores, formatos, alineaciones y demás cuestiones visuales de la tabla, al implementar dicha interfaz solamente es necesario definir el comportamiento del método getTableCellRendererComponent() y dentro de él definir lo que se desea.

El dicho método tiene la siguiente estructura:

public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {

 

Donde:

table: Es la tabla contenedora de la celda actual.

Object: El contenido de la celda.

isSelected: Indica si dicha celda está seleccionada o no.

hasFocus: Indica si dicha celda tiene o no el foco.

row: La fila en la que se encuentra ubicada la celda.

column: La columna en la que se encuentra ubicada la celda.

 

Ya que conocemos el método que se va a utilizar pasemos con la definición de la clase.

 

::Definición de la clase::

La clase que utilizaremos debe de heredar de cualquier tipo de objeto derivado de la clase Component, desde un campo de texto (JTextField) hasta incluso un panel (JPanel) que a su vez podrá contener cualquier otro componente. En este caso utilizaré el componente JFormattedTextField ya que en mi caso necesito darle cierto formato a los datos que manejarán cantidades monetarias.

La definición inicial de la clase queda de la siguiente manera:

 

public class FormatoTabla extends JFormattedTextField implements TableCellRenderer{

public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,boolean hasFocus, int row, int column) {

}

}

 

Ahora bien, lo siguiente que debemos hacer es definir un objeto del tipo de la clase que vamos a estar manejando, en este caso un JFormattedTextField para irle dando el formato que deseamos. En este ejemplo lo definí dentro del método aunque puedes hacerlo como te sea más útil en tu aplicación…

 

JFormattedTextField campoTexto = new JFormattedTextField();

 

…posteriormente le establecí un borde vacío para que siguiera adaptándose al estilo de la tabla como normalmente la vemos…

 

campoTexto.setBorder(BorderFactory.createEmptyBorder());

 

…una vez hecho esto, vamos a aplicar el formato a la celda de acuerdo al tipo de dato que esta contenga, en mi caso la celda puede contener uno de 3 tipos: String, Integer o BigDecimal, que son los cuales voy a estar validando de la siguiente manera:

- Si el objeto es de tipo String únicamente lo escribo en el campo de texto sin cambiar su formato:

if (value instanceof String){
            campoTexto.setText((String)value);
}

 

- Si el objeto es de tipo Integer escribo su valor y lo alineo al centro:

if(value instanceof Integer){
            campoTexto.setText(""+(Integer)value);  
            campoTexto.setHorizontalAlignment(SwingConstants.CENTER);
        }

 

- Si el objeto es tipo BigDecimal además de escribir su valor le aplico un formato para que me separa por comas cada 3 cifras y establezco su alineación de derecha a izquierda…

campoTexto.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter(new java.text.DecimalFormat("#,##0.00"))));
campoTexto.setHorizontalAlignment(SwingConstants.TRAILING);
campoTexto.setValue(valor);

 

…pero si además su valor es negativo, le quito el signo menos (-) y le establezco su color de fondo a rojo…

if(valor.compareTo(new BigDecimal(0))==-1) {
  campoTexto.setText(etiqueta.getText().replace("-", ""));
  campoTexto.setBackground(new Color(0xFE899B));
  campoTexto.setOpaque(true);
}

 

…al hacer lo anterior solo la celda que contiene el valor negativo se dibujará de color rojo, sin embargo, en mi caso deseo que todas las celdas de dicha fila sean rojas así que agregué el siguiente código:

if(((BigDecimal)table.getValueAt(row, table.getColumnCount()-1)).compareTo(new BigDecimal(0))==-1){
            campoTexto.setBackground(0xFE899B);
            campoTexto.setOpaque(true);
        }

Lo que hago en las líneas anteriores es verificar si en la última celda del lado derecho de la fila en la que se encuentra la celda actual se localiza un valor negativo, en caso de ser así cambio el color de fondo de la celda actual a rojo claro.

Para terminar  vamos a definir el comportamiento de las celdas al estar seleccionadas, en este caso, vamos a cambiar su color de fondo por un tono gris claro…

if(isSelected){
etiqueta.setBackground(Color.lightGray);
}

 

Cuando desees utilizar el formato que hemos definido anteriormente en alguna de las tablas de tu aplicación basta con realizar lo siguiente:

FormatoTabla formato = new FormatoTabla();
tabla.setDefaultRenderer(BigDecimal.class, formato);
tabla.setDefaultRenderer(String.class, formato);
tabla.setDefaultRenderer(Integer.class, formato);

 

Con lo anterior estoy indicando que para la tabla ‘tabla’ se utilice el formato definido en la clase FormatoTabla para cada celda donde su valor sea de tipo BigDecimal, String e Integer.

Tras realizar todo lo anterior tendrás una tabla con un formato parecido a la siguiente:

image

Si lo deseas puedes descargar el código fuente de la clase FormatoTabla desde el siguiente vínculo:

Descargar.

La contraseña para descomprimirlo es: http://monillo007.blogspot.com

Alguna duda o algo qué decir? Deja tu comentario. Saludox.

28 comentarios:

  1. Anónimo dijo...:

    Hola buen dia, excelente tu explicacion bastante buena diria yo, solo quu quiero descargar el codigo fuente ´pero el link no funciona.

    Gracias . . .

  1. Anónimo dijo...:

    Hola muy bueno tut tuto ,yo tambien quiero descargar el codigo . . . .

  1. Anónimo dijo...:

    Hola muy bien explicado pero no me funciona al implementarlo en mi aplicación, me gustaría ver el codigo para ver en que estoy fallando Muchas Gracias.

  1. Anónimo dijo...:

    Pues a mi también me pareció muy útil pero cuando lo trate de probar en mi aplicación no funciono. El link de descarga no funciona :(

  1. Anónimo dijo...:

    Hola
    En primer lugar gracias por tu aporte, me gustaría poder descargar el codigo fuente.
    El link que dejaste no funciona, podrías enviarmelo. Mi correo es marll_star@yahoo.com.mx
    Gracias por tu atencion.

  1. Anónimo dijo...:

    El link de descarga no funciona ... te agradeceria me lo pudieras enviar a mi correo... ya que me seria de mucha ayuda.

    De antemano muchas gracias y felicidades por tu Blog tan bueno.

    mi correo.

    joel.sys@hotmail.com

  1. Anónimo dijo...:

    Hola. Me parece interesante tu aporte... y me gustaria bajar el codigo fuente lo cual me será de mucha ayuda, pero el link no funciona. Te agradezco me lo envias a mi correo:
    wserpa@gmail.com.

    Te antemano muchas gracias

  1. Anónimo dijo...:

    muy buenos post gracias Monillo007

  1. Anónimo dijo...:

    Gracias por el post logre hacerlo sin necesidad de copiar y pegar, me ayudaste. Saludos

  1. Anónimo dijo...:

    Excelente aporte, muchas gracias me sirvió de mucho
    Atte, PlayGame

  1. Anónimo dijo...:

    Hay un error o es etiqueta o es campoTexto, esto pasa por copiar y pegar de otras páginas ...

    if(isSelected){
    etiqueta.setBackground(Color.lightGray);
    }

    Te falta el return campoTexto;

    ...Pobre gente que quiere hacer andar este código ....

  1. Anónimo dijo...:

    import java.awt.Color;
    import java.awt.Component;
    import javax.swing.*;
    import javax.swing.table.TableCellRenderer;

    public class TableRendererFTextField implements TableCellRenderer {

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    JFormattedTextField txtFormated = new JFormattedTextField();
    txtFormated.setBorder(BorderFactory.createEmptyBorder());
    fillColor(table,txtFormated,isSelected);
    txtFormated.setText(""+ value);

    txtFormated.setHorizontalAlignment(SwingConstants.CENTER);
    if(((Float)table.getValueAt(row, table.getColumnCount()-2)).compareTo(new Float(0))==-1) {
    txtFormated.setBackground(new Color(0xFE899B));
    txtFormated.setOpaque(true);
    if(isSelected){
    txtFormated.setBackground(Color.lightGray);
    }

    }

    return (txtFormated);
    }

    public void fillColor(JTable t, JFormattedTextField JFTextField, boolean isSelected) {
    if (isSelected) {
    JFTextField.setBackground(t.getSelectionBackground());
    JFTextField.setForeground(t.getSelectionForeground());
    } else {
    JFTextField.setBackground(t.getBackground());
    JFTextField.setForeground(t.getForeground());

    }

    }

    }

  1. MIKE dijo...:

    Donde declaras la variable "valor"

  1. Luis Navarro dijo...:

    Qué tal Mike,

    'valor' es valor que vas a establecer en la fila, en este ejemplo sería tipo texto ;)

    Saludos.

  1. Anónimo dijo...:

    Alguien me puede enviar el codigo completo por email.

    El enlace no funciona.

    gracias

    jesuseti@hotmail.com

  1. Alberto Palafox dijo...:

    El linkde la descarga del código ya no sirve! Podrías resubirlo nuevamente?? Gracias!! :D

  1. Anónimo dijo...:

    El link no esta disponible.....hermano sera que lo puede subir nuevamente?

  1. Anónimo dijo...:

    Podrías activar el linck de descarga otra ves?

  1. Anónimo dijo...:

    vuelve a subir tu codigo por q no sirve

  1. Anónimo dijo...:

    hola que tal alguien me podria enviar el codigo a mi correo por favor
    chias@live.com.mx

  1. Hola amigo muy buena tu explicación pero podrías subir el código nuevamente o enviármelo por correo sheikav22@hotmail.com te lo agradecería ya que llevo mucho tiempo buscando como hacerto en mis proyectos.

  1. Findex dijo...:

    Cual es la contrasenia? gracias de antemano

  1. Lalo Wolf dijo...:

    CUal es la contraseña alguien me la podria pasar mi correo es cobra_1884@hotmail.com

  1. Anónimo dijo...:

    tiene contraseña al descomprimir el carchovo...alguien me puede proorcionar la contraseña...gracias

  1. Luis Navarro dijo...:

    Qué tal,

    La contraseña está al final del post, es:

    http://monillo007.blogspot.com

    Saludos.

  1. Pero tengo unos problemas.
    1.- Que veo que tus ejemplo trae los datos fijos.
    2.- Y yo necesito llenar de una tabla de EBCDIC, (Este tema ya lo soluciones) ya convierto los datos a String
    3.- No hayo la manera de mandar ejecutar tu proceso para que me realice el cambio en la tabla.
    4.- Puedo crear una clase exclusiva para mandar los datos por paremetro y me regrese el valor del llenado de la tabla?
    5.- Esto es por que son varias tablas con las cuales ocupare la salida formateada de los importes ejemplo recibo 1234567890 y requiero que salga $ 12,345,678.90

    Espero me puedas ayuda ru orientar en que parte de mi ciclo while coloco tu proceso para que sea ejecutado obvio quitando los valores fijos.

    Gracias de antemano

    Saludos.

  1. Anónimo dijo...:

    Gracias la explicación esta detallada y me sirvió de mucho

Publicar un comentario

Este es un espacio abierto, puedes escribir lo que gustes respetando los siguientes puntos:

1.- Lo que escribas esté relacionado con el post, si gustas contactarme puedes hacerlo aqui.

2.- Todo es cuestionable, aunque ten en cuenta que existen formas de hacerlo, evita las agresiones y revisa tu lenguaje antes de publicar un comentario.

3.- Siempre hay tres verdades: tu verdad, mi verdad y la verdad, por lo que opiniones diferentes no necesariamente son equivocadas.

4.- Los comentarios son una forma de discusión abierta, por lo que al publicar uno, implícitamente entras a una discusión, con todo lo que esto representa.

5. Me reservo el derecho de eliminar comentarios que no respeten las condiciones mencionadas anteriormente.

Toma en cuenta que puedes utilizar emoticones en tu comentario, para ver una lista de los disponibles da clic en este enlace.

 
Monillo007 © 2010 | Designed by Trucks, Manual Bookmarking | Elegant Themes