FlowLayout的意外行为

问题描述 投票:0回答:1

我用的是 JPanel 默认 FlowLayout 布局管理器。我想万一应用程序窗口被调整了大小,没有足够的宽度来显示所有的组件在 JPanel 中,一些组件将被移动到另一行。

这个假设是基于文档的。

如果容器中的水平空间太小,无法将所有组件放在一行中,FlowLayout类就会使用多行。

https:/docs.oracle.comjavasetutorialuiswinglayoutflow.html。

在某些情况下是可行的。例如,当使用这段代码并减少窗口宽度时,按钮将位于不同的行上。

import javax.swing.*;
import java.awt.*;

public class FlowLayoutExpected {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();

        JButton button1 = new JButton("Button 1");
        JButton button2 = new JButton("Button 2");
        JButton button3 = new JButton("Button 3");

        panel.add(button1);
        panel.add(button2);
        panel.add(button3);

        frame.getContentPane().add(BorderLayout.CENTER, panel);

        frame.setSize(350, 70);
        frame.setVisible(true);
    }
}

在减少宽度之前 -> 减宽后

但只要把一个 JPanel 变成 JPanel 布局管理器就会像预期的那样停止工作。

import javax.swing.*;
import java.awt.*;

public class FlowLayoutReal {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        JPanel outerPanel = new JPanel();
        JPanel innerPanel = new JPanel();

        JButton button1 = new JButton("Button 1");
        JButton button2 = new JButton("Button 2");
        JButton button3 = new JButton("Button 3");

        innerPanel.add(button1);
        innerPanel.add(button2);
        innerPanel.add(button3);

        outerPanel.add(innerPanel);
        frame.getContentPane().add(BorderLayout.CENTER, outerPanel);

        frame.setSize(350, 70);
        frame.setVisible(true);
    }
}

在减少宽度之前 -> 减宽后

我想澄清一下我误解的地方。


我读到了很多关于使用 WrapLayout 而不是 FlowLayout. 这似乎是合理的,但我仍然不清楚为什么我在上面的例子中得到了不一致的行为。

java awt flowlayout
1个回答
1
投票
frame.getContentPane().add(BorderLayout.CENTER, panel);

首先,该方法从JDK1.1开始就已经 "过时 "了。

从那时起,首选的方法是添加 "约束 "作为第二个参数。

frame.getContentPane().add(panel, BorderLayout.CENTER);

但只要把一个JPanel放到另一个JPanel中就可以了,布局管理器就不会再像预期的那样了。

代码是按预期工作的 问题在于你的期望。

改变你第一个例子中的代码。

//frame.getContentPane().add(panel, BorderLayout.CENTER);
frame.getContentPane().add(panel, BorderLayout.PAGE_START);

现在,当你减少宽度时,组件消失了。这是因为 BorderLayout.PAGE_START 将尊重所添加组件的首选高度。首选的高度是通过在单行上显示所有组件来确定的。

但是,只要把一个JPanel放到另一个JPanel中,布局管理器就会按照预期的方式停止运行。

当你开始包装面板时,你需要了解其中的含义。

FlowLayout 尊重所有添加的组件的首选大小。因此,内部面板中的组件都会按照预期的方式显示在一行中。

当您将外部面板添加到 BorderLayout.CENTER 调整了外侧面板的尺寸,但它并不影响内侧面板,因为规则中的 FlowLayout,比如说添加的任何组件都会显示在面板的顶部。由于内部面板是一个单一的组件,所以没有任何东西可以包裹。

这是一个常用的技巧,对你有好处,以确保一个组件保留它的首选大小。

另一个例子。也许你有一个水平的 GridLayout 的按钮的数量。BorderLayout.PAGE_START.

如果你直接添加面板,那么按钮的大小将随着框架的改变而缩小。

如果你想让按钮的大小保持不变,你可以使用一个 "包装 "面板。那么 "包装 "面板的大小会收缩增长,但按钮的大小保持不变。

你需要了解布局管理器的规则,这样你才能有效地使用它。

© www.soinside.com 2019 - 2024. All rights reserved.