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.
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.
Most user actions associated with a GUI component are probably handled by the container of the component.
Among other reasons, that is the place where it is possible to override the event-handling methods of the Component class in order to provide the desired functionality.
If we want a component to be able to handle its own events, (as opposed to having its events handled by its container) we can extend the class for that component, thereby creating a class for a custom component having all the attributes of the original component.
Then, instead of adding an object of the original component type to our container, we instantiate and add an object of the new custom type.
Having done that, we can write event handlers for the custom component class to handle events at the component level rather than at the container level.
As you may recall, a user action involving a GUI component causes the operating system to send a message to the Java runtime system.
The runtime system
One of the duties of the postEvent() method is to handle the task of passing the Event object up the component hierarchy until the handleEvent() method at some level returns true indicating that the event has been handled.
The default handleEvent() method for the component probably returns false, signaling the postEvent() method to invoke the handleEvent() method for the container of the component.
It is at the container level, rather than the component level, where the event normally gets handled, if it gets handled at all. (Many random events never get handled, but simply propagate upward until they are discarded.)
More than likely, you will design the class for the container. In so doing, you can override the handleEvent() method to
You will probably handle those events in which you are interested, and return false for those events that don't interest you, again signaling the postEvent() method to pass the event up to the next higher level container in the hierarchy.
One difficulty in doing this is determining in advance whether or not the runtime system will create an Event object and invoke the postEvent() method on the custom component for a specific user action.
The documentation is sketchy at best, and most of the currently published books gloss over the subject.
To give us a concrete example to work with, let's consider the following question:
As of February 1997, I am of the opinion that Java in a Nutshell by David Flanagan is one of the best and most informative Java books available.
On page 183, while discussing a chart that follows in his text, Flanagan states:
The chart lists
Since the TextField class extends the TextComponent class which extends the Component class, one would be led to believe that a TextField object should receive all of the mouse events listed above as well as the GOT_FOCUS event.
Alas, such does not seem to be the case as we will see later in our sample program.
When you click the mouse in a TextField object (which involves all of the mouse events listed above except MOUSE_DRAG) the TextField object receives the focus, as evidenced by the blinking I-beam cursor. As a result, one might expect that the object would receive a host of mouse events plus a GOT_FOCUS event.
The sample program for this lesson accomplishes two purposes.
First, it teaches you how to create smart components which can respond to events posted by the runtime system for those components.
Second, it teaches you how to write a simple program by which you can experimentally determine whether or not the runtime system posts an Event object for a specific user action with respect to a specific GUI object of interest.
We will use the sample program in an attempt to answer the question posed above. We will learn some other interesting things in the process as well.
/*File Event05.java Copyright 1997, R.G.Baldwin Primarily designed to illustrate smart components, and a method for determining the events received by a component. Closing the frame terminates the program. */ import java.awt.*; //Define a custom TextField class that can respond to events. // Note that this class extends TextField. class TF extends TextField{ TF(String inString){setText(inString);}//end constructor //The following event handler method handles events at the // component level as opposed to the container level. public boolean handleEvent(Event evObj){ System.out.println(evObj.toString());//display the Event object switch(evObj.id){//display type of event case Event.KEY_PRESS : setText(getText() + "," + "KEY_PRESS");break; case Event.KEY_RELEASE : setText(getText() + "," + "KEY_RELEASE");break; case Event.ACTION_EVENT : setText(getText() + "," + "ACTION_EVENT");break; default : //catch and display all other event types here setText(getText() + "," + evObj.id); }//end switch return super.handleEvent(evObj); }//end handleEvent() in class TF }//end class TF //=================================================================== //Make the controlling class extend the Frame class to provide // a container for the custom TextField component public class Event05 extends Frame{ public Event05(){//constructor TF myTextField = new TF("TF");//instantiate custom TextField object add ("Center",myTextField);//add it to the frame myTextField.setEditable(false);//make it non-editable //Dress the frame up a little setTitle("Copyright 1997, R.G.Baldwin"); resize(300,200);//set frame size }//end constructor //Create and show the frame object public static void main(String[] args){ Event05 displayWindow = new Event05(); //instantiate obj of this type displayWindow.show();//display the frame }//end main //Override handleEvent() method relative to the frame for program termination public boolean handleEvent(Event evObj){ //Terminate program if user closes the window if(evObj.id == Event.WINDOW_DESTROY) System.exit(0); //Always finish by invoking the handleEvent method in the superclass return super.handleEvent(evObj); }//end handleEvent() }//end class Event05In this program, a smart component in the form of a custom TextField is defined by extending the TextField class. An object of this type is instantiated and placed in a frame which becomes the container for the component.
Because the class definition for the custom component includes an overridden version of handleEvent(), this custom component has the ability to handle its own events rather than simply passing them up to the Frame container for processing.
Due to the design of the overridden handleEvent() method, clicking the custom TextField object to give it the focus at runtime and then pressing a key displays information in the TextField and also displays information on the console screen.
The overridden handleEvent() method is repeated below for convenient viewing.
public boolean handleEvent(Event evObj){ System.out.println(evObj.toString());//display the Event object switch(evObj.id){//display type of event case Event.KEY_PRESS : setText(getText() + "," + "KEY_PRESS");break; case Event.KEY_RELEASE : setText(getText() + "," + "KEY_RELEASE");break; case Event.ACTION_EVENT : setText(getText() + "," + "ACTION_EVENT");break; default : //catch and display all other event types here setText(getText() + "," + evObj.id); }//end switch return super.handleEvent(evObj); }//end handleEvent() in class TFAs you can see, the information displayed on the console screen is the toString() conversion of the Event object delivered by the runtime system to the postEvent() method and ultimately to the handleEvent() method.
For example, pressing the return key when the TextField object has the focus causes the following information to be displayed on the console (only the beginning portion of each line is shown):
java.awt.Event[id=401,x=0,y=0,key=10,target=TF[4,175,292x21,text=TF,... java.awt.Event[id=1001,x=0,y=0,target=TF[4,175,292x21,text=TF,... java.awt.Event[id=402,x=0,y=0,key=10,target=TF[4,175,292x21,text=TF,...
The integer values
id = 401, 1001, and 402
in the above output are respectively the id-field values for
The following information is displayed in the TextField when the return key is pressed.
Note that the "TF" is placed at the beginning when the custom TextField object is instantiated. The additional text is placed there by code in the handleEvent() method with each new event simply adding more text onto the end of the existing text string.
TF,KEY_PRESS,ACTION_EVENT,KEY_RELEASE
In other words, pressing the return key once causes three separate Event objects to be delivered to the handleEvent() method for the custom TextField object:
java.awt.Event[id=401,x=0,y=0,key=97,target=TF[4,23,292x173,text=TF,... java.awt.Event[id=402,x=0,y=0,key=97,target=TF[4,23,292x173,text=TF,...
and causes the following to be displayed in the custom TextField.
TF,KEY_PRESS,KEY_RELEASE
In this case, only two events are delivered to the handleEvent() method:
java.awt.Event[id=403,x=0,y=0,key=1008,target=TF[4,23,292x173,text=TF,... java.awt.Event[id=404,x=0,y=0,key=1008,target=TF[4,23,292x173,text=TF,...
and produces the following in the custom TextField:
TF,403,404
In this case, 403 and 404 are the respective event values of the id field in the Event object for
So the answer to the first part of the question is that apparently the runtime system does not create and pass Event objects when the mouse enters a TextField or clicks in a TextField. A TextField object appears to be immune to mouse events.
Clicking the mouse on the custom TextField object gave it the focus but did not cause an event with an id field containing GOT_FOCUS to be delivered to the postEvent() and handleEvent() methods.
Therefore, the answer to the second part of the question appears to be that the runtime system does not create and pass an Event object whenever a TextField gains the focus.
So, we have used our sample program to experimentally determine the answer to the original question.
Not related to the question, but also interesting was the fact that some keys such as CapsLock, Shift, and Ctrl did not produce a KEY_PRESS event on the downstroke, but did produce a KEY_RELEASE event on the upstroke.
The Alt key did not produce any event unless another key was pressed while the Alt key was being held down, in which case it only produced a KEY_RELEASE event on the upstroke of the Alt key. In this case, pressing and releasing the other key while holding the Alt key down did not produce an event independent of the event produced by releasing the Alt key.
These results were produced using Java JDK 1.0.2 running under Windows 95.
-end-