1 5 package com.tc.util.event; 6 7 import java.io.Serializable ; 8 import java.util.ArrayList ; 9 import java.util.Collections ; 10 import java.util.Iterator ; 11 import java.util.LinkedList ; 12 import java.util.List ; 13 14 48 public final class EventMulticaster implements Serializable { 49 50 private transient UpdateEventListener eventListener; 51 private transient EventQueue queue; 52 private transient Thread dispatchThread; 53 private volatile boolean dispatchInterrupted; 54 55 public synchronized void enableDispatchThread() { 56 this.eventListener = null; 57 this.queue = new EventQueue(); 58 this.dispatchThread = new Thread () { 59 public void run() { 60 UpdateEvent event = null; 61 try { 62 while (true) { 63 event = queue.take(); 64 event.listener.handleUpdate(event.arg); 65 } 66 } catch (InterruptedException e) { 67 dispatchInterrupted = true; 68 } 69 } 70 }; 71 dispatchThread.setDaemon(true); 72 dispatchThread.start(); 73 } 74 75 public void fireUpdateEvent() { 76 fireUpdateEvent(null); 77 } 78 79 public synchronized void fireUpdateEvent(Object arg) { 80 if (dispatchInterrupted) throw new IllegalStateException (); 81 if (eventListener != null) { 82 if (queue == null) eventListener.handleUpdate(arg); 83 else { 84 UpdateEvent event = new UpdateEvent(); 85 event.listener = eventListener; 86 event.arg = arg; 87 queue.offer(event); 88 } 89 } 90 } 91 92 public synchronized void addListener(UpdateEventListener listener) { 93 if (eventListener == null) { 94 eventListener = listener; 95 } else if (eventListener instanceof EventMulticaster.BroadcastListener) { 96 EventMulticaster.BroadcastListener broadcast = (EventMulticaster.BroadcastListener) eventListener; 97 broadcast.add(listener); 98 } else { 99 EventMulticaster.BroadcastListener broadcast = new BroadcastListener(); 100 broadcast.add(eventListener); 101 broadcast.add(listener); 102 eventListener = broadcast; 103 } 104 } 105 106 public synchronized boolean removeListener(UpdateEventListener listener) { 107 if (eventListener instanceof EventMulticaster.BroadcastListener) { 108 EventMulticaster.BroadcastListener broadcast = (EventMulticaster.BroadcastListener) eventListener; 109 if (!broadcast.remove(listener)) return false; 110 if (broadcast.size() == 1) eventListener = broadcast.pop(); 111 return true; 112 } else { 113 if (eventListener != listener) return false; 114 eventListener = null; 115 return true; 116 } 117 } 118 119 121 private class BroadcastListener implements UpdateEventListener, Serializable { 122 123 private List listeners = Collections.synchronizedList(new ArrayList ()); 124 125 public void handleUpdate(Object arg) { 126 for (Iterator iter = listeners.iterator(); iter.hasNext();) { 127 if (queue == null) ((UpdateEventListener) iter.next()).handleUpdate(arg); 128 else { 129 UpdateEvent event = new UpdateEvent(); 130 event.listener = (UpdateEventListener) iter.next(); 131 event.arg = arg; 132 queue.offer(event); 133 } 134 } 135 } 136 137 private void add(UpdateEventListener listener) { 138 listeners.add(listener); 139 } 140 141 private boolean remove(UpdateEventListener listener) { 142 return listeners.remove(listener); 143 } 144 145 private int size() { 146 return listeners.size(); 147 } 148 149 private UpdateEventListener pop() { 150 return (UpdateEventListener) listeners.iterator().next(); 151 } 152 } 153 154 156 private class UpdateEvent implements Serializable { 157 private UpdateEventListener listener; 158 private Object arg; 159 } 160 161 163 private class EventQueue implements Serializable { 164 165 private final List list = new LinkedList (); 166 167 private void offer(UpdateEvent val) { 168 if (val == null) throw new NullPointerException (); 169 synchronized (list) { 170 list.add(val); 171 list.notify(); 172 } 173 } 174 175 private UpdateEvent take() throws InterruptedException { 176 synchronized (list) { 177 while (list.size() == 0) { 178 list.wait(); 179 } 180 return (UpdateEvent) list.remove(0); 181 } 182 } 183 } 184 } 185 | Popular Tags |