I’m trying to get a custom ToolTip for a specific column of a JTable. I’ve already created a CellRenderer (of which I’ve been changing other cell-specific attributes successfully):
private class CustomCellRenderer extends DefaultTableCellRenderer
{
private static final long serialVersionUID = 1L;
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
{
JComponent c = (JComponent) super.getTableCellRendererComponent(table, value,
isSelected, hasFocus, row, column);
if (value != null)
{
if(column == 1 && value instanceof Date)
{
final DateFormat df = new SimpleDateFormat("h:mm aa");
table.setValueAt(df.format(value), row, column);
}
else if(column == 2)
{
c.setToolTipText((String) value);
}
else if(column == 4)
{
final Mail m = main.selectedPage.messages.get(row);
JCheckBox checkBox;
if((Boolean) value)
{
checkBox = new JCheckBox()
{
@Override
public JToolTip createToolTip()
{
System.out.println("Passed");
return new ImageToolTip(m.getImage());
}
};
checkBox.setToolTipText(m.attachName);
}
else
checkBox = new JCheckBox();
checkBox.setSelected(((Boolean)value).booleanValue());
c = checkBox;
}
}
else
{
c.setToolTipText(null);
}
return c;
}
}
When I override any other JComponent’s createTooltip() method like so, it all works fine outside of the Renderer.
checkBox = new JCheckBox()
{
@Override
public JToolTip createToolTip()
{
System.out.println("Passed");
return new ImageToolTip(m.getImage());
}
};
From what I can tell, the tooltip is created elsewhere, because “Passed” is never even printed. The checkBox.setToolTipText(m.attachName); only results in a default ToolTip with that String.
I’ve found someone with a similar question, but I can’t say I completely understand the only resolving answer. Do I need to extend JTable and override getToolTipText(MouseEvent e)? If so, I’m not sure what with to get the correct (mine) Tooltip.
Please excuse any of my self-taught weirdness. Thanks in advance. 🙂
EDIT:
Thanks to Robin, I was able to piece together something based on JTable’s getToolTipText(MouseEvent e) code. I’ll leave it here for anyone else with a similar problem. Again, I’m not sure it this it the best way to do it, so feel free to critique it below. 🙂
messageTable = new JTable()
{
@Override
public JToolTip createToolTip()
{
Point p = getMousePosition();
// Locate the renderer under the event location
int hitColumnIndex = columnAtPoint(p);
int hitRowIndex = rowAtPoint(p);
if ((hitColumnIndex != -1) && (hitRowIndex != -1))
{
TableCellRenderer renderer = getCellRenderer(hitRowIndex, hitColumnIndex);
Component component = prepareRenderer(renderer, hitRowIndex, hitColumnIndex);
if (component instanceof JCheckBox)
{
Image img = main.selectedPage.messages.get(hitRowIndex).getImage();
if(((JCheckBox) component).isSelected())
return new ImageToolTip(img);
}
}
return super.createToolTip();
}
}
The reason that the
JTabledoes not use your tooltip can be seen in the implementation. TheJTablewill indeed use the component returned by the renderer, but it will ask it for its tooltip text. So only settings a custom tooltip text will work if you stick to the defaultJTableimplementation. Just a quick copy-paste of the relevant part of theJTablesource code to illustrate this:So yes, you will have to override the
JTablemethod if you really want an image as tooltip for your check box.On a side-note: your renderer code has weird behavior. The
seems incorrect. You should replace the
setValueAtcall by aor something similar. The renderer should not adjust the table values, but create an appropriate component to visualize the data. In this case a
JLabelseems sufficient. And as Stanislav noticed in the comments, you should not constantly create new components. That defeats the purpose of the renderer which was introduced to avoid creating new components for each row/column combination. Note that the method is calledgetTableCellRendererComponent(emphasis onget) and notcreateTableCellRendererComponent