src/share/classes/java/awt/EventDispatchThread.java

Print this page




  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     }