/** Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.*********************/package java.awt;import java.util.Timer;import java.util.TimerTask;import java.util.concurrent.atomic.AtomicBoolean;import java.security.PrivilegedAction;import java.security.AccessController;import sun.awt.PeerEvent;import sun.util.logging.PlatformLogger;/*** This utility class is used to suspend execution on a thread* while still allowing {@code EventDispatchThread} to dispatch events.* The API methods of the class are thread-safe.** @author Anton Tarasov, Artem Ananiev** @since 1.7*/class WaitDispatchSupport implements SecondaryLoop {private final static PlatformLogger log =PlatformLogger.getLogger("java.awt.event.WaitDispatchSupport");private EventDispatchThread dispatchThread;private EventFilter filter;private volatile Conditional extCondition;private volatile Conditional condition;private long interval;// Use a shared daemon timer to serve all the WaitDispatchSupportsprivate static Timer timer;// When this WDS expires, we cancel the timer task leaving the// shared timer up and runningprivate TimerTask timerTask;private AtomicBoolean keepBlockingEDT = new AtomicBoolean(false);private AtomicBoolean keepBlockingCT = new AtomicBoolean(false);private AtomicBoolean afterExit = new AtomicBoolean(false);private static synchronized void initializeTimer() {if (timer == null) {timer = new Timer("AWT-WaitDispatchSupport-Timer", true);}}/*** Creates a {@code WaitDispatchSupport} instance to* serve the given event dispatch thread.** @param dispatchThread An event dispatch thread that* should not stop dispatching events while waiting** @since 1.7*/public WaitDispatchSupport(EventDispatchThread dispatchThread) {this(dispatchThread, null);}/*** Creates a {@code WaitDispatchSupport} instance to* serve the given event dispatch thread.** @param dispatchThread An event dispatch thread that* should not stop dispatching events while waiting* @param extCond A conditional object used to determine* if the loop should be terminated** @since 1.7*/public WaitDispatchSupport(EventDispatchThread dispatchThread,Conditional extCond){if (dispatchThread == null) {throw new IllegalArgumentException("The dispatchThread can not be null");}this.dispatchThread = dispatchThread;this.extCondition = extCond;this.condition = new Conditional() {@Overridepublic boolean evaluate() {if (log.isLoggable(PlatformLogger.Level.FINEST)) {log.finest("evaluate(): blockingEDT=" + keepBlockingEDT.get() +", blockingCT=" + keepBlockingCT.get());}boolean extEvaluate =(extCondition != null) ? extCondition.evaluate() : true;if (!keepBlockingEDT.get() || !extEvaluate) {if (timerTask != null) {timerTask.cancel();timerTask = null;}return false;}return true;}};}/*** Creates a {@code WaitDispatchSupport} instance to* serve the given event dispatch thread.* <p>* The {@link EventFilter} is set on the {@code dispatchThread}* while waiting. The filter is removed on completion of the* waiting process.* <p>*** @param dispatchThread An event dispatch thread that* should not stop dispatching events while waiting* @param filter {@code EventFilter} to be set* @param interval A time interval to wait for. Note that* when the waiting process takes place on EDT* there is no guarantee to stop it in the given time** @since 1.7*/public WaitDispatchSupport(EventDispatchThread dispatchThread,Conditional extCondition,EventFilter filter, long interval){this(dispatchThread, extCondition);this.filter = filter;if (interval < 0) {throw new IllegalArgumentException("The interval value must be >= 0");}this.interval = interval;if (interval != 0) {initializeTimer();}}/*** {@inheritDoc}*/@Overridepublic boolean enter() {if (log.isLoggable(PlatformLogger.Level.FINE)) {log.fine("enter(): blockingEDT=" + keepBlockingEDT.get() +", blockingCT=" + keepBlockingCT.get());}if (!keepBlockingEDT.compareAndSet(false, true)) {log.fine("The secondary loop is already running, aborting");return false;}try {if (afterExit.get()) {log.fine("Exit was called already, aborting");return false;}final Runnable run = new Runnable() {public void run() {log.fine("Starting a new event pump");if (filter == null) {dispatchThread.pumpEvents(condition);} else {dispatchThread.pumpEventsForFilter(condition, filter);}}};// We have two mechanisms for blocking: if we're on the// dispatch thread, start a new event pump; if we're// on any other thread, call wait() on the treelockThread currentThread = Thread.currentThread();if (currentThread == dispatchThread) {if (log.isLoggable(PlatformLogger.Level.FINEST)) {log.finest("On dispatch thread: " + dispatchThread);}if (interval != 0) {if (log.isLoggable(PlatformLogger.Level.FINEST)) {log.finest("scheduling the timer for " + interval + " ms");}timer.schedule(timerTask = new TimerTask() {@Overridepublic void run() {if (keepBlockingEDT.compareAndSet(true, false)) {wakeupEDT();}}}, interval);}// Dispose SequencedEvent we are dispatching on the current// AppContext, to prevent us from hang - see 4531693 for detailsSequencedEvent currentSE = KeyboardFocusManager.getCurrentKeyboardFocusManager().getCurrentSequencedEvent();if (currentSE != null) {if (log.isLoggable(PlatformLogger.Level.FINE)) {log.fine("Dispose current SequencedEvent: " + currentSE);}currentSE.dispose();}// In case the exit() method is called before starting// new event pump it will post the waking event to EDT.// The event will be handled after the new event pump// starts. Thus, the enter() method will not hang.//// Event pump should be privileged. See 6300270.AccessController.doPrivileged(new PrivilegedAction<Void>() {public Void run() {run.run();return null;}});} else {if (log.isLoggable(PlatformLogger.Level.FINEST)) {log.finest("On non-dispatch thread: " + currentThread);}keepBlockingCT.set(true);synchronized (getTreeLock()) {if (afterExit.get()) return false;if (filter != null) {dispatchThread.addEventFilter(filter);}try {EventQueue eq = dispatchThread.getEventQueue();eq.postEvent(new PeerEvent(this, run, PeerEvent.PRIORITY_EVENT));if (interval > 0) {long currTime = System.currentTimeMillis();while (keepBlockingCT.get() &&((extCondition != null) ? extCondition.evaluate() : true) &&(currTime + interval > System.currentTimeMillis())){getTreeLock().wait(interval);}} else {while (keepBlockingCT.get() &&((extCondition != null) ? extCondition.evaluate() : true)){getTreeLock().wait();}}if (log.isLoggable(PlatformLogger.Level.FINE)) {log.fine("waitDone " + keepBlockingEDT.get() + " " + keepBlockingCT.get());}} catch (InterruptedException e) {if (log.isLoggable(PlatformLogger.Level.FINE)) {log.fine("Exception caught while waiting: " + e);}} finally {if (filter != null) {dispatchThread.removeEventFilter(filter);}}}}return true;}finally {keepBlockingEDT.set(false);keepBlockingCT.set(false);afterExit.set(false);}}/*** {@inheritDoc}*/public boolean exit() {if (log.isLoggable(PlatformLogger.Level.FINE)) {log.fine("exit(): blockingEDT=" + keepBlockingEDT.get() +", blockingCT=" + keepBlockingCT.get());}afterExit.set(true);if (keepBlockingEDT.getAndSet(false)) {wakeupEDT();return true;}return false;}private final static Object getTreeLock() {return Component.LOCK;}private final Runnable wakingRunnable = new Runnable() {public void run() {log.fine("Wake up EDT");synchronized (getTreeLock()) {keepBlockingCT.set(false);getTreeLock().notifyAll();}log.fine("Wake up EDT done");}};private void wakeupEDT() {if (log.isLoggable(PlatformLogger.Level.FINEST)) {log.finest("wakeupEDT(): EDT == " + dispatchThread);}EventQueue eq = dispatchThread.getEventQueue();eq.postEvent(new PeerEvent(this, wakingRunnable, PeerEvent.PRIORITY_EVENT));}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。