有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

GridBagLayout中的java非均匀列

我想创建一个JPanel,它由4个组件组成,分为2列。左列中的上部构件应占垂直空间的60%,下部构件占剩余的40%。在右栏中,它应该是另一种方式-上部组件占40%,下部组件占60%

因此,基本上我希望我的组件如图所示:

enter image description here

我试图通过GridBagLayout实现这种行为

public class Test extends JFrame {
JPanel testPanel = new JPanel();

public static void main(String[] args) {
    SwingUtilities.invokeLater(() -> {
        new Test().setVisible(true);
    });
}

Test() {
    prepareTestPanel();
    setContentPane(testPanel);
    setSize(500, 500);
    setTitle("Test");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

private void prepareTestPanel() {
    testPanel.setLayout(new GridBagLayout());
    addComp(makeUpperLeft());
    addComp(makeLowerLeft());
    addComp(makeUpperRight());
    addComp(makeLowerRight());
}

private void addComp(Pair p) {
    testPanel.add(p.comp, p.gbc);
}

private Pair makeUpperLeft() {
    JPanel panel = new JPanel();
    panel.setBorder(BorderFactory.createTitledBorder("Upper Left"));

    GridBagConstraints gbc = new GridBagConstraints();
    gbc.gridx = 0;
    gbc.gridy = 0;
    gbc.gridheight = 60;
    gbc.gridwidth = 50;
    gbc.fill = GridBagConstraints.BOTH;
    gbc.anchor = GridBagConstraints.LINE_START;
    gbc.weightx = 0.5;
    gbc.weighty = 0.6;

    return new Pair(panel, gbc);
}

private Pair makeLowerLeft() {
    JPanel panel = new JPanel();
    panel.setBorder(BorderFactory.createTitledBorder("Lower Left"));

    GridBagConstraints gbc = new GridBagConstraints();
    gbc.gridx = 0;
    gbc.gridy = 60;
    gbc.gridheight = 40;
    gbc.gridwidth = 50;
    gbc.fill = GridBagConstraints.BOTH;
    gbc.anchor = GridBagConstraints.LINE_START;
    gbc.weightx = 0.5;
    gbc.weighty = 0.4;

    return new Pair(panel, gbc);
}

private Pair makeUpperRight() {
    JPanel panel = new JPanel();
    panel.setBorder(BorderFactory.createTitledBorder("Upper Right"));

    GridBagConstraints gbc = new GridBagConstraints();
    gbc.gridx = 50;
    gbc.gridy = 0;
    gbc.gridheight = 40;
    gbc.gridwidth = 50;
    gbc.fill = GridBagConstraints.BOTH;
    gbc.anchor = GridBagConstraints.LINE_START;
    gbc.weightx = 0.5;
    gbc.weighty = 0.4;

    return new Pair(panel, gbc);
}

private Pair makeLowerRight() {
    JPanel panel = new JPanel();
    panel.setBorder(BorderFactory.createTitledBorder("Lower Right"));

    GridBagConstraints gbc = new GridBagConstraints();
    gbc.gridx = 50;
    gbc.gridy = 40;
    gbc.gridheight = 60;
    gbc.gridwidth = 50;
    gbc.fill = GridBagConstraints.BOTH;
    gbc.anchor = GridBagConstraints.LINE_START;
    gbc.weightx = 0.5;
    gbc.weighty = 0.6;

    return new Pair(panel, gbc);
}


private class Pair {
    Component comp;
    GridBagConstraints gbc;

    public Pair(Component comp, GridBagConstraints gbc) {
        this.comp = comp;
        this.gbc = gbc;
    }
}
}

不幸的是,我得到的是:

enter image description here

我应该如何更正代码?此外,我希望无论窗口大小如何调整,这个比例都保持不变。我应该如何设置weighty


共 (2) 个答案

  1. # 1 楼答案

    这不能直接在一个容器内完成。您必须为这两个列创建两个容器元素(比如另外两个JPanel对象)。在外部容器中添加列,然后在内部面板中添加组件。下面是一些代码:

    public class Test extends JFrame {
    public Test() {
    
        JPanel testPanel = new JPanel();
        setContentPane(testPanel);
        GridBagLayout gbl_testPanel = new GridBagLayout();
        gbl_testPanel.columnWidths = new int[]{0, 0};
        gbl_testPanel.rowHeights = new int[]{0};
        gbl_testPanel.columnWeights = new double[]{0.5, 0.5};
        gbl_testPanel.rowWeights = new double[]{1.0};
        testPanel.setLayout(gbl_testPanel);
    
        JPanel leftPanel = new JPanel();
        GridBagConstraints gbc_leftPanel = new GridBagConstraints();
        gbc_leftPanel.fill = GridBagConstraints.BOTH;
        gbc_leftPanel.insets = new Insets(0, 0, 0, 5);
        gbc_leftPanel.gridx = 0;
        gbc_leftPanel.gridy = 0;
        testPanel.add(leftPanel, gbc_leftPanel);
        GridBagLayout gbl_leftPanel = new GridBagLayout();
        gbl_leftPanel.columnWidths = new int[]{0};
        gbl_leftPanel.rowHeights = new int[]{0, 0};
        gbl_leftPanel.columnWeights = new double[]{0.0};
        gbl_leftPanel.rowWeights = new double[]{0.6, 0.4};
        leftPanel.setLayout(gbl_leftPanel);
    
        JLabel lbl00 = new JLabel("Upper Left");
        GridBagConstraints gbc_lbl00 = new GridBagConstraints();
        gbc_lbl00.anchor = GridBagConstraints.NORTH;
        gbc_lbl00.fill = GridBagConstraints.HORIZONTAL;
        gbc_lbl00.insets = new Insets(0, 0, 5, 0);
        gbc_lbl00.gridx = 0;
        gbc_lbl00.gridy = 0;
        leftPanel.add(lbl00, gbc_lbl00);
    
        JLabel lbl10 = new JLabel("Lower Left");
        GridBagConstraints gbc_lbl10 = new GridBagConstraints();
        gbc_lbl10.anchor = GridBagConstraints.NORTH;
        gbc_lbl10.fill = GridBagConstraints.HORIZONTAL;
        gbc_lbl10.gridx = 0;
        gbc_lbl10.gridy = 1;
        leftPanel.add(lbl10, gbc_lbl10);
    
        JPanel rightPanel = new JPanel();
        GridBagConstraints gbc_rightPanel = new GridBagConstraints();
        gbc_rightPanel.fill = GridBagConstraints.BOTH;
        gbc_rightPanel.gridx = 1;
        gbc_rightPanel.gridy = 0;
        testPanel.add(rightPanel, gbc_rightPanel);
        GridBagLayout gbl_rightPanel = new GridBagLayout();
        gbl_rightPanel.columnWidths = new int[]{0};
        gbl_rightPanel.rowHeights = new int[]{0, 0};
        gbl_rightPanel.columnWeights = new double[]{0.0};
        gbl_rightPanel.rowWeights = new double[]{0.4, 0.6};
        rightPanel.setLayout(gbl_rightPanel);
    
        JLabel lbl01 = new JLabel("Upper Right");
        GridBagConstraints gbc_lbl01 = new GridBagConstraints();
        gbc_lbl01.insets = new Insets(0, 0, 5, 0);
        gbc_lbl01.fill = GridBagConstraints.HORIZONTAL;
        gbc_lbl01.anchor = GridBagConstraints.NORTH;
        gbc_lbl01.gridx = 0;
        gbc_lbl01.gridy = 0;
        rightPanel.add(lbl01, gbc_lbl01);
    
        JLabel lbl11 = new JLabel("Lower Right");
        GridBagConstraints gbc_lbl11 = new GridBagConstraints();
        gbc_lbl11.anchor = GridBagConstraints.NORTH;
        gbc_lbl11.fill = GridBagConstraints.HORIZONTAL;
        gbc_lbl11.gridx = 0;
        gbc_lbl11.gridy = 1;
        rightPanel.add(lbl11, gbc_lbl11);
    }
    

    }

  2. # 2 楼答案

    GridBagLayout不容易支持这一点:

    1. 不能只按所需的比率指定gridwidth/height。如果您想要6/4的比例,那么实际上需要创建10个相同大小的虚拟组件,然后首先将它们添加到面板中。然后可以说组件的gridheight等于这些虚拟组件的4(或6)

    2. 权重X/y约束仅在调整帧大小时应用于额外空间。因此,组件最初将按照其首选尺寸进行包装,这意味着您还需要手动设置所需比例的首选尺寸

    您可以查看RelativeLayout。它允许您根据可用空间轻松创建相对大小的构件

    使用此布局的基本代码如下所示:

    RelativeLayout rl = new RelativeLayout(RelativeLayout.Y_AXIS);
    rl.setFill( true );
    JPanel left = new JPanel( rl );
    left.add(upperLeft, new Float(60));
    left.add(lowerLeft, new Float(40));
    
    // repeat above for the right panel
    
    JPanel main = new JPanel( new GridLayout(0, 2) );
    main.add(left);
    main.add(right);
    
    frame.add(main);