Often I have tables where the cell width is smaller than the cell content. The DefaultTableCellRenderer always clips the text on the right, which is a problem since often the rightmost part is of importance. (E.g. complete file path).

So I wrote a renderer which would clip on the left.

Its not the most efficient one and only supports single line text and no HTML. Also, I had to put in a small dirty workaround to get the display correctly (See line 21). A side effect is some extra space on the right.

For now it satisfies my needs, but any better ideas are welcome.

1    import javax.swing.*; 
2    import javax.swing.table.DefaultTableCellRenderer; 
3    import java.awt.*; 
4     
5    public class LeftClippingRenderer extends DefaultTableCellRenderer { 
6      public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, 
7                                                     boolean hasFocus, int row, int column) { 
8     
9        String clippedText = getLeftClippedText((String) value, table, row, column); 
10       Component component = super.getTableCellRendererComponent(table, clippedText, isSelected, 
11                                                                 hasFocus, row, column); 
12       setToolTipText((String) value); 
13       return component; 
14     } 
15    
16     private String getLeftClippedText(String strValue, JTable table, int row, int column) { 
17       int widthForPainting; 
18       int stringWidth; 
19       int strValueLen = strValue.length(); 
20       //I needed to give some extra space to get the clipping to work correctly. Dirty but works. 
21       int extraSpace = SwingUtilities.computeStringWidth(getFontMetrics(getFont()), "W"); 
22       int availableWidth = table.getCellRect(row, column, false).width - extraSpace; 
23       widthForPainting = availableWidth - getInsets().left + getInsets().right; 
24       FontMetrics fm = getFontMetrics(this.getFont()); 
25       stringWidth = SwingUtilities.computeStringWidth(getFontMetrics(getFont()), strValue); 
26       int index = 0; 
27       if (widthForPainting > 0 && stringWidth > widthForPainting) { 
28         while (stringWidth > widthForPainting && index < strValueLen) { 
29           index += 1; 
30           String testStr = "..." + strValue.substring(index); 
31           stringWidth = fm.stringWidth(testStr); 
32         } 
33         strValue = "..." + strValue.substring(index); 
34       } 
35       return strValue; 
36     } 
37   }

If you know of a better way to do this, please use the comments link below to let me know.

Advertisements