Home » openjdk-7 » javax » swing » plaf » basic » [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 Alexander T. Simbirtsev
   19   */
   20   package javax.swing.plaf.basic;
   21   
   22   import java.awt.Component;
   23   import java.awt.KeyboardFocusManager;
   24   import java.awt.event.KeyEvent;
   25   import java.awt.event.KeyListener;
   26   
   27   import javax.swing.JPopupMenu;
   28   import javax.swing.JRootPane;
   29   import javax.swing.MenuElement;
   30   import javax.swing.MenuSelectionManager;
   31   import javax.swing.SwingUtilities;
   32   import javax.swing.event.ChangeEvent;
   33   import javax.swing.event.ChangeListener;
   34   
   35   import org.apache.harmony.x.swing.Utilities;
   36   
   37   
   38   class RootPaneFocusHandler implements ChangeListener {
   39       private static RootPaneFocusHandler sharedInstance;
   40       private static int numInstallations;
   41       private static Component previousFocusOwner;
   42       private static Component focusedRootPane;
   43   
   44       private KeyListener rootPaneKeyListener;
   45   
   46       private RootPaneFocusHandler() {
   47       }
   48   
   49       public static void attach() {
   50           if (sharedInstance == null) {
   51               sharedInstance = new RootPaneFocusHandler();
   52           }
   53           if (numInstallations == 0) {
   54               MenuSelectionManager.defaultManager().addChangeListener(sharedInstance);
   55           }
   56           numInstallations++;
   57       }
   58   
   59       public static void detach() {
   60           if (numInstallations == 1) {
   61               MenuSelectionManager.defaultManager().removeChangeListener(sharedInstance);
   62           }
   63           if (numInstallations > 0) {
   64               numInstallations--;
   65           }
   66       }
   67   
   68       public void stateChanged(final ChangeEvent e) {
   69           final MenuElement[] path = MenuSelectionManager.defaultManager().getSelectedPath();
   70           if (Utilities.isEmptyArray(path)) {
   71               if (focusedRootPane != null) {
   72                   returnFocus();
   73               }
   74           } else {
   75               if (focusedRootPane == null && Utilities.isValidFirstPathElement(path[0])) {
   76                   grabFocus(path);
   77               }
   78           }
   79       }
   80   
   81       private void grabFocus(final MenuElement[] path) {
   82           for (int i = 0; i < path.length; i++) {
   83               final MenuElement item = path[i];
   84               if (i > 0 && !(item instanceof Component)) {
   85                   continue;
   86               }
   87               final JRootPane pane = SwingUtilities.getRootPane(getRootPaneChild(item));
   88               if (pane != null) {
   89                   Component focusOwner = getFocusManager().getFocusOwner();
   90                   if (pane.requestFocus(true)) {
   91                       previousFocusOwner = focusOwner;
   92                       focusedRootPane = pane;
   93                       MenuKeyBindingProcessor.attach();
   94                       if (pane.getJMenuBar() == null) {
   95                           pane.addKeyListener(createRootPaneKeyListener());
   96                       }
   97                   }
   98                   break;
   99               }
  100           }
  101       }
  102   
  103       private KeyListener createRootPaneKeyListener() {
  104           return (rootPaneKeyListener != null) ? rootPaneKeyListener : (rootPaneKeyListener = new KeyListener() {
  105               public void keyPressed(KeyEvent event) {
  106                   MenuSelectionManager.defaultManager().processKeyEvent(event);
  107               }
  108   
  109               public void keyReleased(KeyEvent event) {
  110                   MenuSelectionManager.defaultManager().processKeyEvent(event);
  111               }
  112   
  113               public void keyTyped(KeyEvent event) {
  114                   MenuSelectionManager.defaultManager().processKeyEvent(event);
  115               }
  116           });
  117       }
  118   
  119       private Component getRootPaneChild(final MenuElement item) {
  120           return (item instanceof JPopupMenu) ? ((JPopupMenu)item).getInvoker() : (Component)item;
  121       }
  122   
  123       private void returnFocus() {
  124           if (isValidPreviusFocusOwner()) {
  125               previousFocusOwner.requestFocusInWindow();
  126           } else {
  127               getFocusManager().focusNextComponent();
  128           }
  129           focusedRootPane.removeKeyListener(rootPaneKeyListener);
  130           focusedRootPane = null;
  131           MenuKeyBindingProcessor.detach();
  132       }
  133   
  134       private KeyboardFocusManager getFocusManager() {
  135           return KeyboardFocusManager.getCurrentKeyboardFocusManager();
  136       }
  137   
  138       private boolean isValidPreviusFocusOwner() {
  139           return previousFocusOwner != null && previousFocusOwner.isFocusable() && previousFocusOwner.isVisible() && previousFocusOwner.isEnabled();
  140       }
  141   }

Home » openjdk-7 » javax » swing » plaf » basic » [javadoc | source]