java - GridBagLayout 的奇怪行为,部分忽略了网格位置

标签 java swing gridbaglayout

我在使用 GridBagLayout 时遇到了一个非常奇怪的问题,布局似乎“调整”了网格位置以使组件在整齐的列中对齐 - 这正是我不想要的。我希望我的组件以砖墙方式对齐,但我得到的是棋盘布局。

这个例子重现了这个案例:

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);
            }
        });
    }
}

这就是它目前的样子:

Layout as obseved from the example

预期布局是一堵砖墙(大约,我手动编辑了这个):

Approximate expected layout

这只在最左边的列中遵守,之后 GridBagLayout 似乎对我的组件的位置有自己的想法。是什么原因造成的,我该如何解决?

最佳答案

这会给你想要的效果,在我的电脑上它看起来像这样:

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);
            }
        });
    }
}

诀窍是将表格的 columnWeights 设置为 1,因为如果没有它,colums 可以有不同的大小,一些列可以被拉伸(stretch)到按钮宽度,或者被粉碎为 0。

关于java - GridBagLayout 的奇怪行为,部分忽略了网格位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30513307/

相关文章:

java - 使用 RequestDispatcher 在转发 URL 中使用哈希符号

java - 如何使用java apache poi仅从Excel工作表中的几列而不是所有列中删除过滤器

java - Graphics2D 和 JComponent

Java Swing Gridbag 面板不会 colspan

java - 重新定位整个 GridBagLayout

java - LibGDX - 多台机器上的库

java - 使用线程的套接字写入错误

java if语句文本提示不起作用

Java GridBagLayout 聚集在一行中

Java GridBagLayout + 绝对布局