GridBagLayout 和面板的问题

trouble with GridBagLayout and panels

所以我想做的是创建这个:

我正在使用 gridbag 布局,这是我目前所拥有的布局:

public class board {
public static void addComponentsToPane(Container pane) {
    pane.setLayout(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();

    JPanel leftTop = new JPanel();
    leftTop.setPreferredSize(new Dimension(251,300));
    leftTop.setBackground(Color.black);
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridx = 0;
    c.gridy = 0;

    pane.add(leftTop, c);

    JPanel middleTop = new JPanel();
    middleTop.setPreferredSize(new Dimension(251,200));
    middleTop.setBackground(Color.green);
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridx = 1;
    c.gridy = 0;

    pane.add(middleTop, c);

    JPanel rightTop = new JPanel();
    rightTop.setPreferredSize(new Dimension(251,600));
    rightTop.setBackground(Color.blue);
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridx = 2;
    c.gridy = 0;

    pane.add(rightTop, c);

    JPanel leftBottom = new JPanel();
    leftBottom.setPreferredSize(new Dimension(251,300));
    leftBottom.setBackground(Color.red);
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridx = 0;
    c.gridy = 1;

    pane.add(leftBottom, c);

    JPanel middleBottom = new JPanel();
    middleBottom.setPreferredSize(new Dimension(251,400));
    middleBottom.setBackground(Color.yellow);
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridx = 1;
    c.gridy = 1;

    pane.add(middleBottom, c);
}

private static void createAndShowGUI() {
    JFrame frame = new JFrame("GridBagLayoutDemo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    addComponentsToPane(frame.getContentPane());

    frame.pack();
    frame.setVisible(true);
}

public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI();
        }
    });
}
}

它会创建如下内容:

我如何将面板向上推,使它们像我的第一张照片中那样相互接触。我查看了 GridBagConstraints,但找不到任何看起来可行的东西。谢谢!

与其试图用一个布局管理器解决整个布局问题,嵌套布局通常更简单。例如,您的示例代码可以修改为使用水平网格布局(以保持列的宽度相等 - 我实际上不知道您是否要强制这样做。如果不是,则 FlowLayoutBoxLayout 会更好),每个列使用 BoxLayout

import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class board {
    public static void addComponentsToPane(Container pane) {
        pane.setLayout(new GridLayout(1, 0));

        JPanel left = new JPanel();
        pane.add(left);
        left.setLayout(new BoxLayout(left, BoxLayout.Y_AXIS));

        JPanel leftTop = new JPanel();
        leftTop.setPreferredSize(new Dimension(125, 150));
        leftTop.setBackground(Color.black);
        left.add(leftTop);

        JPanel leftBottom = new JPanel();
        leftBottom.setPreferredSize(new Dimension(125, 150));
        leftBottom.setBackground(Color.red);
        left.add(leftBottom);

        JPanel middle = new JPanel();
        pane.add(middle);
        middle.setLayout(new BoxLayout(middle, BoxLayout.Y_AXIS));

        JPanel middleTop = new JPanel();
        middleTop.setPreferredSize(new Dimension(125, 100));
        middleTop.setBackground(Color.green);
        middle.add(middleTop);

        JPanel middleBottom = new JPanel();
        middleBottom.setPreferredSize(new Dimension(125, 200));
        middleBottom.setBackground(Color.yellow);
        middle.add(middleBottom);

        JPanel right = new JPanel();
        right.setPreferredSize(new Dimension(125, 300));
        right.setBackground(Color.blue);

        pane.add(right);
    }

    private static void createAndShowGUI() {
        JFrame frame = new JFrame("GridBagLayoutDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        addComponentsToPane(frame.getContentPane());
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

结果:

(我稍微修改了首选尺寸以使图像更小。作为进一步说明,override getPreferredSize() rather than use setPreferredSize() 通常更好;不过 setPreferredSize() 对于快速示例来说很方便)