defaultkeyboardfocusmanager.java
来自「This is a resource based on j2me embedde」· Java 代码 · 共 888 行 · 第 1/3 页
JAVA
888 行
/* * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */package java.awt;import java.awt.event.FocusEvent;import java.awt.event.KeyEvent;import java.awt.event.WindowEvent;import java.beans.PropertyChangeListener;import java.util.LinkedList;import java.util.Iterator;import java.util.ListIterator;import java.util.Set;import sun.awt.AppContext;import sun.awt.SunToolkit;class DefaultKeyboardFocusManager extends KeyboardFocusManager { private int inSendMessage; private boolean consumeNextKeyTyped; private Window mostRecentFocusedWindow; private Window pendingWindow; private Component pendingComponent; private LinkedList enqueuedKeyEvents = new LinkedList(); private LinkedList typeAheadMarkers = new LinkedList(); private boolean doDebug=false; // added to support vetoable changes private Window realOppositeWindow; private Component realOppositeComponent; private static class TypeAheadMarker { long after; Component untilFocused; TypeAheadMarker(long after, Component untilFocused) { this.after = after; this.untilFocused = untilFocused; } } /* * This series of restoreFocus methods is used for recovering from a * rejected focus or activation change. Rejections typically occur when * the user attempts to focus a non-focusable Component or Window. */ private void restoreFocus(FocusEvent fe, Window newFocusedWindow) { Component realOppositeComponent = this.realOppositeComponent; Component vetoedComponent = fe.getComponent(); if (newFocusedWindow != null && restoreFocus(newFocusedWindow, vetoedComponent, false)) { } else if (realOppositeComponent != null && restoreFocus(realOppositeComponent, false)) { } else if (fe.getOppositeComponent() != null && restoreFocus(fe.getOppositeComponent(), false)) { } else { clearGlobalFocusOwner(); } } private void restoreFocus(WindowEvent we) { Window realOppositeWindow = this.realOppositeWindow; if (realOppositeWindow != null && restoreFocus(realOppositeWindow, null, false)) { } else if (we.getOppositeWindow() != null && restoreFocus(we.getOppositeWindow(), null, false)) { } else { clearGlobalFocusOwner(); } } private boolean restoreFocus(Window aWindow, Component vetoedComponent, boolean clearOnFailure) { Component toFocus = KeyboardFocusManager.getMostRecentFocusOwner(aWindow); if (toFocus != null && toFocus != vetoedComponent && restoreFocus(toFocus, false)) { return true; } else if (clearOnFailure) { clearGlobalFocusOwner(); return true; } else { return false; } } private boolean restoreFocus(Component toFocus, boolean clearOnFailure) { if (doDebug) System.out.println(" restoreFocus to " + toFocus); // 6198823: vetoableChangeListener not working as expected when trying // to veto a FOCUS_LOST event. if (toFocus.hasFocus()) { return true; } // 6198823: vetoableChangeListener not working as expected when trying // to veto a FOCUS_LOST event. // // The new focus management system puts a check at the beginning of // the Component.requestFocusHelper() method to see whether the // component hasFocus(), if true, just returns false without going // through the steps of asking peer to request the focus. This has // the implication that if the clearGlobalFocusOwner() call was vetoed // by a vetoable change listener and the logic flow falls back to the // restoreFocus() call, after trying the first if branch and then the // second if branch without success, calling the third branch will // lead to an infinite recursion leading to stack overflow. if (toFocus.isShowing() && toFocus.isFocusable() && toFocus.requestFocus(false)) { return true; } else if (toFocus.nextFocusHelper()) { return true; } else if (clearOnFailure) { clearGlobalFocusOwner(); return true; } else { return false; } } private Window getOwningFrame(Window window) { while (window != null && !(window instanceof Frame)) { window = (Window)window.getParent(); } return window; } /** * A special type of SentEvent which updates a counter in the target * KeyboardFocusManager if it is an instance of * DefaultKeyboardFocusManager. */ private static class DefaultKeyboardFocusManagerSentEvent extends SentEvent { public DefaultKeyboardFocusManagerSentEvent(AWTEvent nested, AppContext toNotify) { super(nested, toNotify); } public final void dispatch() { KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); DefaultKeyboardFocusManager defaultManager = (manager instanceof DefaultKeyboardFocusManager) ? (DefaultKeyboardFocusManager)manager : null; if (defaultManager != null) { synchronized (defaultManager) { defaultManager.inSendMessage++; } } super.dispatch(); if (defaultManager != null) { synchronized (defaultManager) { defaultManager.inSendMessage--; } } } } /** * Sends a synthetic AWTEvent to a Component. If the Component is in * the current AppContext, then the event is immediately dispatched. * If the Component is in a different AppContext, then the event is * posted to the other AppContext's EventQueue, and this method blocks * until the event is handled or target AppContext is disposed. * Returns true if successfuly dispatched event, false if failed * to dispatch. */ boolean sendMessage(Component target, AWTEvent e) { AppContext myAppContext = AppContext.getAppContext(); final SentEvent se = new DefaultKeyboardFocusManagerSentEvent(e, myAppContext); return sendMessage(target.appContext,se); } public boolean dispatchEvent(AWTEvent e) { if (!(e instanceof WindowEvent) && !(e instanceof FocusEvent) && !(e instanceof KeyEvent)) { return false; } switch( e.getID() ) { case WindowEvent.WINDOW_GAINED_FOCUS: { WindowEvent we = (WindowEvent) e; Window oldFocusedWindow = getGlobalFocusedWindow(); Window newFocusedWindow = we.getWindow(); Component oldFocusOwner = getGlobalFocusOwner(); if (newFocusedWindow == oldFocusedWindow) { break; } // If there exists a current focused window, then notify it // that it has lost focus. if (oldFocusedWindow != null) { boolean isEventDispatched = sendMessage(oldFocusedWindow, new WindowEvent(oldFocusedWindow, WindowEvent.WINDOW_LOST_FOCUS, newFocusedWindow)); // Failed to dispatch, clear by ourselfves if (!isEventDispatched) { setGlobalFocusOwner(null); setGlobalFocusedWindow(null); } } // Because the native libraries do not post WINDOW_ACTIVATED // events, we need to synthesize one if the active Window // changed. Window newActiveWindow = getOwningFrame(newFocusedWindow); Window currentActiveWindow = getGlobalActiveWindow(); if (newActiveWindow != currentActiveWindow) { sendMessage(newActiveWindow, new WindowEvent(newActiveWindow, WindowEvent.WINDOW_ACTIVATED, currentActiveWindow)); if (newActiveWindow != getGlobalActiveWindow()) { // Activation change was rejected. Unlikely, but // possible. restoreFocus(we); break; } } setGlobalFocusedWindow(newFocusedWindow); if (newFocusedWindow != getGlobalFocusedWindow()) { // Focus change was rejected. Will happen if // newFocusedWindow is not a focusable Window. restoreFocus(we); break; } mostRecentFocusedWindow = newFocusedWindow; // Pbp if ( inSendMessage == 0 ) { Component toFocus = KeyboardFocusManager.getMostRecentFocusOwner(newFocusedWindow); if (toFocus == null && newFocusedWindow.isFocusableWindow()) { toFocus = newFocusedWindow.getFocusTraversalPolicy(). getInitialComponent(newFocusedWindow); } if (toFocus != null) { toFocus.requestFocusInWindow(); } } // Does not apply as of now, since we support only one Frame// J2SE// Window realOppositeWindow = this.realOppositeWindow;// if (realOppositeWindow != we.getOppositeWindow()) {// we = new WindowEvent(newFocusedWindow,// WindowEvent.WINDOW_GAINED_FOCUS,// realOppositeWindow);// }// J2SE return typeAheadAssertions(newFocusedWindow, we); } case WindowEvent.WINDOW_ACTIVATED: { WindowEvent we = (WindowEvent)e; Window oldActiveWindow = getGlobalActiveWindow(); Window newActiveWindow = we.getWindow(); if (oldActiveWindow == newActiveWindow) { break; } // If there exists a current active window, then notify it that // it has lost activation. if (oldActiveWindow != null) { boolean isEventDispatched = sendMessage(oldActiveWindow, new WindowEvent(oldActiveWindow,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?