Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/awt/EventDispatchThread.java
38829 views
/*1* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.awt;2627import java.awt.event.MouseEvent;28import java.awt.event.ActionEvent;29import java.awt.event.WindowEvent;3031import java.util.ArrayList;32import sun.util.logging.PlatformLogger;3334import sun.awt.dnd.SunDragSourceContextPeer;35import sun.awt.EventQueueDelegate;3637/**38* EventDispatchThread is a package-private AWT class which takes39* events off the EventQueue and dispatches them to the appropriate40* AWT components.41*42* The Thread starts a "permanent" event pump with a call to43* pumpEvents(Conditional) in its run() method. Event handlers can choose to44* block this event pump at any time, but should start a new pump (<b>not</b>45* a new EventDispatchThread) by again calling pumpEvents(Conditional). This46* secondary event pump will exit automatically as soon as the Condtional47* evaluate()s to false and an additional Event is pumped and dispatched.48*49* @author Tom Ball50* @author Amy Fowler51* @author Fred Ecks52* @author David Mendenhall53*54* @since 1.155*/56class EventDispatchThread extends Thread {5758private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventDispatchThread");5960private EventQueue theQueue;61private volatile boolean doDispatch = true;6263private static final int ANY_EVENT = -1;6465private ArrayList<EventFilter> eventFilters = new ArrayList<EventFilter>();6667EventDispatchThread(ThreadGroup group, String name, EventQueue queue) {68super(group, name);69setEventQueue(queue);70}7172/*73* Must be called on EDT only, that's why no synchronization74*/75public void stopDispatching() {76doDispatch = false;77}7879public void run() {80try {81pumpEvents(new Conditional() {82public boolean evaluate() {83return true;84}85});86} finally {87getEventQueue().detachDispatchThread(this);88}89}9091void pumpEvents(Conditional cond) {92pumpEvents(ANY_EVENT, cond);93}9495void pumpEventsForHierarchy(Conditional cond, Component modalComponent) {96pumpEventsForHierarchy(ANY_EVENT, cond, modalComponent);97}9899void pumpEvents(int id, Conditional cond) {100pumpEventsForHierarchy(id, cond, null);101}102103void pumpEventsForHierarchy(int id, Conditional cond, Component modalComponent) {104pumpEventsForFilter(id, cond, new HierarchyEventFilter(modalComponent));105}106107void pumpEventsForFilter(Conditional cond, EventFilter filter) {108pumpEventsForFilter(ANY_EVENT, cond, filter);109}110111void pumpEventsForFilter(int id, Conditional cond, EventFilter filter) {112addEventFilter(filter);113doDispatch = true;114while (doDispatch && !isInterrupted() && cond.evaluate()) {115pumpOneEventForFilters(id);116}117removeEventFilter(filter);118}119120void addEventFilter(EventFilter filter) {121if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) {122eventLog.finest("adding the event filter: " + filter);123}124synchronized (eventFilters) {125if (!eventFilters.contains(filter)) {126if (filter instanceof ModalEventFilter) {127ModalEventFilter newFilter = (ModalEventFilter)filter;128int k = 0;129for (k = 0; k < eventFilters.size(); k++) {130EventFilter f = eventFilters.get(k);131if (f instanceof ModalEventFilter) {132ModalEventFilter cf = (ModalEventFilter)f;133if (cf.compareTo(newFilter) > 0) {134break;135}136}137}138eventFilters.add(k, filter);139} else {140eventFilters.add(filter);141}142}143}144}145146void removeEventFilter(EventFilter filter) {147if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) {148eventLog.finest("removing the event filter: " + filter);149}150synchronized (eventFilters) {151eventFilters.remove(filter);152}153}154155boolean filterAndCheckEvent(AWTEvent event) {156boolean eventOK = true;157synchronized (eventFilters) {158for (int i = eventFilters.size() - 1; i >= 0; i--) {159EventFilter f = eventFilters.get(i);160EventFilter.FilterAction accept = f.acceptEvent(event);161if (accept == EventFilter.FilterAction.REJECT) {162eventOK = false;163break;164} else if (accept == EventFilter.FilterAction.ACCEPT_IMMEDIATELY) {165break;166}167}168}169return eventOK && SunDragSourceContextPeer.checkEvent(event);170}171172void pumpOneEventForFilters(int id) {173AWTEvent event = null;174boolean eventOK = false;175try {176EventQueue eq = null;177EventQueueDelegate.Delegate delegate = null;178do {179// EventQueue may change during the dispatching180eq = getEventQueue();181delegate = EventQueueDelegate.getDelegate();182183if (delegate != null && id == ANY_EVENT) {184event = delegate.getNextEvent(eq);185} else {186event = (id == ANY_EVENT) ? eq.getNextEvent() : eq.getNextEvent(id);187}188189eventOK = filterAndCheckEvent(event);190if (!eventOK) {191event.consume();192}193}194while (eventOK == false);195196if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) {197eventLog.finest("Dispatching: " + event);198}199200Object handle = null;201if (delegate != null) {202handle = delegate.beforeDispatch(event);203}204eq.dispatchEvent(event);205if (delegate != null) {206delegate.afterDispatch(event, handle);207}208}209catch (ThreadDeath death) {210doDispatch = false;211throw death;212}213catch (InterruptedException interruptedException) {214doDispatch = false; // AppContext.dispose() interrupts all215// Threads in the AppContext216}217catch (Throwable e) {218processException(e);219}220}221222private void processException(Throwable e) {223if (eventLog.isLoggable(PlatformLogger.Level.FINE)) {224eventLog.fine("Processing exception: " + e);225}226getUncaughtExceptionHandler().uncaughtException(this, e);227}228229public synchronized EventQueue getEventQueue() {230return theQueue;231}232public synchronized void setEventQueue(EventQueue eq) {233theQueue = eq;234}235236private static class HierarchyEventFilter implements EventFilter {237private Component modalComponent;238public HierarchyEventFilter(Component modalComponent) {239this.modalComponent = modalComponent;240}241public FilterAction acceptEvent(AWTEvent event) {242if (modalComponent != null) {243int eventID = event.getID();244boolean mouseEvent = (eventID >= MouseEvent.MOUSE_FIRST) &&245(eventID <= MouseEvent.MOUSE_LAST);246boolean actionEvent = (eventID >= ActionEvent.ACTION_FIRST) &&247(eventID <= ActionEvent.ACTION_LAST);248boolean windowClosingEvent = (eventID == WindowEvent.WINDOW_CLOSING);249/*250* filter out MouseEvent and ActionEvent that's outside251* the modalComponent hierarchy.252* KeyEvent is handled by using enqueueKeyEvent253* in Dialog.show254*/255if (Component.isInstanceOf(modalComponent, "javax.swing.JInternalFrame")) {256/*257* Modal internal frames are handled separately. If event is258* for some component from another heavyweight than modalComp,259* it is accepted. If heavyweight is the same - we still accept260* event and perform further filtering in LightweightDispatcher261*/262return windowClosingEvent ? FilterAction.REJECT : FilterAction.ACCEPT;263}264if (mouseEvent || actionEvent || windowClosingEvent) {265Object o = event.getSource();266if (o instanceof sun.awt.ModalExclude) {267// Exclude this object from modality and268// continue to pump it's events.269return FilterAction.ACCEPT;270} else if (o instanceof Component) {271Component c = (Component) o;272// 5.0u3 modal exclusion273boolean modalExcluded = false;274if (modalComponent instanceof Container) {275while (c != modalComponent && c != null) {276if ((c instanceof Window) &&277(sun.awt.SunToolkit.isModalExcluded((Window)c))) {278// Exclude this window and all its children from279// modality and continue to pump it's events.280modalExcluded = true;281break;282}283c = c.getParent();284}285}286if (!modalExcluded && (c != modalComponent)) {287return FilterAction.REJECT;288}289}290}291}292return FilterAction.ACCEPT;293}294}295}296297298