一个 GroupLayout 示例

Note:

本课涵盖了手工编写布局代码,这可能会很困难。如果您不希望了解布局 管理 的所有详细信息,则可能更喜欢将GroupLayout布局 管理 器与构建器工具结合使用来布局 GUI。 NetBeans IDE是此类构建器工具之一。否则,如果您想手工编码并且不想使用GroupLayout,那么推荐使用GridBagLayout作为下一个最灵活,功能最强大的布局 管理 器。

如果您对使用 JavaFX 创建 GUI 感兴趣,请参阅在 JavaFX 中使用布局

作为使用GroupLayout创建 GUI 的示例,让我们为该“查找”对话框创建布局:

Find.

Horizontal layout

从左到右检查水平尺寸,我们可以看到一个序列中有 3 个组。第一个实际上不是一个组,而只是一个组件-标签。第二个是一个包含文本字段和复选框的组(稍后我们将对其进行分解)。第三个是两个按钮中的一组。如此处所示:

Find.

让我们勾勒出代码中的 Sequences 组。请注意,GroupLayout.Alignment.LEADING对应于水平尺寸的左对齐。另请注意,假设间隙自动插入功能已打开,则我们未指定间隙。

layout.setHorizontalGroup(layout.createSequentialGroup()
    .addComponent(label)
    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING))
    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING))
);

现在让我们分解中间的组。这是最难的。有一个并行的文本字段,其中包含两个并行组的序列,每个并行组包含两个复选框。请参见下图:

Find_a2.

让我们添加相应的代码:

layout.setHorizontalGroup(layout.createSequentialGroup()
    .addComponent(label)
    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
         .addComponent(textField)
         .addGroup(layout.createSequentialGroup()
              .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                  .addComponent(caseCheckBox)
                  .addComponent(wholeCheckBox))
              .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                  .addComponent(wrapCheckBox)
                  .addComponent(backCheckBox))))
     .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING))
);

我们希望文本字段可调整大小,但这会自动发生,因为JTextField默认会返回正确的最大大小。

右边的其余组很简单:它仅包含两个按钮。这是代码:

layout.setHorizontalGroup(layout.createSequentialGroup()
    .addComponent(label)
    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
        .addComponent(textField)
        .addGroup(layout.createSequentialGroup()
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                .addComponent(caseCheckBox)
                .addComponent(wholeCheckBox))
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                .addComponent(wrapCheckBox)
                .addComponent(backCheckBox))))
    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
        .addComponent(findButton)
        .addComponent(cancelButton))
);

最后,我们希望按钮的大小始终相同,因此让我们将它们链接起来:

layout.linkSize(SwingConstants.HORIZONTAL, findButton, cancelButton);

现在我们完成了水平尺寸。让我们切换到垂直尺寸。从现在开始,我们只需要考虑 y 轴。

Vertical layout

在垂直方向上,我们从上到下检查布局。我们绝对希望第一行的所有组件都与基线对齐。因此,沿着垂直轴,有一组基线组,然后是一组其余组件。见下图。

Find_a3.

让我们勾勒出代码。首先,我们需要定义两个 Parallel 的组。请注意,GroupLayout.Alignment.LEADING对应于垂直尺寸的顶部对齐。

layout.setVerticalGroup(layout.createSequentialGroup()
    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE))
    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING))
);

我们可以立即填充基准组:

layout.setVerticalGroup(layout.createSequentialGroup()
    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
        .addComponent(label)
        .addComponent(textField)
        .addComponent(findButton))
    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING))
);

现在让我们看一下最底层的人群。请注意,“取消”按钮不在与复选框共享的基线上。它在顶部对齐。因此,第二个并行组包括按钮和两个带有复选框的基线组的 Sequences 组:

Find_a4.

相应的代码如下所示:

layout.setVerticalGroup(layout.createSequentialGroup()
    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
        .addComponent(label)
        .addComponent(textField)
        .addComponent(findButton))
    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                .addComponent(caseCheckBox)
                .addComponent(wrapCheckBox))
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                .addComponent(wholeCheckBox)
                .addComponent(backCheckBox)))
        .addComponent(cancelButton))
);

因此,我们创建了一个完整的布局,包括调整大小行为,而没有指定单个像素(一个 true 的跨平台布局)。请注意,我们不需要指定组件之间的间隙,我们会根据外观和感觉准则自动获得正确的间距。这是“查找”对话框的布局的完整代码:

GroupLayout layout = new GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true);

layout.setHorizontalGroup(layout.createSequentialGroup()
    .addComponent(label)
    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
        .addComponent(textField)
        .addGroup(layout.createSequentialGroup()
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                .addComponent(caseCheckBox)
                .addComponent(wholeCheckBox))
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                .addComponent(wrapCheckBox)
                .addComponent(backCheckBox))))
    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
        .addComponent(findButton)
        .addComponent(cancelButton))
);
layout.linkSize(SwingConstants.HORIZONTAL, findButton, cancelButton);

layout.setVerticalGroup(layout.createSequentialGroup()
    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
        .addComponent(label)
        .addComponent(textField)
        .addComponent(findButton))
    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                .addComponent(caseCheckBox)
                .addComponent(wrapCheckBox))
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                .addComponent(wholeCheckBox)
                .addComponent(backCheckBox)))
        .addComponent(cancelButton))
);

这是完整的Find.java文件。您可以编译并运行它。try水平调整对话框的大小,以查看布局如何自动调整为新的大小。