Source for java.awt.Component

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