Introduction to the AWT

A description of Java's user interface toolkit

The Java programming language class library provides a user interface toolkit called the Abstract Windowing Toolkit, or the AWT. The AWT is both powerful and flexible. Newcomers, however, often find that its power is veiled. The class and method descriptions found in the distributed documentation provide little guidance for the new programmer. Furthermore, the available examples often leave many important questions unanswered. Of course, newcomers should expect some difficulty. Effective graphical user interfaces are inherently challenging to design and implement, and the sometimes complicated interactions between classes in the AWT only make this task more complex. However, with proper guidance, the creation of a graphical user interface using the AWT is not only possible, but relatively straightforward.

This article covers some of the philosophy behind the AWT and addresses the practical concern of how to create a simple user interface for an applet or application.

What is a user interface

The user interface is that part of a program that interacts with the user of the program. User interfaces take many forms. These forms range in complexity from simple command-line interfaces to the point-and-click graphical user interfaces provided by many modern applications.

At the lowest level, the operating system transmits information from the mouse and keyboard to the program as input, and provides pixels for program output. The AWT was designed so that programmers don't have worry about the details of tracking the mouse or reading the keyboard, nor attend to the details of writing to the screen. The AWT provides a well-designed object-oriented interface to these low-level services and resources.

Because the Java programming language is platform-independent, the AWT must also be platform-independent. The AWT was designed to provide a common set of tools for graphical user interface design that work on a variety of platforms. The user interface elements provided by the AWT are implemented using each platform's native GUI toolkit, thereby preserving the look and feel of each platform. This is one of the AWT's strongest points. The disadvantage of such an approach is the fact that a graphical user interface designed on one platform may look different when displayed on another platform.

Components and containers

A graphical user interface is built of graphical elements called components. Typical components include such items as buttons, scrollbars, and text fields. Components allow the user to interact with the program and provide the user with visual feedback about the state of the program. In the AWT, all user interface components are instances of class Component or one of its subtypes.

Components do not stand alone, but rather are found within containers. Containers contain and control the layout of components. Containers are themselves components, and can thus be placed inside other containers. In the AWT, all containers are instances of class Container or one of its subtypes.

Spatially, components must fit completely within the container that contains them. This nesting of components (including containers) into containers creates a tree of elements, starting with the container at the root of the tree and expanding out to the leaves, which are components such as buttons.

The illustration in Figure 1 depicts a simple graphical user interface as it would look when displayed under Windows 95. Figure 2 shows the interface components from Figure 1 arranged as a tree.

Frame
Figure 1.
Tree
Figure 2.

Types of components

Figure 3 shows the inheritance relationship between the user interface component classes provided by the AWT. Class Component defines the interface to which all components must adhere.

Hierarchy
Figure 3.

The AWT provides nine basic non-container component classes from which a user interface may be constructed. (Of course, new component classes may be derived from any of these or from class Component itself.) These nine classes are class Button, Canvas, Checkbox, Choice, Label, List, Scrollbar, TextArea, and TextField. Figure 4 depicts an instance of each class.

You need a Java-enabled browser to view this applet.

Figure 4.

Nine user interface components

The source for this display is found here.

Types of containers

The AWT provides four container classes. They are class Window and its two subtypes -- class Frame and class Dialog -- as well as the Panel class. In addition to the containers provided by the AWT, the Applet class is a container -- it is a subtype of the Panel class and can therefore hold components. Brief descriptions of each container class provided by the AWT are provided below.

WindowA top-level display surface (a window). An instance of the Window class is not attached to nor embedded within another container. An instance of the Window class has no border and no title.
FrameA top-level display surface (a window) with a border and title. An instance of the Frame class may have a menu bar. It is otherwise very much like an instance of the Window class.
DialogA top-level display surface (a window) with a border and title. An instance of the Dialog class cannot exist without an associated instance of the Frame class.
Panel

A generic container for holding components. An instance of the Panel class provides a container to which to add components.

Creating a container

Before adding the components that make up a user interface, the programmer must create a container. When building an application, the programmer must first create an instance of class Window or class Frame. When building an applet, a frame (the browser window) already exists. Since the Applet class is a subtype of the Panel class, the programmer can add the components to the instance of the Applet class itself.

The code in Listing 1 creates an empty frame. The title of the frame ("Example 1") is set in the call to the constructor. A frame is initially invisible and must be made visible by invoking its show() method.

import java.awt.*;

public class Example1 { public static void main(String [] args) { Frame f = new Frame("Example 1");

f.show(); } }

Listing 1.

An empty frame

The code in Listing 2 extends the code from Listing 1 so that the new class inherits from class Panel. In the main() method, an instance of this new class is created and added to the Frame object via a call to the add() method. The result is then displayed. The results of both examples should look identical (that is, they should look quite uninteresting).

import java.awt.*;

public class Example1a extends Panel { public static void main(String [] args) { Frame f = new Frame("Example 1a");

Example1a ex = new Example1a();

f.add("Center", ex);

f.pack(); f.show(); } }

Listing 2.

A frame with an empty panel

By deriving the new class from class Applet instead of class Panel, this example can now run as either a standalone application or as an applet embedded in a Web page. The code for this example is provided in Listing 3. The resulting applet is displayed in Figure 5 (and is still quite uninteresting).

import java.awt.*;

public class Example1b extends java.applet.Applet { public static void main(String [] args) { Frame f = new Frame("Example 1b");

Example1b ex = new Example1b();

f.add("Center", ex);

f.pack(); f.show(); } }

Listing 3.

A frame with an empty applet

You need a Java-enabled browser to view this applet.

Figure 5.

An empty frame

Note: a Window object, and in certain cases even a Dialog object, could replace the Frame object. They are all valid containers, and components are added to each in the same fashion.

Adding components to a container

To be useful, a user interface must consist of more than just a container -- it must contain components. Components are added to containers via a container's add() method. There are three basic forms of the add() method. The method to use depends on the container's layout manager (see the section titled Component layout).

The code in Listing 4 adds the creation of two buttons to the code presented in Listing 3. The creation is performed in the init() method because it is automatically called during applet initialization. Therefore, no matter how the program is started, the buttons are created, because init() is called by either the browser or by the main() method. Figure 6 contains the resulting applet.

import java.awt.*;

public class Example3 extends java.applet.Applet { public void init() { add(new Button("One")); add(new Button("Two")); }

public Dimension preferredSize() { return new Dimension(200, 100); }

public static void main(String [] args) { Frame f = new Frame("Example 3");

Example3 ex = new Example3();

ex.init();

f.add("Center", ex);

f.pack(); f.show(); } }

Listing 4.

An applet with two buttons

You need a Java-enabled browser to view this applet.

Figure 6.

An applet with two buttons

Component layout

Up to this point, nothing has been said about how the components that have been added to a container are laid out. Layout is controlled not by the container, but by a layout manager associated with the container. The layout manager makes all of the component placement decisions. In the AWT, all layout manager classes implement the LayoutManager interface.

The AWT provides five layout managers. They range from very simple to very complex. This article covers only the two layout manager classes used by the examples herein: the FlowLayout class and the BorderLayout class.

The FlowLayout class places components in a container from left to right. When the space in one row is exhausted, another row is started. The single-argument version of a container's add() method is used to add components.

The BorderLayout class has five zones as depicted in Figure 7. The zones are named "North", "South", "East", "West", and "Center". A single component can be placed in each of these five zones. When the enclosing container is resized, each border zone is resized just enough to hold the component placed within. Any excess space is given to the center zone. The two-argument version of a container's add() method is used to add components. The first argument is a String object that names the zone in which to place the component.

Border
Figure 7.

Each container class has a default layout manager. The default layout manager for the Frame class and Dialog class is the BorderLayout manager. The default layout manager for the Panel class (and the Applet class) is the FlowLayout manager.

The code in Listing 5 uses both layout managers and includes a few more user interface components. The result is displayed in Figure 8.

import java.awt.*;

public class Example4 extends java.applet.Applet { public void init() { Panel p;

setLayout(new BorderLayout());

p = new Panel();

p.add(new TextArea());

add("Center", p);

p = new Panel();

p.add(new Button("One")); p.add(new Button("Two"));

Choice c = new Choice();

c.addItem("one"); c.addItem("two"); c.addItem("three");

p.add(c);

add("South", p); }

public static void main(String [] args) { Frame f = new Frame("Example 4");

Example4 ex = new Example4();

ex.init();

f.add("Center", ex);

f.pack(); f.show(); } }

Listing 5.

A more complicated example

You need a Java-enabled browser to view this applet.

Figure 8.

A more complicated example

Event handling

The examples above do nothing more than display an inert user interface. It is, of course, very important that a user interface take action as a result of user input. It is, however, beyond the scope this article to delve deeply into the mysteries of event handling. That must wait until a future article. However, in the interest of completeness, the example code in Listing 6 shows how to handle one type of event a program may receive. The new class overrides the action() method provided by the Component class. The action() method responds to the action events that are generated, for example, by the selection of an item from a pop-up list. The action() method requires that two parameters be supplied, an Event instance and an Object instance. The Event instance contains information about the event, including the target of the event (the component that first received the event), the x and y coordinates of the event, and the time when the event occurred. The Object instance holds an event-specific piece of data. For Button objects it contains the text in the button label.

import java.awt.*;

public class Example5 extends java.applet.Applet { TextArea ta = null;

public void init() { Panel p;

setLayout(new BorderLayout());

p = new Panel();

ta = new TextArea();

p.add(ta);

add("Center", p);

p = new Panel();

p.add(new Button("One")); p.add(new Button("Two"));

Choice c = new Choice();

c.addItem("one"); c.addItem("two"); c.addItem("three");

p.add(c);

add("South", p); }

public boolean action(Event e, Object o) { String str = (String)o;

ta.appendText(str + "\n");

return false; }

public static void main(String [] args) { Frame f = new Frame("Example 5");

Example5 ex = new Example5();

ex.init();

f.add("Center", ex);

f.pack(); f.show(); } }

Listing 6.

An example with event handling

You need a Java-enabled browser to view this applet.

Figure 9.

An example with event handling

Next month's article will elaborate upon this brief description of event handling.

Todd Sundsted has been programming since computers became available in desktop models. Though originally interested in building distributed object applications in C++, Todd moved to the Java programming language when Java became an obvious choice for that sort of thing. In addition to writing, Todd provides Internet and Web application consulting services to companies in the southeastern United States.

Learn more about this topic

Join the discussion
Be the first to comment on this article. Our Commenting Policies