EventDispatchThread.java revision 5274
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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.
*/
/**
* EventDispatchThread is a package-private AWT class which takes
* events off the EventQueue and dispatches them to the appropriate
* AWT components.
*
* The Thread starts a "permanent" event pump with a call to
* pumpEvents(Conditional) in its run() method. Event handlers can choose to
* block this event pump at any time, but should start a new pump (<b>not</b>
* a new EventDispatchThread) by again calling pumpEvents(Conditional). This
* secondary event pump will exit automatically as soon as the Condtional
* evaluate()s to false and an additional Event is pumped and dispatched.
*
* @author Tom Ball
* @author Amy Fowler
* @author Fred Ecks
* @author David Mendenhall
*
* @since 1.1
*/
class EventDispatchThread extends Thread {
private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventDispatchThread");
private EventQueue theQueue;
private volatile boolean doDispatch = true;
private static final int ANY_EVENT = -1;
}
/*
* Must be called on EDT only, that's why no synchronization
*/
public void stopDispatching() {
doDispatch = false;
}
public void run() {
while (true) {
try {
pumpEvents(new Conditional() {
public boolean evaluate() {
return true;
}
});
} finally {
// 7189350: doDispatch is reset from stopDispatching(),
// on InterruptedException, or ThreadDeath. Either way,
// this indicates that we must force shutting down.
if (getEventQueue().detachDispatchThread(this,
!doDispatch || isInterrupted()))
{
break;
}
}
}
}
// MacOSX change:
// This was added because this class (and java.awt.Conditional) are package private.
// There are certain instances where classes in other packages need to block the
// AWTEventQueue while still allowing it to process events. This uses reflection
// to call back into the caller in order to remove dependencies.
//
// NOTE: This uses reflection in its implementation, so it is not for performance critical code.
//
// cond is an instance of sun.lwawt.macosx.EventDispatchAccess
//
try {
return new Conditional() {
final Method evaluateMethod = Class.forName("sun.lwawt.macosx.EventDispatchAccess").getMethod("evaluate", null);
public boolean evaluate() {
try {
} catch (Exception e) {
return false;
}
}
};
} catch (Exception e) {
return new Conditional() { public boolean evaluate() { return false; } };
}
}
}
}
}
}
}
doDispatch = true;
}
}
synchronized (eventFilters) {
if (filter instanceof ModalEventFilter) {
int k = 0;
if (f instanceof ModalEventFilter) {
break;
}
}
}
} else {
}
}
}
}
synchronized (eventFilters) {
}
}
void pumpOneEventForFilters(int id) {
boolean eventOK = false;
try {
do {
// EventQueue may change during the dispatching
eq = getEventQueue();
} else {
}
eventOK = true;
synchronized (eventFilters) {
eventOK = false;
break;
break;
}
}
}
if (!eventOK) {
}
}
while (eventOK == false);
}
}
}
}
catch (ThreadDeath death) {
doDispatch = false;
throw death;
}
catch (InterruptedException interruptedException) {
doDispatch = false; // AppContext.dispose() interrupts all
// Threads in the AppContext
}
catch (Throwable e) {
processException(e);
}
}
private void processException(Throwable e) {
}
getUncaughtExceptionHandler().uncaughtException(this, e);
}
public synchronized EventQueue getEventQueue() {
return theQueue;
}
}
private static class HierarchyEventFilter implements EventFilter {
private Component modalComponent;
this.modalComponent = modalComponent;
}
if (modalComponent != null) {
/*
* filter out MouseEvent and ActionEvent that's outside
* the modalComponent hierarchy.
* KeyEvent is handled by using enqueueKeyEvent
* in Dialog.show
*/
/*
* Modal internal frames are handled separately. If event is
* for some component from another heavyweight than modalComp,
* it is accepted. If heavyweight is the same - we still accept
* event and perform further filtering in LightweightDispatcher
*/
}
// Exclude this object from modality and
// continue to pump it's events.
return FilterAction.ACCEPT;
} else if (o instanceof Component) {
// 5.0u3 modal exclusion
boolean modalExcluded = false;
if (modalComponent instanceof Container) {
while (c != modalComponent && c != null) {
if ((c instanceof Window) &&
// Exclude this window and all its children from
// modality and continue to pump it's events.
modalExcluded = true;
break;
}
c = c.getParent();
}
}
if (!modalExcluded && (c != modalComponent)) {
return FilterAction.REJECT;
}
}
}
}
return FilterAction.ACCEPT;
}
}
}