Question

How can I prevent GUI components from shrinking on resizing in a BorderLayout Manager? Is it possible to set a minimum size so that components do not shrink beyond it? It seems using setBounds does not work with Layout Managers.

Just one more question: If I used nested panels, is it possible to assign them fixed positions and let the layout manager takes care of the components inside these panels? I'm trying to prevent GUI components from moving around.

Was it helpful?

Solution

Unfortunately, whether a layout manager honors minimum size, max size, etc is up to the layout manager implementation. This leads to a lot of confusing behavior because not all layout managers honor them, and BorderLayout doesn't honor those constraints.

BoxLayout will honor those values. JComponent.setBounds is what the LayoutManager will use to set the bounds of a child so your layout manager will probably overwrite whatever you put in there. If you are trying to limit how small something can get I'd suggest setting a minimum size on your JFrame or JDialog then that prevent someone from making it too small causing the layout manager to do funny things.

My first suggestion for anyone doing Swing is grab TableLayout, spend 15 minutes to learn it, and most of your layout problems can be solved. I don't know if that applies to what you're doing, but it won't be long before you have a layout problem that requires it. TableLayout allows you to specify which things grow or shrink, and if the window is too small to show it then it doesn't resize them smaller than the preferred size.

https://www.oracle.com/technetwork/java/tablelayout-141489.html

I'm not sure exactly what your trying to do to offer any better advice.

OTHER TIPS

How to prevent GUI components from shrinking on resizing in a BorderLayout Manager? Is it possible to set a minimum size so that components do not shrink beyond it?

problem for me should be to set MaximumSize for majority of LayoutManagers as I want to, but Minimum & PreferredSize works as I expected, just basic example

layed by BorderLayout , expecting CENTER area

import java.awt.*;
import javax.swing.*;

public class CustomComponent extends JFrame {

    private static final long serialVersionUID = 1L;

    public CustomComponent() {
        setTitle("Custom Component Test / BorderLayout");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public void display() {
        add(new CustomComponents(), BorderLayout.NORTH);
        add(new CustomComponents(), BorderLayout.CENTER);
        add(new CustomComponents(), BorderLayout.SOUTH);
        add(new CustomComponents(), BorderLayout.EAST);
        pack();
        // enforces the minimum size of both frame and component
        setMinimumSize(getMinimumSize());
        setPreferredSize(getPreferredSize());
        setVisible(true);
    }

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

class CustomComponents extends JLabel {

    private static final long serialVersionUID = 1L;

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

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

    @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);
    }
}

layed by GridLayout

import java.awt.*;
import javax.swing.*;

public class CustomComponent1 extends JFrame {

    private static final long serialVersionUID = 1L;

    public CustomComponent1() {
        setTitle("Custom Component Test / GridLayout");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public void display() {
        setLayout(new GridLayout(0, 1));
        add(new CustomComponents());
        add(new CustomComponents());
        add(new CustomComponents());
        add(new CustomComponents());
        pack();
        // enforces the minimum size of both frame and component
        setMinimumSize(getMinimumSize());
        setPreferredSize(getPreferredSize());
        setVisible(true);
    }

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

class CustomComponents extends JLabel {

    private static final long serialVersionUID = 1L;

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

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

    @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);
    }
}

Just one more question: If I used nested panels, is it possible to assign 
them fixed positions and let the layout manager takes care of the components 
inside these panels?

yes I can't see any problem for most complete GUI, problem should be layout just a few JComponents into GUI correctly, but for that you have to ask real question

You can use setMinimumSize, setMaximumSize and setPreferredSize to control how big your components will be (though some layout managers will necessarily ignore these if they conflict with the requirements of the layout manager).

You shouldn't use setBounds when you are using a layout manager because setBounds is the mechanism by which the layout manager sizes the components, so any bounds you set will be over-ridden by the layout manager.

Maybe you could try MigLyout. It's really good layout manager.

I was looking for a solution to a similar issue and i found very interesting documentation here (it solved my problem) : http://javadude.com/articles/layouts/#blHow

In fact you just need to set the preferedSize of your component when using BorderLayout (see the link for more information)

example

JFrame jframe = new JFrame("test Borderlayout");
jframe.setLayout(new BorderLayout());

JButton button1 = new JButton("1");
JButton button2 = new JButton("2");
button2.setPreferredSize(new Dimension(200,0));

jframe.add(button1,BorderLayout.CENTER);
jframe.add(button2, BorderLayout.EAST);

jframe.setSize(300, 100);
jframe.setVisible(true);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

In the example above, button2 will not shrink (keeping his width to 200 pixels), even when you resize.

Result

enter image description here

Result resized

enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top