Java 请帮助我了解BoxLayout对齐问题
我正在尝试使用Java布局创建一个非常简单的窗口。我有三个元素要安排:一个按钮、一个进度条和一个标签。按钮必须垂直居中,进度条必须全宽,标签必须左对齐 下面是一些代码(假设pane是JFrame的内容窗格,并且按钮、进度条和标签以前已经创建过): 当我测试应用程序时,我看到所有的东西都没有对齐和扭曲:按钮和标签是随机缩进的,如果我调整窗口的大小,缩进量会以一种奇怪的方式改变。 进度条看起来不错(全宽)Java 请帮助我了解BoxLayout对齐问题,java,swing,alignment,boxlayout,Java,Swing,Alignment,Boxlayout,我正在尝试使用Java布局创建一个非常简单的窗口。我有三个元素要安排:一个按钮、一个进度条和一个标签。按钮必须垂直居中,进度条必须全宽,标签必须左对齐 下面是一些代码(假设pane是JFrame的内容窗格,并且按钮、进度条和标签以前已经创建过): 当我测试应用程序时,我看到所有的东西都没有对齐和扭曲:按钮和标签是随机缩进的,如果我调整窗口的大小,缩进量会以一种奇怪的方式改变。 进度条看起来不错(全宽) 我只是不明白发生了什么。你能给我一个线索吗?也许你的代码只是一个片段,但我错过了对pack()
我只是不明白发生了什么。你能给我一个线索吗?也许你的代码只是一个片段,但我错过了对
pack()
的调用
手工编写swing布局对于标准布局管理器来说可能非常令人沮丧。我用它来做这个用途。这是直接的,你有一个很好的布局,只有几行代码。如果你不是被迫使用BoxLayout,我建议你试试。不要使用BoxLayout。它只适用于非常简单的情况 对于您的情况,我推荐GridBagLayout或(我最喜欢的)GroupLayout
对于GroupLayout,我创建了一个子类(),其中包含一些实用方法和有用的构造函数,这使得编写布局更加容易 当然,通常我以相同的方式对齐一组中的所有组件,因此它不像在简单情况下那样短
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));
以下是一个屏幕截图:
对于一个简单的“所有东西都以相同的方式对齐”,水平组如下所示:
h.setHorizontalGroup
( h.parallel (button, progressBar, label));
(可以选择使用第一个参数表示对齐)。为了补充我对原始问题的评论,下面是一个使用以下内容的片段:
它完全符合您问题中的描述,不需要对任何组件进行任何特定调用。BoxLayout无法处理不同的对齐方式:请参阅
引用那篇文章的话:“一般来说,由自上而下的BoxLayout对象控制的所有组件都应该具有相同的X对齐方式。类似地,由左到右的BoxLayout对象控制的所有组件通常都应该具有相同的Y对齐方式。”有时,您需要有点创意,并使用嵌套面板。但我更喜欢这种方法,而不是尝试学习和记忆使用其他布局管理器(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);
}
}
我喜欢这种MiG布局,但我真的不想为这样一个非常非常简单的应用程序链接其他JAR并将其推到更“复杂”的级别。@Giacomo:Fair够了;)“丢失的”pack()不是问题所在?就我个人而言,我从不信任setAlignmentX或setAlignmentY,并试图避免它们成为瘟疫,我也会避免完全依赖它们的布局管理器。我现在明白你为什么这么做了。。。你会建议什么替代方案呢?好吧,如果你必须坚持纯JDK,那么我可能会在你的案例中使用GridBagLayout;这将很好地工作,因为您的布局很简单(当您的布局有更多组件时,GBL开始变得复杂)。否则,我将使用DesignGridLayout。@Paulo您是否手工编写了GroupLayout?然后你似乎有太多的空闲时间:-)@kleopatra:我有一个包装器类,它有点方便。(我将添加它与此相关的外观)。一个简单的GroupLayout并不好,但也不比GridBagLayout好多少。@Giacomo:老实说,我不知道BoxLayout有什么好处。我在使用它时也遇到了一些问题,尤其是与布局方向正交的对齐方式。谢谢,所以BoxLayout对我来说是垃圾。我会按照你的提示去做。你确定它不能处理不同的对齐方式吗@安德鲁斯:当你建议长方体可以处理不同的对齐方式时,你指的是教程的哪一部分?解决方案是否涉及使用Box.createHorizontalGlue(),或者这是否可能?@Mins,请查看名为BoxLayoutDemo2的图像示例的部分。您将看到,使用Component.LEFT\u对齐、Component.CENTER\u对齐和Component.RIGHT\u对齐,组件之间是相对对齐的。@AndrewS:这对我不起作用,我已经发布了代码。出什么问题了?有史以来最好的解决方案,因为它不涉及额外的库,也不涉及额外的类,而且它是针对我所面临的问题定制的。然而,我将遵循其他用户的解决方案来了解更多关于布局的信息,但在本例中,我正在寻找一种简单的方法。
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();
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);
}
}