Source for java.awt.Component

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