I have the following program (simplified version of my actual program):
MyPanel.java:
public class MyPanel extends JPanel{
private JLayeredPane layeredPane;
public MyPanel(int width, int height){
Dimension dimension = new Dimension(width, height);
layeredPane = new JLayeredPane();
layeredPane.setPreferredSize(dimension);
layeredPane.setBounds(0, 0, width, height);
setPreferredSize(dimension);
setBounds(0, 0, width, height);
setBorder(BorderFactory.createLineBorder(Color.red));
}
}
Main.java:
public class Main{
private static int WIDTH = 500;
private static int HEIGHT = 300;
private static JFrame frame;
public static void main(String[] args){
initFrame();
addPanels();
frame.setVisible(true);
}
private static void initFrame(){
frame = new JFrame();
frame.setPreferredSize(new Dimension(WIDTH, HEIGHT));
frame.setBounds(0, 0, WIDTH, HEIGHT);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLayout(new GridBagLayout());
}
private static void addPanels(){
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridheight = 2;
MyPanel panel1 = new MyPanel(200, 300);
frame.add(panel1, gbc);
gbc.gridx = 1;
gbc.gridy = 0;
gbc.gridheight = 1;
MyPanel panel2 = new MyPanel(300, 200);
frame.add(panel2, gbc);
gbc.gridx = 1;
gbc.gridy = 1;
gbc.gridheight = 1;
MyPanel panel3 = new MyPanel(300, 100);
frame.add(panel3, gbc);
}
}
Expectation:
I want to create a 500x300 sized JFrame that has GridBagLayout. I want to divide this layout into 2 columns, further dividing the right column horizontally into 2 parts. My goal is to set the cell sizes precisely with the help of setting the preferredSize-s of the MyPanel components added into the layout.
This whole idea is based on the Oracle documentation of the GridBagLayout:
Essentially, GridBagLayout places components in rectangles (cells) in a grid, and then uses the components' preferred sizes to determine how big the cells should be.
source: https://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html
Problem:
GridBagLayout seems to add "outer margins" to itself and I can't fit the manually sized components into the JFrame without somehow...shrinking it. Running the code above results in something like this:
The image shows the 500x300 JFrame rendered in the given size, but the components don't match the manually set sizes.
However, if I increase the WIDTH
and HEIGHT
values to the following:
private static int WIDTH = 1000;
private static int HEIGHT = 600;
This time all the MyPanel components were rendered in their given sizes, but the JFrame is far too big. I want the components to fill up the entire JFrame with the given size.
Question:
What could cause this? How can I set manually the sizes of the components without running into this issue?
Notes:
I am aware of the GridBagConstraints.weightx/y
variables, but my goal is to prevent the layout manager from setting the sizes of the components so those options don't seem ideal.
Every help is much appreciated!
Thanks to the helpful comment of @Gilbert Le Blanc, I was able to fix my code.
Removing the
frame.setPreferredSize(new Dimension(WIDTH, HEIGHT));
frame.setBounds(0, 0, WIDTH, HEIGHT);
lines from Main.java and calling frame.pack();
at the end of the main
method solved the problem.
The problem was caused by my misunderstanding of layout managers. You don't need to set the exact size of the JFrame
, but only my components in the GridBagLayout. The GridBagLayout manager will handle the rest and set my frame size according to the components in it.