Event-Listener Pattern

In lossy-couple environment, notification system is essential, because it allows two or more lossy-couple components to communicate and notify each other when an event is triggered. There are several patterns to implement notification system in Java and one of them is event-listener pattern.

In Java, building event-listener components is not easy as Flex or C#. It requires a lot of boilerplate code to implement it. In this article, I will talk about building simple event listener in Java. First I will demonstrate the general algorithm for event listeners then I will implement it in a simple, humble example.

Event-Listener Pattern:

Event-Listener pattern is a simple pattern that can be implemented easily in Java bean class. Actually, it is part of JavaBean conventions. It has been used mainly in J2SE platform, particularly in GUI libraries. This pattern consists of two main parts (Source and Listener):

  1. Source: the source is the Java class for maintaining the event listeners which has previously been registered - It is like a small database . Therefore, the source class has method for registering (add) and unregistering (remove) listeners to the small database. The source also has ability to fire an event.
  2. Listener: As the name refers to, the listener is the Java component that interests in a specific event. When an event is triggered, all listeners interested in the event will get a notification and will execute their own event handler codes. Listeners register for events using the methods defined by the sources of those events.

What is share between these two parts is listener event message! The message is usually interface used to determine event data-type.

Sample:

Now, we are going to write a simple implementation for the pattern, so let's start with the source part.

First of all, we need a simple bean class. I will name it “SourceClass”:

class SourceClass {

}


Then we need a data structure to store the listeners (Remember, the small database). For simplicity, I will use Vector
private Vector listeners = new Vector();
Now, we need two methods, one of them for registering and the other unregistering, they should have JavaBean conventional style. The method used to register a listener in the vector must use the prefix “add”, and the other one, must start with the prefix “remove”. Both of them should follow by the event type and must end with the postfix “Listener”. In addition, they should have an argument with event data-type
public void addTestEventListener(TestEvent l) {
listeners.addElement(l);
}

public void removeTestEventListener(TestEvent l) {
listeners.removeElement(l);
}
As the preceding example depicts, the two methods manage the listeners which interest in "TestEvent" Event.

For simplicity, a simple fire method will be added to notify all registered listeners

public void fire() {
Vector temp = (Vector) listeners.clone();

for (int i=0; i > l.size(); i++) {
TestEventListener listeners = (TestEventListener) temp.elementAt(i);
listener.eventHandler ();
}
}

Now, let's define our event, which simply extends EventListener interface in the Java util package
public interface TestEvent extends java.util.EventListener {

void eventHandler();
}
So as you see, the event is nothing than a simple, share interface between the source and listeners.

Finally, we need a simple listener which listens to our TestEvent. Remember, listener can be any class you want. The only thing is required to become a listener is creating a SourceClass and adding the event (TestEvent).
.
.
.
SourceClass c = new SourceClass();
TestEvent e = new TestEvent(){
void eventHandler(){
//Do something
}
}
c.addTestEventListener(e);

c.fire();
As the codes shown above, SourceClass and TestEvent objects have been created. of course, we have to resolve all abstract methods in TestEventListener interface and the last not the least, we add the later object to the source.

when the source fires the
TestEvent, listeners gets a notification and will execute their event handler code.

Conclusion:

Event-Listener Pattern provides simple notification system for Java components. The pattern has two main parts (Source and Listener). The source stores all listeners, and the listeners listen to particular event, which is simply the message or notification that transports from source to listeners.

Further Reading:

2 comments:

Anonymous said...

Dude, your code is sooo JDK1.1.

Also you have an extra brace in your fire() method on the clone() line.

Software Engineer said...

I know there are many java libraries that can help you in reducing your boilerplate codes. However, In this post, I wanna use JavaBeans conventions only to demonstrate the pattern. Because, basically, I wanna explain the pattern NOT the third party libraries.

Thanks for ur comment.

Post a Comment