一个 GroupLayout 示例
Note:
本课涵盖了手工编写布局代码,这可能会很困难。如果您不希望了解布局 管理 的所有详细信息,则可能更喜欢将GroupLayout
布局 管理 器与构建器工具结合使用来布局 GUI。 NetBeans IDE是此类构建器工具之一。否则,如果您想手工编码并且不想使用GroupLayout
,那么推荐使用GridBagLayout
作为下一个最灵活,功能最强大的布局 管理 器。
如果您对使用 JavaFX 创建 GUI 感兴趣,请参阅在 JavaFX 中使用布局。
作为使用GroupLayout
创建 GUI 的示例,让我们为该“查找”对话框创建布局:
Horizontal layout
从左到右检查水平尺寸,我们可以看到一个序列中有 3 个组。第一个实际上不是一个组,而只是一个组件-标签。第二个是一个包含文本字段和复选框的组(稍后我们将对其进行分解)。第三个是两个按钮中的一组。如此处所示:
让我们勾勒出代码中的 Sequences 组。请注意,GroupLayout.Alignment.LEADING
对应于水平尺寸的左对齐。另请注意,假设间隙自动插入功能已打开,则我们未指定间隙。
layout.setHorizontalGroup(layout.createSequentialGroup()
.addComponent(label)
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING))
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING))
);
现在让我们分解中间的组。这是最难的。有一个并行的文本字段,其中包含两个并行组的序列,每个并行组包含两个复选框。请参见下图:
让我们添加相应的代码:
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
在垂直方向上,我们从上到下检查布局。我们绝对希望第一行的所有组件都与基线对齐。因此,沿着垂直轴,有一组基线组,然后是一组其余组件。见下图。
让我们勾勒出代码。首先,我们需要定义两个 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 组:
相应的代码如下所示:
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水平调整对话框的大小,以查看布局如何自动调整为新的大小。