Handling Events through handleEvent

The boolean handleEvent(Event evt) method of an Applet is used to dispatch events in a low level fashion. The default implementation of handleEvent calls the event-dependent methods (like mouseDown, keyUp< etc.) so when handleEvent is implemented in an applet these other methods cannot easily be used.

An Event object has a number of important data fields:

When handleEvent has indeed handled the event (evt) it should return true, else it may call super.handleEvent(evt) to pass the event to the event handler of the superclass. (Doing so enables the use of other event handling methods.)

Using handleEvent is indicative of a bottom-up approach towards event handling: the applet receives the event, and has to figure out which component (target) needs to really handle it. Depending on which component the target is the handleEvent routine may either handle the event for that component, or call one of the component's methods.
In fact the event handling in Java (en AWT) is always top-down. However, AWT components like buttons, textfields, etc. by default ignore events, and just pass them to their (parent) container. The user-interface programmer then adds the handleEvent method to the container, possibly thinking that the event has not first been passed to the top-level components.

handleEvent is an appropriate (but now officially deprecated) way of handling events when there are no simple targets to identify, that can handle events. This is the case for instance in the Rolodex example: there is no component which can be the target of a mouseclick, and even if the images would be able to receive events, the fact that they are moving independently (in a separate thread) makes it even harder to pass events to them automatically. Below is the handleEvent method of the Rolodex example:

    public boolean handleEvent(Event evt) {
	switch (evt.id) {
	case Event.MOUSE_DOWN:
	    if ((evt.modifiers & Event.SHIFT_MASK) != 0) {
		showDescription();
		return true;
	    } else if (hrefs != null) {
		// let mouse-up handle going to the new page
		return true;
	    } else if (loaded) {
		if (engine != null && engine.isAlive()) {
		    if (userPause) {
			engine.resume();
			startPlaying();
		    } else {
			engine.suspend();
			stopPlaying();
		    }
		    userPause = !userPause;
		} else {
		    userPause = false;
		    setImageNum(0);
		    engine = new Thread(this);
		    engine.start();
		}
	    }
	    return true;
	case Event.MOUSE_UP:
	    if (hrefs != null && ((evt.modifiers & Event.SHIFT_MASK) == 0)) {
		if (imageNum < hrefs.size()) {
		    if (Direction == LEFT) {
		    System.out.println("imagenum " + imageNum);
			if (((Image)images.elementAt(imageNum)).getWidth(null) - frameNum > evt.x) {
			    Object o = hrefs.elementAt(imageNum);
			    getAppletContext().showDocument((URL)o);
			} else {
			    if (imageNum+1 >= images.size()) {
				Object o = hrefs.elementAt(0);
				getAppletContext().showDocument((URL)o);
			    } else if (imageNum+1 < hrefs.size()) {
				Object o = hrefs.elementAt(imageNum+1);
				getAppletContext().showDocument((URL)o);
			    }
			    else System.out.println("imagenum " + imageNum + " hrefs.size " + hrefs.size() );
			}
		    } else if (Direction == RIGHT) {
			if (evt.x > appWidth - ((Image)images.elementAt(imageNum)).getWidth(null) + frameNum) {
			    Object o = hrefs.elementAt(imageNum);
			    getAppletContext().showDocument((URL)o);
			} else {
			    if (imageNum+1 >= images.size()) {
				Object o = hrefs.elementAt(0);
				getAppletContext().showDocument((URL)o);
			    } else if (imageNum+1 < hrefs.size()) {
				Object o = hrefs.elementAt(imageNum+1);
				getAppletContext().showDocument((URL)o);
			    }
			}
		    } else if (Direction == UP) {
			if (((Image)images.elementAt(imageNum)).getHeight(null) - frameNum > evt.y) {
			    Object o = hrefs.elementAt(imageNum);
			    getAppletContext().showDocument((URL)o);
			} else {
			    if (imageNum+1 >= images.size()) {
				Object o = hrefs.elementAt(0);
				getAppletContext().showDocument((URL)o);
			    } else if (imageNum+1 < hrefs.size()) {
				Object o = hrefs.elementAt(imageNum+1);
				getAppletContext().showDocument((URL)o);
			    }
			}
		    } else if (Direction == DOWN) {
			if (evt.y > appHeight - ((Image)images.elementAt(imageNum)).getHeight(null) + frameNum) {
			    Object o = hrefs.elementAt(imageNum);
			    getAppletContext().showDocument((URL)o);
			} else {
			    if (imageNum+1 >= images.size()) {
				Object o = hrefs.elementAt(0);
				getAppletContext().showDocument((URL)o);
			    } else if (imageNum+1 < hrefs.size()) {
				Object o = hrefs.elementAt(imageNum+1);
				getAppletContext().showDocument((URL)o);
			    }
			}
		    }
		}
	    }
	    return true;
	case Event.MOUSE_ENTER:
	    showStatus(getAppletInfo()+" -- shift-click for info");
	    return true;
	case Event.MOUSE_EXIT:
	    showStatus("");
	    return true;
	case Event.KEY_ACTION:
	case Event.KEY_RELEASE:
	case Event.KEY_ACTION_RELEASE:
	    dbg("Got event "+evt);
	    return true;
	default:
	    return super.handleEvent(evt);
	}
    }


class ParseException extends Exception {
    ParseException(String s) {
	super(s);
    }
}


class DescriptionFrame extends Frame {

    static final int rows = 26;
    static final int cols = 70;
    
    TextArea info;

    DescriptionFrame() {
	super("Rolodex v0.0");
	add("Center", info = new TextArea(rows, cols));
	info.setEditable(false);
	info.setBackground(Color.white);
	Panel buttons = new Panel();
	buttons.setLayout(new FlowLayout());
	add("South", buttons);
	buttons.add(new Button("Cancel"));
	
	pack();
    }

    public void show() {
	info.select(0,0);
	super.show();
    }

    void tell(String s) {
	info.appendText(s);
    }

    public boolean action(Event e, Object arg) {
	if (e.target instanceof Button) {
	    hide();
	    return true;
	}
	return false;
    }
}