0

I have JLabel which I would like to change its size while I resize the window. When JLabel contains String which is too big, the String should be shortened, with right part visible and adds dots on the left hand side of the String.

My JLabel is inside innerPanel which is a header in middlePanel which is added to outerPanel. So when I resize window I use listener on outerPanel in that way:

outerPanel.addComponentListener(new ComponentListener() {
    @Override
    public void componentResized(ComponentEvent evt) {
       int width = ((JPanel) evt.getSource()).getWidth();
       windowSize = width;
       refresh();
    }

    // [...] other not used override methods
}); 

refresh() repaints view and creates new middlePanel where is called class which creates innerPanel where is located my JLabel:

Public class InnerPanel extends JPanel {
    private int maxSize;
    String string = "<VERY_LONG_STRING>";
    private static final int DEFAULT_INDEND_PIXEL = 70;

    public InnerPanel(int windowSize) {
        maxSize = windowSize - DEFAULT_INDENT_PIXEL;
        createPanel();
    }

    private createPanel() {
        // [...] gridbag and GridBagConstraints implementation

        String shortString = countString();
        JLabel label = new JLabel(shortString);
        add(label,gc);
    }

    private String countString() {
        int index = 0;
        boolean toBig = true;  
        StringBuilder sb = new StringBuilder(string);

        while(toBig) {
            Rectangle2d rect = // [...] code which creates rectangle around text from sb.toString()
            // I have no access to repo at home but if it's important I can paste it tomorrow

            if(rect.getWidth() > maxSize)
                sb.deleteCharAt(0);
            else
                toBig = false;
        }

        return sb.toString();
   }
}

That's works fine in general, bacause it do resize JLabel in one step when I enlarge window in width. But the problem is appear when I try to reduce the window in width. In this case componentResized() calculate width step by step (and it's called multiple times), gradually decreases width by some amount of pixels till it reach real window size. It's behave in that way even thow I change window size in one step from maximum size to 800. Whole process is so slow, that it takes around a second to fit string to window size. So it looks bit like an animation.

The problem is very rare to me, bacause width in componentResized() method is calculeted step by step only when I assign windowSize variable.

When I give windowSize fixed size like for example 500 - componentResized() is called only onces - with correct width indicated real window size (!!) - and there's no its step by step decrease!

It's look like width variable which is assigned by ((JPanel) evt.getSource()).getWidth() knows that windowSize is used to dynamically change size of JLabel component even before first call of refresh() method.

If anyone have an idea what is going on here - I will be very appreciate for help.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
Ziemo
  • 941
  • 8
  • 27

1 Answers1

1

You may be able to adapt one of the approaches shown here to better effect. As shown here, the ellipsis is supplied by the label's UI delegate via a call to SwingUtilities2.clipString(), which appends the clipString. Rather than re-invent the label UI, use TextLayout to determine the required geometry, prepend the ellipsis, and handle the alignment in a table or list renderer, as shown here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045