jt9

Customizando un JTable, hágalo usted mismo en 5 simples pasos (Leer con la voz de Sprayette)

El objetivo de este artículo es modificar un JTable para que quede totalmente distinto y mejorado. Si no les sirve tal como queda al final, no se preocupen ya que pueden sacar buenas ideas de los pasos intermedios. Empecemos, el objetivo es tranformar:

En…

Manos a la obra (como diría mi abuelo) …

Paso 1:  Modificar el Modelo del JTable JDefaultTableModel

Para no meter mágia y misticismo en esto, vamos a usar directamente el editor de Netbeans. Para ello seleccionamos la Tabla, y en las propiedades buscamos “model” y le damos a los tres puntitos “” Esto va a abrir un editor muy simple, la idea es dejar sin filas la tabla y con solo dos columnas (para este caso la primera tiene el icono y la segunda tiene el texto).

Deberían configurar algo como esto:

Cuando terminemos ya deberíamos tener nuestra tabla en el siguiente estado:

Paso 2:  Que no se muestre la cabecera del JTable

Esto es muy simple de hacer, pero es por la mayoría desconocido. La idea es que la cabecera (Icono – Texto) esté, pero no se muestre. Para esto seleccionamos el JTable, y buscamos en el cuadro de propiedades “tableHeader” y le damos a los tres puntitos ““. La idea aca es poner un null como parametro del constructor para esto, dentro del editor, seleccionamos en el combo “Código Personal” y ponemos (null).

Vamos avanzando y seguro ya tenemos algo como ésto:

Paso 3: Creando el Renderizador de las celdas

Este es el “killer step” de la idea, donde la mayoria toma aire, cuenta hasta 10 y tira la compu al patio no sin antes recordar a la madre de los desarrolladores de sun y desear que les pase un Focus por arriba.
Lo que tenemos que hacer es crear una clase que será utilizada para renderizar las celdas, en ella vamos a escribir como se va a mostrar cada una y de que forma. Parece sumamente complicado, salvo que tenemos un As bajo la manga, los jLabel.
El jLabel si tiene algo de bueno es que podemos mostrar un icono/imágen en él, entonces sería buena idea poder hacer que cada celda del JTable sea un jLabel.
El código de esta clase se los dejo a continuación y comentado, luego hago unas breves acotaciones:

/**
 * Descripción:  Un renderizador de celdas de un JTable que pone
 * un jLabel en cada una de las celdas para que se pueda poner
 * un icono/imagen
 * @version 1.0
 * @author Iuga
 * @cambios
 * @todo
 */

public class IconCellRenderer extends DefaultTableCellRenderer
{
/**
 * Acá redefinimos como se muestra, vemos q ahora lo forzamos a
 * trabajar con JLabel, pero si no lo es, por ejemplo un String
 * igual lo muestro llamando a Super
 */
public Component getTableCellRendererComponent (JTable table, Object value, boolean isSelected,boolean hasFocus, int row, int column)
{
if(value instanceof JLabel)
{
JLabel label = (JLabel)value;
           label.setOpaque(true);
fillColor(table,label,isSelected);
return label;
}
else
{
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
}

/**
 * Este método es para que pinte el fondo del JLabel cuando
 * lo seleccionamos para que no quede en blanco, desentonando
 * con el resto de las celdas que no son JLabel
 */
public void fillColor(JTable t,JLabel l,boolean isSelected )
{
if(isSelected)
{
l.setBackground(t.getSelectionBackground());
l.setForeground(t.getSelectionForeground());
}
else
{
l.setBackground(t.getBackground());
l.setForeground(t.getForeground());
}
}
}

Como vemos, redefinimos dos métodos de DefaultTableCellRenderer, el primero indica que y como vamos a mostrar la celda (y vemos que trabajamos con JLabel) y el segundo método está atento a los cambios de color para ahcerlo uniforme y que no desentonen los colores.
Ahora lo que resta es pasarle el Rederer al JTable para que use éste en lugar del Default.

jTable1.setDefaultRenderer(Object.class,new IconCellRenderer());

En este punto no tenemos cambios visuales, así que sigamos con el siguiente paso

Paso 4:  Llenando el JTable con datos de Prueba

Ahora a probar el producto terminado. Vamos a cargar algunas filas con datos, vamos con los datos de una sola fila para que se entienda la idea:

Object[] fila = new Object[2];
 ImageIcon icon = new ImageIcon(getClass().getResource("/res/iconos/plantillas/vacio.png"));
 fila[0] = new JLabel(icon);
 fila[1] = "Presupuesto en Blanco";

Como vemos el primer valor del Array es un JLabel con un icono y sin texto. (Nota: Si, podríamos haber hecho una sola columna y que muestre icono y texto al mismo tiempo, pero era para mejorar el ejemplo y demostrar que podemos mezclar JLabels y otros tipos de datos sin complicar el modelo).

Una vez que tenemos los datos solo queda agregarlos al modelo de la tabla:

DefaultTableModel modelo = (DefaultTableModel)jTable1.getModel();
modelo.addRow(fila);

Paso 5: Mejorando la Visual del JTable y la altura de las celdas

Primero tenemos que ajustar, en cada caso, la altura de las celdas de acuerdo al tamaño de los iconos/imágenes que mostremos, así no nos corta la imágen como en el caso anterior.

// Donde 50 es el tamaño que querramos en la celda según lo q necesitemos
jTable1.setRowHeight(50);

Ahora podemos cambiar un poco el tamaño de la tabla para que quede acorde a los datos y el tamaño de las celdas. Para esto nuevamente recurrimos a la facilidad que nos da Netbeans y vamos a otro editor haciendo “click derecho” en la JTable y en “Contenido de la Tabla…” y vamos a la segunda Solapa “Columnas“, en cada una podemos configurar el tamaño mínimo, sugerido y máximo.

Todo lo bueno tiene fin, y este fue el nuestro, ya con esto tenemos nuestro JTable modificado completamente y si seguimos bien los pasos deberíamos tener algo como esto:

Lo que sigue es llenar la tabla con datos a nuestro antojo, poner o sacar columnas, simplemente modificarla a nuestro antojo.

Intente ser lo más claro y lento posible, para que no pase cual libros de análisis matemático con las demostraciones (bueno y estamos demostrando este teorema, y seguimos con este paso, ahora este otro …. un momento!! COMO LLEGO A ESE PASOOOOOO ES IMPOSIBLEEEEE  y Lluvia de puteadas al autor). Cualquier duda q tengan preguntenla y voy a intentar resolverselas. Hasta el proximo tutorial

By Iuga Publicado en java

20 comments on “Customizando un JTable, hágalo usted mismo en 5 simples pasos (Leer con la voz de Sprayette)

  1. Hola, nada mas queríamos agradecerte, estuvimos con ésto bastantes días dandole vueltas y no lográbamos hacer andar el render.
    La verdad que está muy claro y muy bien explicado.
    Saludos

  2. Excelente asi es q deberian ser todo pasos simples que todos entendamos gracias ;)

  3. no entiendo T_T esa imagen que pones en el jlabel donde se supone que deberia estar… otra pregunta… en la clase iconcellrendered me salen errores en jtable y jlabel… porque??
    … quiero configurar una tabla de 3 columnas y 12 filas donde las celdas tengan fondo rojo y negro es decir tabla[0][0] color rojo tabla[0][1] color negro tabla[0][2] color rojo
    tabla[1][0] color negro … asi sucesivamente… pero con tu ejemplo no se ni como pintar el fondo de una sola celda ayudaaa

  4. Son las 6 :10 de la mñn y gracias a tu código y explicacion e conseguido que me salgan las malditas imágenes. simplemente GRACIAS!

    un par de detalles, netBeans me obligó a quitar el public de la linea 11 y a hacer el método @Override.

    G R A C I A S ! ! ! !

    • Gracias a vos, es bueno saber que lo que escribo le es útil a alguien !!

  5. Muchas
    gracias por el turotial, ha sido de mucha ayuda, solo que me preguntaba
    como podría combinar dos celdas consecutivas en una fila, he tratado de
    buscar una solución pero el JTable no me lo permite.

    • mmm Yo creería que no se puede, lo que yo hice en un momento con eso, es jugar con los colores de fondo de celda y los bordes, y “simular” que las celdas estaban unidas, quedo bastante bien, pero claro, es una solución muy horrible.

  6. hola luga.. una consulta.. como hago para que pulsando sobre una celda de un JTable pueda obtener el resultado de un operacion hecha con dos celdas contiguas..?

    desde ya gracias!

  7. Tio me encantaria que pudieras dejar el applet para ver el codigo fuente. No se si es mucho pedir. Gracias

    • Mmm no es un applet, es un proyecto de escritorio y el código está muy acoplado a la implementación del sistema, no te serviría.

  8. Hola, estoy probando tu codigo y no me muestra el icono… utilizo una imagen que esta dentro del mismo paquete que la clase y no la muestra. Que problema puede ser?

    gracias!

    • Pasáme el código que estas usando para cargar la imágen y el del renderer

  9. Por falta de tiempo puse una solucion parcial que fue insertar toda la ruta donde se encontraba guardado el archivo en mi maquina… cuando los tiempos sean mas holgados intentare agregar las imagenes que tengo guardadas en los paquetes. Muchisimas gracias por todo, fue de mucha utilidad la informacion que porporcionaste.

    Saludos!

  10. excelente post!

  11. Pues me preguntaba si es posible que al darle clic a esa imagen o en general al texto del label (asi lo tengo) mostrara una ventana es decir, como le agregaria el evento del mouse al JLabel he tratado de hacerlo pero no funciona. Seria de mucha ayuda alguna sugerencia.

  12. tengo Problemas me aparece un error en el Jlable

    Exception in thread “AWT-EventQueue-0″ java.lang.ArrayStoreException: javax.swing.JLabel

    no se si me pudiera ayudar

    • excelente Codigo ya lo resolvi era una imcompativilidad en los Object

  13. man, muchas gracias me sirvio demaciado tu codigo y tutorial, ademas me entretuve mucho, desde aca muchas gracias!!!

  14. Son las 4:41 de la madrugada a solo 4 horas de entregar el proyecto, y tu diste con mi problema, no sabes cuanto te agradezco
    Saludos

  15. Que gusto poder contar con una web que tenga lo que andaba buscando buen aporte amigo. me sirvio de mucho

Deja un comentario

Fill in your details below or click an icon to log in:

Logo de WordPress.com

You are commenting using your WordPress.com account. Log Out / Cambiar )

Twitter picture

You are commenting using your Twitter account. Log Out / Cambiar )

Facebook photo

You are commenting using your Facebook account. Log Out / Cambiar )

Connecting to %s