The Event Class

An instance of the Event class is a platform-independent representation that encapsulates the specifics of an event that happens within the Java 1.0 model. It contains everything you need to know about an event: who, what, when, where, and why the event happened. Note that the Event class is not used in the Java 1.1 event model; instead, Java 1.1 has an AWTEvent class, with subclasses for different event types.

When an event occurs, you decide whether or not to process the event. If you decide against reacting, the event passes through your program quickly without anything happening. If you decide to handle the event, you must deal with it quickly so the system can process the next event. If handling the event requires a lot of work, you should move the event-handling code into its own thread. That way, the system can process the next event while you go off and process the first. If you do not multithread your event processing, the system becomes slow and unresponsive and could lose events. A slow and unresponsive program frustrates users and may convince them to find another solution for their problems.

Variables

Event contains ten instance variables that offer all the specific information for a particular event. Instance variables

public boolean mouseDown (Event e, int x, int y) {
 System.out.println ("Coordinates: " + x + "-" + y); if (e.evt != null) postEvent (e.evt);
return true;
}
Date d = new Date (e.when); 

Constants

Numerous constants are provided with the Event class. Several designate which event happened (the why). Others are available to help in determining the function key a user pressed (the what). And yet more are available to make your life easier.

When the system generates an event, it calls a handler method for it. To deal with the event, you have to override the appropriate method. The different event type sections describe which methods you override. Key constants

These constants are set when a user presses a key. Most of them correspond to function and keypad keys; since such keys are generally used to invoke an action from the program or the system, Java calls them action keys and causes them to generate a different Event type (KEY_ACTION) from regular alphanumeric keys (KEY_PRESS).

Table 4.2 shows the constants used to represent keys and the event type that uses each constant. The values, which are all declared public static final int, appear in the key variable of the event instance. A few keys represent ASCII characters that have string equivalents such as \n. Black stars ((New)) mark the constants that are new in Java 1.1; they can be used with the 1.0 event model, provided that you are running Java 1.1. Java 1.1 events use a different set of key constants defined in the KeyEvent class.

Constants for Keys in Java 1.0
Constant Event Type Constant Event Type
HOME KEY_ACTION F9 KEY_ACTION
END KEY_ACTION F10 KEY_ACTION
PGUP KEY_ACTION F11 KEY_ACTION
PGDN KEY_ACTION F12 KEY_ACTION
UP KEY_ACTION PRINT_SCREEN(New) KEY_ACTION
DOWN KEY_ACTION SCROLL_LOCK(New) KEY_ACTION
LEFT KEY_ACTION CAPS_LOCK(New) KEY_ACTION
RIGHT KEY_ACTION NUM_LOCK(New) KEY_ACTION
F1 KEY_ACTION PAUSE(New) KEY_ACTION
F2 KEY_ACTION INSERT(New) KEY_ACTION
F3 KEY_ACTION ENTER (\n)(New) KEY_PRESS
F4 KEY_ACTION BACK_SPACE (\b)(New) KEY_PRESS
F5 KEY_ACTION TAB (\t)(New) KEY_PRESS
F6 KEY_ACTION ESCAPE(New) KEY_PRESS
F7 KEY_ACTION DELETE(New) KEY_PRESS
F8 KEY_ACTION
Modifiers

Modifiers are keys like Shift, Control, Alt, or Meta. When a user presses any key or mouse button that generates an Event, the modifiers field of the Event instance is set. You can check whether any modifier key was pressed by ANDing its constant with the modifiers field. If multiple modifier keys were down at the time the event occurred, the constants for the different modifiers are ORed together in the field.

public static final int ALT_MASK
public static final int CTRL_MASK
public static final int META_MASK
public static final int SHIFT_MASK

When reporting a mouse event, the system automatically sets the modifiers field. Since Java is advertised as supporting the single-button mouse model, all buttons generate the same mouse events, and the system uses the modifiers field to differentiate between mouse buttons. That way, a user with a one- or two-button mouse can simulate a three-button mouse by clicking on his mouse while holding down a modifier key. Table 4.3 lists the mouse modifier keys; an applet in Working With Mouse Buttons in Java 1.0 demonstrates how to differentiate between mouse buttons.

Mouse Button Modifier Keys
Mouse Button Modifier Key
Left mouse button None
Middle mouse button ALT_MASK
Right mouse button META_MASK

For example, if you have a three-button mouse, and click the right button, Java generates some kind of mouse event with the META_MASK set in the modifiers field. If you have a one-button mouse, you can generate the same event by clicking the mouse while depressing the Meta key.

NOTE:

If you have a multibutton mouse and do an Alt+right mouse or Meta+left mouse, the results are platform specific. You should get a mouse event with two masks set.Key events

The component peers deliver separate key events when a user presses and releases nearly any key. KEY_ACTION and KEY_ACTION_RELEASE are for the function and arrow keys, while KEY_PRESS and KEY_RELEASE are for the remaining control and alphanumeric keys.

NOTE:

If you want to capture arrow and keypad keys under the X Window System, make sure the key codes are set up properly, using the xmodmap command.

NOTE:

Some platforms generate events for the modifier keys by themselves, whereas other platforms require modifier keys to be pressed with another key. For example, on a Windows platform, if Ctrl+A is pressed, you would expect one KEY_PRESS and one KEY_RELEASE. However, there is a second KEY_RELEASE for the Control key. Under Motif, you get only a single KEY_RELEASE.

Window events

Window events happen only for components that are children of Window. Several of these events are available only on certain platforms. Like other event types, the id variable holds the value of the specific event instance.

Mouse events

The component peers deliver mouse events when a user presses or releases a mouse button. Events are also delivered whenever the mouse moves. In order to be platform independent, Java pretends that all mice have a single button. If you press the second or third button, Java generates a regular mouse event but sets the event's modifers field with a flag that indicates which button was pressed. If you press the left button, no modifiers flags are set. Pressing the center button sets the ALT_MASK flag; pressing the right button sets the META_MASK flag. Therefore, you can determine which mouse button was pressed by looking at the Event.modifiers attribute. Furthermore, users with a one-button or two-button mouse can generate the same events by pressing a mouse button while holding down the Alt or Meta keys.

NOTE:

Early releases of Java (1.0.2 and earlier) only propagated mouse events from Canvas and Container objects. With the 1.1 event model, the events that different components process are better defined.

Scrolling events

The peers deliver scrolling events for the Scrollbar component. The objects that have a built-in scrollbar (like List, ScrollPane, and TextArea) do not generate these events. No default methods are called for any of the scrolling events. They must be dealt with in the handleEvent() method of the Container or a subclass of the Scrollbar. You can determine which particular event occurred by checking the id variable of the event, and find out the new position of the thumb by looking at the arg variable or calling getValue() on the scrollbar. See also the description of the AdjustmentListener interface later in this chapter.

List events

Two events specific to the List class are passed along by the peers. They signify when the user has selected or deselected a specific choice in the List. It is not ordinarily necessary to capture these events, because the peers deliver the ACTION_EVENT when the user double-clicks on a specific item in the List and it is this ACTION_EVENT that triggers something to happen. However, if there is reason to do something when the user has just single-clicked on a choice, these events may be useful. An example of how they would prove useful is if you are displaying a list of filenames with the ability to preview files before loading. Single selection would preview, double-click would load, and deselect would stop previewing.

No default methods are called for any of the list events. They must be dealt with in the handleEvent() method of the Container of the List or a subclass of the List. You can determine which particular event occurred by checking the id variable of the event.

Focus events

The peers deliver focus events when a component gains (GOT_FOCUS) or loses (LOST_FOCUS) the input focus. No default methods are called for the focus events. They must be dealt with in the handleEvent() method of the Container of the component or a subclass of the component. You can determine which particular event occurred by checking the id variable of the event.

NOTE:

Early releases of Java (1.0.2 and before) did not propagate focus events on all platforms. This is fixed in release 1.1 of Java. Still, you should avoid capturing focus events if you want to write portable 1.0 code.

FileDialog events

The FileDialog events are another set of nonportable events. Ordinarily, the FileDialog events are completely dealt with by the system, and you never see them. Refer to Containers for exactly how to work with the FileDialog object. If you decide to create a generic FileDialog object, you can use these events to indicate file loading and saving. These constants would be used in the id variable of the specific event instance:

public static final int LOAD_FILE
public static final int SAVE_FILEMiscellaneous events

ACTION_EVENT is probably the event you deal with most frequently. It is generated when the user performs the desired action for a specific component type (e.g., when a user selects a button or toggles a checkbox). This constant would be found in the id variable of the specific event instance.

Event Methods

Constructors

Ordinarily, the peers deliver all your events for you. However, if you are creating your own components or want to communicate across threads, it may be necessary to create your own events. You can also create your own events to notify your component's container of application-specific occurrences. For example, if you were implementing your own tab sequencing for text fields, you could create a "next text field" event to tell your container to move to the next text field. Once you create the event, you send it through the system using the Component.postEvent() method.

Modifier methods

The modifier methods check to see if the different modifier mask values are set. They report the state of each modifier key at the moment an event occurred. It is possible for multiple masks to be set if multiple modifiers are pressed when the event occurs.

There is no altDown() method; to check whether the Alt key is pressed you must directly compare the event's modifiers against the Event.ALT_MASK constant. The metaDown() method is helpful when dealing with mouse events to see if the user pressed the right mouse button.

Miscellaneous methods

Figure 4.3: Translating an event's location relative to a component

[Graphic: Figure 4-3]

protected String paramString() {
 return super.paramString() + ",foo=" + foo;
}
java.awt.Event[id=602,x=374,y=110,target=java.awt.Scrollbar[374, 110,15x50,val=1,vis=true,min=0,max=255,vert],arg=1] 

Working With Mouse Buttons in Java 1.0

As stated earlier, the modifiers component of Event can be used to differentiate the different mouse buttons. If the user has a multibutton mouse, the modifiers field is set automatically to indicate which button was pressed. If the user does not own a multibutton mouse, he or she can press the mouse button in combination with the Alt or Meta keys to simulate a three-button mouse. Example 4.2 is a sample program called mouseEvent that displays the mouse button selected.

Example 4.2: Differentiating Mouse Buttons in Java 1.0

import java.awt.*; import java.applet.*;
public class mouseEvent extends Applet {
 String theString = "Press a Mouse Key";
public synchronized void setString (String s) {
 theString = s;
}
public synchronized String getString () {
 return theString;
}
public synchronized void paint (Graphics g) {
 g.drawString (theString, 20, 20);
}
public boolean mouseDown (Event e, int x, int y) {
 if (e.modifiers == Event.META_MASK) {
 setString ("Right Button Pressed");
}
else if (e.modifiers == Event.ALT_MASK) {
 setString ("Middle Button Pressed");
}
else {
 setString ("Left Button Pressed");
}
repaint ();
return true;
}
public boolean mouseUp (Event e, int x, int y) {
 setString ("Press a Mouse Key"); repaint ();
return true;
}
} 

Unfortunately, this technique does not always work. With certain components on some platforms, the peer captures the mouse event and does not pass it along; for example, on Windows, the display-edit menu of a TextField appears when you select the right mouse button. Be cautious about relying on multiple mouse buttons; better yet, if you want to ensure absolute portability, stick to a single button.

Comprehensive Event List

Unfortunately, there are many platform-specific differences in the way event handling works. It's not clear whether these differences are bugs or whether vendors think they are somehow improving their product by introducing portability problems. We hope that as Java matures, different platforms will gradually come into synch. Until that happens, you might want your programs to assume the lowest common denominator. If you are willing to take the risk, you can program for a specific browser or platform, but should be aware of the possibility of changes.

Appendix C, Platform-Specific Event Handling, includes a table that shows which components pass along which events by default in the most popular environments. This table was developed using an interactive program called compList, which generates a list of supported events for each component. You can find compList on this tutorial's Web site, http://www.ora.com/catalog/javawt. If you want to check the behavior of some new platform, or a newer version of one of the platforms in Appendix C, Platform-Specific Event Handling, feel free to use compList. It does require a little bit of work on your part. You have to click, toggle, type, and mouse over every object. Hopefully, as Java matures, this program will become unnecessary.