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: |
final void detachDispatchThread() {
dispatchThread = null;
}
|
protected void dispatchEvent(AWTEvent event) {
event.isPosted = true;
Object src = event.getSource();
if (event instanceof ActiveEvent) {
// This could become the sole method of dispatching in time.
setCurrentEventAndMostRecentTimeImpl(event);
((ActiveEvent)event).dispatch();
} else if (src instanceof Component) {
((Component)src).dispatchEvent(event);
event.dispatched();
} else if (src instanceof MenuComponent) {
((MenuComponent)src).dispatchEvent(event);
} else if (src instanceof TrayIcon) {
((TrayIcon)src).dispatchEvent(event);
} else if (src instanceof AWTAutoShutdown) {
if (noEvents()) {
dispatchThread.stopDispatching();
}
} else {
System.err.println("unable to dispatch event: " + event);
}
}
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() {
return dispatchThread;
}
|
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. |
synchronized long getMostRecentEventTimeEx() {
return mostRecentEventTime;
}
|
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();
synchronized (this) {
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;
}
}
AWTAutoShutdown.getInstance().notifyThreadFree(dispatchThread);
wait();
}
} 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();
synchronized (this) {
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.id == 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;
}
}
}
this.waitForID = id;
wait();
this.waitForID = 0;
}
} while(true);
}
|
final void initDispatchThread() {
synchronized (this) {
if (dispatchThread == null && !threadGroup.isDestroyed()) {
dispatchThread = (EventDispatchThread)
AccessController.doPrivileged(new PrivilegedAction() {
public Object 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();
}
}
}
|
public static void invokeAndWait(Runnable runnable) throws InvocationTargetException, InterruptedException {
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);
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();
EventQueue next = eq.nextQueue;
while (next != null) {
eq = next;
next = eq.nextQueue;
}
return (Thread.currentThread() == eq.dispatchThread);
}
|
public synchronized AWTEvent peekEvent() {
for (int i = NUM_PRIORITIES - 1; i >= 0; i--) {
if (queues[i].head != null) {
return queues[i].head.event;
}
}
return null;
}
Returns the first event on the EventQueue
without removing it. |
public synchronized AWTEvent peekEvent(int id) {
for (int i = NUM_PRIORITIES - 1; i >= 0; i--) {
EventQueueItem q = queues[i].head;
for (; q != null; q = q.next) {
if (q.id == id) {
return q.event;
}
}
}
return null;
}
Returns the first event with the specified id, if any. |
protected void pop() throws EmptyStackException {
if (eventLog.isLoggable(Level.FINE)) {
eventLog.log(Level.FINE, "EventQueue.pop(" + this + ")");
}
// To prevent deadlock, we lock on the previous EventQueue before
// this one. This uses the same locking order as everything else
// in EventQueue.java, so deadlock isn't possible.
EventQueue prev = previousQueue;
synchronized ((prev != null) ? prev : this) {
synchronized(this) {
if (nextQueue != null) {
nextQueue.pop();
return;
}
if (previousQueue == null) {
throw new EmptyStackException();
}
// Transfer all events back to previous EventQueue.
previousQueue.nextQueue = null;
while (peekEvent() != null) {
try {
previousQueue.postEventPrivate(getNextEvent());
} catch (InterruptedException ie) {
if (eventLog.isLoggable(Level.FINE)) {
eventLog.log(Level.FINE, "Interrupted pop", ie);
}
}
}
AppContext appContext = AppContext.getAppContext();
if (appContext.get(AppContext.EVENT_QUEUE_KEY) == this) {
appContext.put(AppContext.EVENT_QUEUE_KEY, previousQueue);
}
previousQueue = null;
}
}
EventDispatchThread dt = this.dispatchThread;
if (dt != null) {
dt.stopDispatching(); // Must be done outside synchronized
// block to avoid possible deadlock
}
}
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. |
final void postEventPrivate(AWTEvent theEvent) {
theEvent.isPosted = true;
synchronized(this) {
if (dispatchThread == null && nextQueue == null) {
if (theEvent.getSource() == AWTAutoShutdown.getInstance()) {
return;
} else {
initDispatchThread();
}
}
if (nextQueue != null) {
// Forward event to top of EventQueue stack.
nextQueue.postEventPrivate(theEvent);
return;
}
postEvent(theEvent, getPriority(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 synchronized void push(EventQueue newEventQueue) {
if (eventLog.isLoggable(Level.FINE)) {
eventLog.log(Level.FINE, "EventQueue.push(" + newEventQueue + ")");
}
if (nextQueue != null) {
nextQueue.push(newEventQueue);
return;
}
synchronized (newEventQueue) {
// Transfer all events forward to new EventQueue.
while (peekEvent() != null) {
try {
newEventQueue.postEventPrivate(getNextEvent());
} catch (InterruptedException ie) {
if (eventLog.isLoggable(Level.FINE)) {
eventLog.log(Level.FINE, "Interrupted push", ie);
}
}
}
newEventQueue.previousQueue = this;
}
/*
* Stop the event dispatch thread associated with the currently
* active event queue, so that after the new queue is pushed
* on the top this event dispatch thread won't prevent AWT from
* being automatically shut down.
* Use stopDispatchingLater() to avoid deadlock: stopDispatching()
* waits for the dispatch thread to exit, so if the dispatch
* thread attempts to synchronize on this EventQueue object
* it will never exit since we already hold this lock.
*/
if (dispatchThread != null) {
dispatchThread.stopDispatchingLater();
}
nextQueue = newEventQueue;
AppContext appContext = AppContext.getAppContext();
if (appContext.get(AppContext.EVENT_QUEUE_KEY) == this) {
appContext.put(AppContext.EVENT_QUEUE_KEY, newEventQueue);
}
}
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();
synchronized (this) {
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;
}
}
}
|
static void setCurrentEventAndMostRecentTime(AWTEvent e) {
Toolkit.getEventQueue().setCurrentEventAndMostRecentTimeImpl(e);
}
|