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