01: package uk.org.ponder.event;
02:
03: import uk.org.ponder.arrayutil.ArrayUtil;
04: import uk.org.ponder.util.AssertionException;
05: import uk.org.ponder.util.Logger;
06:
07: import java.util.ArrayList;
08:
09: /// Event handling
10:
11: /**
12: * @package <numode.event The package event contains the tag interface EventTag,
13: * which is implemented
14: * by all event classes. The interface Listener has to be implemented by classes
15: * wishing to receive events. An object of the class EventFirer is responsible
16: * for managing Listeners and firing events.
17: */
18:
19: /** An object of the class EventFirer is responsible for managing Listeners registered
20: * to receive events and to fire events on demand. Upon construction, the object
21: * receives information about which classes of events will be fired. For each class,
22: * it manages an ArrayList of Listeners.
23: */
24:
25: public class EventFirer {
26: /// An array of ArrayLists containing the Listeners registered to receive events.
27: private ArrayList[] listenervectors;
28:
29: /// The array of event classes handled by this firer.
30: private Class[] registeredclasses;
31:
32: /// Constructs an EventFirer with the specified classes of events to be fired.
33: public EventFirer(Class[] classvector) {
34: registeredclasses = classvector;
35: listenervectors = new ArrayList[classvector.length];
36: for (int i = 0; i < classvector.length; ++i) {
37: listenervectors[i] = new ArrayList();
38: }
39: }
40:
41: public EventFirer(Class clazz) {
42: this (new Class[] { clazz });
43: }
44:
45: public void addListener(Class[] eventclasses, Listener listener) {
46: for (int i = 0; i < eventclasses.length; ++i) {
47: addListener(eventclasses[i], listener);
48: }
49: }
50:
51: /// Register a Listener to receive events of the specified class
52: public void addListener(Class eventclass, Listener listener) {
53: if (listener == null) {
54: throw new AssertionException(
55: "Null listener added to EventFirer for class "
56: + eventclass);
57: }
58: int classindex = ArrayUtil.indexOf(registeredclasses,
59: eventclass);
60: if (classindex != -1) {
61: ArrayList listeners = listenervectors[classindex];
62: listeners.add(listener);
63: } else {
64: throw new AssertionException("Unknown event class "
65: + eventclass + " added to EventFirer");
66: }
67: }
68:
69: /// Unregister a Listener from receiving events of the specified class
70: public void removeListener(Class eventclass, Listener listener) {
71: int classindex = ArrayUtil.indexOf(registeredclasses,
72: eventclass);
73: if (classindex != -1) {
74: ArrayList listeners = listenervectors[classindex];
75: listeners.remove(listener);
76: }
77: }
78:
79: /// Fire the supplied event object to any registered listeners. The listeners are chosen based on the class of the supplied object.
80:
81: public void fireEvent(EventTag tofire) {
82: for (int classindex = 0; classindex < registeredclasses.length; ++classindex) {
83: if (registeredclasses[classindex].isInstance(tofire)) {
84: ArrayList listeners = listenervectors[classindex];
85: for (int i = listeners.size() - 1; i >= 0; --i) {
86: try {
87: ((Listener) listeners.get(i))
88: .receiveEvent(tofire);
89: } catch (Throwable t) {
90: Logger.log.warn("Error propagating event", t);
91: }
92: }
93: }
94: }
95: }
96: }
|