Implementing Simple GUIs in Java
1. java.awt.Label – contains a field called text of type String The value of text may be accessed by query getText() and changed by command setText(aString) by the program but not the user There are options for setting the alignment of the
text string and for changing font properties. This component is useful for static labeling and for dynamic display of simple textual output that is under program control. The JFC component javax.swing.JLabel may be used in the same way.
2. java.awt.TextField – contains a single line of text, represented by field text of type String, that may be editable by the user. The value of text may be accessed
by query getText() and changed by command setText(aString) by the program. The value of text may also be changed directly by the user. This component is useful for user input of simple textual information as well as output display. The JFC component javax.swing.JTextField may be used in the same way. The text field components generate a KeyEvent
while being edited and an ActionEvent on pressing the Enter key.
3. java.awt.Button – a simple control that translates a mouse click over its image into an ActionEvent. This provides the user with a simple activating input. The JFC component javax.swing.JButton may be used in the same way. Other useful components include the AWT components List, TextArea, Choice, Checkbox, CheckboxGroup (a group of Checkbox
objects behaving as a group of radio buttons), Dialog, and Menu. The JFC adds many more useful components. Some of these components are used in the GUI laboratories in Part Two of the book.
6.1.3—
Organizing and Laying out Components in a Window
The Java 2 Platform comes with several predefined layout managers that automatically size and position components within a container. Each container has a default layout manager; the default for Frame is BorderLayout (see Java documentation). For simple applications the predefined layout managers may be suitable; however, for applications with a large number of precisely arranged components a different approach is needed.
The process of sizing and positioning components in a container is one of the most labor-intensive parts of building a GUI application. Fortunately, we have a variety of development environments that allow this to be done graphically. The development environment generates the Java code from the graphical design. Each development environment has its own style for layout coding. A simple, non -cluttering, and understandable style that works well for most GUI
applications is to set the layout manager to null and use the Component method setBounds to set the size and position of all components. JBuilder1 uses this approach. Listing 6.2 shows a simple class, LayoutExample, for adding two buttons and a label to a Frame. Command initialize() sets the layout to null, creates the components, determines their size and position using setBounds(), and then adds them to the frame.
Listing 6.2 Simple Layout Example
/** Positioning components in a container */
import java.awt.*; import java.awt.event.*;
public class LayoutExample extends Frame { Label valueLabel; Button incrementButton; Button resetButton; public LayoutExample () { super(''An Incrementer" ); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0)
} });
initialize(); }
private void initialize () {
setSize(200, 100); this.setLayout(null);
incrementButton = new Button("Increment" ); incrementButton.setBounds(20, 40, 75, 25); add(incrementButton);
resetButton = new Button("Reset" ); resetButton.setBounds(105, 40, 75, 25); add(resetButton);
valueLabel = new Label("0" , Label.CENTER); valueLabel.setBounds(75, 70, 50, 25); add(valueLabel);
setVisible(true); }
public static void main (String[] args) {
new LayoutExample(); }
}
If we use a JFrame instead of Frame, the components must be added to the content pane of the JFrame. Listing 6.3 shows the details for command initialize() if we are using a JFrame. Components are contained in the JFrame's content pane. The second parameter of each setBounds() message is reduced by 20 because the y-distance is measured from the bottom of the title bar in a JFrame. Key changes are shown in boldface.
Listing 6.3 Adding Components to a JFrame
. . .
private void initialize () {
this.getContentPane().setLayout(null);
incrementButton = new Button(''Increment" ); incrementButton.setBounds(20, 20, 75, 25); getContentPane().add(incrementButton);
resetButton = new Button("Reset" ); resetButton.setBounds(105, 20, 75, 25); getContentPane().add(resetButton);
valueLabel = new Label("0" , Label.CENTER); valueLabel.setBounds(75, 50, 50, 25); getContentPane().add(valueLabel);
setVisible(true); }
. . .
We have now built a simple GUI with some components (two buttons and a label; other components are used in examples in later chapters) that still does nothing. The next step is to understand and enable event handling, to make the application do some work.
6.2—
Implementation of Event Handling in Java
The delegation event model in Java allows any object to register as an event handler by (1) adding itself as a listener to the event source and (2) implementing the appropriate EventListener interface for that source.
6.2.1—
Options for Implementing an EventListener Interface
In a GUI application there are many options for implementing listener interfaces for the variety of events that may be generated by components in the GUI. These options are illustrated in Figure 6.1.
Specific EventListener interfaces may be implemented: • Directly by:
•MyGUI
•NamedInnerClass
•AnonymousInnerClass
•ExternalHelper
• Subclassed under predefined adapter:
• Difficult for MyGUI (usually a subclass of Frame or JFrame) • Possible for NamedInnerClass
• Possible for AnonymousInnerClass
• Possible for ExternalHelper
The first option available to an event listener is to decide who implements the EventListener interface methods. The event listener may choose to implement
Figure 6.1.
Options for implementing EventListener interfaces.
these methods itself or to use a helper class. The helper class may be (1) a named inner class, (2) an anonymous inner class, or (3) an external class.
An advantage of using a helper class is that the helper class usually has no constraints on its parent class and may extend one of the predefined adapter classes. A GUI application class is typically a subclass of Frame. Adapter classes provide ''do nothing" implementations of EventListener subinterfaces that have more than one method. They satisfy the contract that all methods in the interface must be implemented. In many applications, not all the methods in an EventListener are used; the helper class then extends the adapter class and redefines the method or methods that are used. In a roundabout way, adapters save a little effort by providing empty implementations for the methods that are not used. Figure 6.2 shows the predefined adapter classes that are part of the AWT. Each adapter class implements its corresponding event listener interface; for example, class ComponentAdapter implements interface ComponentListener.
6.2.2—
Steps in Processing a Simple Button Click Event
In the AWT, components have peer classes that interface directly with the operating system. Implementations for these peer classes handle details of capturing low-level events and posting semantic (see Chapter 5) events to the EventQueue. Figure 6.3 presents a collaboration diagram showing the sequence of steps following the clicking of a Button component in a user interface. The AWT Runtime is not really an object. It is more precisely a collection of objects and instructions that comprise the Java runtime environment (JRE). Its first role in our example is to recognize that the mouse pointer is over the button and that the mouse button has been clicked, that is, responds to an imagined message, buttonClicked().
Figure 6.2.
Predefined adapter classes in the AWT. Discussion of the Collaboration Diagram in Figure 6.3
The rectangular boxes are objects with labels identifying their class and optionally the object name; for example, button
is an instance of Button and is the source for the ActionEvent. Object AWT Runtime represents the peer class object for
Button plus other supporting communication with the operating system; most of its details are hidden.
The steps are numbered in their sequence of occurrence. Thus step 1 occurs when the user clicks the mouse with its cursor positioned on the button object's image in a user interface. The steps show messages sent to an object by another object. The arrows show the direction of communication. A description of the steps in Figure 6.3 is given as: