How can I prevent a LayoutManager from shrinking my components too much?
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.
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.
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.
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
Result resized
Maybe you could try MigLyout. It's really good layout manager.
精彩评论