|
null
* @since 1.2
*/
protected void dispatchEvent(final AWTEvent event) {
final Object src = event.getSource();
final PrivilegedAction<Void> action = new PrivilegedActionInvocationEvent
s 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 {@link #isDispatchThread event dispatching thread}.
* If this method is
* invoked from another thread, the current system time (as reported by
* <code>System.currentTimeMillis()) will be returned instead.
*
* @return the timestamp of the last <code>InputEvent,
* <code>ActionEvent, or InvocationEvent
to be
* dispatched, or <code>System.currentTimeMillis() if this
* method is invoked on a thread other than an event dispatching
* thread
* @see java.awt.event.InputEvent#getWhen
* @see java.awt.event.ActionEvent#getWhen
* @see java.awt.event.InvocationEvent#getWhen
* @see #isDispatchThread
*
* @since 1.4
*/
public static long getMostRecentEventTime() {
return Toolkit.getEventQueue().getMostRecentEventTimeImpl();
}
private long getMostRecentEventTimeImpl() {
pushPopLock.lock();
try {
return (Thread.currentThread() == dispatchThread)
? mostRecentEventTime
: System.currentTimeMillis();
} finally {
pushPopLock.unlock();
}
}
/**
* @return most recent event time on all threads.
*/
long getMostRecentEventTimeEx() {
pushPopLock.lock();
try {
return mostRecentEventTime;
} finally {
pushPopLock.unlock();
}
}
/**
* Returns the the event currently being dispatched by the
* <code>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.
*
* @return the event currently being dispatched, or null if this method is
* invoked on a thread other than an event dispatching thread
* @since 1.4
*/
public static AWTEvent getCurrentEvent() {
return Toolkit.getEventQueue().getCurrentEventImpl();
}
private AWTEvent getCurrentEventImpl() {
pushPopLock.lock();
try {
return (Thread.currentThread() == dispatchThread)
? currentEvent.get()
: null;
} finally {
pushPopLock.unlock();
}
}
/**
* Replaces the existing <code>EventQueue with the specified one.
* Any pending events are transferred to the new <code>EventQueue
* for processing by it.
*
* @param newEventQueue an <code>EventQueue
* (or subclass thereof) instance to be use
* @see java.awt.EventQueue#pop
* @throws NullPointerException if <code>newEventQueue is null
* @since 1.2
*/
public void push(EventQueue newEventQueue) {
if (eventLog.isLoggable(PlatformLogger.Level.FINE)) {
eventLog.fine("EventQueue.push(" + newEventQueue + ")");
}
pushPopLock.lock();
try {
EventQueue topQueue = this;
while (topQueue.nextQueue != null) {
topQueue = topQueue.nextQueue;
}
if (topQueue.fwDispatcher != null) {
throw new RuntimeException("push() to queue with fwDispatcher");
}
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.Level.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;
if (appContext.get(AppContext.EVENT_QUEUE_KEY) == topQueue) {
appContext.put(AppContext.EVENT_QUEUE_KEY, newEventQueue);
}
pushPopCond.signalAll();
} finally {
pushPopLock.unlock();
}
}
/**
* Stops dispatching events using this <code>EventQueue.
* Any pending events are transferred to the previous
* <code>EventQueue for processing.
* <p>
* Warning: To avoid deadlock, do not declare this method
* synchronized in a subclass.
*
* @exception EmptyStackException if no previous push was made
* on this <code>EventQueue
* @see java.awt.EventQueue#push
* @since 1.2
*/
protected void pop() throws EmptyStackException {
if (eventLog.isLoggable(PlatformLogger.Level.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.Level.FINE)) {
eventLog.fine("Interrupted pop", ie);
}
}
}
if ((topQueue.dispatchThread != null) &&
(topQueue.dispatchThread.getEventQueue() == this))
{
prevQueue.dispatchThread = topQueue.dispatchThread;
topQueue.dispatchThread.setEventQueue(prevQueue);
}
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();
}
}
/**
* Creates a new {@code secondary loop} associated with this
* event queue. Use the {@link SecondaryLoop#enter} and
* {@link SecondaryLoop#exit} methods to start and stop the
* event loop and dispatch the events from this queue.
*
* @return secondaryLoop A new secondary loop object, which can
* be used to launch a new nested event
* loop and dispatch events from this queue
*
* @see SecondaryLoop#enter
* @see SecondaryLoop#exit
*
* @since 1.7
*/
public SecondaryLoop createSecondaryLoop() {
return createSecondaryLoop(null, null, 0);
}
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 (fwDispatcher != null) {
return fwDispatcher.createSecondaryLoop();
}
if (dispatchThread == null) {
initDispatchThread();
}
return new WaitDispatchSupport(dispatchThread, cond, filter, interval);
} finally {
pushPopLock.unlock();
}
}
/**
* Returns true if the calling thread is
* {@link Toolkit#getSystemEventQueue the current AWT EventQueue}'s
* dispatch thread. Use this method to ensure that a particular
* task is being executed (or not being) there.
* <p>
* Note: use the {@link #invokeLater} or {@link #invokeAndWait}
* methods to execute a task in
* {@link Toolkit#getSystemEventQueue the current AWT EventQueue}'s
* dispatch thread.
* <p>
*
* @return true if running in
* {@link Toolkit#getSystemEventQueue the current AWT EventQueue}'s
* dispatch thread
* @see #invokeLater
* @see #invokeAndWait
* @see Toolkit#getSystemEventQueue
* @since 1.2
*/
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;
}
if (eq.fwDispatcher != null) {
return eq.fwDispatcher.isDispatchThread();
}
return (Thread.currentThread() == eq.dispatchThread);
} finally {
pushPopLock.unlock();
}
}
final void initDispatchThread() {
pushPopLock.lock();
try {
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();
}
}
final void detachDispatchThread(EventDispatchThread edt) {
/*
* Minimize discard possibility for non-posted events
*/
SunToolkit.flushPendingEvents(appContext);
/*
* 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) {
dispatchThread = null;
}
AWTAutoShutdown.getInstance().notifyThreadFree(edt);
} finally {
pushPopLock.unlock();
}
}
/*
* Gets the <code>EventDispatchThread for this
* <code>EventQueue.
* @return the event dispatch thread associated with this event queue
* or <code>null if this event queue doesn't have a
* working thread associated with it
* @see java.awt.EventQueue#initDispatchThread
* @see java.awt.EventQueue#detachDispatchThread
*/
final EventDispatchThread getDispatchThread() {
pushPopLock.lock();
try {
return dispatchThread;
} finally {
pushPopLock.unlock();
}
}
/*
* Removes any pending events for the specified source object.
* If removeAllEvents parameter is <code>true then all
* events for the specified source object are removed, if it
* is <code>false then SequencedEvent
, SentEvent
,
* <code>FocusEvent, WindowEvent
, KeyEvent
,
* and <code>InputMethodEvent are kept in the queue, but all other
* events are removed.
*
* This method is normally called by the source's
* <code>removeNotify method.
*/
final void removeSourceEvents(Object source, boolean removeAllEvents) {
SunToolkit.flushPendingEvents(appContext);
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 (entry.event instanceof InvocationEvent) {
AWTAccessor.getInvocationEventAccessor()
.dispose((InvocationEvent)entry.event);
}
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();
}
}
synchronized long getMostRecentKeyEventTime() {
pushPopLock.lock();
try {
return mostRecentKeyEventTime;
} finally {
pushPopLock.unlock();
}
}
static void setCurrentEventAndMostRecentTime(AWTEvent e) {
Toolkit.getEventQueue().setCurrentEventAndMostRecentTimeImpl(e);
}
private void setCurrentEventAndMostRecentTimeImpl(AWTEvent e) {
pushPopLock.lock();
try {
if (Thread.currentThread() != dispatchThread) {
return;
}
currentEvent = new WeakReference<>(e);
// This series of 'instanceof' checks should be replaced with a
// polymorphic type (for example, an interface which declares a
// getWhen() method). However, this would require us to make such
// a type public, or to place it in sun.awt. Both of these approaches
// have been frowned upon. So for now, we hack.
//
// In tiger, we will probably give timestamps to all events, so this
// will no longer be an issue.
long mostRecentEventTime2 = Long.MIN_VALUE;
if (e instanceof InputEvent) {
InputEvent ie = (InputEvent)e;
mostRecentEventTime2 = ie.getWhen();
if (e instanceof KeyEvent) {
mostRecentKeyEventTime = ie.getWhen();
}
} else if (e instanceof InputMethodEvent) {
InputMethodEvent ime = (InputMethodEvent)e;
mostRecentEventTime2 = ime.getWhen();
} else if (e instanceof ActionEvent) {
ActionEvent ae = (ActionEvent)e;
mostRecentEventTime2 = ae.getWhen();
} else if (e instanceof InvocationEvent) {
InvocationEvent ie = (InvocationEvent)e;
mostRecentEventTime2 = ie.getWhen();
}
mostRecentEventTime = Math.max(mostRecentEventTime, mostRecentEventTime2);
} finally {
pushPopLock.unlock();
}
}
/**
* Causes <code>runnable to have its run
* method called in the {@link #isDispatchThread dispatch thread} of
* {@link Toolkit#getSystemEventQueue the system EventQueue}.
* This will happen after all pending events are processed.
*
* @param runnable the <code>Runnable whose run
* method should be executed
* asynchronously in the
* {@link #isDispatchThread event dispatch thread}
* of {@link Toolkit#getSystemEventQueue the system EventQueue}
* @see #invokeAndWait
* @see Toolkit#getSystemEventQueue
* @see #isDispatchThread
* @since 1.2
*/
public static void invokeLater(Runnable runnable) {
Toolkit.getEventQueue().postEvent(
new InvocationEvent(Toolkit.getDefaultToolkit(), runnable));
}
/**
* Causes <code>runnable to have its run
* method called in the {@link #isDispatchThread dispatch thread} of
* {@link Toolkit#getSystemEventQueue the system EventQueue}.
* This will happen after all pending events are processed.
* The call blocks until this has happened. This method
* will throw an Error if called from the
* {@link #isDispatchThread event dispatcher thread}.
*
* @param runnable the <code>Runnable whose run
* method should be executed
* synchronously in the
* {@link #isDispatchThread event dispatch thread}
* of {@link Toolkit#getSystemEventQueue the system EventQueue}
* @exception InterruptedException if any thread has
* interrupted this thread
* @exception InvocationTargetException if an throwable is thrown
* when running <code>runnable
* @see #invokeLater
* @see Toolkit#getSystemEventQueue
* @see #isDispatchThread
* @since 1.2
*/
public static void invokeAndWait(Runnable runnable)
throws InterruptedException, InvocationTargetException
{
invokeAndWait(Toolkit.getDefaultToolkit(), runnable);
}
static void invokeAndWait(Object source, 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(source, 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);
}
}
/*
* Called from PostEventQueue.postEvent to notify that a new event
* appeared. First it proceeds to the EventQueue on the top of the
* stack, then notifies the associated dispatch thread if it exists
* or starts a new one otherwise.
*/
private void wakeup(boolean isShutdown) {
pushPopLock.lock();
try {
if (nextQueue != null) {
// Forward call to the top of EventQueue stack.
nextQueue.wakeup(isShutdown);
} else if (dispatchThread != null) {
pushPopCond.signalAll();
} else if (!isShutdown) {
initDispatchThread();
}
} finally {
pushPopLock.unlock();
}
}
// The method is used by AWTAccessor for javafx/AWT single threaded mode.
private void setFwDispatcher(FwDispatcher dispatcher) {
if (nextQueue != null) {
nextQueue.setFwDispatcher(dispatcher);
} else {
fwDispatcher = dispatcher;
}
}
}
/**
* The Queue object holds pointers to the beginning and end of one internal
* queue. An EventQueue object is composed of multiple internal Queues, one
* for each priority supported by the EventQueue. All Events on a particular
* internal Queue have identical priority.
*/
class Queue {
EventQueueItem head;
EventQueueItem tail;
}
Here is a short list of links related to this Java EventQueue.java source code file:
Java example source code file (EventQueue.java)
The EventQueue.java Java example source code/* * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package java.awt; import java.awt.event.*; import java.awt.peer.ComponentPeer; import java.lang.ref.WeakReference; import java.lang.reflect.InvocationTargetException; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.EmptyStackException; import sun.awt.*; import sun.awt.dnd.SunDropTargetEvent; import sun.util.logging.PlatformLogger; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.atomic.AtomicInteger; import java.security.AccessControlContext; import sun.misc.SharedSecrets; import sun.misc.JavaSecurityAccess; /** * <code>EventQueue is a platform-independent class * that queues events, both from the underlying peer classes * and from trusted application classes. * <p> * It encapsulates asynchronous event dispatch machinery which * extracts events from the queue and dispatches them by calling * {@link #dispatchEvent(AWTEvent) dispatchEvent(AWTEvent)} method * on this <code>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 <code>EventQueue can be coalesced) * are dispatched: * <dl> * <dt> Sequentially. * <dd> That is, it is not permitted that several events from * this queue are dispatched simultaneously. * <dt> In the same order as they are enqueued. * <dd> That is, if |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.