Vertical Table Header Cell Renderer
Posted by Darryl Burke on March 6, 2009
Does your JTable have short column content, but long column names? Do the column headers take up more horizontal space than you can spare?
No longer do you need to resort to cryptic two and three letter column headings in an attempt to solve this problem. Just rotate your table header text to the vertical, using VerticalTableHeaderCellRenderer.
This class makes use of two classes published earlier, extending DefaultTableHeaderCellRenderer and using a VerticalLabelUI to handle the actual vertical rendering.
To use the VerticalTableHeaderCellRenderer, for the entire header, set it as the header renderer for each column of the table.
TableCellRenderer headerRenderer = new VerticalTableHeaderCellRenderer();
Enumeration columns = table.getColumnModel().getColumns();
while (columns.hasMoreElements()) {
columns.nextElement().
setHeaderRenderer(headerRenderer);
}
Note that setting this class as the default renderer for the table’s header will not suffice, as the table header’s UI delegate, BasicTableHeaderUI, will fail to provide adequate height for any vertical header taller than the first.
If all column headers are not to be rendered with vertical text, set the renderer for the remaining columns to a DefaultTableHeaderCellRenderer, published earlier. This will vertically align the horizontal text at the bottom of the header instead of at the center.
VerticalTableHeaderCellRenderer extends DefaultTableHeaderCellRenderer.
Get The Code
VerticalTableHeaderCellRenderer.java
Jeff said
Note that this appears to require 1.6
Darryl Burke said
Yup. Please feel free to trim it down to work with an earlier version — you’ll need to remove anything related to row sorting from both VerticalTableHeaderCellRenderer and its superclass DefaultTableHeaderCellRenderer.
cheers, Darryl
kalebo said
what is package darrylbu.renderer? i cann’t make this code work.help please.
Andre Uhres said
How can I change the font of the table header?
Darryl Burke said
One way I can see to do this is to override getTableCellRendererComponent:
cheers, Darryl
Andre Uhres said
Yes, that works, thanks. I was trying to set the font to the header like this:
final JTableHeader header = table.getTableHeader();
header.setFont(header.getFont().deriveFont(Font.BOLD));
This works for normal header but not with your vertical table header.
Baze said
Hi all,
I have one question!
I want to add a mouse listener for the header cell renderer,
but its not working! no events are produced.
why?!
TableCellRenderer headerRenderer = new VerticalTableHeaderCellRenderer() {
Font font = new Font(Font.MONOSPACED, Font.ITALIC, 12);
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
super.getTableCellRendererComponent(table, value, isSelected,
hasFocus, row, column);
setFont(font);
addMouseListener(new SomeMyMouseListener());
return this;
}
};
Anonymous said
Baze, renderers are not added to a component hierarchy and do not respond to input events. You cannot add a MouseListener to this or any other renderer.
Darryl
Baze said
Hi Darryl,
First tnx for your replay!
I read the spec/docs for default table cell renderer and of course you are right. But how than I can catch a mouse event on one column/header, this is possible I’m sure:) because its implemented in Firefox and in Thunderbird. On mouse over they change the color of the background for thet specific column header and paint low border in orange color.
If I try with table.getTableHeader() and add some listener to it, i get the hole table header not the column headers of course, also I try it to go throw all components witch the table header is holding and it came out that it has just one CellRendererPane witch is responsable for painting the column headers but dose not hold them…?!
Any help would be nice,
Tnx Baze
Darryl Burke said
Baze, this blog page is specifically about a renderer. As already said, renderers do not respond to input events.
I suggest you take your question to an appropriate forum, like forums.sun.com, java-forums.org or javaranch.com.
Darryl
Shane said
Like the results. Two questions though.
How to add some additional padding (top and bottom) to allow the text to move up slightly off the bottom of the component and how to deal with row sorting (as the table adds bloody icon!!)
Shane said
Okay, kinda working.
I added a “space” infront of the text to provide a small amount padding.
I also adjusted the sort icon so that it appears in front of the text (and instead of translating by -maxSize, I did -(maxSize / 1.5f) which makes it look about right…need to test some other l&fs)
Darryl Burke said
> I added a “space” infront of the text to provide a small amount padding.
The better way to do that would be
UIManager.put("TableHeader.cellBorder",
new BorderUIResource(new CompoundBorder(defaultBorder, new EmptyBorder(5, 0, 0, 0))));
> I also adjusted the sort icon so that it appears in front of the text
Not sure what you mean by that, but I’m happy you could understand the code and modify it to suit your need. If I’m guessing right, you might get the desired result by these settings:
((JLabel)headerRenderer).setHorizontalTextPosition(JLabel.RIGHT);
((JLabel)headerRenderer).setVerticalTextPosition(JLabel.CENTER);
You would then have to deal with sizing the header height to accommodate the icon.
Darryl
Darryl Burke said
Oops, sorry. Before that first code snippet, add
Border defaultBorder = UIManager.getBorder("TableHeader.cellBorder");
Shane said
Thanks Darryl!
Please excuse my brashness, it was Friday and I’d been betting my head against a series of brick walls.
I’m enjoying reading through your suggestions!!
Shane
Anonymous said
It works great, But has anybody try this header include in another Theme like Nimbus or Quaqua?
m n m farhan said
how to set background color to table header. thanks.
mnmfarhan@gmail.com
Darryl Burke said
You question does not appear to have anything to do with the subject of this page and would be better asked on a Java forum.
Aqeel Haider said
I have an error on line. “cannot find method setHeaderRenderer(headerRenderer)”. Any Ideas
Darryl Burke said
You’re trying to set the header renderer of something other than a TableColumn,
Julien said
My comment was deleted, so i resend it.
I am looking for a diagonal header cell renderer like http://www.mcstech.net/blog/images/posts/diagonal_data.png
Can you adapt your code to this ?
Or have you got an idea to do this ?
Thanks for your help.