Reputation: 497
I would like to create a JPanel that consists of 4 components, laid out in 2 columns. The upper component in the left column should take 60% of vertical space, and the lower component the remaining 40%. In the right column it should be the other way around - the upper component takes 40% and the lower one 60%.
So basically I would like to have my components laid out like on this picture:
I'm trying to achieve this behavior with GridBagLayout
.
public class Test extends JFrame {
JPanel testPanel = new JPanel();
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new Test().setVisible(true);
});
}
Test() {
prepareTestPanel();
setContentPane(testPanel);
setSize(500, 500);
setTitle("Test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void prepareTestPanel() {
testPanel.setLayout(new GridBagLayout());
addComp(makeUpperLeft());
addComp(makeLowerLeft());
addComp(makeUpperRight());
addComp(makeLowerRight());
}
private void addComp(Pair p) {
testPanel.add(p.comp, p.gbc);
}
private Pair makeUpperLeft() {
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createTitledBorder("Upper Left"));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridheight = 60;
gbc.gridwidth = 50;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.LINE_START;
gbc.weightx = 0.5;
gbc.weighty = 0.6;
return new Pair(panel, gbc);
}
private Pair makeLowerLeft() {
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createTitledBorder("Lower Left"));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 60;
gbc.gridheight = 40;
gbc.gridwidth = 50;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.LINE_START;
gbc.weightx = 0.5;
gbc.weighty = 0.4;
return new Pair(panel, gbc);
}
private Pair makeUpperRight() {
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createTitledBorder("Upper Right"));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 50;
gbc.gridy = 0;
gbc.gridheight = 40;
gbc.gridwidth = 50;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.LINE_START;
gbc.weightx = 0.5;
gbc.weighty = 0.4;
return new Pair(panel, gbc);
}
private Pair makeLowerRight() {
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createTitledBorder("Lower Right"));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 50;
gbc.gridy = 40;
gbc.gridheight = 60;
gbc.gridwidth = 50;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.LINE_START;
gbc.weightx = 0.5;
gbc.weighty = 0.6;
return new Pair(panel, gbc);
}
private class Pair {
Component comp;
GridBagConstraints gbc;
public Pair(Component comp, GridBagConstraints gbc) {
this.comp = comp;
this.gbc = gbc;
}
}
}
Unfortunately what I get is:
How should I correct my code? Also, I would like this proportion to remain regardless of how the window is resized. How should I set weighty
?
Upvotes: 1
Views: 692
Reputation: 324098
GridBagLayout doesn't support this easily:
You can't just specify gridwidth/height in the ratio you want. If you want a 6/4 ratio, then you actually would need to create 10 dummy components each the same size an add them to the panel first. Then you can say a component has a gridheight equal to 4 (or 6) of those dummy components.
The weightx/y constraints only apply to the extra space as the frame is resized. So components will initially be packed at their preferred size which mean you also manually need to set the preferred size in your desired ratio.
You can check out the RelativeLayout. It does allow you to easily create components of a relative size based on the space available.
The basic code using this layout would be something like:
RelativeLayout rl = new RelativeLayout(RelativeLayout.Y_AXIS);
rl.setFill( true );
JPanel left = new JPanel( rl );
left.add(upperLeft, new Float(60));
left.add(lowerLeft, new Float(40));
// repeat above for the right panel
JPanel main = new JPanel( new GridLayout(0, 2) );
main.add(left);
main.add(right);
frame.add(main);
Upvotes: 2
Reputation: 113
This cannot be done directly within one container. You will have to create two container elements (say two more JPanel
object) for both of your columns. Add your columns in the outer container, and then, add your components in the inner Panels. Here is some code that does that:
public class Test extends JFrame {
public Test() {
JPanel testPanel = new JPanel();
setContentPane(testPanel);
GridBagLayout gbl_testPanel = new GridBagLayout();
gbl_testPanel.columnWidths = new int[]{0, 0};
gbl_testPanel.rowHeights = new int[]{0};
gbl_testPanel.columnWeights = new double[]{0.5, 0.5};
gbl_testPanel.rowWeights = new double[]{1.0};
testPanel.setLayout(gbl_testPanel);
JPanel leftPanel = new JPanel();
GridBagConstraints gbc_leftPanel = new GridBagConstraints();
gbc_leftPanel.fill = GridBagConstraints.BOTH;
gbc_leftPanel.insets = new Insets(0, 0, 0, 5);
gbc_leftPanel.gridx = 0;
gbc_leftPanel.gridy = 0;
testPanel.add(leftPanel, gbc_leftPanel);
GridBagLayout gbl_leftPanel = new GridBagLayout();
gbl_leftPanel.columnWidths = new int[]{0};
gbl_leftPanel.rowHeights = new int[]{0, 0};
gbl_leftPanel.columnWeights = new double[]{0.0};
gbl_leftPanel.rowWeights = new double[]{0.6, 0.4};
leftPanel.setLayout(gbl_leftPanel);
JLabel lbl00 = new JLabel("Upper Left");
GridBagConstraints gbc_lbl00 = new GridBagConstraints();
gbc_lbl00.anchor = GridBagConstraints.NORTH;
gbc_lbl00.fill = GridBagConstraints.HORIZONTAL;
gbc_lbl00.insets = new Insets(0, 0, 5, 0);
gbc_lbl00.gridx = 0;
gbc_lbl00.gridy = 0;
leftPanel.add(lbl00, gbc_lbl00);
JLabel lbl10 = new JLabel("Lower Left");
GridBagConstraints gbc_lbl10 = new GridBagConstraints();
gbc_lbl10.anchor = GridBagConstraints.NORTH;
gbc_lbl10.fill = GridBagConstraints.HORIZONTAL;
gbc_lbl10.gridx = 0;
gbc_lbl10.gridy = 1;
leftPanel.add(lbl10, gbc_lbl10);
JPanel rightPanel = new JPanel();
GridBagConstraints gbc_rightPanel = new GridBagConstraints();
gbc_rightPanel.fill = GridBagConstraints.BOTH;
gbc_rightPanel.gridx = 1;
gbc_rightPanel.gridy = 0;
testPanel.add(rightPanel, gbc_rightPanel);
GridBagLayout gbl_rightPanel = new GridBagLayout();
gbl_rightPanel.columnWidths = new int[]{0};
gbl_rightPanel.rowHeights = new int[]{0, 0};
gbl_rightPanel.columnWeights = new double[]{0.0};
gbl_rightPanel.rowWeights = new double[]{0.4, 0.6};
rightPanel.setLayout(gbl_rightPanel);
JLabel lbl01 = new JLabel("Upper Right");
GridBagConstraints gbc_lbl01 = new GridBagConstraints();
gbc_lbl01.insets = new Insets(0, 0, 5, 0);
gbc_lbl01.fill = GridBagConstraints.HORIZONTAL;
gbc_lbl01.anchor = GridBagConstraints.NORTH;
gbc_lbl01.gridx = 0;
gbc_lbl01.gridy = 0;
rightPanel.add(lbl01, gbc_lbl01);
JLabel lbl11 = new JLabel("Lower Right");
GridBagConstraints gbc_lbl11 = new GridBagConstraints();
gbc_lbl11.anchor = GridBagConstraints.NORTH;
gbc_lbl11.fill = GridBagConstraints.HORIZONTAL;
gbc_lbl11.gridx = 0;
gbc_lbl11.gridy = 1;
rightPanel.add(lbl11, gbc_lbl11);
}
}
Upvotes: 1