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

    1   /*
    2    *  Licensed to the Apache Software Foundation (ASF) under one or more
    3    *  contributor license agreements.  See the NOTICE file distributed with
    4    *  this work for additional information regarding copyright ownership.
    5    *  The ASF licenses this file to You under the Apache License, Version 2.0
    6    *  (the "License"); you may not use this file except in compliance with
    7    *  the License.  You may obtain a copy of the License at
    8    *
    9    *     http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    *  Unless required by applicable law or agreed to in writing, software
   12    *  distributed under the License is distributed on an "AS IS" BASIS,
   13    *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    *  See the License for the specific language governing permissions and
   15    *  limitations under the License.
   16    */
   17   /**
   18    * @author Dmitry A. Durnev
   19    */
   20   package java.awt;
   21   
   22   import java.awt.event.FocusEvent;
   23   
   24   import org.apache.harmony.awt.wtk.NativeEvent;
   25   import org.apache.harmony.awt.wtk.NativeWindow;
   26   
   27   
   28   /**
   29    * "internal" focus manager
   30    * Take decoded native focus events & generate
   31    * WINDOW_GAINED_FOCUS, WINDOW_LOST_FOCUS if necessary.
   32    * Move focus to focus Proxy to simulate "active" Frame/Dialog
   33    * when a non-activateable Window gains focus.
   34    * Interact with current KeyboardFocusManager: query focused, active
   35    * window, and post all Focus(Window)Events to EventQueue
   36    */
   37   
   38   class FocusDispatcher {
   39       private Window nativeFocusedWindow;
   40       private final Toolkit toolkit;
   41   
   42       FocusDispatcher(Toolkit toolkit) {
   43           this.toolkit = toolkit;
   44       }
   45   
   46       boolean dispatch(Component src, NativeEvent event) {
   47           int id = event.getEventId();
   48           long opositeId = event.getOtherWindowId();
   49           long srcId = event.getWindowId();
   50           boolean focusGained = (id == FocusEvent.FOCUS_GAINED);
   51   
   52           Window focusProxyOwner = null;
   53           if (src == null) {
   54               focusProxyOwner = getFocusProxyOwner(srcId);
   55               if (focusProxyOwner == null) {
   56                   return false;
   57               }
   58           }
   59           Component opposite = getComponentById(opositeId);
   60           Window oppositeFocusProxyOwner = null;
   61           if (opposite == null) {
   62               oppositeFocusProxyOwner = getFocusProxyOwner(opositeId);
   63           }
   64   
   65           dispatchFocusEvent(focusGained, src, opposite,
   66                             focusProxyOwner, oppositeFocusProxyOwner);
   67           return false;
   68       }
   69   
   70       private Window getFocusProxyOwner(long id) {
   71           return toolkit.getFocusProxyOwnerById(id);
   72       }
   73   
   74       private Component getComponentById(long srcId) {
   75           return ((srcId != 0) ? toolkit.getComponentById(srcId) : null);
   76       }
   77   
   78       boolean dispatchFocusEvent(boolean focusGained,
   79                                  Component comp, Component oppositeComp,
   80                                  Window focusProxyOwner,
   81                                  Window oppositeFocusProxyOwner) {
   82   
   83           Component other = oppositeComp;
   84           Window wnd = getWindowAncestor(comp, focusProxyOwner);
   85           Window oppositeWnd = getWindowAncestor(other, oppositeFocusProxyOwner);
   86           if (focusGained) {
   87               nativeFocusedWindow = wnd;
   88           } else if (wnd == nativeFocusedWindow) {
   89               nativeFocusedWindow = null;
   90           }
   91   
   92           boolean isFocusProxy = (focusProxyOwner != null);
   93           boolean isOppositeFocusProxy = (oppositeFocusProxyOwner != null);
   94   
   95           if (discardFocusProxyEvent(focusGained,
   96                                      isFocusProxy,
   97                                      isOppositeFocusProxy,
   98                                      wnd)) {
   99               return true;
  100           }
  101   
  102           // if a non-Frame/Dialog gains native focus, transfer focus
  103           // to "focus proxy" in a nearest Frame/Dialog to make it look "active"
  104           if (!DefaultKeyboardFocusManager.isActivateable(wnd) &&
  105               (wnd != oppositeWnd) && focusGained)
  106           {
  107   
  108               activateAncestor(wnd);
  109           }
  110   
  111           return dispatchToKFM(focusGained,
  112                                wnd, oppositeWnd,
  113                                isFocusProxy, isOppositeFocusProxy, other);
  114       }
  115   
  116       private Window getWindowAncestor(Component comp, Window proxyOwner) {
  117           if (comp != null) {
  118               return comp.getWindowAncestor();
  119           }
  120           return proxyOwner;
  121       }
  122   
  123       private boolean dispatchToKFM(boolean focusGained,
  124                                     Window wnd, Window oppositeWnd,
  125                                     boolean isFocusProxy,
  126                                     boolean isOppositeFocusProxy,
  127                                     Component other) {
  128           KeyboardFocusManager kfm =
  129               KeyboardFocusManager.getCurrentKeyboardFocusManager();
  130           Component focusOwner = KeyboardFocusManager.actualFocusOwner;
  131   
  132           // change wnd/oppositeWnd to Java focused window
  133           // if focusProxy is losing focus:
  134   
  135           Window focusedWindow = KeyboardFocusManager.actualFocusedWindow;
  136   
  137           if (!focusGained && isFocusProxy &&
  138               (focusedWindow != null)) {
  139               // discard event when focus proxy
  140               // is losing focus to focused Window
  141               if (oppositeWnd == focusedWindow) {
  142                   return true;
  143               }
  144               wnd = focusedWindow;
  145           }
  146   
  147           if (focusGained && isOppositeFocusProxy) {
  148               oppositeWnd = focusedWindow;
  149               other = focusOwner;
  150           }
  151   
  152           // if focus goes out of our app there's no requestFocus() call, so
  153           // deliver native event to KFM:
  154           if (!focusGained && (other == null)) {
  155               kfm.setFocus(focusOwner, focusedWindow, false, other, true, false);
  156           }
  157           if (focusGained && (wnd != oppositeWnd)) {
  158               // set focus to the appropriate child component:
  159               // contrary to focus spec KeyboardFocusManager doesn't
  160               // have to do it
  161               // [don't call behavior here to avoid endless loop]
  162               kfm.requestFocusInWindow(wnd, false);
  163           }
  164           return true;
  165       }
  166   
  167       /**
  168        * Discard some focus events where focusProxy is source or opposite
  169        * @param focusGained
  170        * @param isFocusProxy
  171        * @param isOppositeFocusProxy
  172        * @param wnd
  173        * @return true if event should be discarded
  174        */
  175       private boolean discardFocusProxyEvent(boolean focusGained,
  176                                              boolean isFocusProxy,
  177                                              boolean isOppositeFocusProxy,
  178                                              Window wnd) {
  179           if (!focusGained && isOppositeFocusProxy) {
  180               return true;
  181           }
  182           if (focusGained && isFocusProxy) {
  183               return true;
  184           }
  185           return false;
  186       }
  187   
  188       /**
  189        *  Try to activate nearest Dialog/Frame[if not already active]
  190        *   by setting native focus to focusProxy[dedicated child of Dialog/Frame]
  191        */
  192       private void activateAncestor(Window wnd) {
  193   
  194           Window decorWnd = wnd.getFrameDialogOwner();
  195           if ((decorWnd != null) && (decorWnd != nativeFocusedWindow)) {
  196               NativeWindow nativeWnd = decorWnd.getNativeWindow();
  197               if (nativeWnd != null) {
  198                   NativeWindow focusProxyWnd = decorWnd.getFocusProxy();
  199   
  200                   if ((focusProxyWnd != null)) {
  201                       focusProxyWnd.setFocus(true);
  202                   }
  203               }
  204           }
  205       }
  206   
  207   }

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