While there are many examples of JTable cell renderers spread on the Internet, they lack a clear understanding about how they were proposed to work. This article presents and explains a minimal and correct cell renderer, extending the default cell renderer as supposed by the Java API. The example explains how to display icons instead of text.
Originally published at https://techtavern.wordpress.com.
For the hurried, first the code:
public class EnumIconCellRenderer extends DefaultTableCellRenderer {
private final Map<!--?, ImageIcon--> icones;
public EnumIconCellRenderer(final Map<!--?, ImageIcon--> icones) {
// Initialize data used to render cells.
this.icones = icones;
// Set properties that never change.
this.setHorizontalAlignment(JLabel.CENTER);
this.setVerticalAlignment(JLabel.CENTER);
this.setText(null);
}
@Override
protected void setValue(Object value) {
// Set properties that change on individual cells.
this.setIcon(icones.get(value));
}
}
A cell renderer works like a rubber-stamp for each cell in the table. The renders uses a Swing component to draw the first cell, changes the contents of that cell renderer, and for each following row shifts the origin of the component to the new location, then re-draws it. The default cell renderer uses the convenient JLabel to stamp a potentially inconvenient toString() representation of data objects. Note that getTableCellRendererComponent() returns itself (the JLabel), but properly configured for an individual cell. Therefore, setting properties of the renderes itself actually configures the component returned by getTableCellRendererComponent().