使用布局管理器
原文:
docs.oracle.com/javase/tutorial/uiswing/layout/using.html
布局管理器是实现LayoutManager
接口*的对象,确定容器内组件的大小和位置。尽管组件可以提供大小和对齐提示,但容器的布局管理器最终决定容器内组件的大小和位置。
**注意:**本课程涵盖了手动编写布局代码,这可能具有挑战性。如果您不想学习布局管理的所有细节,可以选择使用GroupLayout
布局管理器结合构建工具来布局您的 GUI。其中一个构建工具是 NetBeans IDE。否则,如果您想手动编写代码并且不想使用GroupLayout
,那么建议使用GridBagLayout
作为下一个最灵活和强大的布局管理器。
如果您有兴趣使用 JavaFX 创建 GUI,请参阅JavaFX 中的布局。
本节讨论了与使用布局管理器相关的一些常见任务:
- 设置布局管理器
- 向容器添加组件
- 提供大小和对齐提示
- 在组件之间放置空间
- 设置容器的方向
- 选择布局管理器的提示
- 第三方布局管理器
设置布局管理器
通常情况下,您需要关注的唯一容器的布局管理器是JPanel
和内容窗格。每个JPanel
对象在初始化时都会使用FlowLayout
,除非在创建JPanel
时另行指定。内容窗格默认使用BorderLayout
。如果您不喜欢面板或内容窗格使用的默认布局管理器,可以自由更改为其他布局管理器。但是,除非您使用JToolBar
,否则FlowLayout
和BorderLayout
管理器仅适用于原型设计。任何真实的应用程序都需要重新设置布局管理器。再次强调,您应该使用适当的工具来执行此操作,而不是手动编写管理器。
您可以使用JPanel
构造函数设置面板的布局管理器。例如:
JPanel panel = new JPanel(new BorderLayout());
创建容器后,可以使用setLayout
方法设置其布局管理器。例如:
Container contentPane = frame.getContentPane(); contentPane.setLayout(new FlowLayout());
尽管我们强烈建议您使用布局管理器,但您也可以在没有布局管理器的情况下进行布局。通过将容器的布局属性设置为 null,您使容器不使用布局管理器。使用这种策略,称为绝对定位,您必须指定容器内每个组件的大小和位置。绝对定位的一个缺点是,当顶层容器调整大小时,它不会调整得很好。它也无法很好地适应用户和系统之间的差异,例如不同的字体大小和区域设置。
向容器添加组件
当您向面板或内容窗格添加组件时,您为add
方法指定的参数取决于面板或内容窗格使用的布局管理器。实际上,一些布局管理器甚至不需要您显式添加组件;例如,GroupLayout
。例如,BorderLayout
要求您使用类似以下代码指定应将组件添加到的区域(使用BorderLayout
中定义的常量之一):
pane.add(aComponent, BorderLayout.PAGE_START);
每个布局管理器的操作指南中都详细说明了您需要为add
方法指定哪些参数(如果有的话)。一些布局管理器,如GridBagLayout
和SpringLayout
,需要复杂的设置过程。然而,许多布局管理器只是根据它们添加到容器中的顺序来放置组件。
除了JPanel
和内容窗格之外的 Swing 容器通常提供了 API,您应该使用这些 API 而不是add
方法。例如,不要直接向滚动窗格(或者实际上是其视口)添加组件,而是要么在JScrollPane
构造函数中指定组件,要么使用setViewportView
方法。由于有了这样的专门 API,您不需要知道许多 Swing 容器使用的布局管理器(如果有的话)。(对于好奇的人:滚动窗格实际上使用了一个名为ScrollPaneLayout
的布局管理器。)
有关如何向特定容器添加组件的信息,请参阅该容器的操作指南页面。您可以使用各种组件的使用方法找到组件的操作指南页面。
提供大小和对齐提示
有时,您需要自定义组件向其容器的布局管理器提供的大小提示,以便组件能够被很好地布局。您可以通过指定组件的最小、首选和最大大小来实现这一点。您可以调用组件的设置大小提示方法——setMinimumSize
、setPreferredSize
和setMaximumSize
。或者您可以创建一个子类,重写适当的获取器方法——getMinimumSize
、getPreferredSize
和getMaximumSize
。以下是使组件的最大大小无限制的示例:
component.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));
许多布局管理器不关注组件的请求的最大尺寸。然而,BoxLayout
和SpringLayout
会关注。此外,GroupLayout
提供了明确设置最小、首选或最大尺寸的能力,而无需触及组件。
除了提供大小提示外,您还可以提供对齐提示。例如,您可以指定两个组件的顶部边缘应该对齐。您可以通过调用组件的setAlignmentX
和setAlignmentY
方法,或者通过覆盖组件的getAlignmentX
和getAlignmentY
方法来设置对齐提示。尽管大多数布局管理器会忽略对齐提示,但BoxLayout
会遵守它们。您可以在如何使用 BoxLayout 中找到设置对齐的示例。
在组件之间放置空间
影响容器中可见组件之间空间量的三个因素:
布局管理器
一些布局管理器会自动在组件之间放置空间;其他则不会。有些允许您指定组件之间的空间量。有关间距支持的信息,请参见每个布局管理器的操作页面。
不可见组件
你可以创建轻量级组件,不进行绘制,但可以在 GUI 中占据空间。通常情况下,您可以在由BoxLayout
控制的容器中使用不可见组件。参见如何使用 BoxLayout 以查看使用不可见组件的示例。
空边框
无论使用何种布局管理器,您都可以通过向组件添加空边框来影响组件之间的视觉空间量。最适合空边框的候选组件是通常没有默认边框的组件,例如面板和标签。一些其他组件可能在某些外观和感觉实现中无法很好地与边框配合工作,因为它们的绘制代码的实现方式不同。有关边框的信息,请参见如何使用边框。
设置容器的方向
本网站使用英语编写,文本从左到右,然后从上到下。然而,许多其他语言具有不同的方向。componentOrientation
属性提供了一种指示特定组件应该使用与默认的从左到右,从上到下方向不同的方式的方法。在诸如单选按钮之类的组件中,方向可能被用作提示,指示外观和感觉应该切换按钮中图标和文本的位置。在容器中,方向被用作布局管理器的提示。
要设置容器的方向,您可以使用Component
定义的方法setComponentOrientation
或者,为了同时设置容器的子组件的方向,使用applyComponentOrientation
。任一方法的参数可以是常量,如ComponentOrientation.RIGHT_TO_LEFT
,或者可以是调用ComponentOrientation
方法getOrientation(Locale)
。例如,以下代码使所有JComponent
都使用阿拉伯语区域设置进行初始化,然后相应地设置内容窗格和其中所有组件的方向:
JComponent.setDefaultLocale(new Locale("ar")); JFrame frame = new JFrame(); ... Container contentPane = frame.getContentPane(); contentPane.applyComponentOrientation( ComponentOrientation.getOrientation( contentPane.getLocale()));
这里有两张图片展示了FlowLayout
在完全相同的容器中以不同方向布局组件的方式。
默认方向(从左到右)
从右到左方向
支持组件方向的标准布局管理器包括FlowLayout
、BorderLayout
、BoxLayout
、GridBagLayout
和GridLayout
。
注意: 必须注意将组件方向应用于渲染器、编辑器和通过容器层次结构的正常遍历无法访问的任何其他组件。
选择布局管理器的提示
布局管理器有不同的优势和劣势。本节讨论了一些常见的布局场景以及哪些布局管理器可能适用于每种场景。然而,再次强烈建议您使用构建工具来创建您的布局管理器,比如NetBeans IDE Matisse GUI builder,而不是手动编码管理器。下面列出的场景仅供信息参考,以防您想知道不同情况下使用哪种类型的管理器,或者您绝对必须手动编码您的管理器。
如果我们讨论的布局管理器都不适合您的情况,并且您不能使用构建工具,请随意使用您可能编写或找到的其他布局管理器。还要记住,灵活的布局管理器如GridBagLayout
和SpringLayout
可以满足许多布局需求。
场景: 您需要在尽可能多的空间中显示一个组件。
如果它是容器中唯一的组件,请使用GridLayout
或BorderLayout
。否则,BorderLayout
或GridBagLayout
可能是一个很好的选择。
如果使用BorderLayout
,您需要将占用大量空间的组件放在中心位置。使用GridBagLayout
,您需要设置组件的约束条件,使fill=GridBagConstraints.BOTH
。另一种可能性是使用BoxLayout
,使占用大量空间的组件指定非常大的首选大小和最大大小。
场景: 您需要以它们的自然大小在一个紧凑的行中显示几个组件。
考虑使用JPanel
来组合组件,并使用JPanel
的默认FlowLayout
管理器或BoxLayout
管理器。SpringLayout
也适用于这种情况。
场景: 您需要以行和列的方式显示几个相同大小的组件。
GridLayout
非常适合这种情况。
场景: 您需要以行或列的方式显示几个组件,可能在它们之间有不同数量的空间,自定义对齐方式或自定义组件大小。
BoxLayout
非常适合这种情况。
场景: 您需要显示对齐的列,就像在一个类似表单的界面中,一个标签列用于描述相邻列中的文本字段。
SpringLayout
是这种情况的自然选择。几个教程示例中使用的SpringUtilities
类定义了一个makeCompactGrid
方法,让您可以轻松地对齐多行和多列的组件。
场景: 您有一个包含许多组件的复杂布局。
考虑使用非常灵活的布局管理器,如GridBagLayout
或SpringLayout
,或将组件分组到一个或多个JPanel
中以简化布局。如果采用后一种方法,每个JPanel
可能会使用不同的布局管理器。
第三方布局管理器
Swing 社区创建了其他第三方布局管理器,以补充 Java 平台提供的布局管理器。以下列表并非绝对,但下面列出的布局管理器是最受欢迎的:
*早在 JDK 1.1 时引入了第二个接口LayoutManager2
。LayoutManager2
扩展了LayoutManager
,提供了最大尺寸和对齐支持。LayoutManager2
还添加了addLayoutComponent
方法,接受一个Object
,以及invalidateLayout
方法。布局管理器还需要LayoutManager2
提供的通知,因此任何现代布局管理器都需要实现它。
布局管理的工作原理
原文:
docs.oracle.com/javase/tutorial/uiswing/layout/howLayoutWorks.html
注意: 本课程涵盖手动编写布局代码,这可能具有挑战性。如果您不想学习布局管理的所有细节,您可能更喜欢使用GroupLayout
布局管理器结合构建工具来布局您的 GUI。其中一个构建工具是 NetBeans IDE。否则,如果您想手动编码而不想使用GroupLayout
,那么建议使用GridBagLayout
作为下一个最灵活和强大的布局管理器。
如果您有兴趣使用 JavaFX 创建 GUI,请参阅JavaFX 中的布局。
这里是一个使用LayoutManager2
对容器进行布局管理的示例。
- 布局管理器基本上执行两项任务:
- 计算容器的最小/首选/最大大小。
- 布局容器的子元素。
- 布局管理器根据提供的约束、容器的属性(如插入)以及子元素的最小/首选/最大大小来执行此操作。如果子元素本身是一个容器,则使用其自身的布局管理器来获取其最小/首选/最大大小并进行布局。
- 容器可以是有效的(即,
isValid()
返回 true),也可以是无效的。要使容器有效,所有容器的子元素必须已经布局,并且也必须全部有效。Container.validate
方法可用于验证无效容器。此方法触发容器及其子容器沿组件层次结构向下的布局,并将此容器标记为有效。 - 组件创建后,默认处于无效状态。
Window.pack
方法验证窗口,并首次布局窗口的组件层次结构。
最终结果是为了确定容器的最佳大小,系统确定了包含层次结构底部容器的大小。然后这些大小向上层次结构传播,最终确定容器的总大小。
如果组件的大小发生变化,例如更改字体后,必须调用该组件的revalidate
和repaint
方法来重新调整大小并重绘。revalidate
和repaint
都是线程安全的 — 您无需从事件分派线程调用它们。
当你在组件上调用revalidate
时,请求会沿着包含层次结构传递,直到遇到一个容器,比如滚动窗格或顶层容器,这些容器不应受到组件调整大小的影响。(这是通过调用容器的isValidateRoot
方法来确定的。)然后对容器进行布局,这会调整重新验证的组件的大小以及所有受影响组件的大小。
如何使用各种布局管理器
原文:
docs.oracle.com/javase/tutorial/uiswing/layout/layoutlist.html
以下每个页面描述了如何使用特定类型的布局管理器。另一种访问这些页面的方法是通过布局管理器可视化指南。
注意: 这节课涵盖了手动编写布局代码,这可能是具有挑战性的。如果你对学习布局管理的所有细节不感兴趣,你可能更喜欢使用GroupLayout
布局管理器结合构建工具来布局你的 GUI。其中一个构建工具是 NetBeans IDE。否则,如果你想手动编写代码而不想使用GroupLayout
,那么推荐使用GridBagLayout
作为下一个最灵活和强大的布局管理器。
如果你有兴趣使用 JavaFX 创建你的 GUI,请参阅JavaFX 中的布局教程。
- 如何使用 BorderLayout
- 如何使用 BoxLayout
- 如何使用 CardLayout
- 如何使用 FlowLayout
- 如何使用 GridBagLayout
- 如何使用 GridLayout
- 如何使用 GroupLayout
- 如何使用 SpringLayout
如何使用 BorderLayout
原文:
docs.oracle.com/javase/tutorial/uiswing/layout/border.html
注意: 本课程涵盖了手动编写布局代码,这可能具有挑战性。如果您不想学习布局管理的所有细节,您可能更喜欢使用GroupLayout
布局管理器结合构建工具来布局您的 GUI。其中一个构建工具是 NetBeans IDE。否则,如果您想手动编码而不想使用GroupLayout
,那么GridBagLayout
被推荐为下一个最灵活和强大的布局管理器。
如果您有兴趣使用 JavaFX 创建 GUI,请参阅JavaFX 中的布局。
以下图表示了一个使用BorderLayout
类的应用程序的快照。
点击启动按钮以使用Java™ Web Start运行 BorderLayoutDemo(下载 JDK 7 或更高版本)。或者,要自己编译和运行示例,请参考示例索引。
这个演示的完整代码在BorderLayoutDemo.java
文件中。
如前面的图片所示,BorderLayout
对象有五个区域。这些区域由BorderLayout
常量指定:
PAGE_START
PAGE_END
LINE_START
LINE_END
CENTER
版本说明:
在 JDK 1.4 版本发布之前,各个区域的首选名称不同,从罗盘点(例如,BorderLayout.NORTH
表示顶部区域)到我们示例中使用的常量的较长版本。我们示例中使用的常量是首选的,因为它们是标准的,并且使程序能够适应具有不同方向的语言。
如果窗口被放大,中心区域会尽可能占用所有可用空间。其他区域只会扩展到填满所有可用空间为止。通常,一个容器只使用BorderLayout
对象的一个或两个区域 — 只有中心,或中心和底部。
以下代码向框架的内容窗格添加组件。因为内容窗格默认使用 BorderLayout
类,所以代码不需要设置布局管理器。完整程序在 BorderLayoutDemo.java
文件中。
...*//Container pane = aFrame.getContentPane()*... JButton button = new JButton("Button 1 (PAGE_START)"); pane.add(button, BorderLayout.PAGE_START); //Make the center component big, since that's the //typical usage of BorderLayout. button = new JButton("Button 2 (CENTER)"); button.setPreferredSize(new Dimension(200, 100)); pane.add(button, BorderLayout.CENTER); button = new JButton("Button 3 (LINE_START)"); pane.add(button, BorderLayout.LINE_START); button = new JButton("Long-Named Button 4 (PAGE_END)"); pane.add(button, BorderLayout.PAGE_END); button = new JButton("5 (LINE_END)"); pane.add(button, BorderLayout.LINE_END);
指定组件的位置(例如,BorderLayout.LINE_END
)作为 add
方法的参数之一。如果此组件在由 BorderLayout
对象控制的容器中缺失,请确保已指定组件的位置,并且没有其他组件放置在相同位置。
所有使用 BorderLayout
类的教程示例将组件指定为 add
方法的第一个参数。例如:
add(component, BorderLayout.CENTER) //preferred
然而,在其他程序中的代码将组件指定为第二个参数。例如,以下是编写前述代码的替代方式:
add(BorderLayout.CENTER, component) //valid but old fashioned *or* add("Center", component) //valid but error prone
BorderLayout API
以下表列出了指定间隙(以像素为单位)的构造函数和方法。
指定间隙
构造函数或方法 | 目的 |
BorderLayout(int *horizontalGap*, int *verticalGap*) |
定义具有指定组件间隙的边界布局。 |
setHgap(int) |
设置组件之间的水平间距。 |
setVgap(int) |
设置组件之间的垂直间距。 |
使用 BorderLayout 的示例
以下表列出了使用 BorderLayout
类的代码示例,并提供到相关部分的链接。
示例 | 描述位置 | 注释 |
BorderLayoutDemo |
本页 | 将一个组件放在五个可能的位置中的每一个。 |
TabbedPaneDemo |
如何使用选项卡窗格 | 其中一个示例,将一个组件放在内容窗格的中心,使组件尽可能大。 |
CheckBoxDemo |
如何使用复选框 | 创建一个使用 BorderLayout 类的 JPanel 对象。将组件放入左侧(实际上是 LINE_START )和中心位置。 |
如何使用 BoxLayout
注意: 本课程涵盖了手动编写布局代码,这可能具有挑战性。如果你不想学习布局管理的所有细节,可以选择使用GroupLayout
布局管理器结合构建工具来布局你的 GUI。其中一个构建工具是 NetBeans IDE。否则,如果你想手动编码而不想使用GroupLayout
,那么推荐使用GridBagLayout
作为下一个最灵活和强大的布局管理器。
如果你有兴趣使用 JavaFX 来创建你的 GUI,请查看JavaFX 布局教程。
Swing 包含一个名为BoxLayout
的通用布局管理器。BoxLayout
可以将其组件堆叠在一起或者按行排列 - 由你选择。你可以将其视为FlowLayout
的一个版本,但功能更强大。这里是一个应用程序的图片,演示了如何使用BoxLayout
来显示一个居中的组件列:
点击“启动”按钮以使用Java™ Web Start运行 BoxLayoutDemo(下载 JDK 7 或更高版本)。或者,要自行编译和运行示例,请参考示例索引。
你可以在BoxLayoutDemo.java
中查看代码。
以下图片展示了一个使用两个BoxLayout
实例的 GUI。在 GUI 的顶部,一个从上到下的盒式布局将一个标签放在滚动窗格上方。在 GUI 的底部,一个从左到右的盒式布局将两个按钮并排放置。BorderLayout
结合了 GUI 的两部分,并确保任何多余的空间都给了滚动窗格。
你可以在示例索引中找到运行 ListDialog 以及其源文件的链接,用于使用 Swing 组件。
以下代码取自ListDialog.java
,布局了 GUI。这段代码位于对话框的构造函数中,该对话框是作为JDialog
子类实现的。粗体代码设置了 Box 布局并向其中添加了组件。
JScrollPane listScroller = new JScrollPane(list); listScroller.setPreferredSize(new Dimension(250, 80)); listScroller.setAlignmentX(LEFT_ALIGNMENT); ... //Lay out the label and scroll pane from top to bottom. JPanel listPane = new JPanel(); listPane.setLayout(new BoxLayout(listPane, BoxLayout.PAGE_AXIS)); JLabel label = new JLabel(labelText); ... listPane.add(label); listPane.add(Box.createRigidArea(new Dimension(0,5))); listPane.add(listScroller); listPane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); //Lay out the buttons from left to right. JPanel buttonPane = new JPanel(); buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS)); buttonPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10)); buttonPane.add(Box.createHorizontalGlue()); buttonPane.add(cancelButton); buttonPane.add(Box.createRigidArea(new Dimension(10, 0))); buttonPane.add(setButton); //Put everything together, using the content pane's BorderLayout. Container contentPane = getContentPane(); contentPane.add(listPane, BorderLayout.CENTER); contentPane.add(buttonPane, BorderLayout.PAGE_END);
第一行粗体代码创建了一个从上到下的 Box 布局,并将其设置为listPane
的布局管理器。BoxLayout
构造函数的两个参数是它管理的容器和组件将被布局的轴。PAGE_AXIS
常量指定组件应该按照页面上行流动的方向进行布局,由目标容器的ComponentOrientation
属性确定。LINE_AXIS
常量指定组件应该按照文本行的方向进行布局,由目标容器的ComponentOrientation
属性确定。这些常量允许通过以正确的从左到右、从右到左或从上到下的方向为所用语言的容器中的组件进行布局来进行国际化。
接下来的三行粗体代码将标签和滚动窗格添加到容器中,并使用一个刚性区域分隔它们 — 一个用于在组件之间添加空间的不可见组件。在这种情况下,刚性区域没有宽度,并在标签和滚动窗格之间放置了确切的5 像素
。稍后在使用不可见组件作为填充中讨论了刚性区域。
下一块粗体代码创建了一个从左到右的 Box 布局,并为buttonPane
容器设置了布局。然后代码向容器添加了两个按钮,使用一个刚性区域在按钮之间放置了10 像素
。为了将按钮放置在其容器的右侧,添加到容器的第一个组件是glue。这个 glue 是一个不可见组件,根据需要增长以吸收其容器中的任何额外空间。在使用不可见组件作为填充中讨论了 glue。
作为使用不可见组件的替代方案,有时可以使用空边框来在组件周围创建空间,尤其是面板。例如,前面的代码片段使用空边框在对话框及其内容的所有边缘之间以及内容的两个部分之间放置了10 像素
。边框完全独立于布局管理器。它们只是 Swing 组件如何绘制其边缘并在组件内容和边缘之间提供填充的方式。更多信息请参见如何使用边框。
以下部分更详细地讨论了BoxLayout
:
- Box 布局特性
- 使用不可见组件作为填充
- 修复对齐问题
- 指定组件大小
- Box 布局 API
- 使用 Box 布局的示例
不要让BoxLayout
讨论的长度吓到你!你可能已经可以使用BoxLayout
了。如果遇到问题或想利用BoxLayout
的功能,继续阅读。
Box Layout 特点
如前所述,BoxLayout
将组件排列在彼此上方或一行中。在安排组件时,BoxLayout 会考虑组件的对齐方式以及最小、首选和最大尺寸。在本节中,我们将讨论从上到下的布局。相同的概念适用于从左到右或从右到左的布局。只需用 Y 替换 X,宽度替换高度等。
**版本说明:**在 JDK 版本 1.4 之前,没有为以本地化方式指定框布局轴的常量。相反,在创建BoxLayout
时,您指定X_AXIS
(从左到右)或Y_AXIS
(从上到下)。我们的示例现在使用常量LINE_AXIS
和PAGE_AXIS
,因为它们可以使程序适应具有不同方向的语言。在默认的从左到右方向中,LINE_AXIS
指定从左到右的布局,PAGE_AXIS
指定从上到下的布局。
当BoxLayout
从上到下布局组件时,它会尝试将每个组件的大小设置为组件的首选高度。如果布局的垂直空间与首选高度之和不匹配,那么BoxLayout
会尝试调整组件的大小以填充空间。组件会增长或缩小以填充空间,BoxLayout
会遵守每个组件的最小和最大尺寸。任何额外的空间都会出现在容器的底部。
对于从上到下的框布局,容器的首选宽度是子组件的最大首选宽度。如果容器被强制变宽,BoxLayout
会尝试将每个组件的宽度调整为容器的宽度(减去插入)。如果组件的最大尺寸小于容器的宽度,则 X 对齐会起作用。
X 对齐不仅影响组件相对位置,还影响组件(作为一组)在容器中的位置。以下图示说明了具有受限制最大宽度的组件的对齐方式。
在第一个图中,所有三个组件的 X 对齐为 0.0(Component.LEFT_ALIGNMENT
)。这意味着组件的左侧应对齐。此外,这意味着所有三个组件在容器中尽可能靠左位置。
在第二个图中,所有三个组件的 X 对齐为 0.5(Component.CENTER_ALIGNMENT
)。这意味着组件的中心应该对齐,并且组件应该位于其容器的水平中心。
在第三个图中,组件的 X 对齐为 1.0(Component.RIGHT_ALIGNMENT
)。您可以猜测这对于组件的对齐和位置相对于其容器意味着什么。
您可能想知道当组件具有受限制的最大尺寸和不同的 X 对齐方式时会发生什么。下一个图显示了一个示例:
如您所见,具有 X 对齐为 0.0(Component.LEFT_ALIGNMENT
)的组件的左侧与具有 0.5 X 对齐(Component.CENTER_ALIGNMENT
)的组件的中心对齐,后者与具有 X 对齐为 1.0(Component.RIGHT_ALIGNMENT
)的组件的右侧对齐。这种混合对齐方式在修复对齐问题中进一步讨论。
如果没有任何组件具有最大宽度会怎么样?在这种情况下,如果所有组件具有相同的 X 对齐方式,则所有组件将与其容器一样宽。如果 X 对齐方式不同,则具有 X 对齐为 0.0(左)或 1.0(右)的任何组件将较小。所有具有中间 X 对齐方式(例如中心)的组件将与其容器一样宽。以下是两个示例:
要更好地了解BoxLayout
,您可以运行自己的 BoxLayoutDemo2 实验。
试试这个:
- 单击“启动”按钮以使用Java™ Web Start运行 BoxLayoutDemo2(下载 JDK 7 或更高版本)。或者,要自行编译和运行示例,请参考示例索引。
您可以在BoxLayoutDemo2.java
中查看代码。
您将看到一个类似上面的窗口,其中包含三个矩形。每个矩形都是BLDComponent
的一个实例,它是JComponent
的子类。 - 单击其中一个矩形内部。
这是如何更改矩形的 X 对齐方式。 - 单击窗口底部的复选框。
这将关闭所有矩形的限制尺寸。 - 使窗口变得更高。
这使得矩形的容器比矩形的首选大小之和更大。容器是一个带有红色轮廓的JPanel
,这样您就可以知道容器的边缘在哪里。
使用不可见组件作为填充器
由框布局控制的每个组件都与其相邻组件紧密相连。如果您希望在组件之间有空间,可以向一个或两个组件添加空的边框,或插入不可见组件来提供空间。您可以借助Box
类创建不可见组件。
Box
类定义了一个嵌套类Box.Filler
,这是一个透明的组件,不绘制任何内容,用于在其他组件之间提供空间。然而,Filler
实际上并不是不可见的,因为没有调用setVisible(false)
。Box
类提供了便利方法来帮助您创建常见类型的填充器。以下表格详细介绍了如何使用Box
和Box.Filler
创建不可见组件。
类型 | 大小约束 | 创建方式 |
刚性区域 | Box.createRigidArea(size) |
|
粘合剂,水平 | Box.createHorizontalGlue() |
|
粘合剂,垂直 | Box.createVerticalGlue() |
|
自定义Box.Filler |
(如指定) | new Box.Filler(minSize, prefSize, maxSize) |
这是您通常如何使用每种类型的填充器:
刚性区域
当您希望在两个组件之间有固定大小的空间时,请使用此选项。例如,在从左到右的框中在两个组件之间放置 5 像素,您可以使用以下代码:
container.add(firstComponent); container.add(Box.createRigidArea(new Dimension(5,0))); container.add(secondComponent);
注意: Box
类提供了另一种用于在组件之间放置固定空间的填充器:垂直或水平支柱。不幸的是,支柱具有无限的最大高度或宽度(分别用于水平和垂直支柱)。这意味着,如果您在垂直框内使用水平框,水平框有时可能会变得太高。因此,我们建议您使用刚性区域而不是支柱。
粘合剂
使用这个方法可以指定布局中多余的空间应该去哪里。将其视为一种弹性胶水 — 有弹性和可伸缩性,但除非你拉开它粘附的组件,否则不占用空间。例如,在一个从左到右的盒式布局中,在两个组件之间放置水平粘合剂,可以使任何额外的空间都在这些组件之间,而不是在所有组件的右侧。以下是一个示例,使得从左到右的盒式布局中的空间在两个组件之间,而不是在组件的右侧:
container.add(firstComponent); container.add(Box.createHorizontalGlue()); container.add(secondComponent);
自定义Box.Filler
使用这个方法可以指定组件的最小、首选和最大尺寸。例如,要在一个从左到右的布局中创建一些填充物,使得两个组件之间至少有 5 像素的间距,并确保容器的最小高度为 100 像素,你可以使用以下代码:
container.add(firstComponent); Dimension minSize = new Dimension(5, 100); Dimension prefSize = new Dimension(5, 100); Dimension maxSize = new Dimension(Short.MAX_VALUE, 100); container.add(new Box.Filler(minSize, prefSize, maxSize)); container.add(secondComponent);
Java 中文官方教程 2022 版(二十二)(2)https://developer.aliyun.com/article/1486763