blob: 126a593061ed490d2038375e1e9db3d3eccb3a14 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Michael Danilov, Pavel Dolgov
* @version $Revision$
*/
package java.awt;
import java.awt.event.InvocationEvent;
import java.lang.reflect.InvocationTargetException;
import java.util.EmptyStackException;
/**
* The EventQueue class manages events. It is a platform-independent class that
* queues events both from the underlying peer classes and from trusted
* application classes.
*
* @since Android 1.0
*/
public class EventQueue {
/**
* The core ref.
*/
private final EventQueueCoreAtomicReference coreRef = new EventQueueCoreAtomicReference();
/**
* The Class EventQueueCoreAtomicReference.
*/
private static final class EventQueueCoreAtomicReference {
/**
* The core.
*/
private EventQueueCore core;
/* synchronized */
/**
* Gets the.
*
* @return the event queue core.
*/
EventQueueCore get() {
return core;
}
/* synchronized */
/**
* Sets the.
*
* @param newCore
* the new core.
*/
void set(EventQueueCore newCore) {
core = newCore;
}
}
/**
* Returns true if the calling thread is the current AWT EventQueue's
* dispatch thread.
*
* @return true, if the calling thread is the current AWT EventQueue's
* dispatch thread; false otherwise.
*/
public static boolean isDispatchThread() {
return Thread.currentThread() instanceof EventDispatchThread;
}
/**
* Posts an InvocationEvent which executes the run() method on a Runnable
* when dispatched by the AWT event dispatcher thread.
*
* @param runnable
* the Runnable whose run method should be executed synchronously
* on the EventQueue.
*/
public static void invokeLater(Runnable runnable) {
Toolkit toolkit = Toolkit.getDefaultToolkit();
InvocationEvent event = new InvocationEvent(toolkit, runnable);
toolkit.getSystemEventQueueImpl().postEvent(event);
}
/**
* Posts an InvocationEvent which executes the run() method on a Runnable
* when dispatched by the AWT event dispatcher thread and the notifyAll
* method is called on it immediately after run returns.
*
* @param runnable
* the Runnable whose run method should be executed synchronously
* on the EventQueue.
* @throws InterruptedException
* if another thread has interrupted this thread.
* @throws InvocationTargetException
* if an error occurred while running the runnable.
*/
public static void invokeAndWait(Runnable runnable) throws InterruptedException,
InvocationTargetException {
if (isDispatchThread()) {
throw new Error();
}
final Toolkit toolkit = Toolkit.getDefaultToolkit();
final Object notifier = new Object(); // $NON-LOCK-1$
InvocationEvent event = new InvocationEvent(toolkit, runnable, notifier, true);
synchronized (notifier) {
toolkit.getSystemEventQueueImpl().postEvent(event);
notifier.wait();
}
Exception exception = event.getException();
if (exception != null) {
throw new InvocationTargetException(exception);
}
}
/**
* Gets the system event queue.
*
* @return the system event queue.
*/
private static EventQueue getSystemEventQueue() {
Thread th = Thread.currentThread();
if (th instanceof EventDispatchThread) {
return ((EventDispatchThread)th).toolkit.getSystemEventQueueImpl();
}
return null;
}
/**
* Gets the most recent event's timestamp. This event was dispatched from
* the EventQueue associated with the calling thread.
*
* @return the timestamp of the last Event to be dispatched, or
* System.currentTimeMillis() if this method is invoked from a
* thread other than an event-dispatching thread.
*/
public static long getMostRecentEventTime() {
EventQueue eq = getSystemEventQueue();
return (eq != null) ? eq.getMostRecentEventTimeImpl() : System.currentTimeMillis();
}
/**
* Gets the most recent event time impl.
*
* @return the most recent event time impl.
*/
private long getMostRecentEventTimeImpl() {
return getCore().getMostRecentEventTime();
}
/**
* Returns the the currently dispatched event by the EventQueue associated
* with the calling thread.
*
* @return the currently dispatched event or null if this method is invoked
* from a thread other than an event-dispatching thread.
*/
public static AWTEvent getCurrentEvent() {
EventQueue eq = getSystemEventQueue();
return (eq != null) ? eq.getCurrentEventImpl() : null;
}
/**
* Gets the current event impl.
*
* @return the current event impl.
*/
private AWTEvent getCurrentEventImpl() {
return getCore().getCurrentEvent();
}
/**
* Instantiates a new event queue.
*/
public EventQueue() {
setCore(new EventQueueCore(this));
}
/**
* Instantiates a new event queue.
*
* @param t
* the t.
*/
EventQueue(Toolkit t) {
setCore(new EventQueueCore(this, t));
}
/**
* Posts a event to the EventQueue.
*
* @param event
* AWTEvent.
*/
public void postEvent(AWTEvent event) {
event.isPosted = true;
getCore().postEvent(event);
}
/**
* Returns an event from the EventQueue and removes it from this queue.
*
* @return the next AWTEvent.
* @throws InterruptedException
* is thrown if another thread interrupts this thread.
*/
public AWTEvent getNextEvent() throws InterruptedException {
return getCore().getNextEvent();
}
/**
* Gets the next event no wait.
*
* @return the next event no wait.
*/
AWTEvent getNextEventNoWait() {
return getCore().getNextEventNoWait();
}
/**
* Returns the first event of the EventQueue (without removing it from the
* queue).
*
* @return the the first AWT event of the EventQueue.
*/
public AWTEvent peekEvent() {
return getCore().peekEvent();
}
/**
* Returns the first event of the EventQueue with the specified ID (without
* removing it from the queue).
*
* @param id
* the type ID of event.
* @return the first event of the EventQueue with the specified ID.
*/
public AWTEvent peekEvent(int id) {
return getCore().peekEvent(id);
}
/**
* Replaces the existing EventQueue with the specified EventQueue. Any
* pending events are transferred to the new EventQueue.
*
* @param newEventQueue
* the new event queue.
*/
public void push(EventQueue newEventQueue) {
getCore().push(newEventQueue);
}
/**
* Stops dispatching events using this EventQueue. Any pending events are
* transferred to the previous EventQueue.
*
* @throws EmptyStackException
* is thrown if no previous push was made on this EventQueue.
*/
protected void pop() throws EmptyStackException {
getCore().pop();
}
/**
* Dispatches the specified event.
*
* @param event
* the AWTEvent.
*/
protected void dispatchEvent(AWTEvent event) {
getCore().dispatchEventImpl(event);
}
/**
* Checks if the queue is empty.
*
* @return true, if is empty.
*/
boolean isEmpty() {
return getCore().isEmpty();
}
/**
* Gets the core.
*
* @return the core.
*/
EventQueueCore getCore() {
return coreRef.get();
}
/**
* Sets the core.
*
* @param newCore
* the new core.
*/
void setCore(EventQueueCore newCore) {
coreRef.set((newCore != null) ? newCore : new EventQueueCore(this));
}
}