java - 如何使包含 FlowLayout 的 JPanel 居中?

标签 java swing jpanel layout-manager

我有一个包含一些组件的 JPanel,使用 FlowLayout 对它们进行布局,以便它们在必要时进行换行,我想将这个 JPanel 置于 JFrame 的中心。 我尝试将 BoxLayout 与 VerticalGlue 一起使用,但它并没有完全居中。 这是一个简单的 SSCCE,它演示了我的问题,因为我认为我无法很好地解释它:

import javax.swing.*;
public class Test extends JFrame {
    public static void main(String[] args) {
        new Test();
    }
    public Test() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
        getContentPane().add(Box.createVerticalGlue());
        JPanel panel = new JPanel();
        panel.add(new JButton("New button"));
        panel.add(new JButton("New button"));
        getContentPane().add(panel);
        setVisible(true);
    }
}

如果窗口足够宽,可以让两个按钮并排放置,它看起来几乎居中:

但如果它太小你可以清楚地看到我的问题:

问题是 JPanel 占据了 JFrame 的下半部分,而 Glue 占据了上半部分:

我也尝试过其他 LayoutManager,但我还不能解决这个问题。

编辑:

如果 BorderLayout 和 JPanel 位于中心,则按钮出现在顶部,因为 JPanel 扩展到 JFrame 的 ContentPane 的大小:

有了 GridBagLayout,它看起来很完美,所有东西都相邻。但如果组件被包裹起来,它们就会消失:

使用 MigLayout,按钮将不再换行:

编辑: 我使用的解决方案是 Wrap Layout 的组合使用 GridBagLayout:

import java.awt.*;
import javax.swing.*;
class Test extends JFrame {
    public static void main(String[] args) {
        new Test();
    }
    Test() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        GridBagLayout gridBagLayout = new GridBagLayout();
        gridBagLayout.columnWeights = new double[]{1.0};
        getContentPane().setLayout(gridBagLayout);
        JPanel panel = new JPanel(new WrapLayout());
        GridBagConstraints gbc_panel = new GridBagConstraints();
        gbc_panel.fill = GridBagConstraints.HORIZONTAL;
        getContentPane().add(panel, gbc_panel);
        panel.add(new JButton("New button"));
        panel.add(new JButton("New button"));
        setVisible(true);
    }
}

最佳答案

The problem is that the JPanel takes the lower half of the JFrame and the Glue the upper half:

问题在于 BoxLayout 将允许组件增长到组件的最大尺寸。在面板的情况下,最大尺寸是最大整数值,因此胶水和面板都获得相等的空间量。因此,如果您想使用 BoxLayout,则需要覆盖 getMaximumSize() 方法以返回面板的首选大小。

I tried to use a BoxLayout with a VerticalGlue, but it doesn't center it completely.

完成上述更改后,您需要使用 verticalGlue 两次:

Box box = new Box.createVerticalBox(); 
box.add( Box.createVerticalGlue() );
box.add( panel );
box.add( Box.createVerticalGlue() );

现在面板上方和下方的空间相等。但是,当组件换行到下一行时,这仍然不起作用,因为 FlowLayout 不会根据换行的组件重新计算高度。所以在这种情况下,您可以将 FlowLayout 替换为 Wrap Layout它只是扩展 FlowLayout 以正确计算包裹高度。

或者不使用 BoxLayout,您可以使用 GridBagLayout。默认情况下,添加到 GridBagLayout 的组件将水平和垂直居中。您仍然需要带有 WrapLayout

的面板

关于java - 如何使包含 FlowLayout 的 JPanel 居中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30762173/

相关文章:

java - 如何在 Java 中的 JFrame 上的 JPanel 上绘画

java - 不同类(class)的 JPanel,是我做的不好吗?为什么?

java - 检查双重平等是否安全?

java - 无法注入(inject)在 persistence.xml 中声明的 EntityManager

java - JDBC 混合大小写表名和列名

java - 按钮大小不变

带有自定义标题栏的 java swing 应用程序?

java - 为什么我的 java 应用程序模糊?

JavaFx:获取点击的按钮值

java - 运行 JPanel 窗体