I have an SWT Tree (via a JFace TreeViewer), that displays items in columns, some of which have long strings. The end of the string is the meaningful bit for the user, not the start, so when the text is clipped I want the clipping to occur at the start of the string and not the end. Example:
The default behaviour for a cell containing something like: “This is a very long string that completely exceeds the bounds of the tree column” is:
|This is a very l...|
Where as I want:
|... the tree column|
EDIT:
I solved this with a custom PaintItem listener as described here: http://www.eclipse.org/articles/article.php?file=Article-CustomDrawingTableAndTreeItems/index.html
Came up with the following code (not quite perfect, some duplication & magic numbers in there):
tree.addListener(SWT.EraseItem, new Listener()
{
public void handleEvent(Event event)
{
String text = ((TreeItem)event.item).getText(event.index);
Point size = event.gc.textExtent(text);
TreeColumn column = ((Tree)event.widget).getColumn(event.index);
int columnWidth = column.getWidth() - 10; /* magic number alert - the cells have some padding - must be a way of determining this... */
if(size.x > columnWidth)
{
event.detail &= ~SWT.FOREGROUND;
}
}
});
tree.addListener(SWT.PaintItem, new Listener()
{
@Override
public void handleEvent(Event event)
{
String text = ((TreeItem)event.item).getText(event.index);
Point size = event.gc.textExtent(text);
TreeColumn column = ((Tree)event.widget).getColumn(event.index);
int columnWidth = column.getWidth() - 10; /* magic number alert - the cells have some padding - must be a way of determining this... */
if(size.x > columnWidth)
{
drawTextTail(event, text, columnWidth);
}
}
private void drawTextTail(Event event, String text, int columnWidth)
{
String clippedText = "";
int offset = text.length() - 1;
String nextClippedText = text.charAt(offset) + clippedText;
while(fits(nextClippedText, columnWidth, event.gc))
{
clippedText = nextClippedText;
offset--;
nextClippedText = text.charAt(offset) + clippedText;
}
event.gc.drawText("..." + clippedText,
event.x + 5, /* magic number alert - the cells have some padding - must be a way of determining this... */
event.y, false);
}
private boolean fits(String clippedText, int columnWidth, GC gc)
{
Point size = gc.textExtent("..." + clippedText);
return size.x < columnWidth;
}
});
Try this. The second column automatically crops the
Stringto fit into the column.It might need some fixing to really show the
...in front of the croppedString, but it’s a start.