javaswinggridbaglayout

Having problem when using GridBagLayout on JPanel and putting JButton inside


Here's what I've got. I have two JPanels, each with GridBagLayout. They have weightx = 0.5 and fill both directions. So basically the window is half one JPanel, half the other. And it should stay this way. But if i put for example JButton in one of them, then the JPanel widens and takes some space of the second JPanel.

What should I do to prevent this behavior? Is there any other layout that would work the same way as I described?

Here's the code I've been testing this on.

`

JFrame f = new JFrame();
        f.setLayout(new BorderLayout());
        f.setTitle("Start Window");
        f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
        f.setSize(400,300);
        f.setResizable(true);

        JPanel top = new JPanel();
        JPanel right = new JPanel();
        JPanel bottom = new JPanel();
        JPanel left = new JPanel();

        top.setPreferredSize(new Dimension(30,30));
        right.setPreferredSize(new Dimension(30,30));
        bottom.setPreferredSize(new Dimension(30,30));
        left.setPreferredSize(new Dimension(30,30));

        f.add(top,BorderLayout.NORTH);
        f.add(right,BorderLayout.EAST);
        f.add(bottom,BorderLayout.SOUTH);
        f.add(left,BorderLayout.WEST);

        JPanel centerContainer = new JPanel(new GridBagLayout());
        GridBagConstraints centerLayout = new GridBagConstraints();
        centerContainer.setBackground(Color.blue);
        f.add(centerContainer);

        JPanel centerLeft = new JPanel(new GridBagLayout());
        GridBagConstraints centerLeftLayout = new GridBagConstraints();
        centerLayout.gridx=0;
        centerLayout.gridy=0;
        centerLayout.weightx=0.5;
        centerLayout.weighty=1;
        centerLayout.fill = GridBagConstraints.BOTH;
        centerLeft.setBackground(Color.red);
        centerContainer.add(centerLeft,centerLayout);

        JPanel centerRight = new JPanel();
        centerLayout.gridx=1;
        centerLayout.gridy=0;
        centerLayout.weightx=0.5;
        centerLayout.weighty=1;
        centerLayout.fill = GridBagConstraints.BOTH;
        centerRight.setBackground(Color.green);
        centerContainer.add(centerRight,centerLayout);

        JPanel leftElement = new JPanel(new GridBagLayout());
        GridBagConstraints leftElementLayout = new GridBagConstraints();

        centerLeftLayout.gridx=0;
        centerLeftLayout.gridy=0;
        centerLeftLayout.weightx=1;
        centerLeftLayout.weighty=1;
        centerLeftLayout.fill = GridBagConstraints.HORIZONTAL;

        centerLeft.add(leftElement,centerLeftLayout);

        JButton leftBtn = new JButton("CLIIIIICK!!!");
        leftBtn.setLayout(new GridBagLayout());
        leftElementLayout.gridx=0;
        leftElementLayout.gridy=0;
        leftElementLayout.weighty=0;
        leftElementLayout.weightx=1;
        leftElementLayout.fill=GridBagConstraints.HORIZONTAL;


        leftElement.add(leftBtn,leftElementLayout);


        f.setVisible(true);

`


Solution

  • Solution: You should use a simpler layout when one is called for. Here, better to have those center JPanels held in a GridLayout with 1 row and 2 columns as this will guarantee that they split the panel exactly in two. And you can still use GridBagLayout inside the left panel if you want to center the button mid-panel.

    Side notes:

    int ebGap = 30;
    setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));
    

    For example:

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.GridLayout;
    import javax.swing.*;
    
    @SuppressWarnings("serial")
    public class SwingFoo02 extends JPanel {
        
        private static final int PREF_W = 400;
        private static final int PREF_H = 300;
        
        public SwingFoo02() {
            int ebGap = 30;
            setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));
            
            JPanel centerLeft = new JPanel(new GridBagLayout());
            JPanel centerRight = new JPanel();
            
            centerLeft.setBackground(Color.RED);
            centerRight.setBackground(Color.GREEN);        
    
            JButton leftBtn = new JButton("CLIIIIICK!!!");
            GridBagConstraints gbc = new GridBagConstraints();        
            gbc.anchor = GridBagConstraints.CENTER;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.weightx = 1.0;
            gbc.weighty = 0.0;
            gbc.gridx = 0;
            gbc.gridy = 0;
            centerLeft.add(leftBtn, gbc);
            
            setLayout(new GridLayout(1, 2));
            add(centerLeft);
            add(centerRight);
    
        }
        
    
        @Override
        public Dimension getPreferredSize() {
            Dimension supSize = super.getPreferredSize();
            int w = Math.max(supSize.width, PREF_W);
            int h = Math.max(supSize.height, PREF_H);
            return new Dimension(w, h);
        }
        
        public static void main(String[] args) {
            SwingUtilities.invokeLater(() -> {
                SwingFoo02 mainPanel = new SwingFoo02();
    
                JFrame frame = new JFrame("GUI");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(mainPanel);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            });
        }
    
    }