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;
|