如何根据布局获取容器组件?

How to get container components according to layout?

我在使用 GUI 时遇到了两个不同的问题。 第一个是:如何获取容器组件?我想从 BorderLayout 获得 5 个组件(并且更愿意让它们了解布局中的位置,例如:CENER,NORTH,SOUTH,EAST,WEST 第二个是:我想 "calculate" gui 布局,同时调整容器的大小,而不是仅在它已经停止调整大小的时候。我该怎么做?

对于第一个问题,我尝试使用 getComponenets() 方法,但是 returns 许多组件在布局中没有任何关于组件位置的信息。 对于第二个问题,当我实现方法 componentResized() 时,只有在调整大小过程结束时才会触发事件,但我想为容器中的每个更改计算布局

    public class GridLayoutFrame extends JFrame  
{
    LabelAndJtextAreaPanel topPanel;
    //KeyboardbuttonPanel buttomPanel ;

    public GridLayoutFrame ()
    {
        super("Typing Application");
        setLayout(new GridLayout());
        topPanel = new LabelAndJtextAreaPanel();
        add(topPanel);

        addComponentListener(new ComponentAdapter() {
            public void componentResized(ComponentEvent e) {
                System.out.println("componentResized\n");
                // want to put here many calculation during JFrame is resized
            }
        }
        );
        */
        setSize(300,200);
        setVisible(true);

    }

    public static void main(String[] args)
    {
        GridLayoutFrame frame = new GridLayoutFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

I want to get 5 components from BorderLayout (and prefer to get them with knowledge of there placement in the layout, e.g : CENER,NORTH,SOUTH,EAST,WEST

好吧,只有 BorderLayout 知道您使用了什么约束。这样就可以在 BorderLayout API 中找到该信息。查看各种 getter 方法。

您将使用:

BorderLayout layout = (BorderLayout)panel.getLayout();

访问布局管理器。

然后您将使用 API 中的适当方法为每个约束请求组件。

i'm trying to build application with gui that demonstrate computer keyboard. and since in each row there are different numbers of keys, and some of them are in different size i decided to use FlowLayout for each "row" in keyboard

更好的解决方案是让布局管理器进行大小调整。

查看:Why does this GridBagLayout not appear as planned? 示例。

您只需要添加:

gbc.weightx = 1.0f;

允许动态水平调整大小的示例。

编辑:

正在尝试回答与其他人相关的问题link。

看看另一个link中的图片。您将看到每一行包含 5 到 8 个按钮,这意味着 GridBagLayout 只知道 8 个单独列的大小。

将 (..) 中的数字相加,表示每行的网格宽度。总数是22.

GridBagLayout 不知道如何将 8 列变成 22 列。它不知道每列使用什么宽度。

因此建议的解决方案是在一行中添加 22 个虚拟组件。现在每列都有一个宽度,因此指定 "gridwidth" 现在对 GridBagLayout 有一定的意义。

在代码中你会看到我试图将虚拟按钮分配给 gridy=4,但是代码是错误的:

ui.add(new JButton()); //wrong
//ui.add(new JButton(), gbc); // what I should have had

现在的默认行为是您不指定 GridBagConstraint,只是在第一行显示每个组件(即 gridy=0)。

所以问题是现在有两行按钮试图显示在 gridy=0 处,这显然是错误的。

当时我没有意识到我忘记为虚拟按钮指定 "gbc" 所以我只是调整了每一行按钮的网格,这就是为什么你看到这样的代码:

//gbc.gridy = 0;
gbc.gridy = 1;

我只是将键盘按钮的每一行向下移动了 1,因此虚拟按钮可以显示在 gridy=0 处。

如果你想看到底部的按钮更改代码如下:

//gbc.gridy = 4;
//ui.add(new JButton());
gbc.gridy = 5;
ui.add(new JButton(), gbc);

现在 gridy=1、2、3、4、5 的组件将存在。gridy=0 中没有组件。

Somehow GridBagLayout "lerans" cell size from the "for" loop

是的,因为每个按钮都有自己的大小。由于在一行中添加了 22 个按钮,因此 GridBagLayout 知道所有 22 列的最小宽度。

现在如果您在 gridx=1 添加一个按钮,gridwidth=2,按钮的宽度就是第 1 列和第 2 列的宽度,在本例中就是虚拟按钮的宽度在每一列中。

但是,"edited" 解决方案更好,因为您不需要虚拟按钮来确定 22 列中每一列的宽度。

数组的大小定义了列数。

分配给数组中每个条目的值是该列的 "minimum width"(每列可以不同)。

所以现在,即使您没有虚拟组件,GridBagLayout 也知道如何计算每列的宽度并且使用 "gridwidth" 将按预期工作。