Aqua Phoenix
     >>  Lectures >>  Java 4  


4.4 Layout Managers

The area of an applet serves the purpose of laying out and managing objects. The Applet object is derived from a Panel, which again is derived from Container. Containers are objects that serve as areas to which Layouts can be assigned. Layouts then accept placement of GUI objects.

The order in which GUI components are placed is achieved by using Layout Managers. Layout Managers are objects, but only serve the purpose of providing a space, into which objects can be placed. Some popular and very useful layout managers are BorderLayout, GridLayout, and FlowLayout.

Regardless of which layouts are used, a fair amount of the decisions going into layout usage depend on trial and error. The bahavior of each Layout Manager can be predicted, but practice shows that there are exceptions that must be handled individually.

4.4.1 BorderLayout

BorderLayout divides the screen into 5 areas: North, South, East, West, and Center. These areas, if and when they are all utilized, are arranged as follows:

Figure 4.1

The size of each of the 5 regions is not pre-defined, and depends to a large extent on the objects placed in adjacent areas. Should you add a larger object to the East and a smaller one to the West, then each region would take on the appropriate size and the center region would adjust automatically. GUI components that are defined with very specific sizes, e.g. scrollbars, tend to dictate the sizes of other components that are more flexible in their dimensions. Regardless of the size of the applet, the layout manager adjusts itself to the applet size, and all objects are resized appropriately to fit the layout manager.

It is not necessary to use all five of the possible regions. Unused regions are simply scaled to use no space.

A BorderLayout is created and assigned to a container as follows:

BorderLayout borderLayout = new BorderLayout();
or the abbreviated (and more common) version:

CONTAINER_OBJECT.setLayout(new BorderLayout());
GUI Objects are added to the five regions of a BorderLayout as follows. For the purpose of this example, Labels are used to denote any type of GUI object that can be added to the layout:

CONTAINER_OBJECT.add(new Label("North"), BorderLayout.NORTH);
CONTAINER_OBJECT.add(new Label("South"), BorderLayout.SOUTH);
CONTAINER_OBJECT.add(new Label("East"), BorderLayout.EAST);
CONTAINER_OBJECT.add(new Label("West"), BorderLayout.WEST);
CONTAINER_OBJECT.add(new Label("Center"), BorderLayout.CENTER);
The reference to BorderLayout.NORTH is a reference to a static value named NORTH defined in the class BorderLayout.

4.4.2 GridLayout

While BorderLayout is constrained to at most 5 regions and distributes the regions regardless of size, GridLayout lays out components in a 2-dimensional grid-like fashion, where all cells have the same size, and are ordered from left to right, then top to bottom:

Figure 4.2

The size of a cell depends on the overall available space for the applet, as well as on the largest fixed component.

GridLayouts are created and assigned as follows:

GridLayout gridLayout = new GridLayout(3, 2);
or the abbreviated (and more common) version:

CONTAINER_OBJECT.setLayout(new GridLayout(3, 2));
This creates a GridLayout with 3 rows and 2 columns. GUI components are assigned to this layout primarily by row, then by column. This order is reflected by Figure 4.2.

CONTAINER_OBJECT.add(new Label("1st cell"));
CONTAINER_OBJECT.add(new Label("2nd cell"));
CONTAINER_OBJECT.add(new Label("3rd cell"));
CONTAINER_OBJECT.add(new Label("4th cell"));
CONTAINER_OBJECT.add(new Label("5th cell"));
CONTAINER_OBJECT.add(new Label("6th cell"));

4.4.3 FlowLayout

FlowLayout is the default layout for any given container. When there are no explicit assignments to new Layout Managers, FlowLayout is used.

Figure 4.3

GUI components are merely spaced out horizontally, one after the next, until the width of the window has been reached. FlowLayout then skips to the next area below to place more objects.

FlowLayouts are created and assigned as follows:

FlowLayout flowLayout = new FlowLayout();
or the abbreviated (and more common) version:

CONTAINER_OBJECT.setLayout(new FlowLayout());
GUI components are added to this layout from left to right, row by row. When a row is filled with components, the next row is then used.

4.4.4 Nesting Layout Managers

LayoutManagers can include other LayoutManagers, which can include other LayoutManagers, etc. There are virtually no boundaries as to how many LayoutManagers can be used and nested.

LayoutManagers can be used within other layout managers by adding blank Panels, which act as containers:

Figure 4.4

This example shows a BorderLayout assigned to the root container. The center area in the BorderLayout is assigned a Panel, which again holds another LayoutManager, namely a GridLayout. The code snippet for this layout, assuming that the root container is named root, is:

CONTAINER_OBJECT.setLayout(new BorderLayout());

Panel centerPanel = new Panel();
root.add(centerPanel, BorderLayout.CENTER);

centerPanel.setLayout(new GridLayout(3, 2));
When adding GUI components to the Panel centerPanel, they will now be spaced according to the GridLayout rules, and they will be confined to the center area.

4.4.5 Containers

The methods for assigning LayoutManagers and assigning GUI components apply only to containers. That is, given some container by the name CONTAINER_OBJECT (like in the examples above), a LayoutManager is first assigned using CONTAINER_OBJECT.setLayout(...) , and afterwards, GUI components can be added using CONTAINER_OBJECT.add(...) .

Panel objects are derived from Containers, i.e. they inherit from Container, and can thus be used as objects to which layouts can be assigned.

Applet is a special object that is in fact a Panel, and thus also a Container. This is important in beginning the layout of an applet:

  • Applet = Container, and thus without having to refer to any object in particular, it is valid to use the layout methods in init():

        public void init() {

          setLayout( ... );

          add( ... );
          add( ... );
          add( ... );

Any Container that is added for the purpose of nesting other LayoutManagers must be explicitely created and referenced:

      public void init() {

        setLayout( ... );

        add( ... );

        Panel nestedPanel = new Panel();
        nestedPanel.setLayout( ... );
          nestedPanel.add( ... );
          nestedPanel.add( ... );
          nestedPanel.add( ... );

        add(nestedPanel ... );