Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Last month I demonstrated how to assemble a graphical user interface from components provided by the Java class library's abstract windowing toolkit. After assembling a few such interfaces, I spoke briefly about the topic of event handling, but I stopped short of a full description of event handling as implemented by the AWT. This month, we pick up where we left off.
In the distant past, a program that wanted to know what the user was doing had to actively collect such information itself. In practice this meant that after a program initialized itself, it entered a big loop in which it repeatedly looked to see if the user was doing anything interesting (for example, pressing a button, touching a key, moving a slider, moving the mouse) and then took the appropriate action. This technique is known as polling.
Polling gets the job done but tends to be unwieldy when used in modern-day applications for two related reasons: First, the use of polling tends to push all event-handling code into one location (inside the big loop); second, the resulting interactions within the big loop tend to be complex. In addition, polling requires a program to sit in a loop, consuming CPU cycles, while waiting for the user to do something -- a serious waste of a valuable resource.
The AWT solved these problems by embracing a different paradigm, one that underlies all modern window systems: event-driven programming. Within the AWT, all user actions belong to an abstract set of things called events. An event describes, in sufficient detail, a particular user action. Rather than the program actively collecting user-generated events, the Java run time notifies the program when an interesting event occurs. Programs that handle user interaction in this fashion are said to be event driven.
The Event class is the primary player in the event game. It attempts to capture the fundamental characteristics of all user-generated events. Table 1 lists the public data members provided by class Event.
|Object||target||A reference to the component that initially received the event.|
|long||when||The point in time at which the event occurred.|
|int||id||The event type (see section Event Types for more information).|
|int||x||The x coordinate at which the action occurred relative to the component that is currently processing the event. For a given event, the x coordinate will change in value as the event moves up the component hierarchy. The origin of the coordinate plane is in the component's upper-left-hand corner.|
|int||y||The y coordinate at which the action occurred relative to the component that is currently processing the event. For a given event, the y coordinate will change in value as the event moves up the component hierarchy. The origin of the coordinate plane is in the component's upper-left-hand corner.|
|int||key||For keyboard events, the keycode of the key just pressed. Its value will typically be the Unicode value of the character the key represents. Other possibilities include values for the special keys HOME, END, F1, F2, and so on.|
|int||modifiers||An arithmetically or'd combination of the values SHIFT_MASK, CTRL_MASK, META_MASK, and ALT_MASK. Its value represents the state of the shift, control, meta, and alt keys, respectively.|
|int||clickCount||The number of consecutive mouse clicks. This data member is only significant in MOUSE_DOWN events.|
|Object||arg||An event-dependent argument. For Button objects, this object is a String object that contains the textural label of the button.|
As I will explain in the section titled Event dispatch and propagation, an instance of class Event is typically created by the Java run-time system. It is possible, however, for a program to create
and send events to components via their
As mentioned above, the Event class is a model of a user interface event. Events naturally fall into categories based on the
type of the event (the event type is indicated by the
id data member). Table 2 lists all of the events defined by the AWT, sorted by category.
It can be instructive to see event generation in action. The button in Figure 1, when pressed, creates an event browser that displays event information about the events the browser receives. The source code for the event browser is available here.
Figure 1: Event generation in action
Consider the applet in Figure 2. It consists of two instances of the Button class, embedded within an instance of the Panel class. This instance of the Panel class is itself embedded within another instance of the Panel class. The latter instance of the Panel class sits below an instance of class TextArea, and both instances are embedded within an instance of the Applet class. Figure 3 presents the elements that make up this applet laid out as a tree, with the TextArea and Button instances as the leaves, and an Applet instance as the root. (For more information about the hierarchical layout of components in a user interface, read last month's introduction to the AWT.)
Figure 2: Classes embedded within classes
Figure 3: Applet elements tree (hierarchy)
When a user interacts with the applet in Figure 2, the Java run-time system creates an instance of class Event and fills its data members with information describing the action. The Java run-time system then allows the applet to handle the event. It begins with the component that initially received the event (for instance, the button that was clicked) and moves up the component tree, component by component, until it reaches the container at the top of the tree. Along the way, each component has the opportunity to ignore the event or to react to it in one (or more) of the following ways:
The Java run-time system passes event information to a component via the component's
handleEvent() method. All valid
handleEvent() methods must be of the form
public boolean handleEvent(Event e)
An event handler requires a single piece of information: a reference to the instance of the Event class containing information about the event that just occurred.
The value returned from the
handleEvent() method is important. It indicates to the Java run-time system whether or not the event has been completely handled within
the event handler. A true value indicates that the event has been handled and propagation should stop. A false value indicates
that the event has been ignored, could not be handled, or has been handled incompletely and should continue up the tree.