50 *
51 * The Thread starts a "permanent" event pump with a call to
52 * pumpEvents(Conditional) in its run() method. Event handlers can choose to
53 * block this event pump at any time, but should start a new pump (<b>not</b>
54 * a new EventDispatchThread) by again calling pumpEvents(Conditional). This
55 * secondary event pump will exit automatically as soon as the Condtional
56 * evaluate()s to false and an additional Event is pumped and dispatched.
57 *
58 * @author Tom Ball
59 * @author Amy Fowler
60 * @author Fred Ecks
61 * @author David Mendenhall
62 *
63 * @since 1.1
64 */
65 class EventDispatchThread extends Thread {
66
67 private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventDispatchThread");
68
69 private EventQueue theQueue;
70 private boolean doDispatch = true;
71 private volatile boolean shutdown = false;
72
73 private static final int ANY_EVENT = -1;
74
75 private ArrayList<EventFilter> eventFilters = new ArrayList<EventFilter>();
76
77 EventDispatchThread(ThreadGroup group, String name, EventQueue queue) {
78 super(group, name);
79 setEventQueue(queue);
80 }
81
82 /*
83 * Must be called on EDT only, that's why no synchronization
84 */
85 public void stopDispatching() {
86 doDispatch = false;
87 }
88
89 public void interrupt() {
90 shutdown = true;
91 super.interrupt();
92 }
93
94 public void run() {
95 while (true) {
96 try {
97 pumpEvents(new Conditional() {
98 public boolean evaluate() {
99 return true;
100 }
101 });
102 } finally {
103 if(getEventQueue().detachDispatchThread(this, shutdown)) {
104 break;
105 }
106 }
107 }
108 }
109
110 // MacOSX change:
111 // This was added because this class (and java.awt.Conditional) are package private.
112 // There are certain instances where classes in other packages need to block the
113 // AWTEventQueue while still allowing it to process events. This uses reflection
114 // to call back into the caller in order to remove dependencies.
115 //
116 // NOTE: This uses reflection in its implementation, so it is not for performance critical code.
117 //
118 // cond is an instance of sun.lwawt.macosx.EventDispatchAccess
119 //
120 private Conditional _macosxGetConditional(final Object cond) {
121 try {
122 return new Conditional() {
123 final Method evaluateMethod = Class.forName("sun.lwawt.macosx.EventDispatchAccess").getMethod("evaluate", null);
141
142 void pumpEventsForHierarchy(Conditional cond, Component modalComponent) {
143 pumpEventsForHierarchy(ANY_EVENT, cond, modalComponent);
144 }
145
146 void pumpEvents(int id, Conditional cond) {
147 pumpEventsForHierarchy(id, cond, null);
148 }
149
150 void pumpEventsForHierarchy(int id, Conditional cond, Component modalComponent) {
151 pumpEventsForFilter(id, cond, new HierarchyEventFilter(modalComponent));
152 }
153
154 void pumpEventsForFilter(Conditional cond, EventFilter filter) {
155 pumpEventsForFilter(ANY_EVENT, cond, filter);
156 }
157
158 void pumpEventsForFilter(int id, Conditional cond, EventFilter filter) {
159 addEventFilter(filter);
160 doDispatch = true;
161 shutdown |= isInterrupted();
162 while (doDispatch && !shutdown && cond.evaluate()) {
163 pumpOneEventForFilters(id);
164 }
165 removeEventFilter(filter);
166 }
167
168 void addEventFilter(EventFilter filter) {
169 eventLog.finest("adding the event filter: " + filter);
170 synchronized (eventFilters) {
171 if (!eventFilters.contains(filter)) {
172 if (filter instanceof ModalEventFilter) {
173 ModalEventFilter newFilter = (ModalEventFilter)filter;
174 int k = 0;
175 for (k = 0; k < eventFilters.size(); k++) {
176 EventFilter f = eventFilters.get(k);
177 if (f instanceof ModalEventFilter) {
178 ModalEventFilter cf = (ModalEventFilter)f;
179 if (cf.compareTo(newFilter) > 0) {
180 break;
181 }
182 }
230 if (!eventOK) {
231 event.consume();
232 }
233 }
234 while (eventOK == false);
235
236 if (eventLog.isLoggable(PlatformLogger.FINEST)) {
237 eventLog.finest("Dispatching: " + event);
238 }
239
240 Object handle = null;
241 if (delegate != null) {
242 handle = delegate.beforeDispatch(event);
243 }
244 eq.dispatchEvent(event);
245 if (delegate != null) {
246 delegate.afterDispatch(event, handle);
247 }
248 }
249 catch (ThreadDeath death) {
250 shutdown = true;
251 throw death;
252 }
253 catch (InterruptedException interruptedException) {
254 shutdown = true; // AppContext.dispose() interrupts all
255 // Threads in the AppContext
256 }
257 catch (Throwable e) {
258 processException(e);
259 }
260 }
261
262 private void processException(Throwable e) {
263 if (eventLog.isLoggable(PlatformLogger.FINE)) {
264 eventLog.fine("Processing exception: " + e);
265 }
266 getUncaughtExceptionHandler().uncaughtException(this, e);
267 }
268
269 public synchronized EventQueue getEventQueue() {
270 return theQueue;
271 }
272 public synchronized void setEventQueue(EventQueue eq) {
273 theQueue = eq;
274 }
|
50 *
51 * The Thread starts a "permanent" event pump with a call to
52 * pumpEvents(Conditional) in its run() method. Event handlers can choose to
53 * block this event pump at any time, but should start a new pump (<b>not</b>
54 * a new EventDispatchThread) by again calling pumpEvents(Conditional). This
55 * secondary event pump will exit automatically as soon as the Condtional
56 * evaluate()s to false and an additional Event is pumped and dispatched.
57 *
58 * @author Tom Ball
59 * @author Amy Fowler
60 * @author Fred Ecks
61 * @author David Mendenhall
62 *
63 * @since 1.1
64 */
65 class EventDispatchThread extends Thread {
66
67 private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventDispatchThread");
68
69 private EventQueue theQueue;
70 private volatile boolean doDispatch = true;
71
72 private static final int ANY_EVENT = -1;
73
74 private ArrayList<EventFilter> eventFilters = new ArrayList<EventFilter>();
75
76 EventDispatchThread(ThreadGroup group, String name, EventQueue queue) {
77 super(group, name);
78 setEventQueue(queue);
79 }
80
81 /*
82 * Must be called on EDT only, that's why no synchronization
83 */
84 public void stopDispatching() {
85 doDispatch = false;
86 }
87
88 public void run() {
89 while (true) {
90 try {
91 pumpEvents(new Conditional() {
92 public boolean evaluate() {
93 return true;
94 }
95 });
96 } finally {
97 // 7189350: doDispatch is reset from stopDispatching(),
98 // on InterruptedException, or ThreadDeath. Either way,
99 // this indicates that we must force shutting down.
100 if (getEventQueue().detachDispatchThread(this,
101 !doDispatch || isInterrupted()))
102 {
103 break;
104 }
105 }
106 }
107 }
108
109 // MacOSX change:
110 // This was added because this class (and java.awt.Conditional) are package private.
111 // There are certain instances where classes in other packages need to block the
112 // AWTEventQueue while still allowing it to process events. This uses reflection
113 // to call back into the caller in order to remove dependencies.
114 //
115 // NOTE: This uses reflection in its implementation, so it is not for performance critical code.
116 //
117 // cond is an instance of sun.lwawt.macosx.EventDispatchAccess
118 //
119 private Conditional _macosxGetConditional(final Object cond) {
120 try {
121 return new Conditional() {
122 final Method evaluateMethod = Class.forName("sun.lwawt.macosx.EventDispatchAccess").getMethod("evaluate", null);
140
141 void pumpEventsForHierarchy(Conditional cond, Component modalComponent) {
142 pumpEventsForHierarchy(ANY_EVENT, cond, modalComponent);
143 }
144
145 void pumpEvents(int id, Conditional cond) {
146 pumpEventsForHierarchy(id, cond, null);
147 }
148
149 void pumpEventsForHierarchy(int id, Conditional cond, Component modalComponent) {
150 pumpEventsForFilter(id, cond, new HierarchyEventFilter(modalComponent));
151 }
152
153 void pumpEventsForFilter(Conditional cond, EventFilter filter) {
154 pumpEventsForFilter(ANY_EVENT, cond, filter);
155 }
156
157 void pumpEventsForFilter(int id, Conditional cond, EventFilter filter) {
158 addEventFilter(filter);
159 doDispatch = true;
160 while (doDispatch && !isInterrupted() && cond.evaluate()) {
161 pumpOneEventForFilters(id);
162 }
163 removeEventFilter(filter);
164 }
165
166 void addEventFilter(EventFilter filter) {
167 eventLog.finest("adding the event filter: " + filter);
168 synchronized (eventFilters) {
169 if (!eventFilters.contains(filter)) {
170 if (filter instanceof ModalEventFilter) {
171 ModalEventFilter newFilter = (ModalEventFilter)filter;
172 int k = 0;
173 for (k = 0; k < eventFilters.size(); k++) {
174 EventFilter f = eventFilters.get(k);
175 if (f instanceof ModalEventFilter) {
176 ModalEventFilter cf = (ModalEventFilter)f;
177 if (cf.compareTo(newFilter) > 0) {
178 break;
179 }
180 }
228 if (!eventOK) {
229 event.consume();
230 }
231 }
232 while (eventOK == false);
233
234 if (eventLog.isLoggable(PlatformLogger.FINEST)) {
235 eventLog.finest("Dispatching: " + event);
236 }
237
238 Object handle = null;
239 if (delegate != null) {
240 handle = delegate.beforeDispatch(event);
241 }
242 eq.dispatchEvent(event);
243 if (delegate != null) {
244 delegate.afterDispatch(event, handle);
245 }
246 }
247 catch (ThreadDeath death) {
248 doDispatch = false;
249 throw death;
250 }
251 catch (InterruptedException interruptedException) {
252 doDispatch = false; // AppContext.dispose() interrupts all
253 // Threads in the AppContext
254 }
255 catch (Throwable e) {
256 processException(e);
257 }
258 }
259
260 private void processException(Throwable e) {
261 if (eventLog.isLoggable(PlatformLogger.FINE)) {
262 eventLog.fine("Processing exception: " + e);
263 }
264 getUncaughtExceptionHandler().uncaughtException(this, e);
265 }
266
267 public synchronized EventQueue getEventQueue() {
268 return theQueue;
269 }
270 public synchronized void setEventQueue(EventQueue eq) {
271 theQueue = eq;
272 }
|