is a platform-independent class
that queues events, both from the underlying peer classes
and from trusted application classes.
It encapsulates asynchronous event dispatch machinery which
extracts events from the queue and dispatches them by calling
dispatchEvent(AWTEvent) method
on this EventQueue with the event to be dispatched
as an argument. The particular behavior of this machinery is
implementation-dependent. The only requirements are that events
which were actually enqueued to this queue (note that events
being posted to the EventQueue can be coalesced)
are dispatched:
Some browsers partition applets in different code bases into
separate contexts, and establish walls between these contexts.
In such a scenario, there will be one EventQueue
per context. Other browsers place all applets into the same
context, implying that there will be only a single, global
EventQueue for all applets. This behavior is
implementation-dependent. Consult your browser's documentation
for more information.
| Method from java.awt.EventQueue Detail: |
public SecondaryLoop createSecondaryLoop() {
return createSecondaryLoop(null, null, 0);
}
Creates a new {@code secondary loop} associated with this
event queue. Use the SecondaryLoop#enter and
SecondaryLoop#exit methods to start and stop the
event loop and dispatch the events from this queue. |
SecondaryLoop createSecondaryLoop(Conditional cond,
EventFilter filter,
long interval) {
pushPopLock.lock();
try {
if (nextQueue != null) {
// Forward the request to the top of EventQueue stack
return nextQueue.createSecondaryLoop(cond, filter, interval);
}
if (dispatchThread == null) {
initDispatchThread();
}
return new WaitDispatchSupport(dispatchThread, cond, filter, interval);
} finally {
pushPopLock.unlock();
}
}
|
final boolean detachDispatchThread(EventDispatchThread edt) {
/*
* This synchronized block is to secure that the event dispatch
* thread won't die in the middle of posting a new event to the
* associated event queue. It is important because we notify
* that the event dispatch thread is busy after posting a new event
* to its queue, so the EventQueue.dispatchThread reference must
* be valid at that point.
*/
pushPopLock.lock();
try {
if (edt == dispatchThread) {
/*
* Don't detach the thread if any events are pending. Not
* sure if it's a possible scenario, though.
*
* Fix for 4648733. Check both the associated java event
* queue and the PostEventQueue.
*/
if ((peekEvent() != null) || !SunToolkit.isPostEventQueueEmpty()) {
return false;
}
dispatchThread = null;
}
AWTAutoShutdown.getInstance().notifyThreadFree(edt);
return true;
} finally {
pushPopLock.unlock();
}
}
|
protected void dispatchEvent(AWTEvent event) {
final Object src = event.getSource();
final PrivilegedAction< Void > action = new PrivilegedAction< Void >() {
public Void run() {
dispatchEventImpl(event, src);
return null;
}
};
final AccessControlContext stack = AccessController.getContext();
final AccessControlContext srcAcc = getAccessControlContextFrom(src);
final AccessControlContext eventAcc = event.getAccessControlContext();
if (srcAcc == null) {
javaSecurityAccess.doIntersectionPrivilege(action, stack, eventAcc);
} else {
javaSecurityAccess.doIntersectionPrivilege(
new PrivilegedAction< Void >() {
public Void run() {
javaSecurityAccess.doIntersectionPrivilege(action, eventAcc);
return null;
}
}, stack, srcAcc);
}
}
Dispatches an event. The manner in which the event is
dispatched depends upon the type of the event and the
type of the event's source object:
| Event Type |
Source Type |
Dispatched To |
| ActiveEvent |
Any |
event.dispatch() |
| Other |
Component |
source.dispatchEvent(AWTEvent) |
| Other |
MenuComponent |
source.dispatchEvent(AWTEvent) |
| Other |
Other |
No action (ignored) |
|
public static AWTEvent getCurrentEvent() {
return Toolkit.getEventQueue().getCurrentEventImpl();
}
Returns the the event currently being dispatched by the
EventQueue associated with the calling thread. This is
useful if a method needs access to the event, but was not designed to
receive a reference to it as an argument. Note that this method should
only be invoked from an application's event dispatching thread. If this
method is invoked from another thread, null will be returned. |
final EventDispatchThread getDispatchThread() {
pushPopLock.lock();
try {
return dispatchThread;
} finally {
pushPopLock.unlock();
}
}
|
public static long getMostRecentEventTime() {
return Toolkit.getEventQueue().getMostRecentEventTimeImpl();
}
Returns the timestamp of the most recent event that had a timestamp, and
that was dispatched from the EventQueue associated with the
calling thread. If an event with a timestamp is currently being
dispatched, its timestamp will be returned. If no events have yet
been dispatched, the EventQueue's initialization time will be
returned instead.In the current version of
the JDK, only InputEvents,
ActionEvents, and InvocationEvents have
timestamps; however, future versions of the JDK may add timestamps to
additional event types. Note that this method should only be invoked
from an application's event dispatching thread .
If this method is
invoked from another thread, the current system time (as reported by
System.currentTimeMillis()) will be returned instead. |
long getMostRecentEventTimeEx() {
pushPopLock.lock();
try {
return mostRecentEventTime;
} finally {
pushPopLock.unlock();
}
}
|
public AWTEvent getNextEvent() throws InterruptedException {
do {
/*
* SunToolkit.flushPendingEvents must be called outside
* of the synchronized block to avoid deadlock when
* event queues are nested with push()/pop().
*/
SunToolkit.flushPendingEvents();
pushPopLock.lock();
try {
AWTEvent event = getNextEventPrivate();
if (event != null) {
return event;
}
AWTAutoShutdown.getInstance().notifyThreadFree(dispatchThread);
pushPopCond.await();
} finally {
pushPopLock.unlock();
}
} while(true);
}
Removes an event from the EventQueue and
returns it. This method will block until an event has
been posted by another thread. |
AWTEvent getNextEvent(int id) throws InterruptedException {
do {
/*
* SunToolkit.flushPendingEvents must be called outside
* of the synchronized block to avoid deadlock when
* event queues are nested with push()/pop().
*/
SunToolkit.flushPendingEvents();
pushPopLock.lock();
try {
for (int i = 0; i < NUM_PRIORITIES; i++) {
for (EventQueueItem entry = queues[i].head, prev = null;
entry != null; prev = entry, entry = entry.next)
{
if (entry.event.getID() == id) {
if (prev == null) {
queues[i].head = entry.next;
} else {
prev.next = entry.next;
}
if (queues[i].tail == entry) {
queues[i].tail = prev;
}
uncacheEQItem(entry);
return entry.event;
}
}
}
waitForID = id;
pushPopCond.await();
waitForID = 0;
} finally {
pushPopLock.unlock();
}
} while(true);
}
|
AWTEvent getNextEventPrivate() throws InterruptedException {
for (int i = NUM_PRIORITIES - 1; i >= 0; i--) {
if (queues[i].head != null) {
EventQueueItem entry = queues[i].head;
queues[i].head = entry.next;
if (entry.next == null) {
queues[i].tail = null;
}
uncacheEQItem(entry);
return entry.event;
}
}
return null;
}
|
final void initDispatchThread() {
pushPopLock.lock();
try {
AppContext appContext = AppContext.getAppContext();
if (dispatchThread == null && !threadGroup.isDestroyed() && !appContext.isDisposed()) {
dispatchThread = AccessController.doPrivileged(
new PrivilegedAction< EventDispatchThread >() {
public EventDispatchThread run() {
EventDispatchThread t =
new EventDispatchThread(threadGroup,
name,
EventQueue.this);
t.setContextClassLoader(classLoader);
t.setPriority(Thread.NORM_PRIORITY + 1);
t.setDaemon(false);
return t;
}
}
);
AWTAutoShutdown.getInstance().notifyThreadBusy(dispatchThread);
dispatchThread.start();
}
} finally {
pushPopLock.unlock();
}
}
|
public static void invokeAndWait(Runnable runnable) throws InterruptedException, InvocationTargetException {
if (EventQueue.isDispatchThread()) {
throw new Error("Cannot call invokeAndWait from the event dispatcher thread");
}
class AWTInvocationLock {}
Object lock = new AWTInvocationLock();
InvocationEvent event =
new InvocationEvent(Toolkit.getDefaultToolkit(), runnable, lock,
true);
synchronized (lock) {
Toolkit.getEventQueue().postEvent(event);
while (!event.isDispatched()) {
lock.wait();
}
}
Throwable eventThrowable = event.getThrowable();
if (eventThrowable != null) {
throw new InvocationTargetException(eventThrowable);
}
}
|
public static void invokeLater(Runnable runnable) {
Toolkit.getEventQueue().postEvent(
new InvocationEvent(Toolkit.getDefaultToolkit(), runnable));
}
|
public static boolean isDispatchThread() {
EventQueue eq = Toolkit.getEventQueue();
return eq.isDispatchThreadImpl();
}
|
final boolean isDispatchThreadImpl() {
EventQueue eq = this;
pushPopLock.lock();
try {
EventQueue next = eq.nextQueue;
while (next != null) {
eq = next;
next = eq.nextQueue;
}
return (Thread.currentThread() == eq.dispatchThread);
} finally {
pushPopLock.unlock();
}
}
|
public AWTEvent peekEvent() {
pushPopLock.lock();
try {
for (int i = NUM_PRIORITIES - 1; i >= 0; i--) {
if (queues[i].head != null) {
return queues[i].head.event;
}
}
} finally {
pushPopLock.unlock();
}
return null;
}
Returns the first event on the EventQueue
without removing it. |
public AWTEvent peekEvent(int id) {
pushPopLock.lock();
try {
for (int i = NUM_PRIORITIES - 1; i >= 0; i--) {
EventQueueItem q = queues[i].head;
for (; q != null; q = q.next) {
if (q.event.getID() == id) {
return q.event;
}
}
}
} finally {
pushPopLock.unlock();
}
return null;
}
Returns the first event with the specified id, if any. |
protected void pop() throws EmptyStackException {
if (eventLog.isLoggable(PlatformLogger.FINE)) {
eventLog.fine("EventQueue.pop(" + this + ")");
}
pushPopLock.lock();
try {
EventQueue topQueue = this;
while (topQueue.nextQueue != null) {
topQueue = topQueue.nextQueue;
}
EventQueue prevQueue = topQueue.previousQueue;
if (prevQueue == null) {
throw new EmptyStackException();
}
topQueue.previousQueue = null;
prevQueue.nextQueue = null;
// Transfer all events back to previous EventQueue.
while (topQueue.peekEvent() != null) {
try {
prevQueue.postEventPrivate(topQueue.getNextEventPrivate());
} catch (InterruptedException ie) {
if (eventLog.isLoggable(PlatformLogger.FINE)) {
eventLog.fine("Interrupted pop", ie);
}
}
}
if ((topQueue.dispatchThread != null) &&
(topQueue.dispatchThread.getEventQueue() == this))
{
prevQueue.dispatchThread = topQueue.dispatchThread;
topQueue.dispatchThread.setEventQueue(prevQueue);
}
AppContext appContext = AppContext.getAppContext();
if (appContext.get(AppContext.EVENT_QUEUE_KEY) == this) {
appContext.put(AppContext.EVENT_QUEUE_KEY, prevQueue);
}
// Wake up EDT waiting in getNextEvent(), so it can
// pick up a new EventQueue
topQueue.postEventPrivate(new InvocationEvent(topQueue, dummyRunnable));
pushPopCond.signalAll();
} finally {
pushPopLock.unlock();
}
}
Stops dispatching events using this EventQueue.
Any pending events are transferred to the previous
EventQueue for processing.
Warning: To avoid deadlock, do not declare this method
synchronized in a subclass. |
public void postEvent(AWTEvent theEvent) {
SunToolkit.flushPendingEvents();
postEventPrivate(theEvent);
}
Posts a 1.1-style event to the EventQueue.
If there is an existing event on the queue with the same ID
and event source, the source Component's
coalesceEvents method will be called. |
public void push(EventQueue newEventQueue) {
if (eventLog.isLoggable(PlatformLogger.FINE)) {
eventLog.fine("EventQueue.push(" + newEventQueue + ")");
}
pushPopLock.lock();
try {
EventQueue topQueue = this;
while (topQueue.nextQueue != null) {
topQueue = topQueue.nextQueue;
}
if ((topQueue.dispatchThread != null) &&
(topQueue.dispatchThread.getEventQueue() == this))
{
newEventQueue.dispatchThread = topQueue.dispatchThread;
topQueue.dispatchThread.setEventQueue(newEventQueue);
}
// Transfer all events forward to new EventQueue.
while (topQueue.peekEvent() != null) {
try {
// Use getNextEventPrivate() as it doesn't call flushPendingEvents()
newEventQueue.postEventPrivate(topQueue.getNextEventPrivate());
} catch (InterruptedException ie) {
if (eventLog.isLoggable(PlatformLogger.FINE)) {
eventLog.fine("Interrupted push", ie);
}
}
}
// Wake up EDT waiting in getNextEvent(), so it can
// pick up a new EventQueue. Post the waking event before
// topQueue.nextQueue is assigned, otherwise the event would
// go newEventQueue
topQueue.postEventPrivate(new InvocationEvent(topQueue, dummyRunnable));
newEventQueue.previousQueue = topQueue;
topQueue.nextQueue = newEventQueue;
AppContext appContext = AppContext.getAppContext();
if (appContext.get(AppContext.EVENT_QUEUE_KEY) == topQueue) {
appContext.put(AppContext.EVENT_QUEUE_KEY, newEventQueue);
}
pushPopCond.signalAll();
} finally {
pushPopLock.unlock();
}
}
Replaces the existing EventQueue with the specified one.
Any pending events are transferred to the new EventQueue
for processing by it. |
final void removeSourceEvents(Object source,
boolean removeAllEvents) {
SunToolkit.flushPendingEvents();
pushPopLock.lock();
try {
for (int i = 0; i < NUM_PRIORITIES; i++) {
EventQueueItem entry = queues[i].head;
EventQueueItem prev = null;
while (entry != null) {
if ((entry.event.getSource() == source)
&& (removeAllEvents
|| ! (entry.event instanceof SequencedEvent
|| entry.event instanceof SentEvent
|| entry.event instanceof FocusEvent
|| entry.event instanceof WindowEvent
|| entry.event instanceof KeyEvent
|| entry.event instanceof InputMethodEvent)))
{
if (entry.event instanceof SequencedEvent) {
((SequencedEvent)entry.event).dispose();
}
if (entry.event instanceof SentEvent) {
((SentEvent)entry.event).dispose();
}
if (prev == null) {
queues[i].head = entry.next;
} else {
prev.next = entry.next;
}
uncacheEQItem(entry);
} else {
prev = entry;
}
entry = entry.next;
}
queues[i].tail = prev;
}
} finally {
pushPopLock.unlock();
}
}
|
static void setCurrentEventAndMostRecentTime(AWTEvent e) {
Toolkit.getEventQueue().setCurrentEventAndMostRecentTimeImpl(e);
}
|