Source for java.awt.KeyboardFocusManager

   1: /* KeyboardFocusManager.java -- manage component focusing via the keyboard
   2:    Copyright (C) 2002, 2004  Free Software Foundation
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package java.awt;
  40: 
  41: import java.applet.Applet;
  42: import java.awt.event.FocusEvent;
  43: import java.awt.event.KeyEvent;
  44: import java.awt.event.WindowEvent;
  45: import java.beans.PropertyChangeListener;
  46: import java.beans.PropertyChangeSupport;
  47: import java.beans.PropertyVetoException;
  48: import java.beans.VetoableChangeListener;
  49: import java.beans.VetoableChangeSupport;
  50: import java.util.ArrayList;
  51: import java.util.Collection;
  52: import java.util.Collections;
  53: import java.util.HashMap;
  54: import java.util.HashSet;
  55: import java.util.Iterator;
  56: import java.util.List;
  57: import java.util.Map;
  58: import java.util.Set;
  59: 
  60: /**
  61:  * The <code>KeyboardFocusManager</code> handles the focusing of
  62:  * windows for receiving keyboard events.  The manager handles
  63:  * the dispatch of all <code>FocusEvent</code>s and
  64:  * <code>KeyEvent</code>s, along with <code>WindowEvent</code>s
  65:  * relating to the focused window.  Users can use the manager
  66:  * to ascertain the current focus owner and fire events.
  67:  * <br />
  68:  * <br />
  69:  * The focus owner is the <code>Component</code> that receives
  70:  * key events.  The focus owner is either the currently focused
  71:  * window or a component within this window.
  72:  * <br />
  73:  * <br />
  74:  * The underlying native windowing system may denote the active
  75:  * window or its children with special decorations (e.g. a highlighted
  76:  * title bar).  The active window is always either a <code>Frame</code>
  77:  * or <code>Dialog</code>, and is either the currently focused
  78:  * window or its owner.
  79:  * <br />
  80:  * <br />
  81:  * Applets may be partitioned into different applet contexts, according
  82:  * to their code base.  In this case, each context has its own
  83:  * <code>KeyboardFocusManager</code>, as opposed to the global
  84:  * manager maintained by applets which share the same context.
  85:  * Each context is insulated from the others, and they don't interact.
  86:  * The resulting behaviour, as with context division, depends on the browser
  87:  * supporting the applets.  Regardless, there can only ever be
  88:  * one focused window, one active window and one focus owner
  89:  * per <code>ClassLoader</code>.
  90:  * <br />
  91:  * <br />
  92:  * To support this separation of focus managers, the manager instances
  93:  * and the internal state information is grouped by the
  94:  * <code>ThreadGroup</code> to which it pertains.  With respect to
  95:  * applets, each code base has its own <code>ThreadGroup</code>, so the
  96:  * isolation of each context is enforced within the manager.
  97:  * <br />
  98:  * <br />
  99:  * By default, the manager defines TAB and Ctrl+TAB as the
 100:  * forward focus traversal keys and Shift+TAB and Ctrl+Shift+TAB
 101:  * as the backward focus traversal keys.  No up or down cycle
 102:  * traversal keys are defined by default.  Traversal takes effect
 103:  * on the firing of a relevant <code>KEY_PRESSED</code> event.
 104:  * However, all other key events related to the use of the
 105:  * defined focus traversal key sequence are consumed and not
 106:  * dispatched.
 107:  * <br />
 108:  * <br />
 109:  * These default traversal keys come into effect on all windows
 110:  * for which no alternative set of keys is defined.  This also
 111:  * applies recursively to any child components of such a window,
 112:  * which define no traversal keys of their own.
 113:  *
 114:  * @author Eric Blake (ebb9@email.byu.edu)
 115:  * @author Thomas Fitzsimmons (fitzsim@redhat.com)
 116:  * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 117:  * @since 1.4
 118:  */
 119: public abstract class KeyboardFocusManager
 120:   implements KeyEventDispatcher, KeyEventPostProcessor
 121: {
 122:   /** Identifies {@link AWTKeyStroke}s that move the focus forward in
 123:       the focus cycle. */
 124:   public static final int FORWARD_TRAVERSAL_KEYS = 0;
 125: 
 126:   /** Identifies {@link AWTKeyStroke}s that move the focus backward in
 127:       the focus cycle. */
 128:   public static final int BACKWARD_TRAVERSAL_KEYS = 1;
 129: 
 130:   /** Identifies {@link AWTKeyStroke}s that move the focus up to the
 131:       parent focus cycle root. */
 132:   public static final int UP_CYCLE_TRAVERSAL_KEYS = 2;
 133: 
 134:   /** Identifies {@link AWTKeyStroke}s that move the focus down to the
 135:       child focus cycle root. */
 136:   public static final int DOWN_CYCLE_TRAVERSAL_KEYS = 3;
 137: 
 138:   /** The set of {@link AWTKeyStroke}s that cause focus to be moved to
 139:       the next focusable Component in the focus cycle. */
 140:   private static final Set DEFAULT_FORWARD_KEYS;
 141: 
 142:   /** The set of {@link AWTKeyStroke}s that cause focus to be moved to
 143:       the previous focusable Component in the focus cycle. */
 144:   private static final Set DEFAULT_BACKWARD_KEYS;
 145: 
 146:   /** Populate the DEFAULT_FORWARD_KEYS and DEFAULT_BACKWARD_KEYS
 147:       {@link java.util.Set}s. */
 148:   static
 149:   {
 150:     Set s = new HashSet();
 151:     s.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, 0));
 152:     s.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB,
 153:                                        KeyEvent.CTRL_DOWN_MASK));
 154:     DEFAULT_FORWARD_KEYS = Collections.unmodifiableSet(s);
 155:     s = new HashSet();
 156:     s.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB,
 157:                                        KeyEvent.SHIFT_DOWN_MASK));
 158:     s.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB,
 159:                                        KeyEvent.SHIFT_DOWN_MASK
 160:                                        | KeyEvent.CTRL_DOWN_MASK));
 161:     DEFAULT_BACKWARD_KEYS = Collections.unmodifiableSet(s);
 162:   }
 163: 
 164:   /** The global object {@link java.util.Map}s. */
 165: 
 166:   /** For security reasons, {@link java.applet.Applet}s in different
 167:       codebases must be insulated from one another.  Since {@link
 168:       KeyboardFocusManager}s have the ability to return {@link
 169:       Component}s from a given {@link java.applet.Applet}, each
 170:       codebase must have an independent {@link KeyboardFocusManager}.
 171:       Since each codebase has its own {@link ThreadGroup} in which its
 172:       {@link Applet}s run, it makes sense to partition {@link
 173:       KeyboardFocusManager}s according to {@link
 174:       java.lang.ThreadGroup}.  Thus, currentKeyboardFocusManagers is a
 175:       {@link java.util.Map} keyed on {@link java.lang.ThreadGroup}. */
 176:   private static Map currentKeyboardFocusManagers = new HashMap ();
 177: 
 178:   /** {@link java.applet.Applet}s in one codebase must not be allowed
 179:       to access {@link Component}s in {@link java.applet.Applet}s in
 180:       other codebases.  To enforce this restriction, we key the
 181:       following {@link java.util.Map}s on {@link java.lang.ThreadGroup}s (which
 182:       are per-codebase).  For example, if {@link
 183:       java.lang.ThreadGroup} A calls {@link #setGlobalFocusOwner},
 184:       passing {@link Component} C, currentFocusOwners[A] is assigned
 185:       C, and all other currentFocusOwners values are nullified.  Then
 186:       if {@link java.lang.ThreadGroup} A subsequently calls {@link
 187:       #getGlobalFocusOwner}, it will return currentFocusOwners[A],
 188:       that is, {@link Component} C.  If another {@link
 189:       java.lang.ThreadGroup} K calls {@link #getGlobalFocusOwner}, it
 190:       will return currentFocusOwners[K], that is, null.
 191: 
 192:       Since this is a static field, we ensure that there is only one
 193:       focused {@link Component} per class loader. */
 194:   private static Map currentFocusOwners = new HashMap ();
 195: 
 196:   /** A {@link java.util.Map} keyed on {@link java.lang.ThreadGroup}s
 197:       that stores the {@link Component} that owns the permanent
 198:       keyboard focus. @see currentFocusOwners */
 199:   private static Map currentPermanentFocusOwners = new HashMap ();
 200: 
 201:   /** A {@link java.util.Map} keyed on {@link java.lang.ThreadGroup}s
 202:       that stores the focused {@link Window}. @see
 203:       currentFocusOwners */
 204:   private static Map currentFocusedWindows = new HashMap ();
 205: 
 206:   /** A {@link java.util.Map} keyed on {@link java.lang.ThreadGroup}s
 207:       that stores the active {@link Window}. @see
 208:       currentFocusOwners */
 209:   private static Map currentActiveWindows = new HashMap ();
 210: 
 211:   /** A {@link java.util.Map} keyed on {@link java.lang.ThreadGroup}s
 212:       that stores the focus cycle root {@link Container}. @see
 213:       currentFocusOwners */
 214:   private static Map currentFocusCycleRoots = new HashMap ();
 215: 
 216:   /** The default {@link FocusTraveralPolicy} that focus-managing
 217:       {@link Container}s will use to define their initial focus
 218:       traversal policy. */
 219:   private FocusTraversalPolicy defaultPolicy;
 220: 
 221:   /** An array that stores the {@link #FORWARD_TRAVERSAL_KEYS}, {@link
 222:       #BACKWARD_TRAVERSAL_KEYS}, {@link #UP_CYCLE_TRAVERSAL_KEYS} and
 223:       {@link #DOWN_CYCLE_TRAVERSAL_KEYS} {@link AWTKeyStroke}s {@link
 224:       java.util.Set}s. */
 225:   private Set[] defaultFocusKeys = new Set[]
 226:   {
 227:     DEFAULT_FORWARD_KEYS, DEFAULT_BACKWARD_KEYS,
 228:     Collections.EMPTY_SET, Collections.EMPTY_SET
 229:   };
 230: 
 231:   /**
 232:    * A utility class to support the handling of events relating to property changes.
 233:    */
 234:   private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport (this);
 235: 
 236:   /**
 237:    * A utility class to support the handling of events relating to vetoable changes.
 238:    */
 239:   private final VetoableChangeSupport vetoableChangeSupport = new VetoableChangeSupport (this);
 240: 
 241:   /** A list of {@link KeyEventDispatcher}s that process {@link
 242:       KeyEvent}s before they are processed the default keyboard focus
 243:       manager. */
 244:   private final ArrayList keyEventDispatchers = new ArrayList();
 245: 
 246:   /** A list of {@link KeyEventPostProcessor}s that process unconsumed
 247:       {@link KeyEvent}s. */
 248:   private final ArrayList keyEventPostProcessors = new ArrayList();
 249: 
 250:   /**
 251:    * Construct a KeyboardFocusManager.
 252:    */
 253:   public KeyboardFocusManager ()
 254:   {
 255:   }
 256: 
 257:   /**
 258:    * Retrieve the keyboard focus manager associated with the {@link
 259:    * java.lang.ThreadGroup} to which the calling thread belongs.
 260:    *
 261:    * @return the keyboard focus manager associated with the current
 262:    * thread group
 263:    */
 264:   public static KeyboardFocusManager getCurrentKeyboardFocusManager ()
 265:   {
 266:     ThreadGroup currentGroup = Thread.currentThread ().getThreadGroup ();
 267: 
 268:     if (currentKeyboardFocusManagers.get (currentGroup) == null)
 269:       setCurrentKeyboardFocusManager (null);
 270: 
 271:     return (KeyboardFocusManager) currentKeyboardFocusManagers.get (currentGroup);
 272:   }
 273: 
 274:   /**
 275:    * Set the keyboard focus manager associated with the {@link
 276:    * java.lang.ThreadGroup} to which the calling thread belongs.
 277:    *
 278:    * @param m the keyboard focus manager for the current thread group
 279:    */
 280:   public static void setCurrentKeyboardFocusManager (KeyboardFocusManager m)
 281:   {
 282:     SecurityManager sm = System.getSecurityManager ();
 283:     if (sm != null)
 284:       sm.checkPermission (new AWTPermission ("replaceKeyboardFocusManager"));
 285: 
 286:     ThreadGroup currentGroup = Thread.currentThread ().getThreadGroup ();
 287:     KeyboardFocusManager manager;
 288: 
 289:     if (m == null)
 290:       manager = createFocusManager();
 291:     else
 292:       manager = m;
 293: 
 294:     currentKeyboardFocusManagers.put (currentGroup, manager);
 295:   }
 296: 
 297:   /**
 298:    * Creates a KeyboardFocusManager. The exact class is determined by the
 299:    * system property 'gnu.java.awt.FocusManager'. If this is not set,
 300:    * we default to DefaultKeyboardFocusManager.
 301:    */
 302:   private static KeyboardFocusManager createFocusManager()
 303:   {
 304:     String fmClassName = System.getProperty("gnu.java.awt.FocusManager",
 305:                                        "java.awt.DefaultKeyboardFocusManager");
 306:     try
 307:       {
 308:         Class fmClass = Class.forName(fmClassName);
 309:         KeyboardFocusManager fm = (KeyboardFocusManager) fmClass.newInstance();
 310:         return fm;
 311:       }
 312:     catch (ClassNotFoundException ex)
 313:       {
 314:         System.err.println("The class " + fmClassName + " cannot be found.");
 315:         System.err.println("Check the setting of the system property");
 316:         System.err.println("gnu.java.awt.FocusManager");
 317:         return null;
 318:       }
 319:     catch (InstantiationException ex)
 320:       {
 321:         System.err.println("The class " + fmClassName + " cannot be");
 322:         System.err.println("instantiated.");
 323:         System.err.println("Check the setting of the system property");
 324:         System.err.println("gnu.java.awt.FocusManager");
 325:         return null;
 326:       }
 327:     catch (IllegalAccessException ex)
 328:       {
 329:         System.err.println("The class " + fmClassName + " cannot be");
 330:         System.err.println("accessed.");
 331:         System.err.println("Check the setting of the system property");
 332:         System.err.println("gnu.java.awt.FocusManager");
 333:         return null;
 334:       }
 335:   }
 336: 
 337:   /**
 338:    * Retrieve the {@link Component} that has the keyboard focus, or
 339:    * null if the focus owner was not set by a thread in the current
 340:    * {@link java.lang.ThreadGroup}.
 341:    *
 342:    * @return the keyboard focus owner or null
 343:    */
 344:   public Component getFocusOwner ()
 345:   {
 346:     Component owner = (Component) getObject (currentFocusOwners);
 347:     if (owner == null)
 348:       owner = (Component) getObject (currentPermanentFocusOwners);
 349:     return owner;
 350:   }
 351: 
 352:   /**
 353:    * Retrieve the {@link Component} that has the keyboard focus,
 354:    * regardless of whether or not it was set by a thread in the
 355:    * current {@link java.lang.ThreadGroup}.  If there is no temporary
 356:    * focus owner in effect then this method will return the same value
 357:    * as {@link #getGlobalPermanentFocusOwner}.
 358:    *
 359:    * @return the keyboard focus owner
 360:    * @throws SecurityException if this is not the keyboard focus
 361:    * manager associated with the current {@link java.lang.ThreadGroup}
 362:    */
 363:   protected Component getGlobalFocusOwner ()
 364:   {
 365:     // Check if there is a temporary focus owner.
 366:     Component focusOwner = (Component) getGlobalObject (currentFocusOwners);
 367: 
 368:     return (focusOwner == null) ? getGlobalPermanentFocusOwner () : focusOwner;
 369:   }
 370: 
 371:   /**
 372:    * Set the {@link Component} that will be returned by {@link
 373:    * #getFocusOwner} (when it is called from the current {@link
 374:    * java.lang.ThreadGroup}) and {@link #getGlobalFocusOwner}.  This
 375:    * method does not actually transfer the keyboard focus.
 376:    *
 377:    * @param owner the Component to return from getFocusOwner and
 378:    * getGlobalFocusOwner
 379:    *
 380:    * @see Component#requestFocus()
 381:    * @see Component#requestFocusInWindow()
 382:    */
 383:   protected void setGlobalFocusOwner (Component owner)
 384:   {
 385:     if (owner == null || owner.focusable)
 386:       setGlobalObject (currentFocusOwners, owner, "focusOwner");
 387:   }
 388: 
 389:   /**
 390:    * Clear the global focus owner and deliver a FOCUS_LOST event to
 391:    * the previously-focused {@link Component}.  Until another {@link
 392:    * Component} becomes the keyboard focus owner, key events will be
 393:    * discarded by top-level windows.
 394:    */
 395:   public void clearGlobalFocusOwner ()
 396:   {
 397:     synchronized (currentFocusOwners)
 398:       {
 399:         Component focusOwner = getGlobalFocusOwner ();
 400:         Component permanentFocusOwner = getGlobalPermanentFocusOwner ();
 401: 
 402:         setGlobalFocusOwner (null);
 403:         setGlobalPermanentFocusOwner (null);
 404: 
 405:         // Inform the old focus owner that it has lost permanent
 406:         // focus.
 407:         if (focusOwner != null)
 408:           {
 409:             // We can't cache the event queue, because of
 410:             // bootstrapping issues.  We need to set the default
 411:             // KeyboardFocusManager in EventQueue before the event
 412:             // queue is started.
 413:             EventQueue q = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
 414:             if (focusOwner != permanentFocusOwner)
 415:               q.postEvent (new FocusEvent (focusOwner, FocusEvent.FOCUS_LOST, true));
 416:             else
 417:               q.postEvent (new FocusEvent (focusOwner, FocusEvent.FOCUS_LOST, false));
 418:           }
 419: 
 420:         if (focusOwner != permanentFocusOwner)
 421:           {
 422:             EventQueue q = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
 423:             q.postEvent (new FocusEvent (permanentFocusOwner, FocusEvent.FOCUS_LOST, false));
 424:           }
 425:       }
 426:   }
 427: 
 428:   /**
 429:    * Retrieve the {@link Component} that has the permanent keyboard
 430:    * focus, or null if the focus owner was not set by a thread in the
 431:    * current {@link java.lang.ThreadGroup}.
 432:    *
 433:    * @return the keyboard focus owner or null
 434:    */
 435:   public Component getPermanentFocusOwner ()
 436:   {
 437:     return (Component) getObject (currentPermanentFocusOwners);
 438:   }
 439: 
 440:   /**
 441:    * Retrieve the {@link Component} that has the permanent keyboard
 442:    * focus, regardless of whether or not it was set by a thread in the
 443:    * current {@link java.lang.ThreadGroup}.
 444:    *
 445:    * @return the keyboard focus owner
 446:    * @throws SecurityException if this is not the keyboard focus
 447:    * manager associated with the current {@link java.lang.ThreadGroup}
 448:    */
 449:   protected Component getGlobalPermanentFocusOwner ()
 450:   {
 451:     return (Component) getGlobalObject (currentPermanentFocusOwners);
 452:   }
 453: 
 454:   /**
 455:    * Set the {@link Component} that will be returned by {@link
 456:    * #getPermanentFocusOwner} (when it is called from the current
 457:    * {@link java.lang.ThreadGroup}) and {@link
 458:    * #getGlobalPermanentFocusOwner}.  This method does not actually
 459:    * transfer the keyboard focus.
 460:    *
 461:    * @param focusOwner the Component to return from
 462:    * getPermanentFocusOwner and getGlobalPermanentFocusOwner
 463:    *
 464:    * @see Component#requestFocus()
 465:    * @see Component#requestFocusInWindow()
 466:    */
 467:   protected void setGlobalPermanentFocusOwner (Component focusOwner)
 468:   {
 469:     if (focusOwner == null || focusOwner.focusable)
 470:       setGlobalObject (currentPermanentFocusOwners, focusOwner,
 471:                "permanentFocusOwner");
 472:   }
 473: 
 474:   /**
 475:    * Retrieve the {@link Window} that is or contains the keyboard
 476:    * focus owner, or null if the focused window was not set by a
 477:    * thread in the current {@link java.lang.ThreadGroup}.
 478:    *
 479:    * @return the focused window or null
 480:    */
 481:   public Window getFocusedWindow ()
 482:   {
 483:     return (Window) getObject (currentFocusedWindows);
 484:   }
 485: 
 486:   /**
 487:    * Retrieve the {@link Window} that is or contains the focus owner,
 488:    * regardless of whether or not the {@link Window} was set focused
 489:    * by a thread in the current {@link java.lang.ThreadGroup}.
 490:    *
 491:    * @return the focused window
 492:    * @throws SecurityException if this is not the keyboard focus
 493:    * manager associated with the current {@link java.lang.ThreadGroup}
 494:    */
 495:   protected Window getGlobalFocusedWindow ()
 496:   {
 497:     return (Window) getGlobalObject (currentFocusedWindows);
 498:   }
 499: 
 500:   /**
 501:    * Set the {@link Window} that will be returned by {@link
 502:    * #getFocusedWindow} (when it is called from the current {@link
 503:    * java.lang.ThreadGroup}) and {@link #getGlobalFocusedWindow}.
 504:    * This method does not actually cause <code>window</code> to become
 505:    * the focused {@link Window}.
 506:    *
 507:    * @param window the Window to return from getFocusedWindow and
 508:    * getGlobalFocusedWindow
 509:    */
 510:   protected void setGlobalFocusedWindow (Window window)
 511:   {
 512:     if (window == null || window.focusable)
 513:       setGlobalObject (currentFocusedWindows, window, "focusedWindow");
 514:   }
 515: 
 516:   /**
 517:    * Retrieve the active {@link Window}, or null if the active window
 518:    * was not set by a thread in the current {@link
 519:    * java.lang.ThreadGroup}.
 520:    *
 521:    * @return the active window or null
 522:    */
 523:   public Window getActiveWindow()
 524:   {
 525:     return (Window) getObject (currentActiveWindows);
 526:   }
 527: 
 528:   /**
 529:    * Retrieve the active {@link Window}, regardless of whether or not
 530:    * the {@link Window} was made active by a thread in the current
 531:    * {@link java.lang.ThreadGroup}.
 532:    *
 533:    * @return the active window
 534:    * @throws SecurityException if this is not the keyboard focus
 535:    * manager associated with the current {@link java.lang.ThreadGroup}
 536:    */
 537:   protected Window getGlobalActiveWindow()
 538:   {
 539:     return (Window) getGlobalObject (currentActiveWindows);
 540:   }
 541: 
 542:   /**
 543:    * Set the {@link Window} that will be returned by {@link
 544:    * #getActiveWindow} (when it is called from the current {@link
 545:    * java.lang.ThreadGroup}) and {@link #getGlobalActiveWindow}.  This
 546:    * method does not actually cause <code>window</code> to be made
 547:    * active.
 548:    *
 549:    * @param window the Window to return from getActiveWindow and
 550:    * getGlobalActiveWindow
 551:    */
 552:   protected void setGlobalActiveWindow(Window window)
 553:   {
 554:     setGlobalObject (currentActiveWindows, window, "activeWindow");
 555:   }
 556: 
 557:   /**
 558:    * Retrieve the default {@link FocusTraversalPolicy}.
 559:    * Focus-managing {@link Container}s use the returned object to
 560:    * define their initial focus traversal policy.
 561:    *
 562:    * @return a non-null default FocusTraversalPolicy object
 563:    */
 564:   public FocusTraversalPolicy getDefaultFocusTraversalPolicy ()
 565:   {
 566:     if (defaultPolicy == null)
 567:       defaultPolicy = new DefaultFocusTraversalPolicy ();
 568:     return defaultPolicy;
 569:   }
 570: 
 571:   /**
 572:    * Set the {@link FocusTraversalPolicy} returned by {@link
 573:    * #getDefaultFocusTraversalPolicy}.  Focus-managing {@link
 574:    * Container}s created after this call will use policy as their
 575:    * initial focus traversal policy.  Existing {@link Container}s'
 576:    * focus traversal policies will not be affected by calls to this
 577:    * method.
 578:    *
 579:    * @param policy the FocusTraversalPolicy that will be returned by
 580:    * subsequent calls to getDefaultFocusTraversalPolicy
 581:    * @throws IllegalArgumentException if policy is null
 582:    */
 583:   public void setDefaultFocusTraversalPolicy (FocusTraversalPolicy policy)
 584:   {
 585:     if (policy == null)
 586:       throw new IllegalArgumentException ();
 587:     firePropertyChange ("defaultFocusTraversalPolicy", defaultPolicy, policy);
 588:     defaultPolicy = policy;
 589:   }
 590: 
 591:   /**
 592:    * Set the default {@link java.util.Set} of focus traversal keys for
 593:    * one of the focus traversal directions.
 594:    *
 595:    * @param id focus traversal direction identifier
 596:    * @param keystrokes set of AWTKeyStrokes
 597:    *
 598:    * @see #FORWARD_TRAVERSAL_KEYS
 599:    * @see #BACKWARD_TRAVERSAL_KEYS
 600:    * @see #UP_CYCLE_TRAVERSAL_KEYS
 601:    * @see #DOWN_CYCLE_TRAVERSAL_KEYS
 602:    */
 603:   public void setDefaultFocusTraversalKeys (int id, Set keystrokes)
 604:   {
 605:     if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
 606:         id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
 607:         id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS &&
 608:         id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS)
 609:       throw new IllegalArgumentException ();
 610: 
 611:     if (keystrokes == null)
 612:       throw new IllegalArgumentException ();
 613: 
 614:     Set sa;
 615:     Set sb;
 616:     Set sc;
 617:     String type;
 618:     switch (id)
 619:       {
 620:       case FORWARD_TRAVERSAL_KEYS:
 621:         sa = defaultFocusKeys[BACKWARD_TRAVERSAL_KEYS];
 622:         sb = defaultFocusKeys[UP_CYCLE_TRAVERSAL_KEYS];
 623:         sc = defaultFocusKeys[DOWN_CYCLE_TRAVERSAL_KEYS];
 624:         type = "forwardDefaultFocusTraversalKeys";
 625:         break;
 626:       case BACKWARD_TRAVERSAL_KEYS:
 627:         sa = defaultFocusKeys[FORWARD_TRAVERSAL_KEYS];
 628:         sb = defaultFocusKeys[UP_CYCLE_TRAVERSAL_KEYS];
 629:         sc = defaultFocusKeys[DOWN_CYCLE_TRAVERSAL_KEYS];
 630:         type = "backwardDefaultFocusTraversalKeys";
 631:         break;
 632:       case UP_CYCLE_TRAVERSAL_KEYS:
 633:         sa = defaultFocusKeys[FORWARD_TRAVERSAL_KEYS];
 634:         sb = defaultFocusKeys[BACKWARD_TRAVERSAL_KEYS];
 635:         sc = defaultFocusKeys[DOWN_CYCLE_TRAVERSAL_KEYS];
 636:         type = "upCycleDefaultFocusTraversalKeys";
 637:         break;
 638:       case DOWN_CYCLE_TRAVERSAL_KEYS:
 639:         sa = defaultFocusKeys[FORWARD_TRAVERSAL_KEYS];
 640:         sb = defaultFocusKeys[BACKWARD_TRAVERSAL_KEYS];
 641:         sc = defaultFocusKeys[UP_CYCLE_TRAVERSAL_KEYS];
 642:         type = "downCycleDefaultFocusTraversalKeys";
 643:         break;
 644:       default:
 645:         throw new IllegalArgumentException ();
 646:       }
 647:     int i = keystrokes.size ();
 648:     Iterator iter = keystrokes.iterator ();
 649:     while (--i >= 0)
 650:       {
 651:         Object o = iter.next ();
 652:         if (!(o instanceof AWTKeyStroke)
 653:             || sa.contains (o) || sb.contains (o) || sc.contains (o)
 654:             || ((AWTKeyStroke) o).keyCode == KeyEvent.VK_UNDEFINED)
 655:           throw new IllegalArgumentException ();
 656:       }
 657:     keystrokes = Collections.unmodifiableSet (new HashSet (keystrokes));
 658:     firePropertyChange (type, defaultFocusKeys[id], keystrokes);
 659:     defaultFocusKeys[id] = keystrokes;
 660:   }
 661: 
 662:   /**
 663:    * Retrieve the default {@link java.util.Set} of focus traversal
 664:    * keys for one of the focus traversal directions.
 665:    *
 666:    * @param id focus traversal direction identifier
 667:    *
 668:    * @return the default set of AWTKeyStrokes
 669:    *
 670:    * @see #FORWARD_TRAVERSAL_KEYS
 671:    * @see #BACKWARD_TRAVERSAL_KEYS
 672:    * @see #UP_CYCLE_TRAVERSAL_KEYS
 673:    * @see #DOWN_CYCLE_TRAVERSAL_KEYS
 674:    */
 675:   public Set getDefaultFocusTraversalKeys (int id)
 676:   {
 677:     if (id < FORWARD_TRAVERSAL_KEYS || id > DOWN_CYCLE_TRAVERSAL_KEYS)
 678:       throw new IllegalArgumentException ();
 679:     return defaultFocusKeys[id];
 680:   }
 681: 
 682:   /**
 683:    * Retrieve the current focus cycle root, or null if the focus owner
 684:    * was not set by a thread in the current {@link
 685:    * java.lang.ThreadGroup}.
 686:    *
 687:    * @return the current focus cycle root or null
 688:    */
 689:   public Container getCurrentFocusCycleRoot ()
 690:   {
 691:     return (Container) getObject (currentFocusCycleRoots);
 692:   }
 693: 
 694:   /**
 695:    * Retrieve the current focus cycle root, regardless of whether or
 696:    * not it was made set by a thread in the current {@link
 697:    * java.lang.ThreadGroup}.
 698:    *
 699:    * @return the current focus cycle root
 700:    * @throws SecurityException if this is not the keyboard focus
 701:    * manager associated with the current {@link java.lang.ThreadGroup}
 702:    */
 703:   protected Container getGlobalCurrentFocusCycleRoot ()
 704:   {
 705:     return (Container) getGlobalObject (currentFocusCycleRoots);
 706:   }
 707: 
 708:   /**
 709:    * Set the {@link Container} that will be returned by {@link
 710:    * #getCurrentFocusCycleRoot} (when it is called from the current
 711:    * {@link java.lang.ThreadGroup}) and {@link
 712:    * #getGlobalCurrentFocusCycleRoot}.  This method does not actually
 713:    * make <code>cycleRoot</code> the current focus cycle root.
 714:    * 
 715:    * @param cycleRoot the focus cycle root to return from
 716:    * getCurrentFocusCycleRoot and getGlobalCurrentFocusCycleRoot
 717:    */
 718:   public void setGlobalCurrentFocusCycleRoot (Container cycleRoot)
 719:   {
 720:     setGlobalObject (currentFocusCycleRoots, cycleRoot, "currentFocusCycleRoot");
 721:   }
 722: 
 723:   /**
 724:    * Registers the supplied property change listener for receiving
 725:    * events caused by the following property changes:
 726:    *
 727:    * <ul>
 728:    * <li>the current focus owner ("focusOwner")</li>
 729:    * <li>the permanent focus owner ("permanentFocusOwner")</li>
 730:    * <li>the focused window ("focusedWindow")</li>
 731:    * <li>the active window ("activeWindow")</li>
 732:    * <li>the default focus traversal policy ("defaultFocusTraversalPolicy")</li>
 733:    * <li>the default set of forward traversal keys ("forwardDefaultFocusTraversalKeys")</li>
 734:    * <li>the default set of backward traversal keys ("backwardDefaultFocusTraversalKeys")</li>
 735:    * <li>the default set of up cycle traversal keys ("upCycleDefaultFocusTraversalKeys")</li>
 736:    * <li>the default set of down cycle traversal keys ("downCycleDefaultFocusTraversalKeys")</li>
 737:    * <li>the current focus cycle root ("currentFocusCycleRoot")</li>
 738:    * </ul>
 739:    *
 740:    * If the supplied listener is null, nothing occurs.
 741:    *
 742:    * @param l the new listener to register.
 743:    * @see KeyboardFocusManager#addPropertyChangeListener(String, java.beans.PropertyChangeListener)
 744:    */
 745:   public void addPropertyChangeListener(PropertyChangeListener l)
 746:   {
 747:     if (l != null)
 748:       propertyChangeSupport.addPropertyChangeListener(l);
 749:   }
 750: 
 751:   /**
 752:    * Removes the supplied property change listener from the list
 753:    * of registered listeners.  If the supplied listener is null,
 754:    * nothing occurs.
 755:    *
 756:    * @param l the listener to remove.
 757:    */
 758:   public void removePropertyChangeListener(PropertyChangeListener l)
 759:   {
 760:     if (l != null)
 761:       propertyChangeSupport.removePropertyChangeListener(l);
 762:   }
 763: 
 764:   /**
 765:    * Returns the currently registered property change listeners
 766:    * in array form.  The returned array is empty if no listeners are
 767:    * currently registered.
 768:    *
 769:    * @return an array of registered property change listeners.
 770:    */
 771:   public PropertyChangeListener[] getPropertyChangeListeners()
 772:   {
 773:     return propertyChangeSupport.getPropertyChangeListeners();
 774:   }
 775: 
 776:   /**
 777:    * Registers a property change listener for receiving events relating
 778:    * to a change to a specified property.  The supplied property name can be
 779:    * either user-defined or one from the following list of properties
 780:    * relevant to this class:
 781:    *
 782:    * <ul>
 783:    * <li>the current focus owner ("focusOwner")</li>
 784:    * <li>the permanent focus owner ("permanentFocusOwner")</li>
 785:    * <li>the focused window ("focusedWindow")</li>
 786:    * <li>the active window ("activeWindow")</li>
 787:    * <li>the default focus traversal policy ("defaultFocusTraversalPolicy")</li>
 788:    * <li>the default set of forward traversal keys ("forwardDefaultFocusTraversalKeys")</li>
 789:    * <li>the default set of backward traversal keys ("backwardDefaultFocusTraversalKeys")</li>
 790:    * <li>the default set of up cycle traversal keys ("upCycleDefaultFocusTraversalKeys")</li>
 791:    * <li>the default set of down cycle traversal keys ("downCycleDefaultFocusTraversalKeys")</li>
 792:    * <li>the current focus cycle root ("currentFocusCycleRoot")</li>
 793:    * </ul>
 794:    *
 795:    * Nothing occurs if a null listener is supplied.  null is regarded as a valid property name.
 796:    *
 797:    * @param name the name of the property to handle change events for.
 798:    * @param l the listener to register for changes to the specified property. 
 799:    * @see KeyboardFocusManager#addPropertyChangeListener(java.beans.PropertyChangeListener)
 800:    */
 801:   public void addPropertyChangeListener(String name, PropertyChangeListener l)
 802:   {
 803:     if (l != null)
 804:       propertyChangeSupport.addPropertyChangeListener(name, l);
 805:   }
 806: 
 807:   /**
 808:    * Removes the supplied property change listener registered for the
 809:    * specified property from the list of registered listeners.  If the
 810:    * supplied listener is null, nothing occurs.
 811:    *
 812:    * @param name the name of the property the listener is
 813:    *        monitoring changes to.
 814:    * @param l the listener to remove.
 815:    */
 816:   public void removePropertyChangeListener(String name,
 817:                                            PropertyChangeListener l)
 818:   {
 819:     if (l != null)
 820:       propertyChangeSupport.removePropertyChangeListener(name, l);
 821:   }
 822: 
 823:   /**
 824:    * Returns the currently registered property change listeners
 825:    * in array form, which listen for changes to the supplied property.
 826:    * The returned array is empty, if no listeners are currently registered
 827:    * for events pertaining to the supplied property.
 828:    *
 829:    * @param name The property the returned listeners monitor for changes.
 830:    * @return an array of registered property change listeners which
 831:    *         listen for changes to the supplied property.
 832:    */
 833:   public PropertyChangeListener[] getPropertyChangeListeners(String name)
 834:   {
 835:     return propertyChangeSupport.getPropertyChangeListeners(name);
 836:   }
 837: 
 838:   /**
 839:    * Fires a property change event as a response to a change to
 840:    * to the specified property.  The event is only fired if a
 841:    * change has actually occurred (i.e. o and n are different).
 842:    *
 843:    * @param name The name of the property to which a change occurred.
 844:    * @param o The old value of the property.
 845:    * @param n The new value of the property.
 846:    */
 847:   protected void firePropertyChange(String name, Object o, Object n)
 848:   {
 849:     propertyChangeSupport.firePropertyChange(name, o, n);
 850:   }
 851: 
 852:   /**
 853:    * Registers a vetoable property change listener for receiving events
 854:    * relating to the following properties:
 855:    *
 856:    * <ul>
 857:    * <li>the current focus owner ("focusOwner")</li>
 858:    * <li>the permanent focus owner ("permanentFocusOwner")</li>
 859:    * <li>the focused window ("focusedWindow")</li>
 860:    * <li>the active window ("activeWindow")</li>
 861:    * </ul>
 862:    *
 863:    * Nothing occurs if a null listener is supplied.
 864:    *
 865:    * @param l the listener to register. 
 866:    * @see KeyboardFocusManager#addVetoableChangeListener(String, java.beans.VetoableChangeListener)
 867:    */
 868:   public void addVetoableChangeListener(VetoableChangeListener l)
 869:   {
 870:     if (l != null)
 871:       vetoableChangeSupport.addVetoableChangeListener(l);
 872:   }
 873: 
 874:   /**
 875:    * Removes the supplied vetoable property change listener from
 876:    * the list of registered listeners.  If the supplied listener
 877:    * is null, nothing occurs.
 878:    *
 879:    * @param l the listener to remove.
 880:    */
 881:   public void removeVetoableChangeListener(VetoableChangeListener l)
 882:   {
 883:     if (l != null)
 884:       vetoableChangeSupport.removeVetoableChangeListener(l);
 885:   }
 886: 
 887:   /**
 888:    * Returns the currently registered vetoable property change listeners
 889:    * in array form.  The returned array is empty if no listeners are
 890:    * currently registered.
 891:    *
 892:    * @return an array of registered vetoable property change listeners.
 893:    * @since 1.4
 894:    */
 895:   public VetoableChangeListener[] getVetoableChangeListeners()
 896:   {
 897:     return vetoableChangeSupport.getVetoableChangeListeners();
 898:   }
 899: 
 900:   /**
 901:    * Registers a vetoable property change listener for receiving events relating
 902:    * to a vetoable change to a specified property.  The supplied property name can be
 903:    * either user-defined or one from the following list of properties
 904:    * relevant to this class:
 905:    *
 906:    * <ul>
 907:    * <li>the current focus owner ("focusOwner")</li>
 908:    * <li>the permanent focus owner ("permanentFocusOwner")</li>
 909:    * <li>the focused window ("focusedWindow")</li>
 910:    * <li>the active window ("activeWindow")</li>
 911:    * </ul>
 912:    *
 913:    * Nothing occurs if a null listener is supplied.  null is regarded as a valid property name.
 914:    *
 915:    * @param name the name of the property to handle change events for.
 916:    * @param l the listener to register for changes to the specified property. 
 917:    * @see KeyboardFocusManager#addVetoableChangeListener(java.beans.VetoableChangeListener)
 918:    */
 919:   public void addVetoableChangeListener(String name, VetoableChangeListener l)
 920:   {
 921:     if (l != null)
 922:       vetoableChangeSupport.addVetoableChangeListener(name, l);
 923:   }
 924: 
 925:   /**
 926:    * Removes the supplied vetoable property change listener registered
 927:    * for the specified property from the list of registered listeners.
 928:    * If the supplied listener is null, nothing occurs.
 929:    *
 930:    * @param name the name of the vetoable property the listener is
 931:    *        monitoring changes to.
 932:    * @param l the listener to remove.
 933:    */
 934:   public void removeVetoableChangeListener(String name,
 935:                                            VetoableChangeListener l)
 936:   {
 937:     if (l != null)
 938:       vetoableChangeSupport.removeVetoableChangeListener(name, l);
 939:   }
 940: 
 941:   /**
 942:    * Returns the currently registered vetoable property change listeners
 943:    * in array form, which listen for changes to the supplied property.
 944:    * The returned array is empty, if no listeners are currently registered
 945:    * for events pertaining to the supplied property.
 946:    *
 947:    * @param name The property the returned listeners monitor for changes.
 948:    * @return an array of registered property change listeners which
 949:    *         listen for changes to the supplied property.
 950:    * @since 1.4
 951:    */
 952:   public VetoableChangeListener[] getVetoableChangeListeners(String name)
 953:   {
 954:     return vetoableChangeSupport.getVetoableChangeListeners(name);
 955:   }
 956: 
 957:   /**
 958:    * Fires a property change event as a response to a vetoable change to
 959:    * to the specified property.  The event is only fired if a
 960:    * change has actually occurred (i.e. o and n are different).
 961:    * In the event that the property change is vetoed, the following
 962:    * occurs:
 963:    *
 964:    * <ol>
 965:    * <li>
 966:    * This method throws a <code>PropertyVetoException</code> to
 967:    * the proposed change.
 968:    * </li>
 969:    * <li>
 970:    * A new event is fired to reverse the previous change.
 971:    * </li>
 972:    * <li>
 973:    * This method again throws a <code>PropertyVetoException</code>
 974:    * in response to the reversion.
 975:    * </li>
 976:    * </ol>
 977:    *
 978:    * @param name The name of the property to which a change occurred.
 979:    * @param o The old value of the property.
 980:    * @param n The new value of the property.
 981:    * @throws PropertyVetoException if one of the listeners vetos
 982:    *         the change by throwing this exception.
 983:    */
 984:   protected void fireVetoableChange(String name, Object o, Object n)
 985:     throws PropertyVetoException
 986:   {
 987:     vetoableChangeSupport.fireVetoableChange(name, o, n);
 988:   }
 989: 
 990:   /**
 991:    * Adds a key event dispatcher to the list of registered dispatchers.
 992:    * When a key event is fired, each dispatcher's <code>dispatchKeyEvent</code>
 993:    * method is called in the order that they were added, prior to the manager
 994:    * dispatching the event itself.  Notifications halt when one of the
 995:    * dispatchers returns true.
 996:    * <br />
 997:    * <br />
 998:    * The same dispatcher can exist multiple times within the list
 999:    * of registered dispatchers, and there is no limit on the length
1000:    * of this list.  A null dispatcher is simply ignored.
1001:    *
1002:    * @param dispatcher The dispatcher to register.
1003:    */
1004:   public void addKeyEventDispatcher(KeyEventDispatcher dispatcher)
1005:   {
1006:     if (dispatcher != null)
1007:       keyEventDispatchers.add(dispatcher);
1008:   }
1009: 
1010:   /**
1011:    * Removes the specified key event dispatcher from the list of
1012:    * registered dispatchers.  The manager always dispatches events,
1013:    * regardless of its existence within the list.  The manager
1014:    * can be added and removed from the list, as with any other
1015:    * dispatcher, but this does not affect its ability to dispatch
1016:    * key events.  Non-existent and null dispatchers are simply ignored
1017:    * by this method.
1018:    *
1019:    * @param dispatcher The dispatcher to remove.
1020:    */
1021:   public void removeKeyEventDispatcher(KeyEventDispatcher dispatcher)
1022:   {
1023:     keyEventDispatchers.remove(dispatcher);
1024:   }
1025: 
1026:   /**
1027:    * Returns the currently registered key event dispatchers in <code>List</code>
1028:    * form.  At present, this only includes dispatchers explicitly registered
1029:    * via the <code>addKeyEventDispatcher()</code> method, but this behaviour
1030:    * is subject to change and should not be depended on.  The manager itself
1031:    * may be a member of the list, but only if explicitly registered.  If no
1032:    * dispatchers have been registered, the list will be empty.
1033:    *
1034:    * @return A list of explicitly registered key event dispatchers.
1035:    * @see KeyboardFocusManager#addKeyEventDispatcher(java.awt.KeyEventDispatcher)
1036:    */
1037:   protected List getKeyEventDispatchers ()
1038:   {
1039:     return (List) keyEventDispatchers.clone ();
1040:   }
1041: 
1042:   /**
1043:    * Adds a key event post processor to the list of registered post processors.
1044:    * Post processors work in the same way as key event dispatchers, except
1045:    * that they are invoked after the manager has dispatched the key event,
1046:    * and not prior to this.  Each post processor's <code>postProcessKeyEvent</code>
1047:    * method is called to see if any post processing needs to be performed.  THe
1048:    * processors are called in the order in which they were added to the list,
1049:    * and notifications continue until one returns true.  As with key event
1050:    * dispatchers, the manager is implicitly called following this process,
1051:    * regardless of whether or not it is present within the list.
1052:    * <br />
1053:    * <br />
1054:    * The same post processor can exist multiple times within the list
1055:    * of registered post processors, and there is no limit on the length
1056:    * of this list.  A null post processor is simply ignored.
1057:    *
1058:    * @param postProcessor the post processor to register.
1059:    * @see KeyboardFocusManager#addKeyEventDispatcher(java.awt.KeyEventDispatcher)
1060:    */
1061:   public void addKeyEventPostProcessor (KeyEventPostProcessor postProcessor)
1062:   {
1063:     if (postProcessor != null)
1064:       keyEventPostProcessors.add (postProcessor);
1065:   }
1066: 
1067:   /**
1068:    * Removes the specified key event post processor from the list of
1069:    * registered post processors.  The manager always post processes events,
1070:    * regardless of its existence within the list.  The manager
1071:    * can be added and removed from the list, as with any other
1072:    * post processor, but this does not affect its ability to post process
1073:    * key events.  Non-existent and null post processors are simply ignored
1074:    * by this method.
1075:    *
1076:    * @param postProcessor the post processor to remove.
1077:    */
1078:   public void removeKeyEventPostProcessor (KeyEventPostProcessor postProcessor)
1079:   {
1080:     keyEventPostProcessors.remove (postProcessor);
1081:   }
1082: 
1083:   /**
1084:    * Returns the currently registered key event post processors in <code>List</code>
1085:    * form.  At present, this only includes post processors explicitly registered
1086:    * via the <code>addKeyEventPostProcessor()</code> method, but this behaviour
1087:    * is subject to change and should not be depended on.  The manager itself
1088:    * may be a member of the list, but only if explicitly registered.  If no
1089:    * post processors have been registered, the list will be empty.
1090:    *
1091:    * @return A list of explicitly registered key event post processors.
1092:    * @see KeyboardFocusManager#addKeyEventPostProcessor(java.awt.KeyEventPostProcessor)
1093:    */
1094:   protected List getKeyEventPostProcessors ()
1095:   {
1096:     return (List) keyEventPostProcessors.clone ();
1097:   }
1098: 
1099:   /**
1100:    * The AWT event dispatcher uses this method to request that the manager
1101:    * handle a particular event.  If the manager fails or refuses to
1102:    * dispatch the supplied event (this method returns false), the
1103:    * AWT event dispatcher will try to dispatch the event itself.
1104:    * <br />
1105:    * <br />
1106:    * The manager is expected to handle all <code>FocusEvent</code>s
1107:    * and <code>KeyEvent</code>s, and <code>WindowEvent</code>s
1108:    * relating to the focus.  Dispatch is done with regard to the
1109:    * the focus owner and the currently focused and active windows.
1110:    * In handling the event, the source of the event may be overridden.
1111:    * <br />
1112:    * <br />
1113:    * The actual dispatching is performed by calling
1114:    * <code>redispatchEvent()</code>.  This avoids the infinite recursion
1115:    * of dispatch requests which may occur if this method is called on
1116:    * the target component.  
1117:    *
1118:    * @param e the event to dispatch.
1119:    * @return true if the event was dispatched.
1120:    * @see KeyboardFocusManager#redispatchEvent(java.awt.Component, java.awt.AWTEvent)
1121:    * @see KeyEvent
1122:    * @see FocusEvent
1123:    * @see WindowEvent
1124:    */
1125:   public abstract boolean dispatchEvent (AWTEvent e);
1126: 
1127:   /**
1128:    * Handles redispatching of an event so that recursion of
1129:    * dispatch requests does not occur.  Event dispatch methods
1130:    * within this manager (<code>dispatchEvent()</code>) and
1131:    * the key event dispatchers should use this method to handle
1132:    * dispatching rather than the dispatch method of the target
1133:    * component.  
1134:    * <br />
1135:    * <br />
1136:    * <strong>
1137:    * This method is not intended for general consumption, and is
1138:    * only for the use of the aforementioned classes.
1139:    * </strong>
1140:    * 
1141:    * @param target the target component to which the event is
1142:    *        dispatched.
1143:    * @param e the event to dispatch.
1144:    */
1145:   public final void redispatchEvent (Component target, AWTEvent e)
1146:   {
1147:     synchronized (e)
1148:       {
1149:         e.setSource (target);
1150:         target.dispatchEvent (e);
1151:       }
1152:   }
1153: 
1154:   /**
1155:    * Attempts to dispatch key events for which no key event dispatcher
1156:    * has so far succeeded.  This method is usually called by
1157:    * <code>dispatchEvent()</code> following the sending of the key
1158:    * event to any registered key event dispatchers.  If the key
1159:    * event reaches this stage, none of the dispatchers returned
1160:    * true.  This is, of course, always the case if there are no
1161:    * registered dispatchers.
1162:    * <br />
1163:    * <br />
1164:    * If this method also fails to handle the key event, then
1165:    * false is returned to the caller.  In the case of
1166:    * <code>dispatchEvent()</code>, the calling method may try
1167:    * to handle the event itself or simply forward on the
1168:    * false result to its caller.  When the event is dispatched
1169:    * by this method, a true result is propogated through the
1170:    * calling methods.
1171:    *
1172:    * @param e the key event to dispatch.
1173:    * @return true if the event was dispatched successfully.
1174:    */
1175:   public abstract boolean dispatchKeyEvent (KeyEvent e);
1176: 
1177:   /**
1178:    * Handles the post processing of key events.  By default,
1179:    * this method will map unhandled key events to appropriate
1180:    * <code>MenuShortcut</code>s.  The event is consumed
1181:    * in the process and the shortcut is activated.  This
1182:    * method is usually called by <code>dispatchKeyEvent</code>.
1183:    *
1184:    * @param e the key event to post process.
1185:    * @return true by default, as the event was handled.
1186:    */
1187:   public abstract boolean postProcessKeyEvent (KeyEvent e);
1188: 
1189:   /**
1190:    * Handles focus traversal operations for key events which
1191:    * represent focus traversal keys in relation to the supplied
1192:    * component.  The supplied component is assumed to have the
1193:    * focus, whether it does so or not, and the operation is
1194:    * carried out as appropriate, with this in mind.
1195:    *
1196:    * @param focused the component on which to perform focus traversal,
1197:    *        on the assumption that this component has the focus.
1198:    * @param e the possible focus traversal key event.
1199:    */
1200:   public abstract void processKeyEvent (Component focused, KeyEvent e);
1201: 
1202:   /**
1203:    * Delays all key events following the specified timestamp until the
1204:    * supplied component has focus.  The AWT calls this method when it is
1205:    * determined that a focus change may occur within the native windowing
1206:    * system.  Any key events which occur following the time specified by
1207:    * after are delayed until a <code>FOCUS_GAINED</code> event is received
1208:    * for the untilFocused component.  The manager is responsible for ensuring
1209:    * this takes place.
1210:    *
1211:    * @param after the timestamp beyond which all key events are delayed until
1212:    *        the supplied component gains focus.
1213:    * @param untilFocused the component to wait on gaining focus.
1214:    */
1215:   protected abstract void enqueueKeyEvents (long after, Component untilFocused);
1216: 
1217:   /**
1218:    * Removes the key event block specified by the supplied timestamp and component.
1219:    * All delayed key events are released for normal dispatching following its
1220:    * removal and subsequent key events that would have been blocked are now
1221:    * immediately dispatched.  If the specified timestamp is below 0, then
1222:    * the request with the oldest timestamp is removed.
1223:    *
1224:    * @param after the timestamp of the key event block to be removed, or a
1225:    *        value smaller than 0 if the oldest is to be removed.
1226:    * @param untilFocused the component of the key event block to be removed.
1227:    */
1228:   protected abstract void dequeueKeyEvents (long after, Component untilFocused);
1229: 
1230:   /**
1231:    * Discards all key event blocks relating to focus requirements for
1232:    * the supplied component, regardless of timestamp.
1233:    *
1234:    * @param comp the component of the key event block(s) to be removed.
1235:    */
1236:   protected abstract void discardKeyEvents (Component comp);
1237: 
1238:   /**
1239:    * Moves the current focus to the next component following
1240:    * comp, based on the current focus traversal policy.  By
1241:    * default, only visible, displayable, accepted components
1242:    * can receive focus.  <code>Canvas</code>es, <code>Panel</code>s,
1243:    * <code>Label</code>s, <code>ScrollPane</code>s, <code>Scrollbar</code>s,
1244:    * <code>Window</code>s and lightweight components are judged
1245:    * to be unacceptable by default.  See the
1246:    * <code>DefaultFocusTraversalPolicy</code> for more details.
1247:    *
1248:    * @param comp the component prior to the one which will
1249:    *        become the focus, following execution of this method.
1250:    * @see DefaultFocusTraversalPolicy
1251:    */
1252:   public abstract void focusNextComponent(Component comp);
1253: 
1254:   /**
1255:    * Moves the current focus to the previous component, prior to
1256:    * comp, based on the current focus traversal policy.  By
1257:    * default, only visible, displayable, accepted components
1258:    * can receive focus.  <code>Canvas</code>es, <code>Panel</code>s,
1259:    * <code>Label</code>s, <code>ScrollPane</code>s, <code>Scrollbar</code>s,
1260:    * <code>Window</code>s and lightweight components are judged
1261:    * to be unacceptable by default.  See the
1262:    * <code>DefaultFocusTraversalPolicy</code> for more details.
1263:    *
1264:    * @param comp the component following the one which will
1265:    *        become the focus, following execution of this method.
1266:    * @see DefaultFocusTraversalPolicy
1267:    */
1268:   public abstract void focusPreviousComponent(Component comp);
1269: 
1270:   /**
1271:    * Moves the current focus upwards by one focus cycle.
1272:    * Both the current focus owner and current focus cycle root
1273:    * become the focus cycle root of the supplied component.
1274:    * However, in the case of a <code>Window</code>, the default
1275:    * focus component becomes the focus owner and the focus cycle
1276:    * root is not changed.
1277:    * 
1278:    * @param comp the component used as part of the focus traversal.
1279:    */ 
1280:   public abstract void upFocusCycle(Component comp);
1281: 
1282:   /**
1283:    * Moves the current focus downwards by one focus cycle.
1284:    * If the supplied container is a focus cycle root, then this
1285:    * becomes the current focus cycle root and the focus goes
1286:    * to the default component of the specified container.
1287:    * Nothing happens for non-focus cycle root containers. 
1288:    * 
1289:    * @param cont the container used as part of the focus traversal.
1290:    */ 
1291:   public abstract void downFocusCycle(Container cont);
1292: 
1293:   /**
1294:    * Moves the current focus to the next component, based on the
1295:    * current focus traversal policy.  By default, only visible,
1296:    * displayable, accepted component can receive focus.
1297:    * <code>Canvas</code>es, <code>Panel</code>s,
1298:    * <code>Label</code>s, <code>ScrollPane</code>s, <code>Scrollbar</code>s,
1299:    * <code>Window</code>s and lightweight components are judged
1300:    * to be unacceptable by default.  See the
1301:    * <code>DefaultFocusTraversalPolicy</code> for more details.
1302:    *
1303:    * @see DefaultFocusTraversalPolicy
1304:    */
1305:   public final void focusNextComponent()
1306:   {
1307:     focusNextComponent (null);
1308:   }
1309: 
1310:   /**
1311:    * Moves the current focus to the previous component, based on the
1312:    * current focus traversal policy.  By default, only visible,
1313:    * displayable, accepted component can receive focus.
1314:    * <code>Canvas</code>es, <code>Panel</code>s,
1315:    * <code>Label</code>s, <code>ScrollPane</code>s, <code>Scrollbar</code>s,
1316:    * <code>Window</code>s and lightweight components are judged
1317:    * to be unacceptable by default.  See the
1318:    * <code>DefaultFocusTraversalPolicy</code> for more details.
1319:    *
1320:    * @see DefaultFocusTraversalPolicy
1321:    */
1322:   public final void focusPreviousComponent()
1323:   {
1324:     focusPreviousComponent (null);
1325:   }
1326: 
1327:   /**
1328:    * Moves the current focus upwards by one focus cycle,
1329:    * so that the new focus owner is the focus cycle root
1330:    * of the current owner.  The current focus cycle root then
1331:    * becomes the focus cycle root of the new focus owner.
1332:    * However, in the case of the focus cycle root of the
1333:    * current focus owner being a <code>Window</code>, the default
1334:    * component of this window becomes the focus owner and the
1335:    * focus cycle root is not changed.
1336:    */
1337:   public final void upFocusCycle()
1338:   {
1339:     upFocusCycle (null);
1340:   }
1341: 
1342:   /**
1343:    * Moves the current focus downwards by one focus cycle,
1344:    * iff the current focus cycle root is a <code>Container</code>.
1345:    * Usually, the new focus owner is set to the default component
1346:    * of the container and the current focus cycle root is set
1347:    * to the current focus owner.  Nothing occurs if the current
1348:    * focus cycle root is not a container.
1349:    */
1350:   public final void downFocusCycle()
1351:   {
1352:     Component focusOwner = getGlobalFocusOwner ();
1353:     if (focusOwner instanceof Container
1354:         && ((Container) focusOwner).isFocusCycleRoot ())
1355:       downFocusCycle ((Container) focusOwner);
1356:   }
1357: 
1358:   /**
1359:    * Retrieve an object from one of the global object {@link
1360:    * java.util.Map}s, if the object was set by the a thread in the
1361:    * current {@link java.lang.ThreadGroup}.  Otherwise, return null.
1362:    *
1363:    * @param globalMap one of the global object Maps
1364:    *
1365:    * @return a global object set by the current ThreadGroup, or null
1366:    *
1367:    * @see getFocusOwner
1368:    * @see getPermanentFocusOwner
1369:    * @see getFocusedWindow
1370:    * @see getActiveWindow
1371:    * @see getCurrentFocusCycleRoot
1372:    */
1373:   private Object getObject (Map globalMap)
1374:   {
1375:     ThreadGroup currentGroup = Thread.currentThread ().getThreadGroup ();
1376:     return globalMap.get (currentGroup);
1377:   }
1378: 
1379:   /**
1380:    * Retrieve an object from one of the global object {@link
1381:    * java.util.Map}s, regardless of whether or not the object was set
1382:    * by a thread in the current {@link java.lang.ThreadGroup}.
1383:    *
1384:    * @param globalMap one of the global object Maps
1385:    *
1386:    * @return a global object set by the current ThreadGroup, or null
1387:    *
1388:    * @throws SecurityException if this is not the keyboard focus
1389:    * manager associated with the current {@link java.lang.ThreadGroup}
1390:    *
1391:    * @see getGlobalFocusOwner
1392:    * @see getGlobalPermanentFocusOwner
1393:    * @see getGlobalFocusedWindow
1394:    * @see getGlobalActiveWindow
1395:    * @see getGlobalCurrentFocusCycleRoot
1396:    */
1397:   private Object getGlobalObject (Map globalMap)
1398:   {
1399:     ThreadGroup currentGroup = Thread.currentThread ().getThreadGroup ();
1400:     KeyboardFocusManager managerForCallingThread
1401:       = (KeyboardFocusManager) currentKeyboardFocusManagers.get (currentGroup);
1402: 
1403:     if (this != managerForCallingThread)
1404:       throw new SecurityException ("Attempted to retrieve an object from a "
1405:                                    + "keyboard focus manager that isn't "
1406:                                    + "associated with the current thread group.");
1407: 
1408:     synchronized (globalMap)
1409:       {
1410:         Collection globalObjects = globalMap.values ();
1411:         Iterator i = globalObjects.iterator ();
1412:         Component globalObject;
1413: 
1414:         while (i.hasNext ())
1415:           {
1416:             globalObject = (Component) i.next ();
1417:             if (globalObject != null)
1418:               return globalObject;
1419:           }
1420:       }
1421: 
1422:     // No Object was found.
1423:     return null;
1424:   }
1425: 
1426:   /**
1427:    * Set an object in one of the global object {@link java.util.Map}s,
1428:    * that will be returned by subsequent calls to getGlobalObject on
1429:    * the same {@link java.util.Map}.
1430:    *
1431:    * @param globalMap one of the global object Maps
1432:    * @param newObject the object to set
1433:    * @param property the property that will change
1434:    *
1435:    * @see setGlobalFocusOwner
1436:    * @see setGlobalPermanentFocusOwner
1437:    * @see setGlobalFocusedWindow
1438:    * @see setGlobalActiveWindow
1439:    * @see setGlobalCurrentFocusCycleRoot
1440:    */
1441:   private void setGlobalObject (Map globalMap,
1442:                                 Object newObject,
1443:                                 String property)
1444:   {
1445:     synchronized (globalMap)
1446:       {
1447:         // Save old object.
1448:         Object oldObject = getGlobalObject (globalMap);
1449: 
1450:         // Nullify old object.
1451:         Collection threadGroups = globalMap.keySet ();
1452:         Iterator i = threadGroups.iterator ();
1453:         while (i.hasNext ())
1454:           {
1455:             ThreadGroup oldThreadGroup = (ThreadGroup) i.next ();
1456:             if (globalMap.get (oldThreadGroup) != null)
1457:               {
1458:                 globalMap.put (oldThreadGroup, null);
1459:                 // There should only be one object set at a time, so
1460:                 // we can short circuit.
1461:                 break;
1462:               }
1463:           }
1464: 
1465:         ThreadGroup currentGroup = Thread.currentThread ().getThreadGroup ();
1466:         firePropertyChange (property, oldObject, newObject);
1467:         try
1468:           {
1469:             fireVetoableChange (property, oldObject, newObject);
1470:             // Set new object.
1471:             globalMap.put (currentGroup, newObject);
1472:           }
1473:         catch (PropertyVetoException e)
1474:           {
1475:           }
1476:       }
1477:   }
1478: }