Thursday, October 23, 2008

Ellipsis (...) in TreeTableView

I use the Idea's TreeTableView to display data in my plugin.
The "tree" part contains the class tree of the current project.

The problem is that when I narrow the tree column the texts just gets truncated without displaying the pretty '...' at the end like it is the case for normal JTable columns.

Most probably this also applies to 'normal' JTree's - I don't have any scrollbar-free JTree at hand to check.

I use a slightly modified DefaultTreeCellRenderer to draw tree nodes, which is practically a JLabel, which in turn should be able to add ellipsis if the component size is too small to contain all the text.

This is the clue - if the renderer has the setSize() set to proper value, it would do the work for you.

A bit of debugging led me to this solution:
Override the paint(Graphics) method of the renderer and manually setSize() of the label just before it is painted.

Where to find the appropriate size? Use the clip bounds that are used to clip the label:
<edit>
Naa, actually clip area is not the right source. This fails when only part of the tree is repainted, for example during scrolling. You would get ellipsis inside of the text.

So, I have changed my renderer to look like this:
private JTree tree;
@Override
public Component getTreeCellRendererComponent(JTree tree, ...) {
// tree size is not known yet for any reason, save for paint()
this.tree = tree;

... // rest of stuff
return this;
}

@Override
public void paint(Graphics g) {
final int maxWidth = tree.getWidth() - getBounds().x;
if (maxWidth < getWidth()) {
setSize(maxWidth, getHeight());
}
super.paint(g);
}

</edit>
Now, the final trick:

Make JLabel draw ellipsis to the left of the text


Like that: '...that'
instead of the default 'Like...'

Solution: reverse the string and give it Right-To-Left direction using unicode marker.
Underlying LabelUI will take care to display it the way you want :-)
(would not work in a RightToLeft environment without modification, but you probably have more serious bugs then ellipsis on the wrong side anyway, right?)

Java snippet:
final String mangledStr = new StringBuilder(str).append('\u202e').reverse().toString();
setText(mangledStr);

3 comments:

Marcin Gorycki said...

This is evil stuff :)

Sami Andoni said...

Oh, Thxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Ondrej Medek said...

Make JLabel draw ellipsis to the left of the text: thanks for this evil hack. Why Java has not methods for this?

Post a Comment