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