java - 如何让 FlowLayout 像其他组件一样在底部对齐 JPanel?

标签 java swing layout layout-manager flowlayout

我有一个案例,我将 JPanel 添加到 FlowLayout,但它们没有将自己对齐到布局的底部。我正在使用此 layout.setAlignOnBaseline(true) 并将 JLabel 正确对齐到面板底部。但是,一旦这些标签本身包裹在面板中,它就不再有效了。这是我的意思的示例,顶部和底部有两个面板。

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

public class BadLayout {

    private static final Font font1 = new Font("Arial", Font.BOLD, 14);
    private static final Font font2 = new Font("Arial", Font.BOLD, 30);

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("Bad layout");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            FlowLayout layout = new FlowLayout(FlowLayout.LEADING, 0, 0);
            layout.setAlignOnBaseline(true);

            JPanel topPanel = new JPanel();
            topPanel.setLayout(layout);
            topPanel.setBackground(Color.BLACK);
            for (int i = 0; i < 10; i++) {
                JLabel label = new JLabel("Foo");
                label.setForeground(Color.WHITE);
                label.setBackground(Color.RED);
                label.setOpaque(true);
                label.setFont(i % 2 == 0 ? font1 : font2);

                JPanel subPanel = new JPanel();
                subPanel.setLayout(layout);
                subPanel.setBackground(Color.RED);
                subPanel.add(label);
                subPanel.setAlignmentY(Component.BOTTOM_ALIGNMENT);

                topPanel.add(subPanel);
            }

            JPanel bottomPanel = new JPanel();
            bottomPanel.setLayout(layout);
            bottomPanel.setBackground(Color.DARK_GRAY);
            for (int i = 0; i < 10; i++) {
                JLabel label = new JLabel("Foo");
                label.setForeground(Color.WHITE);
                label.setBackground(Color.RED);
                label.setOpaque(true);
                label.setFont(i % 2 == 0 ? font1 : font2);
                bottomPanel.add(label);
            }

            JPanel parentPanel = new JPanel();
            parentPanel.setLayout(new BorderLayout());
            parentPanel.add(topPanel, BorderLayout.NORTH);
            parentPanel.add(bottomPanel, BorderLayout.SOUTH);

            frame.getContentPane().add(parentPanel);
            frame.pack();
            frame.setVisible(true);
        });
    }
}

如果您运行此代码,您会注意到顶部面板有较小的“Foo”居中,而底部的面板具有我希望的所需“底部对齐”行为。有什么想法可以让子 JPanel 的行为相同吗?

最佳答案

setAlignOnBaseline(...) 方法的 API 声明:

没有基线的组件将居中

JPanel 没有合理的基线可供使用,因为组件可能位于多行,具体取决于所使用的布局管理器。所以它是居中的。

我无法从你的问题中判断出你是否真的试图将所有文本居中放置在与字体大小无关的基线上,或者你是否只是想让所有组件都绘制在面板的底部。

如果您尝试将文本置于基线上居中,那么也许您可以使用如下代码覆盖面板的基线:

JPanel subPanel = new JPanel()
{
    @Override
    public int getBaseline(int width, int height)
    {
        Component c = getComponent(0);
        return c.getBaseline(width, height);
    }
};

当然,这只有在面板上的所有组件都具有相同的基线时才有效。

或者,如果您只是想将所有组件放置在面板底部,那么您需要使用不同的布局管理器。

您可以使用 Relative Layout将所有组件对齐到底部。

它可以直接替换您现有的代码:

RelativeLayout rl = new RelativeLayout(RelativeLayout.X_AXIS, 0);
rl.setAlignment( RelativeLayout.TRAILING );
JPanel topPanel = new JPanel(rl);

或者,如果您不想使用非 JDK 类,则可以使用 BoxLayoutGridBagLayout

如果您使用 BoxLayout,那么您将需要使用每个组件的 setAlignmentY(...) 属性。

如果您使用 GridBagLayout,那么您将需要使用每个组件的约束。

关于java - 如何让 FlowLayout 像其他组件一样在底部对齐 JPanel?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39111028/

相关文章:

Java树节点选择

java: JSplitpane 的问题

JSF Primefaces在布局问题中使用菜单栏

html - 如何在标题 div 内的导航栏 div 中放置无序列表?

java - 二维数组错误检查,战舰游戏

java - 如何在 Eclipse ADT 中调试库

java - 有没有办法使单个 JPA 实体中两个外键的组合唯一?

java - 当我更新 JTable 中的数据库时,我得到多个项目

java - 为什么我的 Paint surface 方法不起作用?

具有等高列的 CSS Fluid-Fixed 布局