使用布局 管理 器

布局 管理 器是一个实现LayoutManagerinterface*并确定容器中组件大小和位置的对象。尽管组件可以提供大小和对齐提示,但是容器的布局 管理 器对容器中组件的大小和位置拥有final决定权。

Note:

本课涵盖了手工编写布局代码,这可能会很困难。如果您不希望了解布局 管理 的所有详细信息,则可能更喜欢将GroupLayout布局 管理 器与构建器工具结合使用来布局 GUI。 NetBeans IDE是此类构建器工具之一。否则,如果您想手工编码并且不想使用GroupLayout,那么推荐使用GridBagLayout作为下一个最灵活,功能最强大的布局 管理 器。

如果您对使用 JavaFX 创建 GUI 感兴趣,请参阅在 JavaFX 中使用布局

本节讨论与使用布局 管理 器有关的一些常见任务:

设置布局 管理 器

通常,您唯一需要担心其布局 管理 器的容器是JPanelscontent panes。每个JPanel对象都被初始化为使用FlowLayout,除非在创建JPanel时指定了不同的内容。默认情况下,内容窗格使用BorderLayout。如果您不喜欢面板或内容窗格使用的默认布局 管理 器,则可以随意将其更改为其他布局 管理 器。但是,除非使用JToolBar,否则FlowLayoutBorderLayout管理 器仅对原型有用。任何实际的应用程序都需要重置布局 管理 器。同样,您应该使用适当的工具来执行此操作,而不是手动编写 管理 器代码。

您可以使用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方法指定的参数。某些布局 管理 器,例如GridBagLayoutSpringLayout,需要复杂的设置过程。但是,许多布局 管理 器只是根据将组件添加到容器的 Sequences 来放置组件。

JPanel和内容窗格以外的其他摆动容器通常提供您应使用的 API 而不是add方法。例如,您可以在JScrollPane构造函数中指定该组件,也可以使用setViewportView,而不是直接将组件添加到scroll pane(或实际上是添加到其视口)。由于像这样的专用 API,您不需要知道许多 Swing 容器使用哪个布局 管理 器(如果有)。 (出于好奇:滚动窗格碰巧使用了名为ScrollPaneLayout的布局 管理 器.)

有关如何将组件添加到特定容器的信息,请参见该容器的使用方法页面。您可以使用如何使用各种组件查找组件操作指南页面。

提供尺寸和对齐方式提示

有时,您需要自定义组件向其容器的布局 管理 器提供的大小提示,以使组件布局良好。您可以通过指定组件的最小,首选和最大大小中的一个或多个来做到这一点。您可以调用组件的方法来设置大小提示— setMinimumSizesetPreferredSizesetMaximumSize。或者,您可以创建重写适当的 getter 方法的组件的子类getMinimumSizegetPreferredSizegetMaximumSize。这是使组件的最大大小不受限制的示例:

component.setMaximumSize(new Dimension(Integer.MAX_VALUE,
                                       Integer.MAX_VALUE));

许多布局 管理 器并不关注组件所请求的最大大小。但是,BoxLayoutSpringLayout可以。此外,GroupLayout可以显式设置最小,首选或最大大小,而无需接触组件。

除了提供大小提示外,您还可以提供对齐提示。例如,您可以指定两个组件的顶部边缘应该对齐。您可以通过调用组件的setAlignmentXsetAlignmentY方法或覆盖组件的getAlignmentXgetAlignmentY方法来设置对齐提示。尽管大多数布局 管理 器都忽略对齐提示,但BoxLayout尊重它们。您可以在如何使用 BoxLayout中找到设置对齐方式的示例。

在组件之间放置空间

三个因素影响容器中可见组件之间的空间量:

  • 布局 Manager

    • 一些布局 管理 器会自动在组件之间放置空间。别人没有。有些可以让您指定组件之间的空间量。有关间距支持的信息,请参见每个布局 管理 器的使用方法页面。
  • Invisible components

    • 您可以创建轻量级组件,这些组件不执行任何绘制,但是会占用 GUI 中的空间。通常,您在BoxLayout控制的容器中使用不可见的组件。有关使用不可见组件的示例,请参见如何使用 BoxLayout
  • 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如何布置容器中除了其方向完全相同的组件。

FlowLayoutDemo,具有默认的,从左到右的方向

默认方向(从左到右)

从右到左方向的 FlowLayoutDemo

Right-to-left orientation

支持组件方向的标准布局 管理 器是FlowLayoutBorderLayoutBoxLayoutGridBagLayoutGridLayout

Note:

必须注意将组件方向应用于渲染器,编辑器和通过容器层次的正常遍历无法访问的任何其他组件。

选择布局 管理 器的提示

布局 Manager 有不同的优势和劣势。本节讨论一些常见的布局方案以及哪些布局 管理 器可能适用于每种方案。但是,再次强烈建议您使用构建器工具来创建布局 管理 器(例如NetBeans IDE Matisse GUI 构建器),而不要手动编码 管理 器。下面列出的方案仅供参考,以防您对在不同情况下使用哪种类型的 管理 器感到好奇,或者如果您绝对必须手动编写 管理 器代码。

如果我们讨论的布局 管理 器都不适合您的情况,并且您不能使用构建器工具,请随意使用您可能编写或找到的其他布局 管理 器。还请记住,灵活的布局 管理 器(例如GridBagLayoutSpringLayout)可以满足许多布局需求。

  • 场景: 您需要在尽可能多的空间中显示组件。

如果使用BorderLayout,则需要将需要大量空间的组件放在中间。使用GridBagLayout,您将需要设置组件的约束,以便fill=GridBagConstraints.BOTH。另一种可能性是使用BoxLayout,使需要大量空间的组件指定非常大的首选和最大大小。

  • 场景: 您需要以其自然大小在紧凑的行中显示一些组件。

  • 场景: 您需要在行和列中显示一些相同大小的组件。

  • 场景: 您需要在行或列中显示一些组件,它们之间的间距,自定义对齐方式或自定义组件大小可能会有所不同。

  • 场景: 您需要显示对齐的列,就像在类似窗体的interface中一样,其中一列标签用于描述相邻列中的文本字段。

    • SpringLayout是很自然的选择。几个 Tutorial 示例使用的SpringUtilities类定义了makeCompactGrid方法,使您可以轻松地对齐组件的多行和多列。
  • 方案: 您的布局很复杂,包含许多组件。

    • 考虑使用非常灵活的布局 管理 器(例如GridBagLayoutSpringLayout),或将组件分为一个或多个JPanel来简化布局。如果采用后一种方法,则每个JPanel可能会使用不同的布局 管理 器。

第三方布局 Manager

Swing 社区已经创建了其他第三方布局 管理 器,以补充 Java 平台提供的 管理 器。以下列表决不是绝对的,但是下面列出的布局 管理 器是最受欢迎的:


  • 在 JDK 1.1 中回溯引入了第二个interfaceLayoutManager2LayoutManager2扩展了LayoutManager,为最大尺寸和对齐方式提供了支持。 LayoutManager2还添加了方法addLayoutComponentinvalidateLayout,这些方法采用ObjectinvalidateLayout。布局 管理 器还需要LayoutManager2提供的通知,因此任何现代布局 管理 器都将需要实现它。