简体   繁体   English

FlowLayout 的意外行为

[英]Unexpected behavior of FlowLayout

I'm using JPanel with a default FlowLayout layout manager.我正在使用带有默认FlowLayout布局管理器的JPanel I think in case the application window was resized and there is not enough width to show all components in JPanel in one row, some components will be moved to another row(s).我认为如果应用程序 window 被调整大小并且没有足够的宽度在一行中显示JPanel中的所有组件,一些组件将被移动到另一行。

This assumption is based on the documentation:此假设基于文档:

If the horizontal space in the container is too small to put all the components in one row, the FlowLayout class uses multiple rows.如果容器中的水平空间太小,无法将所有组件放在一行中,则 FlowLayout class 使用多行。

https://docs.oracle.com/javase/tutorial/uiswing/layout/flow.html https://docs.oracle.com/javase/tutorial/uiswing/layout/flow.html

It works in some cases.它在某些情况下有效。 For example, while using this code and decreasing window width, buttons will be located on different rows:例如,在使用此代码并减小 window 宽度时,按钮将位于不同的行:

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);
    }
}

Before decreasing width减小宽度之前-> After decreasing width -> 减小宽度后

But it is enough to put one JPanel into another JPanel and layout manager stops to behave as expected:但是将一个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);
    }
}

Before decreasing width减小宽度之前-> After decreasing width -> 减小宽度后

I'm trying to clarify what I misunderstood.我试图澄清我误解了什么。


I've read a lot of suggestions to use WrapLayout instead of FlowLayout .我已经阅读了很多使用WrapLayout而不是FlowLayout的建议。 It seems reasonable, but still not clear for me why I got inconsistent behavior in the examples above.这似乎是合理的,但我仍然不清楚为什么在上面的示例中我的行为不一致。

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

First of all that method has been "obsolete" since JDK1.1.首先,该方法自 JDK1.1 以来已“过时”。

The preferred approach since then is to add the "constraint" as the second parameter:从那时起,首选方法是添加“约束”作为第二个参数:

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

But it is enough to put one JPanel into another JPanel and layout manager stops to behave as expected:但是将一个 JPanel 放入另一个 JPanel 并且布局管理器停止按预期运行就足够了:

The code is working as expected.代码按预期工作。 The issue is your expectation.问题是你的期望。

Change the code in your first example:更改第一个示例中的代码:

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

Now, when you decrease the width the components disappear.现在,当您减小宽度时,组件就会消失。 This is because the BorderLayout.PAGE_START will respect the preferred height of the component added.这是因为BorderLayout.PAGE_START将尊重所添加组件的首选高度。 The preferred height is determined by displaying all components on a single row.首选高度是通过在单行上显示所有组件来确定的。

But it is enough to put one JPanel into another JPanel and layout manager stops to behave as expected但是将一个 JPanel 放入另一个 JPanel 并且布局管理器停止按预期运行就足够了

When you start wrapping panels you need to understand the implications.当您开始包装面板时,您需要了解其中的含义。

The FlowLayout respects the preferred size of all components added. FlowLayout尊重添加的所有组件的首选大小。 So the components in the inner panel are all displayed in a row as expected.所以内部面板中的组件都按预期显示在一行中。

When you add the outer panel to the BorderLayout.CENTER the outer panel size is adjusted, but it does not affect the inner panel because the rules of the FlowLayout , say any component added is displayed at the top of the panel.当您将外面板添加到BorderLayout.CENTER时,会调整外面板的大小,但不会影响内面板,因为FlowLayout的规则,比如添加的任何组件都会显示在面板的顶部。 Since the inner panel is a single component, there is nothing to wrap.由于内面板是单个组件,因此无需包装。

This is a trick that is often used to your advantage to ensure a component retains its preferred size.这是一个经常用于确保组件保持其首选大小的技巧。

Another example.另一个例子。 Maybe you have a horizontal GridLayout of buttons on a panel you want to add to the BorderLayout.PAGE_START .也许您在要添加到BorderLayout.PAGE_START的面板上有一个水平GridLayout按钮。

If you add the panel directly, then the size of the button will shrink/grow as the frame with is changed.如果您直接添加面板,则按钮的大小将随着框架的更改而缩小/增长。

If you want the buttons size to remain constant, you can use a "wrapper" panel.如果您希望按钮大小保持不变,您可以使用“包装”面板。 Then the "wrapper" panel size shrinks/grows, but the buttons size remains constant.然后“包装”面板大小缩小/增长,但按钮大小保持不变。

You need to understand the rules of the layout manager so you can use it effectively.您需要了解布局管理器的规则,以便有效地使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM