Odd behavior with GridBagLayout, grid positions are partially ignored

I have a very strange problem with the GridBagLayout, where the layout seems to "adjust" the grid positions so the components align in neat columns - exactly what I don't want. I want my components to be aligned in a brick wall, but I end up with a checkerboard layout.

This example reproduces the case:

public class GBLayout extends JPanel {

    public GBLayout() {
        setLayout(new GridBagLayout());
        for (int y=0; y<10; ++y) {
            int offset = y & 1;
            if (offset != 0) {
                GridBagConstraints c = new GridBagConstraints(
                        0, y, // x, y
                        1, 1, // w, h
                        0D, 0D,
                        GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
                        new Insets(2, 2, 2, 2),
                        0, 0);
                add(new JLabel("!"), c);
            }
            for (int x=0; x<10; ++x) {
                int bx = x * 2 + offset;
                int by = y;
                JButton b = new JButton("(" + bx + ", " + by + ")");
                GridBagConstraints c = new GridBagConstraints(
                        bx, by, // x, y
                        2, 1, // w, h
                        1D, 0D,
                        GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
                        new Insets(2, 2, 2, 2),
                        0, 0);
                add(b, c);
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                GBLayout panel = new GBLayout();
                JFrame frame = new JFrame("Test");
                frame.setLayout(new BorderLayout());
                frame.add(panel, BorderLayout.CENTER);
                frame.pack();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }
}

      

This is how it looks at the moment:

Layout as obseved from the example

The expected layout is brick wall (roughly, I edited this by hand):

Approximate expected layout

What is only observed in the leftmost column, after that the GridBagLayout seems to have its own idea of โ€‹โ€‹where to put my components. What is causing this and how can I get around it?

+3


source to share


1 answer


This will give you the effect you want, on my computer it looks like this:

enter image description here



import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class GBLayout extends JPanel {

    public GBLayout() {
        GridBagLayout gridBagLayout = new GridBagLayout();
        gridBagLayout.columnWeights = new double[] {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
        setLayout(gridBagLayout);
        for (int y=0; y<10; ++y) {
            int offset = y & 1;
            if (offset != 0) {
                GridBagConstraints c = new GridBagConstraints(
                        0, y, // x, y
                        1, 1, // w, h
                        0D, 0D,
                        GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
                        new Insets(2, 2, 2, 2),
                        0, 0);
                add(new JLabel("!"), c);
            }
            for (int x=0; x<10; ++x) {
                int bx = x * 2 + offset;
                int by = y;
                JButton b = new JButton("(" + bx + ", " + by + ")");
                GridBagConstraints c = new GridBagConstraints(
                        bx, by, // x, y
                        2, 1, // w, h
                        1D, 1D,
                        GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
                        new Insets(2, 2, 2, 2),
                        0, 0);
                add(b, c);
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                GBLayout panel = new GBLayout();
                JFrame frame = new JFrame("Test");
                frame.setLayout(new BorderLayout());
                frame.add(panel, BorderLayout.CENTER);
                frame.pack();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }
}

      

The trick is to set the "Column" column to 1, because without this the number of columns can have different sizes, some columns can be stretched to the width of the buttons or split by 0.

+3


source







All Articles