Java 中文官方教程 2022 版(二十二)(3)

简介: Java 中文官方教程 2022 版(二十二)

Java 中文官方教程 2022 版(二十二)(2)https://developer.aliyun.com/article/1486763

但是,我们建议您使用Container.add方法,因为这比使用setConstraints更清晰。


这里是一个表格,显示了GridBagLayoutDemo内容窗格中每个组件的所有约束条件。非默认值用粗体标记。与前一表项不同的值用斜体标记。

组件 约束条件
所有组件
ipadx = 0
fill = GridBagConstraints.HORIZONTAL

|

按钮 1
ipady = 0 weightx = 0.5 weighty = 0.0 gridwidth = 1 anchor = GridBagConstraints.CENTER insets = new Insets(0,0,0,0) gridx = 0 gridy = 0

|

按钮 2
weightx = 0.5
***gridx = 1***
gridy = 0

|

按钮 3
weightx = 0.5
***gridx = 2***
gridy = 0

|

按钮 4
***ipady = 40***
*weightx = 0.0*
***gridwidth = 3***
***gridx = 0***
***gridy = 1***

|

按钮 5
*ipady = 0*
weightx = 0.0
***weighty = 1.0***
***anchor = GridBagConstraints.PAGE_END***
***insets = new Insets(10,0,0,0)***
***gridwidth = 2***
***gridx = 1***
***gridy = 2***

|

GridBagLayoutDemo有两个跨越多列的组件(按钮 4 和按钮 5)。为了使按钮 4 变高,我们向其添加了内部填充(ipady)。为了在按钮 4 和按钮 5 之间留出空间,我们使用插入来在按钮 5 上方添加至少 10 像素,并使按钮 5 贴近其单元格的底边。

pane容器中的所有组件都尽可能宽,给定它们所占用的单元格。程序通过将GridBagConstraintsfill实例变量设置为GridBagConstraints.HORIZONTAL来实现这一点,并为所有组件保持该设置。如果程序没有指定填充,按钮将保持其自然宽度,如下所示:


当您放大 GridBagLayoutDemo 的窗口时,列会成比例增长。这是因为第一行中的每个组件,每个组件都是一列宽,weightx = 0.5。这些组件的weightx的实际值并不重要。重要的是所有组件,因此所有列,具有大于 0 的相等权重。如果由GridBagLayout管理的任何组件未设置weightx,则当组件的容器变宽时,组件将保持在容器中心聚集在一起,如下所示:


如果容器的大小比首选大小小或大,则任何空间都根据GridBagContainer的权重分配。

请注意,如果您放大窗口,只有最后一行会变高。这是因为只有按钮 5 的weighty大于零。

GridBagLayout API

GridBagLayoutGridBagConstraints类各自只有一个构造函数,没有参数。您不是在GridBagConstraints对象上调用方法,而是操作其实例变量,如指定约束中所述。通常,您在GridBagLayout对象上调用的唯一方法是setConstraints,如示例解释中所示。

使用 GridBagLayout 的示例

您可以在本教程中找到使用GridBagLayout的示例。以下表格列出了一些示例。

示例 描述位置 注释
GridBagLayoutDemo 本节 使用许多功能——权重、插入、内部填充、水平填充、精确单元格定位、多列单元格和锚定(组件在单元格内的定位)。
TextSamplerDemo 使用文本组件 对齐两对标签和文本字段,并在容器的整个宽度上添加一个标签。
ContainerEventDemo 如何编写容器监听器 使用权重、填充和相对定位在容器中定位五个组件。

如何使用 GridLayout

原文:docs.oracle.com/javase/tutorial/uiswing/layout/grid.html


注意: 本课程涵盖手动编写布局代码,这可能具有挑战性。如果您不想学习布局管理的所有细节,您可能更喜欢使用GroupLayout布局管理器结合构建工具来布局您的 GUI。其中一个构建工具是 NetBeans IDE。否则,如果您想手动编码且不想使用GroupLayout,那么建议使用GridBagLayout作为下一个最灵活和强大的布局管理器。


如果您有兴趣使用 JavaFX 创建 GUI,请参阅JavaFX 中的布局

以下图表示使用GridLayout类的应用程序的快照。


点击“启动”按钮以使用Java™ Web Start运行GridLayoutDemo下载 JDK 7 或更高版本)。或者,要自行编译和运行示例,请参考示例索引。


此演示的完整代码位于GridLayoutDemo.java文件中。

GridLayout 对象将组件放置在单元格网格中。每个组件占据其单元格中的所有可用空间,每个单元格的大小完全相同。如果调整GridLayoutDemo窗口的大小,GridLayout 对象会更改单元格大小,以使单元格尽可能大,给定容器可用的空间。

下面的代码片段创建了GridLayout对象和其管理的组件。

GridLayout experimentLayout = new GridLayout(0,2);
...
        compsToExperiment.setLayout(experimentLayout);
        compsToExperiment.add(new JButton("Button 1"));
        compsToExperiment.add(new JButton("Button 2"));
        compsToExperiment.add(new JButton("Button 3"));
        compsToExperiment.add(new JButton("Long-Named Button 4"));
        compsToExperiment.add(new JButton("5"));

GridLayout 类的构造函数创建一个具有两列并且必要行数的实例。

使用组合框设置组件周围的垂直或水平填充量,然后单击“应用间隙”按钮。以下代码片段显示了如何使用GridLayout类的setVgapsetHgap方法处理您的选择:

applyButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                //Get the horizontal gap value
                String horGap = (String)horGapComboBox.getSelectedItem();
                //Get the vertical gap value
                String verGap = (String)verGapComboBox.getSelectedItem();
                //Set up the horizontal gap value
                experimentLayout.setHgap(Integer.parseInt(horGap));
                //Set up the vertical gap value
                experimentLayout.setVgap(Integer.parseInt(verGap));
                //Set up the layout of the buttons
                experimentLayout.layoutContainer(compsToExperiment);
            }
        });

GridLayout API

以下表格列出了指定行数和列数的GridLayout类的构造函数。

GridLayout 类的构造函数

构造函数 目的
GridLayout(int *rows*, int *cols*) 创建具有指定行数和列数的网格布局。布局中的所有组件都具有相同的大小。rowscols中的一个,但不是两者都可以为零,这意味着可以在一行或一列中放置任意数量的对象。
GridLayout(int *rows*, int *cols*, int *hgap*, int *vgap*) 创建具有指定行数和列数的网格布局。此外,水平和垂直间隙设置为指定值。水平间隙放置在每列之间。垂直间隙放置在每行之间。

GridLayout类有两个构造函数:

使用GridLayout的示例

下表列出了使用GridLayout类的代码示例,并提供到相关部分的链接。

示例 描述位置 注释
GridLayoutDemo 本页面 使用了 2 列网格。
ComboBoxDemo2 如何使用组合框 其中一个示例,使用 1x1 网格使组件尽可能大。
LabelDemo 如何使用标签 使用了 3 行网格。

如何使用 GroupLayout

原文:docs.oracle.com/javase/tutorial/uiswing/layout/group.html

GroupLayout 是为 GUI 构建器(如 NetBeans IDE 提供的 GUI 构建器 Matisse)开发的布局管理器。尽管布局管理器最初是为适应 GUI 构建器的需求而设计的,但它也适用于手动编码。本讨论将教你GroupLayout的工作原理,并向你展示如何使用GroupLayout构建 GUI,无论你选择使用像 Matisse 这样的 GUI 构建器还是编写自己的代码。


注意: 本课程涵盖了手动编写布局代码,这可能具有挑战性。如果您对学习布局管理的所有细节不感兴趣,您可能更喜欢使用GroupLayout布局管理器结合构建工具来布局您的 GUI。其中一个构建工具是 NetBeans IDE。否则,如果您想手动编写代码而不想使用GroupLayout,那么推荐使用GridBagLayout作为下一个最灵活和强大的布局管理器。


如果您有兴趣使用 JavaFX 创建 GUI,请参阅JavaFX 中的布局

设计原则:独立维度

GroupLayout 分别处理水平和垂直布局。每个维度的布局都是独立定义的。在定义水平布局时,你不需要担心垂直维度,反之亦然,因为沿着每个轴的布局完全独立于沿着另一个轴的布局。

当只关注一个维度时,你只需一次解决一半的问题。这比同时处理两个维度要容易。这意味着,当然,每个组件在布局中需要定义两次。如果忘记这样做,GroupLayout 将生成异常。

布局组织:分层组

GroupLayout 使用两种类型的布局——顺序和并行,结合了分层组合。

  1. 采用顺序排列,组件就像BoxLayoutFlowLayout沿一个轴一样简单地一个接一个地放置。每个组件的位置都是相对于前一个组件定义的。
  2. 第二种方式将组件并排放置——在同一空间中叠加。它们可以沿垂直轴基线对齐、顶部对齐或底部对齐。沿水平轴,如果组件大小不同,它们可以左对齐、右对齐或居中对齐。

通常,沿一个维度并排放置的组件在另一个维度上是顺序排列的,以避免重叠。

这两种布局之所以强大,是因为它们可以被嵌套层次化。为此,GroupLayout 定义了布局组。一个组可以是顺序的或并行的,并且可以包含组件、其他组和间隙(下面讨论)。

顺序组的大小是包含元素的大小之和,而并行组的大小对应于最大元素的大小(尽管,根据元素和基线的位置,基线对齐组的大小可能比最大元素稍大一些)。

定义布局意味着定义组件如何通过组合顺序和并行排列进行分组。

让我们用一个简单的例子来看看它在实践中是如何工作的。

一个例子

让我们从一些简单的东西开始,只有一排中的三个组件:


我们将使用组来表示此布局。从水平轴开始,很容易看到有一个从左到右排列的顺序组,包含 3 个组件。沿着垂直轴,有一个相同位置、大小和基线的并行组,包含相同的 3 个组件:


在伪代码中,布局规范可能看起来像这样(真正的代码在下面的编写代码部分):

horizontal layout = sequential group { c1, c2, c3 }
vertical layout = parallel group (BASELINE) { c1, c2, c3 }

这说明了前面提到的一个原则:在一个维度上顺序组合的组件通常在另一个维度上形成并行组。

现在让我们再添加一个组件 C4,与 C3 左对齐:


沿着水平轴,新组件占据与 C3 相同的水平空间,以便与 C3 形成并行组。沿着垂直轴,C4 与最初的三个组件的并行组形成顺序组。


在伪代码中,布局规范现在看起来像这样:

horizontal layout = sequential group { c1, c2, parallel group (LEFT) { c3, c4 } }
vertical layout = sequential group { parallel group (BASELINE) { c1, c2, c3 }, c4 }

现在您了解了使用GroupLayout设计布局的最重要方面。还有一些细节需要解释:如何添加间隙,如何定义大小和调整大小行为,如何定义对齐布局,以及如何编写真实代码。

间隙

间隙可以被视为具有特定大小的不可见组件。可以像组件或其他组件一样向组中添加任意大小的间隙。使用间隙,您可以精确控制组件之间的距离或与容器边框的距离。

GroupLayout还定义了自动间隙,这些间隙对应于相邻组件之间(或组件与容器边框之间)的首选距离。这样的间隙的大小是动态计算的,基于应用程序使用的外观和感觉(LayoutStyle类用于此)。使用自动(首选)间隙有两个优点:您不必指定间隙的像素大小,它们会自动调整到 UI 运行的外观和感觉,反映实际的外观和感觉指南。

GroupLayout区分两个组件之间的首选间隙和组件与容器边框之间的首选间隙。在GroupLayout API 中有相应的方法用于添加这些间隙(addPreferredGapsetContainerGap)。有三种类型的组件间隙:相关不相关缩进LayoutStyle.ComponentPlacement枚举定义了用作addPreferredGap方法参数的相应常量:RELATEDUNRELATEDINDENT。相关和不相关间隙之间的区别仅在于大小 - 不相关组件之间的距离稍大一些。缩进表示当一个组件位于另一个组件下方并带有缩进时,两个组件之间的首选水平距离。


如上所述,GroupLayout可以自动插入间隙 - 如果您没有显式添加自己的间隙,它会为您添加相关的首选间隙。但这不是默认行为。您必须通过在GroupLayout上调用setAutoCreateGaps(true)setAutoCreateContainerGaps(true)来打开此功能。然后您将自动获得正确的间距。

编写代码

现在,让我们看一下创建上述布局的实际代码。

假设我们有一个名为panel的容器和已经呈现的相同四个组件(c1c2c3c4)。首先,我们创建一个新的GroupLayout对象并将其与面板关联:

GroupLayout layout = new GroupLayout(panel);
 panel.setLayout(layout);

我们指定自动插入间隙:

layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true);

然后,我们定义组并添加组件。我们使用setHorizontalGroupsetVerticalGroup方法为每个维度建立根组。通过createSequentialGroupcreateParallelGroup方法创建组。使用addComponent方法将组件添加到组中。

layout.setHorizontalGroup(
   layout.createSequentialGroup()
      .addComponent(c1)
      .addComponent(c2)
      .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
           .addComponent(c3)
           .addComponent(c4))
);
layout.setVerticalGroup(
   layout.createSequentialGroup()
      .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
           .addComponent(c1)
           .addComponent(c2)
           .addComponent(c3))
      .addComponent(c4)
);

您可以为平行组指定对齐方式。它可以是GroupLayout.Alignment枚举中定义的以下常量之一:LEADINGTRAILINGCENTERBASELINE。这些常量用于两个维度,并取决于组件方向是从左到右还是从右到左(从上到下还是从下到上)。例如,如果水平(垂直)组件方向是从左到右(从上到下),LEADING表示左(上),而TRAILING表示右(下)。CENTER表示在两个维度上“居中”。如果不指定对齐方式,将使用LEADINGBASELINE对齐方式仅在垂直维度上有效。


注意:

组布局中的对齐仅对不同大小的组件有意义。相同大小的组件将自动对齐到每个GroupLayout.Alignment常量。


有关代码的一些注释:

  • 您不需要直接将组件添加到容器中 - 当使用其中一个 addComponent 方法时,这将隐式完成。
  • 注意addComponent方法的链式调用用于填充组。addComponent方法总是返回调用它的组。由于这一点,你不需要使用局部变量来保存组。
  • 缩进代码是个好主意,这样可以更容易看到组的层次结构。给每个组件一个新行,在层次结构中的每个新组添加一个缩进级别。一个好的源代码编辑器会帮助你匹配括号来关闭createXXXGroup方法。遵循这些简单规则,更容易添加新组件或移除现有组件。

组件大小和可调整性

在布局中可调整大小的组件数量没有限制。

GroupLayout中,每个组件的大小受到三个值的限制;最小大小、首选大小和最大大小。这些大小控制组件在布局中的调整大小。GroupLayout.addComponent(...)方法允许指定大小约束。

如果没有明确指定,布局会通过使用组件的getMinimumSize()getPreferredSize()getMaximumSize()方法来询问组件的默认大小。对于大多数组件,比如使JTextField可调整大小或JButton固定大小,你不需要指定任何内容,因为这些组件本身具有默认的调整大小行为。另一方面,你可以覆盖默认行为。例如,你可以使JTextField固定大小或JButton可调整大小。

GroupLayout定义了提供对调整大小行为精确控制的常量。它们可以作为addComponent(Component comp, int min, int pref, int max)方法的参数使用。以下是两个示例:

  1. 强制组件可调整大小(允许缩小和增长):
*group*.addComponent(component, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ...
  1. 这允许组件在零大小(最小)到任意大小(Short.MAX_VALUE作为最大大小表示“无限”)之间调整大小。如果我们不希望组件在其默认最小大小以下缩小,我们会在第二个参数中使用GroupLayout.DEFAULT_SIZE而不是0
  2. 要使组件固定大小(禁止调整大小):
group.addComponent(component, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,
          GroupLayout.PREFERRED_SIZE) ...

在这些示例中,组件的初始大小不会改变,其默认大小是组件的首选大小。如果我们想要为组件指定特定大小,我们会在第二个参数中指定,而不是使用GroupLayout.DEFAULT_SIZE

可调整大小的间隙

指定大小和可调整性也适用于间隙,包括首选间隙。例如,你可以指定两个组件之间的首选间隙,它就像一个弹簧,将组件推开(到容器的相反侧)。两个组件的首选距离仅用作间隙的最小大小。请看下面的代码片段:

layout.createSequentialGroup()
    .addComponent(c1)
    .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED,
                     GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
    .addComponent(c2);

并排组大小

放置在平行组中的可调整大小的元素被拉伸以填充由组中最大元素确定的空间,因此它们最终以相同大小对齐。GroupLayout还提供了控制是否应调整封闭平行组本身的功能。如果组调整大小被抑制,它会阻止包含的元素超过组的首选大小。这样,您可以使一组组件在两侧对齐,或者限制单个组件具有相同的大小。

让我们尝试使我们的例子中的两个组件(水平维度上的c3c4)大小相同:

layout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
  .addComponent(c3, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
  .addComponent(c4, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE);

底层机制的工作方式如下:

  1. 平行组的大小设置为最大元素的首选大小;因此在我们的例子中是c4的首选大小。
  2. 可调整大小的元素被拉伸到组的大小。在我们的例子中,只有c3被有效地拉伸,c4的大小已经对应于组的大小。

结果,c3c4将具有相同的宽度。组件不会进一步调整大小,因为平行组本身不可调整大小(上面createParallelGroup方法的第二个参数为false)。


给细心读者的问题:为什么在这个例子中我们将平行组中的两个组件都定义为可调整大小?似乎只有c3可调整大小就足够了,因为c4无论如何都不会被拉伸…

答案是:由于平台和本地化的独立性。否则,我们将不得不依赖于c4组件始终比c3大。但是当应用程序在不同平台上运行或被翻译成另一种语言时,这可能会发生变化。通过使两个组件都可调整大小,它们会相互调整,无论哪一个在特定时刻更大。

使组件大小相同

前面的情况是特殊的,因为组件在同一个平行组中。但是如果我们希望不相关的组件具有相同的大小怎么办?显然,通过分组不能始终保证相同的大小。对话框底部一行中的“确定”和“取消”按钮就是一个很好的例子。为此,GroupLayout提供了一个linkSize方法。该方法允许将任意组件的大小链接在一起,而不管它们放置在何处。链接组件的结果大小根据最大组件设置。例如:

layout.linkSize(SwingConstants.HORIZONTAL, c3, c4);

在这个例子中,尺寸在水平维度上是有选择性地链接的。

运行时更改您的 GUI

有两个重要的方法可以在运行时对 GUI 进行更改,replace()setHonorsVisibility()。使用这两种方法,您可以在运行时交换组件或更改组件的可见性,并使 GUI 相应地重新排列。

replace(Component existingComponent, Component newComponent) 用新组件替换现有组件。动态布局所需的常见操作之一是能够像这样替换组件。例如,也许复选框在显示图形或树的组件之间切换。 GroupLayout 通过 replace() 方法使这种情况变得简单。您可以在不重新创建所有组的情况下交换组件。

用户界面中的另一个常见操作是动态更改组件的可见性。也许组件只有在用户完成表单的早期部分时才显示。为了避免在这种情况下组件移动,应该占用空间,无论组件的可见性如何。 GroupLayout 提供了两种配置不可见组件处理方式的方法。 setHonorsVisibility(boolean) 方法全局设置了不可见组件的处理方式。默认值为 true,表示不可见组件被视为不存在。另一方面,值为 false 为不可见组件提供空间,将其视为可见。 setHonorsVisibility(Component,Boolean) 方法可用于在特定组件级别配置行为。为了确定如何处理可见性,GroupLayout 首先检查组件是否已指定值,如果没有,则检查全局属性的设置。


一些历史:

Java 标准版 6 中的 GroupLayout 由三个不同的工作部分组成:获取组件基线的能力,获取组件之间首选间隔的能力(LayoutStyle),以及 GroupLayout。这项工作最初是作为一个开源项目在 java.net/projects/swing-layout/ 上完成的。

NetBeans 5.0 通过 swing-layout 项目支持 GroupLayout。由于这项工作的成功,所有三个部分都已合并到了 Java 标准版 6 中的 GroupLayout 中。Java SE 6 中的 GroupLayout 与 swing-layout 中的主要区别在于包名称和方法名称。NetBeans 5.5 提供了针对 Java SE 6 中的 GroupLayout 或 swing-layout 中的 GroupLayout 的定位能力。NetBeans 定位的版本取决于项目定位的 Java 平台版本。定位 Java SE 6 的项目使用 Java SE 中的 GroupLayout,否则使用 swing-layout 中的 GroupLayout


一个 GroupLayout 示例

原文:docs.oracle.com/javase/tutorial/uiswing/layout/groupExample.html


注意: 本课程涵盖了手动编写布局代码,这可能具有挑战性。如果您对学习布局管理的所有细节不感兴趣,您可能更喜欢使用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文件。您可以编译并运行它。尝试水平调整对话框的大小,看看布局如何自动调整到新的大小。

Java 中文官方教程 2022 版(二十二)(4)https://developer.aliyun.com/article/1486769

相关文章
|
7月前
|
JavaScript NoSQL Java
接替此文【下篇-服务端+后台管理】优雅草蜻蜓z系统JAVA版暗影版为例-【蜻蜓z系列通用】-2025年全新项目整合搭建方式-这是独立吃透代码以后首次改变-独立PC版本vue版搭建教程-优雅草卓伊凡
接替此文【下篇-服务端+后台管理】优雅草蜻蜓z系统JAVA版暗影版为例-【蜻蜓z系列通用】-2025年全新项目整合搭建方式-这是独立吃透代码以后首次改变-独立PC版本vue版搭建教程-优雅草卓伊凡
360 96
接替此文【下篇-服务端+后台管理】优雅草蜻蜓z系统JAVA版暗影版为例-【蜻蜓z系列通用】-2025年全新项目整合搭建方式-这是独立吃透代码以后首次改变-独立PC版本vue版搭建教程-优雅草卓伊凡
|
3月前
|
Oracle Java 关系型数据库
java 编程基础入门级超级完整版教程详解
这份文档是针对Java编程入门学习者的超级完整版教程,涵盖了从环境搭建到实际项目应用的全方位内容。首先介绍了Java的基本概念与开发环境配置方法,随后深入讲解了基础语法、控制流程、面向对象编程的核心思想,并配以具体代码示例。接着探讨了常用类库与API的应用,如字符串操作、集合框架及文件处理等。最后通过一个学生成绩管理系统的实例,帮助读者将理论知识应用于实践。此外,还提供了进阶学习建议,引导学员逐步掌握更复杂的Java技术。适合初学者系统性学习Java编程。资源地址:[点击访问](https://pan.quark.cn/s/14fcf913bae6)。
305 2
|
8月前
|
消息中间件 Java 数据库
自研Java框架 Sunrays-Framework使用教程「博客之星」
### Sunrays-Framework:助力高效开发的Java微服务框架 **Sunrays-Framework** 是一款基于 Spring Boot 构建的高效微服务开发框架,深度融合了 Spring Cloud 生态中的核心技术组件。它旨在简化数据访问、缓存管理、消息队列、文件存储等常见开发任务,帮助开发者快速构建高质量的企业级应用。 #### 核心功能 - **MyBatis-Plus**:简化数据访问层开发,提供强大的 CRUD 操作和分页功能。 - **Redis**:实现高性能缓存和分布式锁,提升系统响应速度。 - **RabbitMQ**:可靠的消息队列支持,适用于异步
自研Java框架 Sunrays-Framework使用教程「博客之星」
|
9月前
|
移动开发 前端开发 Java
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。 JavaFX允许开发人员快速构建丰富的跨平台应用程序,允许开发人员在单个编程接口中组合图形,动画和UI控件。本文详细介绍了JavaFx的常见用法,相信读完本教程你一定有所收获!
8405 5
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
|
8月前
|
Java 数据库连接 数据处理
探究Java异常处理【保姆级教程】
Java 异常处理是确保程序稳健运行的关键机制。它通过捕获和处理运行时错误,避免程序崩溃。Java 的异常体系以 `Throwable` 为基础,分为 `Error` 和 `Exception`。前者表示严重错误,后者可细分为受检和非受检异常。常见的异常处理方式包括 `try-catch-finally`、`throws` 和 `throw` 关键字。此外,还可以自定义异常类以满足特定需求。最佳实践包括捕获具体异常、合理使用 `finally` 块和谨慎抛出异常。掌握这些技巧能显著提升程序的健壮性和可靠性。
133 4
|
8月前
|
存储 移动开发 算法
【潜意识Java】Java基础教程:从零开始的学习之旅
本文介绍了 Java 编程语言的基础知识,涵盖从简介、程序结构到面向对象编程的核心概念。首先,Java 是一种高级、跨平台的面向对象语言,支持“一次编写,到处运行”。接着,文章详细讲解了 Java 程序的基本结构,包括包声明、导入语句、类声明和 main 方法。随后,深入探讨了基础语法,如数据类型、变量、控制结构、方法和数组。此外,还介绍了面向对象编程的关键概念,例如类与对象、继承和多态。最后,针对常见的编程错误提供了调试技巧,并总结了学习 Java 的重要性和方法。适合初学者逐步掌握 Java 编程。
145 1
|
9月前
|
NoSQL Java 关系型数据库
Liunx部署java项目Tomcat、Redis、Mysql教程
本文详细介绍了如何在 Linux 服务器上安装和配置 Tomcat、MySQL 和 Redis,并部署 Java 项目。通过这些步骤,您可以搭建一个高效稳定的 Java 应用运行环境。希望本文能为您在实际操作中提供有价值的参考。
556 26
|
8月前
|
前端开发 Java 开发工具
Git使用教程-将idea本地Java等文件配置到gitte上【保姆级教程】
本内容详细介绍了使用Git进行版本控制的全过程,涵盖从本地仓库创建到远程仓库配置,以及最终推送代码至远程仓库的步骤。
415 0
|
9月前
|
安全 Java 编译器
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
|
9月前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)

热门文章

最新文章