Check out the new USENIX Web site.
;login: The Magazine
of USENIX & SAGE

 

using java

Life After Containers and Layout Managers:
Part 1

rao_prithvi by Prithvi Rao
<prithvi+@ux4.sp.cs.smu.edu>

Prithvi Rao is the co-founder of KiwiLabs, which specializes in software engineering methodology and Java/CORBA training. He has also worked on the development of the MACH OS and a real-time version of MACH. He is an adjunct faculty at Carnegie Mellon and teaches in the Heinz School of Public Policy and Management.

In a previous ;login: article I presented the use of Layout Managers to facilitate writing Graphical User Interfaces (GUIs) in Java. The motivation for this was, in part, the increasing popularity of GUI-based client-side applications.

In the electronic-commerce domain, for instance, the canonical n-tiered architecture often relies on a "thin" client that can be a GUI-based Java program. This does not imply that the console-based paradigm is being abandoned; it suggests that using GUI applications permits a more suitable semantic format for expressing a product's capability. An example of this is the merging of two database queries from two different databases. In this example a user may prefer to click and drag icons to merge these queries, as opposed to typing them at a console.

In this article I will present a brief background on containers and layout management and proceed to discuss the use of panels, frames, menus, and dialogs. I will present the use of layout managers to change the default layout of a container. In Part 2, I will go on to present examples of how to handle menus and dialogs.

Although the Java Swing class obviates the need to know the details of using these Abstract Windowing Toolkit (AWT) components, it is useful to understand the work on which Swing is based.

AWT Containers

The Container class is an abstract class that represents a component containing other components. Some of the subclasses of the Container class include Panel, Applet, Frame, and Dialogue. Once a Container object has been created, it is possible to add components to it using the add() method; remove() removes them.

A particularly useful method is the getComponents() method, which returns an array of components contained in the Container object.

Layout Management

The visual layout of the components in a container is performed not by the container itself but by a "Layout Manager."

Recall that the layout manager is any class implementing the LayoutManager interface. Some of the standard AWT layout managers are FlowLayout, BorderLayout, GridLayout, GridBagLayout, and CardLayout. It is also possible to implement your own layout manager derived from the LayoutManager interface.

A container specifies which layout manager to use by calling the setLayout() method. This can specify either an instance of a layout manager or null, which means that no layout manager is required. Components are then added to the container using the add() method. At this time, the precise layout of a component is determined by the layout manager associated with the component's container.

Although it is possible to position components in the absence of a layout manager, that renders it unsuitable for use with applets and other platform-independent programs. (This is related to the size of components differing for each platform.)

FlowLayout

The FlowLayout manager is the default for panels and therefore for applets, since applets are a type of panel. The components are positioned from left to right and from top to bottom. By default, components are centered within their row; creating a new FlowLayout manager object permits specifying left or right alignment to the constructor. The following is an example of its use:

  public void init() {
    // change layout to flow left aligned
    setLayout(new FlowLayout(FlowLayout.LEFT));
    add(new Label("USERID");
    add(nameField = new TextField(12);
    ......
  }

BorderLayout

The BorderLayout manager handles up to five components, and they each occupy a designated region of the container &151; namely, North, South, East, West, or Centre. The contained components will be stretched to fill the container according to their preferred and minimum sizes.

For instance, the North and South components will be stretched to fit the width of the container and given their preferred height. The East and West components' height will be stretched to fit between the North and South components and given their preferred width. The Centre components will be allocated the remaining space. The following is an example of BorderLayout use:

  public void init() {
  // change layout to border
  setLayout(new BorderLayout());
  add("West", colourSelect = new Select());
  ......
  }

GridLayout

The GridLayout manager divides the container into a grid of a specified number of rows and columns. As components are added to the container, they are placed in the cells of the grid in the order in which they are added (i.e., left to right and top to bottom). The result of this is that all components have the same size.

  public void init() {
  // change layout to grid of 4 rows and 3 columns
    setLayout(new GridLayout(4, 3));
    add(new Button("1");
    add(new Button("2");
    ......
  }

The GridBagLayout manager is more powerful but also much more complicated to use than the simpler GridLayout manager. As in the GridLayout manager, the container is divided into a grid of rows and columns. However, as components are added to the container, adjacent cells may be merged to accommodate the component; in other words, the components need not all be the same size. In order to achieve this, each component must specify a number of "constraints" in a GridBagConstraints object. Setting these up is a topic for a future article. (This information is also available in the JDK documentation.)

Using Panels to Improve Layout

The Panel class is a general-purpose type of container that can be used to hold other components. Panels are very useful for improving the layout of a container. Recall that the Applet class extends Panel. This permits an applet to run in a browser or appletviewer.

From the Container class the Panel class inherits the hooks for layout management, which determines the position and size of each of its components and offers the ability to manage groups of components. For instance, to add a component to a panel you simply use one of the overloaded versions of the add() method. Interestingly, the default layout manager for a Panel is the FlowLayout layout manager.

Using No Layout Manager

It is possible to add components in the absence of a layout manager. For instance, if null is specified in setLayout(), a container can specify that it does not have a layout manager. This means that the container must position and size each component using the reshape() and resize() methods of the Component class. The following elucidates this point:

  Button enter, exit;

  ......
  setLayout(null); // specify no layout manager
  add(enter = new Button("ENTER"));
  add(exit = new Button("EXIT"));
  enter.reshape(10, 10, 30, 15);
  exit.reshape(90, 10, 30, 15);
  ......

Building GUI Applications

The Frame class provides top-level windows for applets and applications. It is derived from the Window class, which is itself derived from the Container class. It also implements the MenuContainer interface.

A Frame window is surrounded by "controls" for the titlebar, sizable border, system menu, and shortcut buttons. The system menu and the shortcut buttons permit it to be minimized, maximized, and closed. When it is minimized, it is represented by an icon. A Frame can also provide a menubar with pull-down menus.

Note: a graphical application requires at least one frame window. Unlike an applet window, a frame window is both sizable and movable. It can also display a dialog window.

As with any component, the AWT sends a frame window to all mouse, keyboard, and focus events that occur over it, as well as menu-item action events and general window events, such as "window deiconify," "window destroy," "window expose," "window iconify," and "window moved."

It is important to understand that a newly created Frame window has zero size and is invisible. It can be given a size by calling the resize() method of the Component class. Alternatively, you can use pack(), which sets the window size to match the preferred size of the components contained within the window. It is necessary to call "show" to make the window visible and bring it to the foreground.

A Frame window can be removed from the screen by calling hide(). If the window is no longer needed, call dispose() to free up its window resources.

Creating a Top-Level Window

By default a new Frame window is hidden and has zero size, so it is necessary to call its resize() and show() methods, as in the following examples:

  public class MyFrame extends Frame {
  ......

    public static void main(String[] args) {
      Frame f = new MyFrame();
      f.resize(300, 200);
      f.show();
    ....
    }

  }

Conclusion

We have examined the use of layout managers and the role they play in writing GUI applications in Java. We have also seen that it is possible to manipulate components in the absence of a layout manager. This, however, does not promote portability.

Part II of this article (in the next issue of ;login:) will discuss the use of menus and dialogs, concentrate on how to respond to events, and cover displaying and returning data from a dialog.

  

?Need help? Use our Contacts page.
Last changed: 27 dec. 2000 ah
Using Java index
Issue index
;login: index
USENIX home