javatextaccessibilityjlabelbounds

Getting the bounds of the text inside a jlabel


I want to draw an arrow from the text in a JLabel to a point outside the JLabel. To start the arrow at an appropriate place, I need the bounds of the actual text inside the JLabel. My answer below will show how to get those bounds.


Solution

  • To get the bounds of text in a JLabel, we need the accessible context, a protected field. So we extend JLabel. The accessible context only knows about the text if it is HTML, so I prepend "<html>" in the constructor; a more general version would first check to see if the text already begins with that string.

       class FieldLabel extends JLabel {
            FieldLabel(String text) {
                super("<html>"+text);
            }
            Rectangle getTextBounds() {
                JLabel.AccessibleJLabel acclab 
                    = (JLabel.AccessibleJLabel) getAccessibleContext();
                if (acclab.getCharCount() <= 0)
                    return null;
                Rectangle r0 = acclab.getCharacterBounds(0);
                Rectangle rn = acclab
                    .getCharacterBounds(acclab.getCharCount()-1);
    
                return new Rectangle(r0.x, r0.y, 
                        rn.x+rn.width-r0.x, Math.max(r0.height, rn.height));
            }
        }
    

    Other solutions have the potential advantage of not creating three new Rectangle objects per call. This could be a problem if getTextBounds is called in a MouseMoved event listener. At some cost in complexity, the final Rectangle could be cached along with the JLabel width and height.