1. /*
  2. * @(#)KeyboardFocusManager.java 1.40 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.awt;
  8. import java.awt.event.FocusEvent;
  9. import java.awt.event.InputEvent;
  10. import java.awt.event.KeyEvent;
  11. import java.awt.event.WindowEvent;
  12. import java.awt.peer.LightweightPeer;
  13. import java.beans.*;
  14. import java.util.Set;
  15. import java.util.HashSet;
  16. import java.util.Collections;
  17. import java.util.Iterator;
  18. import java.util.LinkedList;
  19. import java.util.ListIterator;
  20. import java.util.StringTokenizer;
  21. import java.util.WeakHashMap;
  22. import java.lang.ref.WeakReference;
  23. import sun.awt.AppContext;
  24. import sun.awt.DebugHelper;
  25. import sun.awt.SunToolkit;
  26. /**
  27. * The KeyboardFocusManager is responsible for managing the active and focused
  28. * Windows, and the current focus owner. The focus owner is defined as the
  29. * Component in an application that will typically receive all KeyEvents
  30. * generated by the user. The focused Window is the Window that is, or
  31. * contains, the focus owner. Only a Frame or a Dialog can be the active
  32. * Window. The native windowing system may denote the active Window or its
  33. * children with special decorations, such as a highlighted title bar. The
  34. * active Window is always either the focused Window, or the first Frame or
  35. * Dialog that is an owner of the focused Window.
  36. * <p>
  37. * The KeyboardFocusManager is both a centralized location for client code to
  38. * query for the focus owner and initiate focus changes, and an event
  39. * dispatcher for all FocusEvents, WindowEvents related to focus, and
  40. * KeyEvents.
  41. * <p>
  42. * Some browsers partition applets in different code bases into separate
  43. * contexts, and establish walls between these contexts. In such a scenario,
  44. * there will be one KeyboardFocusManager per context. Other browsers place all
  45. * applets into the same context, implying that there will be only a single,
  46. * global KeyboardFocusManager for all applets. This behavior is
  47. * implementation-dependent. Consult your browser's documentation for more
  48. * information. No matter how many contexts there may be, however, there can
  49. * never be more than one focus owner, focused Window, or active Window, per
  50. * ClassLoader.
  51. *
  52. * @author David Mendenhall
  53. * @version 1.40, 01/23/03
  54. *
  55. * @see Window
  56. * @see Frame
  57. * @see Dialog
  58. * @see java.awt.event.FocusEvent
  59. * @see java.awt.event.WindowEvent
  60. * @see java.awt.event.KeyEvent
  61. * @since 1.4
  62. */
  63. public abstract class KeyboardFocusManager
  64. implements KeyEventDispatcher, KeyEventPostProcessor
  65. {
  66. static {
  67. /* ensure that the necessary native libraries are loaded */
  68. Toolkit.loadLibraries();
  69. if (!GraphicsEnvironment.isHeadless()) {
  70. initIDs();
  71. }
  72. }
  73. /**
  74. * Initialize JNI field and method IDs
  75. */
  76. private static native void initIDs();
  77. private static final DebugHelper dbg =
  78. DebugHelper.create(KeyboardFocusManager.class);
  79. /**
  80. * The identifier for the Forward focus traversal keys.
  81. *
  82. * @see #setDefaultFocusTraversalKeys
  83. * @see #getDefaultFocusTraversalKeys
  84. * @see Component#setFocusTraversalKeys
  85. * @see Component#getFocusTraversalKeys
  86. */
  87. public static final int FORWARD_TRAVERSAL_KEYS = 0;
  88. /**
  89. * The identifier for the Backward focus traversal keys.
  90. *
  91. * @see #setDefaultFocusTraversalKeys
  92. * @see #getDefaultFocusTraversalKeys
  93. * @see Component#setFocusTraversalKeys
  94. * @see Component#getFocusTraversalKeys
  95. */
  96. public static final int BACKWARD_TRAVERSAL_KEYS = 1;
  97. /**
  98. * The identifier for the Up Cycle focus traversal keys.
  99. *
  100. * @see #setDefaultFocusTraversalKeys
  101. * @see #getDefaultFocusTraversalKeys
  102. * @see Component#setFocusTraversalKeys
  103. * @see Component#getFocusTraversalKeys
  104. */
  105. public static final int UP_CYCLE_TRAVERSAL_KEYS = 2;
  106. /**
  107. * The identifier for the Down Cycle focus traversal keys.
  108. *
  109. * @see #setDefaultFocusTraversalKeys
  110. * @see #getDefaultFocusTraversalKeys
  111. * @see Component#setFocusTraversalKeys
  112. * @see Component#getFocusTraversalKeys
  113. */
  114. public static final int DOWN_CYCLE_TRAVERSAL_KEYS = 3;
  115. static final int TRAVERSAL_KEY_LENGTH = DOWN_CYCLE_TRAVERSAL_KEYS + 1;
  116. /**
  117. * Returns the current KeyboardFocusManager instance for the calling
  118. * thread's context.
  119. *
  120. * @return this thread's context's KeyboardFocusManager
  121. * @see #setCurrentKeyboardFocusManager
  122. */
  123. public static KeyboardFocusManager getCurrentKeyboardFocusManager() {
  124. return getCurrentKeyboardFocusManager(AppContext.getAppContext());
  125. }
  126. synchronized static KeyboardFocusManager
  127. getCurrentKeyboardFocusManager(AppContext appcontext)
  128. {
  129. KeyboardFocusManager manager = (KeyboardFocusManager)
  130. appcontext.get(KeyboardFocusManager.class);
  131. if (manager == null) {
  132. manager = new DefaultKeyboardFocusManager();
  133. appcontext.put(KeyboardFocusManager.class, manager);
  134. }
  135. return manager;
  136. }
  137. /**
  138. * Sets the current KeyboardFocusManager instance for the calling thread's
  139. * context. If null is specified, then the current KeyboardFocusManager
  140. * is replaced with a new instance of DefaultKeyboardFocusManager.
  141. * <p>
  142. * If a SecurityManager is installed, the calling thread must be granted
  143. * the AWTPermission "replaceKeyboardFocusManager" in order to replace the
  144. * the current KeyboardFocusManager. If this permission is not granted,
  145. * this method will throw a SecurityException, and the current
  146. * KeyboardFocusManager will be unchanged.
  147. *
  148. * @param newManager the new KeyboardFocusManager for this thread's context
  149. * @see #getCurrentKeyboardFocusManager
  150. * @see DefaultKeyboardFocusManager
  151. * @throws SecurityException if the calling thread does not have permission
  152. * to replace the current KeyboardFocusManager
  153. */
  154. public synchronized static void setCurrentKeyboardFocusManager(
  155. KeyboardFocusManager newManager) throws SecurityException
  156. {
  157. AppContext appcontext = AppContext.getAppContext();
  158. if (newManager != null) {
  159. SecurityManager security = System.getSecurityManager();
  160. if (security != null) {
  161. if (replaceKeyboardFocusManagerPermission == null) {
  162. replaceKeyboardFocusManagerPermission =
  163. new AWTPermission("replaceKeyboardFocusManager");
  164. }
  165. security.
  166. checkPermission(replaceKeyboardFocusManagerPermission);
  167. }
  168. appcontext.put(KeyboardFocusManager.class, newManager);
  169. } else {
  170. appcontext.remove(KeyboardFocusManager.class);
  171. }
  172. }
  173. /**
  174. * The Component in an application that will typically receive all
  175. * KeyEvents generated by the user.
  176. */
  177. private static Component focusOwner;
  178. /**
  179. * The Component in an application that will regain focus when an
  180. * outstanding temporary focus transfer has completed, or the focus owner,
  181. * if no outstanding temporary transfer exists.
  182. */
  183. private static Component permanentFocusOwner;
  184. /**
  185. * The Window which is, or contains, the focus owner.
  186. */
  187. private static Window focusedWindow;
  188. /**
  189. * Only a Frame or a Dialog can be the active Window. The native windowing
  190. * system may denote the active Window with a special decoration, such as a
  191. * highlighted title bar. The active Window is always either the focused
  192. * Window, or the first Frame or Dialog which is an owner of the focused
  193. * Window.
  194. */
  195. private static Window activeWindow;
  196. /**
  197. * The default FocusTraversalPolicy for all Windows that have no policy of
  198. * their own set. If those Windows have focus-cycle-root children that have
  199. * no keyboard-traversal policy of their own, then those children will also
  200. * inherit this policy (as will, recursively, their focus-cycle-root
  201. * children).
  202. */
  203. private FocusTraversalPolicy defaultPolicy =
  204. new DefaultFocusTraversalPolicy();
  205. /**
  206. * The bound property names of each focus traversal key.
  207. */
  208. private static final String[] defaultFocusTraversalKeyPropertyNames = {
  209. "forwardDefaultFocusTraversalKeys",
  210. "backwardDefaultFocusTraversalKeys",
  211. "upCycleDefaultFocusTraversalKeys",
  212. "downCycleDefaultFocusTraversalKeys"
  213. };
  214. /**
  215. * The default Strings for initializing the default focus traversal keys.
  216. * Only used if default traversal keys are not set using Preferences API.
  217. */
  218. private static final String[] defaultFocusTraversalKeyStrings = {
  219. "TAB,ctrl TAB", "shift TAB,ctrl shift TAB", "", ""
  220. };
  221. /**
  222. * The default focus traversal keys. Each array of traversal keys will be
  223. * in effect on all Windows that have no such array of their own explicitly
  224. * set. Each array will also be inherited, recursively, by any child
  225. * Component of those Windows that has no such array of its own explicitly
  226. * set.
  227. */
  228. private Set[] defaultFocusTraversalKeys = new Set[4];
  229. /**
  230. * The current focus cycle root. If the focus owner is itself a focus cycle
  231. * root, then it may be ambiguous as to which Components represent the next
  232. * and previous Components to focus during normal focus traversal. In that
  233. * case, the current focus cycle root is used to differentiate among the
  234. * possibilities.
  235. */
  236. private static Container currentFocusCycleRoot;
  237. /**
  238. * A description of any VetoableChangeListeners which have been registered.
  239. */
  240. private VetoableChangeSupport vetoableSupport;
  241. /**
  242. * A description of any PropertyChangeListeners which have been registered.
  243. */
  244. private PropertyChangeSupport changeSupport;
  245. /**
  246. * This KeyboardFocusManager's KeyEventDispatcher chain. The List does not
  247. * include this KeyboardFocusManager unless it was explicitly re-registered
  248. * via a call to <code>addKeyEventDispatcher</code>. If no other
  249. * KeyEventDispatchers are registered, this field may be null or refer to
  250. * a List of length 0.
  251. */
  252. private java.util.LinkedList keyEventDispatchers;
  253. /**
  254. * This KeyboardFocusManager's KeyEventPostProcessor chain. The List does
  255. * not include this KeyboardFocusManager unless it was explicitly
  256. * re-registered via a call to <code>addKeyEventPostProcessor</code>.
  257. * If no other KeyEventPostProcessors are registered, this field may be
  258. * null or refer to a List of length 0.
  259. */
  260. private java.util.LinkedList keyEventPostProcessors;
  261. /**
  262. * Maps Windows to those Windows' most recent focus owners.
  263. */
  264. private static java.util.Map mostRecentFocusOwners = new WeakHashMap();
  265. /**
  266. * Error String for initializing SecurityExceptions.
  267. */
  268. private static final String notPrivileged = "this KeyboardFocusManager is not installed in the current thread's context";
  269. /**
  270. * We cache the permission used to verify that the calling thread is
  271. * permitted to access the global focus state.
  272. */
  273. private static AWTPermission replaceKeyboardFocusManagerPermission;
  274. /*
  275. * SequencedEvent which is currently dispatched in AppContext.
  276. */
  277. transient SequencedEvent currentSequencedEvent = null;
  278. final void setCurrentSequencedEvent(SequencedEvent current) {
  279. synchronized (SequencedEvent.class) {
  280. assert(current == null || currentSequencedEvent == null);
  281. currentSequencedEvent = current;
  282. }
  283. }
  284. final SequencedEvent getCurrentSequencedEvent() {
  285. synchronized (SequencedEvent.class) {
  286. return currentSequencedEvent;
  287. }
  288. }
  289. static Set initFocusTraversalKeysSet(String value, Set targetSet) {
  290. StringTokenizer tokens = new StringTokenizer(value, ",");
  291. while (tokens.hasMoreTokens()) {
  292. targetSet.add(AWTKeyStroke.getAWTKeyStroke(tokens.nextToken()));
  293. }
  294. return (targetSet.isEmpty())
  295. ? Collections.EMPTY_SET
  296. : Collections.unmodifiableSet(targetSet);
  297. }
  298. /**
  299. * Initializes a KeyboardFocusManager.
  300. */
  301. public KeyboardFocusManager() {
  302. for (int i = 0; i < TRAVERSAL_KEY_LENGTH; i++) {
  303. defaultFocusTraversalKeys[i] = initFocusTraversalKeysSet(
  304. defaultFocusTraversalKeyStrings[i], new HashSet());
  305. }
  306. }
  307. /**
  308. * Returns the focus owner, if the focus owner is in the same context as
  309. * the calling thread. The focus owner is defined as the Component in an
  310. * application that will typically receive all KeyEvents generated by the
  311. * user. KeyEvents which map to the focus owner's focus traversal keys will
  312. * not be delivered if focus traversal keys are enabled for the focus
  313. * owner. In addition, KeyEventDispatchers may retarget or consume
  314. * KeyEvents before they reach the focus owner.
  315. *
  316. * @return the focus owner, or null if the focus owner is not a member of
  317. * the calling thread's context
  318. * @see #getGlobalFocusOwner
  319. * @see #setGlobalFocusOwner
  320. */
  321. public Component getFocusOwner() {
  322. synchronized (KeyboardFocusManager.class) {
  323. if (focusOwner == null) {
  324. return null;
  325. }
  326. return (focusOwner.appContext == AppContext.getAppContext())
  327. ? focusOwner
  328. : null;
  329. }
  330. }
  331. /**
  332. * Returns the focus owner, even if the calling thread is in a different
  333. * context than the focus owner. The focus owner is defined as the
  334. * Component in an application that will typically receive all KeyEvents
  335. * generated by the user. KeyEvents which map to the focus owner's focus
  336. * traversal keys will not be delivered if focus traversal keys are enabled
  337. * for the focus owner. In addition, KeyEventDispatchers may retarget or
  338. * consume KeyEvents before they reach the focus owner.
  339. * <p>
  340. * This method will throw a SecurityException if this KeyboardFocusManager
  341. * is not the current KeyboardFocusManager for the calling thread's
  342. * context.
  343. *
  344. * @return the focus owner
  345. * @see #getFocusOwner
  346. * @see #setGlobalFocusOwner
  347. * @throws SecurityException if this KeyboardFocusManager is not the
  348. * current KeyboardFocusManager for the calling thread's context
  349. */
  350. protected Component getGlobalFocusOwner() throws SecurityException {
  351. synchronized (KeyboardFocusManager.class) {
  352. if (this == getCurrentKeyboardFocusManager()) {
  353. return focusOwner;
  354. } else {
  355. throw new SecurityException(notPrivileged);
  356. }
  357. }
  358. }
  359. /**
  360. * Sets the focus owner. The operation will be cancelled if the Component
  361. * is not focusable. The focus owner is defined as the Component in an
  362. * application that will typically receive all KeyEvents generated by the
  363. * user. KeyEvents which map to the focus owner's focus traversal keys will
  364. * not be delivered if focus traversal keys are enabled for the focus
  365. * owner. In addition, KeyEventDispatchers may retarget or consume
  366. * KeyEvents before they reach the focus owner.
  367. * <p>
  368. * This method does not actually set the focus to the specified Component.
  369. * It merely stores the value to be subsequently returned by
  370. * <code>getFocusOwner()</code>. Use <code>Component.requestFocus()</code>
  371. * or <code>Component.requestFocusInWindow()</code> to change the focus
  372. * owner, subject to platform limitations.
  373. *
  374. * @param focusOwner the focus owner
  375. * @see #getFocusOwner
  376. * @see #getGlobalFocusOwner
  377. * @see Component#requestFocus()
  378. * @see Component#requestFocusInWindow()
  379. * @see Component#isFocusable
  380. * @beaninfo
  381. * bound: true
  382. */
  383. protected void setGlobalFocusOwner(Component focusOwner) {
  384. Component oldFocusOwner = null;
  385. boolean shouldFire = false;
  386. if (focusOwner == null || focusOwner.isFocusable()) {
  387. synchronized (KeyboardFocusManager.class) {
  388. oldFocusOwner = getFocusOwner();
  389. try {
  390. fireVetoableChange("focusOwner", oldFocusOwner,
  391. focusOwner);
  392. } catch (PropertyVetoException e) {
  393. // rejected
  394. return;
  395. }
  396. KeyboardFocusManager.focusOwner = focusOwner;
  397. if (focusOwner != null &&
  398. (getCurrentFocusCycleRoot() == null ||
  399. !focusOwner.isFocusCycleRoot(getCurrentFocusCycleRoot())))
  400. {
  401. Container rootAncestor =
  402. focusOwner.getFocusCycleRootAncestor();
  403. if (rootAncestor == null && (focusOwner instanceof Window))
  404. {
  405. rootAncestor = (Container)focusOwner;
  406. }
  407. if (rootAncestor != null) {
  408. setGlobalCurrentFocusCycleRoot(rootAncestor);
  409. }
  410. }
  411. shouldFire = true;
  412. }
  413. }
  414. if (shouldFire) {
  415. firePropertyChange("focusOwner", oldFocusOwner, focusOwner);
  416. }
  417. }
  418. /**
  419. * Clears the global focus owner at both the Java and native levels. If
  420. * there exists a focus owner, that Component will receive a permanent
  421. * FOCUS_LOST event. After this operation completes, the native windowing
  422. * system will discard all user-generated KeyEvents until the user selects
  423. * a new Component to receive focus, or a Component is given focus
  424. * explicitly via a call to <code>requestFocus()</code>. This operation
  425. * does not change the focused or active Windows.
  426. *
  427. * @see Component#requestFocus()
  428. * @see java.awt.event.FocusEvent#FOCUS_LOST
  429. */
  430. public void clearGlobalFocusOwner() {
  431. if (!GraphicsEnvironment.isHeadless()) {
  432. // Toolkit must be fully initialized, otherwise
  433. // _clearGlobalFocusOwner will crash or throw an exception
  434. Toolkit.getDefaultToolkit();
  435. _clearGlobalFocusOwner();
  436. }
  437. }
  438. private native void _clearGlobalFocusOwner();
  439. static native Component getNativeFocusOwner();
  440. static native Window getNativeFocusedWindow();
  441. /**
  442. * Returns the permanent focus owner, if the permanent focus owner is in
  443. * the same context as the calling thread. The permanent focus owner is
  444. * defined as the last Component in an application to receive a permanent
  445. * FOCUS_GAINED event. The focus owner and permanent focus owner are
  446. * equivalent unless a temporary focus change is currently in effect. In
  447. * such a situation, the permanent focus owner will again be the focus
  448. * owner when the temporary focus change ends.
  449. *
  450. * @return the permanent focus owner, or null if the permanent focus owner
  451. * is not a member of the calling thread's context
  452. * @see #getGlobalPermanentFocusOwner
  453. * @see #setGlobalPermanentFocusOwner
  454. */
  455. public Component getPermanentFocusOwner() {
  456. synchronized (KeyboardFocusManager.class) {
  457. if (permanentFocusOwner == null) {
  458. return null;
  459. }
  460. return (permanentFocusOwner.appContext ==
  461. AppContext.getAppContext())
  462. ? permanentFocusOwner
  463. : null;
  464. }
  465. }
  466. /**
  467. * Returns the permanent focus owner, even if the calling thread is in a
  468. * different context than the permanent focus owner. The permanent focus
  469. * owner is defined as the last Component in an application to receive a
  470. * permanent FOCUS_GAINED event. The focus owner and permanent focus owner
  471. * are equivalent unless a temporary focus change is currently in effect.
  472. * In such a situation, the permanent focus owner will again be the focus
  473. * owner when the temporary focus change ends.
  474. * <p>
  475. * This method will throw a SecurityException if this KeyboardFocusManager
  476. * is not the current KeyboardFocusManager for the calling thread's
  477. * context.
  478. *
  479. * @return the permanent focus owner
  480. * @see #getPermanentFocusOwner
  481. * @see #setGlobalPermanentFocusOwner
  482. * @throws SecurityException if this KeyboardFocusManager is not the
  483. * current KeyboardFocusManager for the calling thread's context
  484. */
  485. protected Component getGlobalPermanentFocusOwner()
  486. throws SecurityException
  487. {
  488. synchronized (KeyboardFocusManager.class) {
  489. if (this == getCurrentKeyboardFocusManager()) {
  490. return permanentFocusOwner;
  491. } else {
  492. throw new SecurityException(notPrivileged);
  493. }
  494. }
  495. }
  496. /**
  497. * Sets the permanent focus owner. The operation will be cancelled if the
  498. * Component is not focusable. The permanent focus owner is defined as the
  499. * last Component in an application to receive a permanent FOCUS_GAINED
  500. * event. The focus owner and permanent focus owner are equivalent unless
  501. * a temporary focus change is currently in effect. In such a situation,
  502. * the permanent focus owner will again be the focus owner when the
  503. * temporary focus change ends.
  504. * <p>
  505. * This method does not actually set the focus to the specified Component.
  506. * It merely stores the value to be subsequently returned by
  507. * <code>getPermanentFocusOwner()</code>. Use
  508. * <code>Component.requestFocus()</code> or
  509. * <code>Component.requestFocusInWindow()</code> to change the focus owner,
  510. * subject to platform limitations.
  511. *
  512. * @param permanentFocusOwner the permanent focus owner
  513. * @see #getPermanentFocusOwner
  514. * @see #getGlobalPermanentFocusOwner
  515. * @see Component#requestFocus()
  516. * @see Component#requestFocusInWindow()
  517. * @see Component#isFocusable
  518. * @beaninfo
  519. * bound: true
  520. */
  521. protected void setGlobalPermanentFocusOwner(Component permanentFocusOwner)
  522. {
  523. Component oldPermanentFocusOwner = null;
  524. boolean shouldFire = false;
  525. if (permanentFocusOwner == null || permanentFocusOwner.isFocusable()) {
  526. synchronized (KeyboardFocusManager.class) {
  527. oldPermanentFocusOwner = getPermanentFocusOwner();
  528. try {
  529. fireVetoableChange("permanentFocusOwner",
  530. oldPermanentFocusOwner,
  531. permanentFocusOwner);
  532. } catch (PropertyVetoException e) {
  533. // rejected
  534. return;
  535. }
  536. KeyboardFocusManager.permanentFocusOwner = permanentFocusOwner;
  537. KeyboardFocusManager.
  538. setMostRecentFocusOwner(permanentFocusOwner);
  539. shouldFire = true;
  540. }
  541. }
  542. if (shouldFire) {
  543. firePropertyChange("permanentFocusOwner", oldPermanentFocusOwner,
  544. permanentFocusOwner);
  545. }
  546. }
  547. /**
  548. * Returns the focused Window, if the focused Window is in the same context
  549. * as the calling thread. The focused Window is the Window that is or
  550. * contains the focus owner.
  551. *
  552. * @return the focused Window, or null if the focused Window is not a
  553. * member of the calling thread's context
  554. * @see #getGlobalFocusedWindow
  555. * @see #setGlobalFocusedWindow
  556. */
  557. public Window getFocusedWindow() {
  558. synchronized (KeyboardFocusManager.class) {
  559. if (focusedWindow == null) {
  560. return null;
  561. }
  562. return (focusedWindow.appContext == AppContext.getAppContext())
  563. ? focusedWindow
  564. : null;
  565. }
  566. }
  567. /**
  568. * Returns the focused Window, even if the calling thread is in a different
  569. * context than the focused Window. The focused Window is the Window that
  570. * is or contains the focus owner.
  571. * <p>
  572. * This method will throw a SecurityException if this KeyboardFocusManager
  573. * is not the current KeyboardFocusManager for the calling thread's
  574. * context.
  575. *
  576. * @return the focused Window
  577. * @see #getFocusedWindow
  578. * @see #setGlobalFocusedWindow
  579. * @throws SecurityException if this KeyboardFocusManager is not the
  580. * current KeyboardFocusManager for the calling thread's context
  581. */
  582. protected Window getGlobalFocusedWindow() throws SecurityException {
  583. synchronized (KeyboardFocusManager.class) {
  584. if (this == getCurrentKeyboardFocusManager()) {
  585. return focusedWindow;
  586. } else {
  587. throw new SecurityException(notPrivileged);
  588. }
  589. }
  590. }
  591. /**
  592. * Sets the focused Window. The focused Window is the Window that is or
  593. * contains the focus owner. The operation will be cancelled if the
  594. * specified Window to focus is not a focusable Window.
  595. * <p>
  596. * This method does not actually change the focused Window as far as the
  597. * native windowing system is concerned. It merely stores the value to be
  598. * subsequently returned by <code>getFocusedWindow()</code>. Use
  599. * <code>Component.requestFocus()</code> or
  600. * <code>Component.requestFocusInWindow()</code> to change the focused
  601. * Window, subject to platform limitations.
  602. *
  603. * @param focusedWindow the focused Window
  604. * @see #getFocusedWindow
  605. * @see #getGlobalFocusedWindow
  606. * @see Component#requestFocus()
  607. * @see Component#requestFocusInWindow()
  608. * @see Window#isFocusableWindow
  609. * @beaninfo
  610. * bound: true
  611. */
  612. protected void setGlobalFocusedWindow(Window focusedWindow) {
  613. Window oldFocusedWindow = null;
  614. boolean shouldFire = false;
  615. if (focusedWindow == null || focusedWindow.isFocusableWindow()) {
  616. synchronized (KeyboardFocusManager.class) {
  617. oldFocusedWindow = getFocusedWindow();
  618. try {
  619. fireVetoableChange("focusedWindow", oldFocusedWindow,
  620. focusedWindow);
  621. } catch (PropertyVetoException e) {
  622. // rejected
  623. return;
  624. }
  625. KeyboardFocusManager.focusedWindow = focusedWindow;
  626. shouldFire = true;
  627. }
  628. }
  629. if (shouldFire) {
  630. firePropertyChange("focusedWindow", oldFocusedWindow,
  631. focusedWindow);
  632. }
  633. }
  634. /**
  635. * Returns the active Window, if the active Window is in the same context
  636. * as the calling thread. Only a Frame or a Dialog can be the active
  637. * Window. The native windowing system may denote the active Window or its
  638. * children with special decorations, such as a highlighted title bar.
  639. * The active Window is always either the focused Window, or the first
  640. * Frame or Dialog that is an owner of the focused Window.
  641. *
  642. * @return the active Window, or null if the active Window is not a member
  643. * of the calling thread's context
  644. * @see #getGlobalActiveWindow
  645. * @see #setGlobalActiveWindow
  646. */
  647. public Window getActiveWindow() {
  648. synchronized (KeyboardFocusManager.class) {
  649. if (activeWindow == null) {
  650. return null;
  651. }
  652. return (activeWindow.appContext == AppContext.getAppContext())
  653. ? activeWindow
  654. : null;
  655. }
  656. }
  657. /**
  658. * Returns the active Window, even if the calling thread is in a different
  659. * context than the active Window. Only a Frame or a Dialog can be the
  660. * active Window. The native windowing system may denote the active Window
  661. * or its children with special decorations, such as a highlighted title
  662. * bar. The active Window is always either the focused Window, or the first
  663. * Frame or Dialog that is an owner of the focused Window.
  664. * <p>
  665. * This method will throw a SecurityException if this KeyboardFocusManager
  666. * is not the current KeyboardFocusManager for the calling thread's
  667. * context.
  668. *
  669. * @return the active Window
  670. * @see #getActiveWindow
  671. * @see #setGlobalActiveWindow
  672. * @throws SecurityException if this KeyboardFocusManager is not the
  673. * current KeyboardFocusManager for the calling thread's context
  674. */
  675. protected Window getGlobalActiveWindow() throws SecurityException {
  676. synchronized (KeyboardFocusManager.class) {
  677. if (this == getCurrentKeyboardFocusManager()) {
  678. return activeWindow;
  679. } else {
  680. throw new SecurityException(notPrivileged);
  681. }
  682. }
  683. }
  684. /**
  685. * Sets the active Window. Only a Frame or a Dialog can be the active
  686. * Window. The native windowing system may denote the active Window or its
  687. * children with special decorations, such as a highlighted title bar. The
  688. * active Window is always either the focused Window, or the first Frame or
  689. * Dialog that is an owner of the focused Window.
  690. * <p>
  691. * This method does not actually change the active Window as far as the
  692. * native windowing system is concerned. It merely stores the value to be
  693. * subsequently returned by <code>getActiveWindow()</code>. Use
  694. * <code>Component.requestFocus()</code> or
  695. * <code>Component.requestFocusInWindow()</code>to change the active
  696. * Window, subject to platform limitations.
  697. *
  698. * @param activeWindow the active Window
  699. * @see #getActiveWindow
  700. * @see #getGlobalActiveWindow
  701. * @see Component#requestFocus()
  702. * @see Component#requestFocusInWindow()
  703. * @beaninfo
  704. * bound: true
  705. */
  706. protected void setGlobalActiveWindow(Window activeWindow) {
  707. Window oldActiveWindow;
  708. synchronized (KeyboardFocusManager.class) {
  709. oldActiveWindow = getActiveWindow();
  710. try {
  711. fireVetoableChange("activeWindow", oldActiveWindow,
  712. activeWindow);
  713. } catch (PropertyVetoException e) {
  714. // rejected
  715. return;
  716. }
  717. KeyboardFocusManager.activeWindow = activeWindow;
  718. }
  719. firePropertyChange("activeWindow", oldActiveWindow, activeWindow);
  720. }
  721. /**
  722. * Returns the default FocusTraversalPolicy. Top-level components
  723. * use this value on their creation to initialize their own focus traversal
  724. * policy by explicit call to Container.setFocusTraversalPolicy.
  725. *
  726. * @return the default FocusTraversalPolicy. null will never be returned.
  727. * @see #setDefaultFocusTraversalPolicy
  728. * @see Container#setFocusTraversalPolicy
  729. * @see Container#getFocusTraversalPolicy
  730. */
  731. public synchronized FocusTraversalPolicy getDefaultFocusTraversalPolicy() {
  732. return defaultPolicy;
  733. }
  734. /**
  735. * Sets the default FocusTraversalPolicy. Top-level components
  736. * use this value on their creation to initialize their own focus traversal
  737. * policy by explicit call to Container.setFocusTraversalPolicy.
  738. * Note: this call doesn't affect already created components as they have
  739. * their policy initialized. Only new components will use this policy as
  740. * their default policy.
  741. *
  742. * @param defaultPolicy the new, default FocusTraversalPolicy
  743. * @see #getDefaultFocusTraversalPolicy
  744. * @see Container#setFocusTraversalPolicy
  745. * @see Container#getFocusTraversalPolicy
  746. * @throws IllegalArgumentException if defaultPolicy is null
  747. * @beaninfo
  748. * bound: true
  749. */
  750. public void setDefaultFocusTraversalPolicy(FocusTraversalPolicy
  751. defaultPolicy) {
  752. if (defaultPolicy == null) {
  753. throw new IllegalArgumentException("default focus traversal policy cannot be null");
  754. }
  755. FocusTraversalPolicy oldPolicy;
  756. synchronized (this) {
  757. oldPolicy = this.defaultPolicy;
  758. this.defaultPolicy = defaultPolicy;
  759. }
  760. firePropertyChange("defaultFocusTraversalPolicy", oldPolicy,
  761. defaultPolicy);
  762. }
  763. /**
  764. * Sets the default focus traversal keys for a given traversal operation.
  765. * This traversal key <code>Set</code> will be in effect on all
  766. * <code>Window</code>s that have no such <code>Set</code> of
  767. * their own explicitly defined. This <code>Set</code> will also be
  768. * inherited, recursively, by any child <code>Component</code> of
  769. * those <code>Windows</code> that has
  770. * no such <code>Set</code> of its own explicitly defined.
  771. * <p>
  772. * The default values for the default focus traversal keys are
  773. * implementation-dependent. Sun recommends that all implementations for a
  774. * particular native platform use the same default values. The
  775. * recommendations for Windows and Unix are listed below. These
  776. * recommendations are used in the Sun AWT implementations.
  777. *
  778. * <table border=1 summary="Recommended default values for focus traversal keys">
  779. * <tr>
  780. * <th>Identifier</th>
  781. * <th>Meaning</th>
  782. * <th>Default</th>
  783. * </tr>
  784. * <tr>
  785. * <td><code>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</code></td>
  786. * <td>Normal forward keyboard traversal</td>
  787. * <td><code>TAB</code> on <code>KEY_PRESSED</code>,
  788. * <code>CTRL-TAB</code> on <code>KEY_PRESSED</code></td>
  789. * </tr>
  790. * <tr>
  791. * <td><code>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</code></td>
  792. * <td>Normal reverse keyboard traversal</td>
  793. * <td><code>SHIFT-TAB</code> on <code>KEY_PRESSED</code>,
  794. * <code>CTRL-SHIFT-TAB</code> on <code>KEY_PRESSED</code></td>
  795. * </tr>
  796. * <tr>
  797. * <td><code>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</code></td>
  798. * <td>Go up one focus traversal cycle</td>
  799. * <td>none</td>
  800. * </tr>
  801. * <tr>
  802. * <td><code>KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS</code></td>
  803. * <td>Go down one focus traversal cycle</td>
  804. * <td>none</td>
  805. * </tr>
  806. * </table>
  807. *
  808. * To disable a traversal key, use an empty <code>Set</code>
  809. * <code>Collections.EMPTY_SET</code> is recommended.
  810. * <p>
  811. * Using the <code>AWTKeyStroke</code> API, client code can
  812. * specify on which of two
  813. * specific <code>KeyEvent</code>s, <code>KEY_PRESSED</code> or
  814. * <code>KEY_RELEASED</code>, the focus traversal operation will
  815. * occur. Regardless of which <code>KeyEvent</code> is specified,
  816. * however, all <code>KeyEvent</code>s related to the focus
  817. * traversal key, including the associated <code>KEY_TYPED</code>
  818. * event, will be consumed, and will not be dispatched
  819. * to any <code>Component</code>. It is a runtime error to
  820. * specify a <code>KEY_TYPED</code> event as
  821. * mapping to a focus traversal operation, or to map the same event to
  822. * multiple default focus traversal operations.
  823. *
  824. * @param id one of
  825. * <code>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</code>,
  826. * <code>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</code>,
  827. * <code>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</code>, or
  828. * <code>KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS</code>
  829. * @param keystrokes the Set of <code>AWTKeyStroke</code>s for the
  830. * specified operation
  831. * @see #getDefaultFocusTraversalKeys
  832. * @see Component#setFocusTraversalKeys
  833. * @see Component#getFocusTraversalKeys
  834. * @throws IllegalArgumentException if id is not one of
  835. * <code>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</code>,
  836. * <code>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</code>,
  837. * <code>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</code>, or
  838. * <code>KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS</code>,
  839. * or if keystrokes is <code>null</code>,
  840. * or if keystrokes contains <code>null</code>,
  841. * or if any <code>Object</code> in
  842. * keystrokes is not an <code>AWTKeyStroke</code>,
  843. * or if any keystroke
  844. * represents a <code>KEY_TYPED</code> event,
  845. * or if any keystroke already maps
  846. * to another default focus traversal operation
  847. * @beaninfo
  848. * bound: true
  849. */
  850. public void setDefaultFocusTraversalKeys(int id, Set keystrokes)
  851. {
  852. if (id < 0 || id >= TRAVERSAL_KEY_LENGTH) {
  853. throw new IllegalArgumentException("invalid focus traversal key identifier");
  854. }
  855. if (keystrokes == null) {
  856. throw new IllegalArgumentException("cannot set null Set of default focus traversal keys");
  857. }
  858. Set oldKeys;
  859. synchronized (this) {
  860. for (Iterator iter = keystrokes.iterator(); iter.hasNext(); ) {
  861. Object obj = iter.next();
  862. if (obj == null) {
  863. throw new IllegalArgumentException("cannot set null focus traversal key");
  864. }
  865. // Generates a ClassCastException if the element is not an
  866. // AWTKeyStroke. This is desirable.
  867. AWTKeyStroke keystroke = (AWTKeyStroke)obj;
  868. if (keystroke.getKeyChar() != KeyEvent.CHAR_UNDEFINED) {
  869. throw new IllegalArgumentException("focus traversal keys cannot map to KEY_TYPED events");
  870. }
  871. // Check to see if key already maps to another traversal
  872. // operation
  873. for (int i = 0; i < TRAVERSAL_KEY_LENGTH; i++) {
  874. if (i == id) {
  875. continue;
  876. }
  877. if (defaultFocusTraversalKeys[i].contains(keystroke)) {
  878. throw new IllegalArgumentException("focus traversal keys must be unique for a Component");
  879. }
  880. }
  881. }
  882. oldKeys = defaultFocusTraversalKeys[id];
  883. defaultFocusTraversalKeys[id] =
  884. Collections.unmodifiableSet(new HashSet(keystrokes));
  885. }
  886. firePropertyChange(defaultFocusTraversalKeyPropertyNames[id],
  887. oldKeys, keystrokes);
  888. }
  889. /**
  890. * Returns a Set of default focus traversal keys for a given traversal
  891. * operation. This traversal key Set will be in effect on all Windows that
  892. * have no such Set of their own explicitly defined. This Set will also be
  893. * inherited, recursively, by any child Component of those Windows that has
  894. * no such Set of its own explicitly defined. (See
  895. * <code>setDefaultFocusTraversalKeys</code> for a full description of each
  896. * operation.)
  897. *
  898. * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
  899. * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
  900. * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
  901. * KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
  902. * @return the <code>Set</code> of <code>AWTKeyStroke</code>s
  903. * for the specified operation; the <code>Set</code>
  904. * will be unmodifiable, and may be empty; <code>null</code>
  905. * will never be returned
  906. * @see #setDefaultFocusTraversalKeys
  907. * @see Component#setFocusTraversalKeys
  908. * @see Component#getFocusTraversalKeys
  909. * @throws IllegalArgumentException if id is not one of
  910. * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
  911. * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
  912. * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
  913. * KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
  914. */
  915. public Set getDefaultFocusTraversalKeys(int id) {
  916. if (id < 0 || id >= TRAVERSAL_KEY_LENGTH) {
  917. throw new IllegalArgumentException("invalid focus traversal key identifier");
  918. }
  919. // Okay to return Set directly because it is an unmodifiable view
  920. return defaultFocusTraversalKeys[id];
  921. }
  922. /**
  923. * Returns the current focus cycle root, if the current focus cycle root is
  924. * in the same context as the calling thread. If the focus owner is itself
  925. * a focus cycle root, then it may be ambiguous as to which Components
  926. * represent the next and previous Components to focus during normal focus
  927. * traversal. In that case, the current focus cycle root is used to
  928. * differentiate among the possibilities.
  929. * <p>
  930. * This method is intended to be used only by KeyboardFocusManagers and
  931. * focus implementations. It is not for general client use.
  932. *
  933. * @return the current focus cycle root, or null if the current focus cycle
  934. * root is not a member of the calling thread's context
  935. * @see #getGlobalCurrentFocusCycleRoot
  936. * @see #setGlobalCurrentFocusCycleRoot
  937. */
  938. public Container getCurrentFocusCycleRoot() {
  939. synchronized (KeyboardFocusManager.class) {
  940. if (currentFocusCycleRoot == null) {
  941. return null;
  942. }
  943. return (currentFocusCycleRoot.appContext ==
  944. AppContext.getAppContext())
  945. ? currentFocusCycleRoot
  946. : null;
  947. }
  948. }
  949. /**
  950. * Returns the current focus cycle root, even if the calling thread is in a
  951. * different context than the current focus cycle root. If the focus owner
  952. * is itself a focus cycle root, then it may be ambiguous as to which
  953. * Components represent the next and previous Components to focus during
  954. * normal focus traversal. In that case, the current focus cycle root is
  955. * used to differentiate among the possibilities.
  956. * <p>
  957. * This method will throw a SecurityException if this KeyboardFocusManager
  958. * is not the current KeyboardFocusManager for the calling thread's
  959. * context.
  960. *
  961. * @return the current focus cycle root, or null if the current focus cycle
  962. * root is not a member of the calling thread's context
  963. * @see #getCurrentFocusCycleRoot
  964. * @see #setGlobalCurrentFocusCycleRoot
  965. * @throws SecurityException if this KeyboardFocusManager is not the
  966. * current KeyboardFocusManager for the calling thread's context
  967. */
  968. protected Container getGlobalCurrentFocusCycleRoot()
  969. throws SecurityException
  970. {
  971. synchronized (KeyboardFocusManager.class) {
  972. if (this == getCurrentKeyboardFocusManager()) {
  973. return currentFocusCycleRoot;
  974. } else {
  975. throw new SecurityException(notPrivileged);
  976. }
  977. }
  978. }
  979. /**
  980. * Sets the current focus cycle root. If the focus owner is itself a focus
  981. * cycle root, then it may be ambiguous as to which Components represent
  982. * the next and previous Components to focus during normal focus traversal.
  983. * In that case, the current focus cycle root is used to differentiate
  984. * among the possibilities.
  985. * <p>
  986. * This method is intended to be used only by KeyboardFocusManagers and
  987. * focus implementations. It is not for general client use.
  988. *
  989. * @param newFocusCycleRoot the new focus cycle root
  990. * @see #getCurrentFocusCycleRoot
  991. * @see #getGlobalCurrentFocusCycleRoot
  992. * @beaninfo
  993. * bound: true
  994. */
  995. public void setGlobalCurrentFocusCycleRoot(Container newFocusCycleRoot) {
  996. Container oldFocusCycleRoot;
  997. synchronized (KeyboardFocusManager.class) {
  998. oldFocusCycleRoot = getCurrentFocusCycleRoot();
  999. currentFocusCycleRoot = newFocusCycleRoot;
  1000. }
  1001. firePropertyChange("currentFocusCycleRoot", oldFocusCycleRoot,
  1002. newFocusCycleRoot);
  1003. }
  1004. /**
  1005. * Adds a PropertyChangeListener to the listener list. The listener is
  1006. * registered for all bound properties of this class, including the
  1007. * following:
  1008. * <ul>
  1009. * <li>the focus owner ("focusOwner")</li>
  1010. * <li>the permanent focus owner ("permanentFocusOwner")</li>
  1011. * <li>the focused Window ("focusedWindow")</li>
  1012. * <li>the active Window ("activeWindow")</li>
  1013. * <li>the default focus traversal policy
  1014. * ("defaultFocusTraversalPolicy")</li>
  1015. * <li>the Set of default FORWARD_TRAVERSAL_KEYS
  1016. * ("forwardDefaultFocusTraversalKeys")</li>
  1017. * <li>the Set of default BACKWARD_TRAVERSAL_KEYS
  1018. * ("backwardDefaultFocusTraversalKeys")</li>
  1019. * <li>the Set of default UP_CYCLE_TRAVERSAL_KEYS
  1020. * ("upCycleDefaultFocusTraversalKeys")</li>
  1021. * <li>the Set of default DOWN_CYCLE_TRAVERSAL_KEYS
  1022. * ("downCycleDefaultFocusTraversalKeys")</li>
  1023. * <li>the current focus cycle root ("currentFocusCycleRoot")</li>
  1024. * </ul>
  1025. * If listener is null, no exception is thrown and no action is performed.
  1026. *
  1027. * @param listener the PropertyChangeListener to be added
  1028. * @see #removePropertyChangeListener
  1029. * @see #getPropertyChangeListeners
  1030. * @see #addPropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
  1031. */
  1032. public void addPropertyChangeListener(PropertyChangeListener listener) {
  1033. if (listener != null) {
  1034. synchronized (this) {
  1035. if (changeSupport == null) {
  1036. changeSupport = new PropertyChangeSupport(this);
  1037. }
  1038. changeSupport.addPropertyChangeListener(listener);
  1039. }
  1040. }
  1041. }
  1042. /**
  1043. * Removes a PropertyChangeListener from the listener list. This method
  1044. * should be used to remove the PropertyChangeListeners that were
  1045. * registered for all bound properties of this class.
  1046. * <p>
  1047. * If listener is null, no exception is thrown and no action is performed.
  1048. *
  1049. * @param listener the PropertyChangeListener to be removed
  1050. * @see #addPropertyChangeListener
  1051. * @see #getPropertyChangeListeners
  1052. * @see #removePropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
  1053. */
  1054. public void removePropertyChangeListener(PropertyChangeListener listener) {
  1055. if (listener != null) {
  1056. synchronized (this) {
  1057. if (changeSupport != null) {
  1058. changeSupport.removePropertyChangeListener(listener);
  1059. }
  1060. }
  1061. }
  1062. }
  1063. /**
  1064. * Returns an array of all the property change listeners
  1065. * registered on this keyboard focus manager.
  1066. *
  1067. * @return all of this keyboard focus manager's
  1068. * <code>PropertyChangeListener</code>s
  1069. * or an empty array if no property change
  1070. * listeners are currently registered
  1071. *
  1072. * @see #addPropertyChangeListener
  1073. * @see #removePropertyChangeListener
  1074. * @see #getPropertyChangeListeners(java.lang.String)
  1075. * @since 1.4
  1076. */
  1077. public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
  1078. if (changeSupport == null) {
  1079. changeSupport = new PropertyChangeSupport(this);
  1080. }
  1081. return changeSupport.getPropertyChangeListeners();
  1082. }
  1083. /**
  1084. * Adds a PropertyChangeListener to the listener list for a specific
  1085. * property. The specified property may be user-defined, or one of the
  1086. * following:
  1087. * <ul>
  1088. * <li>the focus owner ("focusOwner")</li>
  1089. * <li>the permanent focus owner ("permanentFocusOwner")</li>
  1090. * <li>the focused Window ("focusedWindow")</li>
  1091. * <li>the active Window ("activeWindow")</li>
  1092. * <li>the default focus traversal policy
  1093. * ("defaultFocusTraversalPolicy")</li>
  1094. * <li>the Set of default FORWARD_TRAVERSAL_KEYS
  1095. * ("forwardDefaultFocusTraversalKeys")</li>
  1096. * <li>the Set of default BACKWARD_TRAVERSAL_KEYS
  1097. * ("backwardDefaultFocusTraversalKeys")</li>
  1098. * <li>the Set of default UP_CYCLE_TRAVERSAL_KEYS
  1099. * ("upCycleDefaultFocusTraversalKeys")</li>
  1100. * <li>the Set of default DOWN_CYCLE_TRAVERSAL_KEYS
  1101. * ("downCycleDefaultFocusTraversalKeys")</li>
  1102. * <li>the current focus cycle root ("currentFocusCycleRoot")</li>
  1103. * </ul>
  1104. * If listener is null, no exception is thrown and no action is performed.
  1105. *
  1106. * @param propertyName one of the property names listed above
  1107. * @param listener the PropertyChangeListener to be added
  1108. * @see #addPropertyChangeListener(java.beans.PropertyChangeListener)
  1109. * @see #removePropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
  1110. * @see #getPropertyChangeListeners(java.lang.String)
  1111. */
  1112. public void addPropertyChangeListener(String propertyName,
  1113. PropertyChangeListener listener) {
  1114. if (listener != null) {
  1115. synchronized (this) {
  1116. if (changeSupport == null) {
  1117. changeSupport = new PropertyChangeSupport(this);
  1118. }
  1119. changeSupport.addPropertyChangeListener(propertyName,
  1120. listener);
  1121. }
  1122. }
  1123. }
  1124. /**
  1125. * Removes a PropertyChangeListener from the listener list for a specific
  1126. * property. This method should be used to remove PropertyChangeListeners
  1127. * that were registered for a specific bound property.
  1128. * <p>
  1129. * If listener is null, no exception is thrown and no action is performed.
  1130. *
  1131. * @param propertyName a valid property name
  1132. * @param listener the PropertyChangeListener to be removed
  1133. * @see #addPropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
  1134. * @see #getPropertyChangeListeners(java.lang.String)
  1135. * @see #removePropertyChangeListener(java.beans.PropertyChangeListener)
  1136. */
  1137. public void removePropertyChangeListener(String propertyName,
  1138. PropertyChangeListener listener) {
  1139. if (listener != null) {
  1140. synchronized (this) {
  1141. if (changeSupport != null) {
  1142. changeSupport.removePropertyChangeListener(propertyName,
  1143. listener);
  1144. }
  1145. }
  1146. }
  1147. }
  1148. /**
  1149. * Returns an array of all the <code>PropertyChangeListener</code>s
  1150. * associated with the named property.
  1151. *
  1152. * @return all of the <code>PropertyChangeListener</code>s associated with
  1153. * the named property or an empty array if no such listeners have
  1154. * been added.
  1155. *
  1156. * @see #addPropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
  1157. * @see #removePropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
  1158. * @since 1.4
  1159. */
  1160. public synchronized PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
  1161. if (changeSupport == null) {
  1162. changeSupport = new PropertyChangeSupport(this);
  1163. }
  1164. return changeSupport.getPropertyChangeListeners(propertyName);
  1165. }
  1166. /**
  1167. * Fires a PropertyChangeEvent in response to a change in a bound property.
  1168. * The event will be delivered to all registered PropertyChangeListeners.
  1169. * No event will be delivered if oldValue and newValue are the same.
  1170. *
  1171. * @param propertyName the name of the property that has changed
  1172. * @param oldValue the property's previous value
  1173. * @param newValue the property's new value
  1174. */
  1175. protected void firePropertyChange(String propertyName, Object oldValue,
  1176. Object newValue) {
  1177. PropertyChangeSupport changeSupport = this.changeSupport;
  1178. if (changeSupport != null) {
  1179. changeSupport.firePropertyChange(propertyName, oldValue, newValue);
  1180. }
  1181. }
  1182. /**
  1183. * Adds a VetoableChangeListener to the listener list. The listener is
  1184. * registered for all vetoable properties of this class, including the
  1185. * following:
  1186. * <ul>
  1187. * <li>the focus owner ("focusOwner")</li>
  1188. * <li>the permanent focus owner ("permanentFocusOwner")</li>
  1189. * <li>the focused Window ("focusedWindow")</li>
  1190. * <li>the active Window ("activeWindow")</li>
  1191. * </ul>
  1192. * If listener is null, no exception is thrown and no action is performed.
  1193. *
  1194. * @param listener the VetoableChangeListener to be added
  1195. * @see #removeVetoableChangeListener
  1196. * @see #getVetoableChangeListeners
  1197. * @see #addVetoableChangeListener(java.lang.String,java.beans.VetoableChangeListener)
  1198. */
  1199. public void addVetoableChangeListener(VetoableChangeListener listener) {
  1200. if (listener != null) {
  1201. synchronized (this) {
  1202. if (vetoableSupport == null) {
  1203. vetoableSupport =
  1204. new VetoableChangeSupport(this);
  1205. }
  1206. vetoableSupport.addVetoableChangeListener(listener);
  1207. }
  1208. }
  1209. }
  1210. /**
  1211. * Removes a VetoableChangeListener from the listener list. This method
  1212. * should be used to remove the VetoableChangeListeners that were
  1213. * registered for all vetoable properties of this class.
  1214. * <p>
  1215. * If listener is null, no exception is thrown and no action is performed.
  1216. *
  1217. * @param listener the VetoableChangeListener to be removed
  1218. * @see #addVetoableChangeListener
  1219. * @see #getVetoableChangeListeners
  1220. * @see #removeVetoableChangeListener(java.lang.String,java.beans.VetoableChangeListener)
  1221. */
  1222. public void removeVetoableChangeListener(VetoableChangeListener listener) {
  1223. if (listener != null) {
  1224. synchronized (this) {
  1225. if (vetoableSupport != null) {
  1226. vetoableSupport.removeVetoableChangeListener(listener);
  1227. }
  1228. }
  1229. }
  1230. }
  1231. /**
  1232. * Returns an array of all the vetoable change listeners
  1233. * registered on this keyboard focus manager.
  1234. *
  1235. * @return all of this keyboard focus manager's
  1236. * <code>VetoableChangeListener</code>s
  1237. * or an empty array if no vetoable change
  1238. * listeners are currently registered
  1239. *
  1240. * @see #addVetoableChangeListener
  1241. * @see #removeVetoableChangeListener
  1242. * @see #getVetoableChangeListeners(java.lang.String)
  1243. * @since 1.4
  1244. */
  1245. public synchronized VetoableChangeListener[] getVetoableChangeListeners() {
  1246. if (vetoableSupport == null) {
  1247. vetoableSupport = new VetoableChangeSupport(this);
  1248. }
  1249. return vetoableSupport.getVetoableChangeListeners();
  1250. }
  1251. /**
  1252. * Adds a VetoableChangeListener to the listener list for a specific
  1253. * property. The specified property may be user-defined, or one of the
  1254. * following:
  1255. * <ul>
  1256. * <li>the focus owner ("focusOwner")</li>
  1257. * <li>the permanent focus owner ("permanentFocusOwner")</li>
  1258. * <li>the focused Window ("focusedWindow")</li>
  1259. * <li>the active Window ("activeWindow")</li>
  1260. * </ul>
  1261. * If listener is null, no exception is thrown and no action is performed.
  1262. *
  1263. * @param propertyName one of the property names listed above
  1264. * @param listener the VetoableChangeListener to be added
  1265. * @see #addVetoableChangeListener(java.beans.VetoableChangeListener)
  1266. * @see #removeVetoableChangeListener
  1267. * @see #getVetoableChangeListeners
  1268. */
  1269. public void addVetoableChangeListener(String propertyName,
  1270. VetoableChangeListener listener) {
  1271. if (listener != null) {
  1272. synchronized (this) {
  1273. if (vetoableSupport == null) {
  1274. vetoableSupport =
  1275. new VetoableChangeSupport(this);
  1276. }
  1277. vetoableSupport.addVetoableChangeListener(propertyName,
  1278. listener);
  1279. }
  1280. }
  1281. }
  1282. /**
  1283. * Removes a VetoableChangeListener from the listener list for a specific
  1284. * property. This method should be used to remove VetoableChangeListeners
  1285. * that were registered for a specific bound property.
  1286. * <p>
  1287. * If listener is null, no exception is thrown and no action is performed.
  1288. *
  1289. * @param propertyName a valid property name
  1290. * @param listener the VetoableChangeListener to be removed
  1291. * @see #addVetoableChangeListener
  1292. * @see #getVetoableChangeListeners
  1293. * @see #removeVetoableChangeListener(java.beans.VetoableChangeListener)
  1294. */
  1295. public void removeVetoableChangeListener(String propertyName,
  1296. VetoableChangeListener listener) {
  1297. if (listener != null) {
  1298. synchronized (this) {
  1299. if (vetoableSupport != null) {
  1300. vetoableSupport.removeVetoableChangeListener(propertyName,
  1301. listener);
  1302. }
  1303. }
  1304. }
  1305. }
  1306. /**
  1307. * Returns an array of all the <code>VetoableChangeListener</code>s
  1308. * associated with the named property.
  1309. *
  1310. * @return all of the <code>VetoableChangeListener</code>s associated with
  1311. * the named property or an empty array if no such listeners have
  1312. * been added.
  1313. *
  1314. * @see #addVetoableChangeListener(java.lang.String,java.beans.VetoableChangeListener)
  1315. * @see #removeVetoableChangeListener(java.lang.String,java.beans.VetoableChangeListener)
  1316. * @see #getVetoableChangeListeners
  1317. * @since 1.4
  1318. */
  1319. public synchronized VetoableChangeListener[] getVetoableChangeListeners(String propertyName) {
  1320. if (vetoableSupport == null) {
  1321. vetoableSupport = new VetoableChangeSupport(this);
  1322. }
  1323. return vetoableSupport.getVetoableChangeListeners(propertyName);
  1324. }
  1325. /**
  1326. * Fires a PropertyChangeEvent in response to a change in a vetoable
  1327. * property. The event will be delivered to all registered
  1328. * VetoableChangeListeners. If a VetoableChangeListener throws a
  1329. * PropertyVetoException, a new event is fired reverting all
  1330. * VetoableChangeListeners to the old value and the exception is then
  1331. * rethrown. No event will be delivered if oldValue and newValue are the
  1332. * same.
  1333. *
  1334. * @param propertyName the name of the property that has changed
  1335. * @param oldValue the property's previous value
  1336. * @param newValue the property's new value
  1337. * @throws java.beans.PropertyVetoException if a
  1338. * <code>VetoableChangeListener</code> threw
  1339. * <code>PropertyVetoException</code>
  1340. */
  1341. protected void fireVetoableChange(String propertyName, Object oldValue,
  1342. Object newValue)
  1343. throws PropertyVetoException
  1344. {
  1345. VetoableChangeSupport vetoableSupport =
  1346. this.vetoableSupport;
  1347. if (vetoableSupport != null) {
  1348. vetoableSupport.fireVetoableChange(propertyName, oldValue,
  1349. newValue);
  1350. }
  1351. }
  1352. /**
  1353. * Adds a KeyEventDispatcher to this KeyboardFocusManager's dispatcher
  1354. * chain. This KeyboardFocusManager will request that each
  1355. * KeyEventDispatcher dispatch KeyEvents gene