java - GridBagLayout 为列提供额外的边距

标签 java swing layout-manager gridbaglayout

我已经使用 Swing 有一段时间了,我终于找到了学习 GridBadLayout 的自信。

我仍在学习它,在这种情况下,我无法理解为什么以下代码没有按预期响应:特别是我无法理解为什么布局以这种方式显示列。

通过运行代码片段,您将发现代表意大利国旗的面板位置不正确:最后一列(国旗的红色部分)与国旗的其余部分(国旗的白色部分)分离。那么,我做错了什么以及我可以修复什么才能正确表示标志?

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class test extends JPanel {

    private GridBagConstraints gbc;
    private final int CELL_WIDTH = 90;
    private final int CELL_HEIGHT = 110;

    public test() {
        setLayout(new GridBagLayout());

        putBanner(0);

        putFlagRow(1);
        putFlagRow(2);
        putFlagRow(3);
        putFlagRow(4);
    }

    public JPanel getUserPanel(Color c) {
        JPanel ol = new JPanel();
        ol.setPreferredSize(new Dimension(CELL_WIDTH * 10, CELL_HEIGHT));
        ol.setBackground(c);
        return ol;
    }

    public JPanel gettestPanel() {
        JPanel ol = new JPanel();
        ol.setPreferredSize(new Dimension(CELL_WIDTH, CELL_HEIGHT));
        ol.setBackground(Color.white);
        return ol;
    }

    private void putFlagRow(int gridy) {
        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = gridy;
        JPanel p1=gettestPanel();
        p1.setBackground(Color.green);
        add(p1, gbc);

        gbc = new GridBagConstraints();
        gbc.gridx = 1;
        gbc.gridy = gridy;
        add(gettestPanel(), gbc);

        gbc = new GridBagConstraints();
        gbc.gridx = 2;
        gbc.gridy = gridy;
        add(gettestPanel(), gbc);

        gbc = new GridBagConstraints();
        gbc.gridx = 3;
        gbc.gridy = gridy;
        add(gettestPanel(), gbc);

        gbc = new GridBagConstraints();
        gbc.gridx = 4;
        gbc.gridy = gridy;
        add(gettestPanel(), gbc);

        gbc = new GridBagConstraints();
        gbc.gridx = 5;
        gbc.gridy = gridy;
        add(gettestPanel(), gbc);

        gbc = new GridBagConstraints();
        gbc.gridx = 6;
        gbc.gridy = gridy;
        add(gettestPanel(), gbc);

        gbc = new GridBagConstraints();
        gbc.gridx = 7;
        gbc.gridy = gridy;
        add(gettestPanel(), gbc);

        gbc = new GridBagConstraints();
        gbc.gridx = 8;
        gbc.gridy = gridy;
        add(gettestPanel(), gbc);

        gbc = new GridBagConstraints();
        gbc.gridx = 9;
        gbc.gridy = gridy;
        JPanel p=gettestPanel();
        p.setBackground(Color.red);
        add(p, gbc);

        gbc = new GridBagConstraints();
        gbc.gridx = 10;
        gbc.gridy = gridy;
        add(gettestPanel(), gbc);
    }

    private void putBanner(int gridy) {
        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = gridy;
        gbc.gridwidth = 1;
        add(gettestPanel(), gbc);

        gbc = new GridBagConstraints();
        gbc.gridx = 1;
        gbc.gridy = gridy;
        gbc.gridwidth = 9;
        add(getUserPanel(Color.black), gbc);
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("GridBagLayoutTest");
        frame.add(new test());
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

除了了解这个特定问题及其原因之外,我还想了解这一点,它直接来自 GridBagLayout Oracle 文档:

weightx, weighty Specifying weights is an art that can have a significant impact on the appearance of the components a GridBagLayout controls. Weights are used to determine how to distribute space among columns (weightx) and among rows (weighty); this is important for specifying resizing behavior. Unless you specify at least one non-zero value for weightx or weighty, all the components clump together in the center of their container. This is because when the weight is 0.0 (the default), the GridBagLayout puts any extra space between its grid of cells and the edges of the container. Generally weights are specified with 0.0 and 1.0 as the extremes: the numbers in between are used as necessary. Larger numbers indicate that the component's row or column should get more space. For each column, the weight is related to the highest weightx specified for a component within that column, with each multicolumn component's weight being split somehow between the columns the component is in. Similarly, each row's weight is related to the highest weighty specified for a component within that row. Extra space tends to go toward the rightmost column and bottom row.

类似的表达式

is an art

the numbers in between are used as necessary

确实给我的印象是,即使是文档作者也认为不可能教授这种约束的用法。这可不好

最佳答案

the last column(red part of the flag) is detached from the rest of the flag(white part of the flag).

调试GridBagLayout时要做的一件事是向组件添加Border,以便您可以看到每个单元格的大小。我将以下内容添加到您的 getTestPanel() 方法中:

ol.setBorder( new LineBorder(Color.BLUE) );

您可以看到面板大小正确,但面板周围有额外的空间。

然后你看看你的用户面板:

ol.setPreferredSize(new Dimension(CELL_WIDTH * 10, CELL_HEIGHT));

即使您只将网格宽度设置为 9 个单元格,您也会看到大小设置为 10 个单元格。所以现在 9 个单元格必须适合用户面板的空间,看起来额外的空间被分配给了 9 列中的最后一列。

代码应该是:

//ol.setPreferredSize(new Dimension(CELL_WIDTH * 10, CELL_HEIGHT));
ol.setPreferredSize(new Dimension(CELL_WIDTH * 9, CELL_HEIGHT));

另一种选择是不为用户面板提供首选大小,而是使用“填充”约束,以便用户面板现在占用与九列相同的空间。

weightx, weighty Specifying weights is an art...

这与您的问题无关。要查看此效果,请将框架拖得更大。现在,所有整个面板都将位于框架的中心,因为您的组件都没有使用weightx/weighty约束。这意味着如果框架没有任何组件会增长来填充空白空间。

如果其中一个组件的weightx 约束为1.0,则当调整框架大小时,该列将扩展并填充额外的空间。

关于java - GridBagLayout 为列提供额外的边距,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49031902/

相关文章:

java - JLabel 组件中的几个图像快照

Java Applet 大小行为与 JFrame 大小行为

java - 使用扫描生成正弦音 - Android

java - JTable数据垂直滚动时不稳定

java - 如何将数组列表传递到 Java 方法并重用?

java - 从 JTextarea 获取文本到 OutputStream 或将文本打印到控制台

java - 单击 Jbutton 后更改 JPanel

java - 使用 pack() 自动调整 JFrame 的大小而不折叠其 jPanel

java - GWT [警告] 404 - GET/birgit.chat.Chat.nocache.js cometd

java - Car.class - "class"是一个变量吗?