src/share/classes/java/awt/EventQueue.java

Print this page




  30 import java.awt.peer.ComponentPeer;
  31 
  32 import java.lang.ref.WeakReference;
  33 import java.lang.reflect.InvocationTargetException;
  34 
  35 import java.security.AccessController;
  36 import java.security.PrivilegedAction;
  37 
  38 import java.util.EmptyStackException;
  39 import sun.util.logging.PlatformLogger;
  40 
  41 import sun.awt.AppContext;
  42 import sun.awt.AWTAutoShutdown;
  43 import sun.awt.PeerEvent;
  44 import sun.awt.SunToolkit;
  45 import sun.awt.EventQueueItem;
  46 import sun.awt.AWTAccessor;
  47 
  48 import java.util.concurrent.locks.Condition;
  49 import java.util.concurrent.locks.Lock;

  50 
  51 import java.security.AccessControlContext;
  52 import java.security.ProtectionDomain;
  53 
  54 import sun.misc.SharedSecrets;
  55 import sun.misc.JavaSecurityAccess;
  56 
  57 /**
  58  * <code>EventQueue</code> is a platform-independent class
  59  * that queues events, both from the underlying peer classes
  60  * and from trusted application classes.
  61  * <p>
  62  * It encapsulates asynchronous event dispatch machinery which
  63  * extracts events from the queue and dispatches them by calling
  64  * {@link #dispatchEvent(AWTEvent) dispatchEvent(AWTEvent)} method
  65  * on this <code>EventQueue</code> with the event to be dispatched
  66  * as an argument.  The particular behavior of this machinery is
  67  * implementation-dependent.  The only requirements are that events
  68  * which were actually enqueued to this queue (note that events
  69  * being posted to the <code>EventQueue</code> can be coalesced)


  82  * Some browsers partition applets in different code bases into
  83  * separate contexts, and establish walls between these contexts.
  84  * In such a scenario, there will be one <code>EventQueue</code>
  85  * per context. Other browsers place all applets into the same
  86  * context, implying that there will be only a single, global
  87  * <code>EventQueue</code> for all applets. This behavior is
  88  * implementation-dependent.  Consult your browser's documentation
  89  * for more information.
  90  * <p>
  91  * For information on the threading issues of the event dispatch
  92  * machinery, see <a href="doc-files/AWTThreadIssues.html#Autoshutdown"
  93  * >AWT Threading Issues</a>.
  94  *
  95  * @author Thomas Ball
  96  * @author Fred Ecks
  97  * @author David Mendenhall
  98  *
  99  * @since       1.1
 100  */
 101 public class EventQueue {
 102 
 103     // From Thread.java
 104     private static int threadInitNumber;
 105     private static synchronized int nextThreadNum() {
 106         return threadInitNumber++;
 107     }
 108 
 109     private static final int LOW_PRIORITY = 0;
 110     private static final int NORM_PRIORITY = 1;
 111     private static final int HIGH_PRIORITY = 2;
 112     private static final int ULTIMATE_PRIORITY = 3;
 113 
 114     private static final int NUM_PRIORITIES = ULTIMATE_PRIORITY + 1;
 115 
 116     /*
 117      * We maintain one Queue for each priority that the EventQueue supports.
 118      * That is, the EventQueue object is actually implemented as
 119      * NUM_PRIORITIES queues and all Events on a particular internal Queue
 120      * have identical priority. Events are pulled off the EventQueue starting
 121      * with the Queue of highest priority. We progress in decreasing order
 122      * across all Queues.
 123      */
 124     private Queue[] queues = new Queue[NUM_PRIORITIES];
 125 
 126     /*
 127      * The next EventQueue on the stack, or null if this EventQueue is


 158     private final ThreadGroup threadGroup =
 159         Thread.currentThread().getThreadGroup();
 160     private final ClassLoader classLoader =
 161         Thread.currentThread().getContextClassLoader();
 162 
 163     /*
 164      * The time stamp of the last dispatched InputEvent or ActionEvent.
 165      */
 166     private long mostRecentEventTime = System.currentTimeMillis();
 167 
 168     /**
 169      * The modifiers field of the current event, if the current event is an
 170      * InputEvent or ActionEvent.
 171      */
 172     private WeakReference currentEvent;
 173 
 174     /*
 175      * Non-zero if a thread is waiting in getNextEvent(int) for an event of
 176      * a particular ID to be posted to the queue.
 177      */
 178     private int waitForID;
 179 
 180     private final String name = "AWT-EventQueue-" + nextThreadNum();
 181 
 182     private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventQueue");
 183 
 184     static {
 185         AWTAccessor.setEventQueueAccessor(
 186             new AWTAccessor.EventQueueAccessor() {
 187                 public Thread getDispatchThread(EventQueue eventQueue) {
 188                     return eventQueue.getDispatchThread();
 189                 }
 190                 public boolean isDispatchThreadImpl(EventQueue eventQueue) {
 191                     return eventQueue.isDispatchThreadImpl();
 192                 }
 193             });
 194     }
 195 
 196     public EventQueue() {
 197         for (int i = 0; i < NUM_PRIORITIES; i++) {
 198             queues[i] = new Queue();
 199         }
 200         /*


1013                         public EventDispatchThread run() {
1014                             EventDispatchThread t =
1015                                 new EventDispatchThread(threadGroup,
1016                                                         name,
1017                                                         EventQueue.this);
1018                             t.setContextClassLoader(classLoader);
1019                             t.setPriority(Thread.NORM_PRIORITY + 1);
1020                             t.setDaemon(false);
1021                             return t;
1022                         }
1023                     }
1024                 );
1025                 AWTAutoShutdown.getInstance().notifyThreadBusy(dispatchThread);
1026                 dispatchThread.start();
1027             }
1028         } finally {
1029             pushPopLock.unlock();
1030         }
1031     }
1032 
1033     final boolean detachDispatchThread(EventDispatchThread edt) {
1034         /*
1035          * This synchronized block is to secure that the event dispatch
1036          * thread won't die in the middle of posting a new event to the
1037          * associated event queue. It is important because we notify
1038          * that the event dispatch thread is busy after posting a new event
1039          * to its queue, so the EventQueue.dispatchThread reference must
1040          * be valid at that point.
1041          */
1042         pushPopLock.lock();
1043         try {
1044             if (edt == dispatchThread) {
1045                 /*
1046                  * Don't detach the thread if any events are pending. Not
1047                  * sure if it's a possible scenario, though.
1048                  *
1049                  * Fix for 4648733. Check both the associated java event
1050                  * queue and the PostEventQueue.
1051                  */
1052                 if ((peekEvent() != null) || !SunToolkit.isPostEventQueueEmpty()) {
1053                     return false;
1054                 }
1055                 dispatchThread = null;
1056             }
1057             AWTAutoShutdown.getInstance().notifyThreadFree(edt);
1058             return true;
1059         } finally {
1060             pushPopLock.unlock();
1061         }
1062     }
1063 
1064     /*
1065      * Gets the <code>EventDispatchThread</code> for this
1066      * <code>EventQueue</code>.
1067      * @return the event dispatch thread associated with this event queue
1068      *         or <code>null</code> if this event queue doesn't have a
1069      *         working thread associated with it
1070      * @see    java.awt.EventQueue#initDispatchThread
1071      * @see    java.awt.EventQueue#detachDispatchThread
1072      */




  30 import java.awt.peer.ComponentPeer;
  31 
  32 import java.lang.ref.WeakReference;
  33 import java.lang.reflect.InvocationTargetException;
  34 
  35 import java.security.AccessController;
  36 import java.security.PrivilegedAction;
  37 
  38 import java.util.EmptyStackException;
  39 import sun.util.logging.PlatformLogger;
  40 
  41 import sun.awt.AppContext;
  42 import sun.awt.AWTAutoShutdown;
  43 import sun.awt.PeerEvent;
  44 import sun.awt.SunToolkit;
  45 import sun.awt.EventQueueItem;
  46 import sun.awt.AWTAccessor;
  47 
  48 import java.util.concurrent.locks.Condition;
  49 import java.util.concurrent.locks.Lock;
  50 import java.util.concurrent.atomic.AtomicInteger;
  51 
  52 import java.security.AccessControlContext;
  53 import java.security.ProtectionDomain;
  54 
  55 import sun.misc.SharedSecrets;
  56 import sun.misc.JavaSecurityAccess;
  57 
  58 /**
  59  * <code>EventQueue</code> is a platform-independent class
  60  * that queues events, both from the underlying peer classes
  61  * and from trusted application classes.
  62  * <p>
  63  * It encapsulates asynchronous event dispatch machinery which
  64  * extracts events from the queue and dispatches them by calling
  65  * {@link #dispatchEvent(AWTEvent) dispatchEvent(AWTEvent)} method
  66  * on this <code>EventQueue</code> with the event to be dispatched
  67  * as an argument.  The particular behavior of this machinery is
  68  * implementation-dependent.  The only requirements are that events
  69  * which were actually enqueued to this queue (note that events
  70  * being posted to the <code>EventQueue</code> can be coalesced)


  83  * Some browsers partition applets in different code bases into
  84  * separate contexts, and establish walls between these contexts.
  85  * In such a scenario, there will be one <code>EventQueue</code>
  86  * per context. Other browsers place all applets into the same
  87  * context, implying that there will be only a single, global
  88  * <code>EventQueue</code> for all applets. This behavior is
  89  * implementation-dependent.  Consult your browser's documentation
  90  * for more information.
  91  * <p>
  92  * For information on the threading issues of the event dispatch
  93  * machinery, see <a href="doc-files/AWTThreadIssues.html#Autoshutdown"
  94  * >AWT Threading Issues</a>.
  95  *
  96  * @author Thomas Ball
  97  * @author Fred Ecks
  98  * @author David Mendenhall
  99  *
 100  * @since       1.1
 101  */
 102 public class EventQueue {
 103     private static final AtomicInteger threadInitNumber = new AtomicInteger(0);





 104 
 105     private static final int LOW_PRIORITY = 0;
 106     private static final int NORM_PRIORITY = 1;
 107     private static final int HIGH_PRIORITY = 2;
 108     private static final int ULTIMATE_PRIORITY = 3;
 109 
 110     private static final int NUM_PRIORITIES = ULTIMATE_PRIORITY + 1;
 111 
 112     /*
 113      * We maintain one Queue for each priority that the EventQueue supports.
 114      * That is, the EventQueue object is actually implemented as
 115      * NUM_PRIORITIES queues and all Events on a particular internal Queue
 116      * have identical priority. Events are pulled off the EventQueue starting
 117      * with the Queue of highest priority. We progress in decreasing order
 118      * across all Queues.
 119      */
 120     private Queue[] queues = new Queue[NUM_PRIORITIES];
 121 
 122     /*
 123      * The next EventQueue on the stack, or null if this EventQueue is


 154     private final ThreadGroup threadGroup =
 155         Thread.currentThread().getThreadGroup();
 156     private final ClassLoader classLoader =
 157         Thread.currentThread().getContextClassLoader();
 158 
 159     /*
 160      * The time stamp of the last dispatched InputEvent or ActionEvent.
 161      */
 162     private long mostRecentEventTime = System.currentTimeMillis();
 163 
 164     /**
 165      * The modifiers field of the current event, if the current event is an
 166      * InputEvent or ActionEvent.
 167      */
 168     private WeakReference currentEvent;
 169 
 170     /*
 171      * Non-zero if a thread is waiting in getNextEvent(int) for an event of
 172      * a particular ID to be posted to the queue.
 173      */
 174     private volatile int waitForID;
 175 
 176     private final String name = "AWT-EventQueue-" + threadInitNumber.getAndIncrement();
 177 
 178     private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventQueue");
 179 
 180     static {
 181         AWTAccessor.setEventQueueAccessor(
 182             new AWTAccessor.EventQueueAccessor() {
 183                 public Thread getDispatchThread(EventQueue eventQueue) {
 184                     return eventQueue.getDispatchThread();
 185                 }
 186                 public boolean isDispatchThreadImpl(EventQueue eventQueue) {
 187                     return eventQueue.isDispatchThreadImpl();
 188                 }
 189             });
 190     }
 191 
 192     public EventQueue() {
 193         for (int i = 0; i < NUM_PRIORITIES; i++) {
 194             queues[i] = new Queue();
 195         }
 196         /*


1009                         public EventDispatchThread run() {
1010                             EventDispatchThread t =
1011                                 new EventDispatchThread(threadGroup,
1012                                                         name,
1013                                                         EventQueue.this);
1014                             t.setContextClassLoader(classLoader);
1015                             t.setPriority(Thread.NORM_PRIORITY + 1);
1016                             t.setDaemon(false);
1017                             return t;
1018                         }
1019                     }
1020                 );
1021                 AWTAutoShutdown.getInstance().notifyThreadBusy(dispatchThread);
1022                 dispatchThread.start();
1023             }
1024         } finally {
1025             pushPopLock.unlock();
1026         }
1027     }
1028 
1029     final boolean detachDispatchThread(EventDispatchThread edt, boolean forceDetach) {
1030         /*
1031          * This synchronized block is to secure that the event dispatch
1032          * thread won't die in the middle of posting a new event to the
1033          * associated event queue. It is important because we notify
1034          * that the event dispatch thread is busy after posting a new event
1035          * to its queue, so the EventQueue.dispatchThread reference must
1036          * be valid at that point.
1037          */
1038         pushPopLock.lock();
1039         try {
1040             if (edt == dispatchThread) {
1041                 /*
1042                  * Don't detach the thread if any events are pending. Not
1043                  * sure if it's a possible scenario, though.
1044                  *
1045                  * Fix for 4648733. Check both the associated java event
1046                  * queue and the PostEventQueue.
1047                  */
1048                 if (!forceDetach && (peekEvent() != null) || !SunToolkit.isPostEventQueueEmpty()) {
1049                     return false;
1050                 }
1051                 dispatchThread = null;
1052             }
1053             AWTAutoShutdown.getInstance().notifyThreadFree(edt);
1054             return true;
1055         } finally {
1056             pushPopLock.unlock();
1057         }
1058     }
1059 
1060     /*
1061      * Gets the <code>EventDispatchThread</code> for this
1062      * <code>EventQueue</code>.
1063      * @return the event dispatch thread associated with this event queue
1064      *         or <code>null</code> if this event queue doesn't have a
1065      *         working thread associated with it
1066      * @see    java.awt.EventQueue#initDispatchThread
1067      * @see    java.awt.EventQueue#detachDispatchThread
1068      */