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

Event Handling in JDK 1.0.2, Overriding Convenience Event Handlers

Java Programming, Lecture Notes # 66, Revised 8/3/97.

Note: Because the event model for JDK 1.0 is rapidly becoming obsolete, material on the JDK 1.0 event model will not be covered in classroom lectures or examinations in Professor Baldwin's CIS 2103K (Intermediate Java Programming) classes at Austin Community College.


Introduction

To the best of my ability, the material in this lesson conforms to the Java API Documentation 1.0.2.

The beta version of JDK 1.1 is available for testing at this time, and Sun has announced that it will contain important changes to the Abstract Windows Toolkit, including changes to the implementation of events and event handling.

When JDK 1.1 is released and hard information regarding those changes becomes available, this lesson will be supplemented with a new lesson describing events and event handling under JDK 1.1.

A previous lesson taught you how to override the handleEvent() method of the Component class to respond to events.

You can handle any event by overriding the handleEvent() method because the handleEvent() method is invoked by the runtime system whenever any event occurs.

When you override the handleEvent method, all of the information available about the event is encapsulated into an object of the Event class and passed in as a parameter. Therefore, all the information is available for you to use in your handling of the event. However, in order to access that information, you must crack open the object and access the data in the individual fields of the object.

The earlier lesson also mentioned that, in addition to the handleEvent() method, the Component class provides a number of convenience methods which can sometimes be used to handle certain events in a more-convenient manner.

These convenience methods exist in the Component class as empty shells which you can override in your program.

The default behavior of handleEvent() is to

Therefore, if you override one or more of the convenience methods, your overridden method will be invoked automatically without the requirement for you to deal with the id field of the Event object.

In addition, certain event-specific information is extracted from the Event object and passed in as parameters, often eliminating the requirement for you to deal in any way with the Event object.

For example, on mouse events, the x and y coordinates of the mouse when the event happened are passed in as parameters.

In all cases, the Event object is also passed in as a parameter in case you need to extract additional information from the object.

Convenience Event Handlers and Their Associated Event Types

The following code fragment, which shows the default behavior of handleEvent(), identifies the different convenience event handlers and their associated event types, as specified by the id field of the Event object. Please note the source of the code fragment as indicated in the comments at the beginning.

Also note that there are about fourteen other id values defined as symbolic constants in the Event class for which convenience event handlers are not provided in the default version of handleEvent(). Those event types must be handled by overriding the handleEvent() method.

For example, the sample program later in this lesson uses an event of the type WINDOW_DESTROY to terminate the program when the user closes the window. There is no convenience event handler for that type of event.


/*File Event01.txt
This is Listing 19-12 from Using Java, Special Edition
by Joseph Weber, et al.
*/
public boolean handleEvent(Event evt) { 
  switch (evt.id) { 
    case Event.MOUSE_ENTER: return mouseEnter(evt, evt.x, evt.y); 
    case Event.MOUSE_EXIT: return mouseExit(evt, evt.x, evt.y); 
    case Event.MOUSE_MOVE: return mouseMove(evt, evt.x, evt.y); 
    case Event.MOUSE_DOWN: return mouseDown(evt, evt.x, evt.y); 
    case Event.MOUSE_DRAG: return mouseDrag(evt, evt.x, evt.y); 
    case Event.MOUSE_UP: return mouseUp(evt, evt.x, evt.y); 
    case Event.KEY_PRESS: 
    case Event.KEY_ACTION: return keyDown(evt, evt.key); 
    case Event.KEY_RELEASE: 
    case Event.KEY_ACTION_RELEASE: return keyUp(evt, evt.key); 

    case Event.ACTION_EVENT: return action(evt, evt.arg); 
    case Event.GOT_FOCUS: return gotFocus(evt, evt.arg); 
    case Event.LOST_FOCUS: return lostFocus(evt, evt.arg); 
  } //end switch
  return false; 
}

Sample Program

The following sample program illustrates the use of a convenience event handler by overriding the mouseDown() event.

Note that this program also includes an overridden version of the handleEvent() method to handle the event which is generated when the user closes the window (event type WINDOW_DESTROY). This event handler terminates the program. There is no convenience handler available to handle that event.

This discussion will concentrate on event-related issues and will defer GUI-related issues to a subsequent lesson.

You will note that this program is very similar to a program named Event01.java in a previous lesson. However,

The overridden mouseDown() event handler is highlighted in boldface in the following listing.

As you can see, the information needed to handle the event is "conveniently" passed in as parameters, and there is no requirement for the overridden method to crack open the Event object to obtain additional information (in this case). Therefore, it might be viewed as being more convenient than overriding handleEvent().

The code in the overridden version of mouseDown() performs essentially the same actions as the corresponding code in the earlier program. The remaining code in the two programs is essentially the same as well.

Since the operation of the similar program was discussed in detail in a previous lesson, there should be no need for a detailed discussion in this lesson.


/*File Event02.java Copyright 1997, R.G.Baldwin
Illustrates overriding of a "convenience" event handler by 
overriding the mouseDown() method of the Component class.
Displays the coordinates of mouse clicks in a window.

Also overrides handleEvent() to respond to WINDOW_DESTROY 
to terminate the program when the user clicks the close box.
*/

import java.awt.*;

//Make the controlling class extend the Frame class
// to produce a graphic window.
public class Event02 extends Frame{
  String msg = ""; //save message for display here
  int clickX = 0, clickY = 0;//save coordinates for display here

  //Create and size the window
  public static void main(String[] args){
    Event02 displayWindow = new Event02(); //instantiate obj of this type
    displayWindow.resize(300,200);//set window size
    displayWindow.setTitle("Copyright 1997, R.G.Baldwin");
    displayWindow.show();//display the window
  }//end main

  //Event handler overrides  handleEvent() 
  // method in Component class to close window.
  public boolean handleEvent(Event evntObj){
    if(evntObj.id == Event.WINDOW_DESTROY) System.exit(0);
    return super.handleEvent(evntObj);                      
  }//end handleEvent()

  //Override the mouseDown() method of Component class
  public boolean mouseDown(Event  evt, int  x, int  y){
    clickX = x; //save mouse coordinates
    clickY = y;
    msg = "" + x + ", " + y; //construct message for display
    repaint(); //force a repaint of the window
  return true;
  }//end overridden mouseDown()

  //Override paint method to repaint the window
  public void paint(Graphics g){
    g.drawString(msg, clickX, clickY);
  }//end paint()
  
}//end class Event02

Summary

The primary benefit of overriding the convenience event handlers is that in some cases, it is not necessary to crack open the Event object to obtain information in order to handle the event. This is true for those cases where the default version of handleEvent() obtains and passes in all the information necessary to properly handle the event.

There are also many situations where this is not the case, and it is still necessary to crack open the Event object within the overridden convenience handler to properly handle the event.

In those cases, you will have to be the judge insofar as "convenience" is concerned.

Remember, if you want to, you can totally ignore the existence of the convenience event handlers and handle all events by overriding the handleEvent() method.

-end-