How Layout Management Works
Here's an example of a layout management sequence for a frame (JFrame).
After the GUI is constructed, the pack method is invoked on the JFrame. This specifies that the frame should be at its preferred size.
To find the frame's preferred size, the frame's layout manager adds the size of the frame's edges to the preferred size of the component directly contained by the frame. This is the sum of the preferred size of the frame's content pane plus the size of the frame's menu bar, if any.
The content pane's layout manager is responsible for figuring out the content pane's preferred size, and by default, it is a BorderLayout object. However, let's assume that we replace it with a GridLayout object that's set up to create two columns. The interesting thing about grid layout is that it forces all components to be the same size and tries to make them as wide as the widest component's preferred width and as high as the highest one's preferred height. First, the grid layout manager queries the content pane for its insets—the size of the content pane's border, if any. Next, it queries each component in the content pane for its preferred size, noting the largest preferred width and largest preferred height. Then it calculates the content pane's preferred size.
When a component in the content pane is asked for its preferred size, the default implementation (used by most components) first checks whether the user specified a preferred size. If so, it reports that; if not, it queries its look and feel for the preferred size.
The end result is that the system determines the best size for the frame by determining the sizes of the components at the bottom of the containment hierarchy. These sizes then percolate up the hierarchy, eventually determining the frame's size as a whole.
If you change the size of a component even indirectly—by changing its font, for example—the component automatically resizes and repaints itself. With a custom component, you can force this to occur by invoking revalidate and then repaint. Both methods are threadsafe—you needn't invoke them from the event-dispatching thread.
When you invoke revalidate on a component, a request is passed up the containment hierarchy until it encounters a container, such as a scroll pane or top-level container, that shouldn't be affected by the component's resizing. (This is determined by calling the container's isValidateRoot method.) The container is then laid out, which has the effect of adjusting the revalidated component's size and the size of all affected components.