Implementing Variable-Height Column Headers in a JTable Component
The default table header renderer for a table is assumed to render all
column heads with the same preferred height. If you install a default
header renderer that breaks this assumption, your column heads may not
be rendered correctly. In particular, the height of the entire header
is made just high enough to satisfy the first column head. If the
preferred height of any other column head is higher, that column will
not be given enough area to display its contents properly.
Here is how the height of the header is determined.
Check the first visible column for an installed header renderer.
If one exists, it is used to compute a height.
Otherwise, the default header renderer is used to compute a height.
Now check every other column for a header renderer and
if one exists, use it to compute a height.
The final height is the maximum of all computed heights.
Therefore, if a column other than the first lacks a header
renderer and produces a taller height with the default header
renderer, it will never be computed and so won't be given the correct
height. The solution to this problem is to assign a header renderer
to the column to ensure that a height is computed for that column,
even if the renderer is identical to the default header renderer.
This example implements a header renderer that can display
either text or an icon, depending on what is set in the column header
value. Since the height of a column head with an icon depends on the
height of the icon, this icon renderer is set on all columns with
icons.
DefaultTableModel model = new DefaultTableModel();
JTable table = new JTable(model);
// Create 2 columns
model.addColumn("Col1");
model.addColumn("Icon Here");
// the header value for this column will be overwritten
// with an Icon object. There is no point supplying the
// Icon object in the addColumn() call because it will be
// converted to a string.
// Now set the second column with an Icon as the column header value
int vColIndex = 1;
table.getColumnModel().getColumn(vColIndex).setHeaderValue(
new ImageIcon("image.gif"));
// Finally, set the icon header renderer on the second column
table.getColumnModel().getColumn(vColIndex)
.setHeaderRenderer(iconHeaderRenderer);
// Use this renderer for table headers that contain icons
TableCellRenderer iconHeaderRenderer = new DefaultTableCellRenderer() {
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
// Inherit the colors and font from the header component
if (table != null) {
JTableHeader header = table.getTableHeader();
if (header != null) {
setForeground(header.getForeground());
setBackground(header.getBackground());
setFont(header.getFont());
}
}
if (value instanceof Icon) {
// Value is an Icon
setIcon((Icon)value);
setText("");
} else {
// Value is text
setText((value == null) ? "" : value.toString());
setIcon(null);
}
setBorder(UIManager.getBorder("TableHeader.cellBorder"));
setHorizontalAlignment(JLabel.CENTER);
return this;
}
};
Post a comment