The Java TM Tutorial

| Start of Tutorial > Start of Trail > Start of Lesson | Search

Trail: Creating a GUI with JFC/Swing
Lesson: Laying Out Components Within a Container

## General Rules for Using Layout Managers

> As a rule, the only time you have to think about layout managers is when you create a `JPanel` or add components to a content pane. If you don't like the default layout manager that a panel or content pane uses, then you can change it to a different one. When you add components to a panel or content pane, the arguments you specify to the `add` method depend on the layout manager that the panel or content pane is using.

> The other Swing containers are more specialized and tend to hide the details of which layout manager (if any) they use. For example, a scroll pane relies on a layout manager named `ScrollPaneLayout`, but you don't need to know that to use a scroll pane. Most Swing containers provide API that you can use instead of the `add` method. For example, instead of adding a component directly to a scroll pane (or, actually, to its viewport), you either specify the component in the `JScrollPane` constructor or use `setViewportView`. For information about how to add components to a specific container, see the how-to page for the container. You can find the how-to pages using A Visual Index to the Swing Components.

### How to Choose a Layout Manager

> Layout managers have different strengths and weaknesses. This section discusses some common layout scenarios and which layout managers might work for each scenario. If none of the layout managers we discuss is right for your situation, feel free to use other layout managers that you write or find.

> Scenario: You need to display a component in as much space as it can get.
>   Consider using `BorderLayout` or `GridBagLayout`. If you use `BorderLayout`, you'll need to put the space-hungry component in the center. With `GridBagLayout`, you'll need to set the constraints for the component so that `fill=GridBagConstraints.BOTH`. Another possibility is to use `BoxLayout`, making the space-hungry component specify very large preferred and maximum sizes.

> Scenario: You need to display a few components in a compact row at their natural size.
>   Consider using a `JPanel` to group the components and using either the `JPanel`'s default `FlowLayout` manager or the `BoxLayout` manager.

> Scenario: You need to display a few components of the same size in rows and columns.
>   `GridLayout` is perfect for this.

> Scenario: You need to display a few components in a row or column, possibly with varying amounts of space between them, custom alignment, or custom component sizes.
>   `BoxLayout` is perfect for this.

> Scenario: You have a complex layout with many components.
>   Consider either using `GridBagLayout` or grouping the components into one or more `JPanel`s to simplify layout. Each `JPanel` might use a different layout manager.

### How to Create a Layout Manager and Associate It with a Container

> As mentioned in Layout Management, each container either has a layout manager or uses absolute positioning. All `JPanel` objects are initialized to use a `FlowLayout`. Content panes (the main containers in `JApplet`, `JDialog`, and `JFrame` objects) use `BorderLayout`, by default.

> If you want to use a container's default layout manager, you don't have to do a thing. The constructor for the container creates a layout manager instance and initializes the container to use it.

> To use a layout manager other than the default layout manager, you must create an instance of the desired layout manager class and tell the container to use it. The following statement creates a `BorderLayout` manager and sets it up as the layout manager for a panel.

> >     aJPanel.setLayout(new BorderLayout());

> Here is an example of making a `FlowLayout` object the layout manager for an applet's content pane:

> >     //In a JApplet subclass:
> >     Container contentPane = getContentPane();
> >     contentPane.setLayout(new FlowLayout());

> For examples of creating each layout manager, see the how-to section for the particular layout manager.

### When Is a Layout Manager Consulted?

> A container's layout manager is automatically consulted each time the container might need to change its appearance. For example, the layout manager is consulted whenever the user adds a component to a container. Most layout managers don't require programs to directly call their methods.

> Only a few component methods result in a layout manager actually performing layout: the `JComponent` `revalidate` method, the `Window` `pack` method, and the `Window` `show` and `setVisible` methods. Other methods that result in calls to a container's layout manager (but don't trigger a new layout) include the `Container` `add`, `remove`, `removeAll`, `getAlignmentX`, `getAlignmentY`, `getPreferredSize`, `getMinimumSize`, and `getMaximumSize` methods.

> If you change the size of a component, even indirectly by changing its font, for example, the component should automatically resize and repaint itself. If that doesn't happen -- because you made the change to the component's data model instead of the component, for example -- you should invoke the `revalidate` method on the component.

> 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.

> After calling `revalidate` on a component, you can invoke `repaint` on it to make the change appear onscreen. Both `revalidate` and `repaint` are thread-safe -- you needn't invoke them from the event-dispatching thread.

| Start of Tutorial > Start of Trail > Start of Lesson | Search