使用布局 管理 器
布局 管理 器是一个实现LayoutManager
interface*并确定容器中组件大小和位置的对象。尽管组件可以提供大小和对齐提示,但是容器的布局 管理 器对容器中组件的大小和位置拥有final决定权。
Note:
本课涵盖了手工编写布局代码,这可能会很困难。如果您不希望了解布局 管理 的所有详细信息,则可能更喜欢将GroupLayout
布局 管理 器与构建器工具结合使用来布局 GUI。 NetBeans IDE是此类构建器工具之一。否则,如果您想手工编码并且不想使用GroupLayout
,那么推荐使用GridBagLayout
作为下一个最灵活,功能最强大的布局 管理 器。
如果您对使用 JavaFX 创建 GUI 感兴趣,请参阅在 JavaFX 中使用布局。
本节讨论与使用布局 管理 器有关的一些常见任务:
设置布局 管理 器
通常,您唯一需要担心其布局 管理 器的容器是JPanels和content panes。每个JPanel
对象都被初始化为使用FlowLayout
,除非在创建JPanel
时指定了不同的内容。默认情况下,内容窗格使用BorderLayout
。如果您不喜欢面板或内容窗格使用的默认布局 管理 器,则可以随意将其更改为其他布局 管理 器。但是,除非使用JToolBar
,否则FlowLayout
和BorderLayout
管理 器仅对原型有用。任何实际的应用程序都需要重置布局 管理 器。同样,您应该使用适当的工具来执行此操作,而不是手动编写 管理 器代码。
您可以使用JPanel
构造函数设置面板的布局 管理 器。例如:
JPanel panel = new JPanel(new BorderLayout());
创建容器后,可以使用setLayout
方法设置其布局 管理 器。例如:
Container contentPane = frame.getContentPane();
contentPane.setLayout(new FlowLayout());
尽管我们强烈建议您使用布局 管理 器,但是您可以在不使用布局 管理 器的情况下执行布局。通过将容器的 layout 属性设置为 null,可以使该容器不使用任何布局 管理 器。使用称为“绝对定位”的策略,您必须指定该容器中每个组件的大小和位置。绝对定位的一个缺点是,在调整顶层容器的大小时,它的调整效果不佳。它还不能很好地适应用户和系统之间的差异,例如不同的字体大小和locales。
将组件添加到容器
将组件添加到面板或内容窗格时,为add
方法指定的参数取决于面板或内容窗格所使用的布局 管理 器。实际上,某些布局 管理 器甚至不需要您显式添加组件。例如GroupLayout
。例如,BorderLayout
要求您使用以下代码指定组件应添加到的区域(使用BorderLayout
中定义的常量之一):
pane.add(aComponent, BorderLayout.PAGE_START);
每个布局 管理 器的操作方法部分均详细说明了需要为add
方法指定的参数。某些布局 管理 器,例如GridBagLayout
和SpringLayout
,需要复杂的设置过程。但是,许多布局 管理 器只是根据将组件添加到容器的 Sequences 来放置组件。
除JPanel
和内容窗格以外的其他摆动容器通常提供您应使用的 API 而不是add
方法。例如,您可以在JScrollPane
构造函数中指定该组件,也可以使用setViewportView
,而不是直接将组件添加到scroll pane(或实际上是添加到其视口)。由于像这样的专用 API,您不需要知道许多 Swing 容器使用哪个布局 管理 器(如果有)。 (出于好奇:滚动窗格碰巧使用了名为ScrollPaneLayout
的布局 管理 器.)
有关如何将组件添加到特定容器的信息,请参见该容器的使用方法页面。您可以使用如何使用各种组件查找组件操作指南页面。
提供尺寸和对齐方式提示
有时,您需要自定义组件向其容器的布局 管理 器提供的大小提示,以使组件布局良好。您可以通过指定组件的最小,首选和最大大小中的一个或多个来做到这一点。您可以调用组件的方法来设置大小提示— setMinimumSize
,setPreferredSize
和setMaximumSize
。或者,您可以创建重写适当的 getter 方法的组件的子类getMinimumSize
,getPreferredSize
和getMaximumSize
。这是使组件的最大大小不受限制的示例:
component.setMaximumSize(new Dimension(Integer.MAX_VALUE,
Integer.MAX_VALUE));
许多布局 管理 器并不关注组件所请求的最大大小。但是,BoxLayout
和SpringLayout
可以。此外,GroupLayout
可以显式设置最小,首选或最大大小,而无需接触组件。
除了提供大小提示外,您还可以提供对齐提示。例如,您可以指定两个组件的顶部边缘应该对齐。您可以通过调用组件的setAlignmentX
和setAlignmentY
方法或覆盖组件的getAlignmentX
和getAlignmentY
方法来设置对齐提示。尽管大多数布局 管理 器都忽略对齐提示,但BoxLayout
尊重它们。您可以在如何使用 BoxLayout中找到设置对齐方式的示例。
在组件之间放置空间
三个因素影响容器中可见组件之间的空间量:
-
布局 Manager
- 一些布局 管理 器会自动在组件之间放置空间。别人没有。有些可以让您指定组件之间的空间量。有关间距支持的信息,请参见每个布局 管理 器的使用方法页面。
-
Invisible components
- 您可以创建轻量级组件,这些组件不执行任何绘制,但是会占用 GUI 中的空间。通常,您在
BoxLayout
控制的容器中使用不可见的组件。有关使用不可见组件的示例,请参见如何使用 BoxLayout。
- 您可以创建轻量级组件,这些组件不执行任何绘制,但是会占用 GUI 中的空间。通常,您在
-
Empty borders
- 无论使用什么布局 管理 器,都可以通过向组件添加空边框来影响组件之间的表观空间。空边框的最佳候选对象是通常没有默认边框的组件,例如面板和标签。在某些外观实现中,某些其他组件可能无法很好地与边框配合使用,这是因为其绘画代码的实现方式。有关边框的信息,请参见如何使用边框。
设置容器的方向
该网站是用英语编写的,文本从左到右,然后从上到下。但是,许多其他语言具有不同的方向。 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
如何布置容器中除了其方向完全相同的组件。
默认方向(从左到右)
Right-to-left orientation
支持组件方向的标准布局 管理 器是FlowLayout
,BorderLayout
,BoxLayout
,GridBagLayout
和GridLayout
。
Note:
必须注意将组件方向应用于渲染器,编辑器和通过容器层次的正常遍历无法访问的任何其他组件。
选择布局 管理 器的提示
布局 Manager 有不同的优势和劣势。本节讨论一些常见的布局方案以及哪些布局 管理 器可能适用于每种方案。但是,再次强烈建议您使用构建器工具来创建布局 管理 器(例如NetBeans IDE Matisse GUI 构建器),而不要手动编码 管理 器。下面列出的方案仅供参考,以防您对在不同情况下使用哪种类型的 管理 器感到好奇,或者如果您绝对必须手动编写 管理 器代码。
如果我们讨论的布局 管理 器都不适合您的情况,并且您不能使用构建器工具,请随意使用您可能编写或找到的其他布局 管理 器。还请记住,灵活的布局 管理 器(例如GridBagLayout
和SpringLayout
)可以满足许多布局需求。
-
场景: 您需要在尽可能多的空间中显示组件。
- 如果它是容器中唯一的组件,请使用GridLayout或BorderLayout。否则,
BorderLayout
或GridBagLayout可能是很好的匹配。
- 如果它是容器中唯一的组件,请使用GridLayout或BorderLayout。否则,
如果使用BorderLayout
,则需要将需要大量空间的组件放在中间。使用GridBagLayout
,您将需要设置组件的约束,以便fill=GridBagConstraints.BOTH
。另一种可能性是使用BoxLayout,使需要大量空间的组件指定非常大的首选和最大大小。
-
场景: 您需要以其自然大小在紧凑的行中显示一些组件。
- 考虑使用
JPanel
对组件进行分组,并使用JPanel
的默认FlowLayout管理 器或BoxLayout管理 器。 SpringLayout对此也有好处。
- 考虑使用
-
场景: 您需要在行和列中显示一些相同大小的组件。
- GridLayout非常适合此操作。
-
场景: 您需要在行或列中显示一些组件,它们之间的间距,自定义对齐方式或自定义组件大小可能会有所不同。
- BoxLayout非常适合此操作。
-
场景: 您需要显示对齐的列,就像在类似窗体的interface中一样,其中一列标签用于描述相邻列中的文本字段。
- SpringLayout是很自然的选择。几个 Tutorial 示例使用的
SpringUtilities
类定义了makeCompactGrid
方法,使您可以轻松地对齐组件的多行和多列。
- SpringLayout是很自然的选择。几个 Tutorial 示例使用的
-
方案: 您的布局很复杂,包含许多组件。
- 考虑使用非常灵活的布局 管理 器(例如GridBagLayout或SpringLayout),或将组件分为一个或多个
JPanel
来简化布局。如果采用后一种方法,则每个JPanel
可能会使用不同的布局 管理 器。
- 考虑使用非常灵活的布局 管理 器(例如GridBagLayout或SpringLayout),或将组件分为一个或多个
第三方布局 Manager
Swing 社区已经创建了其他第三方布局 管理 器,以补充 Java 平台提供的 管理 器。以下列表决不是绝对的,但是下面列出的布局 管理 器是最受欢迎的:
- 在 JDK 1.1 中回溯引入了第二个interface
LayoutManager2
。LayoutManager2
扩展了LayoutManager
,为最大尺寸和对齐方式提供了支持。LayoutManager2
还添加了方法addLayoutComponent
和invalidateLayout
,这些方法采用Object
和invalidateLayout
。布局 管理 器还需要LayoutManager2
提供的通知,因此任何现代布局 管理 器都将需要实现它。