示例#1
0
  /**
   * Processes a key event forwarded from the <code>MenuSelectionManager</code> and changes the menu
   * selection, if necessary, by using <code>MenuSelectionManager</code>'s API.
   *
   * <p>Note: you do not have to forward the event to sub-components. This is done automatically by
   * the <code>MenuSelectionManager</code>.
   *
   * @param e a <code>KeyEvent</code>
   * @param path the <code>MenuElement</code> path array
   * @param manager the <code>MenuSelectionManager</code>
   */
  public void processKeyEvent(KeyEvent e, MenuElement path[], MenuSelectionManager manager) {
    MenuKeyEvent mke =
        new MenuKeyEvent(
            e.getComponent(),
            e.getID(),
            e.getWhen(),
            e.getModifiers(),
            e.getKeyCode(),
            e.getKeyChar(),
            path,
            manager);
    processMenuKeyEvent(mke);

    if (mke.isConsumed()) {
      e.consume();
    }
  }
  /**
   * Need this method to detect when the focus may have chance to leave the focus cycle root which
   * is EmbeddedFrame. Mostly, the code here is copied from
   * DefaultKeyboardFocusManager.processKeyEvent with some minor modifications.
   */
  public boolean dispatchKeyEvent(KeyEvent e) {

    // We can't guarantee that this is called on the same AppContext as EmbeddedFrame
    // belongs to. That's why we can't use public methods to find current focus cycle
    // root. Instead, we access KFM's private field directly.
    if (currentCycleRoot == null) {
      currentCycleRoot =
          (Field)
              AccessController.doPrivileged(
                  new PrivilegedAction() {
                    public Object run() {
                      try {
                        Field unaccessibleRoot =
                            KeyboardFocusManager.class.getDeclaredField("currentFocusCycleRoot");
                        if (unaccessibleRoot != null) {
                          unaccessibleRoot.setAccessible(true);
                        }
                        return unaccessibleRoot;
                      } catch (NoSuchFieldException e1) {
                        assert false;
                      } catch (SecurityException e2) {
                        assert false;
                      }
                      return null;
                    }
                  });
    }

    Container currentRoot = null;
    if (currentCycleRoot != null) {
      try {
        // The field is static, so we can pass null to Field.get() as the argument.
        currentRoot = (Container) currentCycleRoot.get(null);
      } catch (IllegalAccessException e3) {
        // This is impossible: currentCycleRoot would be null if setAccessible failed.
        assert false;
      }
    }

    // if we are not in EmbeddedFrame's cycle, we should not try to leave.
    if (this != currentRoot) {
      return false;
    }

    // KEY_TYPED events cannot be focus traversal keys
    if (e.getID() == KeyEvent.KEY_TYPED) {
      return false;
    }

    if (!getFocusTraversalKeysEnabled() || e.isConsumed()) {
      return false;
    }

    AWTKeyStroke stroke = AWTKeyStroke.getAWTKeyStrokeForEvent(e);
    Set toTest;
    Component currentFocused = e.getComponent();

    Component last = getFocusTraversalPolicy().getLastComponent(this);
    toTest = getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
    if (toTest.contains(stroke) && (currentFocused == last || last == null)) {
      if (traverseOut(FORWARD)) {
        e.consume();
        return true;
      }
    }

    Component first = getFocusTraversalPolicy().getFirstComponent(this);
    toTest = getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
    if (toTest.contains(stroke) && (currentFocused == first || first == null)) {
      if (traverseOut(BACKWARD)) {
        e.consume();
        return true;
      }
    }
    return false;
  }