1. /*
  2. * @(#)KeyboardFocusManager.java 1.40 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.awt;
  8. import java.awt.event.FocusEvent;
  9. import java.awt.event.InputEvent;
  10. import java.awt.event.KeyEvent;
  11. import java.awt.event.WindowEvent;
  12. import java.awt.peer.LightweightPeer;
  13. import java.beans.*;
  14. import java.util.Set;
  15. import java.util.HashSet;
  16. import java.util.Collections;
  17. import java.util.Iterator;
  18. import java.util.LinkedList;
  19. import java.util.ListIterator;
  20. import java.util.StringTokenizer;
  21. import java.util.WeakHashMap;
  22. import java.lang.ref.WeakReference;
  23. import sun.awt.AppContext;
  24. import sun.awt.DebugHelper;
  25. import sun.awt.SunToolkit;
  26. /**
  27. * The KeyboardFocusManager is responsible for managing the active and focused
  28. * Windows, and the current focus owner. The focus owner is defined as the
  29. * Component in an application that will typically receive all KeyEvents
  30. * generated by the user. The focused Window is the Window that is, or
  31. * contains, the focus owner. Only a Frame or a Dialog can be the active
  32. * Window. The native windowing system may denote the active Window or its
  33. * children with special decorations, such as a highlighted title bar. The
  34. * active Window is always either the focused Window, or the first Frame or
  35. * Dialog that is an owner of the focused Window.
  36. * <p>
  37. * The KeyboardFocusManager is both a centralized location for client code to
  38. * query for the focus owner and initiate focus changes, and an event
  39. * dispatcher for all FocusEvents, WindowEvents related to focus, and
  40. * KeyEvents.
  41. * <p>
  42. * Some browsers partition applets in different code bases into separate
  43. * contexts, and establish walls between these contexts. In such a scenario,
  44. * there will be one KeyboardFocusManager per context. Other browsers place all
  45. * applets into the same context, implying that there will be only a single,
  46. * global KeyboardFocusManager for all applets. This behavior is
  47. * implementation-dependent. Consult your browser's documentation for more
  48. * information. No matter how many contexts there may be, however, there can
  49. * never be more than one focus owner, focused Window, or active Window, per
  50. * ClassLoader.
  51. *
  52. * @author David Mendenhall
  53. * @version 1.40, 01/23/03
  54. *
  55. * @see Window
  56. * @see Frame
  57. * @see Dialog
  58. * @see java.awt.event.FocusEvent
  59. * @see java.awt.event.WindowEvent
  60. * @see java.awt.event.KeyEvent
  61. * @since 1.4
  62. */
  63. public abstract class KeyboardFocusManager
  64. implements KeyEventDispatcher, KeyEventPostProcessor
  65. {
  66. static {
  67. /* ensure that the necessary native libraries are loaded */
  68. Toolkit.loadLibraries();
  69. if (!GraphicsEnvironment.isHeadless()) {
  70. initIDs();
  71. }
  72. }
  73. /**
  74. * Initialize JNI field and method IDs
  75. */
  76. private static native void initIDs();
  77. private static final DebugHelper dbg =
  78. DebugHelper.create(KeyboardFocusManager.class);
  79. /**
  80. * The identifier for the Forward focus traversal keys.
  81. *
  82. * @see #setDefaultFocusTraversalKeys
  83. * @see #getDefaultFocusTraversalKeys
  84. * @see Component#setFocusTraversalKeys
  85. * @see Component#getFocusTraversalKeys
  86. */
  87. public static final int FORWARD_TRAVERSAL_KEYS = 0;
  88. /**
  89. * The identifier for the Backward focus traversal keys.
  90. *
  91. * @see #setDefaultFocusTraversalKeys
  92. * @see #getDefaultFocusTraversalKeys
  93. * @see Component#setFocusTraversalKeys
  94. * @see Component#getFocusTraversalKeys
  95. */
  96. public static final int BACKWARD_TRAVERSAL_KEYS = 1;
  97. /**
  98. * The identifier for the Up Cycle focus traversal keys.
  99. *
  100. * @see #setDefaultFocusTraversalKeys
  101. * @see #getDefaultFocusTraversalKeys
  102. * @see Component#setFocusTraversalKeys
  103. * @see Component#getFocusTraversalKeys
  104. */
  105. public static final int UP_CYCLE_TRAVERSAL_KEYS = 2;
  106. /**
  107. * The identifier for the Down Cycle focus traversal keys.
  108. *
  109. * @see #setDefaultFocusTraversalKeys
  110. * @see #getDefaultFocusTraversalKeys
  111. * @see Component#setFocusTraversalKeys
  112. * @see Component#getFocusTraversalKeys
  113. */
  114. public static final int DOWN_CYCLE_TRAVERSAL_KEYS = 3;
  115. static final int TRAVERSAL_KEY_LENGTH = DOWN_CYCLE_TRAVERSAL_KEYS + 1;
  116. /**
  117. * Returns the current KeyboardFocusManager instance for the calling
  118. * thread's context.
  119. *
  120. * @return this thread's context's KeyboardFocusManager
  121. * @see #setCurrentKeyboardFocusManager
  122. */
  123. public static KeyboardFocusManager getCurrentKeyboardFocusManager() {
  124. return getCurrentKeyboardFocusManager(AppContext.getAppContext());
  125. }
  126. synchronized static KeyboardFocusManager
  127. getCurrentKeyboardFocusManager(AppContext appcontext)
  128. {
  129. KeyboardFocusManager manager = (KeyboardFocusManager)
  130. appcontext.get(KeyboardFocusManager.class);
  131. if (manager == null) {
  132. manager = new DefaultKeyboardFocusManager();
  133. appcontext.put(KeyboardFocusManager.class, manager);
  134. }
  135. return manager;
  136. }
  137. /**
  138. * Sets the current KeyboardFocusManager instance for the calling thread's
  139. * context. If null is specified, then the current KeyboardFocusManager
  140. * is replaced with a new instance of DefaultKeyboardFocusManager.
  141. * <p>
  142. * If a SecurityManager is installed, the calling thread must be granted
  143. * the AWTPermission "replaceKeyboardFocusManager" in order to replace the
  144. * the current KeyboardFocusManager. If this permission is not granted,
  145. * this method will throw a SecurityException, and the current
  146. * KeyboardFocusManager will be unchanged.
  147. *
  148. * @param newManager the new KeyboardFocusManager for this thread's context
  149. * @see #getCurrentKeyboardFocusManager
  150. * @see DefaultKeyboardFocusManager
  151. * @throws SecurityException if the calling thread does not have permission
  152. * to replace the current KeyboardFocusManager
  153. */
  154. public synchronized static void setCurrentKeyboardFocusManager(
  155. KeyboardFocusManager newManager) throws SecurityException
  156. {
  157. AppContext appcontext = AppContext.getAppContext();
  158. if (newManager != null) {
  159. SecurityManager security = System.getSecurityManager();
  160. if (security != null) {
  161. if (replaceKeyboardFocusManagerPermission == null) {
  162. replaceKeyboardFocusManagerPermission =
  163. new AWTPermission("replaceKeyboardFocusManager");
  164. }
  165. security.
  166. checkPermission(replaceKeyboardFocusManagerPermission);
  167. }
  168. appcontext.put(KeyboardFocusManager.class, newManager);
  169. } else {
  170. appcontext.remove(KeyboardFocusManager.class);
  171. }
  172. }
  173. /**
  174. * The Component in an application that will typically receive all
  175. * KeyEvents generated by the user.
  176. */
  177. private static Component focusOwner;
  178. /**
  179. * The Component in an application that will regain focus when an
  180. * outstanding temporary focus transfer has completed, or the focus owner,
  181. * if no outstanding temporary transfer exists.
  182. */
  183. private static Component permanentFocusOwner;
  184. /**
  185. * The Window which is, or contains, the focus owner.
  186. */
  187. private static Window focusedWindow;
  188. /**
  189. * Only a Frame or a Dialog can be the active Window. The native windowing
  190. * system may denote the active Window with a special decoration, such as a
  191. * highlighted title bar. The active Window is always either the focused
  192. * Window, or the first Frame or Dialog which is an owner of the focused
  193. * Window.
  194. */
  195. private static Window activeWindow;
  196. /**
  197. * The default FocusTraversalPolicy for all Windows that have no policy of
  198. * their own set. If those Windows have focus-cycle-root children that have
  199. * no keyboard-traversal policy of their own, then those children will also
  200. * inherit this policy (as will, recursively, their focus-cycle-root
  201. * children).
  202. */
  203. private FocusTraversalPolicy defaultPolicy =
  204. new DefaultFocusTraversalPolicy();
  205. /**
  206. * The bound property names of each focus traversal key.
  207. */
  208. private static final String[] defaultFocusTraversalKeyPropertyNames = {
  209. "forwardDefaultFocusTraversalKeys",
  210. "backwardDefaultFocusTraversalKeys",
  211. "upCycleDefaultFocusTraversalKeys",
  212. "downCycleDefaultFocusTraversalKeys"
  213. };
  214. /**
  215. * The default Strings for initializing the default focus traversal keys.
  216. * Only used if default traversal keys are not set using Preferences API.
  217. */
  218. private static final String[] defaultFocusTraversalKeyStrings = {
  219. "TAB,ctrl TAB", "shift TAB,ctrl shift TAB", "", ""
  220. };
  221. /**
  222. * The default focus traversal keys. Each array of traversal keys will be
  223. * in effect on all Windows that have no such array of their own explicitly
  224. * set. Each array will also be inherited, recursively, by any child
  225. * Component of those Windows that has no such array of its own explicitly
  226. * set.
  227. */
  228. private Set[] defaultFocusTraversalKeys = new Set[4];
  229. /**
  230. * The current focus cycle root. If the focus owner is itself a focus cycle
  231. * root, then it may be ambiguous as to which Components represent the next
  232. * and previous Components to focus during normal focus traversal. In that
  233. * case, the current focus cycle root is used to differentiate among the
  234. * possibilities.
  235. */
  236. private static Container currentFocusCycleRoot;
  237. /**
  238. * A description of any VetoableChangeListeners which have been registered.
  239. */
  240. private VetoableChangeSupport vetoableSupport;
  241. /**
  242. * A description of any PropertyChangeListeners which have been registered.
  243. */
  244. private PropertyChangeSupport changeSupport;
  245. /**
  246. * This KeyboardFocusManager's KeyEventDispatcher chain. The List does not
  247. * include this KeyboardFocusManager unless it was explicitly re-registered
  248. * via a call to <code>addKeyEventDispatcher</code>. If no other
  249. * KeyEventDispatchers are registered, this field may be null or refer to
  250. * a List of length 0.
  251. */
  252. private java.util.LinkedList keyEventDispatchers;
  253. /**
  254. * This KeyboardFocusManager's KeyEventPostProcessor chain. The List does
  255. * not include this KeyboardFocusManager unless it was explicitly
  256. * re-registered via a call to <code>addKeyEventPostProcessor</code>.
  257. * If no other KeyEventPostProcessors are registered, this field may be
  258. * null or refer to a List of length 0.
  259. */
  260. private java.util.LinkedList keyEventPostProcessors;
  261. /**
  262. * Maps Windows to those Windows' most recent focus owners.
  263. */
  264. private static java.util.Map mostRecentFocusOwners = new WeakHashMap();
  265. /**
  266. * Error String for initializing SecurityExceptions.
  267. */
  268. private static final String notPrivileged = "this KeyboardFocusManager is not installed in the current thread's context";
  269. /**
  270. * We cache the permission used to verify that the calling thread is
  271. * permitted to access the global focus state.
  272. */
  273. private static AWTPermission replaceKeyboardFocusManagerPermission;
  274. /*
  275. * SequencedEvent which is currently dispatched in AppContext.
  276. */
  277. transient SequencedEvent currentSequencedEvent = null;
  278. final void setCurrentSequencedEvent(SequencedEvent current) {
  279. synchronized (SequencedEvent.class) {
  280. assert(current == null || currentSequencedEvent == null);
  281. currentSequencedEvent = current;
  282. }
  283. }
  284. final SequencedEvent getCurrentSequencedEvent() {
  285. synchronized (SequencedEvent.class) {
  286. return currentSequencedEvent;
  287. }
  288. }
  289. static Set initFocusTraversalKeysSet(String value, Set targetSet) {
  290. StringTokenizer tokens = new StringTokenizer(value, ",");
  291. while (tokens.hasMoreTokens()) {
  292. targetSet.add(AWTKeyStroke.getAWTKeyStroke(tokens.nextToken()));
  293. }
  294. return (targetSet.isEmpty())
  295. ? Collections.EMPTY_SET
  296. : Collections.unmodifiableSet(targetSet);
  297. }
  298. /**
  299. * Initializes a KeyboardFocusManager.
  300. */
  301. public KeyboardFocusManager() {
  302. for (int i = 0; i < TRAVERSAL_KEY_LENGTH; i++) {
  303. defaultFocusTraversalKeys[i] = initFocusTraversalKeysSet(
  304. defaultFocusTraversalKeyStrings[i], new HashSet());
  305. }
  306. }
  307. /**
  308. * Returns the focus owner, if the focus owner is in the same context as
  309. * the calling thread. The focus owner is defined as the Component in an
  310. * application that will typically receive all KeyEvents generated by the
  311. * user. KeyEvents which map to the focus owner's focus traversal keys will
  312. * not be delivered if focus traversal keys are enabled for the focus
  313. * owner. In addition, KeyEventDispatchers may retarget or consume
  314. * KeyEvents before they reach the focus owner.
  315. *
  316. * @return the focus owner, or null if the focus owner is not a member of
  317. * the calling thread's context
  318. * @see #getGlobalFocusOwner
  319. * @see #setGlobalFocusOwner
  320. */
  321. public Component getFocusOwner() {
  322. synchronized (KeyboardFocusManager.class) {
  323. if (focusOwner == null) {
  324. return null;
  325. }
  326. return (focusOwner.appContext == AppContext.getAppContext())
  327. ? focusOwner
  328. : null;
  329. }
  330. }
  331. /**
  332. * Returns the focus owner, even if the calling thread is in a different
  333. * context than the focus owner. The focus owner is defined as the
  334. * Component in an application that will typically receive all KeyEvents
  335. * generated by the user. KeyEvents which map to the focus owner's focus
  336. * traversal keys will not be delivered if focus traversal keys are enabled
  337. * for the focus owner. In addition, KeyEventDispatchers may retarget or
  338. * consume KeyEvents before they reach the focus owner.
  339. * <p>
  340. * This method will throw a SecurityException if this KeyboardFocusManager
  341. * is not the current KeyboardFocusManager for the calling thread's
  342. * context.
  343. *
  344. * @return the focus owner
  345. * @see #getFocusOwner
  346. * @see #setGlobalFocusOwner
  347. * @throws SecurityException if this KeyboardFocusManager is not the
  348. * current KeyboardFocusManager for the calling thread's context
  349. */
  350. protected Component getGlobalFocusOwner() throws SecurityException {
  351. synchronized (KeyboardFocusManager.class) {
  352. if (this == getCurrentKeyboardFocusManager()) {
  353. return focusOwner;
  354. } else {
  355. throw new SecurityException(notPrivileged);
  356. }
  357. }
  358. }
  359. /**
  360. * Sets the focus owner. The operation will be cancelled if the Component
  361. * is not focusable. The focus owner is defined as the Component in an
  362. * application that will typically receive all KeyEvents generated by the
  363. * user. KeyEvents which map to the focus owner's focus traversal keys will
  364. * not be delivered if focus traversal keys are enabled for the focus
  365. * owner. In addition, KeyEventDispatchers may retarget or consume
  366. * KeyEvents before they reach the focus owner.
  367. * <p>
  368. * This method does not actually set the focus to the specified Component.
  369. * It merely stores the value to be subsequently returned by
  370. * <code>getFocusOwner()</code>. Use <code>Component.requestFocus()</code>
  371. * or <code>Component.requestFocusInWindow()</code> to change the focus
  372. * owner, subject to platform limitations.
  373. *
  374. * @param focusOwner the focus owner
  375. * @see #getFocusOwner
  376. * @see #getGlobalFocusOwner
  377. * @see Component#requestFocus()
  378. * @see Component#requestFocusInWindow()
  379. * @see Component#isFocusable
  380. * @beaninfo
  381. * bound: true
  382. */
  383. protected void setGlobalFocusOwner(Component focusOwner) {
  384. Component oldFocusOwner = null;
  385. boolean shouldFire = false;
  386. if (focusOwner == null || focusOwner.isFocusable()) {
  387. synchronized (KeyboardFocusManager.class) {
  388. oldFocusOwner = getFocusOwner();
  389. try {
  390. fireVetoableChange("focusOwner", oldFocusOwner,
  391. focusOwner);
  392. } catch (PropertyVetoException e) {
  393. // rejected
  394. return;
  395. }
  396. KeyboardFocusManager.focusOwner = focusOwner;
  397. if (focusOwner != null &&
  398. (getCurrentFocusCycleRoot() == null ||
  399. !focusOwner.isFocusCycleRoot(getCurrentFocusCycleRoot())))
  400. {
  401. Container rootAncestor =
  402. focusOwner.getFocusCycleRootAncestor();
  403. if (rootAncestor == null && (focusOwner instanceof Window))
  404. {
  405. rootAncestor = (Container)focusOwner;
  406. }
  407. if (rootAncestor != null) {
  408. setGlobalCurrentFocusCycleRoot(rootAncestor);
  409. }
  410. }
  411. shouldFire = true;
  412. }
  413. }
  414. if (shouldFire) {
  415. firePropertyChange("focusOwner", oldFocusOwner, focusOwner);
  416. }
  417. }
  418. /**
  419. * Clears the global focus owner at both the Java and native levels. If
  420. * there exists a focus owner, that Component will receive a permanent
  421. * FOCUS_LOST event. After this operation completes, the native windowing
  422. * system will discard all user-generated KeyEvents until the user selects
  423. * a new Component to receive focus, or a Component is given focus
  424. * explicitly via a call to <code>requestFocus()</code>. This operation
  425. * does not change the focused or active Windows.
  426. *
  427. * @see Component#requestFocus()
  428. * @see java.awt.event.FocusEvent#FOCUS_LOST
  429. */
  430. public void clearGlobalFocusOwner() {
  431. if (!GraphicsEnvironment.isHeadless()) {
  432. // Toolkit must be fully initialized, otherwise
  433. // _clearGlobalFocusOwner will crash or throw an exception
  434. Toolkit.getDefaultToolkit();
  435. _clearGlobalFocusOwner();
  436. }
  437. }
  438. private native void _clearGlobalFocusOwner();
  439. static native Component getNativeFocusOwner();
  440. static native Window getNativeFocusedWindow();
  441. /**
  442. * Returns the permanent focus owner, if the permanent focus owner is in
  443. * the same context as the calling thread. The permanent focus owner is
  444. * defined as the last Component in an application to receive a permanent
  445. * FOCUS_GAINED event. The focus owner and permanent focus owner are
  446. * equivalent unless a temporary focus change is currently in effect. In
  447. * such a situation, the permanent focus owner will again be the focus
  448. * owner when the temporary focus change ends.
  449. *
  450. * @return the permanent focus owner, or null if the permanent focus owner
  451. * is not a member of the calling thread's context
  452. * @see #getGlobalPermanentFocusOwner
  453. * @see #setGlobalPermanentFocusOwner
  454. */
  455. public Component getPermanentFocusOwner() {
  456. synchronized (KeyboardFocusManager.class) {
  457. if (permanentFocusOwner == null) {
  458. return null;
  459. }
  460. return (permanentFocusOwner.appContext ==
  461. AppContext.getAppContext())
  462. ? permanentFocusOwner
  463. : null;
  464. }
  465. }
  466. /**
  467. * Returns the permanent focus owner, even if the calling thread is in a
  468. * different context than the permanent focus owner. The permanent focus
  469. * owner is defined as the last Component in an application to receive a
  470. * permanent FOCUS_GAINED event. The focus owner and permanent focus owner
  471. * are equivalent unless a temporary focus change is currently in effect.
  472. * In such a situation, the permanent focus owner will again be the focus
  473. * owner when the temporary focus change ends.
  474. * <p>
  475. * This method will throw a SecurityException if this KeyboardFocusManager
  476. * is not the current KeyboardFocusManager for the calling thread's
  477. * context.
  478. *
  479. * @return the permanent focus owner
  480. * @see #getPermanentFocusOwner
  481. * @see #setGlobalPermanentFocusOwner
  482. * @throws SecurityException if this KeyboardFocusManager is not the
  483. * current KeyboardFocusManager for the calling thread's context
  484. */
  485. protected Component getGlobalPermanentFocusOwner()
  486. throws SecurityException
  487. {
  488. synchronized (KeyboardFocusManager.class) {
  489. if (this == getCurrentKeyboardFocusManager()) {
  490. return permanentFocusOwner;
  491. } else {
  492. throw new SecurityException(notPrivileged);
  493. }
  494. }
  495. }
  496. /**
  497. * Sets the permanent focus owner. The operation will be cancelled if the
  498. * Component is not focusable. The permanent focus owner is defined as the
  499. * last Component in an application to receive a permanent FOCUS_GAINED
  500. * event. The focus owner and permanent focus owner are equivalent unless
  501. * a temporary focus change is currently in effect. In such a situation,
  502. * the permanent focus owner will again be the focus owner when the
  503. * temporary focus change ends.
  504. * <p>
  505. * This method does not actually set the focus to the specified Component.
  506. * It merely stores the value to be subsequently returned by
  507. * <code>getPermanentFocusOwner()</code>. Use
  508. * <code>Component.requestFocus()</code> or
  509. * <code>Component.requestFocusInWindow()</code> to change the focus owner,
  510. * subject to platform limitations.
  511. *
  512. * @param permanentFocusOwner the permanent focus owner
  513. * @see #getPermanentFocusOwner
  514. * @see #getGlobalPermanentFocusOwner
  515. * @see Component#requestFocus()
  516. * @see Component#requestFocusInWindow()
  517. * @see Component#isFocusable
  518. * @beaninfo
  519. * bound: true
  520. */
  521. protected void setGlobalPermanentFocusOwner(Component permanentFocusOwner)
  522. {
  523. Component oldPermanentFocusOwner = null;
  524. boolean shouldFire = false;
  525. if (permanentFocusOwner == null || permanentFocusOwner.isFocusable()) {
  526. synchronized (KeyboardFocusManager.class) {
  527. oldPermanentFocusOwner = getPermanentFocusOwner();
  528. try {
  529. fireVetoableChange("permanentFocusOwner",
  530. oldPermanentFocusOwner,
  531. permanentFocusOwner);
  532. } catch (PropertyVetoException e) {
  533. // rejected
  534. return;
  535. }
  536. KeyboardFocusManager.permanentFocusOwner = permanentFocusOwner;
  537. KeyboardFocusManager.
  538. setMostRecentFocusOwner(permanentFocusOwner);
  539. shouldFire = true;
  540. }
  541. }
  542. if (shouldFire) {
  543. firePropertyChange("permanentFocusOwner", oldPermanentFocusOwner,
  544. permanentFocusOwner);
  545. }
  546. }
  547. /**
  548. * Returns the focused Window, if the focused Window is in the same context
  549. * as the calling thread. The focused Window is the Window that is or
  550. * contains the focus owner.
  551. *
  552. * @return the focused Window, or null if the focused Window is not a
  553. * member of the calling thread's context
  554. * @see #getGlobalFocusedWindow
  555. * @see #setGlobalFocusedWindow
  556. */
  557. public Window getFocusedWindow() {
  558. synchronized (KeyboardFocusManager.class) {
  559. if (focusedWindow == null) {
  560. return null;
  561. }
  562. return (focusedWindow.appContext == AppContext.getAppContext())
  563. ? focusedWindow
  564. : null;
  565. }
  566. }
  567. /**
  568. * Returns the focused Window, even if the calling thread is in a different
  569. * context than the focused Window. The focused Window is the Window that
  570. * is or contains the focus owner.
  571. * <p>
  572. * This method will throw a SecurityException if this KeyboardFocusManager
  573. * is not the current KeyboardFocusManager for the calling thread's
  574. * context.
  575. *
  576. * @return the focused Window
  577. * @see #getFocusedWindow
  578. * @see #setGlobalFocusedWindow
  579. * @throws SecurityException if this KeyboardFocusManager is not the
  580. * current KeyboardFocusManager for the calling thread's context
  581. */
  582. protected Window getGlobalFocusedWindow() throws SecurityException {
  583. synchronized (KeyboardFocusManager.class) {
  584. if (this == getCurrentKeyboardFocusManager()) {
  585. return focusedWindow;
  586. } else {
  587. throw new SecurityException(notPrivileged);
  588. }
  589. }
  590. }
  591. /**
  592. * Sets the focused Window. The focused Window is the Window that is or
  593. * contains the focus owner. The operation will be cancelled if the
  594. * specified Window to focus is not a focusable Window.
  595. * <p>
  596. * This method does not actually change the focused Window as far as the
  597. * native windowing system is concerned. It merely stores the value to be
  598. * subsequently returned by <code>getFocusedWindow()</code>. Use
  599. * <code>Component.requestFocus()</code> or
  600. * <code>Component.requestFocusInWindow()</code> to change the focused
  601. * Window, subject to platform limitations.
  602. *
  603. * @param focusedWindow the focused Window
  604. * @see #getFocusedWindow
  605. * @see #getGlobalFocusedWindow
  606. * @see Component#requestFocus()
  607. * @see Component#requestFocusInWindow()
  608. * @see Window#isFocusableWindow
  609. * @beaninfo
  610. * bound: true
  611. */
  612. protected void setGlobalFocusedWindow(Window focusedWindow) {
  613. Window oldFocusedWindow = null;
  614. boolean shouldFire = false;
  615. if (focusedWindow == null || focusedWindow.isFocusableWindow()) {
  616. synchronized (KeyboardFocusManager.class) {
  617. oldFocusedWindow = getFocusedWindow();
  618. try {
  619. fireVetoableChange("focusedWindow", oldFocusedWindow,
  620. focusedWindow);
  621. } catch (PropertyVetoException e) {
  622. // rejected
  623. return;
  624. }
  625. KeyboardFocusManager.focusedWindow = focusedWindow;
  626. shouldFire = true;
  627. }
  628. }
  629. if (shouldFire) {
  630. firePropertyChange("focusedWindow", oldFocusedWindow,
  631. focusedWindow);
  632. }
  633. }
  634. /**
  635. * Returns the active Window, if the active Window is in the same context
  636. * as the calling thread. Only a Frame or a Dialog can be the active
  637. * Window. The native windowing system may denote the active Window or its
  638. * children with special decorations, such as a highlighted title bar.
  639. * The active Window is always either the focused Window, or the first
  640. * Frame or Dialog that is an owner of the focused Window.
  641. *
  642. * @return the active Window, or null if the active Window is not a member
  643. * of the calling thread's context
  644. * @see #getGlobalActiveWindow
  645. * @see #setGlobalActiveWindow
  646. */
  647. public Window getActiveWindow() {
  648. synchronized (KeyboardFocusManager.class) {
  649. if (activeWindow == null) {
  650. return null;
  651. }
  652. return (activeWindow.appContext == AppContext.getAppContext())
  653. ? activeWindow
  654. : null;
  655. }
  656. }
  657. /**
  658. * Returns the active Window, even if the calling thread is in a different
  659. * context than the active Window. Only a Frame or a Dialog can be the
  660. * active Window. The native windowing system may denote the active Window
  661. * or its children with special decorations, such as a highlighted title
  662. * bar. The active Window is always either the focused Window, or the first
  663. * Frame or Dialog that is an owner of the focused Window.
  664. * <p>
  665. * This method will throw a SecurityException if this KeyboardFocusManager
  666. * is not the current KeyboardFocusManager for the calling thread's
  667. * context.
  668. *
  669. * @return the active Window
  670. * @see #getActiveWindow
  671. * @see #setGlobalActiveWindow
  672. * @throws SecurityException if this KeyboardFocusManager is not the
  673. * current KeyboardFocusManager for the calling thread's context
  674. */
  675. protected Window getGlobalActiveWindow() throws SecurityException {
  676. synchronized (KeyboardFocusManager.class) {
  677. if (this == getCurrentKeyboardFocusManager()) {
  678. return activeWindow;
  679. } else {
  680. throw new SecurityException(notPrivileged);
  681. }
  682. }
  683. }
  684. /**
  685. * Sets the active Window. Only a Frame or a Dialog can be the active
  686. * Window. The native windowing system may denote the active Window or its
  687. * children with special decorations, such as a highlighted title bar. The
  688. * active Window is always either the focused Window, or the first Frame or
  689. * Dialog that is an owner of the focused Window.
  690. * <p>
  691. * This method does not actually change the active Window as far as the
  692. * native windowing system is concerned. It merely stores the value to be
  693. * subsequently returned by <code>getActiveWindow()</code>. Use
  694. * <code>Component.requestFocus()</code> or
  695. * <code>Component.requestFocusInWindow()</code>to change the active
  696. * Window, subject to platform limitations.
  697. *
  698. * @param activeWindow the active Window
  699. * @see #getActiveWindow
  700. * @see #getGlobalActiveWindow
  701. * @see Component#requestFocus()
  702. * @see Component#requestFocusInWindow()
  703. * @beaninfo
  704. * bound: true
  705. */
  706. protected void setGlobalActiveWindow(Window activeWindow) {
  707. Window oldActiveWindow;
  708. synchronized (KeyboardFocusManager.class) {
  709. oldActiveWindow = getActiveWindow();
  710. try {
  711. fireVetoableChange("activeWindow", oldActiveWindow,
  712. activeWindow);
  713. } catch (PropertyVetoException e) {
  714. // rejected
  715. return;
  716. }
  717. KeyboardFocusManager.activeWindow = activeWindow;
  718. }
  719. firePropertyChange("activeWindow", oldActiveWindow, activeWindow);
  720. }
  721. /**
  722. * Returns the default FocusTraversalPolicy. Top-level components
  723. * use this value on their creation to initialize their own focus traversal
  724. * policy by explicit call to Container.setFocusTraversalPolicy.
  725. *
  726. * @return the default FocusTraversalPolicy. null will never be returned.
  727. * @see #setDefaultFocusTraversalPolicy
  728. * @see Container#setFocusTraversalPolicy
  729. * @see Container#getFocusTraversalPolicy
  730. */
  731. public synchronized FocusTraversalPolicy getDefaultFocusTraversalPolicy() {
  732. return defaultPolicy;
  733. }
  734. /**
  735. * Sets the default FocusTraversalPolicy. Top-level components
  736. * use this value on their creation to initialize their own focus traversal
  737. * policy by explicit call to Container.setFocusTraversalPolicy.
  738. * Note: this call doesn't affect already created components as they have
  739. * their policy initialized. Only new components will use this policy as
  740. * their default policy.
  741. *
  742. * @param defaultPolicy the new, default FocusTraversalPolicy
  743. * @see #getDefaultFocusTraversalPolicy
  744. * @see Container#setFocusTraversalPolicy
  745. * @see Container#getFocusTraversalPolicy
  746. * @throws IllegalArgumentException if defaultPolicy is null
  747. * @beaninfo
  748. * bound: true
  749. */
  750. public void setDefaultFocusTraversalPolicy(FocusTraversalPolicy
  751. defaultPolicy) {
  752. if (defaultPolicy == null) {
  753. throw new IllegalArgumentException("default focus traversal policy cannot be null");
  754. }
  755. FocusTraversalPolicy oldPolicy;
  756. synchronized (this) {
  757. oldPolicy = this.defaultPolicy;
  758. this.defaultPolicy = defaultPolicy;
  759. }
  760. firePropertyChange("defaultFocusTraversalPolicy", oldPolicy,
  761. defaultPolicy);
  762. }
  763. /**
  764. * Sets the default focus traversal keys for a given traversal operation.
  765. * This traversal key <code>Set</code> will be in effect on all
  766. * <code>Window</code>s that have no such <code>Set</code> of
  767. * their own explicitly defined. This <code>Set</code> will also be
  768. * inherited, recursively, by any child <code>Component</code> of
  769. * those <code>Windows</code> that has
  770. * no such <code>Set</code> of its own explicitly defined.
  771. * <p>
  772. * The default values for the default focus traversal keys are
  773. * implementation-dependent. Sun recommends that all implementations for a
  774. * particular native platform use the same default values. The
  775. * recommendations for Windows and Unix are listed below. These
  776. * recommendations are used in the Sun AWT implementations.
  777. *
  778. * <table border=1 summary="Recommended default values for focus traversal keys">
  779. * <tr>
  780. * <th>Identifier</th>
  781. * <th>Meaning</th>
  782. * <th>Default</th>
  783. * </tr>
  784. * <tr>
  785. * <td><code>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</code></td>
  786. * <td>Normal forward keyboard traversal</td>
  787. * <td><code>TAB</code> on <code>KEY_PRESSED</code>,
  788. * <code>CTRL-TAB</code> on <code>KEY_PRESSED</code></td>
  789. * </tr>
  790. * <tr>
  791. * <td><code>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</code></td>
  792. * <td>Normal reverse keyboard traversal</td>
  793. * <td><code>SHIFT-TAB</code> on <code>KEY_PRESSED</code>,
  794. * <code>CTRL-SHIFT-TAB</code> on <code>KEY_PRESSED</code></td>
  795. * </tr>
  796. * <tr>
  797. * <td><code>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</code></td>
  798. * <td>Go up one focus traversal cycle</td>
  799. * <td>none</td>
  800. * </tr>
  801. * <tr>
  802. * <td><code>KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS</code></td>
  803. * <td>Go down one focus traversal cycle</td>
  804. * <td>none</td>
  805. * </tr>
  806. * </table>
  807. *
  808. * To disable a traversal key, use an empty <code>Set</code>
  809. * <code>Collections.EMPTY_SET</code> is recommended.
  810. * <p>
  811. * Using the <code>AWTKeyStroke</code> API, client code can
  812. * specify on which of two
  813. * specific <code>KeyEvent</code>s, <code>KEY_PRESSED</code> or
  814. * <code>KEY_RELEASED</code>, the focus traversal operation will
  815. * occur. Regardless of which <code>KeyEvent</code> is specified,
  816. * however, all <code>KeyEvent</code>s related to the focus
  817. * traversal key, including the associated <code>KEY_TYPED</code>
  818. * event, will be consumed, and will not be dispatched
  819. * to any <code>Component</code>. It is a runtime error to
  820. * specify a <code>KEY_TYPED</code> event as
  821. * mapping to a focus traversal operation, or to map the same event to
  822. * multiple default focus traversal operations.
  823. *
  824. * @param id one of
  825. * <code>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</code>,
  826. * <code>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</code>,
  827. * <code>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</code>, or
  828. * <code>KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS</code>
  829. * @param keystrokes the Set of <code>AWTKeyStroke</code>s for the
  830. * specified operation
  831. * @see #getDefaultFocusTraversalKeys
  832. * @see Component#setFocusTraversalKeys
  833. * @see Component#getFocusTraversalKeys
  834. * @throws IllegalArgumentException if id is not one of
  835. * <code>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</code>,
  836. * <code>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</code>,
  837. * <code>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</code>, or
  838. * <code>KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS</code>,
  839. * or if keystrokes is <code>null</code>,
  840. * or if keystrokes contains <code>null</code>,
  841. * or if any <code>Object</code> in
  842. * keystrokes is not an <code>AWTKeyStroke</code>,
  843. * or if any keystroke
  844. * represents a <code>KEY_TYPED</code> event,
  845. * or if any keystroke already maps
  846. * to another default focus traversal operation
  847. * @beaninfo
  848. * bound: true
  849. */
  850. public void setDefaultFocusTraversalKeys(int id, Set keystrokes)
  851. {
  852. if (id < 0 || id >= TRAVERSAL_KEY_LENGTH) {
  853. throw new IllegalArgumentException("invalid focus traversal key identifier");
  854. }
  855. if (keystrokes == null) {
  856. throw new IllegalArgumentException("cannot set null Set of default focus traversal keys");
  857. }
  858. Set oldKeys;
  859. synchronized (this) {
  860. for (Iterator iter = keystrokes.iterator(); iter.hasNext(); ) {
  861. Object obj = iter.next();
  862. if (obj == null) {
  863. throw new IllegalArgumentException("cannot set null focus traversal key");
  864. }
  865. // Generates a ClassCastException if the element is not an
  866. // AWTKeyStroke. This is desirable.
  867. AWTKeyStroke keystroke = (AWTKeyStroke)obj;
  868. if (keystroke.getKeyChar() != KeyEvent.CHAR_UNDEFINED) {
  869. throw new IllegalArgumentException("focus traversal keys cannot map to KEY_TYPED events");
  870. }
  871. // Check to see if key already maps to another traversal
  872. // operation
  873. for (int i = 0; i < TRAVERSAL_KEY_LENGTH; i++) {
  874. if (i == id) {
  875. continue;
  876. }
  877. if (defaultFocusTraversalKeys[i].contains(keystroke)) {
  878. throw new IllegalArgumentException("focus traversal keys must be unique for a Component");
  879. }
  880. }
  881. }
  882. oldKeys = defaultFocusTraversalKeys[id];
  883. defaultFocusTraversalKeys[id] =
  884. Collections.unmodifiableSet(new HashSet(keystrokes));
  885. }
  886. firePropertyChange(defaultFocusTraversalKeyPropertyNames[id],
  887. oldKeys, keystrokes);
  888. }
  889. /**
  890. * Returns a Set of default focus traversal keys for a given traversal
  891. * operation. This traversal key Set will be in effect on all Windows that
  892. * have no such Set of their own explicitly defined. This Set will also be
  893. * inherited, recursively, by any child Component of those Windows that has
  894. * no such Set of its own explicitly defined. (See
  895. * <code>setDefaultFocusTraversalKeys</code> for a full description of each
  896. * operation.)
  897. *
  898. * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
  899. * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
  900. * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
  901. * KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
  902. * @return the <code>Set</code> of <code>AWTKeyStroke</code>s
  903. * for the specified operation; the <code>Set</code>
  904. * will be unmodifiable, and may be empty; <code>null</code>
  905. * will never be returned
  906. * @see #setDefaultFocusTraversalKeys
  907. * @see Component#setFocusTraversalKeys
  908. * @see Component#getFocusTraversalKeys
  909. * @throws IllegalArgumentException if id is not one of
  910. * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
  911. * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
  912. * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
  913. * KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
  914. */
  915. public Set getDefaultFocusTraversalKeys(int id) {
  916. if (id < 0 || id >= TRAVERSAL_KEY_LENGTH) {
  917. throw new IllegalArgumentException("invalid focus traversal key identifier");
  918. }
  919. // Okay to return Set directly because it is an unmodifiable view
  920. return defaultFocusTraversalKeys[id];
  921. }
  922. /**
  923. * Returns the current focus cycle root, if the current focus cycle root is
  924. * in the same context as the calling thread. If the focus owner is itself
  925. * a focus cycle root, then it may be ambiguous as to which Components
  926. * represent the next and previous Components to focus during normal focus
  927. * traversal. In that case, the current focus cycle root is used to
  928. * differentiate among the possibilities.
  929. * <p>
  930. * This method is intended to be used only by KeyboardFocusManagers and
  931. * focus implementations. It is not for general client use.
  932. *
  933. * @return the current focus cycle root, or null if the current focus cycle
  934. * root is not a member of the calling thread's context
  935. * @see #getGlobalCurrentFocusCycleRoot
  936. * @see #setGlobalCurrentFocusCycleRoot
  937. */
  938. public Container getCurrentFocusCycleRoot() {
  939. synchronized (KeyboardFocusManager.class) {
  940. if (currentFocusCycleRoot == null) {
  941. return null;
  942. }
  943. return (currentFocusCycleRoot.appContext ==
  944. AppContext.getAppContext())
  945. ? currentFocusCycleRoot
  946. : null;
  947. }
  948. }
  949. /**
  950. * Returns the current focus cycle root, even if the calling thread is in a
  951. * different context than the current focus cycle root. If the focus owner
  952. * is itself a focus cycle root, then it may be ambiguous as to which
  953. * Components represent the next and previous Components to focus during
  954. * normal focus traversal. In that case, the current focus cycle root is
  955. * used to differentiate among the possibilities.
  956. * <p>
  957. * This method will throw a SecurityException if this KeyboardFocusManager
  958. * is not the current KeyboardFocusManager for the calling thread's
  959. * context.
  960. *
  961. * @return the current focus cycle root, or null if the current focus cycle
  962. * root is not a member of the calling thread's context
  963. * @see #getCurrentFocusCycleRoot
  964. * @see #setGlobalCurrentFocusCycleRoot
  965. * @throws SecurityException if this KeyboardFocusManager is not the
  966. * current KeyboardFocusManager for the calling thread's context
  967. */
  968. protected Container getGlobalCurrentFocusCycleRoot()
  969. throws SecurityException
  970. {
  971. synchronized (KeyboardFocusManager.class) {
  972. if (this == getCurrentKeyboardFocusManager()) {
  973. return currentFocusCycleRoot;
  974. } else {
  975. throw new SecurityException(notPrivileged);
  976. }
  977. }
  978. }
  979. /**
  980. * Sets the current focus cycle root. If the focus owner is itself a focus
  981. * cycle root, then it may be ambiguous as to which Components represent
  982. * the next and previous Components to focus during normal focus traversal.
  983. * In that case, the current focus cycle root is used to differentiate
  984. * among the possibilities.
  985. * <p>
  986. * This method is intended to be used only by KeyboardFocusManagers and
  987. * focus implementations. It is not for general client use.
  988. *
  989. * @param newFocusCycleRoot the new focus cycle root
  990. * @see #getCurrentFocusCycleRoot
  991. * @see #getGlobalCurrentFocusCycleRoot
  992. * @beaninfo
  993. * bound: true
  994. */
  995. public void setGlobalCurrentFocusCycleRoot(Container newFocusCycleRoot) {
  996. Container oldFocusCycleRoot;
  997. synchronized (KeyboardFocusManager.class) {
  998. oldFocusCycleRoot = getCurrentFocusCycleRoot();
  999. currentFocusCycleRoot = newFocusCycleRoot;
  1000. }
  1001. firePropertyChange("currentFocusCycleRoot", oldFocusCycleRoot,
  1002. newFocusCycleRoot);
  1003. }
  1004. /**
  1005. * Adds a PropertyChangeListener to the listener list. The listener is
  1006. * registered for all bound properties of this class, including the
  1007. * following:
  1008. * <ul>
  1009. * <li>the focus owner ("focusOwner")</li>
  1010. * <li>the permanent focus owner ("permanentFocusOwner")</li>
  1011. * <li>the focused Window ("focusedWindow")</li>
  1012. * <li>the active Window ("activeWindow")</li>
  1013. * <li>the default focus traversal policy
  1014. * ("defaultFocusTraversalPolicy")</li>
  1015. * <li>the Set of default FORWARD_TRAVERSAL_KEYS
  1016. * ("forwardDefaultFocusTraversalKeys")</li>
  1017. * <li>the Set of default BACKWARD_TRAVERSAL_KEYS
  1018. * ("backwardDefaultFocusTraversalKeys")</li>
  1019. * <li>the Set of default UP_CYCLE_TRAVERSAL_KEYS
  1020. * ("upCycleDefaultFocusTraversalKeys")</li>
  1021. * <li>the Set of default DOWN_CYCLE_TRAVERSAL_KEYS
  1022. * ("downCycleDefaultFocusTraversalKeys")</li>
  1023. * <li>the current focus cycle root ("currentFocusCycleRoot")</li>
  1024. * </ul>
  1025. * If listener is null, no exception is thrown and no action is performed.
  1026. *
  1027. * @param listener the PropertyChangeListener to be added
  1028. * @see #removePropertyChangeListener
  1029. * @see #getPropertyChangeListeners
  1030. * @see #addPropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
  1031. */
  1032. public void addPropertyChangeListener(PropertyChangeListener listener) {
  1033. if (listener != null) {
  1034. synchronized (this) {
  1035. if (changeSupport == null) {
  1036. changeSupport = new PropertyChangeSupport(this);
  1037. }
  1038. changeSupport.addPropertyChangeListener(listener);
  1039. }
  1040. }
  1041. }
  1042. /**
  1043. * Removes a PropertyChangeListener from the listener list. This method
  1044. * should be used to remove the PropertyChangeListeners that were
  1045. * registered for all bound properties of this class.
  1046. * <p>
  1047. * If listener is null, no exception is thrown and no action is performed.
  1048. *
  1049. * @param listener the PropertyChangeListener to be removed
  1050. * @see #addPropertyChangeListener
  1051. * @see #getPropertyChangeListeners
  1052. * @see #removePropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
  1053. */
  1054. public void removePropertyChangeListener(PropertyChangeListener listener) {
  1055. if (listener != null) {
  1056. synchronized (this) {
  1057. if (changeSupport != null) {
  1058. changeSupport.removePropertyChangeListener(listener);
  1059. }
  1060. }
  1061. }
  1062. }
  1063. /**
  1064. * Returns an array of all the property change listeners
  1065. * registered on this keyboard focus manager.
  1066. *
  1067. * @return all of this keyboard focus manager's
  1068. * <code>PropertyChangeListener</code>s
  1069. * or an empty array if no property change
  1070. * listeners are currently registered
  1071. *
  1072. * @see #addPropertyChangeListener
  1073. * @see #removePropertyChangeListener
  1074. * @see #getPropertyChangeListeners(java.lang.String)
  1075. * @since 1.4
  1076. */
  1077. public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
  1078. if (changeSupport == null) {
  1079. changeSupport = new PropertyChangeSupport(this);
  1080. }
  1081. return changeSupport.getPropertyChangeListeners();
  1082. }
  1083. /**
  1084. * Adds a PropertyChangeListener to the listener list for a specific
  1085. * property. The specified property may be user-defined, or one of the
  1086. * following:
  1087. * <ul>
  1088. * <li>the focus owner ("focusOwner")</li>
  1089. * <li>the permanent focus owner ("permanentFocusOwner")</li>
  1090. * <li>the focused Window ("focusedWindow")</li>
  1091. * <li>the active Window ("activeWindow")</li>
  1092. * <li>the default focus traversal policy
  1093. * ("defaultFocusTraversalPolicy")</li>
  1094. * <li>the Set of default FORWARD_TRAVERSAL_KEYS
  1095. * ("forwardDefaultFocusTraversalKeys")</li>
  1096. * <li>the Set of default BACKWARD_TRAVERSAL_KEYS
  1097. * ("backwardDefaultFocusTraversalKeys")</li>
  1098. * <li>the Set of default UP_CYCLE_TRAVERSAL_KEYS
  1099. * ("upCycleDefaultFocusTraversalKeys")</li>
  1100. * <li>the Set of default DOWN_CYCLE_TRAVERSAL_KEYS
  1101. * ("downCycleDefaultFocusTraversalKeys")</li>
  1102. * <li>the current focus cycle root ("currentFocusCycleRoot")</li>
  1103. * </ul>
  1104. * If listener is null, no exception is thrown and no action is performed.
  1105. *
  1106. * @param propertyName one of the property names listed above
  1107. * @param listener the PropertyChangeListener to be added
  1108. * @see #addPropertyChangeListener(java.beans.PropertyChangeListener)
  1109. * @see #removePropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
  1110. * @see #getPropertyChangeListeners(java.lang.String)
  1111. */
  1112. public void addPropertyChangeListener(String propertyName,
  1113. PropertyChangeListener listener) {
  1114. if (listener != null) {
  1115. synchronized (this) {
  1116. if (changeSupport == null) {
  1117. changeSupport = new PropertyChangeSupport(this);
  1118. }
  1119. changeSupport.addPropertyChangeListener(propertyName,
  1120. listener);
  1121. }
  1122. }
  1123. }
  1124. /**
  1125. * Removes a PropertyChangeListener from the listener list for a specific
  1126. * property. This method should be used to remove PropertyChangeListeners
  1127. * that were registered for a specific bound property.
  1128. * <p>
  1129. * If listener is null, no exception is thrown and no action is performed.
  1130. *
  1131. * @param propertyName a valid property name
  1132. * @param listener the PropertyChangeListener to be removed
  1133. * @see #addPropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
  1134. * @see #getPropertyChangeListeners(java.lang.String)
  1135. * @see #removePropertyChangeListener(java.beans.PropertyChangeListener)
  1136. */
  1137. public void removePropertyChangeListener(String propertyName,
  1138. PropertyChangeListener listener) {
  1139. if (listener != null) {
  1140. synchronized (this) {
  1141. if (changeSupport != null) {
  1142. changeSupport.removePropertyChangeListener(propertyName,
  1143. listener);
  1144. }
  1145. }
  1146. }
  1147. }
  1148. /**
  1149. * Returns an array of all the <code>PropertyChangeListener</code>s
  1150. * associated with the named property.
  1151. *
  1152. * @return all of the <code>PropertyChangeListener</code>s associated with
  1153. * the named property or an empty array if no such listeners have
  1154. * been added.
  1155. *
  1156. * @see #addPropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
  1157. * @see #removePropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
  1158. * @since 1.4
  1159. */
  1160. public synchronized PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
  1161. if (changeSupport == null) {
  1162. changeSupport = new PropertyChangeSupport(this);
  1163. }
  1164. return changeSupport.getPropertyChangeListeners(propertyName);
  1165. }
  1166. /**
  1167. * Fires a PropertyChangeEvent in response to a change in a bound property.
  1168. * The event will be delivered to all registered PropertyChangeListeners.
  1169. * No event will be delivered if oldValue and newValue are the same.
  1170. *
  1171. * @param propertyName the name of the property that has changed
  1172. * @param oldValue the property's previous value
  1173. * @param newValue the property's new value
  1174. */
  1175. protected void firePropertyChange(String propertyName, Object oldValue,
  1176. Object newValue) {
  1177. PropertyChangeSupport changeSupport = this.changeSupport;
  1178. if (changeSupport != null) {
  1179. changeSupport.firePropertyChange(propertyName, oldValue, newValue);
  1180. }
  1181. }
  1182. /**
  1183. * Adds a VetoableChangeListener to the listener list. The listener is
  1184. * registered for all vetoable properties of this class, including the
  1185. * following:
  1186. * <ul>
  1187. * <li>the focus owner ("focusOwner")</li>
  1188. * <li>the permanent focus owner ("permanentFocusOwner")</li>
  1189. * <li>the focused Window ("focusedWindow")</li>
  1190. * <li>the active Window ("activeWindow")</li>
  1191. * </ul>
  1192. * If listener is null, no exception is thrown and no action is performed.
  1193. *
  1194. * @param listener the VetoableChangeListener to be added
  1195. * @see #removeVetoableChangeListener
  1196. * @see #getVetoableChangeListeners
  1197. * @see #addVetoableChangeListener(java.lang.String,java.beans.VetoableChangeListener)
  1198. */
  1199. public void addVetoableChangeListener(VetoableChangeListener listener) {
  1200. if (listener != null) {
  1201. synchronized (this) {
  1202. if (vetoableSupport == null) {
  1203. vetoableSupport =
  1204. new VetoableChangeSupport(this);
  1205. }
  1206. vetoableSupport.addVetoableChangeListener(listener);
  1207. }
  1208. }
  1209. }
  1210. /**
  1211. * Removes a VetoableChangeListener from the listener list. This method
  1212. * should be used to remove the VetoableChangeListeners that were
  1213. * registered for all vetoable properties of this class.
  1214. * <p>
  1215. * If listener is null, no exception is thrown and no action is performed.
  1216. *
  1217. * @param listener the VetoableChangeListener to be removed
  1218. * @see #addVetoableChangeListener
  1219. * @see #getVetoableChangeListeners
  1220. * @see #removeVetoableChangeListener(java.lang.String,java.beans.VetoableChangeListener)
  1221. */
  1222. public void removeVetoableChangeListener(VetoableChangeListener listener) {
  1223. if (listener != null) {
  1224. synchronized (this) {
  1225. if (vetoableSupport != null) {
  1226. vetoableSupport.removeVetoableChangeListener(listener);
  1227. }
  1228. }
  1229. }
  1230. }
  1231. /**
  1232. * Returns an array of all the vetoable change listeners
  1233. * registered on this keyboard focus manager.
  1234. *
  1235. * @return all of this keyboard focus manager's
  1236. * <code>VetoableChangeListener</code>s
  1237. * or an empty array if no vetoable change
  1238. * listeners are currently registered
  1239. *
  1240. * @see #addVetoableChangeListener
  1241. * @see #removeVetoableChangeListener
  1242. * @see #getVetoableChangeListeners(java.lang.String)
  1243. * @since 1.4
  1244. */
  1245. public synchronized VetoableChangeListener[] getVetoableChangeListeners() {
  1246. if (vetoableSupport == null) {
  1247. vetoableSupport = new VetoableChangeSupport(this);
  1248. }
  1249. return vetoableSupport.getVetoableChangeListeners();
  1250. }
  1251. /**
  1252. * Adds a VetoableChangeListener to the listener list for a specific
  1253. * property. The specified property may be user-defined, or one of the
  1254. * following:
  1255. * <ul>
  1256. * <li>the focus owner ("focusOwner")</li>
  1257. * <li>the permanent focus owner ("permanentFocusOwner")</li>
  1258. * <li>the focused Window ("focusedWindow")</li>
  1259. * <li>the active Window ("activeWindow")</li>
  1260. * </ul>
  1261. * If listener is null, no exception is thrown and no action is performed.
  1262. *
  1263. * @param propertyName one of the property names listed above
  1264. * @param listener the VetoableChangeListener to be added
  1265. * @see #addVetoableChangeListener(java.beans.VetoableChangeListener)
  1266. * @see #removeVetoableChangeListener
  1267. * @see #getVetoableChangeListeners
  1268. */
  1269. public void addVetoableChangeListener(String propertyName,
  1270. VetoableChangeListener listener) {
  1271. if (listener != null) {
  1272. synchronized (this) {
  1273. if (vetoableSupport == null) {
  1274. vetoableSupport =
  1275. new VetoableChangeSupport(this);
  1276. }
  1277. vetoableSupport.addVetoableChangeListener(propertyName,
  1278. listener);
  1279. }
  1280. }
  1281. }
  1282. /**
  1283. * Removes a VetoableChangeListener from the listener list for a specific
  1284. * property. This method should be used to remove VetoableChangeListeners
  1285. * that were registered for a specific bound property.
  1286. * <p>
  1287. * If listener is null, no exception is thrown and no action is performed.
  1288. *
  1289. * @param propertyName a valid property name
  1290. * @param listener the VetoableChangeListener to be removed
  1291. * @see #addVetoableChangeListener
  1292. * @see #getVetoableChangeListeners
  1293. * @see #removeVetoableChangeListener(java.beans.VetoableChangeListener)
  1294. */
  1295. public void removeVetoableChangeListener(String propertyName,
  1296. VetoableChangeListener listener) {
  1297. if (listener != null) {
  1298. synchronized (this) {
  1299. if (vetoableSupport != null) {
  1300. vetoableSupport.removeVetoableChangeListener(propertyName,
  1301. listener);
  1302. }
  1303. }
  1304. }
  1305. }
  1306. /**
  1307. * Returns an array of all the <code>VetoableChangeListener</code>s
  1308. * associated with the named property.
  1309. *
  1310. * @return all of the <code>VetoableChangeListener</code>s associated with
  1311. * the named property or an empty array if no such listeners have
  1312. * been added.
  1313. *
  1314. * @see #addVetoableChangeListener(java.lang.String,java.beans.VetoableChangeListener)
  1315. * @see #removeVetoableChangeListener(java.lang.String,java.beans.VetoableChangeListener)
  1316. * @see #getVetoableChangeListeners
  1317. * @since 1.4
  1318. */
  1319. public synchronized VetoableChangeListener[] getVetoableChangeListeners(String propertyName) {
  1320. if (vetoableSupport == null) {
  1321. vetoableSupport = new VetoableChangeSupport(this);
  1322. }
  1323. return vetoableSupport.getVetoableChangeListeners(propertyName);
  1324. }
  1325. /**
  1326. * Fires a PropertyChangeEvent in response to a change in a vetoable
  1327. * property. The event will be delivered to all registered
  1328. * VetoableChangeListeners. If a VetoableChangeListener throws a
  1329. * PropertyVetoException, a new event is fired reverting all
  1330. * VetoableChangeListeners to the old value and the exception is then
  1331. * rethrown. No event will be delivered if oldValue and newValue are the
  1332. * same.
  1333. *
  1334. * @param propertyName the name of the property that has changed
  1335. * @param oldValue the property's previous value
  1336. * @param newValue the property's new value
  1337. * @throws java.beans.PropertyVetoException if a
  1338. * <code>VetoableChangeListener</code> threw
  1339. * <code>PropertyVetoException</code>
  1340. */
  1341. protected void fireVetoableChange(String propertyName, Object oldValue,
  1342. Object newValue)
  1343. throws PropertyVetoException
  1344. {
  1345. VetoableChangeSupport vetoableSupport =
  1346. this.vetoableSupport;
  1347. if (vetoableSupport != null) {
  1348. vetoableSupport.fireVetoableChange(propertyName, oldValue,
  1349. newValue);
  1350. }
  1351. }
  1352. /**
  1353. * Adds a KeyEventDispatcher to this KeyboardFocusManager's dispatcher
  1354. * chain. This KeyboardFocusManager will request that each
  1355. * KeyEventDispatcher dispatch KeyEvents generated by the user before
  1356. * finally dispatching the KeyEvent itself. KeyEventDispatchers will be
  1357. * notified in the order in which they were added. Notifications will halt
  1358. * as soon as one KeyEventDispatcher returns <code>true</code> from its
  1359. * <code>dispatchKeyEvent</code> method. There is no limit to the total
  1360. * number of KeyEventDispatchers which can be added, nor to the number of
  1361. * times which a particular KeyEventDispatcher instance can be added.
  1362. * <p>
  1363. * If a null dispatcher is specified, no action is taken and no exception
  1364. * is thrown.
  1365. *
  1366. * @param dispatcher the KeyEventDispatcher to add to the dispatcher chain
  1367. * @see #removeKeyEventDispatcher
  1368. */
  1369. public void addKeyEventDispatcher(KeyEventDispatcher dispatcher) {
  1370. if (dispatcher != null) {
  1371. synchronized (this) {
  1372. if (keyEventDispatchers == null) {
  1373. keyEventDispatchers = new java.util.LinkedList();
  1374. }
  1375. keyEventDispatchers.add(dispatcher);
  1376. }
  1377. }
  1378. }
  1379. /**
  1380. * Removes a KeyEventDispatcher which was previously added to this
  1381. * KeyboardFocusManager's dispatcher chain. This KeyboardFocusManager
  1382. * cannot itself be removed, unless it was explicitly re-registered via a
  1383. * call to <code>addKeyEventDispatcher</code>.
  1384. * <p>
  1385. * If a null dispatcher is specified, if the specified dispatcher is not
  1386. * in the dispatcher chain, or if this KeyboardFocusManager is specified
  1387. * without having been explicitly re-registered, no action is taken and no
  1388. * exception is thrown.
  1389. *
  1390. * @param dispatcher the KeyEventDispatcher to remove from the dispatcher
  1391. * chain
  1392. * @see #addKeyEventDispatcher
  1393. */
  1394. public void removeKeyEventDispatcher(KeyEventDispatcher dispatcher) {
  1395. if (dispatcher != null) {
  1396. synchronized (this) {
  1397. if (keyEventDispatchers != null) {
  1398. keyEventDispatchers.remove(dispatcher);
  1399. }
  1400. }
  1401. }
  1402. }
  1403. /**
  1404. * Returns this KeyboardFocusManager's KeyEventDispatcher chain as a List.
  1405. * The List will not include this KeyboardFocusManager unless it was
  1406. * explicitly re-registered via a call to
  1407. * <code>addKeyEventDispatcher</code>. If no other KeyEventDispatchers are
  1408. * registered, implementations are free to return null or a List of length
  1409. * 0. Client code should not assume one behavior over another, nor should
  1410. * it assume that the behavior, once established, will not change.
  1411. *
  1412. * @return a possibly null or empty List of KeyEventDispatchers
  1413. * @see #addKeyEventDispatcher
  1414. * @see #removeKeyEventDispatcher
  1415. */
  1416. protected synchronized java.util.List getKeyEventDispatchers() {
  1417. return (keyEventDispatchers != null)
  1418. ? (java.util.List)keyEventDispatchers.clone()
  1419. : null;
  1420. }
  1421. /**
  1422. * Adds a KeyEventPostProcessor to this KeyboardFocusManager's post-
  1423. * processor chain. After a KeyEvent has been dispatched to and handled by
  1424. * its target, KeyboardFocusManager will request that each
  1425. * KeyEventPostProcessor perform any necessary post-processing as part
  1426. * of the KeyEvent's final resolution. KeyEventPostProcessors
  1427. * will be notified in the order in which they were added; the current
  1428. * KeyboardFocusManager will be notified last. Notifications will halt
  1429. * as soon as one KeyEventPostProcessor returns <code>true</code> from its
  1430. * <code>postProcessKeyEvent</code> method. There is no limit to the the
  1431. * total number of KeyEventPostProcessors that can be added, nor to the
  1432. * number of times that a particular KeyEventPostProcessor instance can be
  1433. * added.
  1434. * <p>
  1435. * If a null post-processor is specified, no action is taken and no
  1436. * exception is thrown.
  1437. *
  1438. * @param processor the KeyEventPostProcessor to add to the post-processor
  1439. * chain
  1440. * @see #removeKeyEventPostProcessor
  1441. */
  1442. public void addKeyEventPostProcessor(KeyEventPostProcessor processor) {
  1443. if (processor != null) {
  1444. synchronized (this) {
  1445. if (keyEventPostProcessors == null) {
  1446. keyEventPostProcessors = new java.util.LinkedList();
  1447. }
  1448. keyEventPostProcessors.add(processor);
  1449. }
  1450. }
  1451. }
  1452. /**
  1453. * Removes a previously added KeyEventPostProcessor from this
  1454. * KeyboardFocusManager's post-processor chain. This KeyboardFocusManager
  1455. * cannot itself be entirely removed from the chain. Only additional
  1456. * references added via <code>addKeyEventPostProcessor</code> can be
  1457. * removed.
  1458. * <p>
  1459. * If a null post-processor is specified, if the specified post-processor
  1460. * is not in the post-processor chain, or if this KeyboardFocusManager is
  1461. * specified without having been explicitly added, no action is taken and
  1462. * no exception is thrown.
  1463. *
  1464. * @param processor the KeyEventPostProcessor to remove from the post-
  1465. * processor chain
  1466. * @see #addKeyEventPostProcessor
  1467. */
  1468. public void removeKeyEventPostProcessor(KeyEventPostProcessor processor) {
  1469. if (processor != null) {
  1470. synchronized (this) {
  1471. if (keyEventPostProcessors != null) {
  1472. keyEventPostProcessors.remove(processor);
  1473. }
  1474. }
  1475. }
  1476. }
  1477. /**
  1478. * Returns this KeyboardFocusManager's KeyEventPostProcessor chain as a
  1479. * List. The List will not include this KeyboardFocusManager unless it was
  1480. * explicitly added via a call to <code>addKeyEventPostProcessor</code>. If
  1481. * no KeyEventPostProcessors are registered, implementations are free to
  1482. * return null or a List of length 0. Client code should not assume one
  1483. * behavior over another, nor should it assume that the behavior, once
  1484. * established, will not change.
  1485. *
  1486. * @return a possibly null or empty List of KeyEventPostProcessors
  1487. * @see #addKeyEventPostProcessor
  1488. * @see #removeKeyEventPostProcessor
  1489. */
  1490. protected java.util.List getKeyEventPostProcessors() {
  1491. return (keyEventPostProcessors != null)
  1492. ? (java.util.List)keyEventPostProcessors.clone()
  1493. : null;
  1494. }
  1495. static void setMostRecentFocusOwner(Component component) {
  1496. Component window = component;
  1497. while (window != null && !(window instanceof Window)) {
  1498. window = window.parent;
  1499. }
  1500. if (window != null) {
  1501. setMostRecentFocusOwner((Window)window, component);
  1502. }
  1503. }
  1504. static synchronized void setMostRecentFocusOwner(Window window,
  1505. Component component) {
  1506. // ATTN: component has a strong reference to window via chain
  1507. // of Component.parent fields. Since WeakHasMap refers to its
  1508. // values strongly, we need to break the strong link from the
  1509. // value (component) back to its key (window).
  1510. WeakReference weakValue = null;
  1511. if (component != null) {
  1512. weakValue = new WeakReference(component);
  1513. }
  1514. mostRecentFocusOwners.put(window, weakValue);
  1515. }
  1516. static void clearMostRecentFocusOwner(Component comp) {
  1517. Container window;
  1518. if (comp == null) {
  1519. return;
  1520. }
  1521. synchronized (comp.getTreeLock()) {
  1522. window = comp.getParent();
  1523. while (window != null && !(window instanceof Window)) {
  1524. window = window.getParent();
  1525. }
  1526. }
  1527. synchronized (KeyboardFocusManager.class) {
  1528. if ((window != null)
  1529. && (getMostRecentFocusOwner((Window)window) == comp))
  1530. {
  1531. setMostRecentFocusOwner((Window)window, null);
  1532. }
  1533. // Also clear temporary lost component stored in Window
  1534. if (window != null) {
  1535. Window realWindow = (Window)window;
  1536. if (realWindow.getTemporaryLostComponent() == comp) {
  1537. realWindow.setTemporaryLostComponent(null);
  1538. }
  1539. }
  1540. }
  1541. }
  1542. static synchronized Component getMostRecentFocusOwner(Window window) {
  1543. WeakReference weakValue =
  1544. (WeakReference)mostRecentFocusOwners.get(window);
  1545. return weakValue == null ? null : (Component)weakValue.get();
  1546. }
  1547. /**
  1548. * This method is called by the AWT event dispatcher requesting that the
  1549. * current KeyboardFocusManager dispatch the specified event on its behalf.
  1550. * It is expected that all KeyboardFocusManagers will dispatch all
  1551. * FocusEvents, all WindowEvents related to focus, and all KeyEvents.
  1552. * These events should be dispatched based on the KeyboardFocusManager's
  1553. * notion of the focus owner and the focused and active Windows, sometimes
  1554. * overriding the source of the specified AWTEvent. Dispatching must be
  1555. * done using <code>redispatchEvent</code> to prevent the AWT event
  1556. * dispatcher from recursively requesting that the KeyboardFocusManager
  1557. * dispatch the event again. If this method returns <code>false</code>,
  1558. * then the AWT event dispatcher will attempt to dispatch the event itself.
  1559. *
  1560. * @param e the AWTEvent to be dispatched
  1561. * @return <code>true</code> if this method dispatched the event;
  1562. * <code>false</code> otherwise
  1563. * @see #redispatchEvent
  1564. * @see #dispatchKeyEvent
  1565. */
  1566. public abstract boolean dispatchEvent(AWTEvent e);
  1567. /**
  1568. * Redispatches an AWTEvent in such a way that the AWT event dispatcher
  1569. * will not recursively request that the KeyboardFocusManager, or any
  1570. * installed KeyEventDispatchers, dispatch the event again. Client
  1571. * implementations of <code>dispatchEvent</code> and client-defined
  1572. * KeyEventDispatchers must call <code>redispatchEvent(target, e)</code>
  1573. * instead of <code>target.dispatchEvent(e)</code> to dispatch an event.
  1574. * <p>
  1575. * This method is intended to be used only by KeyboardFocusManagers and
  1576. * KeyEventDispatchers. It is not for general client use.
  1577. *
  1578. * @param target the Component to which the event should be dispatched
  1579. * @param e the event to dispatch
  1580. * @see #dispatchEvent
  1581. * @see KeyEventDispatcher
  1582. */
  1583. public final void redispatchEvent(Component target, AWTEvent e) {
  1584. e.focusManagerIsDispatching = true;
  1585. target.dispatchEvent(e);
  1586. e.focusManagerIsDispatching = false;
  1587. }
  1588. /**
  1589. * Typically this method will be called by <code>dispatchEvent</code> if no
  1590. * other KeyEventDispatcher in the dispatcher chain dispatched the
  1591. * KeyEvent, or if no other KeyEventDispatchers are registered. If an
  1592. * implementation of this method returns <code>false</code>,
  1593. * <code>dispatchEvent</code> may try to dispatch the KeyEvent itself, or
  1594. * may simply return <code>false</code>. If <code>true</code> is returned,
  1595. * <code>dispatchEvent</code> should return <code>true</code> as well.
  1596. *
  1597. * @param e the KeyEvent which the current KeyboardFocusManager has
  1598. * requested that this KeyEventDispatcher dispatch
  1599. * @return <code>true</code> if the KeyEvent was dispatched;
  1600. * <code>false</code> otherwise
  1601. * @see #dispatchEvent
  1602. */
  1603. public abstract boolean dispatchKeyEvent(KeyEvent e);
  1604. /**
  1605. * This method will be called by <code>dispatchKeyEvent</code>.
  1606. * By default, this method will handle any unconsumed KeyEvents that
  1607. * map to an AWT <code>MenuShortcut</code> by consuming the event
  1608. * and activating the shortcut.
  1609. *
  1610. * @param e the KeyEvent to post-process
  1611. * @return <code>true</code> to indicate that no other
  1612. * KeyEventPostProcessor will be notified of the KeyEvent.
  1613. * @see #dispatchKeyEvent
  1614. * @see MenuShortcut
  1615. */
  1616. public abstract boolean postProcessKeyEvent(KeyEvent e);
  1617. /**
  1618. * This method initiates a focus traversal operation if and only if the
  1619. * KeyEvent represents a focus traversal key for the specified
  1620. * focusedComponent. It is expected that focusedComponent is the current
  1621. * focus owner, although this need not be the case. If it is not,
  1622. * focus traversal will nevertheless proceed as if focusedComponent
  1623. * were the current focus owner.
  1624. *
  1625. * @param focusedComponent the Component that will be the basis for a focus
  1626. * traversal operation if the specified event represents a focus
  1627. * traversal key for the Component
  1628. * @param e the event that may represent a focus traversal key
  1629. */
  1630. public abstract void processKeyEvent(Component focusedComponent,
  1631. KeyEvent e);
  1632. /**
  1633. * Called by the AWT to notify the KeyboardFocusManager that it should
  1634. * delay dispatching of KeyEvents until the specified Component becomes
  1635. * the focus owner. If client code requests a focus change, and the AWT
  1636. * determines that this request might be granted by the native windowing
  1637. * system, then the AWT will call this method. It is the responsibility of
  1638. * the KeyboardFocusManager to delay dispatching of KeyEvents with
  1639. * timestamps later than the specified time stamp until the specified
  1640. * Component receives a FOCUS_GAINED event, or the AWT cancels the delay
  1641. * request by invoking <code>dequeueKeyEvents</code> or
  1642. * <code>discardKeyEvents</code>.
  1643. *
  1644. * @param after timestamp of current event, or the current, system time if
  1645. * the current event has no timestamp, or the AWT cannot determine
  1646. * which event is currently being handled
  1647. * @param untilFocused Component which should receive a FOCUS_GAINED event
  1648. * before any pending KeyEvents
  1649. * @see #dequeueKeyEvents
  1650. * @see #discardKeyEvents
  1651. */
  1652. protected abstract void enqueueKeyEvents(long after,
  1653. Component untilFocused);
  1654. /**
  1655. * Called by the AWT to notify the KeyboardFocusManager that it should
  1656. * cancel delayed dispatching of KeyEvents. All KeyEvents which were
  1657. * enqueued because of a call to <code>enqueueKeyEvents</code> with the
  1658. * same timestamp and Component should be released for normal dispatching
  1659. * to the current focus owner. If the given timestamp is less than zero,
  1660. * the outstanding enqueue request for the given Component with the <b>
  1661. * oldest</b> timestamp (if any) should be cancelled.
  1662. *
  1663. * @param after the timestamp specified in the call to
  1664. * <code>enqueueKeyEvents</code>, or any value < 0
  1665. * @param untilFocused the Component specified in the call to
  1666. * <code>enqueueKeyEvents</code>
  1667. * @see #enqueueKeyEvents
  1668. * @see #discardKeyEvents
  1669. */
  1670. protected abstract void dequeueKeyEvents(long after,
  1671. Component untilFocused);
  1672. /**
  1673. * Called by the AWT to notify the KeyboardFocusManager that it should
  1674. * cancel delayed dispatching of KeyEvents. All KeyEvents which were
  1675. * enqueued because of one or more calls to <code>enqueueKeyEvents</code>
  1676. * with the same Component should be discarded.
  1677. *
  1678. * @param comp the Component specified in one or more calls to
  1679. * <code>enqueueKeyEvents</code>
  1680. * @see #enqueueKeyEvents
  1681. * @see #dequeueKeyEvents
  1682. */
  1683. protected abstract void discardKeyEvents(Component comp);
  1684. /**
  1685. * Focuses the Component after aComponent, typically based on a
  1686. * FocusTraversalPolicy.
  1687. *
  1688. * @param aComponent the Component that is the basis for the focus
  1689. * traversal operation
  1690. * @see FocusTraversalPolicy
  1691. */
  1692. public abstract void focusNextComponent(Component aComponent);
  1693. /**
  1694. * Focuses the Component before aComponent, typically based on a
  1695. * FocusTraversalPolicy.
  1696. *
  1697. * @param aComponent the Component that is the basis for the focus
  1698. * traversal operation
  1699. * @see FocusTraversalPolicy
  1700. */
  1701. public abstract void focusPreviousComponent(Component aComponent);
  1702. /**
  1703. * Moves the focus up one focus traversal cycle. Typically, the focus owner
  1704. * is set to aComponent's focus cycle root, and the current focus cycle
  1705. * root is set to the new focus owner's focus cycle root. If, however,
  1706. * aComponent's focus cycle root is a Window, then typically the focus
  1707. * owner is set to the Window's default Component to focus, and the current
  1708. * focus cycle root is unchanged.
  1709. *
  1710. * @param aComponent the Component that is the basis for the focus
  1711. * traversal operation
  1712. */
  1713. public abstract void upFocusCycle(Component aComponent);
  1714. /**
  1715. * Moves the focus down one focus traversal cycle. Typically, if
  1716. * aContainer is a focus cycle root, then the focus owner is set to
  1717. * aContainer's default Component to focus, and the current focus cycle
  1718. * root is set to aContainer. If aContainer is not a focus cycle root, then
  1719. * no focus traversal operation occurs.
  1720. *
  1721. * @param aContainer the Container that is the basis for the focus
  1722. * traversal operation
  1723. */
  1724. public abstract void downFocusCycle(Container aContainer);
  1725. /**
  1726. * Focuses the Component after the current focus owner.
  1727. */
  1728. public final void focusNextComponent() {
  1729. Component focusOwner = getFocusOwner();
  1730. if (focusOwner != null) {
  1731. focusNextComponent(focusOwner);
  1732. }
  1733. }
  1734. /**
  1735. * Focuses the Component before the current focus owner.
  1736. */
  1737. public final void focusPreviousComponent() {
  1738. Component focusOwner = getFocusOwner();
  1739. if (focusOwner != null) {
  1740. focusPreviousComponent(focusOwner);
  1741. }
  1742. }
  1743. /**
  1744. * Moves the focus up one focus traversal cycle from the current focus
  1745. * owner. Typically, the new focus owner is set to the current focus
  1746. * owner's focus cycle root, and the current focus cycle root is set to the
  1747. * new focus owner's focus cycle root. If, however, the current focus
  1748. * owner's focus cycle root is a Window, then typically the focus owner is
  1749. * set to the focus cycle root's default Component to focus, and the
  1750. * current focus cycle root is unchanged.
  1751. */
  1752. public final void upFocusCycle() {
  1753. Component focusOwner = getFocusOwner();
  1754. if (focusOwner != null) {
  1755. upFocusCycle(focusOwner);
  1756. }
  1757. }
  1758. /**
  1759. * Moves the focus down one focus traversal cycle from the current focus
  1760. * owner, if and only if the current focus owner is a Container that is a
  1761. * focus cycle root. Typically, the focus owner is set to the current focus
  1762. * owner's default Component to focus, and the current focus cycle root is
  1763. * set to the current focus owner. If the current focus owner is not a
  1764. * Container that is a focus cycle root, then no focus traversal operation
  1765. * occurs.
  1766. */
  1767. public final void downFocusCycle() {
  1768. Component focusOwner = getFocusOwner();
  1769. if (focusOwner instanceof Container) {
  1770. downFocusCycle((Container)focusOwner);
  1771. }
  1772. }
  1773. private static final class LightweightFocusRequest {
  1774. final Component component;
  1775. final boolean temporary;
  1776. LightweightFocusRequest(Component component, boolean temporary) {
  1777. this.component = component;
  1778. this.temporary = temporary;
  1779. }
  1780. public String toString() {
  1781. return "LightweightFocusRequest[component=" + component +
  1782. ",temporary=" + temporary + "]";
  1783. }
  1784. }
  1785. private static final class HeavyweightFocusRequest {
  1786. final Component heavyweight;
  1787. final LinkedList lightweightRequests;
  1788. static final HeavyweightFocusRequest CLEAR_GLOBAL_FOCUS_OWNER =
  1789. new HeavyweightFocusRequest();
  1790. private HeavyweightFocusRequest() {
  1791. heavyweight = null;
  1792. lightweightRequests = null;
  1793. }
  1794. HeavyweightFocusRequest(Component heavyweight, Component descendant,
  1795. boolean temporary) {
  1796. if (dbg.on) {
  1797. dbg.assertion(heavyweight != null);
  1798. }
  1799. this.heavyweight = heavyweight;
  1800. this.lightweightRequests = new LinkedList();
  1801. addLightweightRequest(descendant, temporary);
  1802. }
  1803. boolean addLightweightRequest(Component descendant,
  1804. boolean temporary) {
  1805. if (dbg.on) {
  1806. dbg.assertion(this != HeavyweightFocusRequest.
  1807. CLEAR_GLOBAL_FOCUS_OWNER);
  1808. dbg.assertion(descendant != null);
  1809. }
  1810. Component lastDescendant = ((lightweightRequests.size() > 0)
  1811. ? ((LightweightFocusRequest)lightweightRequests.getLast()).
  1812. component
  1813. : null);
  1814. if (descendant != lastDescendant) {
  1815. // Not a duplicate request
  1816. lightweightRequests.add
  1817. (new LightweightFocusRequest(descendant, temporary));
  1818. return true;
  1819. } else {
  1820. return false;
  1821. }
  1822. }
  1823. LightweightFocusRequest getFirstLightweightRequest() {
  1824. if (this == CLEAR_GLOBAL_FOCUS_OWNER) {
  1825. return null;
  1826. }
  1827. return (LightweightFocusRequest)lightweightRequests.getFirst();
  1828. }
  1829. public String toString() {
  1830. boolean first = true;
  1831. String str = "HeavyweightFocusRequest[heavweight=" + heavyweight +
  1832. ",lightweightRequests=";
  1833. if (lightweightRequests == null) {
  1834. str += null;
  1835. } else {
  1836. str += "[";
  1837. for (Iterator iter = lightweightRequests.iterator();
  1838. iter.hasNext(); )
  1839. {
  1840. if (first) {
  1841. first = false;
  1842. } else {
  1843. str += ",";
  1844. }
  1845. str += iter.next();
  1846. }
  1847. str += "]";
  1848. }
  1849. str += "]";
  1850. return str;
  1851. }
  1852. }
  1853. /*
  1854. * heavyweightRequests is used as a monitor for synchronized changes of
  1855. * currentLightweightRequests, clearingCurrentLightweightRequests and
  1856. * newFocusOwner.
  1857. */
  1858. private static LinkedList heavyweightRequests = new LinkedList();
  1859. private static LinkedList currentLightweightRequests;
  1860. private static boolean clearingCurrentLightweightRequests;
  1861. private static Component newFocusOwner = null;
  1862. int requestCount() {
  1863. return heavyweightRequests.size();
  1864. }
  1865. static final int SNFH_FAILURE = 0;
  1866. static final int SNFH_SUCCESS_HANDLED = 1;
  1867. static final int SNFH_SUCCESS_PROCEED = 2;
  1868. static boolean processSynchronousLightweightTransfer(Component heavyweight, Component descendant,
  1869. boolean temporary, boolean focusedWindowChangeAllowed,
  1870. long time) {
  1871. Window parentWindow = getContainingWindow(heavyweight);
  1872. if (parentWindow == null || !parentWindow.syncLWRequests) {
  1873. return false;
  1874. }
  1875. if (descendant == null) {
  1876. // Focus transfers from a lightweight child back to the
  1877. // heavyweight Container should be treated like lightweight
  1878. // focus transfers.
  1879. descendant = heavyweight;
  1880. }
  1881. FocusEvent currentFocusOwnerEvent = null;
  1882. FocusEvent newFocusOwnerEvent = null;
  1883. Component currentFocusOwner = getCurrentKeyboardFocusManager().
  1884. getGlobalFocusOwner();
  1885. synchronized (heavyweightRequests) {
  1886. HeavyweightFocusRequest hwFocusRequest = (HeavyweightFocusRequest)
  1887. ((heavyweightRequests.size() > 0)
  1888. ? heavyweightRequests.getLast() : null);
  1889. if (hwFocusRequest == null &&
  1890. heavyweight == getNativeFocusOwner())
  1891. {
  1892. if (descendant == currentFocusOwner) {
  1893. // Redundant request.
  1894. return true;
  1895. }
  1896. // 'heavyweight' owns the native focus and there are no pending
  1897. // requests. 'heavyweight' must be a Container and
  1898. // 'descendant' must not be the focus owner. Otherwise,
  1899. // we would never have gotten this far.
  1900. getCurrentKeyboardFocusManager
  1901. (SunToolkit.targetToAppContext(descendant)).
  1902. enqueueKeyEvents(time, descendant);
  1903. hwFocusRequest =
  1904. new HeavyweightFocusRequest(heavyweight, descendant,
  1905. temporary);
  1906. heavyweightRequests.add(hwFocusRequest);
  1907. if (currentFocusOwner != null) {
  1908. currentFocusOwnerEvent =
  1909. new FocusEvent(currentFocusOwner,
  1910. FocusEvent.FOCUS_LOST,
  1911. temporary, descendant);
  1912. }
  1913. newFocusOwnerEvent =
  1914. new FocusEvent(descendant, FocusEvent.FOCUS_GAINED,
  1915. temporary, currentFocusOwner);
  1916. }
  1917. }
  1918. boolean result = false;
  1919. synchronized(Component.LOCK) {
  1920. if (currentFocusOwnerEvent != null && currentFocusOwner != null) {
  1921. currentFocusOwner.dispatchEvent(currentFocusOwnerEvent);
  1922. result = true;
  1923. }
  1924. if (newFocusOwnerEvent != null && descendant != null) {
  1925. descendant.dispatchEvent(newFocusOwnerEvent);
  1926. result = true;
  1927. }
  1928. }
  1929. return result;
  1930. }
  1931. /**
  1932. * Indicates whether the native implementation should proceed with a
  1933. * pending, native focus request. Before changing the focus at the native
  1934. * level, the AWT implementation should always call this function for
  1935. * permission. This function will reject the request if a duplicate request
  1936. * preceded it, or if the specified heavyweight Component already owns the
  1937. * focus and no native focus changes are pending. Otherwise, the request
  1938. * will be approved and the focus request list will be updated so that,
  1939. * if necessary, the proper descendant will be focused when the
  1940. * corresponding FOCUS_GAINED event on the heavyweight is received.
  1941. *
  1942. * An implementation must ensure that calls to this method and native
  1943. * focus changes are atomic. If this is not guaranteed, then the ordering
  1944. * of the focus request list may be incorrect, leading to errors in the
  1945. * type-ahead mechanism. Typically this is accomplished by only calling
  1946. * this function from the native event pumping thread, or by holding a
  1947. * global, native lock during invocation.
  1948. */
  1949. static int shouldNativelyFocusHeavyweight
  1950. (Component heavyweight, Component descendant, boolean temporary,
  1951. boolean focusedWindowChangeAllowed, long time)
  1952. {
  1953. if (dbg.on) {
  1954. dbg.assertion(heavyweight != null);
  1955. dbg.assertion(time != 0);
  1956. }
  1957. if (descendant == null) {
  1958. // Focus transfers from a lightweight child back to the
  1959. // heavyweight Container should be treated like lightweight
  1960. // focus transfers.
  1961. descendant = heavyweight;
  1962. }
  1963. synchronized (heavyweightRequests) {
  1964. HeavyweightFocusRequest hwFocusRequest = (HeavyweightFocusRequest)
  1965. ((heavyweightRequests.size() > 0)
  1966. ? heavyweightRequests.getLast() : null);
  1967. if (hwFocusRequest == null &&
  1968. heavyweight == getNativeFocusOwner())
  1969. {
  1970. Component currentFocusOwner = getCurrentKeyboardFocusManager().
  1971. getGlobalFocusOwner();
  1972. if (descendant == currentFocusOwner) {
  1973. // Redundant request.
  1974. return SNFH_FAILURE;
  1975. }
  1976. // 'heavyweight' owns the native focus and there are no pending
  1977. // requests. 'heavyweight' must be a Container and
  1978. // 'descendant' must not be the focus owner. Otherwise,
  1979. // we would never have gotten this far.
  1980. getCurrentKeyboardFocusManager
  1981. (SunToolkit.targetToAppContext(descendant)).
  1982. enqueueKeyEvents(time, descendant);
  1983. hwFocusRequest =
  1984. new HeavyweightFocusRequest(heavyweight, descendant,
  1985. temporary);
  1986. heavyweightRequests.add(hwFocusRequest);
  1987. if (currentFocusOwner != null) {
  1988. FocusEvent currentFocusOwnerEvent =
  1989. new FocusEvent(currentFocusOwner,
  1990. FocusEvent.FOCUS_LOST,
  1991. temporary, descendant);
  1992. SunToolkit.postEvent(currentFocusOwner.appContext,
  1993. currentFocusOwnerEvent);
  1994. }
  1995. FocusEvent newFocusOwnerEvent =
  1996. new FocusEvent(descendant, FocusEvent.FOCUS_GAINED,
  1997. temporary, currentFocusOwner);
  1998. SunToolkit.postEvent(descendant.appContext,
  1999. newFocusOwnerEvent);
  2000. return SNFH_SUCCESS_HANDLED;
  2001. } else if (hwFocusRequest != null &&
  2002. hwFocusRequest.heavyweight == heavyweight) {
  2003. // 'heavyweight' doesn't have the native focus right now, but
  2004. // if all pending requests were completed, it would. Add
  2005. // descendant to the heavyweight's list of pending
  2006. // lightweight focus transfers.
  2007. if (hwFocusRequest.addLightweightRequest(descendant,
  2008. temporary)) {
  2009. getCurrentKeyboardFocusManager
  2010. (SunToolkit.targetToAppContext(descendant)).
  2011. enqueueKeyEvents(time, descendant);
  2012. }
  2013. return SNFH_SUCCESS_HANDLED;
  2014. } else {
  2015. if (!focusedWindowChangeAllowed) {
  2016. // For purposes of computing oldFocusedWindow, we should
  2017. // look at the second to last HeavyweightFocusRequest on
  2018. // the queue iff the last HeavyweightFocusRequest is
  2019. // CLEAR_GLOBAL_FOCUS_OWNER. If there is no second to last
  2020. // HeavyweightFocusRequest, null is an acceptable value.
  2021. if (hwFocusRequest ==
  2022. HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER)
  2023. {
  2024. int size = heavyweightRequests.size();
  2025. hwFocusRequest = (HeavyweightFocusRequest)((size >= 2)
  2026. ? heavyweightRequests.get(size - 2)
  2027. : null);
  2028. }
  2029. if (focusedWindowChanged(heavyweight,
  2030. (hwFocusRequest != null)
  2031. ? hwFocusRequest.heavyweight
  2032. : getNativeFocusedWindow())) {
  2033. return SNFH_FAILURE;
  2034. }
  2035. }
  2036. getCurrentKeyboardFocusManager
  2037. (SunToolkit.targetToAppContext(descendant)).
  2038. enqueueKeyEvents(time, descendant);
  2039. heavyweightRequests.add
  2040. (new HeavyweightFocusRequest(heavyweight, descendant,
  2041. temporary));
  2042. return SNFH_SUCCESS_PROCEED;
  2043. }
  2044. }
  2045. }
  2046. static void heavyweightButtonDown(Component heavyweight, long time) {
  2047. heavyweightButtonDown(heavyweight, time, false);
  2048. }
  2049. static void heavyweightButtonDown(Component heavyweight, long time, boolean acceptDuplicates) {
  2050. if (dbg.on) {
  2051. dbg.assertion(heavyweight != null);
  2052. dbg.assertion(time != 0);
  2053. }
  2054. synchronized (heavyweightRequests) {
  2055. HeavyweightFocusRequest hwFocusRequest = (HeavyweightFocusRequest)
  2056. ((heavyweightRequests.size() > 0)
  2057. ? heavyweightRequests.getLast() : null);
  2058. Component currentNativeFocusOwner = (hwFocusRequest == null)
  2059. ? getNativeFocusOwner()
  2060. : hwFocusRequest.heavyweight;
  2061. // Behavior for all use cases:
  2062. // 1. Heavyweight leaf Components (e.g., Button, Checkbox, Choice,
  2063. // List, TextComponent, Canvas) that respond to button down.
  2064. //
  2065. // Native platform will generate a FOCUS_GAINED if and only if
  2066. // the Component is not the focus owner (or, will not be the
  2067. // focus owner when all outstanding focus requests are
  2068. // processed).
  2069. //
  2070. // 2. Panel with no descendants.
  2071. //
  2072. // Same as (1).
  2073. //
  2074. // 3. Panel with at least one heavyweight descendant.
  2075. //
  2076. // This function should NOT be called for this case!
  2077. //
  2078. // 4. Panel with only lightweight descendants.
  2079. //
  2080. // Native platform will generate a FOCUS_GAINED if and only if
  2081. // neither the Panel, nor any of its recursive, lightweight
  2082. // descendants, is the focus owner. However, we want a
  2083. // requestFocus() for any lightweight descendant to win out over
  2084. // the focus request for the Panel. To accomplish this, we
  2085. // differ from the algorithm for shouldNativelyFocusHeavyweight
  2086. // as follows:
  2087. // a. If the requestFocus() for a lightweight descendant has
  2088. // been fully handled by the time this function is invoked,
  2089. // then 'hwFocusRequest' will be null and 'heavyweight'
  2090. // will be the native focus owner. Do *not* synthesize a
  2091. // focus transfer to the Panel.
  2092. // b. If the requestFocus() for a lightweight descendant has
  2093. // been recorded, but not handled, then 'hwFocusRequest'
  2094. // will be non-null and 'hwFocusRequest.heavyweight' will
  2095. // equal 'heavyweight'. Do *not* append 'heavyweight' to
  2096. // hwFocusRequest.lightweightRequests.
  2097. // c. If the requestFocus() for a lightweight descendant is
  2098. // yet to be made, then post a new HeavyweightFocusRequest.
  2099. // If no lightweight descendant ever requests focus, then
  2100. // the Panel will get focus. If some descendant does, then
  2101. // the descendant will get focus by either a synthetic
  2102. // focus transfer, or a lightweightRequests focus transfer.
  2103. if (acceptDuplicates || heavyweight != currentNativeFocusOwner) {
  2104. getCurrentKeyboardFocusManager
  2105. (SunToolkit.targetToAppContext(heavyweight)).
  2106. enqueueKeyEvents(time, heavyweight);
  2107. heavyweightRequests.add
  2108. (new HeavyweightFocusRequest(heavyweight, heavyweight,
  2109. false));
  2110. }
  2111. }
  2112. }
  2113. /**
  2114. * Returns the Window which will be active after processing this request,
  2115. * or null if this is a duplicate request. The active Window is useful
  2116. * because some native platforms do not support setting the native focus
  2117. * owner to null. On these platforms, the obvious choice is to set the
  2118. * focus owner to the focus proxy of the active Window.
  2119. */
  2120. static Window markClearGlobalFocusOwner() {
  2121. synchronized (heavyweightRequests) {
  2122. HeavyweightFocusRequest hwFocusRequest = (HeavyweightFocusRequest)
  2123. ((heavyweightRequests.size() > 0)
  2124. ? heavyweightRequests.getLast() : null);
  2125. if (hwFocusRequest ==
  2126. HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER)
  2127. {
  2128. // duplicate request
  2129. return null;
  2130. }
  2131. heavyweightRequests.add
  2132. (HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER);
  2133. Component activeWindow = ((hwFocusRequest != null)
  2134. ? getContainingWindow(hwFocusRequest.heavyweight)
  2135. : getNativeFocusedWindow());
  2136. while (activeWindow != null &&
  2137. !((activeWindow instanceof Frame) ||
  2138. (activeWindow instanceof Dialog)))
  2139. {
  2140. activeWindow = activeWindow.getParent();
  2141. }
  2142. return (Window)activeWindow;
  2143. }
  2144. }
  2145. Component getCurrentWaitingRequest(Component parent) {
  2146. synchronized (heavyweightRequests) {
  2147. HeavyweightFocusRequest hwFocusRequest = (HeavyweightFocusRequest)
  2148. ((heavyweightRequests.size() > 0)
  2149. ? heavyweightRequests.getFirst() : null);
  2150. if (hwFocusRequest != null) {
  2151. if (hwFocusRequest.heavyweight == parent) {
  2152. LightweightFocusRequest lwFocusRequest =
  2153. (LightweightFocusRequest)hwFocusRequest.
  2154. lightweightRequests.getFirst();
  2155. if (lwFocusRequest != null) {
  2156. return lwFocusRequest.component;
  2157. }
  2158. }
  2159. }
  2160. }
  2161. return null;
  2162. }
  2163. static void processCurrentLightweightRequests() {
  2164. KeyboardFocusManager manager = getCurrentKeyboardFocusManager();
  2165. LinkedList localLightweightRequests = null;
  2166. synchronized(heavyweightRequests) {
  2167. if (currentLightweightRequests != null) {
  2168. clearingCurrentLightweightRequests = true;
  2169. localLightweightRequests = currentLightweightRequests;
  2170. currentLightweightRequests = null;
  2171. } else {
  2172. // do nothing
  2173. return;
  2174. }
  2175. }
  2176. try {
  2177. if (localLightweightRequests != null) {
  2178. for (Iterator iter = localLightweightRequests.iterator();
  2179. iter.hasNext(); )
  2180. {
  2181. Component currentFocusOwner = manager.
  2182. getGlobalFocusOwner();
  2183. if (currentFocusOwner == null) {
  2184. // If this ever happens, a focus change has been
  2185. // rejected. Stop generating more focus changes.
  2186. break;
  2187. }
  2188. LightweightFocusRequest lwFocusRequest =
  2189. (LightweightFocusRequest)iter.next();
  2190. FocusEvent currentFocusOwnerEvent =
  2191. new FocusEvent(currentFocusOwner,
  2192. FocusEvent.FOCUS_LOST,
  2193. lwFocusRequest.temporary,
  2194. lwFocusRequest.component);
  2195. FocusEvent newFocusOwnerEvent =
  2196. new FocusEvent(lwFocusRequest.component,
  2197. FocusEvent.FOCUS_GAINED,
  2198. lwFocusRequest.temporary,
  2199. currentFocusOwner);
  2200. currentFocusOwner.dispatchEvent(currentFocusOwnerEvent);
  2201. lwFocusRequest.component.
  2202. dispatchEvent(newFocusOwnerEvent);
  2203. }
  2204. }
  2205. } finally {
  2206. clearingCurrentLightweightRequests = false;
  2207. localLightweightRequests = null;
  2208. }
  2209. }
  2210. static FocusEvent retargetUnexpectedFocusEvent(FocusEvent fe) {
  2211. synchronized (heavyweightRequests) {
  2212. // Any other case represents a failure condition which we did
  2213. // not expect. We need to clearFocusRequestList() and patch up
  2214. // the event as best as possible.
  2215. if (removeFirstRequest()) {
  2216. return (FocusEvent)retargetFocusEvent(fe);
  2217. }
  2218. Component source = fe.getComponent();
  2219. Component opposite = fe.getOppositeComponent();
  2220. boolean temporary = false;
  2221. if (fe.getID() == FocusEvent.FOCUS_LOST &&
  2222. (opposite == null || focusedWindowChanged(source, opposite)))
  2223. {
  2224. temporary = true;
  2225. }
  2226. return new FocusEvent(source, fe.getID(), temporary, opposite);
  2227. }
  2228. }
  2229. static FocusEvent retargetFocusGained(FocusEvent fe) {
  2230. assert (fe.getID() == FocusEvent.FOCUS_GAINED);
  2231. Component currentFocusOwner = getCurrentKeyboardFocusManager().
  2232. getGlobalFocusOwner();
  2233. Component source = fe.getComponent();
  2234. Component opposite = fe.getOppositeComponent();
  2235. Component nativeSource = getHeavyweight(source);
  2236. synchronized (heavyweightRequests) {
  2237. HeavyweightFocusRequest hwFocusRequest = (HeavyweightFocusRequest)
  2238. ((heavyweightRequests.size() > 0)
  2239. ? heavyweightRequests.getFirst() : null);
  2240. if (hwFocusRequest == HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER)
  2241. {
  2242. return retargetUnexpectedFocusEvent(fe);
  2243. }
  2244. if (source != null && nativeSource == null && hwFocusRequest != null) {
  2245. // if source w/o peer and
  2246. // if source is equal to first lightweight
  2247. // then we should correct source and nativeSource
  2248. if (source == hwFocusRequest.getFirstLightweightRequest().component)
  2249. {
  2250. source = hwFocusRequest.heavyweight;
  2251. nativeSource = source; // source is heavuweight itself
  2252. }
  2253. }
  2254. if (hwFocusRequest != null &&
  2255. nativeSource == hwFocusRequest.heavyweight)
  2256. {
  2257. // Focus change as a result of a known call to requestFocus(),
  2258. // or known click on a peer focusable heavyweight Component.
  2259. heavyweightRequests.removeFirst();
  2260. LightweightFocusRequest lwFocusRequest =
  2261. (LightweightFocusRequest)hwFocusRequest.
  2262. lightweightRequests.removeFirst();
  2263. Component newSource = lwFocusRequest.component;
  2264. if (currentFocusOwner != null) {
  2265. /*
  2266. * Since we receive FOCUS_GAINED when current focus
  2267. * owner is not null, correcponding FOCUS_LOST is supposed
  2268. * to be lost. And so, we keep new focus owner
  2269. * to determine synthetic FOCUS_LOST event which will be
  2270. * generated by KeyboardFocusManager for this FOCUS_GAINED.
  2271. *
  2272. * This code based on knowledge of
  2273. * DefaultKeyboardFocusManager's implementation and might
  2274. * be not applicable for another KeyboardFocusManager.
  2275. */
  2276. newFocusOwner = newSource;
  2277. }
  2278. boolean temporary = (opposite == null ||
  2279. focusedWindowChanged(newSource, opposite))
  2280. ? false
  2281. : lwFocusRequest.temporary;
  2282. if (hwFocusRequest.lightweightRequests.size() > 0) {
  2283. currentLightweightRequests =
  2284. hwFocusRequest.lightweightRequests;
  2285. EventQueue.invokeLater(new Runnable() {
  2286. public void run() {
  2287. processCurrentLightweightRequests();
  2288. }
  2289. });
  2290. }
  2291. // 'opposite' will be fixed by
  2292. // DefaultKeyboardFocusManager.realOppositeComponent
  2293. return new FocusEvent(newSource,
  2294. FocusEvent.FOCUS_GAINED, temporary,
  2295. opposite);
  2296. }
  2297. if (currentFocusOwner != null
  2298. && getContainingWindow(currentFocusOwner) == source
  2299. && (hwFocusRequest == null || source != hwFocusRequest.heavyweight))
  2300. {
  2301. // Special case for FOCUS_GAINED in top-levels
  2302. // If it arrives as the result of activation we should skip it
  2303. // This event will not have appropriate request record and
  2304. // on arrival there will be already some focus owner set.
  2305. return new FocusEvent(currentFocusOwner, FocusEvent.FOCUS_GAINED, false, null);
  2306. }
  2307. return retargetUnexpectedFocusEvent(fe);
  2308. } // end synchronized(heavyweightRequests)
  2309. }
  2310. static FocusEvent retargetFocusLost(FocusEvent fe) {
  2311. assert (fe.getID() == FocusEvent.FOCUS_LOST);
  2312. Component currentFocusOwner = getCurrentKeyboardFocusManager().
  2313. getGlobalFocusOwner();
  2314. Component opposite = fe.getOppositeComponent();
  2315. Component nativeOpposite = getHeavyweight(opposite);
  2316. synchronized (heavyweightRequests) {
  2317. HeavyweightFocusRequest hwFocusRequest = (HeavyweightFocusRequest)
  2318. ((heavyweightRequests.size() > 0)
  2319. ? heavyweightRequests.getFirst() : null);
  2320. if (hwFocusRequest == HeavyweightFocusRequest.CLEAR_GLOBAL_FOCUS_OWNER)
  2321. {
  2322. if (currentFocusOwner != null) {
  2323. // Call to KeyboardFocusManager.clearGlobalFocusOwner()
  2324. heavyweightRequests.removeFirst();
  2325. return new FocusEvent(currentFocusOwner,
  2326. FocusEvent.FOCUS_LOST, false, null);
  2327. }
  2328. // Otherwise, fall through to failure case below
  2329. } else if (opposite == null)
  2330. {
  2331. // Focus leaving application
  2332. if (currentFocusOwner != null) {
  2333. return new FocusEvent(currentFocusOwner,
  2334. FocusEvent.FOCUS_LOST,
  2335. true, null);
  2336. } else {
  2337. return fe;
  2338. }
  2339. } else if (hwFocusRequest != null &&
  2340. (nativeOpposite == hwFocusRequest.heavyweight ||
  2341. nativeOpposite == null &&
  2342. opposite == hwFocusRequest.getFirstLightweightRequest().component))
  2343. {
  2344. if (currentFocusOwner == null) {
  2345. return fe;
  2346. }
  2347. // Focus change as a result of a known call to requestFocus(),
  2348. // or click on a peer focusable heavyweight Component.
  2349. // If a focus transfer is made across top-levels, then the
  2350. // FOCUS_LOST event is always temporary, and the FOCUS_GAINED
  2351. // event is always permanent. Otherwise, the stored temporary
  2352. // value is honored.
  2353. LightweightFocusRequest lwFocusRequest =
  2354. (LightweightFocusRequest)hwFocusRequest.
  2355. lightweightRequests.getFirst();
  2356. boolean temporary = focusedWindowChanged(opposite,
  2357. currentFocusOwner)
  2358. ? true
  2359. : lwFocusRequest.temporary;
  2360. return new FocusEvent(currentFocusOwner, FocusEvent.FOCUS_LOST,
  2361. temporary, lwFocusRequest.component);
  2362. }
  2363. return retargetUnexpectedFocusEvent(fe);
  2364. } // end synchronized(heavyweightRequests)
  2365. }
  2366. static AWTEvent retargetFocusEvent(AWTEvent event) {
  2367. if (clearingCurrentLightweightRequests) {
  2368. return event;
  2369. }
  2370. KeyboardFocusManager manager = getCurrentKeyboardFocusManager();
  2371. synchronized(heavyweightRequests) {
  2372. /*
  2373. * This code handles FOCUS_LOST event which is generated by
  2374. * DefaultKeyboardFocusManager for FOCUS_GAINED.
  2375. *
  2376. * This code based on knowledge of DefaultKeyboardFocusManager's
  2377. * implementation and might be not applicable for another
  2378. * KeyboardFocusManager.
  2379. *
  2380. * Fix for 4472032
  2381. */
  2382. if (newFocusOwner != null &&
  2383. event.getID() == FocusEvent.FOCUS_LOST)
  2384. {
  2385. FocusEvent fe = (FocusEvent)event;
  2386. if (manager.getGlobalFocusOwner() == fe.getComponent() &&
  2387. fe.getOppositeComponent() == newFocusOwner)
  2388. {
  2389. newFocusOwner = null;
  2390. return event;
  2391. }
  2392. }
  2393. }
  2394. processCurrentLightweightRequests();
  2395. switch (event.getID()) {
  2396. case FocusEvent.FOCUS_GAINED: {
  2397. event = retargetFocusGained((FocusEvent)event);
  2398. break;
  2399. }
  2400. case FocusEvent.FOCUS_LOST: {
  2401. event = retargetFocusLost((FocusEvent)event);
  2402. break;
  2403. }
  2404. default:
  2405. /* do nothing */
  2406. }
  2407. return event;
  2408. }
  2409. static boolean removeFirstRequest() {
  2410. KeyboardFocusManager manager =
  2411. KeyboardFocusManager.getCurrentKeyboardFocusManager();
  2412. synchronized(heavyweightRequests) {
  2413. HeavyweightFocusRequest hwFocusRequest = (HeavyweightFocusRequest)
  2414. ((heavyweightRequests.size() > 0)
  2415. ? heavyweightRequests.getFirst() : null);
  2416. if (hwFocusRequest != null) {
  2417. heavyweightRequests.removeFirst();
  2418. if (hwFocusRequest.lightweightRequests != null) {
  2419. for (Iterator lwIter = hwFocusRequest.lightweightRequests.
  2420. iterator();
  2421. lwIter.hasNext(); )
  2422. {
  2423. manager.dequeueKeyEvents
  2424. (-1, ((LightweightFocusRequest)lwIter.next()).
  2425. component);
  2426. }
  2427. }
  2428. }
  2429. return (heavyweightRequests.size() > 0);
  2430. }
  2431. }
  2432. static void removeLastFocusRequest(Component heavyweight) {
  2433. if (dbg.on) {
  2434. dbg.assertion(heavyweight != null);
  2435. }
  2436. synchronized(heavyweightRequests) {
  2437. HeavyweightFocusRequest hwFocusRequest = (HeavyweightFocusRequest)
  2438. ((heavyweightRequests.size() > 0)
  2439. ? heavyweightRequests.getLast() : null);
  2440. if (hwFocusRequest != null &&
  2441. hwFocusRequest.heavyweight == heavyweight) {
  2442. heavyweightRequests.removeLast();
  2443. }
  2444. }
  2445. }
  2446. static void removeFocusRequest(Component component) {
  2447. if (dbg.on) {
  2448. dbg.assertion(component != null);
  2449. }
  2450. Component heavyweight = (component.peer instanceof LightweightPeer)
  2451. ? component.getNativeContainer() : component;
  2452. if (heavyweight == null) {
  2453. return;
  2454. }
  2455. synchronized (heavyweightRequests) {
  2456. if ((currentLightweightRequests != null) &&
  2457. (currentLightweightRequests.size() > 0)) {
  2458. LightweightFocusRequest lwFocusRequest =
  2459. (LightweightFocusRequest)currentLightweightRequests.getFirst();
  2460. Component comp = lwFocusRequest.component;
  2461. Component currentHeavyweight =
  2462. (comp.peer instanceof LightweightPeer)
  2463. ? comp.getNativeContainer() : comp;
  2464. if (currentHeavyweight == component) {
  2465. currentLightweightRequests = null;
  2466. } else {
  2467. for (Iterator iter = currentLightweightRequests.iterator();
  2468. iter.hasNext(); ) {
  2469. if (((LightweightFocusRequest)iter.next()).
  2470. component == component)
  2471. {
  2472. iter.remove();
  2473. }
  2474. }
  2475. if (currentLightweightRequests.size() == 0) {
  2476. currentLightweightRequests = null;
  2477. }
  2478. }
  2479. }
  2480. for (Iterator iter = heavyweightRequests.iterator();
  2481. iter.hasNext(); )
  2482. {
  2483. HeavyweightFocusRequest hwFocusRequest =
  2484. (HeavyweightFocusRequest)iter.next();
  2485. if (hwFocusRequest.heavyweight == heavyweight) {
  2486. if (heavyweight == component) {
  2487. iter.remove();
  2488. continue;
  2489. }
  2490. for (Iterator lwIter = hwFocusRequest.lightweightRequests.
  2491. iterator();
  2492. lwIter.hasNext(); )
  2493. {
  2494. if (((LightweightFocusRequest)lwIter.next()).
  2495. component == component)
  2496. {
  2497. lwIter.remove();
  2498. }
  2499. }
  2500. if (hwFocusRequest.lightweightRequests.size() == 0) {
  2501. iter.remove();
  2502. }
  2503. }
  2504. }
  2505. }
  2506. }
  2507. private static void clearFocusRequestList() {
  2508. KeyboardFocusManager manager =
  2509. KeyboardFocusManager.getCurrentKeyboardFocusManager();
  2510. synchronized (heavyweightRequests) {
  2511. for (Iterator iter = heavyweightRequests.iterator();
  2512. iter.hasNext(); )
  2513. {
  2514. HeavyweightFocusRequest hwFocusRequest =
  2515. (HeavyweightFocusRequest)iter.next();
  2516. if (hwFocusRequest.lightweightRequests == null) {
  2517. continue;
  2518. }
  2519. for (Iterator lwIter = hwFocusRequest.lightweightRequests.
  2520. iterator();
  2521. lwIter.hasNext(); )
  2522. {
  2523. manager.dequeueKeyEvents
  2524. (-1, ((LightweightFocusRequest)lwIter.next()).
  2525. component);
  2526. }
  2527. }
  2528. heavyweightRequests.clear();
  2529. }
  2530. }
  2531. private static boolean focusedWindowChanged(Component a, Component b) {
  2532. Window wa = getContainingWindow(a);
  2533. Window wb = getContainingWindow(b);
  2534. if (wa == null || wb == null) {
  2535. return false;
  2536. }
  2537. return (wa != wb);
  2538. }
  2539. static Window getContainingWindow(Component comp) {
  2540. while (comp != null && !(comp instanceof Window)) {
  2541. comp = comp.getParent();
  2542. }
  2543. return (Window)comp;
  2544. }
  2545. private static Component getHeavyweight(Component comp) {
  2546. if (comp == null || comp.getPeer() == null) {
  2547. return null;
  2548. } else if (comp.getPeer() instanceof LightweightPeer) {
  2549. return comp.getNativeContainer();
  2550. } else {
  2551. return comp;
  2552. }
  2553. }
  2554. // Accessor to private field isProxyActive of KeyEvent
  2555. private static native boolean isProxyActiveImpl(KeyEvent e);
  2556. // Returns the value of this KeyEvent's field isProxyActive
  2557. static boolean isProxyActive(KeyEvent e) {
  2558. if (!GraphicsEnvironment.isHeadless()) {
  2559. return isProxyActiveImpl(e);
  2560. } else {
  2561. return false;
  2562. }
  2563. }
  2564. }