0

I'm trying to write a panel with 3 vertical section in MigLayout: top growing, middle fixed and bottom growing.

The top is a JLabel with font-size-based-on-container-size. The middle is also a Jlabel, and the bottom is currently an empty JPanel.

Enlarging window is ok: Enlarging window

When I resize back the window, content doesn't resize back (note that the problem is not the font size, but the container width): enter image description here

This problem exists only when in overrided method paint (see below) is called setFont on timer JLabel.

public class TabRace extends JPanel {
    private JLabel timer;

    public TabRace() {
        super();

        // Set the layout
        this.setLayout(new MigLayout("","[grow]","[grow][][grow]"));

        // Timer label
        timer = new JLabel("00:00:00.000");
        timer.setOpaque(true);
        timer.setBackground(new Color(0, 0, 0));
        timer.setForeground(new Color(255, 255, 255));
        this.add(timer,"grow,wrap");

        // Table label
        JLabel tableCaption = new JLabel("Last Records:");
        this.add(tableCaption,"wrap");

        JPanel bottom = new JPanel();
        this.add(bottom, "grow,wrap");

    }

    public void paint(Graphics g) {
        super.paint(g);

        // Thanks to coobird
        // @see https://stackoverflow.com/questions/2715118/how-to-change-the-size-of-the-font-of-a-jlabel-to-take-the-maximum-size

        Font labelFont = timer.getFont();
        final int stringWidth = timer.getFontMetrics(labelFont).stringWidth(timer.getText());
        final int componentWidth = timer.getWidth();

        // Find out how much the font can grow in width.
        double widthRatio = (double)componentWidth / (double)stringWidth;

        int newFontSize = (int)(labelFont.getSize() * widthRatio);
        int componentHeight = timer.getHeight();

        // Pick a new font size so it will not be larger than the height of label.
       int fontSizeToUse = Math.min(newFontSize, componentHeight);

       // Set the label's font size to the newly determined size.

       // REMOVING NEXT LINE AND RESIZING IS WORKING
       timer.setFont(new Font(labelFont.getName(), Font.PLAIN, fontSizeToUse));

    }

}

I've tried also to put JLabel inside JPanel. Any ideas?

Community
  • 1
  • 1
ocirocir
  • 3,543
  • 2
  • 24
  • 34
  • Why are you doing this in a paint override? This seems dangerous to me. Why not instead use a ComponentListener? – Hovercraft Full Of Eels Aug 09 '14 at 19:50
  • I took [this advice](http://stackoverflow.com/questions/2715118/how-to-change-the-size-of-the-font-of-a-jlabel-to-take-the-maximum-size/2715279#2715279). I can try with listener – ocirocir Aug 09 '14 at 19:54
  • You should never modify the state of a component within paint. It makes absolutely no sense. – Guillaume Polet Aug 09 '14 at 20:32
  • Why should it? How does changing the font size effect the ultimate state of the component? By the time paint is called, the size of component has already been calculated, so you're actually lying ... – MadProgrammer Aug 09 '14 at 20:44
  • @MadProgrammer was the above message destinated to me? Or did I just misunderstood what you meant to say? Cheers :-) – Guillaume Polet Aug 10 '14 at 10:01
  • @GuillaumePolet No, it was a general comment of observation on the OPs question. Why should changing the font size in `paint` affect the size of the component... – MadProgrammer Aug 10 '14 at 10:47

1 Answers1

0

I don't know why, but adding minimum width to first JLabel (or other row) resolves the issue:

this.add(timer,"grow,wrap,wmin 10");
ocirocir
  • 3,543
  • 2
  • 24
  • 34
  • This is because the difference between a minimum size and a preferred size is a component's tendency to shrink. For the label, `MigLayout` seems to set these two sizes to be equal, therefore, the component is not shrinking. However, getting rid of the ellipsis is another story. – Jan Bodnar Aug 11 '14 at 17:03