Java Tips Weblog

  • Blog Stats

    • 2,571,737 hits
  • Categories

  • Archives

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);
}

verticaltableheadercellrenderer

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

See Also

Default Table Header Cell Renderer
Vertical Label UI

21 Responses to “Vertical Table Header Cell Renderer”

  1. Jeff said

    Note that this appears to require 1.6

  2. 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:

      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);
            return this;
         }
      };
      

      cheers, Darryl

  3. 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.

  4. 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

  5. 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

  6. 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");

  7. 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

  8. Anonymous said

    It works great, But has anybody try this header include in another Theme like Nimbus or Quaqua?

  9. m n m farhan said

    how to set background color to table header. thanks.
    mnmfarhan@gmail.com

  10. I have an error on line. “cannot find method setHeaderRenderer(headerRenderer)”. Any Ideas

  11. 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.

Leave a comment