src/share/classes/java/awt/WaitDispatchSupport.java

Print this page




 148     public WaitDispatchSupport(EventDispatchThread dispatchThread,
 149                                Conditional extCondition,
 150                                EventFilter filter, long interval)
 151     {
 152         this(dispatchThread, extCondition);
 153         this.filter = filter;
 154         if (interval < 0) {
 155             throw new IllegalArgumentException("The interval value must be >= 0");
 156         }
 157         this.interval = interval;
 158         if (interval != 0) {
 159             initializeTimer();
 160         }
 161     }
 162 
 163     /**
 164      * @inheritDoc
 165      */
 166     @Override
 167     public boolean enter() {

 168         log.fine("enter(): blockingEDT=" + keepBlockingEDT.get() +
 169                  ", blockingCT=" + keepBlockingCT.get());

 170 
 171         if (!keepBlockingEDT.compareAndSet(false, true)) {
 172             log.fine("The secondary loop is already running, aborting");
 173             return false;
 174         }
 175 
 176         final Runnable run = new Runnable() {
 177             public void run() {
 178                 log.fine("Starting a new event pump");
 179                 if (filter == null) {
 180                     dispatchThread.pumpEvents(condition);
 181                 } else {
 182                     dispatchThread.pumpEventsForFilter(condition, filter);
 183                 }
 184             }
 185         };
 186 
 187         // We have two mechanisms for blocking: if we're on the
 188         // dispatch thread, start a new event pump; if we're
 189         // on any other thread, call wait() on the treelock
 190 
 191         Thread currentThread = Thread.currentThread();
 192         if (currentThread == dispatchThread) {

 193             log.finest("On dispatch thread: " + dispatchThread);

 194             if (interval != 0) {

 195                 log.finest("scheduling the timer for " + interval + " ms");

 196                 timer.schedule(timerTask = new TimerTask() {
 197                     @Override
 198                     public void run() {
 199                         if (keepBlockingEDT.compareAndSet(true, false)) {
 200                             wakeupEDT();
 201                         }
 202                     }
 203                 }, interval);
 204             }
 205             // Dispose SequencedEvent we are dispatching on the the current
 206             // AppContext, to prevent us from hang - see 4531693 for details
 207             SequencedEvent currentSE = KeyboardFocusManager.
 208                 getCurrentKeyboardFocusManager().getCurrentSequencedEvent();
 209             if (currentSE != null) {

 210                 log.fine("Dispose current SequencedEvent: " + currentSE);

 211                 currentSE.dispose();
 212             }
 213             // In case the exit() method is called before starting
 214             // new event pump it will post the waking event to EDT.
 215             // The event will be handled after the the new event pump
 216             // starts. Thus, the enter() method will not hang.
 217             //
 218             // Event pump should be privileged. See 6300270.
 219             AccessController.doPrivileged(new PrivilegedAction() {
 220                 public Object run() {
 221                     run.run();
 222                     return null;
 223                 }
 224             });
 225         } else {

 226             log.finest("On non-dispatch thread: " + currentThread);

 227             synchronized (getTreeLock()) {
 228                 if (filter != null) {
 229                     dispatchThread.addEventFilter(filter);
 230                 }
 231                 try {
 232                     EventQueue eq = dispatchThread.getEventQueue();
 233                     eq.postEvent(new PeerEvent(this, run, PeerEvent.PRIORITY_EVENT));
 234                     keepBlockingCT.set(true);
 235                     if (interval > 0) {
 236                         long currTime = System.currentTimeMillis();
 237                         while (keepBlockingCT.get() &&
 238                                ((extCondition != null) ? extCondition.evaluate() : true) &&
 239                                (currTime + interval > System.currentTimeMillis()))
 240                         {
 241                             getTreeLock().wait(interval);
 242                         }
 243                     } else {
 244                         while (keepBlockingCT.get() &&
 245                                ((extCondition != null) ? extCondition.evaluate() : true))
 246                         {
 247                             getTreeLock().wait();
 248                         }
 249                     }

 250                     log.fine("waitDone " + keepBlockingEDT.get() + " " + keepBlockingCT.get());

 251                 } catch (InterruptedException e) {

 252                     log.fine("Exception caught while waiting: " + e);

 253                 } finally {
 254                     if (filter != null) {
 255                         dispatchThread.removeEventFilter(filter);
 256                     }
 257                 }
 258                 // If the waiting process has been stopped because of the
 259                 // time interval passed or an exception occurred, the state
 260                 // should be changed
 261                 keepBlockingEDT.set(false);
 262                 keepBlockingCT.set(false);
 263             }
 264         }
 265 
 266         return true;
 267     }
 268 
 269     /**
 270      * @inheritDoc
 271      */
 272     public boolean exit() {

 273         log.fine("exit(): blockingEDT=" + keepBlockingEDT.get() +
 274                  ", blockingCT=" + keepBlockingCT.get());

 275         if (keepBlockingEDT.compareAndSet(true, false)) {
 276             wakeupEDT();
 277             return true;
 278         }
 279         return false;
 280     }
 281 
 282     private final static Object getTreeLock() {
 283         return Component.LOCK;
 284     }
 285 
 286     private final Runnable wakingRunnable = new Runnable() {
 287         public void run() {
 288             log.fine("Wake up EDT");
 289             synchronized (getTreeLock()) {
 290                 keepBlockingCT.set(false);
 291                 getTreeLock().notifyAll();
 292             }
 293             log.fine("Wake up EDT done");
 294         }
 295     };
 296 
 297     private void wakeupEDT() {

 298         log.finest("wakeupEDT(): EDT == " + dispatchThread);

 299         EventQueue eq = dispatchThread.getEventQueue();
 300         eq.postEvent(new PeerEvent(this, wakingRunnable, PeerEvent.PRIORITY_EVENT));
 301     }
 302 }


 148     public WaitDispatchSupport(EventDispatchThread dispatchThread,
 149                                Conditional extCondition,
 150                                EventFilter filter, long interval)
 151     {
 152         this(dispatchThread, extCondition);
 153         this.filter = filter;
 154         if (interval < 0) {
 155             throw new IllegalArgumentException("The interval value must be >= 0");
 156         }
 157         this.interval = interval;
 158         if (interval != 0) {
 159             initializeTimer();
 160         }
 161     }
 162 
 163     /**
 164      * @inheritDoc
 165      */
 166     @Override
 167     public boolean enter() {
 168         if (log.isLoggable(PlatformLogger.FINE)) {
 169             log.fine("enter(): blockingEDT=" + keepBlockingEDT.get() +
 170                      ", blockingCT=" + keepBlockingCT.get());
 171         }
 172 
 173         if (!keepBlockingEDT.compareAndSet(false, true)) {
 174             log.fine("The secondary loop is already running, aborting");
 175             return false;
 176         }
 177 
 178         final Runnable run = new Runnable() {
 179             public void run() {
 180                 log.fine("Starting a new event pump");
 181                 if (filter == null) {
 182                     dispatchThread.pumpEvents(condition);
 183                 } else {
 184                     dispatchThread.pumpEventsForFilter(condition, filter);
 185                 }
 186             }
 187         };
 188 
 189         // We have two mechanisms for blocking: if we're on the
 190         // dispatch thread, start a new event pump; if we're
 191         // on any other thread, call wait() on the treelock
 192 
 193         Thread currentThread = Thread.currentThread();
 194         if (currentThread == dispatchThread) {
 195             if (log.isLoggable(PlatformLogger.FINEST)) {
 196                 log.finest("On dispatch thread: " + dispatchThread);
 197             }
 198             if (interval != 0) {
 199                 if (log.isLoggable(PlatformLogger.FINEST)) {
 200                     log.finest("scheduling the timer for " + interval + " ms");
 201                 }
 202                 timer.schedule(timerTask = new TimerTask() {
 203                     @Override
 204                     public void run() {
 205                         if (keepBlockingEDT.compareAndSet(true, false)) {
 206                             wakeupEDT();
 207                         }
 208                     }
 209                 }, interval);
 210             }
 211             // Dispose SequencedEvent we are dispatching on the the current
 212             // AppContext, to prevent us from hang - see 4531693 for details
 213             SequencedEvent currentSE = KeyboardFocusManager.
 214                 getCurrentKeyboardFocusManager().getCurrentSequencedEvent();
 215             if (currentSE != null) {
 216                 if (log.isLoggable(PlatformLogger.FINE)) {
 217                     log.fine("Dispose current SequencedEvent: " + currentSE);
 218                 }
 219                 currentSE.dispose();
 220             }
 221             // In case the exit() method is called before starting
 222             // new event pump it will post the waking event to EDT.
 223             // The event will be handled after the the new event pump
 224             // starts. Thus, the enter() method will not hang.
 225             //
 226             // Event pump should be privileged. See 6300270.
 227             AccessController.doPrivileged(new PrivilegedAction() {
 228                 public Object run() {
 229                     run.run();
 230                     return null;
 231                 }
 232             });
 233         } else {
 234             if (log.isLoggable(PlatformLogger.FINEST)) {
 235                 log.finest("On non-dispatch thread: " + currentThread);
 236             }
 237             synchronized (getTreeLock()) {
 238                 if (filter != null) {
 239                     dispatchThread.addEventFilter(filter);
 240                 }
 241                 try {
 242                     EventQueue eq = dispatchThread.getEventQueue();
 243                     eq.postEvent(new PeerEvent(this, run, PeerEvent.PRIORITY_EVENT));
 244                     keepBlockingCT.set(true);
 245                     if (interval > 0) {
 246                         long currTime = System.currentTimeMillis();
 247                         while (keepBlockingCT.get() &&
 248                                ((extCondition != null) ? extCondition.evaluate() : true) &&
 249                                (currTime + interval > System.currentTimeMillis()))
 250                         {
 251                             getTreeLock().wait(interval);
 252                         }
 253                     } else {
 254                         while (keepBlockingCT.get() &&
 255                                ((extCondition != null) ? extCondition.evaluate() : true))
 256                         {
 257                             getTreeLock().wait();
 258                         }
 259                     }
 260                     if (log.isLoggable(PlatformLogger.FINE)) {
 261                         log.fine("waitDone " + keepBlockingEDT.get() + " " + keepBlockingCT.get());
 262                     }
 263                 } catch (InterruptedException e) {
 264                     if (log.isLoggable(PlatformLogger.FINE)) {
 265                         log.fine("Exception caught while waiting: " + e);
 266                     }
 267                 } finally {
 268                     if (filter != null) {
 269                         dispatchThread.removeEventFilter(filter);
 270                     }
 271                 }
 272                 // If the waiting process has been stopped because of the
 273                 // time interval passed or an exception occurred, the state
 274                 // should be changed
 275                 keepBlockingEDT.set(false);
 276                 keepBlockingCT.set(false);
 277             }
 278         }
 279 
 280         return true;
 281     }
 282 
 283     /**
 284      * @inheritDoc
 285      */
 286     public boolean exit() {
 287         if (log.isLoggable(PlatformLogger.FINE)) {
 288             log.fine("exit(): blockingEDT=" + keepBlockingEDT.get() +
 289                      ", blockingCT=" + keepBlockingCT.get());
 290         }
 291         if (keepBlockingEDT.compareAndSet(true, false)) {
 292             wakeupEDT();
 293             return true;
 294         }
 295         return false;
 296     }
 297 
 298     private final static Object getTreeLock() {
 299         return Component.LOCK;
 300     }
 301 
 302     private final Runnable wakingRunnable = new Runnable() {
 303         public void run() {
 304             log.fine("Wake up EDT");
 305             synchronized (getTreeLock()) {
 306                 keepBlockingCT.set(false);
 307                 getTreeLock().notifyAll();
 308             }
 309             log.fine("Wake up EDT done");
 310         }
 311     };
 312 
 313     private void wakeupEDT() {
 314         if (log.isLoggable(PlatformLogger.FINEST)) {
 315             log.finest("wakeupEDT(): EDT == " + dispatchThread);
 316         }
 317         EventQueue eq = dispatchThread.getEventQueue();
 318         eq.postEvent(new PeerEvent(this, wakingRunnable, PeerEvent.PRIORITY_EVENT));
 319     }
 320 }