Module java.desktop
Package javax.swing

Class GroupLayout

java.lang.Object
javax.swing.GroupLayout
All Implemented Interfaces:
LayoutManager, LayoutManager2

public class GroupLayout extends Object implements LayoutManager2
GroupLayout is a LayoutManager that hierarchically groups components in order to position them in a Container. GroupLayout is intended for use by builders, but may be hand-coded as well. Grouping is done by instances of the Group class. GroupLayout supports two types of groups. A sequential group positions its child elements sequentially, one after another. A parallel group aligns its child elements in one of four ways.

Each group may contain any number of elements, where an element is a Group, Component, or gap. A gap can be thought of as an invisible component with a minimum, preferred and maximum size. In addition GroupLayout supports a preferred gap, whose value comes from LayoutStyle.

Elements are similar to a spring. Each element has a range as specified by a minimum, preferred and maximum. Gaps have either a developer-specified range, or a range determined by LayoutStyle. The range for Components is determined from the Component's getMinimumSize, getPreferredSize and getMaximumSize methods. In addition, when adding Components you may specify a particular range to use instead of that from the component. The range for a Group is determined by the type of group. A ParallelGroup's range is the maximum of the ranges of its elements. A SequentialGroup's range is the sum of the ranges of its elements.

GroupLayout treats each axis independently. That is, there is a group representing the horizontal axis, and a group representing the vertical axis. The horizontal group is responsible for determining the minimum, preferred and maximum size along the horizontal axis as well as setting the x and width of the components contained in it. The vertical group is responsible for determining the minimum, preferred and maximum size along the vertical axis as well as setting the y and height of the components contained in it. Each Component must exist in both a horizontal and vertical group, otherwise an IllegalStateException is thrown during layout, or when the minimum, preferred or maximum size is requested.

The following diagram shows a sequential group along the horizontal axis. The sequential group contains three components. A parallel group was used along the vertical axis.

Sequential group along the horizontal axis in three components

To reinforce that each axis is treated independently the diagram shows the range of each group and element along each axis. The range of each component has been projected onto the axes, and the groups are rendered in blue (horizontal) and red (vertical). For readability there is a gap between each of the elements in the sequential group.

The sequential group along the horizontal axis is rendered as a solid blue line. Notice the sequential group is the sum of the children elements it contains.

Along the vertical axis the parallel group is the maximum of the height of each of the components. As all three components have the same height, the parallel group has the same height.

The following diagram shows the same three components, but with the parallel group along the horizontal axis and the sequential group along the vertical axis.

Sequential group along the vertical axis in three components

As c1 is the largest of the three components, the parallel group is sized to c1. As c2 and c3 are smaller than c1 they are aligned based on the alignment specified for the component (if specified) or the default alignment of the parallel group. In the diagram c2 and c3 were created with an alignment of LEADING. If the component orientation were right-to-left then c2 and c3 would be positioned on the opposite side.

The following diagram shows a sequential group along both the horizontal and vertical axis.

Sequential group along both the horizontal and vertical axis in three components

GroupLayout provides the ability to insert gaps between Components. The size of the gap is determined by an instance of LayoutStyle. This may be turned on using the setAutoCreateGaps method. Similarly, you may use the setAutoCreateContainerGaps method to insert gaps between components that touch the edge of the parent container and the container.

The following builds a panel consisting of two labels in one column, followed by two textfields in the next column:

   JComponent panel = ...;
   GroupLayout layout = new GroupLayout(panel);
   panel.setLayout(layout);

   // Turn on automatically adding gaps between components
   layout.setAutoCreateGaps(true);

   // Turn on automatically creating gaps between components that touch
   // the edge of the container and the container.
   layout.setAutoCreateContainerGaps(true);

   // Create a sequential group for the horizontal axis.

   GroupLayout.SequentialGroup hGroup = layout.createSequentialGroup();

   // The sequential group in turn contains two parallel groups.
   // One parallel group contains the labels, the other the text fields.
   // Putting the labels in a parallel group along the horizontal axis
   // positions them at the same x location.
   //
   // Variable indentation is used to reinforce the level of grouping.
   hGroup.addGroup(layout.createParallelGroup().
            addComponent(label1).addComponent(label2));
   hGroup.addGroup(layout.createParallelGroup().
            addComponent(tf1).addComponent(tf2));
   layout.setHorizontalGroup(hGroup);

   // Create a sequential group for the vertical axis.
   GroupLayout.SequentialGroup vGroup = layout.createSequentialGroup();

   // The sequential group contains two parallel groups that align
   // the contents along the baseline. The first parallel group contains
   // the first label and text field, and the second parallel group contains
   // the second label and text field. By using a sequential group
   // the labels and text fields are positioned vertically after one another.
   vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).
            addComponent(label1).addComponent(tf1));
   vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).
            addComponent(label2).addComponent(tf2));
   layout.setVerticalGroup(vGroup);
 

When run the following is produced.

Produced horizontal/vertical form

This layout consists of the following.

  • The horizontal axis consists of a sequential group containing two parallel groups. The first parallel group contains the labels, and the second parallel group contains the text fields.
  • The vertical axis consists of a sequential group containing two parallel groups. The parallel groups are configured to align their components along the baseline. The first parallel group contains the first label and first text field, and the second group consists of the second label and second text field.
There are a couple of things to notice in this code:
  • You need not explicitly add the components to the container; this is indirectly done by using one of the add methods of Group.
  • The various add methods return the caller. This allows for easy chaining of invocations. For example, group.addComponent(label1).addComponent(label2); is equivalent to group.addComponent(label1); group.addComponent(label2);.
  • There are no public constructors for Groups; instead use the create methods of GroupLayout.
Since:
1.6