java 请帮助我理解 BoxLayout 对齐问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5702857/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 12:23:18  来源:igfitidea点击:

Please help me understanding BoxLayout alignment issues

javaswingalignmentboxlayout

提问by gd1

I'm trying to create a very simple window using Java Layouts. I have got three elements to arrange: a button, a progress bar and a label. The button has to be vertically centered, the progress bar has to take full width, and the label has to be left aligned.

我正在尝试使用 Java 布局创建一个非常简单的窗口。我安排了三个元素:一个按钮、一个进度条和一个标签。按钮必须垂直居中,进度条必须全宽,标签必须左对齐。

Here's some code (just assume pane is the content pane of a JFrame, and button, progressBar and label have been created before):

这是一些代码(假设窗格是 JFrame 的内容窗格,并且之前已创建按钮、进度条和标签):

BoxLayout layout = new BoxLayout(pane, BoxLayout.Y_AXIS);
pane.setLayout(layout);
button.setAlignmentX(Component.CENTER_ALIGNMENT);
pane.add(button);
progressBar.setAlignmentX(Component.CENTER_ALIGNMENT);
pane.add(progressBar);
label.setAlignmentX(Component.LEFT_ALIGNMENT);
pane.add(label);

When I test the application I see everything misaligned and screwed up: the button and the label are randomly indented, and if I resize the window the indentation amount changes in a strange way. The progress bar looks good (full width).

当我测试应用程序时,我看到所有东西都没有对齐和搞砸:按钮和标签是随机缩进的,如果我调整窗口大小,缩进量会以一种奇怪的方式变化。进度条看起来不错(全宽)。

I just don't understand what's happening. Can you give me a clue?

我只是不明白发生了什么。你能给我一个线索吗?

回答by kleopatra

BoxLayout cannot handle different alignments: see http://download.oracle.com/javase/tutorial/uiswing/layout/box.html

BoxLayout 无法处理不同的对齐方式:请参阅http://download.oracle.com/javase/tutorial/uiswing/layout/box.html

quoting from that article: "In general, all the components controlled by a top-to-bottom BoxLayout object should have the same X alignment. Similarly, all the components controlled by a left-to-right Boxlayout should generally have the same Y alignment."

引用那篇文章:“一般来说,由一个自上而下的 BoxLayout 对象控制的所有组件应该具有相同的 X 对齐方式。同样,由一个从左到右的 BoxLayout 对象控制的所有组件通常应该具有相同的 Y 对齐方式.”

回答by camickr

Sometimes you need to get a little creative and use nested panels. But I like this approach better then trying to learn and memorize all the constraints required when using other layout managers (GridBagLayout, GroupLayout) there where designed to be used by IDE's that generate code for you.

有时您需要发挥一点创意并使用嵌套面板。但是我更喜欢这种方法,而不是尝试学习和记住使用其他布局管理器(GridBagLayout、GroupLayout)时所需的所有约束,这些管理器旨在供 IDE 使用,为您生成代码。

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

public class BoxLayoutVertical extends JFrame
{
    public BoxLayoutVertical()
    {
        Box box = Box.createVerticalBox();

        JButton button = new JButton("A button");
        button.setAlignmentX(Component.CENTER_ALIGNMENT);
        box.add(button);

        JProgressBar progressBar = new JProgressBar(0, 100);
        progressBar.setAlignmentX(Component.CENTER_ALIGNMENT);
        box.add(progressBar);

        JPanel panel = new JPanel( new BorderLayout() );
        JLabel label = new JLabel("A label");
        label.setAlignmentX(Component.LEFT_ALIGNMENT);
        panel.add(label);
        box.add(panel);

        add(box, BorderLayout.NORTH);
    }

    public static void main(String[] args)
    {
        BoxLayoutVertical frame = new BoxLayoutVertical();
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
        frame.setSize(300, 200);
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
    }
}

回答by jfpoilpret

To complement my comment to the original question, here is a snippet that uses DesignGridLayout:

为了补充我对原始问题的评论,这里有一个使用DesignGridLayout的片段:

JButton button = new JButton("Button");
JProgressBar progressBar = new JProgressBar();
JLabel label = new JLabel("Label");

// The interesting stuff is in the next 4 lines
DesignGridLayout layout = new DesignGridLayout(getContentPane());
layout.row().center().add(button).withOwnRowWidth();
layout.row().center().fill().add(progressBar);
layout.row().left().add(label);

pack();

It does exactly what wou describe in your question and doesn't require any specific call of any of the components.

它完全符合您在问题中所描述的内容,并且不需要对任何组件进行任何特定调用。

回答by das_weezul

Maybe your code is just a snippet, but I'm missing a call to pack().

也许您的代码只是一个片段,但我错过了对pack().

Coding swing layout by hand can be very frustrating with the standard Layout managers. I use MiG Layoutfor that purpose. It is straight forward and you have a nice layout with just a few lines of code. If you're not forced to use BoxLayout I would suggest you give it a try.

使用标准布局管理器手动编写摆动布局可能会非常令人沮丧。为此,我使用MiG Layout。它很简单,您只需几行代码即可获得漂亮的布局。如果您不是被迫使用 BoxLayout,我建议您尝试一下。

回答by Pa?lo Ebermann

Don't use BoxLayout. It works only for very simple cases.

不要使用 BoxLayout。它仅适用于非常简单的情况。

For your case, I would recommend either GridBagLayout or (my favorite) GroupLayout.

对于您的情况,我会推荐 GridBagLayout 或(我最喜欢的)GroupLayout。



For GroupLayout, I created a subclass (LayoutHelper) with some utility methods and useful constructors, which makes writing the Layout much easier.

对于 GroupLayout,我创建了一个子类 ( LayoutHelper),其中包含一些实用方法和有用的构造函数,这使得编写 Layout 变得更加容易。

Of course, usually I align all components in a group the same way, so it is not as short in your caseas it would be in the simple case.

当然,通常我会以相同的方式对齐一组中的所有组件,因此在您的情况下它不像在简单情况下那么短。

    LayoutHelper h = new LayoutHelper(pane);

    h.setVerticalGroup
        ( h.sequential( button, progressBar, label));

    h.setHorizontalGroup
        ( ((ParallelGroup)h.parallel())
          .addComponent(button, Alignment.CENTER)
          .addComponent(progressBar)
          .addComponent(label, Alignment.TRAILING));

Here is a screenshot:

这是一个屏幕截图:

screenshot

截屏

For a simple "everything aligned the same way", the horizontal group would look like this:

对于简单的“所有内容都以相同方式对齐”,水平组将如下所示:

    h.setHorizontalGroup
        ( h.parallel (button, progressBar, label));

(optionally with a first argument indicating the alignment).

(可选地带有指示对齐的第一个参数)。