Save This Page
Home » openjdk-7 » java » awt » [javadoc | source]
    1   /*
    2    * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package java.awt;
   27   
   28   import java.awt.event.InputEvent;
   29   import java.awt.event.MouseEvent;
   30   import java.awt.event.ActionEvent;
   31   import java.awt.event.WindowEvent;
   32   import java.lang.reflect.Method;
   33   import java.security.AccessController;
   34   import sun.security.action.GetPropertyAction;
   35   import sun.awt.AWTAutoShutdown;
   36   import sun.awt.SunToolkit;
   37   
   38   import java.util.Vector;
   39   import sun.util.logging.PlatformLogger;
   40   
   41   import sun.awt.dnd.SunDragSourceContextPeer;
   42   import sun.awt.EventQueueDelegate;
   43   
   44   /**
   45    * EventDispatchThread is a package-private AWT class which takes
   46    * events off the EventQueue and dispatches them to the appropriate
   47    * AWT components.
   48    *
   49    * The Thread starts a "permanent" event pump with a call to
   50    * pumpEvents(Conditional) in its run() method. Event handlers can choose to
   51    * block this event pump at any time, but should start a new pump (<b>not</b>
   52    * a new EventDispatchThread) by again calling pumpEvents(Conditional). This
   53    * secondary event pump will exit automatically as soon as the Condtional
   54    * evaluate()s to false and an additional Event is pumped and dispatched.
   55    *
   56    * @author Tom Ball
   57    * @author Amy Fowler
   58    * @author Fred Ecks
   59    * @author David Mendenhall
   60    *
   61    * @since 1.1
   62    */
   63   class EventDispatchThread extends Thread {
   64   
   65       private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventDispatchThread");
   66   
   67       private EventQueue theQueue;
   68       private boolean doDispatch = true;
   69       private boolean threadDeathCaught = false;
   70   
   71       private static final int ANY_EVENT = -1;
   72   
   73       private Vector<EventFilter> eventFilters = new Vector<EventFilter>();
   74   
   75       EventDispatchThread(ThreadGroup group, String name, EventQueue queue) {
   76           super(group, name);
   77           setEventQueue(queue);
   78       }
   79   
   80       /*
   81        * Must be called on EDT only, that's why no synchronization
   82        */
   83       public void stopDispatching() {
   84           doDispatch = false;
   85       }
   86   
   87       public void run() {
   88           while (true) {
   89               try {
   90                   pumpEvents(new Conditional() {
   91                       public boolean evaluate() {
   92                           return true;
   93                       }
   94                   });
   95               } finally {
   96                   EventQueue eq = getEventQueue();
   97                   if (eq.detachDispatchThread(this) || threadDeathCaught) {
   98                       break;
   99                   }
  100               }
  101           }
  102       }
  103   
  104       void pumpEvents(Conditional cond) {
  105           pumpEvents(ANY_EVENT, cond);
  106       }
  107   
  108       void pumpEventsForHierarchy(Conditional cond, Component modalComponent) {
  109           pumpEventsForHierarchy(ANY_EVENT, cond, modalComponent);
  110       }
  111   
  112       void pumpEvents(int id, Conditional cond) {
  113           pumpEventsForHierarchy(id, cond, null);
  114       }
  115   
  116       void pumpEventsForHierarchy(int id, Conditional cond, Component modalComponent) {
  117           pumpEventsForFilter(id, cond, new HierarchyEventFilter(modalComponent));
  118       }
  119   
  120       void pumpEventsForFilter(Conditional cond, EventFilter filter) {
  121           pumpEventsForFilter(ANY_EVENT, cond, filter);
  122       }
  123   
  124       void pumpEventsForFilter(int id, Conditional cond, EventFilter filter) {
  125           addEventFilter(filter);
  126           doDispatch = true;
  127           while (doDispatch && cond.evaluate()) {
  128               if (isInterrupted() || !pumpOneEventForFilters(id)) {
  129                   doDispatch = false;
  130               }
  131           }
  132           removeEventFilter(filter);
  133       }
  134   
  135       void addEventFilter(EventFilter filter) {
  136           eventLog.finest("adding the event filter: " + filter);
  137           synchronized (eventFilters) {
  138               if (!eventFilters.contains(filter)) {
  139                   if (filter instanceof ModalEventFilter) {
  140                       ModalEventFilter newFilter = (ModalEventFilter)filter;
  141                       int k = 0;
  142                       for (k = 0; k < eventFilters.size(); k++) {
  143                           EventFilter f = eventFilters.get(k);
  144                           if (f instanceof ModalEventFilter) {
  145                               ModalEventFilter cf = (ModalEventFilter)f;
  146                               if (cf.compareTo(newFilter) > 0) {
  147                                   break;
  148                               }
  149                           }
  150                       }
  151                       eventFilters.add(k, filter);
  152                   } else {
  153                       eventFilters.add(filter);
  154                   }
  155               }
  156           }
  157       }
  158   
  159       void removeEventFilter(EventFilter filter) {
  160           eventLog.finest("removing the event filter: " + filter);
  161           synchronized (eventFilters) {
  162               eventFilters.remove(filter);
  163           }
  164       }
  165   
  166       boolean pumpOneEventForFilters(int id) {
  167           AWTEvent event = null;
  168           boolean eventOK = false;
  169           try {
  170               EventQueue eq = null;
  171               EventQueueDelegate.Delegate delegate = null;
  172               do {
  173                   // EventQueue may change during the dispatching
  174                   eq = getEventQueue();
  175                   delegate = EventQueueDelegate.getDelegate();
  176   
  177                   if (delegate != null && id == ANY_EVENT) {
  178                       event = delegate.getNextEvent(eq);
  179                   } else {
  180                       event = (id == ANY_EVENT) ? eq.getNextEvent() : eq.getNextEvent(id);
  181                   }
  182   
  183                   eventOK = true;
  184                   synchronized (eventFilters) {
  185                       for (int i = eventFilters.size() - 1; i >= 0; i--) {
  186                           EventFilter f = eventFilters.get(i);
  187                           EventFilter.FilterAction accept = f.acceptEvent(event);
  188                           if (accept == EventFilter.FilterAction.REJECT) {
  189                               eventOK = false;
  190                               break;
  191                           } else if (accept == EventFilter.FilterAction.ACCEPT_IMMEDIATELY) {
  192                               break;
  193                           }
  194                       }
  195                   }
  196                   eventOK = eventOK && SunDragSourceContextPeer.checkEvent(event);
  197                   if (!eventOK) {
  198                       event.consume();
  199                   }
  200               }
  201               while (eventOK == false);
  202   
  203               if (eventLog.isLoggable(PlatformLogger.FINEST)) {
  204                   eventLog.finest("Dispatching: " + event);
  205               }
  206   
  207               Object handle = null;
  208               if (delegate != null) {
  209                   handle = delegate.beforeDispatch(event);
  210               }
  211               eq.dispatchEvent(event);
  212               if (delegate != null) {
  213                   delegate.afterDispatch(event, handle);
  214               }
  215   
  216               return true;
  217           }
  218           catch (ThreadDeath death) {
  219               threadDeathCaught = true;
  220               return false;
  221   
  222           }
  223           catch (InterruptedException interruptedException) {
  224               return false; // AppContext.dispose() interrupts all
  225                             // Threads in the AppContext
  226   
  227           }
  228           catch (Throwable e) {
  229               processException(e);
  230           }
  231   
  232           return true;
  233       }
  234   
  235       private void processException(Throwable e) {
  236           if (eventLog.isLoggable(PlatformLogger.FINE)) {
  237               eventLog.fine("Processing exception: " + e);
  238           }
  239           getUncaughtExceptionHandler().uncaughtException(this, e);
  240       }
  241   
  242       public synchronized EventQueue getEventQueue() {
  243           return theQueue;
  244       }
  245       public synchronized void setEventQueue(EventQueue eq) {
  246           theQueue = eq;
  247       }
  248   
  249       private static class HierarchyEventFilter implements EventFilter {
  250           private Component modalComponent;
  251           public HierarchyEventFilter(Component modalComponent) {
  252               this.modalComponent = modalComponent;
  253           }
  254           public FilterAction acceptEvent(AWTEvent event) {
  255               if (modalComponent != null) {
  256                   int eventID = event.getID();
  257                   boolean mouseEvent = (eventID >= MouseEvent.MOUSE_FIRST) &&
  258                                        (eventID <= MouseEvent.MOUSE_LAST);
  259                   boolean actionEvent = (eventID >= ActionEvent.ACTION_FIRST) &&
  260                                         (eventID <= ActionEvent.ACTION_LAST);
  261                   boolean windowClosingEvent = (eventID == WindowEvent.WINDOW_CLOSING);
  262                   /*
  263                    * filter out MouseEvent and ActionEvent that's outside
  264                    * the modalComponent hierarchy.
  265                    * KeyEvent is handled by using enqueueKeyEvent
  266                    * in Dialog.show
  267                    */
  268                   if (Component.isInstanceOf(modalComponent, "javax.swing.JInternalFrame")) {
  269                       /*
  270                        * Modal internal frames are handled separately. If event is
  271                        * for some component from another heavyweight than modalComp,
  272                        * it is accepted. If heavyweight is the same - we still accept
  273                        * event and perform further filtering in LightweightDispatcher
  274                        */
  275                       return windowClosingEvent ? FilterAction.REJECT : FilterAction.ACCEPT;
  276                   }
  277                   if (mouseEvent || actionEvent || windowClosingEvent) {
  278                       Object o = event.getSource();
  279                       if (o instanceof sun.awt.ModalExclude) {
  280                           // Exclude this object from modality and
  281                           // continue to pump it's events.
  282                           return FilterAction.ACCEPT;
  283                       } else if (o instanceof Component) {
  284                           Component c = (Component) o;
  285                           // 5.0u3 modal exclusion
  286                           boolean modalExcluded = false;
  287                           if (modalComponent instanceof Container) {
  288                               while (c != modalComponent && c != null) {
  289                                   if ((c instanceof Window) &&
  290                                       (sun.awt.SunToolkit.isModalExcluded((Window)c))) {
  291                                       // Exclude this window and all its children from
  292                                       //  modality and continue to pump it's events.
  293                                       modalExcluded = true;
  294                                       break;
  295                                   }
  296                                   c = c.getParent();
  297                               }
  298                           }
  299                           if (!modalExcluded && (c != modalComponent)) {
  300                               return FilterAction.REJECT;
  301                           }
  302                       }
  303                   }
  304               }
  305               return FilterAction.ACCEPT;
  306           }
  307       }
  308   }

Save This Page
Home » openjdk-7 » java » awt » [javadoc | source]