I am trying to organise a frame according to the following pattern:
_______________________
| ___________________ |
| | + + + + + | |
| | + + | |
| |___________________| |
| ___________ |
| | + + + | |
| |___________| |
|_______________________|
Here are my requirements:
For the nested JPanel(s), it seems to me that a FlowLayout
is the best solution, and I tried to used a BoxLayout
and a GridBagLayout
for organising my panels, but without success: the internal components never wrap.
Here is my code:
public class Example {
private static final int NB1 = 5;
private static final int NB2 = 13;
private static final int NB3 = 15;
public static void main(String[] args) {
JFrame f = new JFrame();
f.setTitle("Example");
f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
f.setSize(300,600);
JPanel p1 = new JPanel(new FlowLayout(FlowLayout.CENTER));
p1.setBorder(new TitledBorder(new LineBorder(Color.BLACK), "JPanel 1"));
for(int i=0; i<NB1; i++)
p1.add(new JButton("Button " + i));
JPanel p2 = new JPanel(new FlowLayout(FlowLayout.CENTER));
p2.setBorder(new TitledBorder(new LineBorder(Color.BLACK), "JPanel 2"));
for(int i=NB1; i<NB2; i++)
p2.add(new JButton("Button " + i));
JPanel p3 = new JPanel(new FlowLayout(FlowLayout.CENTER));
p3.setBorder(new TitledBorder(new LineBorder(Color.BLACK), "JPanel 3"));
for(int i=NB2; i<NB3; i++)
p3.add(new JButton("Button " + i));
// JPanel global = new JPanel(new GridBagLayout());
// GridBagConstraints gbc = new GridBagConstraints();
// gbc.gridy = 0;
// global.add(p1, gbc);
// gbc.gridy++;
// global.add(p2, gbc);
// gbc.gridy++;
// global.add(p3, gbc);
JPanel global = new JPanel();
Box vb = Box.createVerticalBox();
vb.add(p1);
vb.add(Box.createVerticalStrut(10));
vb.add(p2);
vb.add(Box.createVerticalStrut(10));
vb.add(p3);
global.add(vb);
f.add(global);
f.setVisible(true);
}
}
If you have any idea how to proceed...
Thank you!
For you layout you need to make sure that the panel will fill the horizontal space when the frame is resized.
However, you still can't use the FlowLayout because FlowLayout does not recalculate the preferred size of the panel as the components wrap. Instead you need to use the Wrap Layout which will recalculate the preferred size.
Here is the updated example with "panel 2" using the WrapLayout
and the GridBagLayout changes:
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class Example2 {
private static final int NB1 = 5;
private static final int NB2 = 13;
private static final int NB3 = 15;
public static void main(String[] args) {
JFrame f = new JFrame();
f.setTitle("Example2");
f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
JPanel p1 = new JPanel(new FlowLayout(FlowLayout.CENTER));
p1.setBorder(new TitledBorder(new LineBorder(Color.BLACK), "JPanel 1"));
for(int i=0; i<NB1; i++)
p1.add(new JButton("Button " + i));
// JPanel p2 = new JPanel(new FlowLayout(FlowLayout.CENTER));
JPanel p2 = new JPanel(new WrapLayout(FlowLayout.CENTER));
p2.setBorder(new TitledBorder(new LineBorder(Color.BLACK), "JPanel 2"));
for(int i=NB1; i<NB2; i++)
p2.add(new JButton("Button " + i));
JPanel p3 = new JPanel(new FlowLayout(FlowLayout.CENTER));
p3.setBorder(new TitledBorder(new LineBorder(Color.BLACK), "JPanel 3"));
for(int i=NB2; i<NB3; i++)
p3.add(new JButton("Button " + i));
JPanel global = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL; // added
gbc.weightx = 1.0f; // added
gbc.gridy = 0;
global.add(p1, gbc);
gbc.gridy++;
global.add(p2, gbc);
gbc.gridy++;
global.add(p3, gbc);
f.add(global);
f.pack();
f.setVisible(true);
}
}