Package javax.swing.plaf.basic

Source Code of javax.swing.plaf.basic.RootPaneFocusHandler

/*
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
/**
* @author Alexander T. Simbirtsev
* @version $Revision$
*/
package javax.swing.plaf.basic;

import java.awt.Component;
import java.awt.KeyboardFocusManager;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JPopupMenu;
import javax.swing.JRootPane;
import javax.swing.MenuElement;
import javax.swing.MenuSelectionManager;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.apache.harmony.x.swing.Utilities;


class RootPaneFocusHandler implements ChangeListener {
    private static RootPaneFocusHandler sharedInstance;
    private static int numInstallations;
    private static Component previousFocusOwner;
    private static Component focusedRootPane;

    private KeyListener rootPaneKeyListener;

    private RootPaneFocusHandler() {
    }

    public static void attach() {
        if (sharedInstance == null) {
            sharedInstance = new RootPaneFocusHandler();
        }
        if (numInstallations == 0) {
            MenuSelectionManager.defaultManager().addChangeListener(sharedInstance);
        }
        numInstallations++;
    }

    public static void detach() {
        if (numInstallations == 1) {
            MenuSelectionManager.defaultManager().removeChangeListener(sharedInstance);
        }
        if (numInstallations > 0) {
            numInstallations--;
        }
    }

    public void stateChanged(final ChangeEvent e) {
        final MenuElement[] path = MenuSelectionManager.defaultManager().getSelectedPath();
        if (Utilities.isEmptyArray(path)) {
            if (focusedRootPane != null) {
                returnFocus();
            }
        } else {
            if (focusedRootPane == null && Utilities.isValidFirstPathElement(path[0])) {
                grabFocus(path);
            }
        }
    }

    private void grabFocus(final MenuElement[] path) {
        for (int i = 0; i < path.length; i++) {
            final MenuElement item = path[i];
            if (i > 0 && !(item instanceof Component)) {
                continue;
            }
            final JRootPane pane = SwingUtilities.getRootPane(getRootPaneChild(item));
            if (pane != null) {
                Component focusOwner = getFocusManager().getFocusOwner();
                if (pane.requestFocus(true)) {
                    previousFocusOwner = focusOwner;
                    focusedRootPane = pane;
                    MenuKeyBindingProcessor.attach();
                    if (pane.getJMenuBar() == null) {
                        pane.addKeyListener(createRootPaneKeyListener());
                    }
                }
                break;
            }
        }
    }

    private KeyListener createRootPaneKeyListener() {
        return (rootPaneKeyListener != null) ? rootPaneKeyListener : (rootPaneKeyListener = new KeyListener() {
            public void keyPressed(KeyEvent event) {
                MenuSelectionManager.defaultManager().processKeyEvent(event);
            }

            public void keyReleased(KeyEvent event) {
                MenuSelectionManager.defaultManager().processKeyEvent(event);
            }

            public void keyTyped(KeyEvent event) {
                MenuSelectionManager.defaultManager().processKeyEvent(event);
            }
        });
    }

    private Component getRootPaneChild(final MenuElement item) {
        return (item instanceof JPopupMenu) ? ((JPopupMenu)item).getInvoker() : (Component)item;
    }

    private void returnFocus() {
        if (isValidPreviusFocusOwner()) {
            previousFocusOwner.requestFocusInWindow();
        } else {
            getFocusManager().focusNextComponent();
        }
        focusedRootPane.removeKeyListener(rootPaneKeyListener);
        focusedRootPane = null;
        MenuKeyBindingProcessor.detach();
    }

    private KeyboardFocusManager getFocusManager() {
        return KeyboardFocusManager.getCurrentKeyboardFocusManager();
    }

    private boolean isValidPreviusFocusOwner() {
        return previousFocusOwner != null && previousFocusOwner.isFocusable() && previousFocusOwner.isVisible() && previousFocusOwner.isEnabled();
    }
}
TOP

Related Classes of javax.swing.plaf.basic.RootPaneFocusHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.