0001: /*
0002: *
0003: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
0004: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0005: *
0006: * This program is free software; you can redistribute it and/or
0007: * modify it under the terms of the GNU General Public License version
0008: * 2 only, as published by the Free Software Foundation.
0009: *
0010: * This program is distributed in the hope that it will be useful, but
0011: * WITHOUT ANY WARRANTY; without even the implied warranty of
0012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0013: * General Public License version 2 for more details (a copy is
0014: * included at /legal/license.txt).
0015: *
0016: * You should have received a copy of the GNU General Public License
0017: * version 2 along with this work; if not, write to the Free Software
0018: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0019: * 02110-1301 USA
0020: *
0021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0022: * Clara, CA 95054 or visit www.sun.com if you need additional
0023: * information or have any questions.
0024: */
0025: package java.awt;
0026:
0027: import java.awt.event.FocusEvent;
0028: import java.awt.event.InputEvent;
0029: import java.awt.event.KeyEvent;
0030: import java.awt.event.WindowEvent;
0031: import java.beans.*;
0032: import java.util.Set;
0033: import java.util.HashSet;
0034: import java.util.Collections;
0035: import java.util.Iterator;
0036: import java.util.LinkedList;
0037: import java.util.ListIterator;
0038: import java.util.StringTokenizer;
0039: import java.util.WeakHashMap;
0040: import java.lang.ref.WeakReference;
0041: import sun.awt.peer.LightweightPeer;
0042: import sun.awt.SunToolkit;
0043: import sun.awt.AppContext;
0044:
0045: public abstract class KeyboardFocusManager implements
0046: KeyEventDispatcher, KeyEventPostProcessor {
0047: public static final int FORWARD_TRAVERSAL_KEYS = 0;
0048: public static final int BACKWARD_TRAVERSAL_KEYS = 1;
0049: public static final int UP_CYCLE_TRAVERSAL_KEYS = 2;
0050: public static final int DOWN_CYCLE_TRAVERSAL_KEYS = 3;
0051: static final int TRAVERSAL_KEY_LENGTH = DOWN_CYCLE_TRAVERSAL_KEYS + 1;
0052: private static Component focusOwner;
0053: private static Component permanentFocusOwner;
0054: private static Window focusedWindow;
0055: private static Window activeWindow = null;
0056: private FocusTraversalPolicy defaultPolicy = new DefaultFocusTraversalPolicy();
0057: private static final String[] defaultFocusTraversalKeyPropertyNames = {
0058: "forwardDefaultFocusTraversalKeys",
0059: "backwardDefaultFocusTraversalKeys",
0060: "upCycleDefaultFocusTraversalKeys",
0061: "downCycleDefaultFocusTraversalKeys" };
0062: private static final String[] defaultFocusTraversalKeyStrings = {
0063: "TAB,ctrl TAB", "shift TAB,ctrl shift TAB", "", "" };
0064: private Set[] defaultFocusTraversalKeys = new Set[4];
0065: private static Container currentFocusCycleRoot;
0066: private VetoableChangeSupport vetoableSupport;
0067: private PropertyChangeSupport changeSupport;
0068: private java.util.LinkedList keyEventDispatchers;
0069: private java.util.LinkedList keyEventPostProcessors;
0070: private static java.util.Map mostRecentFocusOwners = new WeakHashMap();
0071: private static final String notPrivileged = "this KeyboardFocusManager is not installed in the current thread's context";
0072: private static AWTPermission replaceKeyboardFocusManagerPermission;
0073: static KeyboardFocusManager manager;
0074:
0075: private native void _clearGlobalFocusOwner();
0076:
0077: static native Component getNativeFocusOwner();
0078:
0079: static native Window getNativeFocusedWindow();
0080:
0081: /**
0082: * Initialize JNI field and method IDs
0083: */
0084: private static native void initIDs();
0085:
0086: private boolean initialized = false;
0087:
0088: /*
0089: * SequencedEvent which is currently dispatched in AppContext.
0090: */
0091: transient SequencedEvent currentSequencedEvent = null;
0092:
0093: final void setCurrentSequencedEvent(SequencedEvent current) {
0094: synchronized (SequencedEvent.class) {
0095: //assert(current == null || currentSequencedEvent == null);
0096: currentSequencedEvent = current;
0097: }
0098: }
0099:
0100: final SequencedEvent getCurrentSequencedEvent() {
0101: synchronized (SequencedEvent.class) {
0102: return currentSequencedEvent;
0103: }
0104: }
0105:
0106: private static final class LightweightFocusRequest {
0107: final Component component;
0108: final boolean temporary;
0109:
0110: LightweightFocusRequest(Component component, boolean temporary) {
0111: this .component = component;
0112: this .temporary = temporary;
0113: }
0114:
0115: public String toString() {
0116: return "LightweightFocusRequest[component=" + component
0117: + ",temporary=" + temporary + "]";
0118: }
0119: }
0120:
0121: private static final class HeavyweightFocusRequest {
0122: final Component heavyweight;
0123: final LinkedList lightweightRequests;
0124:
0125: static final HeavyweightFocusRequest CLEAR_GLOBAL_FOCUS_OWNER = new HeavyweightFocusRequest();
0126:
0127: private HeavyweightFocusRequest() {
0128: heavyweight = null;
0129: lightweightRequests = null;
0130: }
0131:
0132: HeavyweightFocusRequest(Component heavyweight,
0133: Component descendant, boolean temporary) {
0134: /*
0135: if (dbg.on) {
0136: dbg.assertion(heavyweight != null);
0137: }
0138: */
0139:
0140: this .heavyweight = heavyweight;
0141: this .lightweightRequests = new LinkedList();
0142: addLightweightRequest(descendant, temporary);
0143: }
0144:
0145: boolean addLightweightRequest(Component descendant,
0146: boolean temporary) {
0147: /*
0148: if (dbg.on) {
0149: dbg.assertion(this != HeavyweightFocusRequest.
0150: CLEAR_GLOBAL_FOCUS_OWNER);
0151: dbg.assertion(descendant != null);
0152: }
0153: */
0154:
0155: Component lastDescendant = ((lightweightRequests.size() > 0) ? ((LightweightFocusRequest) lightweightRequests
0156: .getLast()).component
0157: : null);
0158:
0159: if (descendant != lastDescendant) {
0160: // Not a duplicate request
0161: lightweightRequests.add(new LightweightFocusRequest(
0162: descendant, temporary));
0163: return true;
0164: } else {
0165: return false;
0166: }
0167: }
0168:
0169: LightweightFocusRequest getFirstLightweightRequest() {
0170: if (this == CLEAR_GLOBAL_FOCUS_OWNER) {
0171: return null;
0172: }
0173: return (LightweightFocusRequest) lightweightRequests
0174: .getFirst();
0175: }
0176:
0177: public String toString() {
0178: boolean first = true;
0179: String str = "HeavyweightFocusRequest[heavweight="
0180: + heavyweight + ",lightweightRequests=";
0181: if (lightweightRequests == null) {
0182: str += null;
0183: } else {
0184: str += "[";
0185: for (Iterator iter = lightweightRequests.iterator(); iter
0186: .hasNext();) {
0187: if (first) {
0188: first = false;
0189: } else {
0190: str += ",";
0191: }
0192: str += iter.next();
0193: }
0194: str += "]";
0195: }
0196: str += "]";
0197: return str;
0198: }
0199: }
0200:
0201: private static boolean focusedWindowChanged(Component a, Component b) {
0202: Window wa = getContainingWindow(a);
0203: Window wb = getContainingWindow(b);
0204:
0205: if (wa == null || wb == null) {
0206: return false;
0207: }
0208: return (wa != wb);
0209: }
0210:
0211: static Window getContainingWindow(Component comp) {
0212: while (comp != null && !(comp instanceof Window)) {
0213: comp = comp.getParent();
0214: }
0215:
0216: return (Window) comp;
0217: }
0218:
0219: private static Component getHeavyweight(Component comp) {
0220: if (comp == null || comp.peer == null) {
0221: return null;
0222: } else if (comp.peer instanceof LightweightPeer) {
0223: return comp.getNativeContainer();
0224: } else {
0225: return comp;
0226: }
0227: }
0228:
0229: /*
0230: * heavyweightRequests is used as a monitor for synchronized changes of
0231: * currentLightweightRequests, clearingCurrentLightweightRequests and
0232: * newFocusOwner.
0233: */
0234: private static LinkedList heavyweightRequests = new LinkedList();
0235: private static LinkedList currentLightweightRequests;
0236: private static boolean clearingCurrentLightweightRequests;
0237: private static Component newFocusOwner = null;
0238:
0239: int requestCount() {
0240: return heavyweightRequests.size();
0241: }
0242:
0243: static final int SNFH_FAILURE = 0;
0244: static final int SNFH_SUCCESS_HANDLED = 1;
0245: static final int SNFH_SUCCESS_PROCEED = 2;
0246:
0247: /**
0248: * Indicates whether the native implementation should proceed with a
0249: * pending, native focus request. Before changing the focus at the native
0250: * level, the AWT implementation should always call this function for
0251: * permission. This function will reject the request if a duplicate request
0252: * preceded it, or if the specified heavyweight Component already owns the
0253: * focus and no native focus changes are pending. Otherwise, the request
0254: * will be approved and the focus request list will be updated so that,
0255: * if necessary, the proper descendant will be focused when the
0256: * corresponding FOCUS_GAINED event on the heavyweight is received.
0257: *
0258: * An implementation must ensure that calls to this method and native
0259: * focus changes are atomic. If this is not guaranteed, then the ordering
0260: * of the focus request list may be incorrect, leading to errors in the
0261: * type-ahead mechanism. Typically this is accomplished by only calling
0262: * this function from the native event pumping thread, or by holding a
0263: * global, native lock during invocation.
0264: */
0265: static int shouldNativelyFocusHeavyweight(Component heavyweight,
0266: Component descendant, boolean temporary,
0267: boolean focusedWindowChangeAllowed, long time) {
0268: /*
0269: if (dbg.on) {
0270: dbg.assertion(heavyweight != null);
0271: dbg.assertion(time != 0);
0272: }
0273: */
0274:
0275: if (descendant == null) {
0276: // Focus transfers from a lightweight child back to the
0277: // heavyweight Container should be treated like lightweight
0278: // focus transfers.
0279: descendant = heavyweight;
0280: }
0281:
0282: synchronized (heavyweightRequests) {
0283: HeavyweightFocusRequest hwFocusRequest = (HeavyweightFocusRequest) ((heavyweightRequests
0284: .size() > 0) ? heavyweightRequests.getLast() : null);
0285: if (hwFocusRequest == null
0286: && heavyweight == getNativeFocusOwner()) {
0287: Component currentFocusOwner = getCurrentKeyboardFocusManager()
0288: .getGlobalFocusOwner();
0289:
0290: if (descendant == currentFocusOwner) {
0291: // Redundant request.
0292: return SNFH_FAILURE;
0293: }
0294:
0295: // 'heavyweight' owns the native focus and there are no pending
0296: // requests. 'heavyweight' must be a Container and
0297: // 'descendant' must not be the focus owner. Otherwise,
0298: // we would never have gotten this far.
0299: getCurrentKeyboardFocusManager(
0300: SunToolkit.targetToAppContext(descendant))
0301: .enqueueKeyEvents(time, descendant);
0302:
0303: hwFocusRequest = new HeavyweightFocusRequest(
0304: heavyweight, descendant, temporary);
0305: heavyweightRequests.add(hwFocusRequest);
0306:
0307: if (currentFocusOwner != null) {
0308: FocusEvent currentFocusOwnerEvent = new FocusEvent(
0309: currentFocusOwner, FocusEvent.FOCUS_LOST,
0310: temporary, descendant);
0311: SunToolkit.postEvent(currentFocusOwner.appContext,
0312: currentFocusOwnerEvent);
0313:
0314: }
0315: FocusEvent newFocusOwnerEvent = new FocusEvent(
0316: descendant, FocusEvent.FOCUS_GAINED, temporary,
0317: currentFocusOwner);
0318: SunToolkit.postEvent(descendant.appContext,
0319: newFocusOwnerEvent);
0320: return SNFH_SUCCESS_HANDLED;
0321: } else if (hwFocusRequest != null
0322: && hwFocusRequest.heavyweight == heavyweight) {
0323: // 'heavyweight' doesn't have the native focus right now, but
0324: // if all pending requests were completed, it would. Add
0325: // descendant to the heavyweight's list of pending
0326: // lightweight focus transfers.
0327: if (hwFocusRequest.addLightweightRequest(descendant,
0328: temporary)) {
0329: getCurrentKeyboardFocusManager(
0330: SunToolkit.targetToAppContext(descendant))
0331: .enqueueKeyEvents(time, descendant);
0332: }
0333:
0334: return SNFH_SUCCESS_HANDLED;
0335: } else {
0336: if (!focusedWindowChangeAllowed) {
0337: // For purposes of computing oldFocusedWindow, we should
0338: // look at the second to last HeavyweightFocusRequest on
0339: // the queue iff the last HeavyweightFocusRequest is
0340: // CLEAR_GLOBAL_FOCUS_OWNER. If there is no second to last
0341: // HeavyweightFocusRequest, null is an acceptable value.
0342: if (hwFocusRequest == HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER) {
0343: int size = heavyweightRequests.size();
0344: hwFocusRequest = (HeavyweightFocusRequest) ((size >= 2) ? heavyweightRequests
0345: .get(size - 2)
0346: : null);
0347: }
0348:
0349: if (focusedWindowChanged(
0350: heavyweight,
0351: (hwFocusRequest != null) ? hwFocusRequest.heavyweight
0352: : getNativeFocusedWindow())) {
0353: return SNFH_FAILURE;
0354: }
0355: }
0356: getCurrentKeyboardFocusManager(
0357: SunToolkit.targetToAppContext(descendant))
0358: .enqueueKeyEvents(time, descendant);
0359: heavyweightRequests.add(new HeavyweightFocusRequest(
0360: heavyweight, descendant, temporary));
0361: return SNFH_SUCCESS_PROCEED;
0362: }
0363: }
0364: }
0365:
0366: static void processCurrentLightweightRequests() {
0367: KeyboardFocusManager manager = getCurrentKeyboardFocusManager();
0368: LinkedList localLightweightRequests = null;
0369:
0370: synchronized (heavyweightRequests) {
0371: if (currentLightweightRequests != null) {
0372: clearingCurrentLightweightRequests = true;
0373: localLightweightRequests = currentLightweightRequests;
0374: currentLightweightRequests = null;
0375: } else {
0376: // do nothing
0377: return;
0378: }
0379: }
0380: try {
0381: if (localLightweightRequests != null) {
0382: for (Iterator iter = localLightweightRequests
0383: .iterator(); iter.hasNext();) {
0384: Component currentFocusOwner = manager
0385: .getGlobalFocusOwner();
0386: if (currentFocusOwner == null) {
0387: // If this ever happens, a focus change has been
0388: // rejected. Stop generating more focus changes.
0389: break;
0390: }
0391:
0392: LightweightFocusRequest lwFocusRequest = (LightweightFocusRequest) iter
0393: .next();
0394: FocusEvent currentFocusOwnerEvent = new FocusEvent(
0395: currentFocusOwner, FocusEvent.FOCUS_LOST,
0396: lwFocusRequest.temporary,
0397: lwFocusRequest.component);
0398: FocusEvent newFocusOwnerEvent = new FocusEvent(
0399: lwFocusRequest.component,
0400: FocusEvent.FOCUS_GAINED,
0401: lwFocusRequest.temporary, currentFocusOwner);
0402:
0403: currentFocusOwner
0404: .dispatchEvent(currentFocusOwnerEvent);
0405: lwFocusRequest.component
0406: .dispatchEvent(newFocusOwnerEvent);
0407: }
0408: }
0409: } finally {
0410: clearingCurrentLightweightRequests = false;
0411: localLightweightRequests = null;
0412: }
0413: }
0414:
0415: static FocusEvent retargetUnexpectedFocusEvent(FocusEvent fe) {
0416: synchronized (heavyweightRequests) {
0417: // Any other case represents a failure condition which we did
0418: // not expect. We need to clearFocusRequestList() and patch up
0419: // the event as best as possible.
0420:
0421: if (removeFirstRequest()) {
0422: return (FocusEvent) retargetFocusEvent(fe);
0423: }
0424:
0425: Component source = fe.getComponent();
0426: Component opposite = fe.getOppositeComponent();
0427: boolean temporary = false;
0428: if (fe.getID() == FocusEvent.FOCUS_LOST
0429: && (opposite == null || focusedWindowChanged(
0430: source, opposite))) {
0431: temporary = true;
0432: }
0433: return new FocusEvent(source, fe.getID(), temporary,
0434: opposite);
0435: }
0436: }
0437:
0438: static FocusEvent retargetFocusGained(FocusEvent fe) {
0439: // assert (fe.getID() == FocusEvent.FOCUS_GAINED);
0440:
0441: Component currentFocusOwner = getCurrentKeyboardFocusManager()
0442: .getGlobalFocusOwner();
0443: Component source = fe.getComponent();
0444: Component opposite = fe.getOppositeComponent();
0445: Component nativeSource = getHeavyweight(source);
0446:
0447: synchronized (heavyweightRequests) {
0448: HeavyweightFocusRequest hwFocusRequest = (HeavyweightFocusRequest) ((heavyweightRequests
0449: .size() > 0) ? heavyweightRequests.getFirst()
0450: : null);
0451:
0452: if (hwFocusRequest == HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER) {
0453: return retargetUnexpectedFocusEvent(fe);
0454: }
0455:
0456: if (source != null && nativeSource == null
0457: && hwFocusRequest != null) {
0458: // if source w/o peer and
0459: // if source is equal to first lightweight
0460: // then we should correct source and nativeSource
0461: if (source == hwFocusRequest
0462: .getFirstLightweightRequest().component) {
0463: source = hwFocusRequest.heavyweight;
0464: nativeSource = source; // source is heavuweight itself
0465: }
0466: }
0467: if (hwFocusRequest != null
0468: && nativeSource == hwFocusRequest.heavyweight) {
0469: // Focus change as a result of a known call to requestFocus(),
0470: // or known click on a peer focusable heavyweight Component.
0471:
0472: heavyweightRequests.removeFirst();
0473:
0474: LightweightFocusRequest lwFocusRequest = (LightweightFocusRequest) hwFocusRequest.lightweightRequests
0475: .removeFirst();
0476:
0477: Component newSource = lwFocusRequest.component;
0478: if (currentFocusOwner != null) {
0479: /*
0480: * Since we receive FOCUS_GAINED when current focus
0481: * owner is not null, correcponding FOCUS_LOST is supposed
0482: * to be lost. And so, we keep new focus owner
0483: * to determine synthetic FOCUS_LOST event which will be
0484: * generated by KeyboardFocusManager for this FOCUS_GAINED.
0485: *
0486: * This code based on knowledge of
0487: * DefaultKeyboardFocusManager's implementation and might
0488: * be not applicable for another KeyboardFocusManager.
0489: */
0490: newFocusOwner = newSource;
0491: }
0492: // LMK - comment out the check for opposite == null - it
0493: // always is for us
0494: boolean temporary = (//opposite == null ||
0495: focusedWindowChanged(newSource, opposite)) ? false
0496: : lwFocusRequest.temporary;
0497:
0498: if (hwFocusRequest.lightweightRequests.size() > 0) {
0499: currentLightweightRequests = hwFocusRequest.lightweightRequests;
0500: EventQueue.invokeLater(new Runnable() {
0501: public void run() {
0502: processCurrentLightweightRequests();
0503: }
0504: });
0505: }
0506:
0507: // 'opposite' will be fixed by
0508: // DefaultKeyboardFocusManager.realOppositeComponent
0509: return new FocusEvent(newSource,
0510: FocusEvent.FOCUS_GAINED, temporary, opposite);
0511: }
0512:
0513: if (currentFocusOwner != null
0514: && getContainingWindow(currentFocusOwner) == source
0515: && (hwFocusRequest == null || source != hwFocusRequest.heavyweight)) {
0516: // Special case for FOCUS_GAINED in top-levels
0517: // If it arrives as the result of activation we should skip it
0518: // This event will not have appropriate request record and
0519: // on arrival there will be already some focus owner set.
0520: return new FocusEvent(currentFocusOwner,
0521: FocusEvent.FOCUS_GAINED, false, null);
0522: }
0523:
0524: return retargetUnexpectedFocusEvent(fe);
0525: } // end synchronized(heavyweightRequests)
0526: }
0527:
0528: static FocusEvent retargetFocusLost(FocusEvent fe) {
0529: // assert (fe.getID() == FocusEvent.FOCUS_LOST);
0530:
0531: Component currentFocusOwner = getCurrentKeyboardFocusManager()
0532: .getGlobalFocusOwner();
0533: Component opposite = fe.getOppositeComponent();
0534: Component nativeOpposite = getHeavyweight(opposite);
0535:
0536: synchronized (heavyweightRequests) {
0537: HeavyweightFocusRequest hwFocusRequest = (HeavyweightFocusRequest) ((heavyweightRequests
0538: .size() > 0) ? heavyweightRequests.getFirst()
0539: : null);
0540:
0541: if (hwFocusRequest == HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER) {
0542: if (currentFocusOwner != null) {
0543: // Call to KeyboardFocusManager.clearGlobalFocusOwner()
0544: heavyweightRequests.removeFirst();
0545: return new FocusEvent(currentFocusOwner,
0546: FocusEvent.FOCUS_LOST, false, null);
0547: }
0548:
0549: // Otherwise, fall through to failure case below
0550:
0551: } else if (opposite == null) {
0552: // Focus leaving application
0553: if (currentFocusOwner != null) {
0554: return new FocusEvent(currentFocusOwner,
0555: FocusEvent.FOCUS_LOST, true, null);
0556: } else {
0557: return fe;
0558: }
0559: } else if (hwFocusRequest != null
0560: && (nativeOpposite == hwFocusRequest.heavyweight || nativeOpposite == null
0561: && opposite == hwFocusRequest
0562: .getFirstLightweightRequest().component)) {
0563: if (currentFocusOwner == null) {
0564: return fe;
0565: }
0566: // Focus change as a result of a known call to requestFocus(),
0567: // or click on a peer focusable heavyweight Component.
0568:
0569: // If a focus transfer is made across top-levels, then the
0570: // FOCUS_LOST event is always temporary, and the FOCUS_GAINED
0571: // event is always permanent. Otherwise, the stored temporary
0572: // value is honored.
0573:
0574: LightweightFocusRequest lwFocusRequest = (LightweightFocusRequest) hwFocusRequest.lightweightRequests
0575: .getFirst();
0576:
0577: boolean temporary = focusedWindowChanged(opposite,
0578: currentFocusOwner) ? true
0579: : lwFocusRequest.temporary;
0580:
0581: return new FocusEvent(currentFocusOwner,
0582: FocusEvent.FOCUS_LOST, temporary,
0583: lwFocusRequest.component);
0584: }
0585:
0586: return retargetUnexpectedFocusEvent(fe);
0587: } // end synchronized(heavyweightRequests)
0588: }
0589:
0590: static AWTEvent retargetFocusEvent(AWTEvent event) {
0591: if (clearingCurrentLightweightRequests) {
0592: return event;
0593: }
0594:
0595: KeyboardFocusManager manager = getCurrentKeyboardFocusManager();
0596:
0597: synchronized (heavyweightRequests) {
0598: /*
0599: * This code handles FOCUS_LOST event which is generated by
0600: * DefaultKeyboardFocusManager for FOCUS_GAINED.
0601: *
0602: * This code based on knowledge of DefaultKeyboardFocusManager's
0603: * implementation and might be not applicable for another
0604: * KeyboardFocusManager.
0605: *
0606: * Fix for 4472032
0607: */
0608: if (newFocusOwner != null
0609: && event.getID() == FocusEvent.FOCUS_LOST) {
0610: FocusEvent fe = (FocusEvent) event;
0611:
0612: if (manager.getGlobalFocusOwner() == fe.getComponent()
0613: && fe.getOppositeComponent() == newFocusOwner) {
0614: newFocusOwner = null;
0615: return event;
0616: }
0617: }
0618: }
0619:
0620: processCurrentLightweightRequests();
0621:
0622: switch (event.getID()) {
0623: case FocusEvent.FOCUS_GAINED: {
0624: event = retargetFocusGained((FocusEvent) event);
0625: break;
0626: }
0627: case FocusEvent.FOCUS_LOST: {
0628: event = retargetFocusLost((FocusEvent) event);
0629: break;
0630: }
0631: default:
0632: /* do nothing */
0633: }
0634: return event;
0635: }
0636:
0637: static boolean removeFirstRequest() {
0638: KeyboardFocusManager manager = KeyboardFocusManager
0639: .getCurrentKeyboardFocusManager();
0640:
0641: synchronized (heavyweightRequests) {
0642: HeavyweightFocusRequest hwFocusRequest = (HeavyweightFocusRequest)
0643:
0644: ((heavyweightRequests.size() > 0) ? heavyweightRequests
0645: .getFirst() : null);
0646: if (hwFocusRequest != null) {
0647: heavyweightRequests.removeFirst();
0648: if (hwFocusRequest.lightweightRequests != null) {
0649: for (Iterator lwIter = hwFocusRequest.lightweightRequests
0650: .iterator(); lwIter.hasNext();) {
0651: manager.dequeueKeyEvents(-1,
0652: ((LightweightFocusRequest) lwIter
0653: .next()).component);
0654: }
0655: }
0656: }
0657: return (heavyweightRequests.size() > 0);
0658: }
0659: }
0660:
0661: static void removeLastFocusRequest(Component heavyweight) {
0662: /* if (dbg.on) {
0663: dbg.assertion(heavyweight != null);
0664: }
0665: */
0666:
0667: synchronized (heavyweightRequests) {
0668: HeavyweightFocusRequest hwFocusRequest = (HeavyweightFocusRequest) ((heavyweightRequests
0669: .size() > 0) ? heavyweightRequests.getLast() : null);
0670: if (hwFocusRequest != null
0671: && hwFocusRequest.heavyweight == heavyweight) {
0672: heavyweightRequests.removeLast();
0673: }
0674: }
0675: }
0676:
0677: static void removeFocusRequest(Component component) {
0678: /*
0679: if (dbg.on) {
0680: dbg.assertion(component != null);
0681: }
0682: */
0683:
0684: Component heavyweight = (component.peer instanceof LightweightPeer) ? component
0685: .getNativeContainer()
0686: : component;
0687: if (heavyweight == null) {
0688: return;
0689: }
0690:
0691: synchronized (heavyweightRequests) {
0692: if ((currentLightweightRequests != null)
0693: && (currentLightweightRequests.size() > 0)) {
0694: LightweightFocusRequest lwFocusRequest = (LightweightFocusRequest) currentLightweightRequests
0695: .getFirst();
0696: Component comp = lwFocusRequest.component;
0697: Component currentHeavyweight = (comp.peer instanceof LightweightPeer) ? comp
0698: .getNativeContainer()
0699: : comp;
0700:
0701: if (currentHeavyweight == component) {
0702: currentLightweightRequests = null;
0703: } else {
0704: for (Iterator iter = currentLightweightRequests
0705: .iterator(); iter.hasNext();) {
0706: if (((LightweightFocusRequest) iter.next()).component == component) {
0707: iter.remove();
0708: }
0709: }
0710: if (currentLightweightRequests.size() == 0) {
0711: currentLightweightRequests = null;
0712: }
0713: }
0714: }
0715: for (Iterator iter = heavyweightRequests.iterator(); iter
0716: .hasNext();) {
0717: HeavyweightFocusRequest hwFocusRequest = (HeavyweightFocusRequest) iter
0718: .next();
0719: if (hwFocusRequest.heavyweight == heavyweight) {
0720: if (heavyweight == component) {
0721: iter.remove();
0722: continue;
0723: }
0724: for (Iterator lwIter = hwFocusRequest.lightweightRequests
0725: .iterator(); lwIter.hasNext();) {
0726: if (((LightweightFocusRequest) lwIter.next()).component == component) {
0727: lwIter.remove();
0728: }
0729: }
0730: if (hwFocusRequest.lightweightRequests.size() == 0) {
0731: iter.remove();
0732: }
0733: }
0734: }
0735: }
0736: }
0737:
0738: private static void clearFocusRequestList() {
0739: KeyboardFocusManager manager = KeyboardFocusManager
0740: .getCurrentKeyboardFocusManager();
0741:
0742: synchronized (heavyweightRequests) {
0743: for (Iterator iter = heavyweightRequests.iterator(); iter
0744: .hasNext();) {
0745: HeavyweightFocusRequest hwFocusRequest = (HeavyweightFocusRequest) iter
0746: .next();
0747: if (hwFocusRequest.lightweightRequests == null) {
0748: continue;
0749: }
0750: for (Iterator lwIter = hwFocusRequest.lightweightRequests
0751: .iterator(); lwIter.hasNext();) {
0752: manager
0753: .dequeueKeyEvents(-1,
0754: ((LightweightFocusRequest) lwIter
0755: .next()).component);
0756: }
0757: }
0758: heavyweightRequests.clear();
0759: }
0760: }
0761:
0762: public static KeyboardFocusManager getCurrentKeyboardFocusManager() {
0763: return getCurrentKeyboardFocusManager(AppContext
0764: .getAppContext());
0765: }
0766:
0767: synchronized static KeyboardFocusManager getCurrentKeyboardFocusManager(
0768: AppContext appcontext) {
0769: KeyboardFocusManager manager = (KeyboardFocusManager) appcontext
0770: .get(KeyboardFocusManager.class);
0771: if (manager == null) {
0772: manager = new DefaultKeyboardFocusManager();
0773: appcontext.put(KeyboardFocusManager.class, manager);
0774: }
0775: return manager;
0776: }
0777:
0778: // Bug #6223096: TCK: PP-TCK_11 Signature Test fails with CDC-PP-Sec
0779: /*
0780: synchronized static void setCurrentKeyboardFocusManager(
0781: KeyboardFocusManager newManager) throws SecurityException {
0782: AppContext appcontext = AppContext.getAppContext();
0783: if (newManager != null) {
0784: SecurityManager security = System.getSecurityManager();
0785: if (security != null) {
0786: if (replaceKeyboardFocusManagerPermission == null) {
0787: replaceKeyboardFocusManagerPermission =
0788: new AWTPermission("replaceKeyboardFocusManager");
0789: }
0790: security.
0791: checkPermission(replaceKeyboardFocusManagerPermission);
0792: }
0793: appcontext.put(KeyboardFocusManager.class, newManager);
0794: }
0795: else {
0796: appcontext.remove(KeyboardFocusManager.class);
0797: }
0798: }
0799: */
0800:
0801: static Set initFocusTraversalKeysSet(String value, Set targetSet) {
0802: StringTokenizer tokens = new StringTokenizer(value, ",");
0803: while (tokens.hasMoreTokens()) {
0804: targetSet.add(AWTKeyStroke.getAWTKeyStroke(tokens
0805: .nextToken()));
0806: }
0807: return (targetSet.isEmpty()) ? Collections.EMPTY_SET
0808: : Collections.unmodifiableSet(targetSet);
0809: }
0810:
0811: KeyboardFocusManager() {
0812: for (int i = 0; i < TRAVERSAL_KEY_LENGTH; i++) {
0813: defaultFocusTraversalKeys[i] = initFocusTraversalKeysSet(
0814: defaultFocusTraversalKeyStrings[i], new HashSet());
0815: }
0816: }
0817:
0818: public Component getFocusOwner() {
0819: synchronized (KeyboardFocusManager.class) {
0820: if (focusOwner == null) {
0821: return null;
0822: }
0823: return (focusOwner.appContext == AppContext.getAppContext()) ? focusOwner
0824: : null;
0825: }
0826: }
0827:
0828: Component getGlobalFocusOwner() throws SecurityException {
0829: synchronized (KeyboardFocusManager.class) {
0830: if (this == getCurrentKeyboardFocusManager()) {
0831: return focusOwner;
0832: } else {
0833: throw new SecurityException(notPrivileged);
0834: }
0835: }
0836: }
0837:
0838: void setGlobalFocusOwner(Component focusOwner) {
0839: Component oldFocusOwner = null;
0840: boolean shouldFire = false;
0841: if (focusOwner == null || focusOwner.isFocusable()) {
0842: synchronized (KeyboardFocusManager.class) {
0843: oldFocusOwner = getFocusOwner();
0844: try {
0845: fireVetoableChange("focusOwner", oldFocusOwner,
0846: focusOwner);
0847: } catch (PropertyVetoException e) {
0848: return;
0849: }
0850: KeyboardFocusManager.focusOwner = focusOwner;
0851: if (focusOwner != null
0852: && (getCurrentFocusCycleRoot() == null || !focusOwner
0853: .isFocusCycleRoot(getCurrentFocusCycleRoot()))) {
0854: Container rootAncestor = focusOwner
0855: .getFocusCycleRootAncestor();
0856: if (rootAncestor == null
0857: && (focusOwner instanceof Window)) {
0858: rootAncestor = (Container) focusOwner;
0859: }
0860: if (rootAncestor != null) {
0861: setGlobalCurrentFocusCycleRoot(rootAncestor);
0862: }
0863: }
0864: shouldFire = true;
0865: }
0866: }
0867: if (shouldFire) {
0868: firePropertyChange("focusOwner", oldFocusOwner, focusOwner);
0869: }
0870: }
0871:
0872: public void clearGlobalFocusOwner() {
0873: if (!GraphicsEnvironment.isHeadless()) {
0874: // Toolkit must be fully initialized, otherwise
0875: // _clearGlobalFocusOwner will crash or throw an exception
0876: Toolkit.getDefaultToolkit();
0877: if (!initialized) {
0878: // 6253293 - don't want to initialize the toolkit in the
0879: // constructor as this starts a bunch of threads up and doesn't
0880: // allow the VM to exit. Don't do it till we need it
0881: initIDs();
0882: initialized = true;
0883: }
0884: _clearGlobalFocusOwner();
0885: }
0886: }
0887:
0888: /**
0889: * Returns the Window which will be active after processing this request,
0890: * or null if this is a duplicate request. The active Window is useful
0891: * because some native platforms do not support setting the native focus
0892: * owner to null. On these platforms, the obvious choice is to set the
0893: * focus owner to the focus proxy of the active Window.
0894: */
0895: static Window markClearGlobalFocusOwner() {
0896: synchronized (heavyweightRequests) {
0897: HeavyweightFocusRequest hwFocusRequest = (HeavyweightFocusRequest) ((heavyweightRequests
0898: .size() > 0) ? heavyweightRequests.getLast() : null);
0899: if (hwFocusRequest == HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER) {
0900: // duplicate request
0901: return null;
0902: }
0903:
0904: heavyweightRequests
0905: .add(HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER);
0906:
0907: Component activeWindow = ((hwFocusRequest != null) ? getContainingWindow(hwFocusRequest.heavyweight)
0908: : getNativeFocusedWindow());
0909: while (activeWindow != null
0910: && !((activeWindow instanceof Frame) || (activeWindow instanceof Dialog))) {
0911: activeWindow = activeWindow.getParent();
0912: }
0913:
0914: return (Window) activeWindow;
0915: }
0916: }
0917:
0918: public Component getPermanentFocusOwner() {
0919: synchronized (KeyboardFocusManager.class) {
0920: if (permanentFocusOwner == null) {
0921: return null;
0922: }
0923: return (permanentFocusOwner.appContext == AppContext
0924: .getAppContext()) ? permanentFocusOwner : null;
0925: }
0926: }
0927:
0928: Component getGlobalPermanentFocusOwner() throws SecurityException {
0929: synchronized (KeyboardFocusManager.class) {
0930: if (this == getCurrentKeyboardFocusManager()) {
0931: return permanentFocusOwner;
0932: } else {
0933: throw new SecurityException(notPrivileged);
0934: }
0935: }
0936: }
0937:
0938: void setGlobalPermanentFocusOwner(Component permanentFocusOwner) {
0939: Component oldPermanentFocusOwner = null;
0940: boolean shouldFire = false;
0941: if (permanentFocusOwner == null
0942: || permanentFocusOwner.isFocusable()) {
0943: synchronized (KeyboardFocusManager.class) {
0944: oldPermanentFocusOwner = getPermanentFocusOwner();
0945: try {
0946: fireVetoableChange("permanentFocusOwner",
0947: oldPermanentFocusOwner, permanentFocusOwner);
0948: } catch (PropertyVetoException e) {
0949: return;
0950: }
0951: KeyboardFocusManager.permanentFocusOwner = permanentFocusOwner;
0952: KeyboardFocusManager
0953: .setMostRecentFocusOwner(permanentFocusOwner);
0954: shouldFire = true;
0955: }
0956: }
0957:
0958: if (shouldFire) {
0959: firePropertyChange("permanentFocusOwner",
0960: oldPermanentFocusOwner, permanentFocusOwner);
0961: }
0962: }
0963:
0964: public Window getFocusedWindow() {
0965:
0966: synchronized (KeyboardFocusManager.class) {
0967: if (focusedWindow == null) {
0968: return null;
0969: }
0970: return (focusedWindow.appContext == AppContext
0971: .getAppContext()) ? focusedWindow : null;
0972: }
0973: }
0974:
0975: Window getGlobalFocusedWindow() throws SecurityException {
0976: synchronized (KeyboardFocusManager.class) {
0977: if (this == getCurrentKeyboardFocusManager()) {
0978: return focusedWindow;
0979: } else {
0980: throw new SecurityException(notPrivileged);
0981: }
0982: }
0983: }
0984:
0985: void setGlobalFocusedWindow(Window focusedWindow) {
0986: Window oldFocusedWindow = null;
0987: boolean shouldFire = false;
0988: if (focusedWindow == null || focusedWindow.isFocusableWindow()) {
0989: synchronized (KeyboardFocusManager.class) {
0990: oldFocusedWindow = getFocusedWindow();
0991: try {
0992: fireVetoableChange("focusedWindow",
0993: oldFocusedWindow, focusedWindow);
0994: } catch (PropertyVetoException e) {
0995: return;
0996: }
0997: KeyboardFocusManager.focusedWindow = focusedWindow;
0998: shouldFire = true;
0999: }
1000: }
1001: if (shouldFire) {
1002: firePropertyChange("focusedWindow", oldFocusedWindow,
1003: focusedWindow);
1004: }
1005: }
1006:
1007: public Window getActiveWindow() {
1008: synchronized (KeyboardFocusManager.class) {
1009: if (activeWindow == null) {
1010: return null;
1011: }
1012: return (activeWindow.appContext == AppContext
1013: .getAppContext()) ? activeWindow : null;
1014: }
1015: }
1016:
1017: Window getGlobalActiveWindow() throws SecurityException {
1018: synchronized (KeyboardFocusManager.class) {
1019: if (this == getCurrentKeyboardFocusManager()) {
1020: return activeWindow;
1021: } else {
1022: throw new SecurityException(notPrivileged);
1023: }
1024: }
1025: }
1026:
1027: void setGlobalActiveWindow(Window activeWindow) {
1028: // 6205919:
1029: // PP-TCK: api/java_awt/Event/WinEventTests.html#WinEventTest0008 hangs.
1030: //
1031: // The following code was once performed within the synchronized block
1032: // of KeyboardFocusManager.class and caused a deadlock because the call
1033: // activeWindow.isFocusableWindow() can potentially try to grab the AWT
1034: // tree lock, while another thread might be doing a dispose call,
1035: // acquiring the AWT tree lock before trying to acquire the
1036: // KeyboardFocusManager.class lock.
1037: if ((activeWindow != null)
1038: && (!activeWindow.isFocusableWindow())) {
1039: return;
1040: }
1041:
1042: Window oldActiveWindow;
1043: synchronized (KeyboardFocusManager.class) {
1044: oldActiveWindow = getActiveWindow();
1045: try {
1046: fireVetoableChange("activeWindow", oldActiveWindow,
1047: activeWindow);
1048: } catch (PropertyVetoException e) {
1049: return;
1050: }
1051: KeyboardFocusManager.activeWindow = activeWindow;
1052: }
1053: firePropertyChange("activeWindow", oldActiveWindow,
1054: activeWindow);
1055: }
1056:
1057: public synchronized FocusTraversalPolicy getDefaultFocusTraversalPolicy() {
1058: return defaultPolicy;
1059: }
1060:
1061: public void setDefaultFocusTraversalPolicy(
1062: FocusTraversalPolicy defaultPolicy) {
1063: if (defaultPolicy == null) {
1064: throw new IllegalArgumentException(
1065: "default focus traversal policy cannot be null");
1066: }
1067: FocusTraversalPolicy oldPolicy;
1068: synchronized (this ) {
1069: oldPolicy = this .defaultPolicy;
1070: this .defaultPolicy = defaultPolicy;
1071: }
1072: firePropertyChange("defaultFocusTraversalPolicy", oldPolicy,
1073: defaultPolicy);
1074: }
1075:
1076: public void setDefaultFocusTraversalKeys(int id, Set keystrokes) {
1077: if (id < 0 || id >= TRAVERSAL_KEY_LENGTH) {
1078: throw new IllegalArgumentException(
1079: "invalid focus traversal key identifier");
1080: }
1081: if (keystrokes == null) {
1082: throw new IllegalArgumentException(
1083: "cannot set null Set of default focus traversal keys");
1084: }
1085: Set oldKeys;
1086: synchronized (this ) {
1087: for (Iterator iter = keystrokes.iterator(); iter.hasNext();) {
1088: Object obj = iter.next();
1089: if (obj == null) {
1090: throw new IllegalArgumentException(
1091: "cannot set null focus traversal key");
1092: }
1093: AWTKeyStroke keystroke = (AWTKeyStroke) obj;
1094: if (keystroke.getKeyChar() != KeyEvent.CHAR_UNDEFINED) {
1095: throw new IllegalArgumentException(
1096: "focus traversal keys cannot map to KEY_TYPED events");
1097: }
1098: for (int i = 0; i < TRAVERSAL_KEY_LENGTH; i++) {
1099: if (i == id) {
1100: continue;
1101: }
1102: if (defaultFocusTraversalKeys[i]
1103: .contains(keystroke)) {
1104: throw new IllegalArgumentException(
1105: "focus traversal keys must be unique for a Component");
1106: }
1107: }
1108: }
1109: oldKeys = defaultFocusTraversalKeys[id];
1110: defaultFocusTraversalKeys[id] = Collections
1111: .unmodifiableSet(new HashSet(keystrokes));
1112: }
1113: firePropertyChange(defaultFocusTraversalKeyPropertyNames[id],
1114: oldKeys, keystrokes);
1115: }
1116:
1117: public Set getDefaultFocusTraversalKeys(int id) {
1118: if (id < 0 || id >= TRAVERSAL_KEY_LENGTH) {
1119: throw new IllegalArgumentException(
1120: "invalid focus traversal key identifier");
1121: }
1122: return defaultFocusTraversalKeys[id];
1123: }
1124:
1125: public Container getCurrentFocusCycleRoot() {
1126:
1127: synchronized (KeyboardFocusManager.class) {
1128: if (currentFocusCycleRoot == null) {
1129: return null;
1130: }
1131: return (currentFocusCycleRoot.appContext == AppContext
1132: .getAppContext()) ? currentFocusCycleRoot : null;
1133: }
1134: }
1135:
1136: Container getGlobalCurrentFocusCycleRoot() throws SecurityException {
1137: synchronized (KeyboardFocusManager.class) {
1138: if (this == getCurrentKeyboardFocusManager()) {
1139: return currentFocusCycleRoot;
1140: } else {
1141: throw new SecurityException(notPrivileged);
1142: }
1143: }
1144: }
1145:
1146: void setGlobalCurrentFocusCycleRoot(Container newFocusCycleRoot) {
1147: Container oldFocusCycleRoot;
1148: synchronized (KeyboardFocusManager.class) {
1149: oldFocusCycleRoot = getCurrentFocusCycleRoot();
1150: currentFocusCycleRoot = newFocusCycleRoot;
1151: }
1152: firePropertyChange("currentFocusCycleRoot", oldFocusCycleRoot,
1153: newFocusCycleRoot);
1154: }
1155:
1156: public void addPropertyChangeListener(
1157: PropertyChangeListener listener) {
1158: if (listener != null) {
1159: synchronized (this ) {
1160: if (changeSupport == null) {
1161: changeSupport = new PropertyChangeSupport(this );
1162: }
1163: changeSupport.addPropertyChangeListener(listener);
1164: }
1165: }
1166: }
1167:
1168: public void removePropertyChangeListener(
1169: PropertyChangeListener listener) {
1170: if (listener != null) {
1171: synchronized (this ) {
1172: if (changeSupport != null) {
1173: changeSupport
1174: .removePropertyChangeListener(listener);
1175: }
1176: }
1177: }
1178: }
1179:
1180: public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
1181: if (changeSupport == null) {
1182: changeSupport = new PropertyChangeSupport(this );
1183: }
1184: return changeSupport.getPropertyChangeListeners();
1185: }
1186:
1187: /*
1188: public void addPropertyChangeListener(String propertyName,
1189: PropertyChangeListener listener) {
1190: if (listener != null) {
1191: synchronized (this) {
1192: if (changeSupport == null) {
1193: changeSupport = new PropertyChangeSupport(this);
1194: }
1195: changeSupport.addPropertyChangeListener(propertyName, listener);
1196: }
1197: }
1198: }
1199:
1200: public void removePropertyChangeListener(String propertyName,
1201: PropertyChangeListener listener) {
1202: if (listener != null) {
1203: synchronized (this) {
1204: if (changeSupport != null) {
1205: changeSupport.removePropertyChangeListener(propertyName,
1206: listener);
1207: }
1208: }
1209: }
1210: }
1211:
1212: public synchronized PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
1213: if (changeSupport == null) {
1214: changeSupport = new PropertyChangeSupport(this);
1215: }
1216: return changeSupport.getPropertyChangeListeners(propertyName);
1217: }
1218:
1219: */
1220: void firePropertyChange(String propertyName, Object oldValue,
1221: Object newValue) {
1222: PropertyChangeSupport changeSupport = this .changeSupport;
1223: if (changeSupport != null) {
1224: changeSupport.firePropertyChange(propertyName, oldValue,
1225: newValue);
1226: }
1227:
1228: }
1229:
1230: public void addVetoableChangeListener(
1231: VetoableChangeListener listener) {
1232: if (listener != null) {
1233: synchronized (this ) {
1234: if (vetoableSupport == null) {
1235: vetoableSupport = new VetoableChangeSupport(this );
1236: }
1237: vetoableSupport.addVetoableChangeListener(listener);
1238: }
1239: }
1240: }
1241:
1242: public void removeVetoableChangeListener(
1243: VetoableChangeListener listener) {
1244: if (listener != null) {
1245: synchronized (this ) {
1246: if (vetoableSupport != null) {
1247: vetoableSupport
1248: .removeVetoableChangeListener(listener);
1249: }
1250: }
1251: }
1252: }
1253:
1254: public synchronized VetoableChangeListener[] getVetoableChangeListeners() {
1255: if (vetoableSupport == null) {
1256: vetoableSupport = new VetoableChangeSupport(this );
1257: }
1258: return vetoableSupport.getVetoableChangeListeners();
1259: }
1260:
1261: /*
1262: public void addVetoableChangeListener(String propertyName,
1263: VetoableChangeListener listener) {
1264: if (listener != null) {
1265: synchronized (this) {
1266: if (vetoableSupport == null) {
1267: vetoableSupport = new VetoableChangeSupport(this);
1268: }
1269: vetoableSupport.addVetoableChangeListener(propertyName, listener);
1270: }
1271: }
1272: }
1273:
1274: public void removeVetoableChangeListener(String propertyName,
1275: VetoableChangeListener listener) {
1276: if (listener != null) {
1277: synchronized (this) {
1278: if (vetoableSupport != null) {
1279: vetoableSupport.removeVetoableChangeListener(propertyName,
1280: listener);
1281: }
1282: }
1283: }
1284: }
1285:
1286: public synchronized VetoableChangeListener[] getVetoableChangeListeners(String propertyName) {
1287: if (vetoableSupport == null) {
1288: vetoableSupport = new VetoableChangeSupport(this);
1289: }
1290: return vetoableSupport.getVetoableChangeListeners(propertyName);
1291: }
1292:
1293: */
1294: void fireVetoableChange(String propertyName, Object oldValue,
1295: Object newValue) throws PropertyVetoException {
1296: VetoableChangeSupport vetoableSupport = this .vetoableSupport;
1297: if (vetoableSupport != null) {
1298: vetoableSupport.fireVetoableChange(propertyName, oldValue,
1299: newValue);
1300: }
1301: }
1302:
1303: public void addKeyEventDispatcher(KeyEventDispatcher dispatcher) {
1304: if (dispatcher != null) {
1305: synchronized (this ) {
1306: if (keyEventDispatchers == null) {
1307: keyEventDispatchers = new java.util.LinkedList();
1308: }
1309: keyEventDispatchers.add(dispatcher);
1310: }
1311: }
1312: }
1313:
1314: public void removeKeyEventDispatcher(KeyEventDispatcher dispatcher) {
1315: if (dispatcher != null) {
1316: synchronized (this ) {
1317: if (keyEventDispatchers != null) {
1318: keyEventDispatchers.remove(dispatcher);
1319: }
1320: }
1321: }
1322: }
1323:
1324: synchronized java.util.List getKeyEventDispatchers() {
1325: return (keyEventDispatchers != null) ? (java.util.List) keyEventDispatchers
1326: .clone()
1327: : null;
1328: }
1329:
1330: public void addKeyEventPostProcessor(KeyEventPostProcessor processor) {
1331: if (processor != null) {
1332: synchronized (this ) {
1333: if (keyEventPostProcessors == null) {
1334: keyEventPostProcessors = new java.util.LinkedList();
1335: }
1336: keyEventPostProcessors.add(processor);
1337: }
1338: }
1339: }
1340:
1341: public void removeKeyEventPostProcessor(
1342: KeyEventPostProcessor processor) {
1343: if (processor != null) {
1344: synchronized (this ) {
1345: if (keyEventPostProcessors != null) {
1346: keyEventPostProcessors.remove(processor);
1347: }
1348: }
1349: }
1350: }
1351:
1352: java.util.List getKeyEventPostProcessors() {
1353: return (keyEventPostProcessors != null) ? (java.util.List) keyEventPostProcessors
1354: .clone()
1355: : null;
1356: }
1357:
1358: static void setMostRecentFocusOwner(Component component) {
1359: Component window = component;
1360: while (window != null && !(window instanceof Window)) {
1361: window = window.parent;
1362: }
1363: if (window != null) {
1364: setMostRecentFocusOwner((Window) window, component);
1365: }
1366: }
1367:
1368: static synchronized void setMostRecentFocusOwner(Window window,
1369: Component component) {
1370: WeakReference weakValue = null;
1371: if (component != null) {
1372: weakValue = new WeakReference(component);
1373: }
1374: mostRecentFocusOwners.put(window, weakValue);
1375: }
1376:
1377: static void clearMostRecentFocusOwner(Component comp) {
1378: Container window;
1379: if (comp == null) {
1380: return;
1381: }
1382: synchronized (comp.getTreeLock()) {
1383: window = comp.getParent();
1384: while (window != null && !(window instanceof Window)) {
1385: window = window.getParent();
1386: }
1387: }
1388: synchronized (KeyboardFocusManager.class) {
1389: if ((window != null)
1390: && (getMostRecentFocusOwner((Window) window) == comp)) {
1391: setMostRecentFocusOwner((Window) window, null);
1392: }
1393: if (window != null) {
1394: Window realWindow = (Window) window;
1395: if (realWindow.getTemporaryLostComponent() == comp) {
1396: realWindow.setTemporaryLostComponent(null);
1397: }
1398: }
1399: }
1400: }
1401:
1402: static synchronized Component getMostRecentFocusOwner(Window window) {
1403: WeakReference weakValue = (WeakReference) mostRecentFocusOwners
1404: .get(window);
1405: return weakValue == null ? null : (Component) weakValue.get();
1406: }
1407:
1408: public abstract boolean dispatchEvent(AWTEvent e);
1409:
1410: public final void redispatchEvent(Component target, AWTEvent e) {
1411: e.focusManagerIsDispatching = true;
1412: target.dispatchEvent(e);
1413: e.focusManagerIsDispatching = false;
1414: }
1415:
1416: public abstract boolean dispatchKeyEvent(KeyEvent e);
1417:
1418: public abstract boolean postProcessKeyEvent(KeyEvent e);
1419:
1420: public abstract void processKeyEvent(Component focusedComponent,
1421: KeyEvent e);
1422:
1423: public abstract void focusNextComponent(Component aComponent);
1424:
1425: public abstract void focusPreviousComponent(Component aComponent);
1426:
1427: public abstract void upFocusCycle(Component aComponent);
1428:
1429: public abstract void downFocusCycle(Container aContainer);
1430:
1431: abstract void enqueueKeyEvents(long after, Component untilFocused);
1432:
1433: abstract void dequeueKeyEvents(long after, Component untilFocused);
1434:
1435: abstract void discardKeyEvents(Component comp);
1436:
1437: public final void focusNextComponent() {
1438: Component focusOwner = getFocusOwner();
1439: if (focusOwner != null) {
1440: focusNextComponent(focusOwner);
1441: }
1442: }
1443:
1444: public final void focusPreviousComponent() {
1445: Component focusOwner = getFocusOwner();
1446: if (focusOwner != null) {
1447: focusPreviousComponent(focusOwner);
1448: }
1449: }
1450:
1451: public final void upFocusCycle() {
1452: Component focusOwner = getFocusOwner();
1453: if (focusOwner != null) {
1454: upFocusCycle(focusOwner);
1455: }
1456: }
1457:
1458: public final void downFocusCycle() {
1459: Component focusOwner = getFocusOwner();
1460: if (focusOwner instanceof Container) {
1461: downFocusCycle((Container) focusOwner);
1462: }
1463: }
1464: }
|