JDK 1.0.x Propagated Events

Class Event

In JDK 1.0.x, all events are represented by the Event class.

java.lang.Object
    java.awt.Event

Class Event has a number of instance variables that describe the event:

target The object that generated the event
when The timestamp for the event
id The type of the event
x The x coordinate of the event
y The y coordinate of the event
key The key code that was pressed in a key event
modifiers The state of the modifier keys
clickCount The number of consecutive mouse clicks
arg An arbitrary argument
evt The next event in the list

Some are used in every event (target, when, id), while others are specific to a particular type of event (x, y, key, clickCount)

Event Types

The java.awt.Event class contains a number of event constants, identifying a set of event types for window, keyboard, mouse and other types.

Window Events

WINDOW_DESTROY  
WINDOW_EXPOSE  
WINDOW_ICONIFY  
WINDOW_DEICONIFY  
WINDOW_MOVED  

Keyboard Events

KEY_PRESS  
KEY_RELEASE  
KEY_ACTION  
KEY_ACTION_RELEASE  

Mouse Events

MOUSE_DOWN  
MOUSE_UP  
MOUSE_MOVE  
MOUSE_ENTER  
MOUSE_EXIT  
MOUSE_DRAG  

Other Events (see later)

SCROLL_LINE_UP  
SCROLL_LINE_DOWN  
SCROLL_PAGE_UP  
SCROLL_PAGE_DOWN  
SCROLL_ABSOLUTE  
LIST_SELECT  
LIST_DESELECT  
ACTION_EVENT  
LOAD_FILE  
SAVE_FILE  
GOT_FOCUS  
LOST_FOCUS  

Event Propagation

These kinds of events are called propagated events, because, whenever such an event occurs in a component, the component's handleEvent(Event) method is invoked.

The component's handleEvent(Event) method may choose to handle the event entirely on its own, or choose to propagate the event to its container.

handleEvent() and Convenience Methods

Here is the class hierarchy for class Frame:

java.lang.Object
    java.awt.Component
        java.awt.Container
            java.awt.Window
                java.awt.Frame

As you can see, a Frame is a kind of Window, which is a kind of Container, which is a kind of Component.

Class java.awt.Component contains a handleEvent() method which makes things easier for derived classes to handle specific events:

// Implementation of Component.handleEvent()
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 keyRelease(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);
    }
    return false;	// Event not handled
}

Note the value returned from the handleEvent() method:

  • true means that the event was handled completely
  • false means that it wasn't

The Convenience Methods

boolean action(Event, Object) An action event
boolean mouseUp(Event, int, int) Mouse up
boolean mouseDown(Event, int, int) Mouse down
boolean mouseDrag(Event, int, int) Mouse drag
boolean mouseMove(Event, int, int) Mouse move
boolean mouseEnter(Event, int, int) Mouse entered component
boolean mouseExit(Event, int, int) Mouse exited component
boolean keyUp(Event, int) Key up
boolean keyDown(Event, int) Key down
boolean gotFocus(Event, Object) Component got focus
boolean lostFocus(Event, Object) Component lost focus

Your class (derived from Component) is expected to override one or more of these methods in order to handle these specific event types.

Note that they also return true or false to indicate whether the event was handled completely or not.

Inheritance Hierarchy vs Containment Hierarchy.

There are two possible chains to follow to look for an event handler:

  • Up the chain of containers (event is in a Panel, which is in a Frame, which is in a Window...)
  • Up the chain of subclasses (event is from myYellowButton, which is a subclass of myButton, which is a subclass of Button, which is a subclass of Component...

Both chains are typically involved.

Rules of Thumb for Handling Events

  • Avoid returning false from a handleEvent() method:

    Returning false from a handleEvent() method propagates the event to the component's container without giving the component's superclass a chance to process the event.

    Instead, if a class has not fully handled the event, it should always give its superclass a chance to process the event and let the superclass decide whether to propagate the event to the component's container.

  • Propagate unhandled events from event handler convenience methods

    Event handler convenience methods like mouseDown() should never return super.handleEvent(event).

    Why Not?

    Instead they should directly propagate unhandled events to their container.

Summary of Choices

Component Choices When Handling Propagated Events:

Component Choice handleEvent(Event event) returns
Propagate event to its container false
Do not propagate event to its container true
Let superclass handle it and decide to propagate super.handleEvent(event)

Event Handling Guidelines When You Have Not Completely Handled the Event:

If you have... ...Then...
Overridden handleEvent() ... call super.handleEvent(event) and let the superclass determine whether to propagate the event
Overridden one of the convenience methods ... return false and propagate the event to the component's container.

This page was last modified on 02 October, 2007