package com.itmill.toolkit.event;
import java.lang.reflect.Method;
+import java.util.Collections;
import java.util.EventObject;
import java.util.Iterator;
-import java.util.LinkedList;
+import java.util.LinkedHashSet;
+import java.util.Set;
/**
* <code>EventRouter</code> class implementing the inheritable event listening
/**
* List of registered listeners.
*/
- private LinkedList listenerList = null;
+ private Set listenerList = null;
/*
* Registers a new listener with the specified activation method to listen
public void addListener(Class eventType, Object object, Method method) {
if (listenerList == null) {
- listenerList = new LinkedList();
+ listenerList = Collections.synchronizedSet(new LinkedHashSet());
}
- listenerList.add(new ListenerMethod(eventType, object, method));
+ synchronized (listenerList) {
+ listenerList.add(new ListenerMethod(eventType, object, method));
+ }
}
/*
public void addListener(Class eventType, Object object, String methodName) {
if (listenerList == null) {
- listenerList = new LinkedList();
+ listenerList = Collections.synchronizedSet(new LinkedHashSet());
}
- listenerList.add(new ListenerMethod(eventType, object, methodName));
+ synchronized (listenerList) {
+ listenerList.add(new ListenerMethod(eventType, object, methodName));
+ }
}
/*
* interface.
*/
public void removeListener(Class eventType, Object target) {
-
if (listenerList != null) {
- final Iterator i = listenerList.iterator();
- while (i.hasNext()) {
- try {
- final ListenerMethod lm = (ListenerMethod) i.next();
- if (lm.matches(eventType, target)) {
- i.remove();
+ synchronized (listenerList) {
+ final Iterator i = listenerList.iterator();
+ while (i.hasNext()) {
+ try {
+ final ListenerMethod lm = (ListenerMethod) i.next();
+ if (lm.matches(eventType, target)) {
+ i.remove();
+ return;
+ }
+ } catch (final java.lang.ClassCastException e) {
+ // Class cast exceptions are ignored
}
- } catch (final java.lang.ClassCastException e) {
- // Class cast exceptions are ignored
}
}
}
public void removeListener(Class eventType, Object target, Method method) {
if (listenerList != null) {
- final Iterator i = listenerList.iterator();
- while (i.hasNext()) {
- try {
- final ListenerMethod lm = (ListenerMethod) i.next();
- if (lm.matches(eventType, target, method)) {
- i.remove();
+ synchronized (listenerList) {
+ final Iterator i = listenerList.iterator();
+ while (i.hasNext()) {
+ try {
+ final ListenerMethod lm = (ListenerMethod) i.next();
+ if (lm.matches(eventType, target, method)) {
+ i.remove();
+ return;
+ }
+ } catch (final java.lang.ClassCastException e) {
+ // Class cast exceptions are ignored
}
- } catch (final java.lang.ClassCastException e) {
- // Class cast exceptions are ignored
}
}
}
}
/*
- * Removes the event listener method matching the given given paramaters.
+ * Removes the event listener method matching the given given parameters.
* Don't add a JavaDoc comment here, we use the default documentation from
* implemented interface.
*/
// Remove the listeners
if (listenerList != null) {
- final Iterator i = listenerList.iterator();
- while (i.hasNext()) {
- try {
- final ListenerMethod lm = (ListenerMethod) i.next();
- if (lm.matches(eventType, target, method)) {
- i.remove();
+ synchronized (listenerList) {
+ final Iterator i = listenerList.iterator();
+ while (i.hasNext()) {
+ try {
+ final ListenerMethod lm = (ListenerMethod) i.next();
+ if (lm.matches(eventType, target, method)) {
+ i.remove();
+ return;
+ }
+ } catch (final java.lang.ClassCastException e) {
+ // Class cast exceptions are ignored
}
- } catch (final java.lang.ClassCastException e) {
- // Class cast exceptions are ignored
}
}
}
* Removes all listeners from event router.
*/
public void removeAllListeners() {
- listenerList = null;
+ synchronized (listenerList) {
+ listenerList = null;
+ }
}
/**
* the Event to be sent to all listeners.
*/
public void fireEvent(EventObject event) {
-
// It is not necessary to send any events if there are no listeners
if (listenerList != null) {
-
// Send the event to all listeners. The listeners themselves
// will filter out unwanted events.
- final Iterator i = new LinkedList(listenerList).iterator();
- while (i.hasNext()) {
- ((ListenerMethod) i.next()).receiveEvent(event);
+ synchronized (listenerList) {
+ final Iterator i = listenerList.iterator();
+ while (i.hasNext()) {
+ ((ListenerMethod) i.next()).receiveEvent(event);
+ }
}
}
}
package com.itmill.toolkit.event;
import java.lang.reflect.Method;
+import java.util.Arrays;
import java.util.EventListener;
import java.util.EventObject;
* by this listener.
* @return <code>true</code> if <code>target</code> is the same object
* as the one stored in this object and <code>eventType</code>
- * equals the event type stored in this object.
+ * equals the event type stored in this object. *
*/
public boolean matches(Class eventType, Object target) {
return (target == object) && (eventType.equals(this.eventType));
.equals(this.method));
}
+ public int hashCode() {
+ int hash = 7;
+
+ hash = 31 * hash + eventArgumentIndex;
+ hash = 31 * hash + (eventType == null ? 0 : eventType.hashCode());
+ hash = 31 * hash + (object == null ? 0 : object.hashCode());
+ hash = 31 * hash + (method == null ? 0 : method.hashCode());
+ hash = 31 * hash + (arguments == null ? 0 : Arrays.hashCode(arguments));
+
+ return hash;
+ }
+
+ public boolean equals(Object obj) {
+
+ if (this == obj)
+ return true;
+
+ // return false if obj is a subclass (do not use instanceof check)
+ if ((obj == null) || (obj.getClass() != this.getClass()))
+ return false;
+
+ // obj is of same class, test it further
+ ListenerMethod t = (ListenerMethod) obj;
+
+ return eventArgumentIndex == t.eventArgumentIndex
+ && (eventType == t.eventType || (eventType != null && eventType
+ .equals(t.eventType)))
+ && (object == t.object || (object != null && object
+ .equals(t.object)))
+ && (method == t.method || (method != null && method
+ .equals(t.method)))
+ && (arguments == t.arguments || (Arrays.deepEquals(arguments,
+ t.arguments)));
+ }
+
/**
* Exception that wraps an exception thrown by an invoked method. When
* <code>ListenerMethod</code> invokes the target method, it may throw