src/share/classes/java/awt/KeyboardFocusManager.java

Print this page




 331         {
 332             AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, 0, false),
 333             AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, InputEvent.CTRL_DOWN_MASK | InputEvent.CTRL_MASK, false),
 334         },
 335         {
 336             AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_DOWN_MASK | InputEvent.SHIFT_MASK, false),
 337             AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB,
 338                                          InputEvent.SHIFT_DOWN_MASK | InputEvent.SHIFT_MASK | InputEvent.CTRL_DOWN_MASK | InputEvent.CTRL_MASK,
 339                                          false),
 340         },
 341         {},
 342         {},
 343       };
 344     /**
 345      * The default focus traversal keys. Each array of traversal keys will be
 346      * in effect on all Windows that have no such array of their own explicitly
 347      * set. Each array will also be inherited, recursively, by any child
 348      * Component of those Windows that has no such array of its own explicitly
 349      * set.
 350      */
 351     private Set[] defaultFocusTraversalKeys = new Set[4];
 352 
 353     /**
 354      * The current focus cycle root. If the focus owner is itself a focus cycle
 355      * root, then it may be ambiguous as to which Components represent the next
 356      * and previous Components to focus during normal focus traversal. In that
 357      * case, the current focus cycle root is used to differentiate among the
 358      * possibilities.
 359      */
 360     private static Container currentFocusCycleRoot;
 361 
 362     /**
 363      * A description of any VetoableChangeListeners which have been registered.
 364      */
 365     private VetoableChangeSupport vetoableSupport;
 366 
 367     /**
 368      * A description of any PropertyChangeListeners which have been registered.
 369      */
 370     private PropertyChangeSupport changeSupport;
 371 
 372     /**
 373      * This KeyboardFocusManager's KeyEventDispatcher chain. The List does not
 374      * include this KeyboardFocusManager unless it was explicitly re-registered
 375      * via a call to <code>addKeyEventDispatcher</code>. If no other
 376      * KeyEventDispatchers are registered, this field may be null or refer to
 377      * a List of length 0.
 378      */
 379     private java.util.LinkedList keyEventDispatchers;
 380 
 381     /**
 382      * This KeyboardFocusManager's KeyEventPostProcessor chain. The List does
 383      * not include this KeyboardFocusManager unless it was explicitly
 384      * re-registered via a call to <code>addKeyEventPostProcessor</code>.
 385      * If no other KeyEventPostProcessors are registered, this field may be
 386      * null or refer to a List of length 0.
 387      */
 388     private java.util.LinkedList keyEventPostProcessors;
 389 
 390     /**
 391      * Maps Windows to those Windows' most recent focus owners.
 392      */
 393     private static java.util.Map mostRecentFocusOwners = new WeakHashMap();
 394 
 395     /**
 396      * We cache the permission used to verify that the calling thread is
 397      * permitted to access the global focus state.
 398      */
 399     private static AWTPermission replaceKeyboardFocusManagerPermission;
 400 
 401     /*
 402      * SequencedEvent which is currently dispatched in AppContext.
 403      */
 404     transient SequencedEvent currentSequencedEvent = null;
 405 
 406     final void setCurrentSequencedEvent(SequencedEvent current) {
 407         synchronized (SequencedEvent.class) {
 408             assert(current == null || currentSequencedEvent == null);
 409             currentSequencedEvent = current;
 410         }
 411     }
 412 
 413     final SequencedEvent getCurrentSequencedEvent() {
 414         synchronized (SequencedEvent.class) {
 415             return currentSequencedEvent;
 416         }
 417     }
 418 
 419     static Set<AWTKeyStroke> initFocusTraversalKeysSet(String value, Set<AWTKeyStroke> targetSet) {
 420         StringTokenizer tokens = new StringTokenizer(value, ",");
 421         while (tokens.hasMoreTokens()) {
 422             targetSet.add(AWTKeyStroke.getAWTKeyStroke(tokens.nextToken()));
 423         }
 424         return (targetSet.isEmpty())
 425             ? Collections.EMPTY_SET
 426             : Collections.unmodifiableSet(targetSet);
 427     }
 428 
 429     /**
 430      * Initializes a KeyboardFocusManager.
 431      */
 432     public KeyboardFocusManager() {
 433         for (int i = 0; i < TRAVERSAL_KEY_LENGTH; i++) {
 434             Set work_set = new HashSet();
 435             for (int j = 0; j < defaultFocusTraversalKeyStrokes[i].length; j++) {
 436                 work_set.add(defaultFocusTraversalKeyStrokes[i][j]);
 437             }
 438             defaultFocusTraversalKeys[i] = (work_set.isEmpty())
 439                 ? Collections.EMPTY_SET
 440                 : Collections.unmodifiableSet(work_set);
 441         }
 442         initPeer();
 443     }
 444 
 445     private void initPeer() {
 446         Toolkit tk = Toolkit.getDefaultToolkit();
 447         KeyboardFocusManagerPeerProvider peerProvider = (KeyboardFocusManagerPeerProvider)tk;
 448         peer = peerProvider.getKeyboardFocusManagerPeer();
 449     }
 450 
 451     /**
 452      * Returns the focus owner, if the focus owner is in the same context as
 453      * the calling thread. The focus owner is defined as the Component in an
 454      * application that will typically receive all KeyEvents generated by the


1108      *         or if keystrokes is {@code null},
1109      *         or if keystrokes contains {@code null},
1110      *         or if any keystroke
1111      *         represents a {@code KEY_TYPED} event,
1112      *         or if any keystroke already maps
1113      *         to another default focus traversal operation
1114      * @beaninfo
1115      *       bound: true
1116      */
1117     public void
1118         setDefaultFocusTraversalKeys(int id,
1119                                      Set<? extends AWTKeyStroke> keystrokes)
1120     {
1121         if (id < 0 || id >= TRAVERSAL_KEY_LENGTH) {
1122             throw new IllegalArgumentException("invalid focus traversal key identifier");
1123         }
1124         if (keystrokes == null) {
1125             throw new IllegalArgumentException("cannot set null Set of default focus traversal keys");
1126         }
1127 
1128         Set oldKeys;
1129 
1130         synchronized (this) {
1131             for (AWTKeyStroke keystroke : keystrokes) {
1132 
1133                 if (keystroke == null) {
1134                     throw new IllegalArgumentException("cannot set null focus traversal key");
1135                 }
1136 
1137                 if (keystroke.getKeyChar() != KeyEvent.CHAR_UNDEFINED) {
1138                     throw new IllegalArgumentException("focus traversal keys cannot map to KEY_TYPED events");
1139                 }
1140 
1141                 // Check to see if key already maps to another traversal
1142                 // operation
1143                 for (int i = 0; i < TRAVERSAL_KEY_LENGTH; i++) {
1144                     if (i == id) {
1145                         continue;
1146                     }
1147 
1148                     if (defaultFocusTraversalKeys[i].contains(keystroke)) {
1149                         throw new IllegalArgumentException("focus traversal keys must be unique for a Component");
1150                     }
1151                 }
1152             }
1153 
1154             oldKeys = defaultFocusTraversalKeys[id];
1155             defaultFocusTraversalKeys[id] =
1156                 Collections.unmodifiableSet(new HashSet(keystrokes));
1157         }
1158 
1159         firePropertyChange(defaultFocusTraversalKeyPropertyNames[id],
1160                            oldKeys, keystrokes);
1161     }
1162 
1163     /**
1164      * Returns a Set of default focus traversal keys for a given traversal
1165      * operation. This traversal key Set will be in effect on all Windows that
1166      * have no such Set of their own explicitly defined. This Set will also be
1167      * inherited, recursively, by any child Component of those Windows that has
1168      * no such Set of its own explicitly defined. (See
1169      * <code>setDefaultFocusTraversalKeys</code> for a full description of each
1170      * operation.)
1171      *
1172      * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
1173      *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
1174      *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
1175      *        KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
1176      * @return the <code>Set</code> of <code>AWTKeyStroke</code>s


1682      * as soon as one KeyEventDispatcher returns <code>true</code> from its
1683      * <code>dispatchKeyEvent</code> method. There is no limit to the total
1684      * number of KeyEventDispatchers which can be added, nor to the number of
1685      * times which a particular KeyEventDispatcher instance can be added.
1686      * <p>
1687      * If a null dispatcher is specified, no action is taken and no exception
1688      * is thrown.
1689      * <p>
1690      * In a multithreaded application, {@link KeyEventDispatcher} behaves
1691      * the same as other AWT listeners.  See
1692      * <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
1693      * >AWT Threading Issues</a> for more details.
1694      *
1695      * @param dispatcher the KeyEventDispatcher to add to the dispatcher chain
1696      * @see #removeKeyEventDispatcher
1697      */
1698     public void addKeyEventDispatcher(KeyEventDispatcher dispatcher) {
1699         if (dispatcher != null) {
1700             synchronized (this) {
1701                 if (keyEventDispatchers == null) {
1702                     keyEventDispatchers = new java.util.LinkedList();
1703                 }
1704                 keyEventDispatchers.add(dispatcher);
1705             }
1706         }
1707     }
1708 
1709     /**
1710      * Removes a KeyEventDispatcher which was previously added to this
1711      * KeyboardFocusManager's dispatcher chain. This KeyboardFocusManager
1712      * cannot itself be removed, unless it was explicitly re-registered via a
1713      * call to <code>addKeyEventDispatcher</code>.
1714      * <p>
1715      * If a null dispatcher is specified, if the specified dispatcher is not
1716      * in the dispatcher chain, or if this KeyboardFocusManager is specified
1717      * without having been explicitly re-registered, no action is taken and no
1718      * exception is thrown.
1719      * <p>
1720      * In a multithreaded application, {@link KeyEventDispatcher} behaves
1721      * the same as other AWT listeners.  See
1722      * <a href="doc-files/AWTThreadIssues.html#ListenersThreads"


1770      * total number of KeyEventPostProcessors that can be added, nor to the
1771      * number of times that a particular KeyEventPostProcessor instance can be
1772      * added.
1773      * <p>
1774      * If a null post-processor is specified, no action is taken and no
1775      * exception is thrown.
1776      * <p>
1777      * In a multithreaded application, {@link KeyEventPostProcessor} behaves
1778      * the same as other AWT listeners.  See
1779      * <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
1780      * >AWT Threading Issues</a> for more details.
1781      *
1782      * @param processor the KeyEventPostProcessor to add to the post-processor
1783      *        chain
1784      * @see #removeKeyEventPostProcessor
1785      */
1786     public void addKeyEventPostProcessor(KeyEventPostProcessor processor) {
1787         if (processor != null) {
1788             synchronized (this) {
1789                 if (keyEventPostProcessors == null) {
1790                     keyEventPostProcessors = new java.util.LinkedList();
1791                 }
1792                 keyEventPostProcessors.add(processor);
1793             }
1794         }
1795     }
1796 
1797 
1798     /**
1799      * Removes a previously added KeyEventPostProcessor from this
1800      * KeyboardFocusManager's post-processor chain. This KeyboardFocusManager
1801      * cannot itself be entirely removed from the chain. Only additional
1802      * references added via <code>addKeyEventPostProcessor</code> can be
1803      * removed.
1804      * <p>
1805      * If a null post-processor is specified, if the specified post-processor
1806      * is not in the post-processor chain, or if this KeyboardFocusManager is
1807      * specified without having been explicitly added, no action is taken and
1808      * no exception is thrown.
1809      * <p>
1810      * In a multithreaded application, {@link KeyEventPostProcessor} behaves


1848             : null;
1849     }
1850 
1851 
1852 
1853     static void setMostRecentFocusOwner(Component component) {
1854         Component window = component;
1855         while (window != null && !(window instanceof Window)) {
1856             window = window.parent;
1857         }
1858         if (window != null) {
1859             setMostRecentFocusOwner((Window)window, component);
1860         }
1861     }
1862     static synchronized void setMostRecentFocusOwner(Window window,
1863                                                      Component component) {
1864         // ATTN: component has a strong reference to window via chain
1865         // of Component.parent fields.  Since WeakHasMap refers to its
1866         // values strongly, we need to break the strong link from the
1867         // value (component) back to its key (window).
1868         WeakReference weakValue = null;
1869         if (component != null) {
1870             weakValue = new WeakReference(component);
1871         }
1872         mostRecentFocusOwners.put(window, weakValue);
1873     }
1874     static void clearMostRecentFocusOwner(Component comp) {
1875         Container window;
1876 
1877         if (comp == null) {
1878             return;
1879         }
1880 
1881         synchronized (comp.getTreeLock()) {
1882             window = comp.getParent();
1883             while (window != null && !(window instanceof Window)) {
1884                 window = window.getParent();
1885             }
1886         }
1887 
1888         synchronized (KeyboardFocusManager.class) {
1889             if ((window != null)
1890                 && (getMostRecentFocusOwner((Window)window) == comp))
1891             {
1892                 setMostRecentFocusOwner((Window)window, null);
1893             }
1894             // Also clear temporary lost component stored in Window
1895             if (window != null) {
1896                 Window realWindow = (Window)window;
1897                 if (realWindow.getTemporaryLostComponent() == comp) {
1898                     realWindow.setTemporaryLostComponent(null);
1899                 }
1900             }
1901         }
1902     }
1903 
1904     /*
1905      * Please be careful changing this method! It is called from
1906      * javax.swing.JComponent.runInputVerifier() using reflection.
1907      */
1908     static synchronized Component getMostRecentFocusOwner(Window window) {
1909         WeakReference weakValue =
1910             (WeakReference)mostRecentFocusOwners.get(window);
1911         return weakValue == null ? null : (Component)weakValue.get();
1912     }
1913 
1914     /**
1915      * This method is called by the AWT event dispatcher requesting that the
1916      * current KeyboardFocusManager dispatch the specified event on its behalf.
1917      * It is expected that all KeyboardFocusManagers will dispatch all
1918      * FocusEvents, all WindowEvents related to focus, and all KeyEvents.
1919      * These events should be dispatched based on the KeyboardFocusManager's
1920      * notion of the focus owner and the focused and active Windows, sometimes
1921      * overriding the source of the specified AWTEvent. Dispatching must be
1922      * done using <code>redispatchEvent</code> to prevent the AWT event
1923      * dispatcher from recursively requesting that the KeyboardFocusManager
1924      * dispatch the event again. If this method returns <code>false</code>,
1925      * then the AWT event dispatcher will attempt to dispatch the event itself.
1926      *
1927      * @param e the AWTEvent to be dispatched
1928      * @return <code>true</code> if this method dispatched the event;
1929      *         <code>false</code> otherwise


2631 
2632         synchronized(heavyweightRequests) {
2633             if (currentLightweightRequests != null) {
2634                 clearingCurrentLightweightRequests = true;
2635                 disableRestoreFocus = true;
2636                 localLightweightRequests = currentLightweightRequests;
2637                 allowSyncFocusRequests = (localLightweightRequests.size() < 2);
2638                 currentLightweightRequests = null;
2639             } else {
2640                 // do nothing
2641                 return;
2642             }
2643         }
2644 
2645         Throwable caughtEx = null;
2646         try {
2647             if (localLightweightRequests != null) {
2648                 Component lastFocusOwner = null;
2649                 Component currentFocusOwner = null;
2650 
2651                 for (Iterator iter = localLightweightRequests.iterator(); iter.hasNext(); ) {
2652 
2653                     currentFocusOwner = manager.getGlobalFocusOwner();
2654                     LightweightFocusRequest lwFocusRequest =
2655                         (LightweightFocusRequest)iter.next();
2656 
2657                     /*
2658                      * WARNING: This is based on DKFM's logic solely!
2659                      *
2660                      * We allow to trigger restoreFocus() in the dispatching process
2661                      * only if we have the last request to dispatch. If the last request
2662                      * fails, focus will be restored to either the component of the last
2663                      * previously succedded request, or to to the focus owner that was
2664                      * before this clearing proccess.
2665                      */
2666                     if (!iter.hasNext()) {
2667                         disableRestoreFocus = false;
2668                     }
2669 
2670                     FocusEvent currentFocusOwnerEvent = null;
2671                     /*
2672                      * We're not dispatching FOCUS_LOST while the current focus owner is null.
2673                      * But regardless of whether it's null or not, we're clearing ALL the local
2674                      * lw requests.
2675                      */


2960 
2961     /**
2962      * Clears markers queue
2963      * This method is not intended to be overridden by KFM's.
2964      * Only DefaultKeyboardFocusManager can implement it.
2965      * @since 1.5
2966      */
2967     void clearMarkers() {
2968     }
2969 
2970     static boolean removeFirstRequest() {
2971         KeyboardFocusManager manager =
2972             KeyboardFocusManager.getCurrentKeyboardFocusManager();
2973 
2974         synchronized(heavyweightRequests) {
2975             HeavyweightFocusRequest hwFocusRequest = getFirstHWRequest();
2976 
2977             if (hwFocusRequest != null) {
2978                 heavyweightRequests.removeFirst();
2979                 if (hwFocusRequest.lightweightRequests != null) {
2980                     for (Iterator lwIter = hwFocusRequest.lightweightRequests.
2981                              iterator();
2982                          lwIter.hasNext(); )
2983                     {
2984                         manager.dequeueKeyEvents
2985                             (-1, ((LightweightFocusRequest)lwIter.next()).
2986                              component);
2987                     }
2988                 }
2989             }
2990             // Fix for 4799136 - clear type-ahead markers if requests queue is empty
2991             // We do it here because this method is called only when problems happen
2992             if (heavyweightRequests.size() == 0) {
2993                 manager.clearMarkers();
2994             }
2995             return (heavyweightRequests.size() > 0);
2996         }
2997     }
2998     static void removeLastFocusRequest(Component heavyweight) {
2999         if (log.isLoggable(PlatformLogger.Level.FINE)) {
3000             if (heavyweight == null) {
3001                 log.fine("Assertion (heavyweight != null) failed");
3002             }
3003         }
3004 
3005         KeyboardFocusManager manager =


3045         if (wfrom == null) {
3046             return false;
3047         }
3048         return (wto != wfrom);
3049     }
3050 
3051     static Component getHeavyweight(Component comp) {
3052         if (comp == null || comp.getPeer() == null) {
3053             return null;
3054         } else if (comp.getPeer() instanceof LightweightPeer) {
3055             return comp.getNativeContainer();
3056         } else {
3057             return comp;
3058         }
3059     }
3060 
3061     static Field proxyActive;
3062     // Accessor to private field isProxyActive of KeyEvent
3063     private static boolean isProxyActiveImpl(KeyEvent e) {
3064         if (proxyActive == null) {
3065             proxyActive = (Field) AccessController.doPrivileged(new PrivilegedAction() {
3066                     public Object run() {
3067                         Field field = null;
3068                         try {
3069                             field = KeyEvent.class.getDeclaredField("isProxyActive");
3070                             if (field != null) {
3071                                 field.setAccessible(true);
3072                             }
3073                         } catch (NoSuchFieldException nsf) {
3074                             assert(false);
3075                         }
3076                         return field;
3077                     }
3078                 });
3079         }
3080 
3081         try {
3082             return proxyActive.getBoolean(e);
3083         } catch (IllegalAccessException iae) {
3084             assert(false);
3085         }
3086         return false;




 331         {
 332             AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, 0, false),
 333             AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, InputEvent.CTRL_DOWN_MASK | InputEvent.CTRL_MASK, false),
 334         },
 335         {
 336             AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_DOWN_MASK | InputEvent.SHIFT_MASK, false),
 337             AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB,
 338                                          InputEvent.SHIFT_DOWN_MASK | InputEvent.SHIFT_MASK | InputEvent.CTRL_DOWN_MASK | InputEvent.CTRL_MASK,
 339                                          false),
 340         },
 341         {},
 342         {},
 343       };
 344     /**
 345      * The default focus traversal keys. Each array of traversal keys will be
 346      * in effect on all Windows that have no such array of their own explicitly
 347      * set. Each array will also be inherited, recursively, by any child
 348      * Component of those Windows that has no such array of its own explicitly
 349      * set.
 350      */
 351     private Set<AWTKeyStroke>[] defaultFocusTraversalKeys = new Set[4];
 352 
 353     /**
 354      * The current focus cycle root. If the focus owner is itself a focus cycle
 355      * root, then it may be ambiguous as to which Components represent the next
 356      * and previous Components to focus during normal focus traversal. In that
 357      * case, the current focus cycle root is used to differentiate among the
 358      * possibilities.
 359      */
 360     private static Container currentFocusCycleRoot;
 361 
 362     /**
 363      * A description of any VetoableChangeListeners which have been registered.
 364      */
 365     private VetoableChangeSupport vetoableSupport;
 366 
 367     /**
 368      * A description of any PropertyChangeListeners which have been registered.
 369      */
 370     private PropertyChangeSupport changeSupport;
 371 
 372     /**
 373      * This KeyboardFocusManager's KeyEventDispatcher chain. The List does not
 374      * include this KeyboardFocusManager unless it was explicitly re-registered
 375      * via a call to <code>addKeyEventDispatcher</code>. If no other
 376      * KeyEventDispatchers are registered, this field may be null or refer to
 377      * a List of length 0.
 378      */
 379     private java.util.LinkedList<KeyEventDispatcher> keyEventDispatchers;
 380 
 381     /**
 382      * This KeyboardFocusManager's KeyEventPostProcessor chain. The List does
 383      * not include this KeyboardFocusManager unless it was explicitly
 384      * re-registered via a call to <code>addKeyEventPostProcessor</code>.
 385      * If no other KeyEventPostProcessors are registered, this field may be
 386      * null or refer to a List of length 0.
 387      */
 388     private java.util.LinkedList<KeyEventPostProcessor> keyEventPostProcessors;
 389 
 390     /**
 391      * Maps Windows to those Windows' most recent focus owners.
 392      */
 393     private static java.util.Map<Window, WeakReference<Component>> mostRecentFocusOwners = new WeakHashMap<>();
 394 
 395     /**
 396      * We cache the permission used to verify that the calling thread is
 397      * permitted to access the global focus state.
 398      */
 399     private static AWTPermission replaceKeyboardFocusManagerPermission;
 400 
 401     /*
 402      * SequencedEvent which is currently dispatched in AppContext.
 403      */
 404     transient SequencedEvent currentSequencedEvent = null;
 405 
 406     final void setCurrentSequencedEvent(SequencedEvent current) {
 407         synchronized (SequencedEvent.class) {
 408             assert(current == null || currentSequencedEvent == null);
 409             currentSequencedEvent = current;
 410         }
 411     }
 412 
 413     final SequencedEvent getCurrentSequencedEvent() {
 414         synchronized (SequencedEvent.class) {
 415             return currentSequencedEvent;
 416         }
 417     }
 418 
 419     static Set<AWTKeyStroke> initFocusTraversalKeysSet(String value, Set<AWTKeyStroke> targetSet) {
 420         StringTokenizer tokens = new StringTokenizer(value, ",");
 421         while (tokens.hasMoreTokens()) {
 422             targetSet.add(AWTKeyStroke.getAWTKeyStroke(tokens.nextToken()));
 423         }
 424         return (targetSet.isEmpty())
 425             ? Collections.EMPTY_SET
 426             : Collections.unmodifiableSet(targetSet);
 427     }
 428 
 429     /**
 430      * Initializes a KeyboardFocusManager.
 431      */
 432     public KeyboardFocusManager() {
 433         for (int i = 0; i < TRAVERSAL_KEY_LENGTH; i++) {
 434             Set<AWTKeyStroke> work_set = new HashSet<>();
 435             for (int j = 0; j < defaultFocusTraversalKeyStrokes[i].length; j++) {
 436                 work_set.add(defaultFocusTraversalKeyStrokes[i][j]);
 437             }
 438             defaultFocusTraversalKeys[i] = (work_set.isEmpty())
 439                 ? Collections.EMPTY_SET
 440                 : Collections.unmodifiableSet(work_set);
 441         }
 442         initPeer();
 443     }
 444 
 445     private void initPeer() {
 446         Toolkit tk = Toolkit.getDefaultToolkit();
 447         KeyboardFocusManagerPeerProvider peerProvider = (KeyboardFocusManagerPeerProvider)tk;
 448         peer = peerProvider.getKeyboardFocusManagerPeer();
 449     }
 450 
 451     /**
 452      * Returns the focus owner, if the focus owner is in the same context as
 453      * the calling thread. The focus owner is defined as the Component in an
 454      * application that will typically receive all KeyEvents generated by the


1108      *         or if keystrokes is {@code null},
1109      *         or if keystrokes contains {@code null},
1110      *         or if any keystroke
1111      *         represents a {@code KEY_TYPED} event,
1112      *         or if any keystroke already maps
1113      *         to another default focus traversal operation
1114      * @beaninfo
1115      *       bound: true
1116      */
1117     public void
1118         setDefaultFocusTraversalKeys(int id,
1119                                      Set<? extends AWTKeyStroke> keystrokes)
1120     {
1121         if (id < 0 || id >= TRAVERSAL_KEY_LENGTH) {
1122             throw new IllegalArgumentException("invalid focus traversal key identifier");
1123         }
1124         if (keystrokes == null) {
1125             throw new IllegalArgumentException("cannot set null Set of default focus traversal keys");
1126         }
1127 
1128         Set<AWTKeyStroke> oldKeys;
1129 
1130         synchronized (this) {
1131             for (AWTKeyStroke keystroke : keystrokes) {
1132 
1133                 if (keystroke == null) {
1134                     throw new IllegalArgumentException("cannot set null focus traversal key");
1135                 }
1136 
1137                 if (keystroke.getKeyChar() != KeyEvent.CHAR_UNDEFINED) {
1138                     throw new IllegalArgumentException("focus traversal keys cannot map to KEY_TYPED events");
1139                 }
1140 
1141                 // Check to see if key already maps to another traversal
1142                 // operation
1143                 for (int i = 0; i < TRAVERSAL_KEY_LENGTH; i++) {
1144                     if (i == id) {
1145                         continue;
1146                     }
1147 
1148                     if (defaultFocusTraversalKeys[i].contains(keystroke)) {
1149                         throw new IllegalArgumentException("focus traversal keys must be unique for a Component");
1150                     }
1151                 }
1152             }
1153 
1154             oldKeys = defaultFocusTraversalKeys[id];
1155             defaultFocusTraversalKeys[id] =
1156                 Collections.unmodifiableSet(new HashSet<>(keystrokes));
1157         }
1158 
1159         firePropertyChange(defaultFocusTraversalKeyPropertyNames[id],
1160                            oldKeys, keystrokes);
1161     }
1162 
1163     /**
1164      * Returns a Set of default focus traversal keys for a given traversal
1165      * operation. This traversal key Set will be in effect on all Windows that
1166      * have no such Set of their own explicitly defined. This Set will also be
1167      * inherited, recursively, by any child Component of those Windows that has
1168      * no such Set of its own explicitly defined. (See
1169      * <code>setDefaultFocusTraversalKeys</code> for a full description of each
1170      * operation.)
1171      *
1172      * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
1173      *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
1174      *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
1175      *        KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
1176      * @return the <code>Set</code> of <code>AWTKeyStroke</code>s


1682      * as soon as one KeyEventDispatcher returns <code>true</code> from its
1683      * <code>dispatchKeyEvent</code> method. There is no limit to the total
1684      * number of KeyEventDispatchers which can be added, nor to the number of
1685      * times which a particular KeyEventDispatcher instance can be added.
1686      * <p>
1687      * If a null dispatcher is specified, no action is taken and no exception
1688      * is thrown.
1689      * <p>
1690      * In a multithreaded application, {@link KeyEventDispatcher} behaves
1691      * the same as other AWT listeners.  See
1692      * <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
1693      * >AWT Threading Issues</a> for more details.
1694      *
1695      * @param dispatcher the KeyEventDispatcher to add to the dispatcher chain
1696      * @see #removeKeyEventDispatcher
1697      */
1698     public void addKeyEventDispatcher(KeyEventDispatcher dispatcher) {
1699         if (dispatcher != null) {
1700             synchronized (this) {
1701                 if (keyEventDispatchers == null) {
1702                     keyEventDispatchers = new java.util.LinkedList<>();
1703                 }
1704                 keyEventDispatchers.add(dispatcher);
1705             }
1706         }
1707     }
1708 
1709     /**
1710      * Removes a KeyEventDispatcher which was previously added to this
1711      * KeyboardFocusManager's dispatcher chain. This KeyboardFocusManager
1712      * cannot itself be removed, unless it was explicitly re-registered via a
1713      * call to <code>addKeyEventDispatcher</code>.
1714      * <p>
1715      * If a null dispatcher is specified, if the specified dispatcher is not
1716      * in the dispatcher chain, or if this KeyboardFocusManager is specified
1717      * without having been explicitly re-registered, no action is taken and no
1718      * exception is thrown.
1719      * <p>
1720      * In a multithreaded application, {@link KeyEventDispatcher} behaves
1721      * the same as other AWT listeners.  See
1722      * <a href="doc-files/AWTThreadIssues.html#ListenersThreads"


1770      * total number of KeyEventPostProcessors that can be added, nor to the
1771      * number of times that a particular KeyEventPostProcessor instance can be
1772      * added.
1773      * <p>
1774      * If a null post-processor is specified, no action is taken and no
1775      * exception is thrown.
1776      * <p>
1777      * In a multithreaded application, {@link KeyEventPostProcessor} behaves
1778      * the same as other AWT listeners.  See
1779      * <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
1780      * >AWT Threading Issues</a> for more details.
1781      *
1782      * @param processor the KeyEventPostProcessor to add to the post-processor
1783      *        chain
1784      * @see #removeKeyEventPostProcessor
1785      */
1786     public void addKeyEventPostProcessor(KeyEventPostProcessor processor) {
1787         if (processor != null) {
1788             synchronized (this) {
1789                 if (keyEventPostProcessors == null) {
1790                     keyEventPostProcessors = new java.util.LinkedList<>();
1791                 }
1792                 keyEventPostProcessors.add(processor);
1793             }
1794         }
1795     }
1796 
1797 
1798     /**
1799      * Removes a previously added KeyEventPostProcessor from this
1800      * KeyboardFocusManager's post-processor chain. This KeyboardFocusManager
1801      * cannot itself be entirely removed from the chain. Only additional
1802      * references added via <code>addKeyEventPostProcessor</code> can be
1803      * removed.
1804      * <p>
1805      * If a null post-processor is specified, if the specified post-processor
1806      * is not in the post-processor chain, or if this KeyboardFocusManager is
1807      * specified without having been explicitly added, no action is taken and
1808      * no exception is thrown.
1809      * <p>
1810      * In a multithreaded application, {@link KeyEventPostProcessor} behaves


1848             : null;
1849     }
1850 
1851 
1852 
1853     static void setMostRecentFocusOwner(Component component) {
1854         Component window = component;
1855         while (window != null && !(window instanceof Window)) {
1856             window = window.parent;
1857         }
1858         if (window != null) {
1859             setMostRecentFocusOwner((Window)window, component);
1860         }
1861     }
1862     static synchronized void setMostRecentFocusOwner(Window window,
1863                                                      Component component) {
1864         // ATTN: component has a strong reference to window via chain
1865         // of Component.parent fields.  Since WeakHasMap refers to its
1866         // values strongly, we need to break the strong link from the
1867         // value (component) back to its key (window).
1868         WeakReference<Component> weakValue = null;
1869         if (component != null) {
1870             weakValue = new WeakReference<>(component);
1871         }
1872         mostRecentFocusOwners.put(window, weakValue);
1873     }
1874     static void clearMostRecentFocusOwner(Component comp) {
1875         Container window;
1876 
1877         if (comp == null) {
1878             return;
1879         }
1880 
1881         synchronized (comp.getTreeLock()) {
1882             window = comp.getParent();
1883             while (window != null && !(window instanceof Window)) {
1884                 window = window.getParent();
1885             }
1886         }
1887 
1888         synchronized (KeyboardFocusManager.class) {
1889             if ((window != null)
1890                 && (getMostRecentFocusOwner((Window)window) == comp))
1891             {
1892                 setMostRecentFocusOwner((Window)window, null);
1893             }
1894             // Also clear temporary lost component stored in Window
1895             if (window != null) {
1896                 Window realWindow = (Window)window;
1897                 if (realWindow.getTemporaryLostComponent() == comp) {
1898                     realWindow.setTemporaryLostComponent(null);
1899                 }
1900             }
1901         }
1902     }
1903 
1904     /*
1905      * Please be careful changing this method! It is called from
1906      * javax.swing.JComponent.runInputVerifier() using reflection.
1907      */
1908     static synchronized Component getMostRecentFocusOwner(Window window) {
1909         WeakReference<Component> weakValue =
1910             (WeakReference)mostRecentFocusOwners.get(window);
1911         return weakValue == null ? null : (Component)weakValue.get();
1912     }
1913 
1914     /**
1915      * This method is called by the AWT event dispatcher requesting that the
1916      * current KeyboardFocusManager dispatch the specified event on its behalf.
1917      * It is expected that all KeyboardFocusManagers will dispatch all
1918      * FocusEvents, all WindowEvents related to focus, and all KeyEvents.
1919      * These events should be dispatched based on the KeyboardFocusManager's
1920      * notion of the focus owner and the focused and active Windows, sometimes
1921      * overriding the source of the specified AWTEvent. Dispatching must be
1922      * done using <code>redispatchEvent</code> to prevent the AWT event
1923      * dispatcher from recursively requesting that the KeyboardFocusManager
1924      * dispatch the event again. If this method returns <code>false</code>,
1925      * then the AWT event dispatcher will attempt to dispatch the event itself.
1926      *
1927      * @param e the AWTEvent to be dispatched
1928      * @return <code>true</code> if this method dispatched the event;
1929      *         <code>false</code> otherwise


2631 
2632         synchronized(heavyweightRequests) {
2633             if (currentLightweightRequests != null) {
2634                 clearingCurrentLightweightRequests = true;
2635                 disableRestoreFocus = true;
2636                 localLightweightRequests = currentLightweightRequests;
2637                 allowSyncFocusRequests = (localLightweightRequests.size() < 2);
2638                 currentLightweightRequests = null;
2639             } else {
2640                 // do nothing
2641                 return;
2642             }
2643         }
2644 
2645         Throwable caughtEx = null;
2646         try {
2647             if (localLightweightRequests != null) {
2648                 Component lastFocusOwner = null;
2649                 Component currentFocusOwner = null;
2650 
2651                 for (Iterator<KeyboardFocusManager.LightweightFocusRequest> iter = localLightweightRequests.iterator(); iter.hasNext(); ) {
2652 
2653                     currentFocusOwner = manager.getGlobalFocusOwner();
2654                     LightweightFocusRequest lwFocusRequest =
2655                         iter.next();
2656 
2657                     /*
2658                      * WARNING: This is based on DKFM's logic solely!
2659                      *
2660                      * We allow to trigger restoreFocus() in the dispatching process
2661                      * only if we have the last request to dispatch. If the last request
2662                      * fails, focus will be restored to either the component of the last
2663                      * previously succedded request, or to to the focus owner that was
2664                      * before this clearing proccess.
2665                      */
2666                     if (!iter.hasNext()) {
2667                         disableRestoreFocus = false;
2668                     }
2669 
2670                     FocusEvent currentFocusOwnerEvent = null;
2671                     /*
2672                      * We're not dispatching FOCUS_LOST while the current focus owner is null.
2673                      * But regardless of whether it's null or not, we're clearing ALL the local
2674                      * lw requests.
2675                      */


2960 
2961     /**
2962      * Clears markers queue
2963      * This method is not intended to be overridden by KFM's.
2964      * Only DefaultKeyboardFocusManager can implement it.
2965      * @since 1.5
2966      */
2967     void clearMarkers() {
2968     }
2969 
2970     static boolean removeFirstRequest() {
2971         KeyboardFocusManager manager =
2972             KeyboardFocusManager.getCurrentKeyboardFocusManager();
2973 
2974         synchronized(heavyweightRequests) {
2975             HeavyweightFocusRequest hwFocusRequest = getFirstHWRequest();
2976 
2977             if (hwFocusRequest != null) {
2978                 heavyweightRequests.removeFirst();
2979                 if (hwFocusRequest.lightweightRequests != null) {
2980                     for (Iterator<KeyboardFocusManager.LightweightFocusRequest> lwIter = hwFocusRequest.lightweightRequests.
2981                              iterator();
2982                          lwIter.hasNext(); )
2983                     {
2984                         manager.dequeueKeyEvents
2985                             (-1, lwIter.next().
2986                              component);
2987                     }
2988                 }
2989             }
2990             // Fix for 4799136 - clear type-ahead markers if requests queue is empty
2991             // We do it here because this method is called only when problems happen
2992             if (heavyweightRequests.size() == 0) {
2993                 manager.clearMarkers();
2994             }
2995             return (heavyweightRequests.size() > 0);
2996         }
2997     }
2998     static void removeLastFocusRequest(Component heavyweight) {
2999         if (log.isLoggable(PlatformLogger.Level.FINE)) {
3000             if (heavyweight == null) {
3001                 log.fine("Assertion (heavyweight != null) failed");
3002             }
3003         }
3004 
3005         KeyboardFocusManager manager =


3045         if (wfrom == null) {
3046             return false;
3047         }
3048         return (wto != wfrom);
3049     }
3050 
3051     static Component getHeavyweight(Component comp) {
3052         if (comp == null || comp.getPeer() == null) {
3053             return null;
3054         } else if (comp.getPeer() instanceof LightweightPeer) {
3055             return comp.getNativeContainer();
3056         } else {
3057             return comp;
3058         }
3059     }
3060 
3061     static Field proxyActive;
3062     // Accessor to private field isProxyActive of KeyEvent
3063     private static boolean isProxyActiveImpl(KeyEvent e) {
3064         if (proxyActive == null) {
3065             proxyActive =  AccessController.doPrivileged(new PrivilegedAction<Field>() {
3066                     public Field run() {
3067                         Field field = null;
3068                         try {
3069                             field = KeyEvent.class.getDeclaredField("isProxyActive");
3070                             if (field != null) {
3071                                 field.setAccessible(true);
3072                             }
3073                         } catch (NoSuchFieldException nsf) {
3074                             assert(false);
3075                         }
3076                         return field;
3077                     }
3078                 });
3079         }
3080 
3081         try {
3082             return proxyActive.getBoolean(e);
3083         } catch (IllegalAccessException iae) {
3084             assert(false);
3085         }
3086         return false;