THE PASZ.COM BLOG

Tuesday, January 24, 2006

Making Sense of Event Listeners

I've always had some trouble conceptually with Listeners. I remember first hearing about them in a Java class, and my opinion was that they were cumbersome. Java 1.0 veterans will remember that the initial version of Java didn't even have Listeners. To define an event handler, all you had to do was override the appropriate method in the application or applet class. So to define an event handler for when the mouse button is pressed, you'd write

public boolean mouseDown(Event evt, int x, int y){
//handle event
}


Simple!

To catch a mouse press in Java 1.1 and above, you have to
1. Make sure your application implements the MouseListener interface
2. Tell the application to listen to its own mouse events: addMouseListener(this);
3. Define a mousePressed() method

I'm sure the designers of Java had some good architectural reasons for switching over to Listeners, but as a novice programmer -- still getting a handle on Interfaces -- I found the change baffling. How was it an improvement when something that used to take one step now took 3?

Similarly, when Flash MX came out, I was perplexed to find that they too were adopting a Listener model (though they still supported simple callbacks for legacy reasons). Instead of defining a MouseDown clip event like this

on(mouseDown){
//handle event
}


in Flash MX, one was now encouraged to do the following:

//1. define the listener Object
mouseListener = new Object();
//2. define the event handler method
mouseListener.onMouseDown = function(){
//handle event
}
//3. "subscribe" to the Mouse object so the listener will be notified of Mouse events
Mouse.addListener(mouseListener);


Again, a clumsy 3-step process. I have to admit that to this day, despite the tens of thousands of lines of ActionScript code that I've written, I still have to refer to the Help to remind myself how to set up a Mouse Listener.

Now, even JavaScript is getting into the act with their element.addEventListener() method. I hate to think about all the poor web designers struggling with that one after years of writing "onClick=handleEvent()". It seems like language designers love to copy Java when looking for the best way to do something, but maybe they don't always think through the ramifications on their users...

My point here is not to say that Listeners are bad. However, from a language design standpoint, I feel that for many event-handling situations a simple callback can be cleaner. It makes sense to use Listeners when you need to have multiple objects responding concurrently to the same event. That is, there is a one-to-many relationship between an event and the event handling object. For example, say you are developing a paint application like Photoshop where you can paint on multiple layers at the same time. In this case, you might want each layer listening independently for mouse events, and responding accordingly.

In smaller programs you usually have a one-to-one relationship between an event and the object that handles the event. In these situations, a simple callback will do, and invoking a Listener is overkill. If you're starting out with event handling, my advice is don't worry about comprehending the subtleties of Listeners. Just paste in the appopriate code whenever you need it, and realize that you're using the equivalent of a sledgehammer to put up a tack.

17 Comments: