Source for java.awt.Component

   1: /* Component.java -- a graphics component
   2:    Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2006
   3:    Free Software Foundation
   4: 
   5: This file is part of GNU Classpath.
   6: 
   7: GNU Classpath is free software; you can redistribute it and/or modify
   8: it under the terms of the GNU General Public License as published by
   9: the Free Software Foundation; either version 2, or (at your option)
  10: any later version.
  11: 
  12: GNU Classpath is distributed in the hope that it will be useful, but
  13: WITHOUT ANY WARRANTY; without even the implied warranty of
  14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15: General Public License for more details.
  16: 
  17: You should have received a copy of the GNU General Public License
  18: along with GNU Classpath; see the file COPYING.  If not, write to the
  19: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  20: 02110-1301 USA.
  21: 
  22: Linking this library statically or dynamically with other modules is
  23: making a combined work based on this library.  Thus, the terms and
  24: conditions of the GNU General Public License cover the whole
  25: combination.
  26: 
  27: As a special exception, the copyright holders of this library give you
  28: permission to link this library with independent modules to produce an
  29: executable, regardless of the license terms of these independent
  30: modules, and to copy and distribute the resulting executable under
  31: terms of your choice, provided that you also meet, for each linked
  32: independent module, the terms and conditions of the license of that
  33: module.  An independent module is a module which is not derived from
  34: or based on this library.  If you modify this library, you may extend
  35: this exception to your version of the library, but you are not
  36: obligated to do so.  If you do not wish to do so, delete this
  37: exception statement from your version. */
  38: 
  39: 
  40: package java.awt;
  41: 
  42: //import gnu.java.awt.dnd.peer.gtk.GtkDropTargetContextPeer;
  43: 
  44: import gnu.java.awt.ComponentReshapeEvent;
  45: 
  46: import java.awt.dnd.DropTarget;
  47: import java.awt.event.ActionEvent;
  48: import java.awt.event.AdjustmentEvent;
  49: import java.awt.event.ComponentEvent;
  50: import java.awt.event.ComponentListener;
  51: import java.awt.event.FocusEvent;
  52: import java.awt.event.FocusListener;
  53: import java.awt.event.HierarchyBoundsListener;
  54: import java.awt.event.HierarchyEvent;
  55: import java.awt.event.HierarchyListener;
  56: import java.awt.event.InputEvent;
  57: import java.awt.event.InputMethodEvent;
  58: import java.awt.event.InputMethodListener;
  59: import java.awt.event.KeyEvent;
  60: import java.awt.event.KeyListener;
  61: import java.awt.event.MouseEvent;
  62: import java.awt.event.MouseListener;
  63: import java.awt.event.MouseMotionListener;
  64: import java.awt.event.MouseWheelEvent;
  65: import java.awt.event.MouseWheelListener;
  66: import java.awt.event.PaintEvent;
  67: import java.awt.event.WindowEvent;
  68: import java.awt.im.InputContext;
  69: import java.awt.im.InputMethodRequests;
  70: import java.awt.image.BufferStrategy;
  71: import java.awt.image.ColorModel;
  72: import java.awt.image.ImageObserver;
  73: import java.awt.image.ImageProducer;
  74: import java.awt.image.VolatileImage;
  75: import java.awt.peer.ComponentPeer;
  76: import java.awt.peer.LightweightPeer;
  77: import java.beans.PropertyChangeEvent;
  78: import java.beans.PropertyChangeListener;
  79: import java.beans.PropertyChangeSupport;
  80: import java.io.IOException;
  81: import java.io.ObjectInputStream;
  82: import java.io.ObjectOutputStream;
  83: import java.io.PrintStream;
  84: import java.io.PrintWriter;
  85: import java.io.Serializable;
  86: import java.lang.reflect.Array;
  87: import java.util.Collections;
  88: import java.util.EventListener;
  89: import java.util.HashSet;
  90: import java.util.Iterator;
  91: import java.util.Locale;
  92: import java.util.Set;
  93: import java.util.Vector;
  94: 
  95: import javax.accessibility.Accessible;
  96: import javax.accessibility.AccessibleComponent;
  97: import javax.accessibility.AccessibleContext;
  98: import javax.accessibility.AccessibleRole;
  99: import javax.accessibility.AccessibleState;
 100: import javax.accessibility.AccessibleStateSet;
 101: 
 102: /**
 103:  * The root of all evil. All graphical representations are subclasses of this
 104:  * giant class, which is designed for screen display and user interaction.
 105:  * This class can be extended directly to build a lightweight component (one
 106:  * not associated with a native window); lightweight components must reside
 107:  * inside a heavyweight window.
 108:  *
 109:  * <p>This class is Serializable, which has some big implications. A user can
 110:  * save the state of all graphical components in one VM, and reload them in
 111:  * another. Note that this class will only save Serializable listeners, and
 112:  * ignore the rest, without causing any serialization exceptions. However, by
 113:  * making a listener serializable, and adding it to another element, you link
 114:  * in that entire element to the state of this component. To get around this,
 115:  * use the idiom shown in the example below - make listeners non-serializable
 116:  * in inner classes, rather than using this object itself as the listener, if
 117:  * external objects do not need to save the state of this object.
 118:  *
 119:  * <pre>
 120:  * import java.awt.*;
 121:  * import java.awt.event.*;
 122:  * import java.io.Serializable;
 123:  * class MyApp implements Serializable
 124:  * {
 125:  *   BigObjectThatShouldNotBeSerializedWithAButton bigOne;
 126:  *   // Serializing aButton will not suck in an instance of MyApp, with its
 127:  *   // accompanying field bigOne.
 128:  *   Button aButton = new Button();
 129:  *   class MyActionListener implements ActionListener
 130:  *   {
 131:  *     public void actionPerformed(ActionEvent e)
 132:  *     {
 133:  *       System.out.println("Hello There");
 134:  *     }
 135:  *   }
 136:  *   MyApp()
 137:  *   {
 138:  *     aButton.addActionListener(new MyActionListener());
 139:  *   }
 140:  * }
 141:  * </pre>
 142:  *
 143:  * <p>Status: Incomplete. The event dispatch mechanism is implemented. All
 144:  * other methods defined in the J2SE 1.3 API javadoc exist, but are mostly
 145:  * incomplete or only stubs; except for methods relating to the Drag and
 146:  * Drop, Input Method, and Accessibility frameworks: These methods are
 147:  * present but commented out.
 148:  *
 149:  * @author original author unknown
 150:  * @author Eric Blake (ebb9@email.byu.edu)
 151:  * @since 1.0
 152:  * @status still missing 1.4 support
 153:  */
 154: public abstract class Component
 155:   implements ImageObserver, MenuContainer, Serializable
 156: {
 157:   // Word to the wise - this file is huge. Search for '\f' (^L) for logical
 158:   // sectioning by fields, public API, private API, and nested classes.
 159: 
 160: 
 161:   /**
 162:    * Compatible with JDK 1.0+.
 163:    */
 164:   private static final long serialVersionUID = -7644114512714619750L;
 165: 
 166:   /**
 167:    * Constant returned by the <code>getAlignmentY</code> method to indicate
 168:    * that the component wishes to be aligned to the top relative to
 169:    * other components.
 170:    *
 171:    * @see #getAlignmentY()
 172:    */
 173:   public static final float TOP_ALIGNMENT = 0;
 174: 
 175:   /**
 176:    * Constant returned by the <code>getAlignmentY</code> and
 177:    * <code>getAlignmentX</code> methods to indicate
 178:    * that the component wishes to be aligned to the center relative to
 179:    * other components.
 180:    *
 181:    * @see #getAlignmentX()
 182:    * @see #getAlignmentY()
 183:    */
 184:   public static final float CENTER_ALIGNMENT = 0.5f;
 185: 
 186:   /**
 187:    * Constant returned by the <code>getAlignmentY</code> method to indicate
 188:    * that the component wishes to be aligned to the bottom relative to
 189:    * other components.
 190:    *
 191:    * @see #getAlignmentY()
 192:    */
 193:   public static final float BOTTOM_ALIGNMENT = 1;
 194: 
 195:   /**
 196:    * Constant returned by the <code>getAlignmentX</code> method to indicate
 197:    * that the component wishes to be aligned to the right relative to
 198:    * other components.
 199:    *
 200:    * @see #getAlignmentX()
 201:    */
 202:   public static final float RIGHT_ALIGNMENT = 1;
 203: 
 204:   /**
 205:    * Constant returned by the <code>getAlignmentX</code> method to indicate
 206:    * that the component wishes to be aligned to the left relative to
 207:    * other components.
 208:    *
 209:    * @see #getAlignmentX()
 210:    */
 211:   public static final float LEFT_ALIGNMENT = 0;
 212: 
 213:   /**
 214:    * Make the treelock a String so that it can easily be identified
 215:    * in debug dumps. We clone the String in order to avoid a conflict in
 216:    * the unlikely event that some other package uses exactly the same string
 217:    * as a lock object.
 218:    */
 219:   static final Object treeLock = new String("AWT_TREE_LOCK");
 220: 
 221:   /**
 222:    * The default maximum size.
 223:    */
 224:   private static final Dimension DEFAULT_MAX_SIZE 
 225:                              = new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
 226: 
 227:   // Serialized fields from the serialization spec.
 228: 
 229:   /**
 230:    * The x position of the component in the parent's coordinate system.
 231:    *
 232:    * @see #getLocation()
 233:    * @serial the x position
 234:    */
 235:   int x;
 236: 
 237:   /**
 238:    * The y position of the component in the parent's coordinate system.
 239:    *
 240:    * @see #getLocation()
 241:    * @serial the y position
 242:    */
 243:   int y;
 244: 
 245:   /**
 246:    * The component width.
 247:    *
 248:    * @see #getSize()
 249:    * @serial the width
 250:    */
 251:   int width;
 252: 
 253:   /**
 254:    * The component height.
 255:    *
 256:    * @see #getSize()
 257:    * @serial the height
 258:    */
 259:   int height;
 260: 
 261:   /**
 262:    * The foreground color for the component. This may be null.
 263:    *
 264:    * @see #getForeground()
 265:    * @see #setForeground(Color)
 266:    * @serial the foreground color
 267:    */
 268:   Color foreground;
 269: 
 270:   /**
 271:    * The background color for the component. This may be null.
 272:    *
 273:    * @see #getBackground()
 274:    * @see #setBackground(Color)
 275:    * @serial the background color
 276:    */
 277:   Color background;
 278: 
 279:   /**
 280:    * The default font used in the component. This may be null.
 281:    *
 282:    * @see #getFont()
 283:    * @see #setFont(Font)
 284:    * @serial the font
 285:    */
 286:   Font font;
 287: 
 288:   /**
 289:    * The font in use by the peer, or null if there is no peer.
 290:    *
 291:    * @serial the peer's font
 292:    */
 293:   Font peerFont;
 294: 
 295:   /**
 296:    * The cursor displayed when the pointer is over this component. This may
 297:    * be null.
 298:    *
 299:    * @see #getCursor()
 300:    * @see #setCursor(Cursor)
 301:    */
 302:   Cursor cursor;
 303: 
 304:   /**
 305:    * The locale for the component.
 306:    *
 307:    * @see #getLocale()
 308:    * @see #setLocale(Locale)
 309:    */
 310:   Locale locale = Locale.getDefault ();
 311: 
 312:   /**
 313:    * True if the object should ignore repaint events (usually because it is
 314:    * not showing).
 315:    *
 316:    * @see #getIgnoreRepaint()
 317:    * @see #setIgnoreRepaint(boolean)
 318:    * @serial true to ignore repaints
 319:    * @since 1.4
 320:    */
 321:   boolean ignoreRepaint;
 322: 
 323:   /**
 324:    * True when the object is visible (although it is only showing if all
 325:    * ancestors are likewise visible). For component, this defaults to true.
 326:    *
 327:    * @see #isVisible()
 328:    * @see #setVisible(boolean)
 329:    * @serial true if visible
 330:    */
 331:   boolean visible = true;
 332: 
 333:   /**
 334:    * True if the object is enabled, meaning it can interact with the user.
 335:    * For component, this defaults to true.
 336:    *
 337:    * @see #isEnabled()
 338:    * @see #setEnabled(boolean)
 339:    * @serial true if enabled
 340:    */
 341:   boolean enabled = true;
 342: 
 343:   /**
 344:    * True if the object is valid. This is set to false any time a size
 345:    * adjustment means the component need to be layed out again.
 346:    *
 347:    * @see #isValid()
 348:    * @see #validate()
 349:    * @see #invalidate()
 350:    * @serial true if layout is valid
 351:    */
 352:   boolean valid;
 353: 
 354:   /**
 355:    * The DropTarget for drag-and-drop operations.
 356:    *
 357:    * @see #getDropTarget()
 358:    * @see #setDropTarget(DropTarget)
 359:    * @serial the drop target, or null
 360:    * @since 1.2
 361:    */
 362:   DropTarget dropTarget;
 363: 
 364:   /**
 365:    * The list of popup menus for this component.
 366:    *
 367:    * @see #add(PopupMenu)
 368:    * @serial the list of popups
 369:    */
 370:   Vector popups;
 371: 
 372:   /**
 373:    * The component's name. May be null, in which case a default name is
 374:    * generated on the first use.
 375:    *
 376:    * @see #getName()
 377:    * @see #setName(String)
 378:    * @serial the name
 379:    */
 380:   String name;
 381: 
 382:   /**
 383:    * True once the user has set the name. Note that the user may set the name
 384:    * to null.
 385:    *
 386:    * @see #name
 387:    * @see #getName()
 388:    * @see #setName(String)
 389:    * @serial true if the name has been explicitly set
 390:    */
 391:   boolean nameExplicitlySet;
 392: 
 393:   /**
 394:    * Indicates if the object can be focused. Defaults to true for components.
 395:    *
 396:    * @see #isFocusable()
 397:    * @see #setFocusable(boolean)
 398:    * @since 1.4
 399:    */
 400:   boolean focusable = true;
 401: 
 402:   /**
 403:    * Tracks whether this component's {@link #isFocusTraversable}
 404:    * method has been overridden.
 405:    *
 406:    * @since 1.4
 407:    */
 408:   int isFocusTraversableOverridden;
 409: 
 410:   /**
 411:    * The focus traversal keys, if not inherited from the parent or
 412:    * default keyboard focus manager. These sets will contain only
 413:    * AWTKeyStrokes that represent press and release events to use as
 414:    * focus control.
 415:    *
 416:    * @see #getFocusTraversalKeys(int)
 417:    * @see #setFocusTraversalKeys(int, Set)
 418:    * @since 1.4
 419:    */
 420:   Set[] focusTraversalKeys;
 421: 
 422:   /**
 423:    * True if focus traversal keys are enabled. This defaults to true for
 424:    * Component. If this is true, keystrokes in focusTraversalKeys are trapped
 425:    * and processed automatically rather than being passed on to the component.
 426:    *
 427:    * @see #getFocusTraversalKeysEnabled()
 428:    * @see #setFocusTraversalKeysEnabled(boolean)
 429:    * @since 1.4
 430:    */
 431:   boolean focusTraversalKeysEnabled = true;
 432: 
 433:   /**
 434:    * Cached information on the minimum size. Should have been transient.
 435:    *
 436:    * @serial ignore
 437:    */
 438:   Dimension minSize;
 439: 
 440:   /**
 441:    * Flag indicating whether the minimum size for the component has been set
 442:    * by a call to {@link #setMinimumSize(Dimension)} with a non-null value.
 443:    */
 444:   boolean minSizeSet;
 445:   
 446:   /**
 447:    * The maximum size for the component.
 448:    * @see #setMaximumSize(Dimension)
 449:    */
 450:   Dimension maxSize;
 451:   
 452:   /**
 453:    * A flag indicating whether the maximum size for the component has been set
 454:    * by a call to {@link #setMaximumSize(Dimension)} with a non-null value.
 455:    */
 456:   boolean maxSizeSet;
 457:   
 458:   /**
 459:    * Cached information on the preferred size. Should have been transient.
 460:    *
 461:    * @serial ignore
 462:    */
 463:   Dimension prefSize;
 464: 
 465:   /**
 466:    * Flag indicating whether the preferred size for the component has been set
 467:    * by a call to {@link #setPreferredSize(Dimension)} with a non-null value.
 468:    */
 469:   boolean prefSizeSet;
 470: 
 471:   /**
 472:    * Set to true if an event is to be handled by this component, false if
 473:    * it is to be passed up the hierarcy.
 474:    *
 475:    * @see #dispatchEvent(AWTEvent)
 476:    * @serial true to process event locally
 477:    */
 478:   boolean newEventsOnly;
 479: 
 480:   /**
 481:    * Set by subclasses to enable event handling of particular events, and
 482:    * left alone when modifying listeners. For component, this defaults to
 483:    * enabling only input methods.
 484:    *
 485:    * @see #enableInputMethods(boolean)
 486:    * @see AWTEvent
 487:    * @serial the mask of events to process
 488:    */
 489:   long eventMask = AWTEvent.INPUT_ENABLED_EVENT_MASK;
 490: 
 491:   /**
 492:    * Describes all registered PropertyChangeListeners.
 493:    *
 494:    * @see #addPropertyChangeListener(PropertyChangeListener)
 495:    * @see #removePropertyChangeListener(PropertyChangeListener)
 496:    * @see #firePropertyChange(String, Object, Object)
 497:    * @serial the property change listeners
 498:    * @since 1.2
 499:    */
 500:   PropertyChangeSupport changeSupport;
 501: 
 502:   /**
 503:    * True if the component has been packed (layed out).
 504:    *
 505:    * @serial true if this is packed
 506:    */
 507:   boolean isPacked;
 508: 
 509:   /**
 510:    * The serialization version for this class. Currently at version 4.
 511:    *
 512:    * XXX How do we handle prior versions?
 513:    *
 514:    * @serial the serialization version
 515:    */
 516:   int componentSerializedDataVersion = 4;
 517: 
 518:   /**
 519:    * The accessible context associated with this component. This is only set
 520:    * by subclasses.
 521:    *
 522:    * @see #getAccessibleContext()
 523:    * @serial the accessibility context
 524:    * @since 1.2
 525:    */
 526:   AccessibleContext accessibleContext;
 527: 
 528: 
 529:   // Guess what - listeners are special cased in serialization. See
 530:   // readObject and writeObject.
 531: 
 532:   /** Component listener chain. */
 533:   transient ComponentListener componentListener;
 534: 
 535:   /** Focus listener chain. */
 536:   transient FocusListener focusListener;
 537: 
 538:   /** Key listener chain. */
 539:   transient KeyListener keyListener;
 540: 
 541:   /** Mouse listener chain. */
 542:   transient MouseListener mouseListener;
 543: 
 544:   /** Mouse motion listener chain. */
 545:   transient MouseMotionListener mouseMotionListener;
 546: 
 547:   /**
 548:    * Mouse wheel listener chain.
 549:    *
 550:    * @since 1.4
 551:    */
 552:   transient MouseWheelListener mouseWheelListener;
 553: 
 554:   /**
 555:    * Input method listener chain.
 556:    *
 557:    * @since 1.2
 558:    */
 559:   transient InputMethodListener inputMethodListener;
 560: 
 561:   /**
 562:    * Hierarcy listener chain.
 563:    *
 564:    * @since 1.3
 565:    */
 566:   transient HierarchyListener hierarchyListener;
 567: 
 568:   /**
 569:    * Hierarcy bounds listener chain.
 570:    *
 571:    * @since 1.3
 572:    */
 573:   transient HierarchyBoundsListener hierarchyBoundsListener;
 574: 
 575:   // Anything else is non-serializable, and should be declared "transient".
 576: 
 577:   /** The parent. */
 578:   transient Container parent;
 579: 
 580:   /** The associated native peer. */
 581:   transient ComponentPeer peer;
 582: 
 583:   /** The preferred component orientation. */
 584:   transient ComponentOrientation componentOrientation = ComponentOrientation.UNKNOWN;
 585: 
 586:   /**
 587:    * The associated graphics configuration.
 588:    *
 589:    * @since 1.4
 590:    */
 591:   transient GraphicsConfiguration graphicsConfig;
 592: 
 593:   /**
 594:    * The buffer strategy for repainting.
 595:    *
 596:    * @since 1.4
 597:    */
 598:   transient BufferStrategy bufferStrategy;
 599: 
 600:   /**
 601:    * The number of hierarchy listeners of this container plus all of its
 602:    * children. This is needed for efficient handling of HierarchyEvents.
 603:    * These must be propagated to all child components with HierarchyListeners
 604:    * attached. To avoid traversal of the whole subtree, we keep track of
 605:    * the number of HierarchyListeners here and only walk the paths that
 606:    * actually have listeners.
 607:    */
 608:   int numHierarchyListeners;
 609:   int numHierarchyBoundsListeners;
 610: 
 611:   /**
 612:    * true if requestFocus was called on this component when its
 613:    * top-level ancestor was not focusable.
 614:    */
 615:   private transient FocusEvent pendingFocusRequest = null;
 616: 
 617:   /**
 618:    * The system properties that affect image updating.
 619:    */
 620:   private static transient boolean incrementalDraw;
 621:   private static transient Long redrawRate;
 622: 
 623:   static
 624:   {
 625:     incrementalDraw = Boolean.getBoolean ("awt.image.incrementalDraw");
 626:     redrawRate = Long.getLong ("awt.image.redrawrate");
 627:   }
 628: 
 629:   // Public and protected API.
 630: 
 631:   /**
 632:    * Default constructor for subclasses. When Component is extended directly,
 633:    * it forms a lightweight component that must be hosted in an opaque native
 634:    * container higher in the tree.
 635:    */
 636:   protected Component()
 637:   {
 638:     // Nothing to do here.
 639:   }
 640: 
 641:   /**
 642:    * Returns the name of this component.
 643:    *
 644:    * @return the name of this component
 645:    * @see #setName(String)
 646:    * @since 1.1
 647:    */
 648:   public String getName()
 649:   {
 650:     if (name == null && ! nameExplicitlySet)
 651:       name = generateName();
 652:     return name;
 653:   }
 654: 
 655:   /**
 656:    * Sets the name of this component to the specified name (this is a bound
 657:    * property with the name 'name').
 658:    *
 659:    * @param name the new name (<code>null</code> permitted).
 660:    * @see #getName()
 661:    * @since 1.1
 662:    */
 663:   public void setName(String name)
 664:   {
 665:     nameExplicitlySet = true;
 666:     String old = this.name;
 667:     this.name = name;
 668:     firePropertyChange("name", old, name);
 669:   }
 670: 
 671:   /**
 672:    * Returns the parent of this component.
 673:    *
 674:    * @return the parent of this component
 675:    */
 676:   public Container getParent()
 677:   {
 678:     return parent;
 679:   }
 680: 
 681:   /**
 682:    * Returns the native windowing system peer for this component. Only the
 683:    * platform specific implementation code should call this method.
 684:    *
 685:    * @return the peer for this component
 686:    * @deprecated user programs should not directly manipulate peers; use
 687:    *             {@link #isDisplayable()} instead
 688:    */
 689:   // Classpath's Gtk peers rely on this.
 690:   public ComponentPeer getPeer()
 691:   {
 692:     return peer;
 693:   }
 694: 
 695:   /**
 696:    * Set the associated drag-and-drop target, which receives events when this
 697:    * is enabled.
 698:    *
 699:    * @param dt the new drop target
 700:    * @see #isEnabled()
 701:    */
 702:   public void setDropTarget(DropTarget dt)
 703:   {
 704:     this.dropTarget = dt;
 705:     
 706:     if (peer != null)
 707:       dropTarget.addNotify(peer);
 708:   }
 709: 
 710:   /**
 711:    * Gets the associated drag-and-drop target, if there is one.
 712:    *
 713:    * @return the drop target
 714:    */
 715:   public DropTarget getDropTarget()
 716:   {
 717:     return dropTarget;
 718:   }
 719: 
 720:   /**
 721:    * Returns the graphics configuration of this component, if there is one.
 722:    * If it has not been set, it is inherited from the parent.
 723:    *
 724:    * @return the graphics configuration, or null
 725:    * @since 1.3
 726:    */
 727:   public GraphicsConfiguration getGraphicsConfiguration()
 728:   {
 729:     GraphicsConfiguration conf = null;
 730:     synchronized (getTreeLock())
 731:       {
 732:         if (graphicsConfig != null)
 733:           {
 734:             conf = graphicsConfig;
 735:           }
 736:         else
 737:           {
 738:             Component par = getParent();
 739:             if (par != null)
 740:               {
 741:                 conf = parent.getGraphicsConfiguration();
 742:               }
 743:           }
 744:       }
 745:     return conf;
 746:   }
 747: 
 748:   /**
 749:    * Returns the object used for synchronization locks on this component
 750:    * when performing tree and layout functions.
 751:    *
 752:    * @return the synchronization lock for this component
 753:    */
 754:   public final Object getTreeLock()
 755:   {
 756:     return treeLock;
 757:   }
 758: 
 759:   /**
 760:    * Returns the toolkit in use for this component. The toolkit is associated
 761:    * with the frame this component belongs to.
 762:    *
 763:    * @return the toolkit for this component
 764:    */
 765:   public Toolkit getToolkit()
 766:   {
 767:     // Only heavyweight peers can handle this.
 768:     ComponentPeer p = peer;
 769:     Component comp = this;
 770:     while (p instanceof LightweightPeer)
 771:       {
 772:         comp = comp.parent;
 773:         p = comp == null ? null : comp.peer;
 774:       }
 775: 
 776:     Toolkit tk = null;
 777:     if (p != null)
 778:       {
 779:         tk = peer.getToolkit();
 780:       }
 781:     if (tk == null)
 782:       tk = Toolkit.getDefaultToolkit();
 783:     return tk;
 784:   }
 785: 
 786:   /**
 787:    * Tests whether or not this component is valid. A invalid component needs
 788:    * to have its layout redone.
 789:    *
 790:    * @return true if this component is valid
 791:    * @see #validate()
 792:    * @see #invalidate()
 793:    */
 794:   public boolean isValid()
 795:   {
 796:     // Tests show that components are invalid as long as they are not showing, even after validate()
 797:     // has been called on them.
 798:     return peer != null && valid;
 799:   }
 800: 
 801:   /**
 802:    * Tests if the component is displayable. It must be connected to a native
 803:    * screen resource.  This reduces to checking that peer is not null.  A 
 804:    * containment  hierarchy is made displayable when a window is packed or 
 805:    * made visible.
 806:    *
 807:    * @return true if the component is displayable
 808:    * @see Container#add(Component)
 809:    * @see Container#remove(Component)
 810:    * @see Window#pack()
 811:    * @see Window#show()
 812:    * @see Window#dispose()
 813:    * @since 1.2
 814:    */
 815:   public boolean isDisplayable()
 816:   {
 817:     return peer != null;
 818:   }
 819: 
 820:   /**
 821:    * Tests whether or not this component is visible. Except for top-level
 822:    * frames, components are initially visible.
 823:    *
 824:    * @return true if the component is visible
 825:    * @see #setVisible(boolean)
 826:    */
 827:   public boolean isVisible()
 828:   {
 829:     return visible;
 830:   }
 831: 
 832:   /**
 833:    * Tests whether or not this component is actually being shown on
 834:    * the screen. This will be true if and only if it this component is
 835:    * visible and its parent components are all visible.
 836:    *
 837:    * @return true if the component is showing on the screen
 838:    * @see #setVisible(boolean)
 839:    */
 840:   public boolean isShowing()
 841:   {
 842:     Component par = parent;
 843:     return visible && peer != null && (par == null || par.isShowing());
 844:   }
 845: 
 846:   /**
 847:    * Tests whether or not this component is enabled. Components are enabled
 848:    * by default, and must be enabled to receive user input or generate events.
 849:    *
 850:    * @return true if the component is enabled
 851:    * @see #setEnabled(boolean)
 852:    */
 853:   public boolean isEnabled()
 854:   {
 855:     return enabled;
 856:   }
 857: 
 858:   /**
 859:    * Enables or disables this component. The component must be enabled to
 860:    * receive events (except that lightweight components always receive mouse
 861:    * events).
 862:    *
 863:    * @param enabled true to enable this component
 864:    * 
 865:    * @see #isEnabled()
 866:    * @see #isLightweight()
 867:    * 
 868:    * @since 1.1
 869:    */
 870:   public void setEnabled(boolean enabled)
 871:   {
 872:     enable(enabled);
 873:   }
 874: 
 875:   /**
 876:    * Enables this component.
 877:    *
 878:    * @deprecated use {@link #setEnabled(boolean)} instead
 879:    */
 880:   public void enable()
 881:   {
 882:     if (! enabled)
 883:       {
 884:         // Need to lock the tree here, because the peers are involved.
 885:         synchronized (getTreeLock())
 886:           {
 887:             enabled = true;
 888:             ComponentPeer p = peer;
 889:             if (p != null)
 890:               p.enable();
 891:           }
 892:       }
 893:   }
 894: 
 895:   /**
 896:    * Enables or disables this component.
 897:    *
 898:    * @param enabled true to enable this component
 899:    * 
 900:    * @deprecated use {@link #setEnabled(boolean)} instead
 901:    */
 902:   public void enable(boolean enabled)
 903:   {
 904:     if (enabled)
 905:       enable();
 906:     else
 907:       disable();
 908:   }
 909: 
 910:   /**
 911:    * Disables this component.
 912:    *
 913:    * @deprecated use {@link #setEnabled(boolean)} instead
 914:    */
 915:   public void disable()
 916:   {
 917:     if (enabled)
 918:       {
 919:         // Need to lock the tree here, because the peers are involved.
 920:         synchronized (getTreeLock())
 921:           {
 922:             enabled = false;
 923:             ComponentPeer p = peer;
 924:             if (p != null)
 925:               p.disable();
 926:           }
 927:       }
 928:   }
 929: 
 930:   /**
 931:    * Checks if this image is painted to an offscreen image buffer that is
 932:    * later copied to screen (double buffering reduces flicker). This version
 933:    * returns false, so subclasses must override it if they provide double
 934:    * buffering.
 935:    *
 936:    * @return true if this is double buffered; defaults to false
 937:    */
 938:   public boolean isDoubleBuffered()
 939:   {
 940:     return false;
 941:   }
 942: 
 943:   /**
 944:    * Enables or disables input method support for this component. By default,
 945:    * components have this enabled. Input methods are given the opportunity
 946:    * to process key events before this component and its listeners.
 947:    *
 948:    * @param enable true to enable input method processing
 949:    * @see #processKeyEvent(KeyEvent)
 950:    * @since 1.2
 951:    */
 952:   public void enableInputMethods(boolean enable)
 953:   {
 954:     if (enable)
 955:       eventMask |= AWTEvent.INPUT_ENABLED_EVENT_MASK;
 956:     else
 957:       eventMask &= ~AWTEvent.INPUT_ENABLED_EVENT_MASK;
 958:   }
 959: 
 960:   /**
 961:    * Makes this component visible or invisible. Note that it wtill might
 962:    * not show the component, if a parent is invisible.
 963:    *
 964:    * @param visible true to make this component visible
 965:    * 
 966:    * @see #isVisible()
 967:    * 
 968:    * @since 1.1
 969:    */
 970:   public void setVisible(boolean visible)
 971:   {
 972:     // Inspection by subclassing shows that Sun's implementation calls
 973:     // show(boolean) which then calls show() or hide(). It is the show()
 974:     // method that is overriden in subclasses like Window.
 975:     show(visible);
 976:   }
 977: 
 978:   /**
 979:    * Makes this component visible on the screen.
 980:    *
 981:    * @deprecated use {@link #setVisible(boolean)} instead
 982:    */
 983:   public void show()
 984:   {
 985:     // We must set visible before showing the peer.  Otherwise the
 986:     // peer could post paint events before visible is true, in which
 987:     // case lightweight components are not initially painted --
 988:     // Container.paint first calls isShowing () before painting itself
 989:     // and its children.
 990:     if(! visible)
 991:       {
 992:         // Need to lock the tree here to avoid races and inconsistencies.
 993:         synchronized (getTreeLock())
 994:           {
 995:             visible = true;
 996:             // Avoid NullPointerExceptions by creating a local reference.
 997:             ComponentPeer currentPeer = peer;
 998:             if (currentPeer != null)
 999:               {
1000:                 currentPeer.show();
1001: 
1002:                 // Fire HierarchyEvent.
1003:                 fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED,
1004:                                    this, parent,
1005:                                    HierarchyEvent.SHOWING_CHANGED);
1006: 
1007:                 // The JDK repaints the component before invalidating the parent.
1008:                 // So do we.
1009:                 if (peer instanceof LightweightPeer)
1010:                   repaint();
1011:               }
1012: 
1013:             // Only post an event if this component actually has a listener
1014:             // or has this event explicitly enabled.
1015:             if (componentListener != null
1016:                 || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0)
1017:               {
1018:                 ComponentEvent ce =
1019:                   new ComponentEvent(this,ComponentEvent.COMPONENT_SHOWN);
1020:                 getToolkit().getSystemEventQueue().postEvent(ce);
1021:               }
1022:           }
1023: 
1024:         // Invalidate the parent if we have one. The component itself must
1025:         // not be invalidated. We also avoid NullPointerException with
1026:         // a local reference here.
1027:         Container currentParent = parent;
1028:         if (currentParent != null)
1029:           currentParent.invalidate();
1030: 
1031:       }
1032:   }
1033: 
1034:   /**
1035:    * Makes this component visible or invisible.
1036:    *
1037:    * @param visible true to make this component visible
1038:    * 
1039:    * @deprecated use {@link #setVisible(boolean)} instead
1040:    */
1041:   public void show(boolean visible)
1042:   {
1043:     if (visible)
1044:       show();
1045:     else
1046:       hide();
1047:   }
1048: 
1049:   /**
1050:    * Hides this component so that it is no longer shown on the screen.
1051:    *
1052:    * @deprecated use {@link #setVisible(boolean)} instead
1053:    */
1054:   public void hide()
1055:   {
1056:     if (visible)
1057:       {
1058:         // Need to lock the tree here to avoid races and inconsistencies.
1059:         synchronized (getTreeLock())
1060:           {
1061:             visible = false;
1062: 
1063:             // Avoid NullPointerExceptions by creating a local reference.
1064:             ComponentPeer currentPeer = peer;
1065:             if (currentPeer != null)
1066:               {
1067:                 currentPeer.hide();
1068: 
1069:                 // Fire hierarchy event.
1070:                 fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED,
1071:                                    this, parent,
1072:                                    HierarchyEvent.SHOWING_CHANGED);
1073:                 // The JDK repaints the component before invalidating the
1074:                 // parent. So do we. This only applies for lightweights.
1075:                 if (peer instanceof LightweightPeer)
1076:                   repaint();
1077:               }
1078: 
1079:             // Only post an event if this component actually has a listener
1080:             // or has this event explicitly enabled.
1081:             if (componentListener != null
1082:                 || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0)
1083:               {
1084:                 ComponentEvent ce =
1085:                   new ComponentEvent(this,ComponentEvent.COMPONENT_HIDDEN);
1086:                 getToolkit().getSystemEventQueue().postEvent(ce);
1087:               }
1088:           }
1089: 
1090:         // Invalidate the parent if we have one. The component itself need
1091:         // not be invalidated. We also avoid NullPointerException with
1092:         // a local reference here.
1093:         Container currentParent = parent;
1094:         if (currentParent != null)
1095:           currentParent.invalidate();
1096: 
1097:       }
1098:   }
1099: 
1100:   /**
1101:    * Returns this component's foreground color. If not set, this is inherited
1102:    * from the parent.
1103:    *
1104:    * @return this component's foreground color, or null
1105:    * @see #setForeground(Color)
1106:    */
1107:   public Color getForeground()
1108:   {
1109:     if (foreground != null)
1110:       return foreground;
1111:     return parent == null ? null : parent.getForeground();
1112:   }
1113: 
1114:   /**
1115:    * Sets this component's foreground color to the specified color. This is a
1116:    * bound property.
1117:    *
1118:    * @param c the new foreground color
1119:    * @see #getForeground()
1120:    */
1121:   public void setForeground(Color c)
1122:   {
1123:     if (peer != null)
1124:       peer.setForeground(c);
1125:     
1126:     Color previous = foreground;
1127:     foreground = c;
1128:     firePropertyChange("foreground", previous, c);
1129:   }
1130: 
1131:   /**
1132:    * Tests if the foreground was explicitly set, or just inherited from the
1133:    * parent.
1134:    *
1135:    * @return true if the foreground has been set
1136:    * @since 1.4
1137:    */
1138:   public boolean isForegroundSet()
1139:   {
1140:     return foreground != null;
1141:   }
1142: 
1143:   /**
1144:    * Returns this component's background color. If not set, this is inherited
1145:    * from the parent.
1146:    *
1147:    * @return the background color of the component, or null
1148:    * @see #setBackground(Color)
1149:    */
1150:   public Color getBackground()
1151:   {
1152:     if (background != null)
1153:       return background;
1154:     return parent == null ? null : parent.getBackground();
1155:   }
1156: 
1157:   /**
1158:    * Sets this component's background color to the specified color. The parts
1159:    * of the component affected by the background color may by system dependent.
1160:    * This is a bound property.
1161:    *
1162:    * @param c the new background color
1163:    * @see #getBackground()
1164:    */
1165:   public void setBackground(Color c)
1166:   {
1167:     // return if the background is already set to that color.
1168:     if ((c != null) && c.equals(background))
1169:       return;
1170: 
1171:     Color previous = background;
1172:     background = c;
1173:     if (peer != null && c != null)
1174:       peer.setBackground(c);
1175:     firePropertyChange("background", previous, c);
1176:   }
1177: 
1178:   /**
1179:    * Tests if the background was explicitly set, or just inherited from the
1180:    * parent.
1181:    *
1182:    * @return true if the background has been set
1183:    * @since 1.4
1184:    */
1185:   public boolean isBackgroundSet()
1186:   {
1187:     return background != null;
1188:   }
1189: 
1190:   /**
1191:    * Returns the font in use for this component. If not set, this is inherited
1192:    * from the parent.
1193:    *
1194:    * @return the font for this component
1195:    * @see #setFont(Font)
1196:    */
1197:   public Font getFont()
1198:   {
1199:     return getFontImpl();
1200:   }
1201: 
1202:   /**
1203:    * Implementation of getFont(). This is pulled out of getFont() to prevent
1204:    * client programs from overriding this.
1205:    *
1206:    * @return the font of this component
1207:    */
1208:   private final Font getFontImpl()
1209:   {
1210:     Font f = font;
1211:     if (f == null)
1212:       {
1213:         Component p = parent;
1214:         if (p != null)
1215:           f = p.getFontImpl();
1216:         else
1217:           {
1218:             // It is important to return null here and not some kind of default
1219:             // font, otherwise the Swing UI would not install its fonts because
1220:             // it keeps non-UIResource fonts.
1221:             f = null;
1222:           }
1223:       }
1224:     return f;
1225:   }
1226: 
1227:   /**
1228:    * Sets the font for this component to the specified font. This is a bound
1229:    * property.
1230:    *
1231:    * @param f the new font for this component
1232:    * 
1233:    * @see #getFont()
1234:    */
1235:   public void setFont(Font f)
1236:   {
1237:     Font oldFont;
1238:     Font newFont;
1239:     // Synchronize on the tree because getFontImpl() relies on the hierarchy
1240:     // not beeing changed.
1241:     synchronized (getTreeLock())
1242:       {
1243:         // Synchronize on this here to guarantee thread safety wrt to the
1244:         // property values.
1245:         synchronized (this)
1246:           {
1247:             oldFont = font;
1248:             font = f;
1249:             newFont = f;
1250:           }
1251:         // Create local variable here for thread safety.
1252:         ComponentPeer p = peer;
1253:         if (p != null)
1254:           {
1255:             // The peer receives the real font setting, which can depend on 
1256:             // the parent font when this component's font has been set to null.
1257:             f = getFont();
1258:             if (f != null)
1259:               {
1260:                 p.setFont(f);
1261:                 peerFont = f;
1262:               }
1263:           }
1264:       }
1265: 
1266:     // Fire property change event.
1267:     firePropertyChange("font", oldFont, newFont);
1268: 
1269:     // Invalidate when necessary as font changes can change the size of the
1270:     // component.
1271:     if (valid)
1272:       invalidate();
1273:   }
1274: 
1275:   /**
1276:    * Tests if the font was explicitly set, or just inherited from the parent.
1277:    *
1278:    * @return true if the font has been set
1279:    * @since 1.4
1280:    */
1281:   public boolean isFontSet()
1282:   {
1283:     return font != null;
1284:   }
1285: 
1286:   /**
1287:    * Returns the locale for this component. If this component does not
1288:    * have a locale, the locale of the parent component is returned.
1289:    *
1290:    * @return the locale for this component
1291:    * @throws IllegalComponentStateException if it has no locale or parent
1292:    * @see #setLocale(Locale)
1293:    * @since 1.1
1294:    */
1295:   public Locale getLocale()
1296:   {
1297:     if (locale != null)
1298:       return locale;
1299:     if (parent == null)
1300:       throw new IllegalComponentStateException
1301:         ("Component has no parent: can't determine Locale");
1302:     return parent.getLocale();
1303:   }
1304: 
1305:   /**
1306:    * Sets the locale for this component to the specified locale. This is a
1307:    * bound property.
1308:    *
1309:    * @param newLocale the new locale for this component
1310:    */
1311:   public void setLocale(Locale newLocale)
1312:   {
1313:     if (locale == newLocale)
1314:       return;
1315: 
1316:     Locale oldLocale = locale;
1317:     locale = newLocale;
1318:     firePropertyChange("locale", oldLocale, newLocale);
1319:     // New writing/layout direction or more/less room for localized labels.
1320:     invalidate();
1321:   }
1322: 
1323:   /**
1324:    * Returns the color model of the device this componet is displayed on.
1325:    *
1326:    * @return this object's color model
1327:    * @see Toolkit#getColorModel()
1328:    */
1329:   public ColorModel getColorModel()
1330:   {
1331:     GraphicsConfiguration config = getGraphicsConfiguration();
1332:     return config != null ? config.getColorModel()
1333:       : getToolkit().getColorModel();
1334:   }
1335: 
1336:   /**
1337:    * Returns the location of this component's top left corner relative to
1338:    * its parent component. This may be outdated, so for synchronous behavior,
1339:    * you should use a component listner.
1340:    *
1341:    * @return the location of this component
1342:    * @see #setLocation(int, int)
1343:    * @see #getLocationOnScreen()
1344:    * @since 1.1
1345:    */
1346:   public Point getLocation()
1347:   {
1348:     return location ();
1349:   }
1350: 
1351:   /**
1352:    * Returns the location of this component's top left corner in screen
1353:    * coordinates.
1354:    *
1355:    * @return the location of this component in screen coordinates
1356:    * @throws IllegalComponentStateException if the component is not showing
1357:    */
1358:   public Point getLocationOnScreen()
1359:   {
1360:     if (! isShowing())
1361:       throw new IllegalComponentStateException("component "
1362:                                                + getClass().getName()
1363:                                                + " not showing");
1364: 
1365:     // Need to lock the tree here. We get crazy races and explosions when
1366:     // the tree changes while we are trying to find the location of this
1367:     // component.
1368:     synchronized (getTreeLock())
1369:       {
1370:         // Only a heavyweight peer can answer the question for the screen
1371:         // location. So we are going through the hierarchy until we find
1372:         // one and add up the offsets while doing so.
1373:         int offsX = 0;
1374:         int offsY = 0;
1375:         ComponentPeer p = peer;
1376:         Component comp = this;
1377:         while (p instanceof LightweightPeer)
1378:           {
1379:             offsX += comp.x;
1380:             offsY += comp.y;
1381:             comp = comp.parent;
1382:             p = comp == null ? null: comp.peer;
1383:           }
1384:         // Now we have a heavyweight component.
1385:         assert ! (p instanceof LightweightPeer);
1386:         Point loc = p.getLocationOnScreen();
1387:         loc.x += offsX;
1388:         loc.y += offsY;
1389:         return loc;
1390:       }
1391:   }
1392: 
1393:   /**
1394:    * Returns the location of this component's top left corner relative to
1395:    * its parent component.
1396:    *
1397:    * @return the location of this component
1398:    * @deprecated use {@link #getLocation()} instead
1399:    */
1400:   public Point location()
1401:   {
1402:     return new Point (x, y);
1403:   }
1404: 
1405:   /**
1406:    * Moves this component to the specified location, relative to the parent's
1407:    * coordinates. The coordinates are the new upper left corner of this
1408:    * component.
1409:    *
1410:    * @param x the new X coordinate of this component
1411:    * @param y the new Y coordinate of this component
1412:    * @see #getLocation()
1413:    * @see #setBounds(int, int, int, int)
1414:    */
1415:   public void setLocation(int x, int y)
1416:   {
1417:     move (x, y);
1418:   }
1419: 
1420:   /**
1421:    * Moves this component to the specified location, relative to the parent's
1422:    * coordinates. The coordinates are the new upper left corner of this
1423:    * component.
1424:    *
1425:    * @param x the new X coordinate of this component
1426:    * @param y the new Y coordinate of this component
1427:    * @deprecated use {@link #setLocation(int, int)} instead
1428:    */
1429:   public void move(int x, int y)
1430:   {
1431:     setBounds(x, y, this.width, this.height);
1432:   }
1433: 
1434:   /**
1435:    * Moves this component to the specified location, relative to the parent's
1436:    * coordinates. The coordinates are the new upper left corner of this
1437:    * component.
1438:    *
1439:    * @param p new coordinates for this component
1440:    * @throws NullPointerException if p is null
1441:    * @see #getLocation()
1442:    * @see #setBounds(int, int, int, int)
1443:    * @since 1.1
1444:    */
1445:   public void setLocation(Point p)
1446:   {
1447:     setLocation(p.x, p.y);
1448:   }
1449: 
1450:   /**
1451:    * Returns the size of this object.
1452:    *
1453:    * @return the size of this object
1454:    * @see #setSize(int, int)
1455:    * @since 1.1
1456:    */
1457:   public Dimension getSize()
1458:   {
1459:     return size ();
1460:   }
1461: 
1462:   /**
1463:    * Returns the size of this object.
1464:    *
1465:    * @return the size of this object
1466:    * @deprecated use {@link #getSize()} instead
1467:    */
1468:   public Dimension size()
1469:   {
1470:     return new Dimension (width, height);
1471:   }
1472: 
1473:   /**
1474:    * Sets the size of this component to the specified width and height.
1475:    *
1476:    * @param width the new width of this component
1477:    * @param height the new height of this component
1478:    * @see #getSize()
1479:    * @see #setBounds(int, int, int, int)
1480:    */
1481:   public void setSize(int width, int height)
1482:   {
1483:     resize (width, height);
1484:   }
1485: 
1486:   /**
1487:    * Sets the size of this component to the specified value.
1488:    *
1489:    * @param width the new width of the component
1490:    * @param height the new height of the component
1491:    * @deprecated use {@link #setSize(int, int)} instead
1492:    */
1493:   public void resize(int width, int height)
1494:   {
1495:     setBounds(this.x, this.y, width, height);
1496:   }
1497: 
1498:   /**
1499:    * Sets the size of this component to the specified value.
1500:    *
1501:    * @param d the new size of this component
1502:    * @throws NullPointerException if d is null
1503:    * @see #setSize(int, int)
1504:    * @see #setBounds(int, int, int, int)
1505:    * @since 1.1
1506:    */
1507:   public void setSize(Dimension d)
1508:   {
1509:     resize (d);
1510:   }
1511: 
1512:   /**
1513:    * Sets the size of this component to the specified value.
1514:    *
1515:    * @param d the new size of this component
1516:    * @throws NullPointerException if d is null
1517:    * @deprecated use {@link #setSize(Dimension)} instead
1518:    */
1519:   public void resize(Dimension d)
1520:   {
1521:     resize (d.width, d.height);
1522:   }
1523: 
1524:   /**
1525:    * Returns a bounding rectangle for this component. Note that the
1526:    * returned rectange is relative to this component's parent, not to
1527:    * the screen.
1528:    *
1529:    * @return the bounding rectangle for this component
1530:    * @see #setBounds(int, int, int, int)
1531:    * @see #getLocation()
1532:    * @see #getSize()
1533:    */
1534:   public Rectangle getBounds()
1535:   {
1536:     return bounds ();
1537:   }
1538: 
1539:   /**
1540:    * Returns a bounding rectangle for this component. Note that the
1541:    * returned rectange is relative to this component's parent, not to
1542:    * the screen.
1543:    *
1544:    * @return the bounding rectangle for this component
1545:    * @deprecated use {@link #getBounds()} instead
1546:    */
1547:   public Rectangle bounds()
1548:   {
1549:     return new Rectangle (x, y, width, height);
1550:   }
1551: 
1552:   /**
1553:    * Sets the bounding rectangle for this component to the specified values.
1554:    * Note that these coordinates are relative to the parent, not to the screen.
1555:    *
1556:    * @param x the X coordinate of the upper left corner of the rectangle
1557:    * @param y the Y coordinate of the upper left corner of the rectangle
1558:    * @param w the width of the rectangle
1559:    * @param h the height of the rectangle
1560:    * @see #getBounds()
1561:    * @see #setLocation(int, int)
1562:    * @see #setLocation(Point)
1563:    * @see #setSize(int, int)
1564:    * @see #setSize(Dimension)
1565:    * @since 1.1
1566:    */
1567:   public void setBounds(int x, int y, int w, int h)
1568:   {
1569:     reshape (x, y, w, h);
1570:   }
1571: 
1572:   /**
1573:    * Sets the bounding rectangle for this component to the specified values.
1574:    * Note that these coordinates are relative to the parent, not to the screen.
1575:    *
1576:    * @param x the X coordinate of the upper left corner of the rectangle
1577:    * @param y the Y coordinate of the upper left corner of the rectangle
1578:    * @param width the width of the rectangle
1579:    * @param height the height of the rectangle
1580:    * @deprecated use {@link #setBounds(int, int, int, int)} instead
1581:    */
1582:   public void reshape(int x, int y, int width, int height)
1583:   {
1584:     // We need to lock the tree here, otherwise we risk races and
1585:     // inconsistencies.
1586:     synchronized (getTreeLock())
1587:       {
1588:         int oldx = this.x;
1589:         int oldy = this.y;
1590:         int oldwidth = this.width;
1591:         int oldheight = this.height;
1592:     
1593:         boolean resized = oldwidth != width || oldheight != height;
1594:         boolean moved = oldx != x || oldy != y;
1595: 
1596:         if (resized || moved)
1597:           {
1598:             // Update the fields.
1599:             this.x = x;
1600:             this.y = y;
1601:             this.width = width;
1602:             this.height = height;
1603: 
1604:             if (peer != null)
1605:               {
1606:                 peer.setBounds (x, y, width, height);
1607:                 if (resized)
1608:                   invalidate();
1609:                 if (parent != null && parent.valid)
1610:                   parent.invalidate();
1611:               }
1612: 
1613:             // Send some events to interested listeners.
1614:             notifyReshape(resized, moved);
1615: 
1616:             // Repaint this component and the parent if appropriate.
1617:             if (parent != null && peer instanceof LightweightPeer
1618:                 && isShowing())
1619:               {
1620:                 // The parent repaints the area that we occupied before.
1621:                 parent.repaint(oldx, oldy, oldwidth, oldheight);
1622:                 // This component repaints the area that we occupy now.
1623:                 repaint();
1624:               }
1625:           }
1626:       }
1627:   }
1628: 
1629:   /**
1630:    * Sends notification to interested listeners about resizing and/or moving
1631:    * the component. If this component has interested
1632:    * component listeners or the corresponding event mask enabled, then
1633:    * COMPONENT_MOVED and/or COMPONENT_RESIZED events are posted to the event
1634:    * queue.
1635:    *
1636:    * @param resized true if the component has been resized, false otherwise
1637:    * @param moved true if the component has been moved, false otherwise
1638:    */
1639:   void notifyReshape(boolean resized, boolean moved)
1640:   {
1641:     // Only post an event if this component actually has a listener
1642:     // or has this event explicitly enabled.
1643:     if (componentListener != null
1644:         || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0)
1645:       {
1646:         // Fire component event on this component.
1647:         if (moved)
1648:           {
1649:             ComponentEvent ce = new ComponentEvent(this,
1650:                                                ComponentEvent.COMPONENT_MOVED);
1651:             getToolkit().getSystemEventQueue().postEvent(ce);
1652:           }
1653:         if (resized)
1654:           {
1655:             ComponentEvent ce = new ComponentEvent(this,
1656:                                              ComponentEvent.COMPONENT_RESIZED);
1657:             getToolkit().getSystemEventQueue().postEvent(ce);
1658:           }
1659:       }
1660:   }
1661: 
1662:   /**
1663:    * Sets the bounding rectangle for this component to the specified
1664:    * rectangle. Note that these coordinates are relative to the parent, not
1665:    * to the screen.
1666:    *
1667:    * @param r the new bounding rectangle
1668:    * @throws NullPointerException if r is null
1669:    * @see #getBounds()
1670:    * @see #setLocation(Point)
1671:    * @see #setSize(Dimension)
1672:    * @since 1.1
1673:    */
1674:   public void setBounds(Rectangle r)
1675:   {
1676:     setBounds (r.x, r.y, r.width, r.height);
1677:   }
1678: 
1679:   /**
1680:    * Gets the x coordinate of the upper left corner. This is more efficient
1681:    * than getBounds().x or getLocation().x.
1682:    *
1683:    * @return the current x coordinate
1684:    * @since 1.2
1685:    */
1686:   public int getX()
1687:   {
1688:     return x;
1689:   }
1690: 
1691:   /**
1692:    * Gets the y coordinate of the upper left corner. This is more efficient
1693:    * than getBounds().y or getLocation().y.
1694:    *
1695:    * @return the current y coordinate
1696:    * @since 1.2
1697:    */
1698:   public int getY()
1699:   {
1700:     return y;
1701:   }
1702: 
1703:   /**
1704:    * Gets the width of the component. This is more efficient than
1705:    * getBounds().width or getSize().width.
1706:    *
1707:    * @return the current width
1708:    * @since 1.2
1709:    */
1710:   public int getWidth()
1711:   {
1712:     return width;
1713:   }
1714: 
1715:   /**
1716:    * Gets the height of the component. This is more efficient than
1717:    * getBounds().height or getSize().height.
1718:    *
1719:    * @return the current width
1720:    * @since 1.2
1721:    */
1722:   public int getHeight()
1723:   {
1724:     return height;
1725:   }
1726: 
1727:   /**
1728:    * Returns the bounds of this component. This allows reuse of an existing
1729:    * rectangle, if r is non-null.
1730:    *
1731:    * @param r the rectangle to use, or null
1732:    * @return the bounds
1733:    */
1734:   public Rectangle getBounds(Rectangle r)
1735:   {
1736:     if (r == null)
1737:       r = new Rectangle();
1738:     r.x = x;
1739:     r.y = y;
1740:     r.width = width;
1741:     r.height = height;
1742:     return r;
1743:   }
1744: 
1745:   /**
1746:    * Returns the size of this component. This allows reuse of an existing
1747:    * dimension, if d is non-null.
1748:    *
1749:    * @param d the dimension to use, or null
1750:    * @return the size
1751:    */
1752:   public Dimension getSize(Dimension d)
1753:   {
1754:     if (d == null)
1755:       d = new Dimension();
1756:     d.width = width;
1757:     d.height = height;
1758:     return d;
1759:   }
1760: 
1761:   /**
1762:    * Returns the location of this component. This allows reuse of an existing
1763:    * point, if p is non-null.
1764:    *
1765:    * @param p the point to use, or null
1766:    * @return the location
1767:    */
1768:   public Point getLocation(Point p)
1769:   {
1770:     if (p == null)
1771:       p = new Point();
1772:     p.x = x;
1773:     p.y = y;
1774:     return p;
1775:   }
1776: 
1777:   /**
1778:    * Tests if this component is opaque. All "heavyweight" (natively-drawn)
1779:    * components are opaque. A component is opaque if it draws all pixels in
1780:    * the bounds; a lightweight component is partially transparent if it lets
1781:    * pixels underneath show through. Subclasses that guarantee that all pixels
1782:    * will be drawn should override this.
1783:    *
1784:    * @return true if this is opaque
1785:    * @see #isLightweight()
1786:    * @since 1.2
1787:    */
1788:   public boolean isOpaque()
1789:   {
1790:     return ! isLightweight();
1791:   }
1792: 
1793:   /**
1794:    * Return whether the component is lightweight. That means the component has
1795:    * no native peer, but is displayable. This applies to subclasses of
1796:    * Component not in this package, such as javax.swing.
1797:    *
1798:    * @return true if the component has a lightweight peer
1799:    * @see #isDisplayable()
1800:    * @since 1.2
1801:    */
1802:   public boolean isLightweight()
1803:   {
1804:     return peer instanceof LightweightPeer;
1805:   }
1806: 
1807:   /**
1808:    * Returns the component's preferred size.
1809:    *
1810:    * @return the component's preferred size
1811:    * @see #getMinimumSize()
1812:    * @see #setPreferredSize(Dimension)
1813:    * @see LayoutManager
1814:    */
1815:   public Dimension getPreferredSize()
1816:   {
1817:     return preferredSize();
1818:   }
1819: 
1820:   /**
1821:    * Sets the preferred size that will be returned by 
1822:    * {@link #getPreferredSize()} always, and sends a 
1823:    * {@link PropertyChangeEvent} (with the property name 'preferredSize') to 
1824:    * all registered listeners.
1825:    * 
1826:    * @param size  the preferred size (<code>null</code> permitted).
1827:    * 
1828:    * @since 1.5
1829:    * 
1830:    * @see #getPreferredSize()
1831:    */
1832:   public void setPreferredSize(Dimension size)
1833:   {
1834:     Dimension old = prefSizeSet ? prefSize : null;
1835:     prefSize = size;
1836:     prefSizeSet = (size != null);
1837:     firePropertyChange("preferredSize", old, size);
1838:   }
1839:   
1840:   /**
1841:    * Returns <code>true</code> if the current preferred size is not 
1842:    * <code>null</code> and was set by a call to 
1843:    * {@link #setPreferredSize(Dimension)}, otherwise returns <code>false</code>.
1844:    * 
1845:    * @return A boolean.
1846:    * 
1847:    * @since 1.5
1848:    */
1849:   public boolean isPreferredSizeSet()
1850:   {
1851:     return prefSizeSet;
1852:   }
1853:   
1854:   /**
1855:    * Returns the component's preferred size.
1856:    *
1857:    * @return the component's preferred size
1858:    * @deprecated use {@link #getPreferredSize()} instead
1859:    */
1860:   public Dimension preferredSize()
1861:   {
1862:     // Create a new Dimension object, so that the application doesn't mess
1863:     // with the actual values.
1864:     return new Dimension(preferredSizeImpl());
1865:   }
1866: 
1867:   /**
1868:    * The actual calculation is pulled out of preferredSize() so that
1869:    * we can call it from Container.preferredSize() and avoid creating a
1870:    * new intermediate Dimension object.
1871:    * 
1872:    * @return the preferredSize of the component
1873:    */
1874:   Dimension preferredSizeImpl()
1875:   {
1876:     Dimension size = prefSize;
1877:     // Try to use a cached value.
1878:     if (size == null || !(valid || prefSizeSet))
1879:       {
1880:         // We need to lock here, because the calculation depends on the
1881:         // component structure not changing.
1882:         synchronized (getTreeLock())
1883:           {
1884:             ComponentPeer p = peer;
1885:             if (p != null)
1886:               size = peer.preferredSize();
1887:             else
1888:               size = minimumSizeImpl();
1889:           }
1890:       }
1891:     return size;
1892:   }
1893: 
1894:   /**
1895:    * Returns the component's minimum size.
1896:    * 
1897:    * @return the component's minimum size
1898:    * @see #getPreferredSize()
1899:    * @see #setMinimumSize(Dimension)
1900:    * @see LayoutManager
1901:    */
1902:   public Dimension getMinimumSize()
1903:   {
1904:     return minimumSize();
1905:   }
1906: 
1907:   /**
1908:    * Sets the minimum size that will be returned by {@link #getMinimumSize()}
1909:    * always, and sends a {@link PropertyChangeEvent} (with the property name
1910:    * 'minimumSize') to all registered listeners.
1911:    * 
1912:    * @param size  the minimum size (<code>null</code> permitted).
1913:    * 
1914:    * @since 1.5
1915:    * 
1916:    * @see #getMinimumSize()
1917:    */
1918:   public void setMinimumSize(Dimension size)
1919:   {
1920:     Dimension old = minSizeSet ? minSize : null;
1921:     minSize = size;
1922:     minSizeSet = (size != null);
1923:     firePropertyChange("minimumSize", old, size);
1924:   }
1925:   
1926:   /**
1927:    * Returns <code>true</code> if the current minimum size is not 
1928:    * <code>null</code> and was set by a call to 
1929:    * {@link #setMinimumSize(Dimension)}, otherwise returns <code>false</code>.
1930:    * 
1931:    * @return A boolean.
1932:    * 
1933:    * @since 1.5
1934:    */
1935:   public boolean isMinimumSizeSet()
1936:   {
1937:     return minSizeSet;
1938:   }
1939:   
1940:   /**
1941:    * Returns the component's minimum size.
1942:    *
1943:    * @return the component's minimum size
1944:    * @deprecated use {@link #getMinimumSize()} instead
1945:    */
1946:   public Dimension minimumSize()
1947:   {
1948:     // Create a new Dimension object, so that the application doesn't mess
1949:     // with the actual values.
1950:     return new Dimension(minimumSizeImpl());
1951:   }
1952: 
1953:   /**
1954:    * The actual calculation is pulled out of minimumSize() so that
1955:    * we can call it from Container.preferredSize() and
1956:    * Component.preferredSizeImpl and avoid creating a
1957:    * new intermediate Dimension object.
1958:    * 
1959:    * @return the minimum size of the component
1960:    */
1961:   Dimension minimumSizeImpl()
1962:   {
1963:     Dimension size = minSize;
1964:     if (size == null || !(valid || minSizeSet))
1965:       {
1966:         // We need to lock here, because the calculation depends on the
1967:         // component structure not changing.
1968:         synchronized (getTreeLock())
1969:           {
1970:             ComponentPeer p = peer;
1971:             if (p != null)
1972:               size = peer.minimumSize();
1973:             else
1974:               size = size();
1975:           }
1976:       }
1977:     return size;
1978:   }
1979: 
1980:   /**
1981:    * Returns the component's maximum size.
1982:    *
1983:    * @return the component's maximum size
1984:    * @see #getMinimumSize()
1985:    * @see #setMaximumSize(Dimension)
1986:    * @see #getPreferredSize()
1987:    * @see LayoutManager
1988:    */
1989:   public Dimension getMaximumSize()
1990:   {
1991:     return new Dimension(maximumSizeImpl());
1992:   }
1993: 
1994:   /**
1995:    * This is pulled out from getMaximumSize(), so that we can access it
1996:    * from Container.getMaximumSize() without creating an additional
1997:    * intermediate Dimension object.
1998:    *
1999:    * @return the maximum size of the component
2000:    */
2001:   Dimension maximumSizeImpl()
2002:   {
2003:     Dimension size;
2004:     if (maxSizeSet)
2005:       size = maxSize;
2006:     else
2007:       size = DEFAULT_MAX_SIZE;
2008:     return size;
2009:   }
2010: 
2011:   /**
2012:    * Sets the maximum size that will be returned by {@link #getMaximumSize()}
2013:    * always, and sends a {@link PropertyChangeEvent} (with the property name
2014:    * 'maximumSize') to all registered listeners.
2015:    * 
2016:    * @param size  the maximum size (<code>null</code> permitted).
2017:    * 
2018:    * @since 1.5
2019:    * 
2020:    * @see #getMaximumSize()
2021:    */
2022:   public void setMaximumSize(Dimension size)
2023:   {
2024:     Dimension old = maxSizeSet ? maxSize : null;
2025:     maxSize = size;
2026:     maxSizeSet = (size != null);
2027:     firePropertyChange("maximumSize", old, size);
2028:   }
2029: 
2030:   /**
2031:    * Returns <code>true</code> if the current maximum size is not 
2032:    * <code>null</code> and was set by a call to 
2033:    * {@link #setMaximumSize(Dimension)}, otherwise returns <code>false</code>.
2034:    * 
2035:    * @return A boolean.
2036:    * 
2037:    * @since 1.5
2038:    */
2039:   public boolean isMaximumSizeSet()
2040:   {
2041:     return maxSizeSet;
2042:   }
2043:   
2044:   /**
2045:    * Returns the preferred horizontal alignment of this component. The value
2046:    * returned will be between {@link #LEFT_ALIGNMENT} and
2047:    * {@link #RIGHT_ALIGNMENT}, inclusive.
2048:    *
2049:    * @return the preferred horizontal alignment of this component
2050:    */
2051:   public float getAlignmentX()
2052:   {
2053:     return CENTER_ALIGNMENT;
2054:   }
2055: 
2056:   /**
2057:    * Returns the preferred vertical alignment of this component. The value
2058:    * returned will be between {@link #TOP_ALIGNMENT} and
2059:    * {@link #BOTTOM_ALIGNMENT}, inclusive.
2060:    *
2061:    * @return the preferred vertical alignment of this component
2062:    */
2063:   public float getAlignmentY()
2064:   {
2065:     return CENTER_ALIGNMENT;
2066:   }
2067: 
2068:   /**
2069:    * Calls the layout manager to re-layout the component. This is called
2070:    * during validation of a container in most cases.
2071:    *
2072:    * @see #validate()
2073:    * @see LayoutManager
2074:    */
2075:   public void doLayout()
2076:   {
2077:     layout ();
2078:   }
2079: 
2080:   /**
2081:    * Calls the layout manager to re-layout the component. This is called
2082:    * during validation of a container in most cases.
2083:    *
2084:    * @deprecated use {@link #doLayout()} instead
2085:    */
2086:   public void layout()
2087:   {
2088:     // Nothing to do unless we're a container.
2089:   }
2090: 
2091:   /**
2092:    * Called to ensure that the layout for this component is valid. This is
2093:    * usually called on containers.
2094:    *
2095:    * @see #invalidate()
2096:    * @see #doLayout()
2097:    * @see LayoutManager
2098:    * @see Container#validate()
2099:    */
2100:   public void validate()
2101:   {
2102:     if (! valid)
2103:       {
2104:         // Synchronize on the tree here as this might change the layout
2105:         // of the hierarchy.
2106:         synchronized (getTreeLock())
2107:           {
2108:             // Create local variables for thread safety.
2109:             ComponentPeer p = peer;
2110:             if (p != null)
2111:               {
2112:                 // Possibly update the peer's font.
2113:                 Font newFont = getFont();
2114:                 Font oldFont = peerFont;
2115:                 // Only update when the font really changed.
2116:                 if (newFont != oldFont
2117:                     && (oldFont == null || ! oldFont.equals(newFont)))
2118:                   {
2119:                     p.setFont(newFont);
2120:                     peerFont = newFont;
2121:                   }
2122:                 // Let the peer perform any layout.
2123:                 p.layout();
2124:               }
2125:           }
2126:         valid = true;
2127:       }
2128:   }
2129: 
2130:   /**
2131:    * Invalidates this component and all of its parent components. This will
2132:    * cause them to have their layout redone. This is called frequently, so
2133:    * make it fast.
2134:    */
2135:   public void invalidate()
2136:   {
2137:     // Need to lock here, to avoid races and other ugly stuff when doing
2138:     // layout or structure changes in other threads.
2139:     synchronized (getTreeLock())
2140:       {
2141:         // Invalidate.
2142:         valid = false;
2143: 
2144:         // Throw away cached layout information.
2145:         if (! minSizeSet)
2146:           minSize = null;
2147:         if (! prefSizeSet)
2148:           prefSize = null;
2149:         if (! maxSizeSet)
2150:           maxSize = null;
2151: 
2152:         // Also invalidate the parent, if it hasn't already been invalidated.
2153:         if (parent != null && parent.isValid())
2154:           parent.invalidate();
2155:       }
2156:   }
2157: 
2158:   /**
2159:    * Returns a graphics object for this component. Returns <code>null</code>
2160:    * if this component is not currently displayed on the screen.
2161:    *
2162:    * @return a graphics object for this component
2163:    * @see #paint(Graphics)
2164:    */
2165:   public Graphics getGraphics()
2166:   {
2167:     // Only heavyweight peers can handle this.
2168:     ComponentPeer p = peer;
2169:     Graphics g = null;
2170:     if (p instanceof LightweightPeer)
2171:       {
2172:         if (parent != null)
2173:           {
2174:             g = parent.getGraphics();
2175:             if (g != null)
2176:               {
2177:                 g.translate(x, y);
2178:                 g.setClip(0, 0, width, height);
2179:                 g.setFont(getFont());
2180:               }
2181:           }
2182:       }
2183:     else
2184:       {
2185:         if (p != null)
2186:           g = p.getGraphics();
2187:       }
2188:     return g;
2189:   }
2190: 
2191:   /**
2192:    * Returns the font metrics for the specified font in this component.
2193:    *
2194:    * @param font the font to retrieve metrics for
2195:    * @return the font metrics for the specified font
2196:    * @throws NullPointerException if font is null
2197:    * @see #getFont()
2198:    * @see Toolkit#getFontMetrics(Font)
2199:    */
2200:   public FontMetrics getFontMetrics(Font font)
2201:   {
2202:     ComponentPeer p = peer;
2203:     Component comp = this;
2204:     while (p instanceof LightweightPeer)
2205:       {
2206:         comp = comp.parent;
2207:         p = comp == null ? null : comp.peer;
2208:       }
2209: 
2210:     return p == null ? getToolkit().getFontMetrics(font)
2211:            : p.getFontMetrics(font);
2212:   }
2213: 
2214:   /**
2215:    * Sets the cursor for this component to the specified cursor. The cursor
2216:    * is displayed when the point is contained by the component, and the
2217:    * component is visible, displayable, and enabled. This is inherited by
2218:    * subcomponents unless they set their own cursor.
2219:    *
2220:    * @param cursor the new cursor for this component
2221:    * @see #isEnabled()
2222:    * @see #isShowing()
2223:    * @see #getCursor()
2224:    * @see #contains(int, int)
2225:    * @see Toolkit#createCustomCursor(Image, Point, String)
2226:    */
2227:   public void setCursor(Cursor cursor)
2228:   {
2229:     this.cursor = cursor;
2230: 
2231:     // Only heavyweight peers handle this.
2232:     ComponentPeer p = peer;
2233:     Component comp = this;
2234:     while (p instanceof LightweightPeer)
2235:       {
2236:         comp = comp.parent;
2237:         p = comp == null ? null : comp.peer;
2238:       }
2239: 
2240:     if (p != null)
2241:       p.setCursor(cursor);
2242:   }
2243: 
2244:   /**
2245:    * Returns the cursor for this component. If not set, this is inherited
2246:    * from the parent, or from Cursor.getDefaultCursor().
2247:    *
2248:    * @return the cursor for this component
2249:    */
2250:   public Cursor getCursor()
2251:   {
2252:     if (cursor != null)
2253:       return cursor;
2254:     return parent != null ? parent.getCursor() : Cursor.getDefaultCursor();
2255:   }
2256: 
2257:   /**
2258:    * Tests if the cursor was explicitly set, or just inherited from the parent.
2259:    *
2260:    * @return true if the cursor has been set
2261:    * @since 1.4
2262:    */
2263:   public boolean isCursorSet()
2264:   {
2265:     return cursor != null;
2266:   }
2267: 
2268:   /**
2269:    * Paints this component on the screen. The clipping region in the graphics
2270:    * context will indicate the region that requires painting. This is called
2271:    * whenever the component first shows, or needs to be repaired because
2272:    * something was temporarily drawn on top. It is not necessary for
2273:    * subclasses to call <code>super.paint(g)</code>. Components with no area
2274:    * are not painted.
2275:    *
2276:    * @param g the graphics context for this paint job
2277:    * @see #update(Graphics)
2278:    */
2279:   public void paint(Graphics g)
2280:   {
2281:     // This is a callback method and is meant to be overridden by subclasses
2282:     // that want to perform custom painting.
2283:   }
2284: 
2285:   /**
2286:    * Updates this component. This is called for heavyweight components in
2287:    * response to {@link #repaint()}. The default implementation simply forwards
2288:    * to {@link #paint(Graphics)}. The coordinates of the graphics are
2289:    * relative to this component. Subclasses should call either
2290:    * <code>super.update(g)</code> or <code>paint(g)</code>.
2291:    *
2292:    * @param g the graphics context for this update
2293:    *
2294:    * @see #paint(Graphics)
2295:    * @see #repaint()
2296:    */
2297:   public void update(Graphics g)
2298:   {
2299:     // Note 1: We used to clear the background here for lightweights and
2300:     // toplevel components. Tests show that this is not what the JDK does
2301:     // here. Note that there is some special handling and background
2302:     // clearing code in Container.update(Graphics).
2303: 
2304:     // Note 2 (for peer implementors): The JDK doesn't seem call update() for
2305:     // toplevel components, even when an UPDATE event is sent (as a result
2306:     // of repaint).
2307:     paint(g);
2308:   }
2309: 
2310:   /**
2311:    * Paints this entire component, including any sub-components.
2312:    *
2313:    * @param g the graphics context for this paint job
2314:    * 
2315:    * @see #paint(Graphics)
2316:    */
2317:   public void paintAll(Graphics g)
2318:   {
2319:     if (isShowing())
2320:       {
2321:         validate();
2322:         if (peer instanceof LightweightPeer)
2323:           paint(g);
2324:         else
2325:           peer.paint(g);
2326:       }
2327:   }
2328: 
2329:   /**
2330:    * Repaint this entire component. The <code>update()</code> method
2331:    * on this component will be called as soon as possible.
2332:    *
2333:    * @see #update(Graphics)
2334:    * @see #repaint(long, int, int, int, int)
2335:    */
2336:   public void repaint()
2337:   {   
2338:     repaint(0, 0, 0, width, height);
2339:   }
2340: 
2341:   /**
2342:    * Repaint this entire component. The <code>update()</code> method on this
2343:    * component will be called in approximate the specified number of
2344:    * milliseconds.
2345:    *
2346:    * @param tm milliseconds before this component should be repainted
2347:    * @see #paint(Graphics)
2348:    * @see #repaint(long, int, int, int, int)
2349:    */
2350:   public void repaint(long tm)
2351:   {
2352:     repaint(tm, 0, 0, width, height);
2353:   }
2354: 
2355:   /**
2356:    * Repaints the specified rectangular region within this component. The
2357:    * <code>update</code> method on this component will be called as soon as
2358:    * possible. The coordinates are relative to this component.
2359:    *
2360:    * @param x the X coordinate of the upper left of the region to repaint
2361:    * @param y the Y coordinate of the upper left of the region to repaint
2362:    * @param w the width of the region to repaint
2363:    * @param h the height of the region to repaint
2364:    * @see #update(Graphics)
2365:    * @see #repaint(long, int, int, int, int)
2366:    */
2367:   public void repaint(int x, int y, int w, int h)
2368:   {
2369:     repaint(0, x, y, w, h);
2370:   }
2371: 
2372:   /**
2373:    * Repaints the specified rectangular region within this component. The
2374:    * <code>update</code> method on this component will be called in
2375:    * approximately the specified number of milliseconds. The coordinates
2376:    * are relative to this component.
2377:    *
2378:    * @param tm milliseconds before this component should be repainted
2379:    * @param x the X coordinate of the upper left of the region to repaint
2380:    * @param y the Y coordinate of the upper left of the region to repaint
2381:    * @param width the width of the region to repaint
2382:    * @param height the height of the region to repaint
2383:    * @see #update(Graphics)
2384:    */
2385:   public void repaint(long tm, int x, int y, int width, int height)
2386:   {
2387:     // The repaint() call has previously been delegated to
2388:     // {@link ComponentPeer.repaint()}. Testing on the JDK using some
2389:     // dummy peers show that this methods is never called. I think it makes
2390:     // sense to actually perform the tasks below here, since it's pretty
2391:     // much peer independent anyway, and makes sure only heavyweights are
2392:     // bothered by this.
2393:     ComponentPeer p = peer;
2394: 
2395:     // Let the nearest heavyweight parent handle repainting for lightweight
2396:     // components.
2397:     // We need to recursivly call repaint() on the parent here, since
2398:     // a (lightweight) parent component might have overridden repaint()
2399:     // to perform additional custom tasks.
2400: 
2401:     if (p instanceof LightweightPeer)
2402:       {
2403:         // We perform some boundary checking to restrict the paint
2404:         // region to this component.
2405:         if (parent != null)
2406:           {
2407:             int px = this.x + Math.max(0, x); 
2408:             int py = this.y + Math.max(0, y);
2409:             int pw = Math.min(this.width, width);
2410:             int ph = Math.min(this.height, height);
2411:             parent.repaint(tm, px, py, pw, ph);
2412:           }
2413:       }
2414:     else
2415:       {
2416:         // Now send an UPDATE event to the heavyweight component that we've found.
2417:         if (isVisible() && p != null && width > 0 && height > 0)
2418:           {
2419:             PaintEvent pe = new PaintEvent(this, PaintEvent.UPDATE,
2420:                                            new Rectangle(x, y, width, height));
2421:             getToolkit().getSystemEventQueue().postEvent(pe);
2422:           }
2423:       }
2424:   }
2425: 
2426:   /**
2427:    * Prints this component. This method is provided so that printing can be
2428:    * done in a different manner from painting. However, the implementation
2429:    * in this class simply calls the <code>paint()</code> method.
2430:    *
2431:    * @param g the graphics context of the print device
2432:    * 
2433:    * @see #paint(Graphics)
2434:    */
2435:   public void print(Graphics g)
2436:   {
2437:     paint(g);
2438:   }
2439: 
2440:   /**
2441:    * Prints this component, including all sub-components. 
2442:    *
2443:    * @param g the graphics context of the print device
2444:    * 
2445:    * @see #paintAll(Graphics)
2446:    */
2447:   public void printAll(Graphics g)
2448:   {
2449:     if( peer != null )
2450:       peer.print( g );
2451:     paintAll( g );
2452:   }
2453: 
2454:   /**
2455:    * Called when an image has changed so that this component is repainted.
2456:    * This incrementally draws an image as more bits are available, when
2457:    * possible. Incremental drawing is enabled if the system property
2458:    * <code>awt.image.incrementalDraw</code> is not present or is true, in which
2459:    * case the redraw rate is set to 100ms or the value of the system property
2460:    * <code>awt.image.redrawrate</code>.
2461:    *
2462:    * <p>The coordinate system used depends on the particular flags.
2463:    *
2464:    * @param img the image that has been updated
2465:    * @param flags tlags as specified in <code>ImageObserver</code>
2466:    * @param x the X coordinate
2467:    * @param y the Y coordinate
2468:    * @param w the width
2469:    * @param h the height
2470:    * @return false if the image is completely loaded, loading has been
2471:    * aborted, or an error has occurred.  true if more updates are
2472:    * required.
2473:    * @see ImageObserver
2474:    * @see Graphics#drawImage(Image, int, int, Color, ImageObserver)
2475:    * @see Graphics#drawImage(Image, int, int, ImageObserver)
2476:    * @see Graphics#drawImage(Image, int, int, int, int, Color, ImageObserver)
2477:    * @see Graphics#drawImage(Image, int, int, int, int, ImageObserver)
2478:    * @see ImageObserver#imageUpdate(Image, int, int, int, int, int)
2479:    */
2480:   public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h)
2481:   {
2482:     if ((flags & (FRAMEBITS | ALLBITS)) != 0)
2483:       repaint();
2484:     else if ((flags & SOMEBITS) != 0)
2485:       {
2486:     if (incrementalDraw)
2487:       {
2488:         if (redrawRate != null)
2489:           {
2490:         long tm = redrawRate.longValue();
2491:         if (tm < 0)
2492:           tm = 0;
2493:                 repaint(tm);
2494:           }
2495:         else
2496:               repaint(100);
2497:       }
2498:       }
2499:     return (flags & (ALLBITS | ABORT | ERROR)) == 0;
2500:   }
2501: 
2502:   /**
2503:    * Creates an image from the specified producer.
2504:    *
2505:    * @param producer the image procedure to create the image from
2506:    * @return the resulting image
2507:    */
2508:   public Image createImage(ImageProducer producer)
2509:   {
2510:     // Only heavyweight peers can handle this.
2511:     ComponentPeer p = peer;
2512:     Component comp = this;
2513:     while (p instanceof LightweightPeer)
2514:       {
2515:         comp = comp.parent;
2516:         p = comp == null ? null : comp.peer;
2517:       }
2518: 
2519:     // Sun allows producer to be null.
2520:     Image im;
2521:     if (p != null)
2522:       im = p.createImage(producer);
2523:     else
2524:       im = getToolkit().createImage(producer);
2525:     return im;
2526:   }
2527: 
2528:   /**
2529:    * Creates an image with the specified width and height for use in
2530:    * double buffering. Headless environments do not support images.
2531:    *
2532:    * @param width the width of the image
2533:    * @param height the height of the image
2534:    * @return the requested image, or null if it is not supported
2535:    */
2536:   public Image createImage (int width, int height)
2537:   {
2538:     Image returnValue = null;
2539:     if (!GraphicsEnvironment.isHeadless ())
2540:       {
2541:         // Only heavyweight peers can handle this.
2542:         ComponentPeer p = peer;
2543:         Component comp = this;
2544:         while (p instanceof LightweightPeer)
2545:           {
2546:             comp = comp.parent;
2547:             p = comp == null ? null : comp.peer;
2548:           }
2549: 
2550:         if (p != null)
2551:           returnValue = p.createImage(width, height);
2552:       }
2553:     return returnValue;
2554:   }
2555: 
2556:   /**
2557:    * Creates an image with the specified width and height for use in
2558:    * double buffering. Headless environments do not support images.
2559:    *
2560:    * @param width the width of the image
2561:    * @param height the height of the image
2562:    * @return the requested image, or null if it is not supported
2563:    * @since 1.4
2564:    */
2565:   public VolatileImage createVolatileImage(int width, int height)
2566:   {
2567:     // Only heavyweight peers can handle this.
2568:     ComponentPeer p = peer;
2569:     Component comp = this;
2570:     while (p instanceof LightweightPeer)
2571:       {
2572:         comp = comp.parent;
2573:         p = comp == null ? null : comp.peer;
2574:       }
2575: 
2576:     VolatileImage im = null;
2577:     if (p != null)
2578:       im = p.createVolatileImage(width, height);
2579:     return im;
2580:   }
2581: 
2582:   /**
2583:    * Creates an image with the specified width and height for use in
2584:    * double buffering. Headless environments do not support images. The image
2585:    * will support the specified capabilities.
2586:    *
2587:    * @param width the width of the image
2588:    * @param height the height of the image
2589:    * @param caps the requested capabilities
2590:    * @return the requested image, or null if it is not supported
2591:    * @throws AWTException if a buffer with the capabilities cannot be created
2592:    * @since 1.4
2593:    */
2594:   public VolatileImage createVolatileImage(int width, int height,
2595:                                            ImageCapabilities caps)
2596:     throws AWTException
2597:   {
2598:     // Only heavyweight peers can handle this.
2599:     ComponentPeer p = peer;
2600:     Component comp = this;
2601:     while (p instanceof LightweightPeer)
2602:       {
2603:         comp = comp.parent;
2604:         p = comp == null ? null : comp.peer;
2605:       }
2606: 
2607:     VolatileImage im = null;
2608:     if (p != null)
2609:       im = peer.createVolatileImage(width, height);
2610:     return im;
2611:   }
2612: 
2613:   /**
2614:    * Prepares the specified image for rendering on this component.
2615:    *
2616:    * @param image the image to prepare for rendering
2617:    * @param observer the observer to notify of image preparation status
2618:    * @return true if the image is already fully prepared
2619:    * @throws NullPointerException if image is null
2620:    */
2621:   public boolean prepareImage(Image image, ImageObserver observer)
2622:   {
2623:     return prepareImage(image, image.getWidth(observer),
2624:                         image.getHeight(observer), observer);
2625:   }
2626: 
2627:   /**
2628:    * Prepares the specified image for rendering on this component at the
2629:    * specified scaled width and height
2630:    *
2631:    * @param image the image to prepare for rendering
2632:    * @param width the scaled width of the image
2633:    * @param height the scaled height of the image
2634:    * @param observer the observer to notify of image preparation status
2635:    * @return true if the image is already fully prepared
2636:    */
2637:   public boolean prepareImage(Image image, int width, int height,
2638:                               ImageObserver observer)
2639:   {
2640:     // Only heavyweight peers handle this.
2641:     ComponentPeer p = peer;
2642:     Component comp = this;
2643:     while (p instanceof LightweightPeer)
2644:       {
2645:         comp = comp.parent;
2646:         p = comp == null ? null : comp.peer;
2647:       }
2648: 
2649:     boolean retval;
2650:     if (p != null)
2651:     retval = p.prepareImage(image, width, height, observer);
2652:     else
2653:     retval = getToolkit().prepareImage(image, width, height, observer);
2654:     return retval;
2655:   }
2656: 
2657:   /**
2658:    * Returns the status of the loading of the specified image. The value
2659:    * returned will be those flags defined in <code>ImageObserver</code>.
2660:    *
2661:    * @param image the image to check on
2662:    * @param observer the observer to notify of image loading progress
2663:    * @return the image observer flags indicating the status of the load
2664:    * @see #prepareImage(Image, int, int, ImageObserver)
2665:    * @see Toolkit#checkImage(Image, int, int, ImageObserver)
2666:    * @throws NullPointerException if image is null
2667:    */
2668:   public int checkImage(Image image, ImageObserver observer)
2669:   {
2670:     return checkImage(image, -1, -1, observer);
2671:   }
2672: 
2673:   /**
2674:    * Returns the status of the loading of the specified image. The value
2675:    * returned will be those flags defined in <code>ImageObserver</code>.
2676:    *
2677:    * @param image the image to check on
2678:    * @param width the scaled image width
2679:    * @param height the scaled image height
2680:    * @param observer the observer to notify of image loading progress
2681:    * @return the image observer flags indicating the status of the load
2682:    * @see #prepareImage(Image, int, int, ImageObserver)
2683:    * @see Toolkit#checkImage(Image, int, int, ImageObserver)
2684:    */
2685:   public int checkImage(Image image, int width, int height,
2686:                         ImageObserver observer)
2687:   {
2688:     // Only heavyweight peers handle this.
2689:     ComponentPeer p = peer;
2690:     Component comp = this;
2691:     while (p instanceof LightweightPeer)
2692:       {
2693:         comp = comp.parent;
2694:         p = comp == null ? null : comp.peer;
2695:       }
2696: 
2697:     int retval;
2698:     if (p != null)
2699:       retval = p.checkImage(image, width, height, observer);
2700:     else
2701:       retval = getToolkit().checkImage(image, width, height, observer);
2702:     return retval;
2703:   }
2704: 
2705:   /**
2706:    * Sets whether paint messages delivered by the operating system should be
2707:    * ignored. This does not affect messages from AWT, except for those
2708:    * triggered by OS messages. Setting this to true can allow faster
2709:    * performance in full-screen mode or page-flipping.
2710:    *
2711:    * @param ignoreRepaint the new setting for ignoring repaint events
2712:    * @see #getIgnoreRepaint()
2713:    * @see BufferStrategy
2714:    * @see GraphicsDevice#setFullScreenWindow(Window)
2715:    * @since 1.4
2716:    */
2717:   public void setIgnoreRepaint(boolean ignoreRepaint)
2718:   {
2719:     this.ignoreRepaint = ignoreRepaint;
2720:   }
2721: 
2722:   /**
2723:    * Test whether paint events from the operating system are ignored.
2724:    *
2725:    * @return the status of ignoring paint events
2726:    * @see #setIgnoreRepaint(boolean)
2727:    * @since 1.4
2728:    */
2729:   public boolean getIgnoreRepaint()
2730:   {
2731:     return ignoreRepaint;
2732:   }
2733: 
2734:   /**
2735:    * Tests whether or not the specified point is contained within this
2736:    * component. Coordinates are relative to this component.
2737:    *
2738:    * @param x the X coordinate of the point to test
2739:    * @param y the Y coordinate of the point to test
2740:    * @return true if the point is within this component
2741:    * @see #getComponentAt(int, int)
2742:    */
2743:   public boolean contains(int x, int y)
2744:   {
2745:     return inside (x, y);
2746:   }
2747: 
2748:   /**
2749:    * Tests whether or not the specified point is contained within this
2750:    * component. Coordinates are relative to this component.
2751:    *
2752:    * @param x the X coordinate of the point to test
2753:    * @param y the Y coordinate of the point to test
2754:    * @return true if the point is within this component
2755:    * @deprecated use {@link #contains(int, int)} instead
2756:    */
2757:   public boolean inside(int x, int y)
2758:   {
2759:     return x >= 0 && y >= 0 && x < width && y < height;
2760:   }
2761: 
2762:   /**
2763:    * Tests whether or not the specified point is contained within this
2764:    * component. Coordinates are relative to this component.
2765:    *
2766:    * @param p the point to test
2767:    * @return true if the point is within this component
2768:    * @throws NullPointerException if p is null
2769:    * @see #getComponentAt(Point)
2770:    * @since 1.1
2771:    */
2772:   public boolean contains(Point p)
2773:   {
2774:     return contains (p.x, p.y);
2775:   }
2776: 
2777:   /**
2778:    * Returns the component occupying the position (x,y). This will either
2779:    * be this component, an immediate child component, or <code>null</code>
2780:    * if neither of the first two occupies the specified location.
2781:    *
2782:    * @param x the X coordinate to search for components at
2783:    * @param y the Y coordinate to search for components at
2784:    * @return the component at the specified location, or null
2785:    * @see #contains(int, int)
2786:    */
2787:   public Component getComponentAt(int x, int y)
2788:   {
2789:     return locate (x, y);
2790:   }
2791: 
2792:   /**
2793:    * Returns the component occupying the position (x,y). This will either
2794:    * be this component, an immediate child component, or <code>null</code>
2795:    * if neither of the first two occupies the specified location.
2796:    *
2797:    * @param x the X coordinate to search for components at
2798:    * @param y the Y coordinate to search for components at
2799:    * @return the component at the specified location, or null
2800:    * @deprecated use {@link #getComponentAt(int, int)} instead
2801:    */
2802:   public Component locate(int x, int y)
2803:   {
2804:     return contains (x, y) ? this : null;
2805:   }
2806: 
2807:   /**
2808:    * Returns the component occupying the position (x,y). This will either
2809:    * be this component, an immediate child component, or <code>null</code>
2810:    * if neither of the first two occupies the specified location.
2811:    *
2812:    * @param p the point to search for components at
2813:    * @return the component at the specified location, or null
2814:    * @throws NullPointerException if p is null
2815:    * @see #contains(Point)
2816:    * @since 1.1
2817:    */
2818:   public Component getComponentAt(Point p)
2819:   {
2820:     return getComponentAt (p.x, p.y);
2821:   }
2822: 
2823:   /**
2824:    * AWT 1.0 event delivery.
2825:    *
2826:    * Deliver an AWT 1.0 event to this Component.  This method simply
2827:    * calls {@link #postEvent}.
2828:    *
2829:    * @param e the event to deliver
2830:    * @deprecated use {@link #dispatchEvent (AWTEvent)} instead
2831:    */
2832:   public void deliverEvent (Event e)
2833:   {
2834:     postEvent (e);
2835:   }
2836: 
2837:   /**
2838:    * Forwards AWT events to processEvent() if:<ul>
2839:    * <li>Events have been enabled for this type of event via
2840:    * <code>enableEvents()</code></li>,
2841:    * <li>There is at least one registered listener for this type of event</li>
2842:    * </ul>
2843:    *
2844:    * @param e the event to dispatch
2845:    */
2846:   public final void dispatchEvent(AWTEvent e)
2847:   {
2848:     // Some subclasses in the AWT package need to override this behavior,
2849:     // hence the use of dispatchEventImpl().
2850:     dispatchEventImpl(e);
2851:   }
2852: 
2853:   /**
2854:    * By default, no old mouse events should be ignored.
2855:    * This can be overridden by subclasses.
2856:    * 
2857:    * @return false, no mouse events are ignored.
2858:    */
2859:   static boolean ignoreOldMouseEvents()
2860:   {
2861:     return false;
2862:   }
2863:   
2864:   /**
2865:    * AWT 1.0 event handler.
2866:    *
2867:    * This method simply calls handleEvent and returns the result.
2868:    *
2869:    * @param e the event to handle
2870:    * @return true if the event was handled, false otherwise
2871:    * @deprecated use {@link #dispatchEvent(AWTEvent)} instead
2872:    */
2873:   public boolean postEvent (Event e)
2874:   {
2875:     boolean handled = handleEvent (e);
2876: 
2877:     if (!handled && getParent() != null)
2878:       // FIXME: need to translate event coordinates to parent's
2879:       // coordinate space.
2880:       handled = getParent ().postEvent (e);
2881: 
2882:     return handled;
2883:   }
2884: 
2885:   /**
2886:    * Adds the specified listener to this component. This is harmless if the
2887:    * listener is null, but if the listener has already been registered, it
2888:    * will now be registered twice.
2889:    *
2890:    * @param listener the new listener to add
2891:    * @see ComponentEvent
2892:    * @see #removeComponentListener(ComponentListener)
2893:    * @see #getComponentListeners()
2894:    * @since 1.1
2895:    */
2896:   public synchronized void addComponentListener(ComponentListener listener)
2897:   {
2898:     if (listener != null)
2899:       {
2900:         componentListener = AWTEventMulticaster.add(componentListener,
2901:                                                     listener);
2902:         newEventsOnly = true;
2903:       }
2904:   }
2905: 
2906:   /**
2907:    * Removes the specified listener from the component. This is harmless if
2908:    * the listener was not previously registered.
2909:    *
2910:    * @param listener the listener to remove
2911:    * @see ComponentEvent
2912:    * @see #addComponentListener(ComponentListener)
2913:    * @see #getComponentListeners()
2914:    * @since 1.1
2915:    */
2916:   public synchronized void removeComponentListener(ComponentListener listener)
2917:   {
2918:     componentListener = AWTEventMulticaster.remove(componentListener, listener);
2919:   }
2920: 
2921:   /**
2922:    * Returns an array of all specified listeners registered on this component.
2923:    *
2924:    * @return an array of listeners
2925:    * @see #addComponentListener(ComponentListener)
2926:    * @see #removeComponentListener(ComponentListener)
2927:    * @since 1.4
2928:    */
2929:   public synchronized ComponentListener[] getComponentListeners()
2930:   {
2931:     return (ComponentListener[])
2932:       AWTEventMulticaster.getListeners(componentListener,
2933:                                        ComponentListener.class);
2934:   }
2935: 
2936:   /**
2937:    * Adds the specified listener to this component. This is harmless if the
2938:    * listener is null, but if the listener has already been registered, it
2939:    * will now be registered twice.
2940:    *
2941:    * @param listener the new listener to add
2942:    * @see FocusEvent
2943:    * @see #removeFocusListener(FocusListener)
2944:    * @see #getFocusListeners()
2945:    * @since 1.1
2946:    */
2947:   public synchronized void addFocusListener(FocusListener listener)
2948:   {
2949:     if (listener != null)
2950:       {
2951:         focusListener = AWTEventMulticaster.add(focusListener, listener);
2952:         newEventsOnly = true;
2953:       }
2954:   }
2955: 
2956:   /**
2957:    * Removes the specified listener from the component. This is harmless if
2958:    * the listener was not previously registered.
2959:    *
2960:    * @param listener the listener to remove
2961:    * @see FocusEvent
2962:    * @see #addFocusListener(FocusListener)
2963:    * @see #getFocusListeners()
2964:    * @since 1.1
2965:    */
2966:   public synchronized void removeFocusListener(FocusListener listener)
2967:   {
2968:     focusListener = AWTEventMulticaster.remove(focusListener, listener);
2969:   }
2970: 
2971:   /**
2972:    * Returns an array of all specified listeners registered on this component.
2973:    *
2974:    * @return an array of listeners
2975:    * @see #addFocusListener(FocusListener)
2976:    * @see #removeFocusListener(FocusListener)
2977:    * @since 1.4
2978:    */
2979:   public synchronized FocusListener[] getFocusListeners()
2980:   {
2981:     return (FocusListener[])
2982:       AWTEventMulticaster.getListeners(focusListener, FocusListener.class);
2983:   }
2984: 
2985:   /**
2986:    * Adds the specified listener to this component. This is harmless if the
2987:    * listener is null, but if the listener has already been registered, it
2988:    * will now be registered twice.
2989:    *
2990:    * @param listener the new listener to add
2991:    * @see HierarchyEvent
2992:    * @see #removeHierarchyListener(HierarchyListener)
2993:    * @see #getHierarchyListeners()
2994:    * @since 1.3
2995:    */
2996:   public synchronized void addHierarchyListener(HierarchyListener listener)
2997:   {
2998:     if (listener != null)
2999:       {
3000:         hierarchyListener = AWTEventMulticaster.add(hierarchyListener,
3001:                                                     listener);
3002:         newEventsOnly = true;
3003:         // Need to lock the tree, otherwise we might end up inconsistent.
3004:         synchronized (getTreeLock())
3005:         {
3006:           numHierarchyListeners++;
3007:           if (parent != null)
3008:             parent.updateHierarchyListenerCount(AWTEvent.HIERARCHY_EVENT_MASK,
3009:                                                 1);
3010:         }
3011:       }
3012:   }
3013: 
3014:   /**
3015:    * Removes the specified listener from the component. This is harmless if
3016:    * the listener was not previously registered.
3017:    *
3018:    * @param listener the listener to remove
3019:    * @see HierarchyEvent
3020:    * @see #addHierarchyListener(HierarchyListener)
3021:    * @see #getHierarchyListeners()
3022:    * @since 1.3
3023:    */
3024:   public synchronized void removeHierarchyListener(HierarchyListener listener)
3025:   {
3026:     hierarchyListener = AWTEventMulticaster.remove(hierarchyListener, listener);
3027: 
3028:     // Need to lock the tree, otherwise we might end up inconsistent.
3029:     synchronized (getTreeLock())
3030:       {
3031:         numHierarchyListeners--;
3032:         if (parent != null)
3033:           parent.updateHierarchyListenerCount(AWTEvent.HIERARCHY_EVENT_MASK,
3034:                                               -1);
3035:       }
3036:   }
3037: 
3038:   /**
3039:    * Returns an array of all specified listeners registered on this component.
3040:    *
3041:    * @return an array of listeners
3042:    * @see #addHierarchyListener(HierarchyListener)
3043:    * @see #removeHierarchyListener(HierarchyListener)
3044:    * @since 1.4
3045:    */
3046:   public synchronized HierarchyListener[] getHierarchyListeners()
3047:   {
3048:     return (HierarchyListener[])
3049:       AWTEventMulticaster.getListeners(hierarchyListener,
3050:                                        HierarchyListener.class);
3051:   }
3052: 
3053:   /**
3054:    * Adds the specified listener to this component. This is harmless if the
3055:    * listener is null, but if the listener has already been registered, it
3056:    * will now be registered twice.
3057:    *
3058:    * @param listener the new listener to add
3059:    * @see HierarchyEvent
3060:    * @see #removeHierarchyBoundsListener(HierarchyBoundsListener)
3061:    * @see #getHierarchyBoundsListeners()
3062:    * @since 1.3
3063:    */
3064:   public synchronized void
3065:     addHierarchyBoundsListener(HierarchyBoundsListener listener)
3066:   {
3067:     if (listener != null)
3068:       {
3069:         hierarchyBoundsListener =
3070:           AWTEventMulticaster.add(hierarchyBoundsListener, listener);
3071:         newEventsOnly = true;
3072: 
3073:         // Need to lock the tree, otherwise we might end up inconsistent.
3074:         synchronized (getTreeLock())
3075:         {
3076:           numHierarchyBoundsListeners++;
3077:           if (parent != null)
3078:             parent.updateHierarchyListenerCount
3079:                                      (AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK, 1);
3080:         }
3081:       }
3082:   }
3083: 
3084:   /**
3085:    * Removes the specified listener from the component. This is harmless if
3086:    * the listener was not previously registered.
3087:    *
3088:    * @param listener the listener to remove
3089:    * @see HierarchyEvent
3090:    * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
3091:    * @see #getHierarchyBoundsListeners()
3092:    * @since 1.3
3093:    */
3094:   public synchronized void
3095:     removeHierarchyBoundsListener(HierarchyBoundsListener listener)
3096:   {
3097:     hierarchyBoundsListener =
3098:       AWTEventMulticaster.remove(hierarchyBoundsListener, listener);
3099: 
3100:     // Need to lock the tree, otherwise we might end up inconsistent.
3101:     synchronized (getTreeLock())
3102:       {
3103:         numHierarchyBoundsListeners--;
3104:         if (parent != null)
3105:           parent.updateHierarchyListenerCount
3106:                                          (AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
3107:                                           -1);
3108:       }
3109:   }
3110: 
3111:   /**
3112:    * Returns an array of all specified listeners registered on this component.
3113:    *
3114:    * @return an array of listeners
3115:    * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
3116:    * @see #removeHierarchyBoundsListener(HierarchyBoundsListener)
3117:    * @since 1.4
3118:    */
3119:   public synchronized HierarchyBoundsListener[] getHierarchyBoundsListeners()
3120:   {
3121:     return (HierarchyBoundsListener[])
3122:       AWTEventMulticaster.getListeners(hierarchyBoundsListener,
3123:                                        HierarchyBoundsListener.class);
3124:   }
3125: 
3126:   /**
3127:    * Fires a HierarchyEvent or HierarchyChangeEvent on this component.
3128:    *
3129:    * @param id the event id
3130:    * @param changed the changed component
3131:    * @param parent the parent
3132:    * @param flags the event flags
3133:    */
3134:   void fireHierarchyEvent(int id, Component changed, Container parent,
3135:                           long flags)
3136:   {
3137:     boolean enabled = false;
3138:     switch (id)
3139:     {
3140:       case HierarchyEvent.HIERARCHY_CHANGED:
3141:         enabled = hierarchyListener != null
3142:                   || (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0;
3143:         break;
3144:       case HierarchyEvent.ANCESTOR_MOVED:
3145:       case HierarchyEvent.ANCESTOR_RESIZED:
3146:         enabled = hierarchyBoundsListener != null
3147:                   || (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0;
3148:         break;
3149:       default:
3150:         assert false : "Should not reach here";
3151:     }
3152:     if (enabled)
3153:       {
3154:         HierarchyEvent ev = new HierarchyEvent(this, id, changed, parent,
3155:                                                flags);
3156:         dispatchEvent(ev);
3157:       }
3158:   }
3159: 
3160:   /**
3161:    * Adds the specified listener to this component. This is harmless if the
3162:    * listener is null, but if the listener has already been registered, it
3163:    * will now be registered twice.
3164:    *
3165:    * @param listener the new listener to add
3166:    * @see KeyEvent
3167:    * @see #removeKeyListener(KeyListener)
3168:    * @see #getKeyListeners()
3169:    * @since 1.1
3170:    */
3171:   public synchronized void addKeyListener(KeyListener listener)
3172:   {
3173:     if (listener != null)
3174:       {
3175:         keyListener = AWTEventMulticaster.add(keyListener, listener);
3176:         newEventsOnly = true;
3177:       }
3178:   }
3179: 
3180:   /**
3181:    * Removes the specified listener from the component. This is harmless if
3182:    * the listener was not previously registered.
3183:    *
3184:    * @param listener the listener to remove
3185:    * @see KeyEvent
3186:    * @see #addKeyListener(KeyListener)
3187:    * @see #getKeyListeners()
3188:    * @since 1.1
3189:    */
3190:   public synchronized void removeKeyListener(KeyListener listener)
3191:   {
3192:     keyListener = AWTEventMulticaster.remove(keyListener, listener);
3193:   }
3194: 
3195:   /**
3196:    * Returns an array of all specified listeners registered on this component.
3197:    *
3198:    * @return an array of listeners
3199:    * @see #addKeyListener(KeyListener)
3200:    * @see #removeKeyListener(KeyListener)
3201:    * @since 1.4
3202:    */
3203:   public synchronized KeyListener[] getKeyListeners()
3204:   {
3205:     return (KeyListener[])
3206:       AWTEventMulticaster.getListeners(keyListener, KeyListener.class);
3207:   }
3208: 
3209:   /**
3210:    * Adds the specified listener to this component. This is harmless if the
3211:    * listener is null, but if the listener has already been registered, it
3212:    * will now be registered twice.
3213:    *
3214:    * @param listener the new listener to add
3215:    * @see MouseEvent
3216:    * @see #removeMouseListener(MouseListener)
3217:    * @see #getMouseListeners()
3218:    * @since 1.1
3219:    */
3220:   public synchronized void addMouseListener(MouseListener listener)
3221:   {
3222:     if (listener != null)
3223:       {
3224:         mouseListener = AWTEventMulticaster.add(mouseListener, listener);
3225:         newEventsOnly = true;
3226:       }
3227:   }
3228: 
3229:   /**
3230:    * Removes the specified listener from the component. This is harmless if
3231:    * the listener was not previously registered.
3232:    *
3233:    * @param listener the listener to remove
3234:    * @see MouseEvent
3235:    * @see #addMouseListener(MouseListener)
3236:    * @see #getMouseListeners()
3237:    * @since 1.1
3238:    */
3239:   public synchronized void removeMouseListener(MouseListener listener)
3240:   {
3241:     mouseListener = AWTEventMulticaster.remove(mouseListener, listener);
3242:   }
3243: 
3244:   /**
3245:    * Returns an array of all specified listeners registered on this component.
3246:    *
3247:    * @return an array of listeners
3248:    * @see #addMouseListener(MouseListener)
3249:    * @see #removeMouseListener(MouseListener)
3250:    * @since 1.4
3251:    */
3252:   public synchronized MouseListener[] getMouseListeners()
3253:   {
3254:     return (MouseListener[])
3255:       AWTEventMulticaster.getListeners(mouseListener, MouseListener.class);
3256:   }
3257: 
3258:   /**
3259:    * Adds the specified listener to this component. This is harmless if the
3260:    * listener is null, but if the listener has already been registered, it
3261:    * will now be registered twice.
3262:    *
3263:    * @param listener the new listener to add
3264:    * @see MouseEvent
3265:    * @see #removeMouseMotionListener(MouseMotionListener)
3266:    * @see #getMouseMotionListeners()
3267:    * @since 1.1
3268:    */
3269:   public synchronized void addMouseMotionListener(MouseMotionListener listener)
3270:   {
3271:     if (listener != null)
3272:       {
3273:         mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener,
3274:                                                       listener);
3275:         newEventsOnly = true;
3276:       }
3277:   }
3278: 
3279:   /**
3280:    * Removes the specified listener from the component. This is harmless if
3281:    * the listener was not previously registered.
3282:    *
3283:    * @param listener the listener to remove
3284:    * @see MouseEvent
3285:    * @see #addMouseMotionListener(MouseMotionListener)
3286:    * @see #getMouseMotionListeners()
3287:    * @since 1.1
3288:    */
3289:   public synchronized void removeMouseMotionListener(MouseMotionListener listener)
3290:   {
3291:     mouseMotionListener = AWTEventMulticaster.remove(mouseMotionListener, listener);
3292:   }
3293: 
3294:   /**
3295:    * Returns an array of all specified listeners registered on this component.
3296:    *
3297:    * @return an array of listeners
3298:    * @see #addMouseMotionListener(MouseMotionListener)
3299:    * @see #removeMouseMotionListener(MouseMotionListener)
3300:    * @since 1.4
3301:    */
3302:   public synchronized MouseMotionListener[] getMouseMotionListeners()
3303:   {
3304:     return (MouseMotionListener[])
3305:       AWTEventMulticaster.getListeners(mouseMotionListener,
3306:                                        MouseMotionListener.class);
3307:   }
3308: 
3309:   /**
3310:    * Adds the specified listener to this component. This is harmless if the
3311:    * listener is null, but if the listener has already been registered, it
3312:    * will now be registered twice.
3313:    *
3314:    * @param listener the new listener to add
3315:    * @see MouseEvent
3316:    * @see MouseWheelEvent
3317:    * @see #removeMouseWheelListener(MouseWheelListener)
3318:    * @see #getMouseWheelListeners()
3319:    * @since 1.4
3320:    */
3321:   public synchronized void addMouseWheelListener(MouseWheelListener listener)
3322:   {
3323:     if (listener != null)
3324:       {
3325:         mouseWheelListener = AWTEventMulticaster.add(mouseWheelListener,
3326:                                                      listener);
3327:         newEventsOnly = true;
3328:       }
3329:   }
3330: 
3331:   /**
3332:    * Removes the specified listener from the component. This is harmless if
3333:    * the listener was not previously registered.
3334:    *
3335:    * @param listener the listener to remove
3336:    * @see MouseEvent
3337:    * @see MouseWheelEvent
3338:    * @see #addMouseWheelListener(MouseWheelListener)
3339:    * @see #getMouseWheelListeners()
3340:    * @since 1.4
3341:    */
3342:   public synchronized void removeMouseWheelListener(MouseWheelListener listener)
3343:   {
3344:     mouseWheelListener = AWTEventMulticaster.remove(mouseWheelListener, listener);
3345:   }
3346: 
3347:   /**
3348:    * Returns an array of all specified listeners registered on this component.
3349:    *
3350:    * @return an array of listeners
3351:    * @see #addMouseWheelListener(MouseWheelListener)
3352:    * @see #removeMouseWheelListener(MouseWheelListener)
3353:    * @since 1.4
3354:    */
3355:   public synchronized MouseWheelListener[] getMouseWheelListeners()
3356:   {
3357:     return (MouseWheelListener[])
3358:       AWTEventMulticaster.getListeners(mouseWheelListener,
3359:                                        MouseWheelListener.class);
3360:   }
3361: 
3362:   /**
3363:    * Adds the specified listener to this component. This is harmless if the
3364:    * listener is null, but if the listener has already been registered, it
3365:    * will now be registered twice.
3366:    *
3367:    * @param listener the new listener to add
3368:    * @see InputMethodEvent
3369:    * @see #removeInputMethodListener(InputMethodListener)
3370:    * @see #getInputMethodListeners()
3371:    * @see #getInputMethodRequests()
3372:    * @since 1.2
3373:    */
3374:   public synchronized void addInputMethodListener(InputMethodListener listener)
3375:   {
3376:     if (listener != null)
3377:       {
3378:         inputMethodListener = AWTEventMulticaster.add(inputMethodListener,
3379:                                                       listener);
3380:         newEventsOnly = true;
3381:       }
3382:   }
3383: 
3384:   /**
3385:    * Removes the specified listener from the component. This is harmless if
3386:    * the listener was not previously registered.
3387:    *
3388:    * @param listener the listener to remove
3389:    * @see InputMethodEvent
3390:    * @see #addInputMethodListener(InputMethodListener)
3391:    * @see #getInputMethodRequests()
3392:    * @since 1.2
3393:    */
3394:   public synchronized void removeInputMethodListener(InputMethodListener listener)
3395:   {
3396:     inputMethodListener = AWTEventMulticaster.remove(inputMethodListener, listener);
3397:   }
3398: 
3399:   /**
3400:    * Returns an array of all specified listeners registered on this component.
3401:    *
3402:    * @return an array of listeners
3403:    * @see #addInputMethodListener(InputMethodListener)
3404:    * @see #removeInputMethodListener(InputMethodListener)
3405:    * @since 1.4
3406:    */
3407:   public synchronized InputMethodListener[] getInputMethodListeners()
3408:   {
3409:     return (InputMethodListener[])
3410:       AWTEventMulticaster.getListeners(inputMethodListener,
3411:                                        InputMethodListener.class);
3412:   }
3413: 
3414:   /**
3415:    * Returns all registered {@link EventListener}s of the given 
3416:    * <code>listenerType</code>.
3417:    *
3418:    * @param listenerType the class of listeners to filter (<code>null</code> 
3419:    *                     not permitted).
3420:    *                     
3421:    * @return An array of registered listeners.
3422:    * 
3423:    * @throws ClassCastException if <code>listenerType</code> does not implement
3424:    *                            the {@link EventListener} interface.
3425:    * @throws NullPointerException if <code>listenerType</code> is 
3426:    *                              <code>null</code>.
3427:    *                            
3428:    * @see #getComponentListeners()
3429:    * @see #getFocusListeners()
3430:    * @see #getHierarchyListeners()
3431:    * @see #getHierarchyBoundsListeners()
3432:    * @see #getKeyListeners()
3433:    * @see #getMouseListeners()
3434:    * @see #getMouseMotionListeners()
3435:    * @see #getMouseWheelListeners()
3436:    * @see #getInputMethodListeners()
3437:    * @see #getPropertyChangeListeners()
3438:    * @since 1.3
3439:    */
3440:   public <T extends EventListener> T[] getListeners(Class<T> listenerType)
3441:   {
3442:     if (listenerType == ComponentListener.class)
3443:       return (T[]) getComponentListeners();
3444:     if (listenerType == FocusListener.class)
3445:       return (T[]) getFocusListeners();
3446:     if (listenerType == HierarchyListener.class)
3447:       return (T[]) getHierarchyListeners();
3448:     if (listenerType == HierarchyBoundsListener.class)
3449:       return (T[]) getHierarchyBoundsListeners();
3450:     if (listenerType == KeyListener.class)
3451:       return (T[]) getKeyListeners();
3452:     if (listenerType == MouseListener.class)
3453:       return (T[]) getMouseListeners();
3454:     if (listenerType == MouseMotionListener.class)
3455:       return (T[]) getMouseMotionListeners();
3456:     if (listenerType == MouseWheelListener.class)
3457:       return (T[]) getMouseWheelListeners();
3458:     if (listenerType == InputMethodListener.class)
3459:       return (T[]) getInputMethodListeners();
3460:     if (listenerType == PropertyChangeListener.class)
3461:       return (T[]) getPropertyChangeListeners();
3462:     return (T[]) Array.newInstance(listenerType, 0);
3463:   }
3464: 
3465:   /**
3466:    * Returns the input method request handler, for subclasses which support
3467:    * on-the-spot text input. By default, input methods are handled by AWT,
3468:    * and this returns null.
3469:    *
3470:    * @return the input method handler, null by default
3471:    * @since 1.2
3472:    */
3473:   public InputMethodRequests getInputMethodRequests()
3474:   {
3475:     return null;
3476:   }
3477: 
3478:   /**
3479:    * Gets the input context of this component, which is inherited from the
3480:    * parent unless this is overridden.
3481:    *
3482:    * @return the text input context
3483:    * @since 1.2
3484:    */
3485:   public InputContext getInputContext()
3486:   {
3487:     return parent == null ? null : parent.getInputContext();
3488:   }
3489: 
3490:   /**
3491:    * Enables the specified events. The events to enable are specified
3492:    * by OR-ing together the desired masks from <code>AWTEvent</code>.
3493:    *
3494:    * <p>Events are enabled by default when a listener is attached to the
3495:    * component for that event type. This method can be used by subclasses
3496:    * to ensure the delivery of a specified event regardless of whether
3497:    * or not a listener is attached.
3498:    *
3499:    * @param eventsToEnable the desired events to enable
3500:    * @see #processEvent(AWTEvent)
3501:    * @see #disableEvents(long)
3502:    * @see AWTEvent
3503:    * @since 1.1
3504:    */
3505:   protected final void enableEvents(long eventsToEnable)
3506:   {
3507:     // Update the counter for hierarchy (bounds) listeners.
3508:     if ((eventsToEnable & AWTEvent.HIERARCHY_EVENT_MASK) != 0
3509:         && (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) == 0)
3510:       {
3511:         // Need to lock the tree, otherwise we might end up inconsistent.
3512:         synchronized (getTreeLock())
3513:           {
3514:             numHierarchyListeners++;
3515:             if (parent != null)
3516:               parent.updateHierarchyListenerCount
3517:                                                 (AWTEvent.HIERARCHY_EVENT_MASK,
3518:                                                  1);
3519:           }
3520:       }
3521:     if ((eventsToEnable & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0
3522:         && (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) == 0)
3523:       {
3524:         // Need to lock the tree, otherwise we might end up inconsistent.
3525:         synchronized (getTreeLock())
3526:           {
3527:             numHierarchyBoundsListeners++;
3528:             if (parent != null)
3529:               parent.updateHierarchyListenerCount
3530:                                          (AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
3531:                                           1);
3532:           }
3533:       }
3534: 
3535:     eventMask |= eventsToEnable;
3536:     newEventsOnly = true;
3537: 
3538:     // Only heavyweight peers handle this.
3539:     ComponentPeer p = peer;
3540:     Component comp = this;
3541:     while (p instanceof LightweightPeer)
3542:       {
3543:         comp = comp.parent;
3544:         p = comp == null ? null : comp.peer;
3545:       }
3546: 
3547:     if (p != null)
3548:       p.setEventMask(eventMask);
3549: 
3550:   }
3551: 
3552:   /**
3553:    * Disables the specified events. The events to disable are specified
3554:    * by OR-ing together the desired masks from <code>AWTEvent</code>.
3555:    *
3556:    * @param eventsToDisable the desired events to disable
3557:    * @see #enableEvents(long)
3558:    * @since 1.1
3559:    */
3560:   protected final void disableEvents(long eventsToDisable)
3561:   {
3562:     // Update the counter for hierarchy (bounds) listeners.
3563:     if ((eventsToDisable & AWTEvent.HIERARCHY_EVENT_MASK) != 0
3564:         && (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0)
3565:       {
3566:         // Need to lock the tree, otherwise we might end up inconsistent.
3567:         synchronized (getTreeLock())
3568:           {
3569:             numHierarchyListeners--;
3570:             if (parent != null)
3571:               parent.updateHierarchyListenerCount
3572:                                                 (AWTEvent.HIERARCHY_EVENT_MASK,
3573:                                                  -1);
3574:           }
3575:       }
3576:     if ((eventsToDisable & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0
3577:         && (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0)
3578:       {
3579:         // Need to lock the tree, otherwise we might end up inconsistent.
3580:         synchronized (getTreeLock())
3581:           {
3582:             numHierarchyBoundsListeners--;
3583:             if (parent != null)
3584:               parent.updateHierarchyListenerCount
3585:                                          (AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
3586:                                           -1);
3587:           }
3588:       }
3589: 
3590:     eventMask &= ~eventsToDisable;
3591: 
3592:     // Only heavyweight peers handle this.
3593:     ComponentPeer p = peer;
3594:     Component comp = this;
3595:     while (p instanceof LightweightPeer)
3596:       {
3597:         comp = comp.parent;
3598:         p = comp == null ? null : comp.peer;
3599:       }
3600: 
3601:     if (p != null)
3602:       p.setEventMask(eventMask);
3603: 
3604:   }
3605: 
3606:   /**
3607:    * This is called by the EventQueue if two events with the same event id
3608:    * and owner component are queued. Returns a new combined event, or null if
3609:    * no combining is done. The coelesced events are currently mouse moves
3610:    * (intermediate ones are discarded) and paint events (a merged paint is
3611:    * created in place of the two events).
3612:    *
3613:    * @param existingEvent the event on the queue
3614:    * @param newEvent the new event that might be entered on the queue
3615:    * @return null if both events are kept, or the replacement coelesced event
3616:    */
3617:   protected AWTEvent coalesceEvents(AWTEvent existingEvent, AWTEvent newEvent)
3618:   {
3619:     AWTEvent coalesced = null;
3620:     switch (existingEvent.id)
3621:       {
3622:       case MouseEvent.MOUSE_MOVED:
3623:       case MouseEvent.MOUSE_DRAGGED:
3624:         // Just drop the old (intermediate) event and return the new one.
3625:         MouseEvent me1 = (MouseEvent) existingEvent;
3626:         MouseEvent me2 = (MouseEvent) newEvent;
3627:         if (me1.getModifiers() == me2.getModifiers())
3628:           coalesced = newEvent;
3629:         break;
3630:       case PaintEvent.PAINT:
3631:       case PaintEvent.UPDATE:
3632:         // For heavyweights the EventQueue should ask the peer.
3633:         if (peer == null || peer instanceof LightweightPeer)
3634:           {
3635:             PaintEvent pe1 = (PaintEvent) existingEvent;
3636:             PaintEvent pe2 = (PaintEvent) newEvent;
3637:             Rectangle r1 = pe1.getUpdateRect();
3638:             Rectangle r2 = pe2.getUpdateRect();
3639:             if (r1.contains(r2))
3640:               coalesced = existingEvent;
3641:             else if (r2.contains(r1))
3642:               coalesced = newEvent;
3643:           }
3644:         else
3645:           {
3646:             // Replace the event and let the heavyweight figure out the expanding
3647:             // of the repaint area.
3648:             coalesced = newEvent;
3649:           }
3650:         break;
3651:       default:
3652:         coalesced = null;
3653:       }
3654:     return coalesced;
3655:   }
3656: 
3657:   /**
3658:    * Processes the specified event. In this class, this method simply
3659:    * calls one of the more specific event handlers.
3660:    *
3661:    * @param e the event to process
3662:    * @throws NullPointerException if e is null
3663:    * @see #processComponentEvent(ComponentEvent)
3664:    * @see #processFocusEvent(FocusEvent)
3665:    * @see #processKeyEvent(KeyEvent)
3666:    * @see #processMouseEvent(MouseEvent)
3667:    * @see #processMouseMotionEvent(MouseEvent)
3668:    * @see #processInputMethodEvent(InputMethodEvent)
3669:    * @see #processHierarchyEvent(HierarchyEvent)
3670:    * @see #processMouseWheelEvent(MouseWheelEvent)
3671:    * @since 1.1
3672:    */
3673:   protected void processEvent(AWTEvent e)
3674:   {
3675:     /* Note: the order of these if statements are
3676:        important. Subclasses must be checked first. Eg. MouseEvent
3677:        must be checked before ComponentEvent, since a MouseEvent
3678:        object is also an instance of a ComponentEvent. */
3679: 
3680:     if (e instanceof FocusEvent)
3681:       processFocusEvent((FocusEvent) e);
3682:     else if (e instanceof MouseWheelEvent)
3683:       processMouseWheelEvent((MouseWheelEvent) e);
3684:     else if (e instanceof MouseEvent)
3685:       {
3686:         if (e.id == MouseEvent.MOUSE_MOVED
3687:             || e.id == MouseEvent.MOUSE_DRAGGED)
3688:           processMouseMotionEvent((MouseEvent) e);
3689:         else
3690:           processMouseEvent((MouseEvent) e);
3691:       }
3692:     else if (e instanceof KeyEvent)
3693:       processKeyEvent((KeyEvent) e);
3694:     else if (e instanceof InputMethodEvent)
3695:       processInputMethodEvent((InputMethodEvent) e);
3696:     else if (e instanceof ComponentEvent)
3697:       processComponentEvent((ComponentEvent) e);
3698:     else if (e instanceof HierarchyEvent)
3699:       {
3700:         if (e.id == HierarchyEvent.HIERARCHY_CHANGED)
3701:           processHierarchyEvent((HierarchyEvent) e);
3702:         else
3703:           processHierarchyBoundsEvent((HierarchyEvent) e);
3704:       }
3705:   }
3706: 
3707:   /**
3708:    * Called when a component event is dispatched and component events are
3709:    * enabled. This method passes the event along to any listeners
3710:    * that are attached.
3711:    *
3712:    * @param e the <code>ComponentEvent</code> to process
3713:    * @throws NullPointerException if e is null
3714:    * @see ComponentListener
3715:    * @see #addComponentListener(ComponentListener)
3716:    * @see #enableEvents(long)
3717:    * @since 1.1
3718:    */
3719:   protected void processComponentEvent(ComponentEvent e)
3720:   {
3721:     if (componentListener == null)
3722:       return;
3723:     switch (e.id)
3724:       {
3725:       case ComponentEvent.COMPONENT_HIDDEN:
3726:         componentListener.componentHidden(e);
3727:         break;
3728:       case ComponentEvent.COMPONENT_MOVED:
3729:         componentListener.componentMoved(e);
3730:         break;
3731:       case ComponentEvent.COMPONENT_RESIZED:
3732:         componentListener.componentResized(e);
3733:         break;
3734:       case ComponentEvent.COMPONENT_SHOWN:
3735:         componentListener.componentShown(e);
3736:         break;
3737:       }
3738:   }
3739: 
3740:   /**
3741:    * Called when a focus event is dispatched and component events are
3742:    * enabled. This method passes the event along to any listeners
3743:    * that are attached.
3744:    *
3745:    * @param e the <code>FocusEvent</code> to process
3746:    * @throws NullPointerException if e is null
3747:    * @see FocusListener
3748:    * @see #addFocusListener(FocusListener)
3749:    * @see #enableEvents(long)
3750:    * @since 1.1
3751:    */
3752:   protected void processFocusEvent(FocusEvent e)
3753:   {
3754:     if (focusListener == null)
3755:       return;
3756: 
3757:     switch (e.id)
3758:       {
3759:         case FocusEvent.FOCUS_GAINED:
3760:           focusListener.focusGained(e);
3761:         break;
3762:         case FocusEvent.FOCUS_LOST:
3763:           focusListener.focusLost(e);
3764:         break;
3765:       }
3766:   }
3767: 
3768:   /**
3769:    * Called when a key event is dispatched and component events are
3770:    * enabled. This method passes the event along to any listeners
3771:    * that are attached.
3772:    *
3773:    * @param e the <code>KeyEvent</code> to process
3774:    * @throws NullPointerException if e is null
3775:    * @see KeyListener
3776:    * @see #addKeyListener(KeyListener)
3777:    * @see #enableEvents(long)
3778:    * @since 1.1
3779:    */
3780:   protected void processKeyEvent(KeyEvent e)
3781:   {
3782:     if (keyListener == null)
3783:       return;
3784:     switch (e.id)
3785:       {
3786:         case KeyEvent.KEY_PRESSED:
3787:           keyListener.keyPressed(e);
3788:         break;
3789:         case KeyEvent.KEY_RELEASED:
3790:           keyListener.keyReleased(e);
3791:         break;
3792:         case KeyEvent.KEY_TYPED:
3793:           keyListener.keyTyped(e);
3794:         break;
3795:       }
3796:   }
3797: 
3798:   /**
3799:    * Called when a regular mouse event is dispatched and component events are
3800:    * enabled. This method passes the event along to any listeners
3801:    * that are attached.
3802:    *
3803:    * @param e the <code>MouseEvent</code> to process
3804:    * @throws NullPointerException if e is null
3805:    * @see MouseListener
3806:    * @see #addMouseListener(MouseListener)
3807:    * @see #enableEvents(long)
3808:    * @since 1.1
3809:    */
3810:   protected void processMouseEvent(MouseEvent e)
3811:   {
3812:     if (mouseListener == null)
3813:       return;
3814:     switch (e.id)
3815:       {
3816:         case MouseEvent.MOUSE_CLICKED:
3817:           mouseListener.mouseClicked(e);
3818:         break;
3819:         case MouseEvent.MOUSE_ENTERED:
3820:        if( isLightweight() )
3821:          setCursor( getCursor() );
3822:           mouseListener.mouseEntered(e);
3823:         break;
3824:         case MouseEvent.MOUSE_EXITED:
3825:           mouseListener.mouseExited(e);
3826:         break;
3827:         case MouseEvent.MOUSE_PRESSED:
3828:           mouseListener.mousePressed(e);
3829:         break;
3830:         case MouseEvent.MOUSE_RELEASED:
3831:           mouseListener.mouseReleased(e);
3832:         break;
3833:       }
3834:   }
3835: 
3836:   /**
3837:    * Called when a mouse motion event is dispatched and component events are
3838:    * enabled. This method passes the event along to any listeners
3839:    * that are attached.
3840:    *
3841:    * @param e the <code>MouseMotionEvent</code> to process
3842:    * @throws NullPointerException if e is null
3843:    * @see MouseMotionListener
3844:    * @see #addMouseMotionListener(MouseMotionListener)
3845:    * @see #enableEvents(long)
3846:    * @since 1.1
3847:    */
3848:   protected void processMouseMotionEvent(MouseEvent e)
3849:   {
3850:     if (mouseMotionListener == null)
3851:       return;
3852:     switch (e.id)
3853:       {
3854:         case MouseEvent.MOUSE_DRAGGED:
3855:           mouseMotionListener.mouseDragged(e);
3856:         break;
3857:         case MouseEvent.MOUSE_MOVED:
3858:           mouseMotionListener.mouseMoved(e);
3859:         break;
3860:       }
3861:       e.consume();
3862:   }
3863: 
3864:   /**
3865:    * Called when a mouse wheel event is dispatched and component events are
3866:    * enabled. This method passes the event along to any listeners that are
3867:    * attached.
3868:    *
3869:    * @param e the <code>MouseWheelEvent</code> to process
3870:    * @throws NullPointerException if e is null
3871:    * @see MouseWheelListener
3872:    * @see #addMouseWheelListener(MouseWheelListener)
3873:    * @see #enableEvents(long)
3874:    * @since 1.4
3875:    */
3876:   protected void processMouseWheelEvent(MouseWheelEvent e)
3877:   {
3878:     if (mouseWheelListener != null
3879:         && e.id == MouseEvent.MOUSE_WHEEL)
3880:     {
3881:       mouseWheelListener.mouseWheelMoved(e);
3882:       e.consume();
3883:     }    
3884:   }
3885: 
3886:   /**
3887:    * Called when an input method event is dispatched and component events are
3888:    * enabled. This method passes the event along to any listeners that are
3889:    * attached.
3890:    *
3891:    * @param e the <code>InputMethodEvent</code> to process
3892:    * @throws NullPointerException if e is null
3893:    * @see InputMethodListener
3894:    * @see #addInputMethodListener(InputMethodListener)
3895:    * @see #enableEvents(long)
3896:    * @since 1.2
3897:    */
3898:   protected void processInputMethodEvent(InputMethodEvent e)
3899:   {
3900:     if (inputMethodListener == null)
3901:       return;
3902:     switch (e.id)
3903:       {
3904:         case InputMethodEvent.CARET_POSITION_CHANGED:
3905:           inputMethodListener.caretPositionChanged(e);
3906:         break;
3907:         case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
3908:           inputMethodListener.inputMethodTextChanged(e);
3909:         break;
3910:       }
3911:   }
3912: 
3913:   /**
3914:    * Called when a hierarchy change event is dispatched and component events
3915:    * are enabled. This method passes the event along to any listeners that are
3916:    * attached.
3917:    *
3918:    * @param e the <code>HierarchyEvent</code> to process
3919:    * @throws NullPointerException if e is null
3920:    * @see HierarchyListener
3921:    * @see #addHierarchyListener(HierarchyListener)
3922:    * @see #enableEvents(long)
3923:    * @since 1.3
3924:    */
3925:   protected void processHierarchyEvent(HierarchyEvent e)
3926:   {
3927:     if (hierarchyListener == null)
3928:       return;
3929:     if (e.id == HierarchyEvent.HIERARCHY_CHANGED)
3930:       hierarchyListener.hierarchyChanged(e);
3931:   }
3932: 
3933:   /**
3934:    * Called when a hierarchy bounds event is dispatched and component events
3935:    * are enabled. This method passes the event along to any listeners that are
3936:    * attached.
3937:    *
3938:    * @param e the <code>HierarchyEvent</code> to process
3939:    * @throws NullPointerException if e is null
3940:    * @see HierarchyBoundsListener
3941:    * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
3942:    * @see #enableEvents(long)
3943:    * @since 1.3
3944:    */
3945:   protected void processHierarchyBoundsEvent(HierarchyEvent e)
3946:   {
3947:     if (hierarchyBoundsListener == null)
3948:       return;
3949:     switch (e.id)
3950:       {
3951:         case HierarchyEvent.ANCESTOR_MOVED:
3952:           hierarchyBoundsListener.ancestorMoved(e);
3953:         break;
3954:         case HierarchyEvent.ANCESTOR_RESIZED:
3955:           hierarchyBoundsListener.ancestorResized(e);
3956:         break;
3957:       }
3958:   }
3959: 
3960:   /**
3961:    * AWT 1.0 event handler.
3962:    *
3963:    * This method calls one of the event-specific handler methods.  For
3964:    * example for key events, either {@link #keyDown(Event,int)}
3965:    * or {@link #keyUp(Event,int)} is called.  A derived
3966:    * component can override one of these event-specific methods if it
3967:    * only needs to handle certain event types.  Otherwise it can
3968:    * override handleEvent itself and handle any event.
3969:    *
3970:    * @param evt the event to handle
3971:    * @return true if the event was handled, false otherwise
3972:    * @deprecated use {@link #processEvent(AWTEvent)} instead
3973:    */
3974:   public boolean handleEvent (Event evt)
3975:   {
3976:     switch (evt.id)
3977:       {
3978:     // Handle key events.
3979:       case Event.KEY_ACTION:
3980:       case Event.KEY_PRESS:
3981:     return keyDown (evt, evt.key);
3982:       case Event.KEY_ACTION_RELEASE:
3983:       case Event.KEY_RELEASE:
3984:     return keyUp (evt, evt.key);
3985: 
3986:     // Handle mouse events.
3987:       case Event.MOUSE_DOWN:
3988:     return mouseDown (evt, evt.x, evt.y);
3989:       case Event.MOUSE_UP:
3990:     return mouseUp (evt, evt.x, evt.y);
3991:       case Event.MOUSE_MOVE:
3992:     return mouseMove (evt, evt.x, evt.y);
3993:       case Event.MOUSE_DRAG:
3994:     return mouseDrag (evt, evt.x, evt.y);
3995:       case Event.MOUSE_ENTER:
3996:     return mouseEnter (evt, evt.x, evt.y);
3997:       case Event.MOUSE_EXIT:
3998:     return mouseExit (evt, evt.x, evt.y);
3999: 
4000:     // Handle focus events.
4001:       case Event.GOT_FOCUS:
4002:     return gotFocus (evt, evt.arg);
4003:       case Event.LOST_FOCUS:
4004:     return lostFocus (evt, evt.arg);
4005: 
4006:     // Handle action event.
4007:       case Event.ACTION_EVENT:
4008:     return action (evt, evt.arg);
4009:       }
4010:     // Unknown event.
4011:     return false;
4012:   }
4013: 
4014:   /**
4015:    * AWT 1.0 MOUSE_DOWN event handler.  This method is meant to be
4016:    * overridden by components providing their own MOUSE_DOWN handler.
4017:    * The default implementation simply returns false.
4018:    *
4019:    * @param evt the event to handle
4020:    * @param x the x coordinate, ignored
4021:    * @param y the y coordinate, ignored
4022:    * @return false
4023:    * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
4024:    */
4025:   public boolean mouseDown(Event evt, int x, int y)
4026:   {
4027:     return false;
4028:   }
4029: 
4030:   /**
4031:    * AWT 1.0 MOUSE_DRAG event handler.  This method is meant to be
4032:    * overridden by components providing their own MOUSE_DRAG handler.
4033:    * The default implementation simply returns false.
4034:    *
4035:    * @param evt the event to handle
4036:    * @param x the x coordinate, ignored
4037:    * @param y the y coordinate, ignored
4038:    * @return false
4039:    * @deprecated use {@link #processMouseMotionEvent(MouseEvent)} instead
4040:    */
4041:   public boolean mouseDrag(Event evt, int x, int y)
4042:   {
4043:     return false;
4044:   }
4045: 
4046:   /**
4047:    * AWT 1.0 MOUSE_UP event handler.  This method is meant to be
4048:    * overridden by components providing their own MOUSE_UP handler.
4049:    * The default implementation simply returns false.
4050:    *
4051:    * @param evt the event to handle
4052:    * @param x the x coordinate, ignored
4053:    * @param y the y coordinate, ignored
4054:    * @return false
4055:    * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
4056:    */
4057:   public boolean mouseUp(Event evt, int x, int y)
4058:   {
4059:     return false;
4060:   }
4061: 
4062:   /**
4063:    * AWT 1.0 MOUSE_MOVE event handler.  This method is meant to be
4064:    * overridden by components providing their own MOUSE_MOVE handler.
4065:    * The default implementation simply returns false.
4066:    *
4067:    * @param evt the event to handle
4068:    * @param x the x coordinate, ignored
4069:    * @param y the y coordinate, ignored
4070:    * @return false
4071:    * @deprecated use {@link #processMouseMotionEvent(MouseEvent)} instead
4072:    */
4073:   public boolean mouseMove(Event evt, int x, int y)
4074:   {
4075:     return false;
4076:   }
4077: 
4078:   /**
4079:    * AWT 1.0 MOUSE_ENTER event handler.  This method is meant to be
4080:    * overridden by components providing their own MOUSE_ENTER handler.
4081:    * The default implementation simply returns false.
4082:    *
4083:    * @param evt the event to handle
4084:    * @param x the x coordinate, ignored
4085:    * @param y the y coordinate, ignored
4086:    * @return false
4087:    * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
4088:    */
4089:   public boolean mouseEnter(Event evt, int x, int y)
4090:   {
4091:     return false;
4092:   }
4093: 
4094:   /**
4095:    * AWT 1.0 MOUSE_EXIT event handler.  This method is meant to be
4096:    * overridden by components providing their own MOUSE_EXIT handler.
4097:    * The default implementation simply returns false.
4098:    *
4099:    * @param evt the event to handle
4100:    * @param x the x coordinate, ignored
4101:    * @param y the y coordinate, ignored
4102:    * @return false
4103:    * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
4104:    */
4105:   public boolean mouseExit(Event evt, int x, int y)
4106:   {
4107:     return false;
4108:   }
4109: 
4110:   /**
4111:    * AWT 1.0 KEY_PRESS and KEY_ACTION event handler.  This method is
4112:    * meant to be overridden by components providing their own key
4113:    * press handler.  The default implementation simply returns false.
4114:    *
4115:    * @param evt the event to handle
4116:    * @param key the key pressed, ignored
4117:    * @return false
4118:    * @deprecated use {@link #processKeyEvent(KeyEvent)} instead
4119:    */
4120:   public boolean keyDown(Event evt, int key)
4121:   {
4122:     return false;
4123:   }
4124: 
4125:   /**
4126:    * AWT 1.0 KEY_RELEASE and KEY_ACTION_RELEASE event handler.  This
4127:    * method is meant to be overridden by components providing their
4128:    * own key release handler.  The default implementation simply
4129:    * returns false.
4130:    *
4131:    * @param evt the event to handle
4132:    * @param key the key pressed, ignored
4133:    * @return false
4134:    * @deprecated use {@link #processKeyEvent(KeyEvent)} instead
4135:    */
4136:   public boolean keyUp(Event evt, int key)
4137:   {
4138:     return false;
4139:   }
4140: 
4141:   /**
4142:    * AWT 1.0 ACTION_EVENT event handler.  This method is meant to be
4143:    * overridden by components providing their own action event
4144:    * handler.  The default implementation simply returns false.
4145:    *
4146:    * @param evt the event to handle
4147:    * @param what the object acted on, ignored
4148:    * @return false
4149:    * @deprecated in classes which support actions, use
4150:    *             <code>processActionEvent(ActionEvent)</code> instead
4151:    */
4152:   public boolean action(Event evt, Object what)
4153:   {
4154:     return false;
4155:   }
4156: 
4157:   /**
4158:    * Called when the parent of this Component is made visible or when
4159:    * the Component is added to an already visible Container and needs
4160:    * to be shown.  A native peer - if any - is created at this
4161:    * time. This method is called automatically by the AWT system and
4162:    * should not be called by user level code.
4163:    *
4164:    * @see #isDisplayable()
4165:    * @see #removeNotify()
4166:    */
4167:   public void addNotify()
4168:   {
4169:     // We need to lock the tree here to avoid races and inconsistencies.
4170:     synchronized (getTreeLock())
4171:       {
4172:         if (peer == null)
4173:           peer = getToolkit().createComponent(this);
4174:         else if (parent != null && parent.isLightweight())
4175:           new HeavyweightInLightweightListener(parent);
4176:         // Now that all the children has gotten their peers, we should
4177:         // have the event mask needed for this component and its
4178:         //lightweight subcomponents.
4179:         peer.setEventMask(eventMask);
4180: 
4181:         // We used to leave the invalidate() to the peer. However, I put it
4182:         // back here for 2 reasons: 1) The RI does call invalidate() from
4183:         // addNotify(); 2) The peer shouldn't be bother with validation too
4184:         // much.
4185:         invalidate();
4186: 
4187:         if (dropTarget != null) 
4188:           dropTarget.addNotify(peer);
4189: 
4190:         // Fetch the peerFont for later installation in validate().
4191:         peerFont = getFont();
4192: 
4193:         // Notify hierarchy listeners.
4194:         long flags = HierarchyEvent.DISPLAYABILITY_CHANGED;
4195:         if (isHierarchyVisible())
4196:           flags |= HierarchyEvent.SHOWING_CHANGED;
4197:         fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED, this, parent,
4198:                            flags);
4199:       }
4200:   }
4201: 
4202:   /**
4203:    * Called to inform this component is has been removed from its
4204:    * container. Its native peer - if any - is destroyed at this time.
4205:    * This method is called automatically by the AWT system and should
4206:    * not be called by user level code.
4207:    *
4208:    * @see #isDisplayable()
4209:    * @see #addNotify()
4210:    */
4211:   public void removeNotify()
4212:   {
4213:     // We need to lock the tree here to avoid races and inconsistencies.
4214:     synchronized (getTreeLock())
4215:       {
4216:         // We null our peer field before disposing of it, such that if we're
4217:         // not the event dispatch thread and the dispatch thread is awoken by
4218:         // the dispose call, there will be no race checking the peer's null
4219:         // status.
4220: 
4221:         ComponentPeer tmp = peer;
4222:         peer = null;
4223:         peerFont = null;
4224:         if (tmp != null)
4225:           {
4226:             tmp.hide();
4227:             tmp.dispose();
4228:           }
4229: 
4230:         // Notify hierarchy listeners.
4231:         long flags = HierarchyEvent.DISPLAYABILITY_CHANGED;
4232:         if (isHierarchyVisible())
4233:           flags |= HierarchyEvent.SHOWING_CHANGED;
4234:         fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED, this, parent,
4235:                            flags);
4236:       }
4237:   }
4238: 
4239:   /**
4240:    * AWT 1.0 GOT_FOCUS event handler.  This method is meant to be
4241:    * overridden by components providing their own GOT_FOCUS handler.
4242:    * The default implementation simply returns false.
4243:    *
4244:    * @param evt the event to handle
4245:    * @param what the Object focused, ignored
4246:    * @return false
4247:    * @deprecated use {@link #processFocusEvent(FocusEvent)} instead
4248:    */
4249:   public boolean gotFocus(Event evt, Object what)
4250:   {
4251:     return false;
4252:   }
4253: 
4254:   /**
4255:    * AWT 1.0 LOST_FOCUS event handler.  This method is meant to be
4256:    * overridden by components providing their own LOST_FOCUS handler.
4257:    * The default implementation simply returns false.
4258:    *
4259:    * @param evt the event to handle
4260:    * @param what the Object focused, ignored
4261:    * @return false
4262:    * @deprecated use {@link #processFocusEvent(FocusEvent)} instead
4263:    */
4264:   public boolean lostFocus(Event evt, Object what)
4265:   {
4266:     return false;
4267:   }
4268: 
4269:   /**
4270:    * Tests whether or not this component is in the group that can be
4271:    * traversed using the keyboard traversal mechanism (such as the TAB key).
4272:    *
4273:    * @return true if the component is traversed via the TAB key
4274:    * @see #setFocusable(boolean)
4275:    * @since 1.1
4276:    * @deprecated use {@link #isFocusable()} instead
4277:    */
4278:   public boolean isFocusTraversable()
4279:   {
4280:     return enabled && visible && (peer == null || isLightweight() || peer.isFocusTraversable());
4281:   }
4282: 
4283:   /**
4284:    * Tests if this component can receive focus.
4285:    *
4286:    * @return true if this component can receive focus
4287:    * @since 1.4
4288:    */
4289:   public boolean isFocusable()
4290:   {
4291:     return focusable;
4292:   }
4293: 
4294:   /**
4295:    * Specify whether this component can receive focus. This method also
4296:    * sets the {@link #isFocusTraversableOverridden} field to 1, which
4297:    * appears to be the undocumented way {@link
4298:    * DefaultFocusTraversalPolicy#accept(Component)} determines whether to
4299:    * respect the {@link #isFocusable()} method of the component.
4300:    *
4301:    * @param focusable the new focusable status
4302:    * @since 1.4
4303:    */
4304:   public void setFocusable(boolean focusable)
4305:   {
4306:     firePropertyChange("focusable", this.focusable, focusable);
4307:     this.focusable = focusable;
4308:     this.isFocusTraversableOverridden = 1;
4309:   }
4310: 
4311:   /**
4312:    * Sets the focus traversal keys for one of the three focus
4313:    * traversal directions supported by Components:
4314:    * {@link KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS},
4315:    * {@link KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS}, or
4316:    * {@link KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS}. Normally, the
4317:    * default values should match the operating system's native
4318:    * choices. To disable a given traversal, use
4319:    * <code>Collections.EMPTY_SET</code>. The event dispatcher will
4320:    * consume PRESSED, RELEASED, and TYPED events for the specified
4321:    * key, although focus can only transfer on PRESSED or RELEASED.
4322:    *
4323:    * <p>The defaults are:
4324:    * <table>
4325:    *   <th><td>Identifier</td><td>Meaning</td><td>Default</td></th>
4326:    *   <tr><td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</td>
4327:    *     <td>Normal forward traversal</td>
4328:    *     <td>TAB on KEY_PRESSED, Ctrl-TAB on KEY_PRESSED</td></tr>
4329:    *   <tr><td>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</td>
4330:    *     <td>Normal backward traversal</td>
4331:    *     <td>Shift-TAB on KEY_PRESSED, Ctrl-Shift-TAB on KEY_PRESSED</td></tr>
4332:    *   <tr><td>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</td>
4333:    *     <td>Go up a traversal cycle</td><td>None</td></tr>
4334:    * </table>
4335:    *
4336:    * If keystrokes is null, this component's focus traversal key set
4337:    * is inherited from one of its ancestors.  If none of its ancestors
4338:    * has its own set of focus traversal keys, the focus traversal keys
4339:    * are set to the defaults retrieved from the current
4340:    * KeyboardFocusManager.  If not null, the set must contain only
4341:    * AWTKeyStrokes that are not already focus keys and are not
4342:    * KEY_TYPED events.
4343:    *
4344:    * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS, or
4345:    *        UP_CYCLE_TRAVERSAL_KEYS
4346:    * @param keystrokes a set of keys, or null
4347:    * @throws IllegalArgumentException if id or keystrokes is invalid
4348:    * @see #getFocusTraversalKeys(int)
4349:    * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
4350:    * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
4351:    * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
4352:    * @since 1.4
4353:    */
4354:   public void setFocusTraversalKeys(int id,
4355:                     Set<? extends AWTKeyStroke> keystrokes)
4356:   {
4357:     if (keystrokes == null)
4358:       {
4359:         Container parent = getParent ();
4360: 
4361:         while (parent != null)
4362:           {
4363:             if (parent.areFocusTraversalKeysSet (id))
4364:               {
4365:                 keystrokes = parent.getFocusTraversalKeys (id);
4366:                 break;
4367:               }
4368:             parent = parent.getParent ();
4369:           }
4370: 
4371:         if (keystrokes == null)
4372:           keystrokes = KeyboardFocusManager.getCurrentKeyboardFocusManager ().
4373:             getDefaultFocusTraversalKeys (id);
4374:       }
4375: 
4376:     Set sa;
4377:     Set sb;
4378:     String name;
4379:     switch (id)
4380:       {
4381:       case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS:
4382:         sa = getFocusTraversalKeys
4383:           (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
4384:         sb = getFocusTraversalKeys
4385:           (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
4386:         name = "forwardFocusTraversalKeys";
4387:         break;
4388:       case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS:
4389:         sa = getFocusTraversalKeys
4390:           (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
4391:         sb = getFocusTraversalKeys
4392:           (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
4393:         name = "backwardFocusTraversalKeys";
4394:         break;
4395:       case KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS:
4396:         sa = getFocusTraversalKeys
4397:           (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
4398:         sb = getFocusTraversalKeys
4399:           (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
4400:         name = "upCycleFocusTraversalKeys";
4401:         break;
4402:       default:
4403:         throw new IllegalArgumentException ();
4404:       }
4405: 
4406:     int i = keystrokes.size ();
4407:     Iterator iter = keystrokes.iterator ();
4408: 
4409:     while (--i >= 0)
4410:       {
4411:         Object o = iter.next ();
4412:         if (!(o instanceof AWTKeyStroke)
4413:             || sa.contains (o) || sb.contains (o)
4414:             || ((AWTKeyStroke) o).keyCode == KeyEvent.VK_UNDEFINED)
4415:           throw new IllegalArgumentException ();
4416:       }
4417: 
4418:     if (focusTraversalKeys == null)
4419:       focusTraversalKeys = new Set[3];
4420: 
4421:     keystrokes = Collections.unmodifiableSet (new HashSet (keystrokes));
4422:     firePropertyChange (name, focusTraversalKeys[id], keystrokes);
4423: 
4424:     focusTraversalKeys[id] = keystrokes;
4425:   }
4426: 
4427:   /**
4428:    * Returns the set of keys for a given focus traversal action, as
4429:    * defined in <code>setFocusTraversalKeys</code>.  If not set, this
4430:    * is inherited from the parent component, which may have gotten it
4431:    * from the KeyboardFocusManager.
4432:    *
4433:    * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS,
4434:    * or UP_CYCLE_TRAVERSAL_KEYS
4435:    *
4436:    * @return set of traversal keys
4437:    *
4438:    * @throws IllegalArgumentException if id is invalid
4439:    * 
4440:    * @see #setFocusTraversalKeys (int, Set)
4441:    * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
4442:    * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
4443:    * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
4444:    * 
4445:    * @since 1.4
4446:    */
4447:   public Set<AWTKeyStroke> getFocusTraversalKeys (int id)
4448:   {
4449:     if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
4450:         id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
4451:         id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS)
4452:       throw new IllegalArgumentException();
4453: 
4454:     Set<AWTKeyStroke> s = null;
4455: 
4456:     if (focusTraversalKeys != null)
4457:       s = focusTraversalKeys[id];
4458: 
4459:     if (s == null && parent != null)
4460:       s = parent.getFocusTraversalKeys (id);
4461: 
4462:     return s == null ? (KeyboardFocusManager.getCurrentKeyboardFocusManager()
4463:                         .getDefaultFocusTraversalKeys(id)) : s;
4464:   }
4465: 
4466:   /**
4467:    * Tests whether the focus traversal keys for a given action are explicitly
4468:    * set or inherited.
4469:    *
4470:    * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS,
4471:    * or UP_CYCLE_TRAVERSAL_KEYS
4472:    * @return true if that set is explicitly specified
4473:    * @throws IllegalArgumentException if id is invalid
4474:    * @see #getFocusTraversalKeys (int)
4475:    * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
4476:    * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
4477:    * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
4478:    * @since 1.4
4479:    */
4480:   public boolean areFocusTraversalKeysSet (int id)
4481:   {
4482:     if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
4483:         id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
4484:         id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS)
4485:       throw new IllegalArgumentException ();
4486: 
4487:     return focusTraversalKeys != null && focusTraversalKeys[id] != null;
4488:   }
4489: 
4490:   /**
4491:    * Enable or disable focus traversal keys on this Component.  If
4492:    * they are, then the keyboard focus manager consumes and acts on
4493:    * key press and release events that trigger focus traversal, and
4494:    * discards the corresponding key typed events.  If focus traversal
4495:    * keys are disabled, then all key events that would otherwise
4496:    * trigger focus traversal are sent to this Component.
4497:    *
4498:    * @param focusTraversalKeysEnabled the new value of the flag
4499:    * @see #getFocusTraversalKeysEnabled ()
4500:    * @see #setFocusTraversalKeys (int, Set)
4501:    * @see #getFocusTraversalKeys (int)
4502:    * @since 1.4
4503:    */
4504:   public void setFocusTraversalKeysEnabled (boolean focusTraversalKeysEnabled)
4505:   {
4506:     firePropertyChange ("focusTraversalKeysEnabled",
4507:             this.focusTraversalKeysEnabled,
4508:             focusTraversalKeysEnabled);
4509:     this.focusTraversalKeysEnabled = focusTraversalKeysEnabled;
4510:   }
4511: 
4512:   /**
4513:    * Check whether or not focus traversal keys are enabled on this
4514:    * Component.  If they are, then the keyboard focus manager consumes
4515:    * and acts on key press and release events that trigger focus
4516:    * traversal, and discards the corresponding key typed events.  If
4517:    * focus traversal keys are disabled, then all key events that would
4518:    * otherwise trigger focus traversal are sent to this Component.
4519:    *
4520:    * @return true if focus traversal keys are enabled
4521:    * @see #setFocusTraversalKeysEnabled (boolean)
4522:    * @see #setFocusTraversalKeys (int, Set)
4523:    * @see #getFocusTraversalKeys (int)
4524:    * @since 1.4
4525:    */
4526:   public boolean getFocusTraversalKeysEnabled ()
4527:   {
4528:     return focusTraversalKeysEnabled;
4529:   }
4530: 
4531:   /**
4532:    * Request that this Component be given the keyboard input focus and
4533:    * that its top-level ancestor become the focused Window.
4534:    *
4535:    * For the request to be granted, the Component must be focusable,
4536:    * displayable and showing and the top-level Window to which it
4537:    * belongs must be focusable.  If the request is initially denied on
4538:    * the basis that the top-level Window is not focusable, the request
4539:    * will be remembered and granted when the Window does become
4540:    * focused.
4541:    *
4542:    * Never assume that this Component is the focus owner until it
4543:    * receives a FOCUS_GAINED event.
4544:    *
4545:    * The behaviour of this method is platform-dependent.
4546:    * {@link #requestFocusInWindow()} should be used instead.
4547:    *
4548:    * @see #requestFocusInWindow ()
4549:    * @see FocusEvent
4550:    * @see #addFocusListener (FocusListener)
4551:    * @see #isFocusable ()
4552:    * @see #isDisplayable ()
4553:    * @see KeyboardFocusManager#clearGlobalFocusOwner ()
4554:    */
4555:   public void requestFocus ()
4556:   {
4557:     requestFocusImpl(false, true);
4558:   }
4559: 
4560:   /**
4561:    * Request that this Component be given the keyboard input focus and
4562:    * that its top-level ancestor become the focused Window.
4563:    *
4564:    * For the request to be granted, the Component must be focusable,
4565:    * displayable and showing and the top-level Window to which it
4566:    * belongs must be focusable.  If the request is initially denied on
4567:    * the basis that the top-level Window is not focusable, the request
4568:    * will be remembered and granted when the Window does become
4569:    * focused.
4570:    *
4571:    * Never assume that this Component is the focus owner until it
4572:    * receives a FOCUS_GAINED event.
4573:    *
4574:    * The behaviour of this method is platform-dependent.
4575:    * {@link #requestFocusInWindow()} should be used instead.
4576:    *
4577:    * If the return value is false, the request is guaranteed to fail.
4578:    * If the return value is true, the request will succeed unless it
4579:    * is vetoed or something in the native windowing system intervenes,
4580:    * preventing this Component's top-level ancestor from becoming
4581:    * focused.  This method is meant to be called by derived
4582:    * lightweight Components that want to avoid unnecessary repainting
4583:    * when they know a given focus transfer need only be temporary.
4584:    *
4585:    * @param temporary true if the focus request is temporary
4586:    * @return true if the request has a chance of success
4587:    * @see #requestFocusInWindow ()
4588:    * @see FocusEvent
4589:    * @see #addFocusListener (FocusListener)
4590:    * @see #isFocusable ()
4591:    * @see #isDisplayable ()
4592:    * @see KeyboardFocusManager#clearGlobalFocusOwner ()
4593:    * @since 1.4
4594:    */
4595:   protected boolean requestFocus (boolean temporary)
4596:   {
4597:     return requestFocusImpl(temporary, true);
4598:   }
4599: 
4600:   /**
4601:    * Request that this component be given the keyboard input focus, if
4602:    * its top-level ancestor is the currently focused Window.  A
4603:    * <code>FOCUS_GAINED</code> event will be fired if and only if this
4604:    * request is successful. To be successful, the component must be
4605:    * displayable, showing, and focusable, and its ancestor top-level
4606:    * Window must be focused.
4607:    *
4608:    * If the return value is false, the request is guaranteed to fail.
4609:    * If the return value is true, the request will succeed unless it
4610:    * is vetoed or something in the native windowing system intervenes,
4611:    * preventing this Component's top-level ancestor from becoming
4612:    * focused.
4613:    *
4614:    * @return true if the request has a chance of success
4615:    * @see #requestFocus ()
4616:    * @see FocusEvent
4617:    * @see #addFocusListener (FocusListener)
4618:    * @see #isFocusable ()
4619:    * @see #isDisplayable ()
4620:    * @see KeyboardFocusManager#clearGlobalFocusOwner ()
4621:    * @since 1.4
4622:    */
4623:   public boolean requestFocusInWindow ()
4624:   {
4625:     return requestFocusImpl(false, false);
4626:   }
4627: 
4628:   /**
4629:    * Request that this component be given the keyboard input focus, if
4630:    * its top-level ancestor is the currently focused Window.  A
4631:    * <code>FOCUS_GAINED</code> event will be fired if and only if this
4632:    * request is successful. To be successful, the component must be
4633:    * displayable, showing, and focusable, and its ancestor top-level
4634:    * Window must be focused.
4635:    *
4636:    * If the return value is false, the request is guaranteed to fail.
4637:    * If the return value is true, the request will succeed unless it
4638:    * is vetoed or something in the native windowing system intervenes,
4639:    * preventing this Component's top-level ancestor from becoming
4640:    * focused.  This method is meant to be called by derived
4641:    * lightweight Components that want to avoid unnecessary repainting
4642:    * when they know a given focus transfer need only be temporary.
4643:    *
4644:    * @param temporary true if the focus request is temporary
4645:    * @return true if the request has a chance of success
4646:    * @see #requestFocus ()
4647:    * @see FocusEvent
4648:    * @see #addFocusListener (FocusListener)
4649:    * @see #isFocusable ()
4650:    * @see #isDisplayable ()
4651:    * @see KeyboardFocusManager#clearGlobalFocusOwner ()
4652:    * @since 1.4
4653:    */
4654:   protected boolean requestFocusInWindow (boolean temporary)
4655:   {
4656:     return requestFocusImpl(temporary, false);
4657:   }
4658: 
4659:   /**
4660:    * Helper method for all 4 requestFocus variants.
4661:    *
4662:    * @param temporary indicates if the focus change is temporary
4663:    * @param focusWindow indicates if the window focus may be changed
4664:    *
4665:    * @return <code>false</code> if the request has been definitely denied,
4666:    *         <code>true</code> otherwise
4667:    */
4668:   private boolean requestFocusImpl(boolean temporary, boolean focusWindow)
4669:   {
4670:     boolean retval = false;
4671:  
4672:     // Don't try to focus non-focusable and non-visible components.
4673:     if (isFocusable() && isVisible())
4674:       {
4675:         ComponentPeer myPeer = peer;
4676:         if (peer != null)
4677:           {
4678:             // Find Window ancestor and find out if we're showing while
4679:             // doing this.
4680:             boolean showing = true;
4681:             Component window = this;
4682:             while (! (window instanceof Window))
4683:               {
4684:                 if (! window.isVisible())
4685:                   showing = false;
4686:                 window = window.parent;
4687:               }
4688:             // Don't allow focus when there is no window or the window
4689:             // is not focusable.
4690:             if (window != null && ((Window) window).isFocusableWindow()
4691:                 && showing)
4692:               {
4693:                 // Search for nearest heavy ancestor (including this
4694:                 // component).
4695:                 Component heavyweightParent = this;
4696:                 while (heavyweightParent.peer instanceof LightweightPeer)
4697:                   heavyweightParent = heavyweightParent.parent;
4698: 
4699:                 // Don't allow focus on lightweight components without
4700:                 // visible heavyweight ancestor
4701:                 if (heavyweightParent != null && heavyweightParent.isVisible())
4702:                   {
4703:                     // Don't allow focus when heavyweightParent has no peer.
4704:                     myPeer = heavyweightParent.peer;
4705:                     if (myPeer != null)
4706:                       {
4707:                         // Register lightweight focus request.
4708:                         if (heavyweightParent != this)
4709:                           {
4710:                             KeyboardFocusManager
4711:                             .addLightweightFocusRequest(heavyweightParent,
4712:                                                         this);
4713:                           }
4714: 
4715:                         // Try to focus the component.
4716:                         long time = EventQueue.getMostRecentEventTime();
4717:                         boolean success = myPeer.requestFocus(this, temporary,
4718:                                                               focusWindow,
4719:                                                               time);
4720:                         if (! success)
4721:                           {
4722:                             // Dequeue key events if focus request failed.
4723:                             KeyboardFocusManager kfm =
4724:                               KeyboardFocusManager.getCurrentKeyboardFocusManager();
4725:                             kfm.dequeueKeyEvents(time, this);
4726:                           }
4727:                         retval = success;
4728:                       }
4729:                   }
4730:               }
4731:           }
4732:       }
4733:     return retval;
4734:   }
4735: 
4736:   /**
4737:    * Transfers focus to the next component in the focus traversal
4738:    * order, as though this were the current focus owner.
4739:    *
4740:    * @see #requestFocus()
4741:    * @since 1.1
4742:    */
4743:   public void transferFocus ()
4744:   {
4745:     nextFocus ();
4746:   }
4747: 
4748:   /**
4749:    * Returns the root container that owns the focus cycle where this
4750:    * component resides. A focus cycle root is in two cycles, one as
4751:    * the ancestor, and one as the focusable element; this call always
4752:    * returns the ancestor.
4753:    *
4754:    * @return the ancestor container that owns the focus cycle
4755:    * @since 1.4
4756:    */
4757:   public Container getFocusCycleRootAncestor ()
4758:   {
4759:     Container parent = getParent ();
4760: 
4761:     while (parent != null && !parent.isFocusCycleRoot())
4762:       parent = parent.getParent ();
4763: 
4764:     return parent;
4765:   }
4766: 
4767:   /**
4768:    * Tests if the container is the ancestor of the focus cycle that
4769:    * this component belongs to.
4770:    *
4771:    * @param c the container to test
4772:    * @return true if c is the focus cycle root
4773:    * @since 1.4
4774:    */
4775:   public boolean isFocusCycleRoot (Container c)
4776:   {
4777:     return c == getFocusCycleRootAncestor ();
4778:   }
4779: 
4780:   /**
4781:    * AWT 1.0 focus event processor.  Transfers focus to the next
4782:    * component in the focus traversal order, as though this were the
4783:    * current focus owner.
4784:    *
4785:    * @deprecated use {@link #transferFocus ()} instead
4786:    */
4787:   public void nextFocus ()
4788:   {
4789:     // Find the nearest valid (== showing && focusable && enabled) focus
4790:     // cycle root ancestor and the focused component in it.
4791:     Container focusRoot = getFocusCycleRootAncestor();
4792:     Component focusComp = this;
4793:     while (focusRoot != null
4794:            && ! (focusRoot.isShowing() && focusRoot.isFocusable()
4795:                  && focusRoot.isEnabled()))
4796:       {
4797:         focusComp = focusRoot;
4798:         focusRoot = focusComp.getFocusCycleRootAncestor();
4799:       }
4800: 
4801:     if (focusRoot != null)
4802:       {
4803:         // First try to get the componentBefore from the policy.
4804:         FocusTraversalPolicy policy = focusRoot.getFocusTraversalPolicy();
4805:         Component nextFocus = policy.getComponentAfter(focusRoot, focusComp);
4806: 
4807:         // If this fails, then ask for the defaultComponent.
4808:         if (nextFocus == null)
4809:           nextFocus = policy.getDefaultComponent(focusRoot);
4810: 
4811:         // Request focus on this component, if not null.
4812:         if (nextFocus != null)
4813:           nextFocus.requestFocus();
4814:       }
4815:   }
4816: 
4817:   /**
4818:    * Transfers focus to the previous component in the focus traversal
4819:    * order, as though this were the current focus owner.
4820:    *
4821:    * @see #requestFocus ()
4822:    * @since 1.4
4823:    */
4824:   public void transferFocusBackward ()
4825:   {
4826:     // Find the nearest valid (== showing && focusable && enabled) focus
4827:     // cycle root ancestor and the focused component in it.
4828:     Container focusRoot = getFocusCycleRootAncestor();
4829:     Component focusComp = this;
4830:     while (focusRoot != null
4831:            && ! (focusRoot.isShowing() && focusRoot.isFocusable()
4832:                  && focusRoot.isEnabled()))
4833:       {
4834:         focusComp = focusRoot;
4835:         focusRoot = focusComp.getFocusCycleRootAncestor();
4836:       }
4837: 
4838:     if (focusRoot != null)
4839:       {
4840:         // First try to get the componentBefore from the policy.
4841:         FocusTraversalPolicy policy = focusRoot.getFocusTraversalPolicy();
4842:         Component nextFocus = policy.getComponentBefore(focusRoot, focusComp);
4843: 
4844:         // If this fails, then ask for the defaultComponent.
4845:         if (nextFocus == null)
4846:           nextFocus = policy.getDefaultComponent(focusRoot);
4847: 
4848:         // Request focus on this component, if not null.
4849:         if (nextFocus != null)
4850:           nextFocus.requestFocus();
4851:       }
4852:   }
4853: 
4854:   /**
4855:    * Transfers focus to the focus cycle root of this component.
4856:    * However, if this is a Window, the default focus owner in the
4857:    * window in the current focus cycle is focused instead.
4858:    *
4859:    * @see #requestFocus()
4860:    * @see #isFocusCycleRoot(Container)
4861:    * @since 1.4
4862:    */
4863:   public void transferFocusUpCycle ()
4864:   {
4865:     // Find the nearest focus cycle root ancestor that is itself
4866:     // focusable, showing and enabled.
4867:     Container focusCycleRoot = getFocusCycleRootAncestor();
4868:     while (focusCycleRoot != null &&
4869:            ! (focusCycleRoot.isShowing() && focusCycleRoot.isFocusable()
4870:               && focusCycleRoot.isEnabled()))
4871:       {
4872:         focusCycleRoot = focusCycleRoot.getFocusCycleRootAncestor();
4873:       }
4874: 
4875:     KeyboardFocusManager fm =
4876:       KeyboardFocusManager.getCurrentKeyboardFocusManager();
4877: 
4878:     if (focusCycleRoot != null)
4879:       {
4880:         // If we found a focus cycle root, then we make this the new
4881:         // focused component, and make it's focus cycle root the new
4882:         // global focus cycle root. If the found root has no focus cycle
4883:         // root ancestor itself, then the component will be both the focused
4884:         // component and the new global focus cycle root.
4885:         Container focusCycleAncestor =
4886:           focusCycleRoot.getFocusCycleRootAncestor();
4887:         Container globalFocusCycleRoot;
4888:         if (focusCycleAncestor == null)
4889:           globalFocusCycleRoot = focusCycleRoot;
4890:         else
4891:           globalFocusCycleRoot = focusCycleAncestor;
4892: 
4893:         fm.setGlobalCurrentFocusCycleRoot(globalFocusCycleRoot);
4894:         focusCycleRoot.requestFocus();
4895:       }
4896:     else
4897:       {
4898:         // If this component has no applicable focus cycle root, we try
4899:         // find the nearest window and set this as the new global focus cycle
4900:         // root and the default focus component of this window the new focused
4901:         // component.
4902:         Container cont;
4903:         if (this instanceof Container)
4904:           cont = (Container) this;
4905:         else
4906:           cont = getParent();
4907: 
4908:         while (cont != null && !(cont instanceof Window))
4909:           cont = cont.getParent();
4910: 
4911:         if (cont != null)
4912:           {
4913:             FocusTraversalPolicy policy = cont.getFocusTraversalPolicy();
4914:             Component focusComp = policy.getDefaultComponent(cont);
4915:             if (focusComp != null)
4916:               {
4917:                 fm.setGlobalCurrentFocusCycleRoot(cont);
4918:                 focusComp.requestFocus();
4919:               }
4920:           }
4921:       }
4922:   }
4923: 
4924:   /**
4925:    * Tests if this component is the focus owner. Use {@link
4926:    * #isFocusOwner ()} instead.
4927:    *
4928:    * @return true if this component owns focus
4929:    * @since 1.2
4930:    */
4931:   public boolean hasFocus ()
4932:   {
4933:     KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
4934: 
4935:     Component focusOwner = manager.getFocusOwner ();
4936: 
4937:     return this == focusOwner;
4938:   }
4939: 
4940:   /**
4941:    * Tests if this component is the focus owner.
4942:    *
4943:    * @return true if this component owns focus
4944:    * @since 1.4
4945:    */
4946:   public boolean isFocusOwner()
4947:   {
4948:     return hasFocus ();
4949:   }
4950: 
4951:   /**
4952:    * Adds the specified popup menu to this component.
4953:    *
4954:    * @param popup the popup menu to be added
4955:    * 
4956:    * @see #remove(MenuComponent)
4957:    * 
4958:    * @since 1.1
4959:    */
4960:   public synchronized void add(PopupMenu popup)
4961:   {
4962:     if (popups == null)
4963:       popups = new Vector();
4964:     popups.add(popup);
4965: 
4966:     if (popup.parent != null)
4967:       popup.parent.remove(popup);
4968:     popup.parent = this;
4969:     if (peer != null)
4970:       popup.addNotify();
4971:   }
4972: 
4973:   /**
4974:    * Removes the specified popup menu from this component.
4975:    *
4976:    * @param popup the popup menu to remove
4977:    * @see #add(PopupMenu)
4978:    * @since 1.1
4979:    */
4980:   public synchronized void remove(MenuComponent popup)
4981:   {
4982:     if (popups != null)
4983:       popups.remove(popup);
4984:   }
4985: 
4986:   /**
4987:    * Returns a debugging string representing this component. The string may
4988:    * be empty but not null.
4989:    *
4990:    * @return a string representing this component
4991:    */
4992:   protected String paramString()
4993:   {
4994:     StringBuffer param = new StringBuffer();
4995:     String name = getName();
4996:     if (name != null)
4997:       param.append(name).append(",");
4998:     param.append(x).append(",").append(y).append(",").append(width)
4999:       .append("x").append(height);
5000:     if (! isValid())
5001:       param.append(",invalid");
5002:     if (! isVisible())
5003:       param.append(",invisible");
5004:     if (! isEnabled())
5005:       param.append(",disabled");
5006:     if (! isOpaque())
5007:       param.append(",translucent");
5008:     if (isDoubleBuffered())
5009:       param.append(",doublebuffered");
5010:     if (parent == null)
5011:       param.append(",parent=null");
5012:     else
5013:       param.append(",parent=").append(parent.getName());
5014:     return param.toString();
5015:   }
5016: 
5017:   /**
5018:    * Returns a string representation of this component. This is implemented
5019:    * as <code>getClass().getName() + '[' + paramString() + ']'</code>.
5020:    *
5021:    * @return a string representation of this component
5022:    */
5023:   public String toString()
5024:   {
5025:     return getClass().getName() + '[' + paramString() + ']';
5026:   }
5027: 
5028:   /**
5029:    * Prints a listing of this component to <code>System.out</code>.
5030:    *
5031:    * @see #list(PrintStream)
5032:    */
5033:   public void list()
5034:   {
5035:     list(System.out, 0);
5036:   }
5037: 
5038:   /**
5039:    * Prints a listing of this component to the specified print stream.
5040:    *
5041:    * @param out the <code>PrintStream</code> to print to
5042:    */
5043:   public void list(PrintStream out)
5044:   {
5045:     list(out, 0);
5046:   }
5047: 
5048:   /**
5049:    * Prints a listing of this component to the specified print stream,
5050:    * starting at the specified indentation point.
5051:    *
5052:    * @param out the <code>PrintStream</code> to print to
5053:    * @param indent the indentation point
5054:    */
5055:   public void list(PrintStream out, int indent)
5056:   {
5057:     for (int i = 0; i < indent; ++i)
5058:       out.print(' ');
5059:     out.println(toString());
5060:   }
5061: 
5062:   /**
5063:    * Prints a listing of this component to the specified print writer.
5064:    *
5065:    * @param out the <code>PrintWrinter</code> to print to
5066:    * @since 1.1
5067:    */
5068:   public void list(PrintWriter out)
5069:   {
5070:     list(out, 0);
5071:   }
5072: 
5073:   /**
5074:    * Prints a listing of this component to the specified print writer,
5075:    * starting at the specified indentation point.
5076:    *
5077:    * @param out the <code>PrintWriter</code> to print to
5078:    * @param indent the indentation point
5079:    * @since 1.1
5080:    */
5081:   public void list(PrintWriter out, int indent)
5082:   {
5083:     for (int i = 0; i < indent; ++i)
5084:       out.print(' ');
5085:     out.println(toString());
5086:   }
5087: 
5088:   /**
5089:    * Adds the specified property listener to this component. This is harmless
5090:    * if the listener is null, but if the listener has already been registered,
5091:    * it will now be registered twice. The property listener ignores inherited
5092:    * properties. Recognized properties include:<br>
5093:    * <ul>
5094:    * <li>the font (<code>"font"</code>)</li>
5095:    * <li>the background color (<code>"background"</code>)</li>
5096:    * <li>the foreground color (<code>"foreground"</code>)</li>
5097:    * <li>the focusability (<code>"focusable"</code>)</li>
5098:    * <li>the focus key traversal enabled state
5099:    *     (<code>"focusTraversalKeysEnabled"</code>)</li>
5100:    * <li>the set of forward traversal keys
5101:    *     (<code>"forwardFocusTraversalKeys"</code>)</li>
5102:    * <li>the set of backward traversal keys
5103:    *     (<code>"backwardFocusTraversalKeys"</code>)</li>
5104:    * <li>the set of up-cycle traversal keys
5105:    *     (<code>"upCycleFocusTraversalKeys"</code>)</li>
5106:    * </ul>
5107:    *
5108:    * @param listener the new listener to add
5109:    * @see #removePropertyChangeListener(PropertyChangeListener)
5110:    * @see #getPropertyChangeListeners()
5111:    * @see #addPropertyChangeListener(String, PropertyChangeListener)
5112:    * @since 1.1
5113:    */
5114:   public void addPropertyChangeListener(PropertyChangeListener listener)
5115:   {
5116:     if (changeSupport == null)
5117:       changeSupport = new PropertyChangeSupport(this);
5118:     changeSupport.addPropertyChangeListener(listener);
5119:   }
5120: 
5121:   /**
5122:    * Removes the specified property listener from the component. This is
5123:    * harmless if the listener was not previously registered.
5124:    *
5125:    * @param listener the listener to remove
5126:    * @see #addPropertyChangeListener(PropertyChangeListener)
5127:    * @see #getPropertyChangeListeners()
5128:    * @see #removePropertyChangeListener(String, PropertyChangeListener)
5129:    * @since 1.1
5130:    */
5131:   public void removePropertyChangeListener(PropertyChangeListener listener)
5132:   {
5133:     if (changeSupport != null)
5134:       changeSupport.removePropertyChangeListener(listener);
5135:   }
5136: 
5137:   /**
5138:    * Returns an array of all specified listeners registered on this component.
5139:    *
5140:    * @return an array of listeners
5141:    * @see #addPropertyChangeListener(PropertyChangeListener)
5142:    * @see #removePropertyChangeListener(PropertyChangeListener)
5143:    * @see #getPropertyChangeListeners(String)
5144:    * @since 1.4
5145:    */
5146:   public PropertyChangeListener[] getPropertyChangeListeners()
5147:   {
5148:     return changeSupport == null ? new PropertyChangeListener[0]
5149:       : changeSupport.getPropertyChangeListeners();
5150:   }
5151: 
5152:   /**
5153:    * Adds the specified property listener to this component. This is harmless
5154:    * if the listener is null, but if the listener has already been registered,
5155:    * it will now be registered twice. The property listener ignores inherited
5156:    * properties. The listener is keyed to a single property. Recognized
5157:    * properties include:<br>
5158:    * <ul>
5159:    * <li>the font (<code>"font"</code>)</li>
5160:    * <li>the background color (<code>"background"</code>)</li>
5161:    * <li>the foreground color (<code>"foreground"</code>)</li>
5162:    * <li>the focusability (<code>"focusable"</code>)</li>
5163:    * <li>the focus key traversal enabled state
5164:    *     (<code>"focusTraversalKeysEnabled"</code>)</li>
5165:    * <li>the set of forward traversal keys
5166:    *     (<code>"forwardFocusTraversalKeys"</code>)</li>
5167: p   * <li>the set of backward traversal keys
5168:    *     (<code>"backwardFocusTraversalKeys"</code>)</li>
5169:    * <li>the set of up-cycle traversal keys
5170:    *     (<code>"upCycleFocusTraversalKeys"</code>)</li>
5171:    * </ul>
5172:    *
5173:    * @param propertyName the property name to filter on
5174:    * @param listener the new listener to add
5175:    * @see #removePropertyChangeListener(String, PropertyChangeListener)
5176:    * @see #getPropertyChangeListeners(String)
5177:    * @see #addPropertyChangeListener(PropertyChangeListener)
5178:    * @since 1.1
5179:    */
5180:   public void addPropertyChangeListener(String propertyName,
5181:                                         PropertyChangeListener listener)
5182:   {
5183:     if (changeSupport == null)
5184:       changeSupport = new PropertyChangeSupport(this);
5185:     changeSupport.addPropertyChangeListener(propertyName, listener);
5186:   }
5187: 
5188:   /**
5189:    * Removes the specified property listener on a particular property from
5190:    * the component. This is harmless if the listener was not previously
5191:    * registered.
5192:    *
5193:    * @param propertyName the property name to filter on
5194:    * @param listener the listener to remove
5195:    * @see #addPropertyChangeListener(String, PropertyChangeListener)
5196:    * @see #getPropertyChangeListeners(String)
5197:    * @see #removePropertyChangeListener(PropertyChangeListener)
5198:    * @since 1.1
5199:    */
5200:   public void removePropertyChangeListener(String propertyName,
5201:                                            PropertyChangeListener listener)
5202:   {
5203:     if (changeSupport != null)
5204:       changeSupport.removePropertyChangeListener(propertyName, listener);
5205:   }
5206: 
5207:   /**
5208:    * Returns an array of all specified listeners on the named property that
5209:    * are registered on this component.
5210:    *
5211:    * @return an array of listeners
5212:    * @see #addPropertyChangeListener(String, PropertyChangeListener)
5213:    * @see #removePropertyChangeListener(String, PropertyChangeListener)
5214:    * @see #getPropertyChangeListeners()
5215:    * @since 1.4
5216:    */
5217:   public PropertyChangeListener[] getPropertyChangeListeners(String property)
5218:   {
5219:     return changeSupport == null ? new PropertyChangeListener[0]
5220:       : changeSupport.getPropertyChangeListeners(property);
5221:   }
5222: 
5223:   /**
5224:    * Report a change in a bound property to any registered property listeners.
5225:    *
5226:    * @param propertyName the property that changed
5227:    * @param oldValue the old property value
5228:    * @param newValue the new property value
5229:    */
5230:   protected void firePropertyChange(String propertyName, Object oldValue,
5231:                                     Object newValue)
5232:   {
5233:     if (changeSupport != null)
5234:       changeSupport.firePropertyChange(propertyName, oldValue, newValue);  
5235:   }
5236: 
5237:   /**
5238:    * Report a change in a bound property to any registered property listeners.
5239:    *
5240:    * @param propertyName the property that changed
5241:    * @param oldValue the old property value
5242:    * @param newValue the new property value
5243:    */
5244:   protected void firePropertyChange(String propertyName, boolean oldValue,
5245:                                     boolean newValue)
5246:   {
5247:     if (changeSupport != null)
5248:       changeSupport.firePropertyChange(propertyName, oldValue, newValue);
5249:   }
5250: 
5251:   /**
5252:    * Report a change in a bound property to any registered property listeners.
5253:    *
5254:    * @param propertyName the property that changed
5255:    * @param oldValue the old property value
5256:    * @param newValue the new property value
5257:    */
5258:   protected void firePropertyChange(String propertyName, int oldValue,
5259:                                     int newValue)
5260:   {
5261:     if (changeSupport != null)
5262:       changeSupport.firePropertyChange(propertyName, oldValue, newValue);
5263:   }
5264: 
5265:   /**
5266:    * Report a change in a bound property to any registered property listeners.
5267:    *
5268:    * @param propertyName the property that changed
5269:    * @param oldValue the old property value
5270:    * @param newValue the new property value
5271:    *
5272:    * @since 1.5
5273:    */
5274:   public void firePropertyChange(String propertyName, byte oldValue,
5275:                                     byte newValue)
5276:   {
5277:     if (changeSupport != null)
5278:       changeSupport.firePropertyChange(propertyName, new Byte(oldValue),
5279:                                        new Byte(newValue));
5280:   }
5281: 
5282:   /**
5283:    * Report a change in a bound property to any registered property listeners.
5284:    *
5285:    * @param propertyName the property that changed
5286:    * @param oldValue the old property value
5287:    * @param newValue the new property value
5288:    *
5289:    * @since 1.5
5290:    */
5291:   public void firePropertyChange(String propertyName, char oldValue,
5292:                                     char newValue)
5293:   {
5294:     if (changeSupport != null)
5295:       changeSupport.firePropertyChange(propertyName, new Character(oldValue),
5296:                                        new Character(newValue));
5297:   }
5298: 
5299:   /**
5300:    * Report a change in a bound property to any registered property listeners.
5301:    *
5302:    * @param propertyName the property that changed
5303:    * @param oldValue the old property value
5304:    * @param newValue the new property value
5305:    *
5306:    * @since 1.5
5307:    */
5308:   public void firePropertyChange(String propertyName, short oldValue,
5309:                                     short newValue)
5310:   {
5311:     if (changeSupport != null)
5312:       changeSupport.firePropertyChange(propertyName, new Short(oldValue),
5313:                                        new Short(newValue));
5314:   }
5315: 
5316:   /**
5317:    * Report a change in a bound property to any registered property listeners.
5318:    *
5319:    * @param propertyName the property that changed
5320:    * @param oldValue the old property value
5321:    * @param newValue the new property value
5322:    *
5323:    * @since 1.5
5324:    */
5325:   public void firePropertyChange(String propertyName, long oldValue,
5326:                                     long newValue)
5327:   {
5328:     if (changeSupport != null)
5329:       changeSupport.firePropertyChange(propertyName, new Long(oldValue),
5330:                                        new Long(newValue));
5331:   }
5332: 
5333:   /**
5334:    * Report a change in a bound property to any registered property listeners.
5335:    *
5336:    * @param propertyName the property that changed
5337:    * @param oldValue the old property value
5338:    * @param newValue the new property value
5339:    *
5340:    * @since 1.5
5341:    */
5342:   public void firePropertyChange(String propertyName, float oldValue,
5343:                                     float newValue)
5344:   {
5345:     if (changeSupport != null)
5346:       changeSupport.firePropertyChange(propertyName, new Float(oldValue),
5347:                                        new Float(newValue));
5348:   }
5349: 
5350: 
5351:   /**
5352:    * Report a change in a bound property to any registered property listeners.
5353:    *
5354:    * @param propertyName the property that changed
5355:    * @param oldValue the old property value
5356:    * @param newValue the new property value
5357:    *
5358:    * @since 1.5
5359:    */
5360:   public void firePropertyChange(String propertyName, double oldValue,
5361:                                  double newValue)
5362:   {
5363:     if (changeSupport != null)
5364:       changeSupport.firePropertyChange(propertyName, new Double(oldValue),
5365:                                        new Double(newValue));
5366:   }
5367: 
5368:   /**
5369:    * Sets the text layout orientation of this component. New components default
5370:    * to UNKNOWN (which behaves like LEFT_TO_RIGHT). This method affects only
5371:    * the current component, while
5372:    * {@link #applyComponentOrientation(ComponentOrientation)} affects the
5373:    * entire hierarchy.
5374:    *
5375:    * @param o the new orientation (<code>null</code> is accepted)
5376:    * @see #getComponentOrientation()
5377:    */
5378:   public void setComponentOrientation(ComponentOrientation o)
5379:   {
5380:  
5381:     ComponentOrientation oldOrientation = componentOrientation;
5382:     componentOrientation = o;
5383:     firePropertyChange("componentOrientation", oldOrientation, o);
5384:   }
5385: 
5386:   /**
5387:    * Determines the text layout orientation used by this component.
5388:    *
5389:    * @return the component orientation (this can be <code>null</code>)
5390:    * @see #setComponentOrientation(ComponentOrientation)
5391:    */
5392:   public ComponentOrientation getComponentOrientation()
5393:   {
5394:     return componentOrientation;
5395:   }
5396: 
5397:   /**
5398:    * Sets the text layout orientation of this component. New components default
5399:    * to UNKNOWN (which behaves like LEFT_TO_RIGHT). This method affects the
5400:    * entire hierarchy, while
5401:    * {@link #setComponentOrientation(ComponentOrientation)} affects only the
5402:    * current component.
5403:    *
5404:    * @param o the new orientation
5405:    * @throws NullPointerException if o is null
5406:    * @see #getComponentOrientation()
5407:    * @since 1.4
5408:    */
5409:   public void applyComponentOrientation(ComponentOrientation o)
5410:   {
5411:     setComponentOrientation(o);
5412:   }
5413: 
5414:   /**
5415:    * Returns the accessibility framework context of this class. Component is
5416:    * not accessible, so the default implementation returns null. Subclasses
5417:    * must override this behavior, and return an appropriate subclass of
5418:    * {@link AccessibleAWTComponent}.
5419:    *
5420:    * @return the accessibility context
5421:    */
5422:   public AccessibleContext getAccessibleContext()
5423:   {
5424:     return null;
5425:   }
5426: 
5427: 
5428:   // Helper methods; some are package visible for use by subclasses.
5429: 
5430:   /**
5431:    * Subclasses should override this to return unique component names like
5432:    * "menuitem0".
5433:    *
5434:    * @return the generated name for this component
5435:    */
5436:   String generateName()
5437:   {
5438:     // Component is abstract.
5439:     return null;
5440:   }
5441: 
5442:   /**
5443:    * Sets the peer for this component.
5444:    *
5445:    * @param peer the new peer
5446:    */
5447:   final void setPeer(ComponentPeer peer)
5448:   {
5449:     this.peer = peer;
5450:   }
5451: 
5452:   /**
5453:    * Translate an AWT 1.1 event ({@link AWTEvent}) into an AWT 1.0
5454:    * event ({@link Event}).
5455:    *
5456:    * @param e an AWT 1.1 event to translate
5457:    *
5458:    * @return an AWT 1.0 event representing e
5459:    */
5460:   static Event translateEvent (AWTEvent e)
5461:   {
5462:     Object target = e.getSource ();
5463:     Event translated = null;
5464:     
5465:     if (e instanceof WindowEvent)
5466:       {
5467:         WindowEvent we = (WindowEvent) e;
5468:         int id = we.id;
5469:         int newId = 0;
5470:         
5471:         switch (id)
5472:           {
5473:           case WindowEvent.WINDOW_DEICONIFIED:
5474:             newId = Event.WINDOW_DEICONIFY;
5475:             break;
5476:           case WindowEvent.WINDOW_CLOSED:
5477:           case WindowEvent.WINDOW_CLOSING:
5478:             newId = Event.WINDOW_DESTROY;
5479:             break;
5480:           case WindowEvent.WINDOW_ICONIFIED:
5481:             newId = Event.WINDOW_ICONIFY;
5482:             break;
5483:           case WindowEvent.WINDOW_GAINED_FOCUS:
5484:             newId = Event.GOT_FOCUS;
5485:             break;
5486:           case WindowEvent.WINDOW_LOST_FOCUS:
5487:             newId = Event.LOST_FOCUS;
5488:             break;
5489:           default:
5490:             return null;
5491:           }
5492: 
5493:         translated = new Event(target, 0, newId, 0, 0, 0, 0);
5494:       }
5495:     else if (e instanceof InputEvent)
5496:       {
5497:         InputEvent ie = (InputEvent) e;
5498:         long when = ie.getWhen ();
5499: 
5500:         int oldID = 0;
5501:         int id = e.getID ();
5502: 
5503:         int oldMods = 0;
5504:         int mods = ie.getModifiersEx ();
5505: 
5506:         if ((mods & InputEvent.BUTTON2_DOWN_MASK) != 0)
5507:           oldMods |= Event.META_MASK;
5508:         else if ((mods & InputEvent.BUTTON3_DOWN_MASK) != 0)
5509:           oldMods |= Event.ALT_MASK;
5510: 
5511:         if ((mods & InputEvent.SHIFT_DOWN_MASK) != 0)
5512:           oldMods |= Event.SHIFT_MASK;
5513: 
5514:         if ((mods & InputEvent.CTRL_DOWN_MASK) != 0)
5515:           oldMods |= Event.CTRL_MASK;
5516: 
5517:         if ((mods & InputEvent.META_DOWN_MASK) != 0)
5518:           oldMods |= Event.META_MASK;
5519: 
5520:         if ((mods & InputEvent.ALT_DOWN_MASK) != 0)
5521:           oldMods |= Event.ALT_MASK;
5522: 
5523:         if (e instanceof MouseEvent && !ignoreOldMouseEvents())
5524:           {
5525:             if (id == MouseEvent.MOUSE_PRESSED)
5526:               oldID = Event.MOUSE_DOWN;
5527:             else if (id == MouseEvent.MOUSE_RELEASED)
5528:               oldID = Event.MOUSE_UP;
5529:             else if (id == MouseEvent.MOUSE_MOVED)
5530:               oldID = Event.MOUSE_MOVE;
5531:             else if (id == MouseEvent.MOUSE_DRAGGED)
5532:               oldID = Event.MOUSE_DRAG;
5533:             else if (id == MouseEvent.MOUSE_ENTERED)
5534:               oldID = Event.MOUSE_ENTER;
5535:             else if (id == MouseEvent.MOUSE_EXITED)
5536:               oldID = Event.MOUSE_EXIT;
5537:             else
5538:               // No analogous AWT 1.0 mouse event.
5539:               return null;
5540: 
5541:             MouseEvent me = (MouseEvent) e;
5542: 
5543:             translated = new Event (target, when, oldID,
5544:                                     me.getX (), me.getY (), 0, oldMods);
5545:           }
5546:         else if (e instanceof KeyEvent)
5547:           {
5548:             if (id == KeyEvent.KEY_PRESSED)
5549:               oldID = Event.KEY_PRESS;
5550:             else if (e.getID () == KeyEvent.KEY_RELEASED)
5551:               oldID = Event.KEY_RELEASE;
5552:             else
5553:               // No analogous AWT 1.0 key event.
5554:               return null;
5555: 
5556:             int oldKey = 0;
5557:             int newKey = ((KeyEvent) e).getKeyCode ();
5558:             switch (newKey)
5559:               {
5560:               case KeyEvent.VK_BACK_SPACE:
5561:                 oldKey = Event.BACK_SPACE;
5562:                 break;
5563:               case KeyEvent.VK_CAPS_LOCK:
5564:                 oldKey = Event.CAPS_LOCK;
5565:                 break;
5566:               case KeyEvent.VK_DELETE:
5567:                 oldKey = Event.DELETE;
5568:                 break;
5569:               case KeyEvent.VK_DOWN:
5570:               case KeyEvent.VK_KP_DOWN:
5571:                 oldKey = Event.DOWN;
5572:                 break;
5573:               case KeyEvent.VK_END:
5574:                 oldKey = Event.END;
5575:                 break;
5576:               case KeyEvent.VK_ENTER:
5577:                 oldKey = Event.ENTER;
5578:                 break;
5579:               case KeyEvent.VK_ESCAPE:
5580:                 oldKey = Event.ESCAPE;
5581:                 break;
5582:               case KeyEvent.VK_F1:
5583:                 oldKey = Event.F1;
5584:                 break;
5585:               case KeyEvent.VK_F10:
5586:                 oldKey = Event.F10;
5587:                 break;
5588:               case KeyEvent.VK_F11:
5589:                 oldKey = Event.F11;
5590:                 break;
5591:               case KeyEvent.VK_F12:
5592:                 oldKey = Event.F12;
5593:                 break;
5594:               case KeyEvent.VK_F2:
5595:                 oldKey = Event.F2;
5596:                 break;
5597:               case KeyEvent.VK_F3:
5598:                 oldKey = Event.F3;
5599:                 break;
5600:               case KeyEvent.VK_F4:
5601:                 oldKey = Event.F4;
5602:                 break;
5603:               case KeyEvent.VK_F5:
5604:                 oldKey = Event.F5;
5605:                 break;
5606:               case KeyEvent.VK_F6:
5607:                 oldKey = Event.F6;
5608:                 break;
5609:               case KeyEvent.VK_F7:
5610:                 oldKey = Event.F7;
5611:                 break;
5612:               case KeyEvent.VK_F8:
5613:                 oldKey = Event.F8;
5614:                 break;
5615:               case KeyEvent.VK_F9:
5616:                 oldKey = Event.F9;
5617:                 break;
5618:               case KeyEvent.VK_HOME:
5619:                 oldKey = Event.HOME;
5620:                 break;
5621:               case KeyEvent.VK_INSERT:
5622:                 oldKey = Event.INSERT;
5623:                 break;
5624:               case KeyEvent.VK_LEFT:
5625:               case KeyEvent.VK_KP_LEFT:
5626:                 oldKey = Event.LEFT;
5627:                 break;
5628:               case KeyEvent.VK_NUM_LOCK:
5629:                 oldKey = Event.NUM_LOCK;
5630:                 break;
5631:               case KeyEvent.VK_PAUSE:
5632:                 oldKey = Event.PAUSE;
5633:                 break;
5634:               case KeyEvent.VK_PAGE_DOWN:
5635:                 oldKey = Event.PGDN;
5636:                 break;
5637:               case KeyEvent.VK_PAGE_UP:
5638:                 oldKey = Event.PGUP;
5639:                 break;
5640:               case KeyEvent.VK_PRINTSCREEN:
5641:                 oldKey = Event.PRINT_SCREEN;
5642:                 break;
5643:               case KeyEvent.VK_RIGHT:
5644:               case KeyEvent.VK_KP_RIGHT:
5645:                 oldKey = Event.RIGHT;
5646:                 break;
5647:               case KeyEvent.VK_SCROLL_LOCK:
5648:                 oldKey = Event.SCROLL_LOCK;
5649:                 break;
5650:               case KeyEvent.VK_TAB:
5651:                 oldKey = Event.TAB;
5652:                 break;
5653:               case KeyEvent.VK_UP:
5654:               case KeyEvent.VK_KP_UP:
5655:                 oldKey = Event.UP;
5656:                 break;
5657:               default:
5658:                 oldKey = ((KeyEvent) e).getKeyChar();
5659:               }
5660: 
5661:             translated = new Event (target, when, oldID,
5662:                                     0, 0, oldKey, oldMods);
5663:           }
5664:       }
5665:     else if (e instanceof AdjustmentEvent)
5666:       {
5667:     AdjustmentEvent ae = (AdjustmentEvent) e;
5668:     int type = ae.getAdjustmentType();
5669:     int oldType;
5670:     if (type == AdjustmentEvent.BLOCK_DECREMENT)
5671:       oldType = Event.SCROLL_PAGE_UP;
5672:     else if (type == AdjustmentEvent.BLOCK_INCREMENT)
5673:       oldType = Event.SCROLL_PAGE_DOWN;
5674:     else if (type == AdjustmentEvent.TRACK)
5675:       oldType = Event.SCROLL_ABSOLUTE;
5676:     else if (type == AdjustmentEvent.UNIT_DECREMENT)
5677:       oldType = Event.SCROLL_LINE_UP;
5678:     else if (type == AdjustmentEvent.UNIT_INCREMENT)
5679:       oldType = Event.SCROLL_LINE_DOWN;
5680:     else
5681:       oldType = type;
5682:     translated = new Event(target, oldType, new Integer(ae.getValue()));
5683:       }
5684:     else if (e instanceof ActionEvent)
5685:       translated = new Event (target, Event.ACTION_EVENT,
5686:                               ((ActionEvent) e).getActionCommand ());
5687: 
5688:     return translated;
5689:   }
5690: 
5691:   /**
5692:    * Implementation of dispatchEvent. Allows trusted package classes
5693:    * to dispatch additional events first.  This implementation first
5694:    * translates <code>e</code> to an AWT 1.0 event and sends the
5695:    * result to {@link #postEvent}.  If the AWT 1.0 event is not
5696:    * handled, and events of type <code>e</code> are enabled for this
5697:    * component, e is passed on to {@link #processEvent}.
5698:    *
5699:    * @param e the event to dispatch
5700:    */
5701:   void dispatchEventImpl(AWTEvent e)
5702:   {
5703:     // Update the component's knowledge about the size.
5704:     // Important: Please look at the big comment in ComponentReshapeEvent
5705:     // to learn why we did it this way. If you change this code, make
5706:     // sure that the peer->AWT bounds update still works.
5707:     // (for instance: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29448 )
5708:     if (e instanceof ComponentReshapeEvent)
5709:       {
5710:         ComponentReshapeEvent reshape = (ComponentReshapeEvent) e;
5711:         x = reshape.x;
5712:         y = reshape.y;
5713:         width = reshape.width;
5714:         height = reshape.height;
5715:         return;
5716:       }
5717: 
5718:     // Retarget focus events before dispatching it to the KeyboardFocusManager
5719:     // in order to handle lightweight components properly.
5720:     boolean dispatched = false;
5721:     if (! e.isFocusManagerEvent)
5722:       {
5723:         e = KeyboardFocusManager.retargetFocusEvent(e);
5724:         dispatched = KeyboardFocusManager.getCurrentKeyboardFocusManager()
5725:                                           .dispatchEvent(e);
5726:       }
5727: 
5728:     if (! dispatched)
5729:       {
5730:         // Give toolkit a chance to dispatch the event
5731:         // to globally registered listeners.
5732:         Toolkit.getDefaultToolkit().globalDispatchEvent(e);
5733: 
5734:         if (newEventsOnly)
5735:           {
5736:             if (eventTypeEnabled(e.id))
5737:               processEvent(e);
5738:           }
5739:         else
5740:           {
5741:             Event oldEvent = translateEvent(e);
5742:             if (oldEvent != null)
5743:               postEvent (oldEvent);
5744:           }
5745:         if (peer != null)
5746:           peer.handleEvent(e);
5747:       }
5748:   }
5749: 
5750:   /**
5751:    * Tells whether or not an event type is enabled.
5752:    */
5753:   boolean eventTypeEnabled (int type)
5754:   {
5755:     if (type > AWTEvent.RESERVED_ID_MAX)
5756:       return true;
5757: 
5758:     switch (type)
5759:       {
5760:       case HierarchyEvent.HIERARCHY_CHANGED:
5761:         return (hierarchyListener != null 
5762:             || (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0);
5763:         
5764:       case HierarchyEvent.ANCESTOR_MOVED:
5765:       case HierarchyEvent.ANCESTOR_RESIZED:
5766:         return (hierarchyBoundsListener != null 
5767:             || (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0);
5768:         
5769:       case ComponentEvent.COMPONENT_HIDDEN:
5770:       case ComponentEvent.COMPONENT_MOVED:
5771:       case ComponentEvent.COMPONENT_RESIZED:
5772:       case ComponentEvent.COMPONENT_SHOWN:
5773:         return (componentListener != null
5774:                 || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0);
5775: 
5776:       case KeyEvent.KEY_PRESSED:
5777:       case KeyEvent.KEY_RELEASED:
5778:       case KeyEvent.KEY_TYPED:
5779:         return (keyListener != null
5780:                 || (eventMask & AWTEvent.KEY_EVENT_MASK) != 0);
5781: 
5782:       case MouseEvent.MOUSE_CLICKED:
5783:       case MouseEvent.MOUSE_ENTERED:
5784:       case MouseEvent.MOUSE_EXITED:
5785:       case MouseEvent.MOUSE_PRESSED:
5786:       case MouseEvent.MOUSE_RELEASED:
5787:         return (mouseListener != null
5788:                 || (eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0);
5789:       case MouseEvent.MOUSE_MOVED:
5790:       case MouseEvent.MOUSE_DRAGGED:
5791:         return (mouseMotionListener != null
5792:                 || (eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0);
5793:       case MouseEvent.MOUSE_WHEEL:
5794:         return (mouseWheelListener != null
5795:                 || (eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0);
5796:         
5797:       case FocusEvent.FOCUS_GAINED:
5798:       case FocusEvent.FOCUS_LOST:
5799:         return (focusListener != null
5800:                 || (eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0);
5801: 
5802:       case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
5803:       case InputMethodEvent.CARET_POSITION_CHANGED:
5804:         return (inputMethodListener != null
5805:                 || (eventMask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0);
5806:         
5807:       case PaintEvent.PAINT:
5808:       case PaintEvent.UPDATE:
5809:         return (eventMask & AWTEvent.PAINT_EVENT_MASK) != 0;
5810:         
5811:       default:
5812:         return false;
5813:       }
5814:   }
5815: 
5816:   /**
5817:    * Returns <code>true</code> when this component and all of its ancestors
5818:    * are visible, <code>false</code> otherwise.
5819:    *
5820:    * @return <code>true</code> when this component and all of its ancestors
5821:    *         are visible, <code>false</code> otherwise
5822:    */
5823:   boolean isHierarchyVisible()
5824:   {
5825:     boolean visible = isVisible();
5826:     Component comp = parent;
5827:     while (comp != null && visible)
5828:       {
5829:         comp = comp.parent;
5830:         if (comp != null)
5831:           visible = visible && comp.isVisible();
5832:       }
5833:     return visible;
5834:   }
5835: 
5836:   /**
5837:    * This method is used to implement transferFocus(). CHILD is the child
5838:    * making the request. This is overridden by Container; when called for an
5839:    * ordinary component there is no child and so we always return null.
5840:    *
5841:    * FIXME: is this still needed, in light of focus traversal policies?
5842:    *
5843:    * @param child the component making the request
5844:    * @return the next component to focus on
5845:    */
5846:   Component findNextFocusComponent(Component child)
5847:   {
5848:     return null;
5849:   }
5850: 
5851:   /**
5852:    * Deserializes this component. This regenerates all serializable listeners
5853:    * which were registered originally.
5854:    *
5855:    * @param s the stream to read from
5856:    * @throws ClassNotFoundException if deserialization fails
5857:    * @throws IOException if the stream fails
5858:    */
5859:   private void readObject(ObjectInputStream s)
5860:     throws ClassNotFoundException, IOException
5861:   {
5862:     s.defaultReadObject();
5863:     String key = (String) s.readObject();
5864:     while (key != null)
5865:       {
5866:         Object listener = s.readObject();
5867:         if ("componentL".equals(key))
5868:           addComponentListener((ComponentListener) listener);
5869:         else if ("focusL".equals(key))
5870:           addFocusListener((FocusListener) listener);
5871:         else if ("keyL".equals(key))
5872:           addKeyListener((KeyListener) listener);
5873:         else if ("mouseL".equals(key))
5874:           addMouseListener((MouseListener) listener);
5875:         else if ("mouseMotionL".equals(key))
5876:           addMouseMotionListener((MouseMotionListener) listener);
5877:         else if ("inputMethodL".equals(key))
5878:           addInputMethodListener((InputMethodListener) listener);
5879:         else if ("hierarchyL".equals(key))
5880:           addHierarchyListener((HierarchyListener) listener);
5881:         else if ("hierarchyBoundsL".equals(key))
5882:           addHierarchyBoundsListener((HierarchyBoundsListener) listener);
5883:         else if ("mouseWheelL".equals(key))
5884:           addMouseWheelListener((MouseWheelListener) listener);
5885:         key = (String) s.readObject();
5886:       }
5887:   }
5888: 
5889:   /**
5890:    * Serializes this component. This ignores all listeners which do not
5891:    * implement Serializable, but includes those that do.
5892:    *
5893:    * @param s the stream to write to
5894:    * @throws IOException if the stream fails
5895:    */
5896:   private void writeObject(ObjectOutputStream s) throws IOException
5897:   {
5898:     s.defaultWriteObject();
5899:     AWTEventMulticaster.save(s, "componentL", componentListener);
5900:     AWTEventMulticaster.save(s, "focusL", focusListener);
5901:     AWTEventMulticaster.save(s, "keyL", keyListener);
5902:     AWTEventMulticaster.save(s, "mouseL", mouseListener);
5903:     AWTEventMulticaster.save(s, "mouseMotionL", mouseMotionListener);
5904:     AWTEventMulticaster.save(s, "inputMethodL", inputMethodListener);
5905:     AWTEventMulticaster.save(s, "hierarchyL", hierarchyListener);
5906:     AWTEventMulticaster.save(s, "hierarchyBoundsL", hierarchyBoundsListener);
5907:     AWTEventMulticaster.save(s, "mouseWheelL", mouseWheelListener);
5908:     s.writeObject(null);
5909:   }
5910: 
5911:   
5912:   // Nested classes.
5913:   
5914:   /**
5915:    * This class fixes the bounds for a Heavyweight component that
5916:    * is placed inside a Lightweight container. When the lightweight is
5917:    * moved or resized, setBounds for the lightweight peer does nothing.
5918:    * Therefore, it was never moved on the screen. This class is 
5919:    * attached to the lightweight, and it adjusts the position and size
5920:    * of the peer when notified.
5921:    * This is the same for show and hide.
5922:    */
5923:   class HeavyweightInLightweightListener
5924:       implements ComponentListener
5925:   {
5926:     
5927:     /**
5928:      * Constructor. Adds component listener to lightweight parent.
5929:      * 
5930:      * @param parent - the lightweight container.
5931:      */
5932:     public HeavyweightInLightweightListener(Container parent)
5933:     {
5934:       parent.addComponentListener(this);
5935:     }
5936:     
5937:     /**
5938:      * This method is called when the component is resized.
5939:      * 
5940:      * @param event the <code>ComponentEvent</code> indicating the resize
5941:      */
5942:     public void componentResized(ComponentEvent event)
5943:     {
5944:       // Nothing to do here, componentMoved will be called.
5945:     }
5946: 
5947:     /**
5948:      * This method is called when the component is moved.
5949:      * 
5950:      * @param event the <code>ComponentEvent</code> indicating the move
5951:      */
5952:     public void componentMoved(ComponentEvent event)
5953:     {
5954:       if (peer != null)
5955:         peer.setBounds(x, y, width, height);
5956:     }
5957: 
5958:     /**
5959:      * This method is called when the component is made visible.
5960:      * 
5961:      * @param event the <code>ComponentEvent</code> indicating the visibility
5962:      */
5963:     public void componentShown(ComponentEvent event)
5964:     {
5965:       if (isShowing())
5966:         peer.show();
5967:     }
5968: 
5969:     /**
5970:      * This method is called when the component is hidden.
5971:      * 
5972:      * @param event the <code>ComponentEvent</code> indicating the visibility
5973:      */
5974:     public void componentHidden(ComponentEvent event)
5975:     {
5976:       if (isShowing())
5977:         peer.hide();
5978:     }
5979:   }
5980:   
5981:   /**
5982:    * This class provides accessibility support for subclasses of container.
5983:    *
5984:    * @author Eric Blake (ebb9@email.byu.edu)
5985:    * @since 1.3
5986:    * @status updated to 1.4
5987:    */
5988:   protected abstract class AccessibleAWTComponent extends AccessibleContext
5989:     implements Serializable, AccessibleComponent
5990:   {
5991:     /**
5992:      * Compatible with JDK 1.3+.
5993:      */
5994:     private static final long serialVersionUID = 642321655757800191L;
5995: 
5996:     /**
5997:      * Converts show/hide events to PropertyChange events, and is registered
5998:      * as a component listener on this component.
5999:      *
6000:      * @serial the component handler
6001:      */
6002:     protected ComponentListener accessibleAWTComponentHandler
6003:       = new AccessibleAWTComponentHandler();
6004: 
6005:     /**
6006:      * Converts focus events to PropertyChange events, and is registered
6007:      * as a focus listener on this component.
6008:      *
6009:      * @serial the focus handler
6010:      */
6011:     protected FocusListener accessibleAWTFocusHandler
6012:       = new AccessibleAWTFocusHandler();
6013: 
6014:     /**
6015:      * The default constructor.
6016:      */
6017:     protected AccessibleAWTComponent()
6018:     {
6019:       Component.this.addComponentListener(accessibleAWTComponentHandler);
6020:       Component.this.addFocusListener(accessibleAWTFocusHandler);
6021:     }
6022: 
6023:     /**
6024:      * Adds a global property change listener to the accessible component.
6025:      *
6026:      * @param l the listener to add
6027:      * @see #ACCESSIBLE_NAME_PROPERTY
6028:      * @see #ACCESSIBLE_DESCRIPTION_PROPERTY
6029:      * @see #ACCESSIBLE_STATE_PROPERTY
6030:      * @see #ACCESSIBLE_VALUE_PROPERTY
6031:      * @see #ACCESSIBLE_SELECTION_PROPERTY
6032:      * @see #ACCESSIBLE_TEXT_PROPERTY
6033:      * @see #ACCESSIBLE_VISIBLE_DATA_PROPERTY
6034:      */
6035:     public void addPropertyChangeListener(PropertyChangeListener l)
6036:     {
6037:       Component.this.addPropertyChangeListener(l);
6038:       super.addPropertyChangeListener(l);
6039:     }
6040: 
6041:     /**
6042:      * Removes a global property change listener from this accessible
6043:      * component.
6044:      *
6045:      * @param l the listener to remove
6046:      */
6047:     public void removePropertyChangeListener(PropertyChangeListener l)
6048:     {
6049:       Component.this.removePropertyChangeListener(l);
6050:       super.removePropertyChangeListener(l);
6051:     }
6052: 
6053:     /**
6054:      * Returns the accessible name of this component. It is almost always
6055:      * wrong to return getName(), since it is not localized. In fact, for
6056:      * things like buttons, this should be the text of the button, not the
6057:      * name of the object. The tooltip text might also be appropriate.
6058:      *
6059:      * @return the name
6060:      * @see #setAccessibleName(String)
6061:      */
6062:     public String getAccessibleName()
6063:     {
6064:       return accessibleName;
6065:     }
6066: 
6067:     /**
6068:      * Returns a brief description of this accessible context. This should
6069:      * be localized.
6070:      *
6071:      * @return a description of this component
6072:      * @see #setAccessibleDescription(String)
6073:      */
6074:     public String getAccessibleDescription()
6075:     {
6076:       return accessibleDescription;
6077:     }
6078: 
6079:     /**
6080:      * Returns the role of this component.
6081:      *
6082:      * @return the accessible role
6083:      */
6084:     public AccessibleRole getAccessibleRole()
6085:     {
6086:       return AccessibleRole.AWT_COMPONENT;
6087:     }
6088: 
6089:     /**
6090:      * Returns a state set describing this component's state.
6091:      *
6092:      * @return a new state set
6093:      * @see AccessibleState
6094:      */
6095:     public AccessibleStateSet getAccessibleStateSet()
6096:     {
6097:       AccessibleStateSet s = new AccessibleStateSet();
6098:       if (Component.this.isEnabled())
6099:         s.add(AccessibleState.ENABLED);
6100:       if (isFocusable())
6101:         s.add(AccessibleState.FOCUSABLE);
6102:       if (isFocusOwner())
6103:         s.add(AccessibleState.FOCUSED);
6104:       // Note: While the java.awt.Component has an 'opaque' property, it
6105:       // seems that it is not added to the accessible state set here, even
6106:       // if this property is true. However, it is handled for
6107:       // javax.swing.JComponent, so we add it there.
6108:       if (Component.this.isShowing())
6109:         s.add(AccessibleState.SHOWING);
6110:       if (Component.this.isVisible())
6111:         s.add(AccessibleState.VISIBLE);
6112:       return s;
6113:     }
6114: 
6115:     /**
6116:      * Returns the parent of this component, if it is accessible.
6117:      *
6118:      * @return the accessible parent
6119:      */
6120:     public Accessible getAccessibleParent()
6121:     {
6122:       if (accessibleParent == null)
6123:         {
6124:           Container parent = getParent();
6125:           accessibleParent = parent instanceof Accessible
6126:             ? (Accessible) parent : null;
6127:         }
6128:       return accessibleParent;
6129:     }
6130: 
6131:     /**
6132:      * Returns the index of this component in its accessible parent.
6133:      *
6134:      * @return the index, or -1 if the parent is not accessible
6135:      * @see #getAccessibleParent()
6136:      */
6137:     public int getAccessibleIndexInParent()
6138:     {
6139:       if (getAccessibleParent() == null)
6140:         return -1;
6141:       AccessibleContext context
6142:         = ((Component) accessibleParent).getAccessibleContext();
6143:       if (context == null)
6144:         return -1;
6145:       for (int i = context.getAccessibleChildrenCount(); --i >= 0; )
6146:         if (context.getAccessibleChild(i) == Component.this)
6147:           return i;
6148:       return -1;
6149:     }
6150: 
6151:     /**
6152:      * Returns the number of children of this component which implement
6153:      * Accessible. Subclasses must override this if they can have children.
6154:      *
6155:      * @return the number of accessible children, default 0
6156:      */
6157:     public int getAccessibleChildrenCount()
6158:     {
6159:       return 0;
6160:     }
6161: 
6162:     /**
6163:      * Returns the ith accessible child. Subclasses must override this if
6164:      * they can have children.
6165:      *
6166:      * @return the ith accessible child, or null
6167:      * @see #getAccessibleChildrenCount()
6168:      */
6169:     public Accessible getAccessibleChild(int i)
6170:     {
6171:       return null;
6172:     }
6173: 
6174:     /**
6175:      * Returns the locale of this component.
6176:      *
6177:      * @return the locale
6178:      * @throws IllegalComponentStateException if the locale is unknown
6179:      */
6180:     public Locale getLocale()
6181:     {
6182:       return Component.this.getLocale();
6183:     }
6184: 
6185:     /**
6186:      * Returns this, since it is an accessible component.
6187:      *
6188:      * @return the accessible component
6189:      */
6190:     public AccessibleComponent getAccessibleComponent()
6191:     {
6192:       return this;
6193:     }
6194: 
6195:     /**
6196:      * Gets the background color.
6197:      *
6198:      * @return the background color
6199:      * @see #setBackground(Color)
6200:      */
6201:     public Color getBackground()
6202:     {
6203:       return Component.this.getBackground();
6204:     }
6205: 
6206:     /**
6207:      * Sets the background color.
6208:      *
6209:      * @param c the background color
6210:      * @see #getBackground()
6211:      * @see #isOpaque()
6212:      */
6213:     public void setBackground(Color c)
6214:     {
6215:       Component.this.setBackground(c);
6216:     }
6217: 
6218:     /**
6219:      * Gets the foreground color.
6220:      *
6221:      * @return the foreground color
6222:      * @see #setForeground(Color)
6223:      */
6224:     public Color getForeground()
6225:     {
6226:       return Component.this.getForeground();
6227:     }
6228: 
6229:     /**
6230:      * Sets the foreground color.
6231:      *
6232:      * @param c the foreground color
6233:      * @see #getForeground()
6234:      */
6235:     public void setForeground(Color c)
6236:     {
6237:       Component.this.setForeground(c);
6238:     }
6239: 
6240:     /**
6241:      * Gets the cursor.
6242:      *
6243:      * @return the cursor
6244:      * @see #setCursor(Cursor)
6245:      */
6246:     public Cursor getCursor()
6247:     {
6248:       return Component.this.getCursor();
6249:     }
6250: 
6251:     /**
6252:      * Sets the cursor.
6253:      *
6254:      * @param cursor the cursor
6255:      * @see #getCursor()
6256:      */
6257:     public void setCursor(Cursor cursor)
6258:     {
6259:       Component.this.setCursor(cursor);
6260:     }
6261: 
6262:     /**
6263:      * Gets the font.
6264:      *
6265:      * @return the font
6266:      * @see #setFont(Font)
6267:      */
6268:     public Font getFont()
6269:     {
6270:       return Component.this.getFont();
6271:     }
6272: 
6273:     /**
6274:      * Sets the font.
6275:      *
6276:      * @param f the font
6277:      * @see #getFont()
6278:      */
6279:     public void setFont(Font f)
6280:     {
6281:       Component.this.setFont(f);
6282:     }
6283: 
6284:     /**
6285:      * Gets the font metrics for a font.
6286:      *
6287:      * @param f the font to look up
6288:      * @return its metrics
6289:      * @throws NullPointerException if f is null
6290:      * @see #getFont()
6291:      */
6292:     public FontMetrics getFontMetrics(Font f)
6293:     {
6294:       return Component.this.getFontMetrics(f);
6295:     }
6296: 
6297:     /**
6298:      * Tests if the component is enabled.
6299:      *
6300:      * @return true if the component is enabled
6301:      * @see #setEnabled(boolean)
6302:      * @see #getAccessibleStateSet()
6303:      * @see AccessibleState#ENABLED
6304:      */
6305:     public boolean isEnabled()
6306:     {
6307:       return Component.this.isEnabled();
6308:     }
6309: 
6310:     /**
6311:      * Set whether the component is enabled.
6312:      *
6313:      * @param b the new enabled status
6314:      * @see #isEnabled()
6315:      */
6316:     public void setEnabled(boolean b)
6317:     {
6318:       Component.this.setEnabled(b);
6319:     }
6320: 
6321:     /**
6322:      * Test whether the component is visible (not necesarily showing).
6323:      *
6324:      * @return true if it is visible
6325:      * @see #setVisible(boolean)
6326:      * @see #getAccessibleStateSet()
6327:      * @see AccessibleState#VISIBLE
6328:      */
6329:     public boolean isVisible()
6330:     {
6331:       return Component.this.isVisible();
6332:     }
6333: 
6334:     /**
6335:      * Sets the visibility of this component.
6336:      *
6337:      * @param b the desired visibility
6338:      * @see #isVisible()
6339:      */
6340:     public void setVisible(boolean b)
6341:     {
6342:       Component.this.setVisible(b);
6343:     }
6344: 
6345:     /**
6346:      * Tests if the component is showing.
6347:      *
6348:      * @return true if this is showing
6349:      */
6350:     public boolean isShowing()
6351:     {
6352:       return Component.this.isShowing();
6353:     }
6354: 
6355:     /**
6356:      * Tests if the point is contained in this component.
6357:      *
6358:      * @param p the point to check
6359:      * @return true if it is contained
6360:      * @throws NullPointerException if p is null
6361:      */
6362:     public boolean contains(Point p)
6363:     {
6364:       return Component.this.contains(p.x, p.y);
6365:     }
6366: 
6367:     /**
6368:      * Returns the location of this object on the screen, or null if it is
6369:      * not showing.
6370:      *
6371:      * @return the location relative to screen coordinates, if showing
6372:      * @see #getBounds()
6373:      * @see #getLocation()
6374:      */
6375:     public Point getLocationOnScreen()
6376:     {
6377:       return Component.this.isShowing() ? Component.this.getLocationOnScreen()
6378:         : null;
6379:     }
6380: 
6381:     /**
6382:      * Returns the location of this object relative to its parent's coordinate
6383:      * system, or null if it is not showing.
6384:      *
6385:      * @return the location
6386:      * @see #getBounds()
6387:      * @see #getLocationOnScreen()
6388:      */
6389:     public Point getLocation()
6390:     {
6391:       return Component.this.getLocation();
6392:     }
6393: 
6394:     /**
6395:      * Sets the location of this relative to its parent's coordinate system.
6396:      *
6397:      * @param p the location
6398:      * @throws NullPointerException if p is null
6399:      * @see #getLocation()
6400:      */
6401:     public void setLocation(Point p)
6402:     {
6403:       Component.this.setLocation(p.x, p.y);
6404:     }
6405: 
6406:     /**
6407:      * Gets the bounds of this component, or null if it is not on screen.
6408:      *
6409:      * @return the bounds
6410:      * @see #contains(Point)
6411:      * @see #setBounds(Rectangle)
6412:      */
6413:     public Rectangle getBounds()
6414:     {
6415:       return Component.this.getBounds();
6416:     }
6417: 
6418:     /**
6419:      * Sets the bounds of this component.
6420:      *
6421:      * @param r the bounds
6422:      * @throws NullPointerException if r is null
6423:      * @see #getBounds()
6424:      */
6425:     public void setBounds(Rectangle r)
6426:     {
6427:       Component.this.setBounds(r.x, r.y, r.width, r.height);
6428:     }
6429: 
6430:     /**
6431:      * Gets the size of this component, or null if it is not showing.
6432:      *
6433:      * @return the size
6434:      * @see #setSize(Dimension)
6435:      */
6436:     public Dimension getSize()
6437:     {
6438:       return Component.this.getSize();
6439:     }
6440: 
6441:     /**
6442:      * Sets the size of this component.
6443:      *
6444:      * @param d the size
6445:      * @throws NullPointerException if d is null
6446:      * @see #getSize()
6447:      */
6448:     public void setSize(Dimension d)
6449:     {
6450:       Component.this.setSize(d.width, d.height);
6451:     }
6452: 
6453:     /**
6454:      * Returns the Accessible child at a point relative to the coordinate
6455:      * system of this component, if one exists, or null. Since components
6456:      * have no children, subclasses must override this to get anything besides
6457:      * null.
6458:      *
6459:      * @param p the point to check
6460:      * @return the accessible child at that point
6461:      * @throws NullPointerException if p is null
6462:      */
6463:     public Accessible getAccessibleAt(Point p)
6464:     {
6465:       return null;
6466:     }
6467: 
6468:     /**
6469:      * Tests whether this component can accept focus.
6470:      *
6471:      * @return true if this is focus traversable
6472:      * @see #getAccessibleStateSet ()
6473:      * @see AccessibleState#FOCUSABLE
6474:      * @see AccessibleState#FOCUSED
6475:      */
6476:     public boolean isFocusTraversable ()
6477:     {
6478:       return Component.this.isFocusTraversable ();
6479:     }
6480: 
6481:     /**
6482:      * Requests focus for this component.
6483:      *
6484:      * @see #isFocusTraversable ()
6485:      */
6486:     public void requestFocus ()
6487:     {
6488:       Component.this.requestFocus ();
6489:     }
6490: 
6491:     /**
6492:      * Adds a focus listener.
6493:      *
6494:      * @param l the listener to add
6495:      */
6496:     public void addFocusListener(FocusListener l)
6497:     {
6498:       Component.this.addFocusListener(l);
6499:     }
6500: 
6501:     /**
6502:      * Removes a focus listener.
6503:      *
6504:      * @param l the listener to remove
6505:      */
6506:     public void removeFocusListener(FocusListener l)
6507:     {
6508:       Component.this.removeFocusListener(l);
6509:     }
6510: 
6511:     /**
6512:      * Converts component changes into property changes.
6513:      *
6514:      * @author Eric Blake (ebb9@email.byu.edu)
6515:      * @since 1.3
6516:      * @status updated to 1.4
6517:      */
6518:     protected class AccessibleAWTComponentHandler implements ComponentListener
6519:     {
6520:       /**
6521:        * Default constructor.
6522:        */
6523:       protected AccessibleAWTComponentHandler()
6524:       {
6525:         // Nothing to do here.
6526:       }
6527: 
6528:       /**
6529:        * Convert a component hidden to a property change.
6530:        *
6531:        * @param e the event to convert
6532:        */
6533:       public void componentHidden(ComponentEvent e)
6534:       {
6535:         AccessibleAWTComponent.this.firePropertyChange
6536:           (ACCESSIBLE_STATE_PROPERTY, AccessibleState.VISIBLE, null);
6537:       }
6538: 
6539:       /**
6540:        * Convert a component shown to a property change.
6541:        *
6542:        * @param e the event to convert
6543:        */
6544:       public void componentShown(ComponentEvent e)
6545:       {
6546:         AccessibleAWTComponent.this.firePropertyChange
6547:           (ACCESSIBLE_STATE_PROPERTY, null, AccessibleState.VISIBLE);
6548:       }
6549: 
6550:       /**
6551:        * Moving a component does not affect properties.
6552:        *
6553:        * @param e ignored
6554:        */
6555:       public void componentMoved(ComponentEvent e)
6556:       {
6557:         // Nothing to do here.
6558:       }
6559: 
6560:       /**
6561:        * Resizing a component does not affect properties.
6562:        *
6563:        * @param e ignored
6564:        */
6565:       public void componentResized(ComponentEvent e)
6566:       {
6567:         // Nothing to do here.
6568:       }
6569:     } // class AccessibleAWTComponentHandler
6570: 
6571:     /**
6572:      * Converts focus changes into property changes.
6573:      *
6574:      * @author Eric Blake (ebb9@email.byu.edu)
6575:      * @since 1.3
6576:      * @status updated to 1.4
6577:      */
6578:     protected class AccessibleAWTFocusHandler implements FocusListener
6579:     {
6580:       /**
6581:        * Default constructor.
6582:        */
6583:       protected AccessibleAWTFocusHandler()
6584:       {
6585:         // Nothing to do here.
6586:       }
6587: 
6588:       /**
6589:        * Convert a focus gained to a property change.
6590:        *
6591:        * @param e the event to convert
6592:        */
6593:       public void focusGained(FocusEvent e)
6594:       {
6595:         AccessibleAWTComponent.this.firePropertyChange
6596:           (ACCESSIBLE_STATE_PROPERTY, null, AccessibleState.FOCUSED);
6597:       }
6598: 
6599:       /**
6600:        * Convert a focus lost to a property change.
6601:        *
6602:        * @param e the event to convert
6603:        */
6604:       public void focusLost(FocusEvent e)
6605:       {
6606:         AccessibleAWTComponent.this.firePropertyChange
6607:           (ACCESSIBLE_STATE_PROPERTY, AccessibleState.FOCUSED, null);
6608:       }
6609:     } // class AccessibleAWTComponentHandler
6610:   } // class AccessibleAWTComponent
6611: 
6612:   /**
6613:    * This class provides support for blitting offscreen surfaces to a
6614:    * component.
6615:    *
6616:    * @see BufferStrategy
6617:    *
6618:    * @since 1.4
6619:    */
6620:   protected class BltBufferStrategy extends BufferStrategy
6621:   {
6622:     /**
6623:      * The capabilities of the image buffer.
6624:      */
6625:     protected BufferCapabilities caps;
6626: 
6627:     /**
6628:      * The back buffers used in this strategy.
6629:      */
6630:     protected VolatileImage[] backBuffers;
6631: 
6632:     /**
6633:      * Whether or not the image buffer resources are allocated and
6634:      * ready to be drawn into.
6635:      */
6636:     protected boolean validatedContents;
6637: 
6638:     /**
6639:      * The width of the back buffers.
6640:      */
6641:     protected int width;
6642: 
6643:     /**
6644:      * The height of the back buffers.
6645:      */
6646:     protected int height;
6647: 
6648:     /**
6649:      * The front buffer.
6650:      */
6651:     private VolatileImage frontBuffer;
6652: 
6653:     /**
6654:      * Creates a blitting buffer strategy.
6655:      *
6656:      * @param numBuffers the number of buffers, including the front
6657:      * buffer
6658:      * @param caps the capabilities of this strategy
6659:      */
6660:     protected BltBufferStrategy(int numBuffers, BufferCapabilities caps)
6661:     {
6662:       this.caps = caps;
6663:       createBackBuffers(numBuffers - 1);
6664:       width = getWidth();
6665:       height = getHeight();
6666:     }
6667: 
6668:     /**
6669:      * Initializes the backBuffers field with an array of numBuffers
6670:      * VolatileImages.
6671:      *
6672:      * @param numBuffers the number of backbuffers to create
6673:      */
6674:     protected void createBackBuffers(int numBuffers)
6675:     {
6676:       GraphicsConfiguration c =
6677:     GraphicsEnvironment.getLocalGraphicsEnvironment()
6678:     .getDefaultScreenDevice().getDefaultConfiguration();
6679: 
6680:       backBuffers = new VolatileImage[numBuffers];
6681: 
6682:       for (int i = 0; i < numBuffers; i++)
6683:     backBuffers[i] = c.createCompatibleVolatileImage(width, height);
6684:     }
6685: 
6686:     /**
6687:      * Retrieves the capabilities of this buffer strategy.
6688:      *
6689:      * @return the capabilities of this buffer strategy
6690:      */
6691:     public BufferCapabilities getCapabilities()
6692:     {
6693:       return caps;
6694:     }
6695: 
6696:     /**
6697:      * Retrieves a graphics object that can be used to draw into this
6698:      * strategy's image buffer.
6699:      *
6700:      * @return a graphics object
6701:      */
6702:     public Graphics getDrawGraphics()
6703:     {
6704:       // Return the backmost buffer's graphics.
6705:       return backBuffers[0].getGraphics();
6706:     }
6707: 
6708:     /**
6709:      * Bring the contents of the back buffer to the front buffer.
6710:      */
6711:     public void show()
6712:     {
6713:       GraphicsConfiguration c =
6714:     GraphicsEnvironment.getLocalGraphicsEnvironment()
6715:     .getDefaultScreenDevice().getDefaultConfiguration();
6716: 
6717:       // draw the front buffer.
6718:       getGraphics().drawImage(backBuffers[backBuffers.length - 1],
6719:                   width, height, null);
6720: 
6721:       BufferCapabilities.FlipContents f = getCapabilities().getFlipContents();
6722: 
6723:       // blit the back buffers.
6724:       for (int i = backBuffers.length - 1; i > 0 ; i--)
6725:     backBuffers[i] = backBuffers[i - 1];
6726: 
6727:       // create new backmost buffer.
6728:       if (f == BufferCapabilities.FlipContents.UNDEFINED)
6729:     backBuffers[0] = c.createCompatibleVolatileImage(width, height);
6730: 
6731:       // create new backmost buffer and clear it to the background
6732:       // color.
6733:       if (f == BufferCapabilities.FlipContents.BACKGROUND)
6734:     {
6735:       backBuffers[0] = c.createCompatibleVolatileImage(width, height);
6736:       backBuffers[0].getGraphics().clearRect(0, 0, width, height);
6737:     }
6738: 
6739:       // FIXME: set the backmost buffer to the prior contents of the
6740:       // front buffer.  How do we retrieve the contents of the front
6741:       // buffer?
6742:       //
6743:       //      if (f == BufferCapabilities.FlipContents.PRIOR)
6744: 
6745:       // set the backmost buffer to a copy of the new front buffer.
6746:       if (f == BufferCapabilities.FlipContents.COPIED)
6747:     backBuffers[0] = backBuffers[backBuffers.length - 1];
6748:     }
6749: 
6750:     /**
6751:      * Re-create the image buffer resources if they've been lost.
6752:      */
6753:     protected void revalidate()
6754:     {
6755:       GraphicsConfiguration c =
6756:     GraphicsEnvironment.getLocalGraphicsEnvironment()
6757:     .getDefaultScreenDevice().getDefaultConfiguration();
6758: 
6759:       for (int i = 0; i < backBuffers.length; i++)
6760:     {
6761:       int result = backBuffers[i].validate(c);
6762:       if (result == VolatileImage.IMAGE_INCOMPATIBLE)
6763:         backBuffers[i] = c.createCompatibleVolatileImage(width, height);
6764:     }
6765:       validatedContents = true;
6766:     }
6767: 
6768:     /**
6769:      * Returns whether or not the image buffer resources have been
6770:      * lost.
6771:      *
6772:      * @return true if the resources have been lost, false otherwise
6773:      */
6774:     public boolean contentsLost()
6775:     {
6776:       for (int i = 0; i < backBuffers.length; i++)
6777:     {
6778:       if (backBuffers[i].contentsLost())
6779:         {
6780:           validatedContents = false;
6781:           return true;
6782:         }
6783:     }
6784:       // we know that the buffer resources are valid now because we
6785:       // just checked them
6786:       validatedContents = true;
6787:       return false;
6788:     }
6789: 
6790:     /**
6791:      * Returns whether or not the image buffer resources have been
6792:      * restored.
6793:      *
6794:      * @return true if the resources have been restored, false
6795:      * otherwise
6796:      */
6797:     public boolean contentsRestored()
6798:     {
6799:       GraphicsConfiguration c =
6800:     GraphicsEnvironment.getLocalGraphicsEnvironment()
6801:     .getDefaultScreenDevice().getDefaultConfiguration();
6802: 
6803:       boolean imageRestored = false;
6804: 
6805:       for (int i = 0; i < backBuffers.length; i++)
6806:     {
6807:       int result = backBuffers[i].validate(c);
6808:       if (result == VolatileImage.IMAGE_RESTORED)
6809:         imageRestored = true;
6810:       else if (result == VolatileImage.IMAGE_INCOMPATIBLE)
6811:         return false;
6812:     }
6813:       // we know that the buffer resources are valid now because we
6814:       // just checked them
6815:       validatedContents = true;
6816:       return imageRestored;
6817:     }
6818:   }
6819: 
6820:   /**
6821:    * This class provides support for flipping component buffers. It
6822:    * can only be used on Canvases and Windows.
6823:    *
6824:    * @since 1.4
6825:    */
6826:   protected class FlipBufferStrategy extends BufferStrategy
6827:   {
6828:     /**
6829:      * The number of buffers.
6830:      */
6831:     protected int numBuffers;
6832: 
6833:     /**
6834:      * The capabilities of this buffering strategy.
6835:      */
6836:     protected BufferCapabilities caps;
6837: 
6838:     /**
6839:      * An Image reference to the drawing buffer.
6840:      */
6841:     protected Image drawBuffer;
6842: 
6843:     /**
6844:      * A VolatileImage reference to the drawing buffer.
6845:      */
6846:     protected VolatileImage drawVBuffer;
6847: 
6848:     /**
6849:      * Whether or not the image buffer resources are allocated and
6850:      * ready to be drawn into.
6851:      */
6852:     protected boolean validatedContents;
6853: 
6854:     /**
6855:      * The width of the back buffer.
6856:      */
6857:     private int width;
6858: 
6859:     /**
6860:      * The height of the back buffer.
6861:      */
6862:     private int height;
6863: 
6864:     /**
6865:      * Creates a flipping buffer strategy.  The only supported
6866:      * strategy for FlipBufferStrategy itself is a double-buffer page
6867:      * flipping strategy.  It forms the basis for more complex derived
6868:      * strategies.
6869:      *
6870:      * @param numBuffers the number of buffers
6871:      * @param caps the capabilities of this buffering strategy
6872:      *
6873:      * @throws AWTException if the requested
6874:      * number-of-buffers/capabilities combination is not supported
6875:      */
6876:     protected FlipBufferStrategy(int numBuffers, BufferCapabilities caps)
6877:       throws AWTException
6878:     {
6879:       this.caps = caps;
6880:       width = getWidth();
6881:       height = getHeight();
6882: 
6883:       if (numBuffers > 1)
6884:     createBuffers(numBuffers, caps);
6885:       else
6886:     {
6887:       drawVBuffer = peer.createVolatileImage(width, height);
6888:       drawBuffer = drawVBuffer;
6889:     }
6890:     }
6891: 
6892:     /**
6893:      * Creates a multi-buffer flipping strategy.  The number of
6894:      * buffers must be greater than one and the buffer capabilities
6895:      * must specify page flipping.
6896:      *
6897:      * @param numBuffers the number of flipping buffers; must be
6898:      * greater than one
6899:      * @param caps the buffering capabilities; caps.isPageFlipping()
6900:      * must return true
6901:      *
6902:      * @throws IllegalArgumentException if numBuffers is not greater
6903:      * than one or if the page flipping capability is not requested
6904:      *
6905:      * @throws AWTException if the requested flipping strategy is not
6906:      * supported
6907:      */
6908:     protected void createBuffers(int numBuffers, BufferCapabilities caps)
6909:       throws AWTException
6910:     {
6911:       if (numBuffers <= 1)
6912:     throw new IllegalArgumentException("FlipBufferStrategy.createBuffers:"
6913:                        + " numBuffers must be greater than"
6914:                        + " one.");
6915: 
6916:       if (!caps.isPageFlipping())
6917:     throw new IllegalArgumentException("FlipBufferStrategy.createBuffers:"
6918:                        + " flipping must be a specified"
6919:                        + " capability.");
6920: 
6921:       peer.createBuffers(numBuffers, caps);
6922:     }
6923: 
6924:     /**
6925:      * Return a direct reference to the back buffer image.
6926:      *
6927:      * @return a direct reference to the back buffer image.
6928:      */
6929:     protected Image getBackBuffer()
6930:     {
6931:       return peer.getBackBuffer();
6932:     }
6933: 
6934:     /**
6935:      * Perform a flip operation to transfer the contents of the back
6936:      * buffer to the front buffer.
6937:      */
6938:     protected void flip(BufferCapabilities.FlipContents flipAction)
6939:     {
6940:       peer.flip(flipAction);
6941:     }
6942: 
6943:     /**
6944:      * Release the back buffer's resources.
6945:      */
6946:     protected void destroyBuffers()
6947:     {
6948:       peer.destroyBuffers();
6949:     }
6950: 
6951:     /**
6952:      * Retrieves the capabilities of this buffer strategy.
6953:      *
6954:      * @return the capabilities of this buffer strategy
6955:      */
6956:     public BufferCapabilities getCapabilities()
6957:     {
6958:       return caps;
6959:     }
6960: 
6961:     /**
6962:      * Retrieves a graphics object that can be used to draw into this
6963:      * strategy's image buffer.
6964:      *
6965:      * @return a graphics object
6966:      */
6967:     public Graphics getDrawGraphics()
6968:     {
6969:       return drawVBuffer.getGraphics();
6970:     }
6971: 
6972:     /**
6973:      * Re-create the image buffer resources if they've been lost.
6974:      */
6975:     protected void revalidate()
6976:     {
6977:       GraphicsConfiguration c =
6978:     GraphicsEnvironment.getLocalGraphicsEnvironment()
6979:     .getDefaultScreenDevice().getDefaultConfiguration();
6980: 
6981:       if (drawVBuffer.validate(c) == VolatileImage.IMAGE_INCOMPATIBLE)
6982:     drawVBuffer = peer.createVolatileImage(width, height);
6983:       validatedContents = true;
6984:     }
6985: 
6986:     /**
6987:      * Returns whether or not the image buffer resources have been
6988:      * lost.
6989:      *
6990:      * @return true if the resources have been lost, false otherwise
6991:      */
6992:     public boolean contentsLost()
6993:     {
6994:       if (drawVBuffer.contentsLost())
6995:     {
6996:       validatedContents = false;
6997:       return true;
6998:     }
6999:       // we know that the buffer resources are valid now because we
7000:       // just checked them
7001:       validatedContents = true;
7002:       return false;
7003:     }
7004: 
7005:     /**
7006:      * Returns whether or not the image buffer resources have been
7007:      * restored.
7008:      *
7009:      * @return true if the resources have been restored, false
7010:      * otherwise
7011:      */
7012:     public boolean contentsRestored()
7013:     {
7014:       GraphicsConfiguration c =
7015:     GraphicsEnvironment.getLocalGraphicsEnvironment()
7016:     .getDefaultScreenDevice().getDefaultConfiguration();
7017: 
7018:       int result = drawVBuffer.validate(c);
7019: 
7020:       boolean imageRestored = false;
7021: 
7022:       if (result == VolatileImage.IMAGE_RESTORED)
7023:     imageRestored = true;
7024:       else if (result == VolatileImage.IMAGE_INCOMPATIBLE)
7025:     return false;
7026: 
7027:       // we know that the buffer resources are valid now because we
7028:       // just checked them
7029:       validatedContents = true;
7030:       return imageRestored;
7031:     }
7032: 
7033:     /**
7034:      * Bring the contents of the back buffer to the front buffer.
7035:      */
7036:     public void show()
7037:     {
7038:       flip(caps.getFlipContents());
7039:     }
7040:   }
7041: }