Reputation: 195
Ok so I am messing around with GridBagLayout to get to grips with it. I want to use it to layout JPanels in a JFrame but these individual panels will use different layout managers, GridBagLayout probably won't suit.
But i have a problem. If i don't add anything to the panels, all of the proportions work out perfectly as in this example:
public class RealMess extends JFrame{
private JPanel panel;
public RealMess(){
initUI();
}
public final void initUI(){
Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
int width = (int) screensize.getWidth();
int height = (int) screensize.getHeight();
panel = new JPanel();
panel.setLayout(new GridBagLayout());
JPanel left = new JPanel();
left.setBackground(Color.GREEN);
JPanel centre = new JPanel();
centre.setBackground(Color.PINK);
JPanel right = new JPanel();
right.setBackground(Color.CYAN);
JPanel leftBottom = new JPanel();
leftBottom.setBackground(Color.LIGHT_GRAY);
leftBottom.setLayout(new FlowLayout(0));
JPanel bottom = new JPanel();
bottom.setBackground(Color.MAGENTA);
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 0.11;
gbc.weighty = 0.9;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.BOTH;
panel.add(left, gbc);
gbc.weightx = 0.11;
gbc.weighty = 0.1;
gbc.anchor = GridBagConstraints.LAST_LINE_START;
gbc.gridx = 0;
gbc.gridy = 1;
gbc.fill = GridBagConstraints.BOTH;
panel.add(leftBottom, gbc);
gbc.weightx = 0.78;
gbc.weighty = 0.9;
gbc.anchor = GridBagConstraints.PAGE_START;
gbc.gridx = 1;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.BOTH;
panel.add(centre, gbc);
gbc.weightx = 0.78;
gbc.weighty = 0.1;
gbc.anchor = GridBagConstraints.PAGE_END;
gbc.gridx = 1;
gbc.gridy = 1;
gbc.fill = GridBagConstraints.BOTH;
panel.add(bottom, gbc);
gbc.weightx = 0.11;
gbc.weighty = 1;
gbc.anchor = GridBagConstraints.FIRST_LINE_END;
gbc.gridx = 2;
gbc.gridy = 0;
gbc.gridheight = 2;
gbc.fill = GridBagConstraints.BOTH;
panel.add(right, gbc);
add(panel);
setTitle("Jack");
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setExtendedState(MAXIMIZED_BOTH);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run(){
RealMess rm = new RealMess();
rm.setVisible(true);
}
});
}
}
I know that I redefined some GridBagConstraints unnecessarily but I didn't want to miss anything.
Anyway, my problem arises when i add a button to any of the panels. Like this:
public class RealMess extends JFrame{
private JPanel panel;
public RealMess(){
initUI();
}
public final void initUI(){
Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
int width = (int) screensize.getWidth();
int height = (int) screensize.getHeight();
panel = new JPanel();
panel.setLayout(new GridBagLayout());
JPanel left = new JPanel();
left.setBackground(Color.GREEN);
JPanel centre = new JPanel();
centre.setBackground(Color.PINK);
JPanel right = new JPanel();
right.setBackground(Color.CYAN);
JPanel leftBottom = new JPanel();
leftBottom.setBackground(Color.LIGHT_GRAY);
leftBottom.setLayout(new FlowLayout(0));
JButton rewind = new JButton("1");
rewind.setPreferredSize(new Dimension(50, 25));
leftBottom.add(rewind);
JPanel bottom = new JPanel();
bottom.setBackground(Color.MAGENTA);
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 0.11;
gbc.weighty = 0.9;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.BOTH;
panel.add(left, gbc);
gbc.weightx = 0.11;
gbc.weighty = 0.1;
gbc.anchor = GridBagConstraints.LAST_LINE_START;
gbc.gridx = 0;
gbc.gridy = 1;
gbc.fill = GridBagConstraints.BOTH;
panel.add(leftBottom, gbc);
gbc.weightx = 0.78;
gbc.weighty = 0.9;
gbc.anchor = GridBagConstraints.PAGE_START;
gbc.gridx = 1;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.BOTH;
panel.add(centre, gbc);
gbc.weightx = 0.78;
gbc.weighty = 0.1;
gbc.anchor = GridBagConstraints.PAGE_END;
gbc.gridx = 1;
gbc.gridy = 1;
gbc.fill = GridBagConstraints.BOTH;
panel.add(bottom, gbc);
gbc.weightx = 0.11;
gbc.weighty = 1;
gbc.anchor = GridBagConstraints.FIRST_LINE_END;
gbc.gridx = 2;
gbc.gridy = 0;
gbc.gridheight = 2;
gbc.fill = GridBagConstraints.BOTH;
panel.add(right, gbc);
add(panel);
setTitle("Jack");
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setExtendedState(MAXIMIZED_BOTH);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run(){
RealMess rm = new RealMess();
rm.setVisible(true);
}
});
}
}
The bottomLeft panel got bigger and hence the size of the grid squares related to it.
In the first example, everything is taking up a percentage of the width or height of the window dictated by:
gbc.weightx
And
gbc.weighty
Doing it this way makes it very easy to make everything the correct size.
Is there a workaround which allows me to force the panel sizes to be influenced only by the weight values?
Upvotes: 1
Views: 2713
Reputation: 3225
weightx and weighty show the proportional assignment for space not requested by the underlying components. For example, if you have a label and a textfield oriented horizontally, you probably want the label to take a fixed amount of spaced based on the biggest label in the column, and the remainder of the space to go to the textfield. Assign all the weightx to the textfield and that is exactly what happens. The label has a weightx of zero, but is not scrunched to zero size because only the excess space is dictated by weight. Empty panels have a minimum size of zero, so all the space is considered extra.
If you want to force the layout to work as you describe, you would need to extend JPanel for the sub-panels to lie to the GridBagLayout about their contents. This could get you into trouble if you start making things smaller than their minimums.
Upvotes: 1