# 布局管理的工作原理

> 原文： [https://docs.oracle.com/javase/tutorial/uiswing/layout/howLayoutWorks.html](https://docs.oracle.com/javase/tutorial/uiswing/layout/howLayoutWorks.html)

* * *

**Note:** This lesson covers writing layout code by hand, which can be challenging. If you are not interested in learning all the details of layout management, you might prefer to use the `GroupLayout` layout manager combined with a builder tool to lay out your GUI. One such builder tool is the [NetBeans IDE](../learn/index.html). Otherwise, if you want to code by hand and do not want to use `GroupLayout`, then `GridBagLayout` is recommended as the next most flexible and powerful layout manager.

* * *

如果您对使用 JavaFX 创建 GUI 感兴趣，请参阅[在 JavaFX](https://docs.oracle.com/javase/8/javafx/layout-tutorial/index.html) 中使用布局。

以下是使用 [`LayoutManager2`](https://docs.oracle.com/javase/8/docs/api/java/awt/LayoutManager2.html) 的容器的布局管理序列示例。

1.  Layout managers basically do two things:
    *   计算容器的最小/首选/最大大小。
    *   布置容器的孩子。

    布局管理器根据提供的约束，容器的属性（例如 insets）以及子项的最小/首选/最大大小来执行此操作。如果一个孩子本身就是一个容器，那么它自己的布局管理器用于获得它的最小/首选/最大尺寸并将其布置出来。

2.  容器可以是 _ 有效 _（即，`isValid()`返回 true）或 _ 无效 _。要使容器有效，所有容器的子容器必须已经布局并且必须全部有效。 [`Container.validate`](https://docs.oracle.com/javase/8/docs/api/java/awt/Container.html#validate--) 方法可用于验证无效容器。此方法触发容器和组件层次结构中所有子容器的布局，并将此容器标记为有效。

3.  创建组件后，默认情况下它处于无效状态。 [`Window.pack`](https://docs.oracle.com/javase/8/docs/api/java/awt/Window.html) 方法验证窗口并首次布置窗口的组件层次结构。

最终结果是，为了确定容器的最佳大小，系统确定容器层次结构底部的容器大小。然后，这些大小渗透包容层次结构，最终确定容器的总大小。

如果组件的大小发生更改（例如，在更改字体后），则必须通过调用该组件上的`revalidate`和`repaint`方法来调整组件的大小并重新绘制。 `revalidate`和`repaint`都是[线程安全](../concurrency/index.html) - 您无需从事件派发线程调用它们。

当您在组件上调用`revalidate`时，请求将在包含层次结构中向上传递，直到遇到容器（例如滚动窗格或顶级容器），该容器不应受组件调整大小的影响。 （这是通过调用容器的`isValidateRoot`方法确定的。）然后布置容器，这样可以调整重新验证的组件的大小和所有受影响组件的大小。