Section 4.4. A Graphical User Interface (GUI)


[Page 159 (continued)]

4.4. A Graphical User Interface (GUI)

While command-line interfaces are useful, one of the great advantages of the Java language is that its extensive class library makes it relatively easy to develop applications that employ Graphical User Interfaces (GUIs). GUIs have been around now for many years, since the production of the Macintosh in the early 1980s. Today nearly all personal computing applications are GUI-based. Therefore, it is important that beginning programmers be able to design and write programs that resemble, albeit on a simpler scale, the programs they use every day. Among other benefits, developing the ability to write GUI programs like the ones everyone uses today will make it easier for you to show off your work to others, and this may motivate further interest in learning to program.

In this and subsequent sections, we will develop an extensible GUI model that can be used with either a Java application or an applet. By extensible we mean a model that can be easily adapted and used in a wide variety of programs. GUI programming involves a computational model known as event-driven programming. This means that GUI programs react to events that are generated mostly by the user's interactions with elements in the GUI. Therefore, we will have to learn how to use Java's event model to handle simple events.

Event-driven programming


Since this is our first look at some complex topics, we will keep the discussion as simple as possible. We will delay discussion of certain issues that will be taken up in more depth in Chapter 13.


[Page 160]

4.4.1. Java's GUI Components

The Java library comes with two separate but interrelated packages of GUI components, the older java.awt package and the newer javax.swing package. For the most part, the Swing classes supersede the AWT classes. For example, the java.awt.Button class is superseded by the javax.swing.JButton class, and the java.awt.TextField class is superseded by the javax.swing.JTextField class. As these examples show, the newer Swing components add an initial J to the names of their corresponding AWT counterparts.

Figure 4.10 illustrates how some of the main components appear in a GUI interface. As can be seen, a JLabel is simply a string of text displayed on the GUI, used here as a prompt. A JTextField is an input element that can hold a single line of text. In this case, the user has input his name. A JTextArea is an output component that can display multiple lines of text. In this example, it displays a simple greeting. A JButton is a labeled control element, which is an element that allows the user to control the interaction with the program. In this example, the user will be greeted by the name input into the JTextField whenever the JButton is clicked. As we will learn, clicking on the JButton causes an event to occur, which leads the program to take the action of displaying the greeting. Finally, all of these components are contained in a JFrame, which is a top-level container. A container is a GUI component that can contain other GUI components.

Figure 4.10. Various GUI components from the javax.swing package.


The Swing classes are generally considered to be superior to their AWT counterparts. For one thing, Swing components use a sophisticated object-oriented design known as the model-view-controller (MVC) architecture. This gives them much greater functionality than their AWT counterparts. For example, whereas an AWT Button can only have a string as its label, a Swing JButton can use an image as a label. (See Chapter 13 for a detailed discussion of the MVC architecture.)

Model-viewcontroller (MVC) architecture



[Page 161]

Second, Swing components are written entirely in Java, which makes them more portable and enables them to behave the same way regardless of the operating system on which they are run. Because of their portability, Swing components are considered lightweight. By contrast, AWT classes use routines that are implemented in the underlying operating system and are therefore not easily portable. Thus, they are considered heavyweight components. Whereas a Swing JButton should look and act the same regardless of platform, an AWT Button would have a different implementation, and hence a different look-and-feel, on a Macintosh and on a Windows system. In this book, we will use the new Swing classes in our programs.

Swing portability


4.4.2. Class Inheritance: Extending a Superclass

As you will recall from Chapter 0, class inheritance is the mechanism by which a class of objects can acquire (inherit) the methods and variables of its superclasses. Just as a horse, by virtue of its membership in the class of horses, inherits the attributes and behaviors of a mammal and, more generally, of an animal, a Java subclass inherits the variables and methods of its superclasses. We sometimes lump together an object's attributes and behaviors and refer to them collectively as its functionality. So we say that an object of a subclass inherits the functionality of all of its superclasses.

Inheritance


Functionality


By the same token, just as a horse and a cow extend their mammalian attributes and behaviors in their own special ways, a Java subclass extends the functionality of its superclasses in its own special way. Thus, a subclass specializes its superclass.

In Chapter 3, we showed how all classes in the Java hierarchy inherit the toString() method from the Object class. The lesson there was that an object in a subclass can either use or override any public method defined in any of its superclasses. In order to implement GUI programs, we need to look at another way to employ inheritance. In particular, we need to learn how to define a new class by extending an existing class.

We noted in Chapter 2 that unless a class is explicitly defined as a subclass of some other class, it is implicitly considered to be a direct subclass of Object. Thus, the GreeterApp class defined earlier in this chapter is a subclass of Object. We can make the relationship between GreeterApp and Object explicit by using the extends keyword when we define the GreeterApp class:

public class GreeterApp extends Object { ... } 


Thus, the extends keyword is used to specify the subclass/superclass relationships that hold in the Java class hierarchy. We sometimes refer to the subclass/superclass relationship as the is-a relationship, in the sense that a horse is a mammal, and a mammal is a animal. Thus, the extends keyword is used to define the is-a relationship among the objects in the Java class hierarchy.

The is-a relationship


A top-level container is a GUI container that cannot be added to another container; it can only have components added to it. Figure 4.11 is a class hierarchy that shows the relationships among some of the top-level Swing and AWT classes. For example, the javax.swing. JFrame class, which represents a top-level window, is a subclass of java.awt.Frame, and the javax.swing.JApplet is a subclass of java.applet.Applet. We can see from this figure that a JApplet is-a Applet and an Applet is-a Panel and a Panel is-a Container.

Figure 4.11. Top-level Swing and AWT classes.
(This item is displayed on page 162 in the print version)


Top-level container



[Page 162]

These subclass/superclass relationships are created in their respective class definitions by using the extends keyword, as follows:

public class JApplet extends Applet { ... } public class Applet extends Panel { ... } public class Panel extends Container { ... } 


As we will see in the next section, extending a class in this way enables us to create a new class by specializing an existing class.

Specialization


4.4.3. Top-Level Windows

Referring again to Figure 4.11, note that all of the Swing components are subclasses of the AWT Container class. This means that Swing components are Containers. They inherit the functionality of the Container class. So Swing components can contain other GUI components. That is why a JButton can contain an image.

All GUI programs must be contained inside a top-level container of some kind. Swing provides four top-level container classes: JFrame, JWindow, JApplet, and JDialog. For our basic GUI, we will use a JFrame as the top-level window for standalone applications. We will use a JApplet as the top-level window for Java applets.

A JFrame encapsulates the basic functionality of a top-level window. It has a content pane to which other Swing components, such as buttons and text fields, can be added. In addition, it comes with enough built-in functionality to respond to certain basic commands, such as when the user adjusts its size or closes it.

Content pane



[Page 163]

Figure 4.12 shows a simple top-level window as it would be displayed on the console. The window has a title ("My GUI"). It is 200 pixels wide, 150 pixels high, and its top-left corner is located at coordinates (100,150) on the console screen. As in other graphical systems, points on the Java console are always given as an ordered pair, (X, Y), with the horizontal coordinate, X, listed first, followed by the vertical coordinate, Y. The horizontal x-axis extends positively from left to right, and the vertical y-axis extends positively from top to bottom.

Figure 4.12. A simple window.


The class that created and displayed this window is shown in Figure 4.13. Note the use of the extends keyword to define SimpleGUI as a subclass of JFrame. As a subclass, SimpleGUI inherits all of the functionality of a JFrame (Fig. 4.14). That is, it can contain other GUI components, it knows how to resize and close itself, and so on. The reason we want to define a subclass of JFrame rather than just use a JFrame instance is because we want eventually to give our subclass additional functionality that is specialized for our application.

Figure 4.13. A top-level window with a title.

import javax.swing.*; public class SimpleGUI extends JFrame {     public SimpleGUI(String title)     {   setSize(200,150);         setLocation(100, 150);         setTitle(title);         setVisible(true);                    // Displays the JFrame     } // SimpleGUI()     public static void main(String args[])     {   new SimpleGUI("My GUI");     } // main() } // SimpleGUI class 

Figure 4.14. SimpleGUI is a subclass of JFrame.
(This item is displayed on page 164 in the print version)


Effective Design: Specialization

By creating a subclass of JFrame we can specialize its functionality for our application.



[Page 164]

Note how SimpleGUI's main() program creates an instance of SimpleGUI by invoking its constructor. There is no need to use a variable here because there are no further references to this object in this class. However, simply constructing a SimpleGUI will not cause it to appear on the Java console. For that to happen, it is necessary to give it a size and to call its setVisible() method. This is done in the constructor method.

The constructor method illustrates how to use some of the methods inherited from JFrame. Figure 4.14 shows some of the methods that SimpleGUI inherits from JFrame. We use the setSize() and setLocation() methods to set SimpleGUI's size and location. We use the setTitle() method to set its title. And we use the setVisible() method to cause it to appear on the console.

4.4.4. GUI Components for Input, Output, and Control

To enable our top-level window to serve as a user interface, it will be necessary to give it some components. Figure 4.15 provides an overview of some of the main Swing components. Generally, there are three types of components, corresponding to the three main functions of a user interface: input, output, and control. A JTextField is an example of an input component. The user can type text into the text field, which can then be transmitted into the program. A JTextArea is an example of an output component. The program can display text in the text area. Control components enable the user to control the actions of the program. A JButton is an example of a control component. It can be associated with an action that can be initiated whenever the user clicks it. We might also consider a JLabel to be an output component, because we can use it to prompt the user as to what type of actions to take.

Figure 4.15. Swing components.
(This item is displayed on page 165 in the print version)


Let's begin by creating a simple user interface, one that enables us to perform basic input, output, and control operations with a minimum of Swing components. This will allow us to demonstrate the basic principles and techniques of user-interface design and will result in a GUI that can be extended for more sophisticated applications. For this example, we will limit our application to simply greeting the user, just as we did in designing our command-line interface. In other words, the user will be prompted to input his or her name, and the program will respond by displaying a greeting (Fig. 4.10). We will call our GUI GreeterGUI, to suggest its interdependence with the Greeter computational object we used with the command-line interface.


[Page 165]

For this simple application, our GUI will make use of the following components:

  • A JTextField will accept user input.

  • A JTextArea will display the program's output.

  • A JButton will allow the user to request the greeting.

  • A JLabel will serve as a prompt for the JTextField.

Figure 4.16 shows some of the constructors and public methods for the JTextArea, JTextField, JButton, and JLabel components. The following code segments illustrate how to use these constructors to create instances of these components:

                               // Declare instance variables for the components private JLabel prompt; private JTextField inField; private JTextArea display; private JButton goButton;                                                    // Instantiate the components prompt = new JLabel("Please type your name here: "); inField = new JTextField(10);                      // 10 chars wide display = new JTextArea(10, 30);                   // 10 rows x 30 columns goButton = new JButton("Click here for a greeting!"); 



[Page 166]

Figure 4.16. Public methods and constructors for basic Swing components.


For this example, we use some of the simpler constructors. Thus, we create a JTextField with a size of 10. This means that it can display 10 characters of input. We create a JTextArea with 10 rows of text, each 30 characters wide. We create a JButton with a simple text prompt meant to inform the user of how to use the button.

4.4.5. Adding GUI Components to a Top-Level Window

Now that we know how to create GUI components, the next task is to add them to the top-level window. A JFrame is a top-level Container (Fig. 4.11), but instead of adding the components directly to the JFrame, we have to add them to the JFrame's content pane, which is also a Container.

Java Language Rule: Content Pane

GUI Components cannot be added directly to a JFrame. They must be added to its content pane.


Java's Container class has several add() methods that can be used to insert components into the container:

add(Component comp)                               // add comp to end of container add(Component comp, int index)                    // add comp at index add(String region, Component comp) add comp at region 


The particular add() method to use depends on how we want to arrange the components in the container. The layout of a container is controlled by its default layout manager, an object associated with the container that determines the sizing and arrangement of its contained components. For a content pane, the default layout manager is a BorderLayout. This is an arrangement whereby components may be placed in the center of the pane and along its north, south, east, and west borders (Fig. 4.17).

Figure 4.17. Arrangement of components in a border layout.
(This item is displayed on page 167 in the print version)


Layout manager



[Page 167]

Components are added to a border layout by using the add(String region, Component comp) method, where the String parameter specifies either "North", "South", "East", "West", or "Center". For example, to add the JTextArea to the center of the JFrame we first create a reference to its content pane and then we add the component at its center:

Container contentPane = getContentPane();    // Get pane contentPane.add("Center",display);           // Add JTextArea 


One limitation of the border layout is that only one component can be added to each area. This is a problem for our example because we want our prompt JLabel to be located right before the JTextField. To get around this problem, we will create another container, a JPanel, and add the prompt, the text field, and the goButton to it. That way, all of the components involved in getting the user's input will be organized into one panel. We then add the entire panel to one of the areas on the content pane.

JPanel inputPanel = new JPanel(); inputPanel.add(prompt);                 // Add JLabel to panel inputPanel.add(inField);                // Add JTextField to panel inputPanel.add(goButton);               // Add JButton to panel contentPane.add("South", inputPanel);   // Add to JFrame 


The default layout for a JPanel is FlowLayout, which means that components are added left to right with the last addition going at the end of the sequence. This is an appropriate layout for this JPanel because it will place the prompt just to the left of the input JTextField.

Effective Design: Encapsulation

JPanels can be used to group related components in a GUI.


4.4.6. Controlling the GUI's Action

Now that we know how to place all the components on the GUI, we need to design the GUI's controls. As mentioned earlier, GUIs use a form of event-driven programming. Anything that happens when you are using a computerevery keystroke and mouse movementis classified as an event. As Figure 4.18 illustrates, events are generated by the computer's hardware and filtered up through the operating system and the application programs. Events are handled by special objects called listeners. A listener is a specialist that monitors constantly for a certain type of event. Some events, such as inserting a CD in the CD-ROM drive, are handled by listeners in the operating system. Others, such as typing input into a Web page or a Word document, are handled by listeners in a piece of application software, such as a browser or a word processor.


[Page 168]

Figure 4.18. Java's event model.


Event listener


In an event-driven programming model, the program is controlled by an event loop. That is, the program repeatedly listens for events, taking some kind of action whenever an event is generated. In effect, we might portray this event loop as follows:

Repeat forever or until the program is stopped    Listen for events    if event-A occurs, handle it with event-A-handler    if event-B occurs, handle it with event-B-handler     ... 


The event loop listens constantly for the occurrence of events and then calls the appropriate object to handle each event.

Figure 4.19 shows some of the main types of events in the java.awt.event package. In most cases, the names of the event classes are suggestive of their roles. Thus, a MouseEvent occurs when the mouse is moved. A KeyEvent occurs when the keyboard is used. The only event that our program needs to listen for is an ActionEvent, the type of event that occurs when the user clicks the JButton.

Figure 4.19. Java's event hierarchy.
(This item is displayed on page 169 in the print version)


When the user clicks the JButton, Java will create an ActionEvent object. This object contains important information about the event, such as the time the event occurred and the object, such as a JButton, that was the locus of the event. For our application, when the user clicks the JButton, the program should input the user's name from the JTextField and display a greeting, such as "Hi John nice to meet you" in the JTextArea. That is, we want the program to execute the following code segment:

String name = inField.getText(); display.append(greeter.greet(name) + "\n"); 



[Page 169]

The first line uses the JTextField.getText() method to get the text the user typed into the JTextField and stores it in a local variable, name. The second line passes the name to the greeter.greet() method and passes the result it gets back to the JTextArea.append() method. This will have the effect of displaying the text at the end of the JTextArea.

In this example, we have used a couple of the standard public methods of the JTextField and JTextArea classes. For our simple GUI, the methods described in Figure 4.16 will be sufficient for our needs. However, if you would like to see the other methods available for these and other Swing components, you should check Java's online API documentation.

java.sun.com/docs


4.4.7. The ActionListener Interface

Given that the code segment just described will do the task of greeting the user, where should we put it in our program? We want the code segment to be invoked whenever the user clicks on the goButton. You know enough Java to understand that we have to put the code in a Java method. However, we need a special method in this case, one that will be called automatically by Java whenever the user clicks the button. In other words, we need a special method that the button's listener knows how to call whenever the button is clicked.

Java solves this problem by letting us define a preselected method that can be associated with the goButton. The name of the method is actionPerformed(), and it is part of the ActionListener interface. In this case, an interface is a special Java class that contains only methods and constants (final variables). It cannot contain instance variables. (Be careful to distinguish this kind of interface, a specific type of Java class, from the more general kind of interface, whereby we say that a class's public methods make up its interface to other objects.) Here is the definition of the ActionListener interface:


[Page 170]

public abstract interface ActionListener extends EventListener {    public abstract void actionPerformed(ActionEvent e); } 


Java interface


This resembles a class definition, but the keyword interface replaces the keyword class in the definition. Note that we are declaring this interface to be abstract. An abstract interface or abstract class is one that contains one or more abstract methods. An abstract method is one that consists entirely of its signature; it lacks an implementationthat is, it does not have a method body. Note that the actionPerformed() method in ActionListener places a semicolon where its body is supposed to be.

Java Language Rule: Java Interface

A Java interface is like a Java class except that it cannot contain instance variables.


Java Language Rule: Abstract Methods and Classes

An abstract method is a method that lacks an implementation. It has no method body.


Declaring a method abstract means that we are leaving its implementation up to the class that implements it. This way, its implementation can be tailored to a particular context, with its signature specifying generally what the method does. Thus, actionPerformed() takes an ActionEvent object as a parameter and performs some kind of action.

Abstract method


What this means, in effect, is that any class that implements the actionPerformed() method can serve as a listener for ActionEvents. Thus, to create a listener for our JButton, all we need to do is give an implementation of the actionPerformed() method. For our program, the action we want to take when the goButton is clicked is to greet the user by name. We want to set things up so that the following actionPerformed() method is called whenever the goButton is clicked:

public void actionPerformed(ActionEvent e) {  if (e.getSource() == goButton)    {   String name = inField.getText();          display.append(greeter.greet(name) + "\n");    } } 


In other words, we place the code that we want executed when the button is clicked in the body of the actionPerformed() method. Note that in the if statement we get the source of the action from the ActionEvent object and check that it was the goButton.


[Page 171]

This explains what is done when the button is clickednamely, the code in action-Performed() will be executed. But it doesn't explain how Java knows that it should call this method in the first place. To set that up we must do two further things. We must place the actionPerformed() method in our GreeterGUI class, and we must tell Java that GreeterGUI will be the ActionListener for the goButton.

The following stripped-down version of the GreeterGUI class illustrates how we put it all together:

 public class GreeterGUI extends Frame implements ActionListener { ...   public void buildGUI()   {  ...      goButton = new JButton("Click here for a greeting!");      goButton.addActionListener(this);      ...   }   ...   public void actionPerformed(ActionEvent e)   {   if (e.getSource() == goButton)       {   String name = inField.getText();           display.append(greeter.greet(name) + "\n");       }   }   ... } 


First, we declare that GreeterGUI implements the ActionListener interface in the class header. This means that the class must provide a definition of the actionPerformed() method, which it does. It also means that GreeterGUI is an ActionListener. So SimpleGUI is both a JFrame and an ActionListener.

Second, note how we use the addActionListener() method to associate the listener with the goButton:

goButton.addActionListener(this) 


The this keyword is a self-referencethat is, it always refers to the object in which it is used. It's the same as when we refer to ourselves by saying "I." When used here, the this keyword refers to the GreeterGUI. In other words, we are setting things up so that the GreeterGUI will serve as the listener for action events on the goButton.

Java Language Rule: This Object

The this keyword always refers to the object that uses it. It is like saying "I" or "me."


4.4.8. Connecting the GUI to the Computational Object

Figure 4.20 gives the complete source code for our GreeterGUI interface. Because there is a lot going on here, it might be helpful to go through the program carefully even though we have introduced most of its elements already. That will help us put together the various concepts we have introduced.


[Page 172]

Figure 4.20. Definition of the GreeterGUI class.

import javax.swing.*; import java.awt.*; import java.awt.event.*; public class GreeterGUI extends JFrame implements ActionListener { private JTextArea display;   private JTextField inField;   private JButton goButton;   private Greeter greeter;   public GreeterGUI(String title)   { greeter = new Greeter();     buildGUI();     setTitle(title);     pack();     setVisible(true);   } // GreeterGUI()   private void buildGUI()   { Container contentPane = getContentPane();     contentPane.setLayout(new BorderLayout());     display = new JTextArea(10,30);     inField = new JTextField(10);     goButton = new JButton("Click here for a greeting!");     goButton.addActionListener(this);     JPanel inputPanel = new JPanel();     inputPanel.add(new JLabel("Input your name here: "));     inputPanel.add(inField);     inputPanel.add(goButton);     contentPane.add("Center", display);     contentPane.add("South", inputPanel);   } // buildGUI()   public void actionPerformed(ActionEvent e)   { if (e.getSource() == goButton)     { String name = inField.getText();       display.append(greeter.greet(name) + "\n");     }   } // actionPerformed() } // GreeterGUI class 

To begin with, note the several Java packages that must be included in this program. The javax.swing package includes definitions for all of the Swing components. The java.awt.event package includes the ActionEvent class and the ActionListener interface, and the java.awt packages contain the Container class.

Next note how the GreeterGUI class is defined as a subclass of JFrame and as implementing the ActionListener interface. GreeterGUI thereby inherits all of the functionality of a JFrame. Plus, we are giving it additional functionality. One of its functions is to serve as an ActionListener for its goButton. The ActionListener interface consists entirely of the actionPerformed() method, which is defined in the program. This method encapsulates the actions that will be taken whenever the user clicks the goButton.

Extending a class


Implementing an interface


The next elements of the program are its four instance variables, the most important of which is the Greeter variable. This is the variable that sets up the relationship between the GUI and the computational object. In this case, because the variable is declared in the GUI, we say that the GUI uses the computational object, as illustrated in Figure 4.8. This is slightly different from the relationship we set up in the command-line interface, in which the computational object uses the interface (Fig. 4.2).


[Page 173]

The computational object


The other instance variables are for GUI components that must be referred to throughout the class. For example, note that the goButton, inField, and display are instantiated in the buildGUI() method and referenced again in the actionPerformed() method.

The next element in the program is its constructor. It begins by creating an instance of the Greeter computational object. It is important to do this first in case we need information from the computational object in order to build the GUI. In this case we don't need anything from Greeter, but we will need such information in other programs.

We've already discussed the fact that the constructor's role is to coordinate the initialization of the GreeterGUI object. Thus, it invokes the buildGUI() method, which takes care of the details of laying out the GUI components. And, finally, it displays itself by calling the pack() and setVisible() methods, which are inherited from JFrame. The pack() method sizes the frame according to the sizes and layout of the components it contains. The setVisible() method is what actually causes the GUI to appear on the Java console.

Finally, note the details of the buildGUI() method. We have discussed each of the individual statements already. Here we see the order in which they are combined. Note that we can declare the contentPane and inputPanel variables locally, because they are not used elsewhere in the class.

Self-Study Exercise

Exercise 4.2

There is a simple modification that we can make to GreeterGUI. The JTextField can serve as both an input element and a control element for action events. An ActionEvent is generated whenever the user presses the Return or Enter key in a JTextField so that the JButton can be removed. Of course, it will be necessary to designate the inField as an ActionListener in order to take advantage of this feature. Make the appropriate changes to the buildGUI() and actionPerformed() methods so that the inField can function as both a control and input element. Call the new class GreeterGUI2.

4.4.9. Using the GUI in a Java Application

As you know, a Java application is a standalone program, one that can be run on its own. We have designed our GUI so that it can easily be used with a Java application. We saw in the preceding section that the GUI has a reference to the Greeter object, which is the computational object. Therefore, all we need to get the program to run as an application is a main() method.

One way to use the GUI in an application is simply to create an instance in a main() method. The main() method can be placed in the GreeterGUI class itself or in a separate class. Here is an example with main() in a separate class:

public class GreeterApplication {  public static void main(String args[])    {       new GreeterGUI("Greeter");    } } 



[Page 174]

The main() method creates an instance of GreeterGUI, passing it a string to use as its title. If you prefer, this same main() method can be incorporated directly into the GreeterGUI class.

4.4.10. Using the GUI in a Java Applet

Using our GUI with a Java applet is just as easy as using it with an application. The only difference is that we instantiate GreeterGUI in the applet's init() method rather than in a main() method:

import javax.swing.*; public class GreeterApplet extends JApplet {     public void init()     {         new GreeterGUI("Greeter");     } } 


When this applet is run from a browser, it will open a separate top-level window that is identical to the window opened by the application. Unlike the other applets we have seen, the GUI will not be embedded directly in the Web page, because it is not possible to add a JFrame, which our GreeterGUI is, to a JApplet. The rule is that you cannot add one top-level window to another top-level window.

Java Language Rule: Top-level Windows

Top-level Java windows cannot contain other top-level windows as components.


It is a relatively simple matter to modify GreeterGUI so that it can be embedded directly in the applet window. The main change we have to make is to define the GUI as a subclass of JPanel rather than as a subclass of JFrame. Figure 4.21 presents a full implementation of the revised class, which we name GreeterGUIPanel.

Figure 4.21. Definition of the GreeterGUIPanel class.
(This item is displayed on page 175 in the print version)

import javax.swing.*; import java.awt.*; import java.awt.event.*; public class GreeterGUIPanel extends JPanel implements ActionListener { private JTextArea display;   private JTextField inField;   private JButton goButton;   private Greeter greeter;   public GreeterGUIPanel()   {   greeter = new Greeter();       buildGUI();   } // GUIPanel()   private void buildGUI()   { display = new JTextArea(10,30);     inField = new JTextField(10);     goButton = new JButton("Click here for a greeting!");     goButton.addActionListener(this);     JPanel inputPanel = new JPanel();     inputPanel.add(new JLabel("Input your name here: "));     inputPanel.add(inField);     inputPanel.add(goButton);     add("Center", display);     add("South", inputPanel);   } // buildGUI()   public void actionPerformed(ActionEvent e)   {   if (e.getSource() == goButton)       {   String name = inField.getText();           display.append(greeter.greet(name) + "\n");       } // if   } // actionPeformed() } // GreeterGUIPanel class 

The revised GreeterGUIPanel class requires the following two changes:

  • Unlike JFrames, JPanels do not have titles and do not have a pack() method. Therefore we modify the constructor method to the simpler form shown here.

  • Unlike JFrames, JPanels do not use a content pane. Swing components are added directly to the JPanel. This simplifies the buildGUI() method.

Given these changes, we would then change the applet's init() method to the following:

import javax.swing.*; public class GreeterPanelApplet extends JApplet {   public void init()     {    getContentPane().add(new GreeterGUIPanel());     } } 



[Page 175]

Since a JApplet has a content pane, we add the GreeterGUIPanel to the content pane rather than to the applet itself. The result would be the applet shown in Figure 4.22.

Figure 4.22. The Greeter applet. This version is embedded directly in the Web page.
(This item is displayed on page 176 in the print version)





Java, Java, Java(c) Object-Orienting Problem Solving
Java, Java, Java, Object-Oriented Problem Solving (3rd Edition)
ISBN: 0131474340
EAN: 2147483647
Year: 2005
Pages: 275

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net