tags:

views:

266

answers:

3

I need to know when the text for a JButton is truncated by the layout. So, in order to find out I am overriding the following method in our custom ButtonUI delegate:

protected void paintText(Graphics g, JComponent c, Rectangle textRect, String text) {
    //the text argument will show an ellipse (...) when truncated
}

Inside the method I check to see if the text argument ends with an ellipse.

Is there a better way for me to check if the text is truncated? What about the ellipse? Is that the universal symbol for truncated text, or do I need to look for localized symbols that will demarcate truncated text?

I noticed that OSX will use a single character representing the ellipse and Windows will use three periods. I assume this is based on the font being used, but it got me thinking of other things that may sneak up on me.

Thanks.

+1  A: 

Wouldn't it work if you compare the text passed to your paintText method with the text returned from ((AbstractButton)c).getText()? If it is different, the text has been truncated.

Eventually, the truncation itself is done in SwingUtilities.layoutCompoundLabel and it's possible for you to call that method yourself, but it doesn't seem particularly easy to calculate all arguments you need for using that method directly.

jarnbjo
I like this solution. I can stop looking for an ellipse and just show the tooltip anytime the text differs.
Tony Eichelberger
+1  A: 

I have put together a small app to demonstrate how you can figure it out. The meat is in the overriden getToolTipText() method in my JButton. It tests the size of the button, accounting for the right and left insets, against the size of the text, using 'FontMetrics'. If you run the demo, you can resize the window and hover over to attempt to get the tool tip. I should only show if there is an ellipsis. Here is the code:

public class GUITest {
    JFrame frame;
    public static void main(String[] args){
        new GUITest();
    }
    public GUITest() {
        frame = new JFrame("test");
        frame.setSize(300,300);
        addStuffToFrame();
        SwingUtilities.invokeLater(new Runnable(){
            public void run() {
                frame.setVisible(true);
            }
        });
    }    

    private void addStuffToFrame() {    
        JPanel panel = new JPanel();
        JButton b = new JButton("will this cause an elipsis?") {
            public String getToolTipText() {
                FontMetrics fm = getFontMetrics(getFont());
                String text = getText();
                int textWidth = fm.stringWidth(text);
                return (textWidth > (getSize().width - getInsets().left - getInsets().right) ? text : null);
            }
        };
        ToolTipManager toolTipManager = ToolTipManager.sharedInstance();
        toolTipManager.registerComponent(b);
        frame.setContentPane(b);
    }


}
akf
This approach is too naive, at least for generic functionality. It does not consider the button's insets (internal border around the text), if the button displays an icon and the gap between the icon and the text. It will also fail if the text contains HTML markup.
jarnbjo
+1  A: 

I would guess that the ellispse will shown when

getPrefferredSize().width > getSize().width
camickr