Richard G Baldwin (512) 223-4758, baldwin@austin.cc.tx.us, http://www2.austin.cc.tx.us/baldwin/

Event Handling in JDK 1.1, Low-level and Semantic Events

Java Programming, Lecture Notes # 84, Revised 03/09/98.

Preface

Students in Prof. Baldwin's Intermediate Java Programming classes at ACC are responsible for knowing and understanding all of the material in this lesson.

Introduction

An earlier lesson briefly discussed the differences between low-level events and semantic events as described in the JDK 1.1 documentation.

This lesson takes another look at that topic through the use of programs which apply both low-level event handling and semantic event handling to the same set of visual components. This makes it possible to compare the two types of events in a more meaningful way.

Overview

Although the suite of semantic events is generally used for different purposes than the suite of low-level events, from a practical programming viewpoint, there is very little difference.

The primary difference appears to reside in the nature of the event object that is passed to the event handler when an event occurs.

Using the information in the event object, low-level events can gain access to the specific Component object that generated the event.

Given a low-level event object, the getComponent() method of the java.awt.event.ComponentEvent class will return a reference to the actual object that generated the event.

Once that reference is available, there are literally dozens of methods of the Component class that can be invoked on the object, such as getLocation(), getLocationOnScreen(), getMaximumSize(), getMinimumSize(), getName(), etc.

A sample program in a previous lesson invoked the getName() method on such an object to determine which object among several objects generated a low-level mouse event.

A sample program that we will see later in this lesson invokes some of the other available methods on such a component object.

All low-level event classes are subclasses of the java.awt.event.ComponentEvent class, so the event handlers for all low-level events have access to the object that generated the event.

Semantic events, on the other hand, do not subclass the ComponentEvent class. Rather, they subclass the superclass of ComponentEvent making them siblings of ComponentEvent.

Because they do not subclass ComponentEvent, the event objects passed into semantic event handlers do not provide a way to obtain a reference to the object that generated the event, and therefore cannot invoke the methods of the Component class on that object.

Whether this is important or not depends on your needs.

For example, if you needed to determine the location of the object that generated an event, you could determine that location by processing a low-level event but you (probably) could not determine that location by processing a semantic event (never say never unless you want some programming genius to prove you wrong).

Regardless of the ability to access the object that generated the event, the name of that object is readily available to the event handlers of both low-level and semantic events.

In both cases, the name of the object is encapsulated in the event object passed as a parameter and can be extracted or tested using methods of the String class. Often knowing the name of the object is sufficient to accomplish the desired result.

Sample Program for Low-Level Events

The following program illustrates some of the capability of low-level events.

A Button object and a TextField object are placed at the top and bottom of a Frame object.

A MouseListener object is instantiated and registered to monitor for low-level mousePressed() events on all three objects.

Whenever a mousePressed() event occurs, the Listener object obtains and displays several pieces of information about the object that generated the event.

Although this demonstration program only obtains and displays information as a result of mousePressed() events, all of the methods of the Component class are available for use at that point. Thus the code in the event handler method could also modify some of the attributes of the object that generated the event.

Finally, a WindowListener object is instantiated and registered to terminate the program when the user closes the Frame object.

Additional information about the program is contained in the comments.
 
/*File Event13.java Copyright 1997, R.G.Baldwin
Revised 03/09/98 to make it fit the page better.

This program is designed to be compiled and run 
under JDK 1.1

The program demonstrates the object-manipulation capability
of low-level events.

A Button object and a TextField object are placed in a 
Frame object.

A MouseListener object is instantiated and registered to 
monitor for low-level mousePressed() events on all three 
objects.  Whenever a mousePressed() event occurs, the 
Listener object obtains and displays several pieces of 
information about the object that generated the event. 
Although this demonstration program only obtains and 
displays information as a result of mousePressed() events,
all of the methods of the Component class are available for
use at that point.  Thus the code in the event handler 
method could also modify some of the attributes of the 
object that generated the event.

Finally, a WindowListener object is instantiated and 
registered to terminate the program when the user closes 
the Frame object.

Starting the program and then clicking successively on the 
Button, the TextField, and the interior of the Frame 
produces the following output.

Name = Button1
Parent's name = Frame
Location = java.awt.Point[x=4,y=23]
Minimum Size = java.awt.Dimension[width=54,height=21]
Size = java.awt.Dimension[width=192,height=21]

Name = TextField1
Parent's name = Frame
Location = java.awt.Point[x=4,y=275]
Minimum Size = java.awt.Dimension[width=104,height=21]
Size = java.awt.Dimension[width=192,height=21]

Name = Frame
No parent name available at this level
Location = java.awt.Point[x=0,y=0]
Minimum Size = java.awt.Dimension[width=112,height=69]
Size = java.awt.Dimension[width=200,height=300]


These results were produced using JDK 1.1.3, under Win95.
**********************************************************/

import java.awt.*;
import java.awt.event.*;

public class Event13 {
  public static void main(String[] args){
    //instantiate a Graphical User Interface object
    GUI gui = new GUI();
  }//end main
}//end class Event13
//=======================================================//

class GUI {
  public GUI(){//constructor
    //Create a visual TextField object 
    TextField myTextField = new TextField("Initial String");
    myTextField.setName("TextField1");

    //Create a visual Button object
    Button myButton = new Button("Click me");
    myButton.setName("Button1");
  
    //Create a visual Frame object
    Frame myFrame = new Frame();
    myFrame.setSize(200,300);
    myFrame.setTitle("Copyright 1997, R.G.Baldwin");
    myFrame.setName("Frame");
    
    //Add the Button and the TextField to the Frame object
    myFrame.add("North",myButton);
    myFrame.add("South",myTextField);
    myFrame.setVisible(true);
   
    //Instantiate and register a MouseListener object which
    // will process mouse events on the Frame object, the 
    // Button object, and the TextField object.
    MouseProc mouseProcCmd = new MouseProc();
    myFrame.addMouseListener(mouseProcCmd);
    myTextField.addMouseListener(mouseProcCmd);
    myButton.addMouseListener(mouseProcCmd);

    //Instantiate and register a Listener object which will
    // terminate the program when the user closes the 
    // Frame object
    WProc1 winProcCmd1 = new WProc1();
    myFrame.addWindowListener(winProcCmd1);
  }//end constructor
}//end class GUI definition
//=======================================================//

//Low-level event monitor.
// This listener class monitors for low-level 
// mousePressed() events. Whenever a mousePressed() event
// occurs, the event handler obtains and displays several
// pieces of information about the object that generated
// the event. 

class MouseProc extends MouseAdapter{
  public void mousePressed(MouseEvent e){
    System.out.println(
                   "Name = " + e.getComponent().getName());
    try{
      System.out.println("Parent's name = " + 
                   e.getComponent().getParent().getName());
    }catch(NullPointerException exception){
      System.out.println(
                 "No parent name available at this level");
    }//end try/catch  
    System.out.println("Location = " + 
                e.getComponent().getLocation().toString());
    System.out.println("Minimum Size = " + 
             e.getComponent().getMinimumSize().toString());
    System.out.println("Size = " + 
                    e.getComponent().getSize().toString());
    System.out.println();//blank line    
  }//end mousePressed()
}//end class MouseProc
//=======================================================//

//The following listener class is used to terminate the 
// program when the user closes the Frame object.
class WProc1 extends WindowAdapter{
  public void windowClosing(WindowEvent e){
    System.exit(0);
  }//end windowClosing()
}//end class WProc1
//=======================================================//

Sample Program for Low-Level and Semantic Events

The next sample program provides both low-level and semantic event handling for the same three components as in the previous sample program.

As before, a Button object and a TextField object are placed at the top and bottom respectively of a Frame object.

Semantic event handling is provided for Action events. Low-level event handling is provided on the same components for mousePressed() events and Focus events. (Note that prior to 3/2/97, this section erroneously referred to Focus events as Semantic events.)

Focus Events

In Java, a component has the focus when it can accept keyboard input. There are a variety of ways by which the focus can move from one component to another. Whenever it moves, one component generates a focusLost() event and the other component generates a focusGained() event.

There are also some issues involving temporary and permanent changes in focus which aren't discussed here, but can be found in the JDK 1.1 documentation.

On the basis of the above description, you should see that there are many different types of components that can generate a focus event. Any component that can gain the focus can generate such an event.

There are some components such as Button objects and TextField objects that automatically gain the focus when they are clicked on by the mouse. There are other components such as Label objects that do not automatically gain the focus when they are clicked on by the mouse. However, even these components can gain the focus by requesting it. We will investigate this in more detail in a subsequent lesson.

Action Events

An action event can also be generated by many different types of components. For example, clicking a button or pressing the Enter key while a TextField object has the focus will generate an action event. The terminology derives from the notion that those user actions which generate action events are messages to the program to take the specific action indicated by the nature of the component.

For example, if a button is labeled Exit and it is clicked by the user, that means that the user is expecting an action that can be interpreted as Exit in that context.

ActionListener Object

In this program an ActionListener object is instantiated and registered to monitor for semantic actionPerformed() events on the Button and the TextField.

When an actionPerformed() event is generated, certain information regarding the event is encapsulated into an object that is passed to the actionPerformed() method of the Listener object. This information includes what the JDK 1.1 documentation refers to as a command name. This information can be accessed by the code in the method by invoking the getActionCommand() method on the object. In this program, the command name is accessed and displayed on the screen.

As it turns out, the "command name" associated with a Button is simply the text, caption, or label on the button (whatever you choose to call it). The "command name" associated with a TextField is the current text content of the TextField object.

This information would have different uses for different components in different situations. For example, it might be used to distinguish among several buttons if the captions on the buttons were not allowed to change during the execution of the program. It might be used to extract user input from a TextField object.

The object of type ActionEvent passed to the actionPerformed() method also includes the name of the component which can be used in a conditional test to identify the component that generated the event. One way to do this is through use of the the indexOf() method of the String class to determine if a given component name is included in a specific object.

In this program, each time the actionPerformed() method is invoked, code in the body of the method uses the indexOf() method to identify the component that generated the event and displays a message identifying that component.

FocusListener Object

A FocusListener object is instantiated and registered to monitor for low-level focusGained() and focusLost() events on the Button and the TextField. (Note that prior to 3/2/97, this section erroneously referred to the two focus events as semantic events.)

Whenever a focusGained() event occurs, a message is displayed identifying the object which gained the focus.

Likewise, whenever a focusLost() event occurs, a message is displayed identifying the object that lost the focus.

The object that gained or lost the focus is identified by performing conditional tests on the FocusEvent object passed in as a parameter in the same manner that the ActionEvent object is used for action events.

MouseListener Object

A MouseListener object is instantiated and registered to monitor for low-level mousePressed() events on all three objects. (Note that there are numerous other low-level mouse events that could be monitored but they were omitted in for the sake of simplicity.)

The MouseListener object differentiates among the three objects (Frame, Button, and TextField) on the basis of the component name assigned to each object when it is instantiated.

At this point, it would probably be worthwhile to point out that JDK 1.1 Beta 3 does not require the programmer to assign unique names to components when they are instantiated. Assigned component names can be duplicated among components. (I wonder if this is a bug? Other products such as Visual Basic and Delphi prohibit the programmer from assigning duplicate names to components.)

If the programmer does not assign names to the components when they are instantiated, they are automatically assigned by the system, and are probably unique. The names which are automatically assigned have the format frame0, frame1, frame2, etc., with the main body of the name identifying the type of component, and the digit at the end being assigned in the order in which the components are instantiated. A clever programmer should be able to find a way to obtain and make use of those names as an alternative to assigning her own names.

The approach used to obtain the component name in this program uses the indexOf() method of the String class on the MouseEvent object. (This is a slightly less complex approach than the approach used to obtain the component name for a mousePressed() event in an earlier lesson which went all the way back to the component object and invoked the getName() method.)

When a mousePressed() event occurs on any of the three visual objects, the MouseListener object displays a message identifying the object that generated the event.

WindowListener Object

Finally, a WindowListener object is instantiated and registered to terminate the program when the user closes the Frame object.

More General Comments about the Program

The screen output for a number of different user actions is shown in the comments at the beginning of the program. This material illustrates how the action, focus, and mousePressed events behave during normal user interaction with the program.

In order to maintain simplicity, the response to events in this program is limited to simply displaying information. Obviously, once control is within an event handler, significant behavior in response to an event can be programmed.

This program also illustrates the fact that a single user action can cause many different types of events to be generated.

One thing to notice in particular is that since this program was not designed to manipulate the objects that generated the low-level events, there is very little difference in the handling of low-level events and semantic events. However, the handling would have been significantly different if the capability to manipulate the objects that generated the events had been exercised (as in the previous program).

Finally, the Program

The program is fairly long, but it is also fairly repetitive.
 
/*File Event12.java Copyright 1997, R.G.Baldwin
Revised 03/09/98 to fit the page better.

This program is designed to be compiled and run 
under JDK 1.1

The program supports experimentation with low-level events
and semantic events.

A Button object and a TextField object are placed in a 
Frame object.

An ActionListener object is instantiated and registered to
monitor for semantic actionPerformed() events on the Button
and the TextField.  

An actionPerformed() event can be generated on a TextField
by pressing the Enter key while the TextField object has 
the focus.  

An actionPerformed() event can be generated by a Button by
clicking on it with the mouse.

An action event cannot be generated by a Frame object.

Whenever an actionPerformed() event occurs, the Listener
object invokes the getActionCommand() method on the object
to obtain the "command name".

The getActionCommand() method returns the "command name" 
associated with the action as a String.  The string is 
displayed.  As it turns out, the "command name" associated
with a Button is simply the text, caption, or label on the
button.  The "command name" associated with a TextField is
the current text content of the TextField object.

The ActionEvent object passed to the actionPerformed() 
method includes the name of the component which can be 
used in a conditional test based on the indexOf() method 
of the String class to identify the component that 
generated the event.

Each time the actionPerformed() method is invoked, code in
the body of the method uses the indexOf() method to 
identify the component that generated the event and 
displays a message identifying that component.

A FocusListener object is instantiated and registered to 
monitor for low-level focusGained() and focusLost() events
on the Button and the TextField.

Whenever a focusGained() event occurs, a message is 
displayed identifying the object which gained the focus.  
Likewise, whenever a focusLost() event occurs, a message is
displayed identifying the object which lost the focus.  The
object that gained or lost focus is identified by 
performing conditional tests on the FocusEvent object 
passed in as a parameter.

A MouseListener object is instantiated and registered to 
monitor for low-level mousePressed() events on all three 
objects.  The Listener object differentiates among the 
three on the basis of the component name assigned to each 
object.  The approach used to obtain the component name in
this program uses the indexOf() method of the String class
on the MouseEvent object.  This is a somewhat less complex
approach than the approach used to obtain the component 
name for a mousePressed() event in an earlier lesson.  When
a mousePressed() event occurs on any of the three visual 
objects, the Listener object displays a message identifying
the object that generated the event.

Finally, a WindowListener object is instantiated and 
registered to terminate the program when the user closes 
the Frame object.

Typical outputs from the program follow:


Clicking the mouse inside the frame but outside of both the
TextField and the Button produces the following output:

Got mousePressed event from Frame object


Clicking the mouse on the TextField when the Button has the
focus produces the following output:

Got mousePressed event from TextField1 object
Got focusLost event from Button1 object
Got focusGained event from TextField1 object


Pressing the Enter key when the TextField has the focus 
produces the following output:

e.getActionCommand() = Initial String
Got actionPerformed event from TextField1 object


Clicking the mouse on the Button when the TextField has the
focus produces the following output:

Got mousePressed event from Button1 object
Got focusLost event from TextField1 object
Got focusGained event from Button1 object
e.getActionCommand() = Click me
Got actionPerformed event from Button1 object


These results were produced using JDK 1.1.3 under Win95.
**********************************************************/

import java.awt.*;
import java.awt.event.*;

public class Event12 {
  public static void main(String[] args){
    //instantiate a Graphical User Interface object
    GUI gui = new GUI();
  }//end main
}//end class Event12
//=======================================================//

//The following class is used to instantiate a graphical 
// user interface object.
class GUI {
  public GUI(){//constructor
    //Create a visual TextField object 
    TextField myTextField = 
                           new TextField("Initial String");
    myTextField.setName("TextField1");

    //Create a visual Button object
    Button myButton = new Button("Click me");
    myButton.setName("Button1");
  
    //Create a visual Frame object and name it Frame
    Frame myFrame = new Frame();
    myFrame.setSize(200,300);
    myFrame.setTitle("Copyright 1997, R.G.Baldwin");
    myFrame.setName("Frame");
    
    //Add the Button and the TextField to the Frame object
    myFrame.add("North",myButton);
    myFrame.add("South",myTextField);
    myFrame.setVisible(true);

    //Instantiate and register an ActionListener object
    // which will monitor for action events on the
    // TextField and the Button.    
    ActionProc actionProcCmd = new ActionProc();
    myTextField.addActionListener(actionProcCmd);
    myButton.addActionListener(actionProcCmd);

    //Instantiate and register a FocusListener object which
    // will monitor for focus events on the TextField and
    // the Button.
    FocusProc focusProcCmd = new FocusProc();
    myTextField.addFocusListener(focusProcCmd);
    myButton.addFocusListener(focusProcCmd);  
    
    //Instantiate and register a MouseListener object which
    // will process mouse events on the Frame object, the
    // Button object, or the TextField object.
    MouseProc mouseProcCmd = new MouseProc();
    myFrame.addMouseListener(mouseProcCmd);
    myTextField.addMouseListener(mouseProcCmd);
    myButton.addMouseListener(mouseProcCmd);

    //Instantiate and register a Listener object which will
    // terminate the program when the user closes the Frame
    // object
    WProc1 winProcCmd1 = new WProc1();
    myFrame.addWindowListener(winProcCmd1);
  }//end constructor
}//end class GUI definition
//=======================================================//

//Semantic event monitor.
// This ActionListener class is used to instantiate a
// Listener object that monitors for action events on the
// TextField and the Button.  Whenever an actionPerformed()
// event occurs, it displays the ActionCommand and the
// identification of the component that generated the
// event. The listener object distinguishes between the
// components on the basis of their component names which
// are embedded in the object passed in as a parameter
// when an event occurs.

class ActionProc implements ActionListener{
  public void actionPerformed(ActionEvent e){
    System.out.println("e.getActionCommand() = " + 
                                     e.getActionCommand());
    
    if( e.toString().indexOf("on TextField1") != -1 ){
      System.out.println(
       "Got actionPerformed event from TextField1 object");
    }//end if
    
    if( e.toString().indexOf("on Button1") != -1 ){
      System.out.println(
          "Got actionPerformed event from Button1 object");
    }//end if
  }//end actionPerformed()
}//end class ActionProc
//=======================================================//

//Semantic event monitor.
// This FocusListener class is used to instantiate a
// Listener object that monitors for focus events on the
// TextField and the Button.  Whenever a focusLost() or 
// focusGained() event occurs, it displays the 
// identification of the component that generated the
// event.  The listener object distinguishes between the
// components on the basis of their component names which
// are embedded in the object passed in as a parameter when
// an event occurs.

class FocusProc implements FocusListener{
  public void focusGained(FocusEvent e){
    if( e.toString().indexOf("on TextField1") != -1 ){
      System.out.println(
           "Got focusGained event from TextField1 object");
    }//end if
    
    if( e.toString().indexOf("on Button1") != -1 ){
      System.out.println(
              "Got focusGained event from Button1 object");
    }//end if    
  }//end focusGained()

  public void focusLost(FocusEvent e){
    if( e.toString().indexOf("on TextField1") != -1 ){
      System.out.println(
             "Got focusLost event from TextField1 object");
    }//end if
    if( e.toString().indexOf("on Button1") != -1 ){
      System.out.println(
                "Got focusLost event from Button1 object");
    }//end if
  }//end focusLost()
}//end class FocusProc
//=======================================================//

//Low-level event monitor.
// This listener class monitors for mouse presses and 
// displays a message when a mousePressed() event occurs on
// the Frame object, the Button object, or the TextField
// object.  The message identifies the component that 
// generated the event. The listener object distinguishes
// between the components on the basis of their component
// names which are embedded in the object passed in as a
// parameter when an event occurs.

class MouseProc extends MouseAdapter{
  public void mousePressed(MouseEvent e){
    if( e.toString().indexOf("on Frame") != -1 ){
      System.out.println(
               "Got mousePressed event from Frame object");
    }//end if

    if( e.toString().indexOf("on TextField1") != -1 ){    
      System.out.println(
          "Got mousePressed event from TextField1 object");
    }//end if

    if( e.toString().indexOf("on Button1") != -1 ){    
      System.out.println(
             "Got mousePressed event from Button1 object");
    }//end if
  }//end mousePressed()
}//end class MouseProc
//=======================================================//

//The following listener is used to display a message and
// terminate the program when the user closes the Frame
// object.
class WProc1 extends WindowAdapter{
  public void windowClosing(WindowEvent e){
    System.exit(0);
  }//end windowClosing()
}//end class WProc1
//=======================================================//

Review

Q - Write a Java application that originally displays a Frame object containing a Button object at the top and a TextField object at the bottom. Cause the TextField to have red letters on a yellow background.

When you click on the TextField object, it disappears. When you click on the Button object, the TextField object reappears.

Use only low-level events.

When you click on the close button in the upper right-hand corner of the Frame object, the program terminates and control is properly returned to the operating system.

A - See program below.
 
/*From lesson 84
Copyright 1997, R.G.Baldwin

Without viewing the following solution, write a Java
application that originally displays a Frame object
containing a button at the top and a TextField object
at the bottom.

Cause the TextField to have red letters on a yellow
background.

When you click on the TextField object, it disappears.
When you click on the Button object, the TextField object
reappears.
Use only low level events.

When you click on the close button in the upper right-hand
corner of the Frame object, the program terminates and
control is properly returned to the operating system.
//=========================================================
*/

import java.awt.*;
import java.awt.event.*;

public class SampProg200 {
  public static void main(String[] args){
    GUI gui = new GUI();
  }//end main
}//end class SampProg200
//=========================================================

class GUI {
  public GUI(){//constructor
    //Create a visual TextField object 
    TextField myTextField = new TextField("Initial String");
    myTextField.setName("TextField1");
    myTextField.setBackground(Color.yellow);
    myTextField.setForeground(Color.red);

    //Create a visual Button object
    Button myButton = new Button("Click me");
    myButton.setName("Button1");
  
    //Create a visual Frame object
    Frame myFrame = new Frame();
    myFrame.setSize(300,100);
    myFrame.setTitle("Copyright 1997, R.G.Baldwin");
    
    //Add the Button and the TextField to the Frame object
    myFrame.add("North",myButton);
    myFrame.add("South",myTextField);
    myFrame.setVisible(true);
   
    //Instantiate and register a MouseListener object which
    // will process mouse events on the Button object, and 
    // the TextField object.
    MouseProc mouseProcCmd = new MouseProc(
      myButton,myTextField);
    myTextField.addMouseListener(mouseProcCmd);
    myButton.addMouseListener(mouseProcCmd);

    //Instantiate and register a Listener object which will
    // terminate the program when the user closes the 
    // Frame object
    myFrame.addWindowListener(new WProc1());
  }//end constructor
}//end class GUI definition
//=========================================================

//Low-level event monitor.
// This listener class monitors for low-level mousePressed()
// events. Whenever a mousePressed() event occurs, the 
// event handler determines which object was the source of
// the event and takes the appropriate action.

class MouseProc extends MouseAdapter{
  Button refToButton = null;
  TextField refToTextField = null;
  String refToButtonName = null;
  String refToTextFieldName = null;
  
  public MouseProc(//constructor
        Button inRefToButton, TextField inRefToTextField){
    refToButton = inRefToButton;
    refToTextField = inRefToTextField;
    refToButtonName = inRefToButton.getName();
    refToTextFieldName = inRefToTextField.getName();
  }//end constructor
  
  public void mousePressed(MouseEvent e){
    if(e.getComponent().getName().compareTo(
                                   refToTextFieldName) == 0)
      refToTextField.setVisible(false);
    if(e.getComponent().getName().compareTo(
                                      refToButtonName) == 0)
      refToTextField.setVisible(true);
  }//end mousePressed()
}//end class MouseProc
//========================================================

//The following listener class is used to terminate the 
// program when the user closes the Frame object.
class WProc1 extends WindowAdapter{
  public void windowClosing(WindowEvent e){
    System.exit(0);
  }//end windowClosing()
}//end class WProc1
//========================================================
.

Q - Write a Java application that originally displays a Frame object containing a Button object at the top and a TextField object at the bottom. Cause the TextField to have red letters on a yellow background.

When you click on the TextField object, it disappears. When you click on the Button object, the TextField object reappears.

Use a mixture of low-level and semantic events.

When you click on the close button in the upper right-hand corner of the Frame object, the program terminates and control is properly returned to the operating system.

A - See program below.
 
/*From lesson 84
Copyright 1997, R.G.Baldwin
*/

import java.awt.*;
import java.awt.event.*;

public class SampProg201 {
  public static void main(String[] args){
    GUI gui = new GUI();
  }//end main
}//end class SampProg201
//=========================================================

class GUI {
  public GUI(){//constructor
    //Create a visual TextField object 
    TextField myTxtField = new TextField("Initial String");
    myTxtField.setBackground(Color.yellow);
    myTxtField.setForeground(Color.red);

    //Create a visual Button object
    Button myButton = new Button("Click me");
  
    //Create a visual Frame object
    Frame myFrame = new Frame();
    myFrame.setSize(300,100);
    myFrame.setTitle("Copyright 1997, R.G.Baldwin");
    
    //Add the Button and the TextField to the Frame object
    myFrame.add("North",myButton);
    myFrame.add("South",myTxtField);
    myFrame.setVisible(true);
   
    //Instantiate and register a MouseListener object which
    // will process mouse events on the TextField object.
    myTxtField.addMouseListener(new MouseProc(myTxtField));
    
    //Instantiate and register an ActionListener object 
    // which will process action events on the Button 
    // object.
    myButton.addActionListener(
      new MyActionProcessor(myTxtField));

    //Instantiate and register a Listener object which will
    // terminate the program when the user closes the 
    // Frame object
    myFrame.addWindowListener(new WProc1());
  }//end constructor
}//end class GUI definition
//=========================================================

//Low-level event monitor.
// This listener class monitors for low-level 
// mousePressed() events. 
class MouseProc extends MouseAdapter{
  TextField refToTextField = null;

  public MouseProc(TextField inRefToTextField){
    refToTextField = inRefToTextField;  
  }//end constructor
  
  public void mousePressed(MouseEvent e){
    refToTextField.setVisible(false);
  }//end mousePressed()
}//end class MouseProc
//=========================================================
//Semantic event monitor.
// This listener class monitors for semantic action events.

class MyActionProcessor implements ActionListener{
  TextField refToTextField = null;
  
  MyActionProcessor(TextField inRefToTextField){//construct
    refToTextField = inRefToTextField;
  }//end constructor

  public void actionPerformed(ActionEvent e){
    refToTextField.setVisible(true);   
  }//end overridden actionPerformed method

}//end class MyActionProcessor


//=========================================================

//The following listener class is used to terminate the 
// program when the user closes the Frame object.
class WProc1 extends WindowAdapter{
  public void windowClosing(WindowEvent e){
    System.exit(0);
  }//end windowClosing()
}//end class WProc1
//=========================================================
-end-