这些Java教程是针对JDK 8编写的。本页面描述的示例和实践不利用后续版本引入的改进,并可能使用不再可用的技术。
有关Java SE 9及其后续版本中更新的语言功能的摘要,请参见Java语言更改。
有关所有JDK版本的新功能、增强功能和已删除或不推荐选项的信息,请参见JDK发行说明。
GroupLayout
布局管理器结合构建工具来布局您的GUI。一个这样的构建工具是NetBeans IDE。否则,如果您想手动编码并且不想使用GroupLayout
,那么GridBagLayout
是推荐的下一个最灵活和强大的布局管理器。
如果您有兴趣使用JavaFX创建GUI,请参阅JavaFX中的布局。
作为使用GroupLayout
创建GUI的示例,让我们为这个“查找”对话框创建一个布局:
从左到右检查水平维度,我们可以看到有3个顺序的组。第一个实际上不是一个组,只是一个组件 - 标签。第二个是一个包含文本字段和复选框的组(我们稍后会拆分它)。第三个是两个按钮的组。如下所示:
让我们用代码勾勒出顺序组。请注意,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轴。
在垂直维度上,我们从上到下检查布局。我们肯定希望第一行上的所有组件在基线上对齐。因此,沿着垂直轴有一个基线组的序列,后面是剩余组件的一个组。请参见以下图片。
让我们先概述一下代码。首先,我们需要定义两个平行组。请注意,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)) );
现在让我们来看看底部组。请注意,取消按钮与复选框不共享基线;它与顶部对齐。因此,第二个平行组包括按钮和两个基线组的序列组:
对应的代码如下:
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)) );
所以,我们已经创建了一个完整的布局,包括调整大小的行为,而不需要指定像素单位的具体数字 - 这是一个真正的跨平台布局。请注意,我们不需要指定组件之间的间距,自动获得正确的间距,以符合外观和感觉的指南。这是查找对话框布局的完整代码:
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
文件。您可以编译并运行它。尝试水平调整对话框的大小,看看布局如何自动调整到新的大小。