Tooltips en celdas de JTable

Hace poco, trabajando con el proyecto discography-generator me encontré el problema de hacer que las celdas de un javax.swing.JTable mostraran un tooltip o "mensaje emergente" cuando el ratón estuviera encima.

Lo único que estaba buscando era que se mostrara el contenido de la celda, algo muy simple a priori pero que, como ocurre casi siempre en Swing, acaba siendo algo rebuscado. La solución la encontré en la documentación oficial de SUN:
En este post veremos el código necesario para implementar este comportamiento.

Consiste en extender la clase JTable y sobrescribir el método:
  • public String getToolTipText(MouseEvent e);
Este método debe devolver el mensaje tooltip en función de la posición del ratón. Lo que haremos en este método será lo siguiente:
  1. Recuperar la fila y columna donde está apuntando el ratón
  2. Ver la clase (Class) de dicha columna
  3. Si podemos y queremos que haya mensaje emergente, extraerlo del valor de dicha celda
Veamos como quedaría dicho método implementado:
public String getToolTipText(MouseEvent e) {
java.awt.Point p = e.getPoint();
int rowIndex = rowAtPoint(p);
int colIndex = columnAtPoint(p);
int realColIndex = convertColumnIndexToModel(colIndex);
TableModel model = getModel();

if(model.getColumnClass(colIndex).equals(String.class))
return (String) model.getValueAt(rowIndex, realColIndex);
if(model.getColumnClass(colIndex).equals(Boolean.class)) {
Boolean checked = (Boolean) model.getValueAt(rowIndex, realColIndex);
if(checked)
return "Checked";
else
return "Unchecked";
}
/*
* Aqui podemos añadir todos los tipos que queramos.
* En mi caso sólo tengo String y Boolean pero podríamos tener
* enteros o cualquier otro tipo, por ejemplo para enteros sería:
* if(model.getColumnClass(colIndex).equals(Integer.class))
*  return ((Integer) model.getValueAt(rowIndex, realColIndex)).toString();
*/
return "";
}

Ahora, si queremos que las cabeceras también devuelvan un tooltip con el nombre que tienen asociado, debemos también liar una buena. En concreto:
  1. Implementar el método
    protected JTableHeader createDefaultTableHeader()
  2. Devolver un objeto JTableHeader que sobrescriba el método
    public String getToolTipText(MouseEvent e)
  3. En dicho índice recuperar el índice de columna donde está apuntando el puntero del ratón
  4. Devolver el título asociado a dicha columna
Veamos dicha implementación:
protected JTableHeader createDefaultTableHeader() {
return new JTableHeader(columnModel) {
public String getToolTipText(MouseEvent e) {
java.awt.Point p = e.getPoint();
int index = columnModel.getColumnIndexAtX(p.x);
int realIndex = columnModel.getColumn(index).getModelIndex();
return getModel().getColumnName(realIndex);
}
};
}

Con esto tenemos un JTable que muestra tooltips en función de su contenido, algo que en mi opinión podría venir implementado en la clase JTable y que pudiera activarse mediante una simple llamada a un método pasándole como argumento un booleano.
Para finalizar, veamos la clase al completo:
public class TooltipJTable extends JTable {

@Override
public String getToolTipText(MouseEvent e) {
java.awt.Point p = e.getPoint();
int rowIndex = rowAtPoint(p);
int colIndex = columnAtPoint(p);
int realColIndex = convertColumnIndexToModel(colIndex);
TableModel model = getModel();

if(model.getColumnClass(colIndex).equals(String.class))
return (String) model.getValueAt(rowIndex, realColIndex);
if(model.getColumnClass(colIndex).equals(Boolean.class)) {
Boolean checked = (Boolean) model.getValueAt(rowIndex, realColIndex);
if(checked)
return "Checked";
else
return "Unchecked";
}
return "";
}

@Override
protected JTableHeader createDefaultTableHeader() {
return new JTableHeader(columnModel) {

@Override
public String getToolTipText(MouseEvent e) {
java.awt.Point p = e.getPoint();
int index = columnModel.getColumnIndexAtX(p.x);
int realIndex = columnModel.getColumn(index).getModelIndex();
return getModel().getColumnName(realIndex);
}
};
}
}

Saludos

2 comentarios:

Anónimo dijo...

amigo puedes poner el codigo fuente para ver como lo as echo , porfavor

enzo dijo...

Muchas gracias amigo.
Me ayudara mucho en mi proyecto.

Publicar un comentario