7

I have a JPanel inside BorderLayout.CENTER

The JPanel has a Grid Layout, and I want it to expand with the CENTER for its width, but the height must stop at a maximum and use the preferredSize when possible.

I have this code

JPanel wrapperCenterPanel = new JPanel(new FlowLayout());
wrapperCenterPanel.add(centerPanel);    
panel.add(wrapperCenterPanel, BorderLayout.CENTER);

centerPanel is my panel (uses GridLayout), I'm wrapping it with a FlowLayout panel, and putting this last one in the CENTER.

Now the size is the preferred one, but it's fixed!! The height doesn't shrink if necessary, and neither does the width.

How can I do this?

luca
  • 12,311
  • 15
  • 70
  • 103

3 Answers3

16

Try using a BoxLayout as the wrapper panel. A BoxLayout respects the maximum/minimum and preferred size of a component.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • Many layout managers ignore max size. I don't think the bug you referred to is a layout manager issue. – camickr Oct 13 '11 at 22:32
4

I think that not possible with BorderLayout, especially for BorderLayout.CENTER area, nor without side_effects as blinking UFO on the screen from the code

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ComponentEvent;
import javax.swing.JComponent;
import javax.swing.JFrame;

public class CustomComponent extends JFrame {

    private static final long serialVersionUID = 1L;

    public CustomComponent() {
        setTitle("Custom Component Graphics2D");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public void display() {
        CustomComponents cc = new CustomComponents();
        cc.addComponentListener(new java.awt.event.ComponentAdapter() {

            @Override
            public void componentResized(ComponentEvent event) {
                setSize(Math.min(getPreferredSize().width, getWidth()),
                        Math.min(getPreferredSize().height, getHeight()));
            }
        });
        add(cc, BorderLayout.CENTER);

        CustomComponents cc1 = new CustomComponents();
        add(cc1, BorderLayout.EAST);

        pack();
        // enforces the minimum size of both frame and component
        setMinimumSize(getSize());
        //setMaximumSize(getMaximumSize());
        setVisible(true);

    }

    public static void main(String[] args) {
        CustomComponent main = new CustomComponent();
        main.display();
    }
}

class CustomComponents extends JComponent {

    private static final long serialVersionUID = 1L;

    @Override
    public Dimension getMinimumSize() {
        return new Dimension(100, 100);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(400, 300);
    }

    @Override
    public Dimension getMaximumSize() {
        return new Dimension(800, 600);
    }

    @Override
    public void paintComponent(Graphics g) {
        int margin = 10;
        Dimension dim = getSize();
        super.paintComponent(g);
        g.setColor(Color.red);
        g.fillRect(margin, margin, dim.width - margin * 2, dim.height - margin * 2);
    }
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
2

The FLowLayout layout manager does not redistribute free space; it uses each component's preferred size (see FlowLayout documentation in the Java API).

I personally would change your wrapper panel's layout manager to a GridBagLayout, and add your centerPanel into it, specify a proper GridBagConstraints object to handle the space distribution as you need.

Laf
  • 7,965
  • 4
  • 37
  • 52