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:             Rectangle bounds = getBounds();
1743:             gfx.setClip(bounds);
1744:             gfx.translate(bounds.x, bounds.y);
1745:             return gfx;
1746:           }
1747:         gfx.setFont(font);
1748:         return gfx;
1749:       }
1750:     return null;
1751:   }
1752: 
1753:   /**
1754:    * Returns the font metrics for the specified font in this component.
1755:    *
1756:    * @param font the font to retrieve metrics for
1757:    * @return the font metrics for the specified font
1758:    * @throws NullPointerException if font is null
1759:    * @see #getFont()
1760:    * @see Toolkit#getFontMetrics(Font)
1761:    */
1762:   public FontMetrics getFontMetrics(Font font)
1763:   {
1764:     return peer == null ? getToolkit().getFontMetrics(font)
1765:       : peer.getFontMetrics(font);
1766:   }
1767: 
1768:   /**
1769:    * Sets the cursor for this component to the specified cursor. The cursor
1770:    * is displayed when the point is contained by the component, and the
1771:    * component is visible, displayable, and enabled. This is inherited by
1772:    * subcomponents unless they set their own cursor.
1773:    *
1774:    * @param cursor the new cursor for this component
1775:    * @see #isEnabled()
1776:    * @see #isShowing()
1777:    * @see #getCursor()
1778:    * @see #contains(int, int)
1779:    * @see Toolkit#createCustomCursor(Image, Point, String)
1780:    */
1781:   public void setCursor(Cursor cursor)
1782:   {
1783:     this.cursor = cursor;
1784:     if (peer != null)
1785:       peer.setCursor(cursor);
1786:   }
1787: 
1788:   /**
1789:    * Returns the cursor for this component. If not set, this is inherited
1790:    * from the parent, or from Cursor.getDefaultCursor().
1791:    *
1792:    * @return the cursor for this component
1793:    */
1794:   public Cursor getCursor()
1795:   {
1796:     if (cursor != null)
1797:       return cursor;
1798:     return parent != null ? parent.getCursor() : Cursor.getDefaultCursor();
1799:   }
1800: 
1801:   /**
1802:    * Tests if the cursor was explicitly set, or just inherited from the parent.
1803:    *
1804:    * @return true if the cursor has been set
1805:    * @since 1.4
1806:    */
1807:   public boolean isCursorSet()
1808:   {
1809:     return cursor != null;
1810:   }
1811: 
1812:   /**
1813:    * Paints this component on the screen. The clipping region in the graphics
1814:    * context will indicate the region that requires painting. This is called
1815:    * whenever the component first shows, or needs to be repaired because
1816:    * something was temporarily drawn on top. It is not necessary for
1817:    * subclasses to call <code>super.paint(g)</code>. Components with no area
1818:    * are not painted.
1819:    *
1820:    * @param g the graphics context for this paint job
1821:    * @see #update(Graphics)
1822:    */
1823:   public void paint(Graphics g)
1824:   {
1825:     // This is a callback method and is meant to be overridden by subclasses
1826:     // that want to perform custom painting.
1827:   }
1828: 
1829:   /**
1830:    * Updates this component. This is called in response to
1831:    * <code>repaint</code>. This method fills the component with the
1832:    * background color, then sets the foreground color of the specified
1833:    * graphics context to the foreground color of this component and calls
1834:    * the <code>paint()</code> method. The coordinates of the graphics are
1835:    * relative to this component. Subclasses should call either
1836:    * <code>super.update(g)</code> or <code>paint(g)</code>.
1837:    *
1838:    * @param g the graphics context for this update
1839:    *
1840:    * @see #paint(Graphics)
1841:    * @see #repaint()
1842:    *
1843:    * @specnote In contrast to what the spec says, tests show that the exact
1844:    *           behaviour is to clear the background on lightweight and
1845:    *           top-level components only. Heavyweight components are not
1846:    *           affected by this method and only call paint().
1847:    */
1848:   public void update(Graphics g)
1849:   {
1850:     // Tests show that the clearing of the background is only done in
1851:     // two cases:
1852:     // - If the component is lightweight (yes this is in contrast to the spec).
1853:     // or
1854:     // - If the component is a toplevel container.
1855:     if (isLightweight() || getParent() == null)
1856:       {
1857:         Rectangle clip = g.getClipBounds();
1858:         if (clip == null)
1859:           g.clearRect(0, 0, width, height);
1860:         else
1861:           g.clearRect(clip.x, clip.y, clip.width, clip.height);
1862:       }
1863:     paint(g);
1864:   }
1865: 
1866:   /**
1867:    * Paints this entire component, including any sub-components.
1868:    *
1869:    * @param g the graphics context for this paint job
1870:    * 
1871:    * @see #paint(Graphics)
1872:    */
1873:   public void paintAll(Graphics g)
1874:   {
1875:     if (! visible)
1876:       return;
1877:     paint(g);
1878:   }
1879: 
1880:   /**
1881:    * Repaint this entire component. The <code>update()</code> method
1882:    * on this component will be called as soon as possible.
1883:    *
1884:    * @see #update(Graphics)
1885:    * @see #repaint(long, int, int, int, int)
1886:    */
1887:   public void repaint()
1888:   {   
1889:     repaint(0, 0, 0, width, height);
1890:   }
1891: 
1892:   /**
1893:    * Repaint this entire component. The <code>update()</code> method on this
1894:    * component will be called in approximate the specified number of
1895:    * milliseconds.
1896:    *
1897:    * @param tm milliseconds before this component should be repainted
1898:    * @see #paint(Graphics)
1899:    * @see #repaint(long, int, int, int, int)
1900:    */
1901:   public void repaint(long tm)
1902:   {
1903:     repaint(tm, 0, 0, width, height);
1904:   }
1905: 
1906:   /**
1907:    * Repaints the specified rectangular region within this component. The
1908:    * <code>update</code> method on this component will be called as soon as
1909:    * possible. The coordinates are relative to this component.
1910:    *
1911:    * @param x the X coordinate of the upper left of the region to repaint
1912:    * @param y the Y coordinate of the upper left of the region to repaint
1913:    * @param w the width of the region to repaint
1914:    * @param h the height of the region to repaint
1915:    * @see #update(Graphics)
1916:    * @see #repaint(long, int, int, int, int)
1917:    */
1918:   public void repaint(int x, int y, int w, int h)
1919:   {
1920:     repaint(0, x, y, w, h);
1921:   }
1922: 
1923:   /**
1924:    * Repaints the specified rectangular region within this component. The
1925:    * <code>update</code> method on this component will be called in
1926:    * approximately the specified number of milliseconds. The coordinates
1927:    * are relative to this component.
1928:    *
1929:    * @param tm milliseconds before this component should be repainted
1930:    * @param x the X coordinate of the upper left of the region to repaint
1931:    * @param y the Y coordinate of the upper left of the region to repaint
1932:    * @param width the width of the region to repaint
1933:    * @param height the height of the region to repaint
1934:    * @see #update(Graphics)
1935:    */
1936:   public void repaint(long tm, int x, int y, int width, int height)
1937:   {
1938:     if (isShowing())
1939:       {
1940:         ComponentPeer p = peer;
1941:         if (p != null)
1942:           p.repaint(tm, x, y, width, height);
1943:       }
1944:   }
1945: 
1946:   /**
1947:    * Prints this component. This method is provided so that printing can be
1948:    * done in a different manner from painting. However, the implementation
1949:    * in this class simply calls the <code>paint()</code> method.
1950:    *
1951:    * @param g the graphics context of the print device
1952:    * 
1953:    * @see #paint(Graphics)
1954:    */
1955:   public void print(Graphics g)
1956:   {
1957:     paint(g);
1958:   }
1959: 
1960:   /**
1961:    * Prints this component, including all sub-components. This method is
1962:    * provided so that printing can be done in a different manner from
1963:    * painting. However, the implementation in this class simply calls the
1964:    * <code>paintAll()</code> method.
1965:    *
1966:    * @param g the graphics context of the print device
1967:    * 
1968:    * @see #paintAll(Graphics)
1969:    */
1970:   public void printAll(Graphics g)
1971:   {
1972:     paintAll(g);
1973:   }
1974: 
1975:   /**
1976:    * Called when an image has changed so that this component is repainted.
1977:    * This incrementally draws an image as more bits are available, when
1978:    * possible. Incremental drawing is enabled if the system property
1979:    * <code>awt.image.incrementalDraw</code> is not present or is true, in which
1980:    * case the redraw rate is set to 100ms or the value of the system property
1981:    * <code>awt.image.redrawrate</code>.
1982:    *
1983:    * <p>The coordinate system used depends on the particular flags.
1984:    *
1985:    * @param img the image that has been updated
1986:    * @param flags tlags as specified in <code>ImageObserver</code>
1987:    * @param x the X coordinate
1988:    * @param y the Y coordinate
1989:    * @param w the width
1990:    * @param h the height
1991:    * @return false if the image is completely loaded, loading has been
1992:    * aborted, or an error has occurred.  true if more updates are
1993:    * required.
1994:    * @see ImageObserver
1995:    * @see Graphics#drawImage(Image, int, int, Color, ImageObserver)
1996:    * @see Graphics#drawImage(Image, int, int, ImageObserver)
1997:    * @see Graphics#drawImage(Image, int, int, int, int, Color, ImageObserver)
1998:    * @see Graphics#drawImage(Image, int, int, int, int, ImageObserver)
1999:    * @see ImageObserver#imageUpdate(Image, int, int, int, int, int)
2000:    */
2001:   public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h)
2002:   {
2003:     if ((flags & (FRAMEBITS | ALLBITS)) != 0)
2004:       repaint();
2005:     else if ((flags & SOMEBITS) != 0)
2006:       {
2007:     if (incrementalDraw)
2008:       {
2009:         if (redrawRate != null)
2010:           {
2011:         long tm = redrawRate.longValue();
2012:         if (tm < 0)
2013:           tm = 0;
2014:                 repaint(tm);
2015:           }
2016:         else
2017:               repaint(100);
2018:       }
2019:       }
2020:     return (flags & (ALLBITS | ABORT | ERROR)) == 0;
2021:   }
2022: 
2023:   /**
2024:    * Creates an image from the specified producer.
2025:    *
2026:    * @param producer the image procedure to create the image from
2027:    * @return the resulting image
2028:    */
2029:   public Image createImage(ImageProducer producer)
2030:   {
2031:     // Sun allows producer to be null.
2032:     if (peer != null)
2033:       return peer.createImage(producer);
2034:     else
2035:       return getToolkit().createImage(producer);
2036:   }
2037: 
2038:   /**
2039:    * Creates an image with the specified width and height for use in
2040:    * double buffering. Headless environments do not support images.
2041:    *
2042:    * @param width the width of the image
2043:    * @param height the height of the image
2044:    * @return the requested image, or null if it is not supported
2045:    */
2046:   public Image createImage (int width, int height)
2047:   {
2048:     Image returnValue = null;
2049:     if (!GraphicsEnvironment.isHeadless ())
2050:       {
2051:     if (isLightweight () && parent != null)
2052:       returnValue = parent.createImage (width, height);
2053:     else if (peer != null)
2054:       returnValue = peer.createImage (width, height);
2055:       }
2056:     return returnValue;
2057:   }
2058: 
2059:   /**
2060:    * Creates an image with the specified width and height for use in
2061:    * double buffering. Headless environments do not support images.
2062:    *
2063:    * @param width the width of the image
2064:    * @param height the height of the image
2065:    * @return the requested image, or null if it is not supported
2066:    * @since 1.4
2067:    */
2068:   public VolatileImage createVolatileImage(int width, int height)
2069:   {
2070:     if (GraphicsEnvironment.isHeadless())
2071:       return null;
2072:     GraphicsConfiguration config = getGraphicsConfiguration();
2073:     return config == null ? null
2074:       : config.createCompatibleVolatileImage(width, height);
2075:   }
2076: 
2077:   /**
2078:    * Creates an image with the specified width and height for use in
2079:    * double buffering. Headless environments do not support images. The image
2080:    * will support the specified capabilities.
2081:    *
2082:    * @param width the width of the image
2083:    * @param height the height of the image
2084:    * @param caps the requested capabilities
2085:    * @return the requested image, or null if it is not supported
2086:    * @throws AWTException if a buffer with the capabilities cannot be created
2087:    * @since 1.4
2088:    */
2089:   public VolatileImage createVolatileImage(int width, int height,
2090:                                            ImageCapabilities caps)
2091:     throws AWTException
2092:   {
2093:     if (GraphicsEnvironment.isHeadless())
2094:       return null;
2095:     GraphicsConfiguration config = getGraphicsConfiguration();
2096:     return config == null ? null
2097:       : config.createCompatibleVolatileImage(width, height, caps);
2098:   }
2099: 
2100:   /**
2101:    * Prepares the specified image for rendering on this component.
2102:    *
2103:    * @param image the image to prepare for rendering
2104:    * @param observer the observer to notify of image preparation status
2105:    * @return true if the image is already fully prepared
2106:    * @throws NullPointerException if image is null
2107:    */
2108:   public boolean prepareImage(Image image, ImageObserver observer)
2109:   {
2110:     return prepareImage(image, image.getWidth(observer),
2111:                         image.getHeight(observer), observer);
2112:   }
2113: 
2114:   /**
2115:    * Prepares the specified image for rendering on this component at the
2116:    * specified scaled width and height
2117:    *
2118:    * @param image the image to prepare for rendering
2119:    * @param width the scaled width of the image
2120:    * @param height the scaled height of the image
2121:    * @param observer the observer to notify of image preparation status
2122:    * @return true if the image is already fully prepared
2123:    */
2124:   public boolean prepareImage(Image image, int width, int height,
2125:                               ImageObserver observer)
2126:   {
2127:     if (peer != null)
2128:     return peer.prepareImage(image, width, height, observer);
2129:     else
2130:     return getToolkit().prepareImage(image, width, height, observer);
2131:   }
2132: 
2133:   /**
2134:    * Returns the status of the loading of the specified image. The value
2135:    * returned will be those flags defined in <code>ImageObserver</code>.
2136:    *
2137:    * @param image the image to check on
2138:    * @param observer the observer to notify of image loading progress
2139:    * @return the image observer flags indicating the status of the load
2140:    * @see #prepareImage(Image, int, int, ImageObserver)
2141:    * @see Toolkit#checkImage(Image, int, int, ImageObserver)
2142:    * @throws NullPointerException if image is null
2143:    */
2144:   public int checkImage(Image image, ImageObserver observer)
2145:   {
2146:     return checkImage(image, -1, -1, observer);
2147:   }
2148: 
2149:   /**
2150:    * Returns the status of the loading of the specified image. The value
2151:    * returned will be those flags defined in <code>ImageObserver</code>.
2152:    *
2153:    * @param image the image to check on
2154:    * @param width the scaled image width
2155:    * @param height the scaled image height
2156:    * @param observer the observer to notify of image loading progress
2157:    * @return the image observer flags indicating the status of the load
2158:    * @see #prepareImage(Image, int, int, ImageObserver)
2159:    * @see Toolkit#checkImage(Image, int, int, ImageObserver)
2160:    */
2161:   public int checkImage(Image image, int width, int height,
2162:                         ImageObserver observer)
2163:   {
2164:     if (peer != null)
2165:       return peer.checkImage(image, width, height, observer);
2166:     return getToolkit().checkImage(image, width, height, observer);
2167:   }
2168: 
2169:   /**
2170:    * Sets whether paint messages delivered by the operating system should be
2171:    * ignored. This does not affect messages from AWT, except for those
2172:    * triggered by OS messages. Setting this to true can allow faster
2173:    * performance in full-screen mode or page-flipping.
2174:    *
2175:    * @param ignoreRepaint the new setting for ignoring repaint events
2176:    * @see #getIgnoreRepaint()
2177:    * @see BufferStrategy
2178:    * @see GraphicsDevice#setFullScreenWindow(Window)
2179:    * @since 1.4
2180:    */
2181:   public void setIgnoreRepaint(boolean ignoreRepaint)
2182:   {
2183:     this.ignoreRepaint = ignoreRepaint;
2184:   }
2185: 
2186:   /**
2187:    * Test whether paint events from the operating system are ignored.
2188:    *
2189:    * @return the status of ignoring paint events
2190:    * @see #setIgnoreRepaint(boolean)
2191:    * @since 1.4
2192:    */
2193:   public boolean getIgnoreRepaint()
2194:   {
2195:     return ignoreRepaint;
2196:   }
2197: 
2198:   /**
2199:    * Tests whether or not the specified point is contained within this
2200:    * component. Coordinates are relative to this component.
2201:    *
2202:    * @param x the X coordinate of the point to test
2203:    * @param y the Y coordinate of the point to test
2204:    * @return true if the point is within this component
2205:    * @see #getComponentAt(int, int)
2206:    */
2207:   public boolean contains(int x, int y)
2208:   {
2209:     return inside (x, y);
2210:   }
2211: 
2212:   /**
2213:    * Tests whether or not the specified point is contained within this
2214:    * component. Coordinates are relative to this component.
2215:    *
2216:    * @param x the X coordinate of the point to test
2217:    * @param y the Y coordinate of the point to test
2218:    * @return true if the point is within this component
2219:    * @deprecated use {@link #contains(int, int)} instead
2220:    */
2221:   public boolean inside(int x, int y)
2222:   {
2223:     return x >= 0 && y >= 0 && x < width && y < height;
2224:   }
2225: 
2226:   /**
2227:    * Tests whether or not the specified point is contained within this
2228:    * component. Coordinates are relative to this component.
2229:    *
2230:    * @param p the point to test
2231:    * @return true if the point is within this component
2232:    * @throws NullPointerException if p is null
2233:    * @see #getComponentAt(Point)
2234:    * @since 1.1
2235:    */
2236:   public boolean contains(Point p)
2237:   {
2238:     return contains (p.x, p.y);
2239:   }
2240: 
2241:   /**
2242:    * Returns the component occupying the position (x,y). This will either
2243:    * be this component, an immediate child component, or <code>null</code>
2244:    * if neither of the first two occupies the specified location.
2245:    *
2246:    * @param x the X coordinate to search for components at
2247:    * @param y the Y coordinate to search for components at
2248:    * @return the component at the specified location, or null
2249:    * @see #contains(int, int)
2250:    */
2251:   public Component getComponentAt(int x, int y)
2252:   {
2253:     return locate (x, y);
2254:   }
2255: 
2256:   /**
2257:    * Returns the component occupying the position (x,y). This will either
2258:    * be this component, an immediate child component, or <code>null</code>
2259:    * if neither of the first two occupies the specified location.
2260:    *
2261:    * @param x the X coordinate to search for components at
2262:    * @param y the Y coordinate to search for components at
2263:    * @return the component at the specified location, or null
2264:    * @deprecated use {@link #getComponentAt(int, int)} instead
2265:    */
2266:   public Component locate(int x, int y)
2267:   {
2268:     return contains (x, y) ? this : null;
2269:   }
2270: 
2271:   /**
2272:    * Returns the component occupying the position (x,y). This will either
2273:    * be this component, an immediate child component, or <code>null</code>
2274:    * if neither of the first two occupies the specified location.
2275:    *
2276:    * @param p the point to search for components at
2277:    * @return the component at the specified location, or null
2278:    * @throws NullPointerException if p is null
2279:    * @see #contains(Point)
2280:    * @since 1.1
2281:    */
2282:   public Component getComponentAt(Point p)
2283:   {
2284:     return getComponentAt (p.x, p.y);
2285:   }
2286: 
2287:   /**
2288:    * AWT 1.0 event delivery.
2289:    *
2290:    * Deliver an AWT 1.0 event to this Component.  This method simply
2291:    * calls {@link #postEvent}.
2292:    *
2293:    * @param e the event to deliver
2294:    * @deprecated use {@link #dispatchEvent (AWTEvent)} instead
2295:    */
2296:   public void deliverEvent (Event e)
2297:   {
2298:     postEvent (e);
2299:   }
2300: 
2301:   /**
2302:    * Forwards AWT events to processEvent() if:<ul>
2303:    * <li>Events have been enabled for this type of event via
2304:    * <code>enableEvents()</code></li>,
2305:    * <li>There is at least one registered listener for this type of event</li>
2306:    * </ul>
2307:    *
2308:    * @param e the event to dispatch
2309:    */
2310:   public final void dispatchEvent(AWTEvent e)
2311:   {
2312:     Event oldEvent = translateEvent(e);
2313:     if (oldEvent != null)
2314:       postEvent (oldEvent);
2315: 
2316:     // Give toolkit a chance to dispatch the event
2317:     // to globally registered listeners.
2318:     Toolkit.getDefaultToolkit().globalDispatchEvent(e);
2319: 
2320:     // Some subclasses in the AWT package need to override this behavior,
2321:     // hence the use of dispatchEventImpl().
2322:     dispatchEventImpl(e);
2323:   }
2324: 
2325:   /**
2326:    * AWT 1.0 event handler.
2327:    *
2328:    * This method simply calls handleEvent and returns the result.
2329:    *
2330:    * @param e the event to handle
2331:    * @return true if the event was handled, false otherwise
2332:    * @deprecated use {@link #dispatchEvent(AWTEvent)} instead
2333:    */
2334:   public boolean postEvent (Event e)
2335:   {
2336:     boolean handled = handleEvent (e);
2337: 
2338:     if (!handled && getParent() != null)
2339:       // FIXME: need to translate event coordinates to parent's
2340:       // coordinate space.
2341:       handled = getParent ().postEvent (e);
2342: 
2343:     return handled;
2344:   }
2345: 
2346:   /**
2347:    * Adds the specified listener to this component. This is harmless if the
2348:    * listener is null, but if the listener has already been registered, it
2349:    * will now be registered twice.
2350:    *
2351:    * @param listener the new listener to add
2352:    * @see ComponentEvent
2353:    * @see #removeComponentListener(ComponentListener)
2354:    * @see #getComponentListeners()
2355:    * @since 1.1
2356:    */
2357:   public synchronized void addComponentListener(ComponentListener listener)
2358:   {
2359:     componentListener = AWTEventMulticaster.add(componentListener, listener);
2360:     if (componentListener != null)
2361:       enableEvents(AWTEvent.COMPONENT_EVENT_MASK);
2362:   }
2363: 
2364:   /**
2365:    * Removes the specified listener from the component. This is harmless if
2366:    * the listener was not previously registered.
2367:    *
2368:    * @param listener the listener to remove
2369:    * @see ComponentEvent
2370:    * @see #addComponentListener(ComponentListener)
2371:    * @see #getComponentListeners()
2372:    * @since 1.1
2373:    */
2374:   public synchronized void removeComponentListener(ComponentListener listener)
2375:   {
2376:     componentListener = AWTEventMulticaster.remove(componentListener, listener);
2377:   }
2378: 
2379:   /**
2380:    * Returns an array of all specified listeners registered on this component.
2381:    *
2382:    * @return an array of listeners
2383:    * @see #addComponentListener(ComponentListener)
2384:    * @see #removeComponentListener(ComponentListener)
2385:    * @since 1.4
2386:    */
2387:   public synchronized ComponentListener[] getComponentListeners()
2388:   {
2389:     return (ComponentListener[])
2390:       AWTEventMulticaster.getListeners(componentListener,
2391:                                        ComponentListener.class);
2392:   }
2393: 
2394:   /**
2395:    * Adds the specified listener to this component. This is harmless if the
2396:    * listener is null, but if the listener has already been registered, it
2397:    * will now be registered twice.
2398:    *
2399:    * @param listener the new listener to add
2400:    * @see FocusEvent
2401:    * @see #removeFocusListener(FocusListener)
2402:    * @see #getFocusListeners()
2403:    * @since 1.1
2404:    */
2405:   public synchronized void addFocusListener(FocusListener listener)
2406:   {
2407:     focusListener = AWTEventMulticaster.add(focusListener, listener);
2408:     if (focusListener != null)
2409:       enableEvents(AWTEvent.FOCUS_EVENT_MASK);
2410:   }
2411: 
2412:   /**
2413:    * Removes the specified listener from the component. This is harmless if
2414:    * the listener was not previously registered.
2415:    *
2416:    * @param listener the listener to remove
2417:    * @see FocusEvent
2418:    * @see #addFocusListener(FocusListener)
2419:    * @see #getFocusListeners()
2420:    * @since 1.1
2421:    */
2422:   public synchronized void removeFocusListener(FocusListener listener)
2423:   {
2424:     focusListener = AWTEventMulticaster.remove(focusListener, listener);
2425:   }
2426: 
2427:   /**
2428:    * Returns an array of all specified listeners registered on this component.
2429:    *
2430:    * @return an array of listeners
2431:    * @see #addFocusListener(FocusListener)
2432:    * @see #removeFocusListener(FocusListener)
2433:    * @since 1.4
2434:    */
2435:   public synchronized FocusListener[] getFocusListeners()
2436:   {
2437:     return (FocusListener[])
2438:       AWTEventMulticaster.getListeners(focusListener, FocusListener.class);
2439:   }
2440: 
2441:   /**
2442:    * Adds the specified listener to this component. This is harmless if the
2443:    * listener is null, but if the listener has already been registered, it
2444:    * will now be registered twice.
2445:    *
2446:    * @param listener the new listener to add
2447:    * @see HierarchyEvent
2448:    * @see #removeHierarchyListener(HierarchyListener)
2449:    * @see #getHierarchyListeners()
2450:    * @since 1.3
2451:    */
2452:   public synchronized void addHierarchyListener(HierarchyListener listener)
2453:   {
2454:     hierarchyListener = AWTEventMulticaster.add(hierarchyListener, listener);
2455:     if (hierarchyListener != null)
2456:       enableEvents(AWTEvent.HIERARCHY_EVENT_MASK);
2457:   }
2458: 
2459:   /**
2460:    * Removes the specified listener from the component. This is harmless if
2461:    * the listener was not previously registered.
2462:    *
2463:    * @param listener the listener to remove
2464:    * @see HierarchyEvent
2465:    * @see #addHierarchyListener(HierarchyListener)
2466:    * @see #getHierarchyListeners()
2467:    * @since 1.3
2468:    */
2469:   public synchronized void removeHierarchyListener(HierarchyListener listener)
2470:   {
2471:     hierarchyListener = AWTEventMulticaster.remove(hierarchyListener, listener);
2472:   }
2473: 
2474:   /**
2475:    * Returns an array of all specified listeners registered on this component.
2476:    *
2477:    * @return an array of listeners
2478:    * @see #addHierarchyListener(HierarchyListener)
2479:    * @see #removeHierarchyListener(HierarchyListener)
2480:    * @since 1.4
2481:    */
2482:   public synchronized HierarchyListener[] getHierarchyListeners()
2483:   {
2484:     return (HierarchyListener[])
2485:       AWTEventMulticaster.getListeners(hierarchyListener,
2486:                                        HierarchyListener.class);
2487:   }
2488: 
2489:   /**
2490:    * Adds the specified listener to this component. This is harmless if the
2491:    * listener is null, but if the listener has already been registered, it
2492:    * will now be registered twice.
2493:    *
2494:    * @param listener the new listener to add
2495:    * @see HierarchyEvent
2496:    * @see #removeHierarchyBoundsListener(HierarchyBoundsListener)
2497:    * @see #getHierarchyBoundsListeners()
2498:    * @since 1.3
2499:    */
2500:   public synchronized void
2501:     addHierarchyBoundsListener(HierarchyBoundsListener listener)
2502:   {
2503:     hierarchyBoundsListener =
2504:       AWTEventMulticaster.add(hierarchyBoundsListener, listener);
2505:     if (hierarchyBoundsListener != null)
2506:       enableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK);
2507:   }
2508: 
2509:   /**
2510:    * Removes the specified listener from the component. This is harmless if
2511:    * the listener was not previously registered.
2512:    *
2513:    * @param listener the listener to remove
2514:    * @see HierarchyEvent
2515:    * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
2516:    * @see #getHierarchyBoundsListeners()
2517:    * @since 1.3
2518:    */
2519:   public synchronized void
2520:     removeHierarchyBoundsListener(HierarchyBoundsListener listener)
2521:   {
2522:     hierarchyBoundsListener =
2523:       AWTEventMulticaster.remove(hierarchyBoundsListener, listener);
2524:   }
2525: 
2526:   /**
2527:    * Returns an array of all specified listeners registered on this component.
2528:    *
2529:    * @return an array of listeners
2530:    * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
2531:    * @see #removeHierarchyBoundsListener(HierarchyBoundsListener)
2532:    * @since 1.4
2533:    */
2534:   public synchronized HierarchyBoundsListener[] getHierarchyBoundsListeners()
2535:   {
2536:     return (HierarchyBoundsListener[])
2537:       AWTEventMulticaster.getListeners(hierarchyBoundsListener,
2538:                                        HierarchyBoundsListener.class);
2539:   }
2540: 
2541:   /**
2542:    * Adds the specified listener to this component. This is harmless if the
2543:    * listener is null, but if the listener has already been registered, it
2544:    * will now be registered twice.
2545:    *
2546:    * @param listener the new listener to add
2547:    * @see KeyEvent
2548:    * @see #removeKeyListener(KeyListener)
2549:    * @see #getKeyListeners()
2550:    * @since 1.1
2551:    */
2552:   public synchronized void addKeyListener(KeyListener listener)
2553:   {
2554:     keyListener = AWTEventMulticaster.add(keyListener, listener);
2555:     if (keyListener != null)
2556:       enableEvents(AWTEvent.KEY_EVENT_MASK);
2557:   }
2558: 
2559:   /**
2560:    * Removes the specified listener from the component. This is harmless if
2561:    * the listener was not previously registered.
2562:    *
2563:    * @param listener the listener to remove
2564:    * @see KeyEvent
2565:    * @see #addKeyListener(KeyListener)
2566:    * @see #getKeyListeners()
2567:    * @since 1.1
2568:    */
2569:   public synchronized void removeKeyListener(KeyListener listener)
2570:   {
2571:     keyListener = AWTEventMulticaster.remove(keyListener, listener);
2572:   }
2573: 
2574:   /**
2575:    * Returns an array of all specified listeners registered on this component.
2576:    *
2577:    * @return an array of listeners
2578:    * @see #addKeyListener(KeyListener)
2579:    * @see #removeKeyListener(KeyListener)
2580:    * @since 1.4
2581:    */
2582:   public synchronized KeyListener[] getKeyListeners()
2583:   {
2584:     return (KeyListener[])
2585:       AWTEventMulticaster.getListeners(keyListener, KeyListener.class);
2586:   }
2587: 
2588:   /**
2589:    * Adds the specified listener to this component. This is harmless if the
2590:    * listener is null, but if the listener has already been registered, it
2591:    * will now be registered twice.
2592:    *
2593:    * @param listener the new listener to add
2594:    * @see MouseEvent
2595:    * @see #removeMouseListener(MouseListener)
2596:    * @see #getMouseListeners()
2597:    * @since 1.1
2598:    */
2599:   public synchronized void addMouseListener(MouseListener listener)
2600:   {
2601:     mouseListener = AWTEventMulticaster.add(mouseListener, listener);
2602:     if (mouseListener != null)
2603:       enableEvents(AWTEvent.MOUSE_EVENT_MASK);
2604:   }
2605: 
2606:   /**
2607:    * Removes the specified listener from the component. This is harmless if
2608:    * the listener was not previously registered.
2609:    *
2610:    * @param listener the listener to remove
2611:    * @see MouseEvent
2612:    * @see #addMouseListener(MouseListener)
2613:    * @see #getMouseListeners()
2614:    * @since 1.1
2615:    */
2616:   public synchronized void removeMouseListener(MouseListener listener)
2617:   {
2618:     mouseListener = AWTEventMulticaster.remove(mouseListener, listener);
2619:   }
2620: 
2621:   /**
2622:    * Returns an array of all specified listeners registered on this component.
2623:    *
2624:    * @return an array of listeners
2625:    * @see #addMouseListener(MouseListener)
2626:    * @see #removeMouseListener(MouseListener)
2627:    * @since 1.4
2628:    */
2629:   public synchronized MouseListener[] getMouseListeners()
2630:   {
2631:     return (MouseListener[])
2632:       AWTEventMulticaster.getListeners(mouseListener, MouseListener.class);
2633:   }
2634: 
2635:   /**
2636:    * Adds the specified listener to this component. This is harmless if the
2637:    * listener is null, but if the listener has already been registered, it
2638:    * will now be registered twice.
2639:    *
2640:    * @param listener the new listener to add
2641:    * @see MouseEvent
2642:    * @see #removeMouseMotionListener(MouseMotionListener)
2643:    * @see #getMouseMotionListeners()
2644:    * @since 1.1
2645:    */
2646:   public synchronized void addMouseMotionListener(MouseMotionListener listener)
2647:   {
2648:     mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener, listener);
2649:     if (mouseMotionListener != null)
2650:       enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
2651:   }
2652: 
2653:   /**
2654:    * Removes the specified listener from the component. This is harmless if
2655:    * the listener was not previously registered.
2656:    *
2657:    * @param listener the listener to remove
2658:    * @see MouseEvent
2659:    * @see #addMouseMotionListener(MouseMotionListener)
2660:    * @see #getMouseMotionListeners()
2661:    * @since 1.1
2662:    */
2663:   public synchronized void removeMouseMotionListener(MouseMotionListener listener)
2664:   {
2665:     mouseMotionListener = AWTEventMulticaster.remove(mouseMotionListener, listener);
2666:   }
2667: 
2668:   /**
2669:    * Returns an array of all specified listeners registered on this component.
2670:    *
2671:    * @return an array of listeners
2672:    * @see #addMouseMotionListener(MouseMotionListener)
2673:    * @see #removeMouseMotionListener(MouseMotionListener)
2674:    * @since 1.4
2675:    */
2676:   public synchronized MouseMotionListener[] getMouseMotionListeners()
2677:   {
2678:     return (MouseMotionListener[])
2679:       AWTEventMulticaster.getListeners(mouseMotionListener,
2680:                                        MouseMotionListener.class);
2681:   }
2682: 
2683:   /**
2684:    * Adds the specified listener to this component. This is harmless if the
2685:    * listener is null, but if the listener has already been registered, it
2686:    * will now be registered twice.
2687:    *
2688:    * @param listener the new listener to add
2689:    * @see MouseEvent
2690:    * @see MouseWheelEvent
2691:    * @see #removeMouseWheelListener(MouseWheelListener)
2692:    * @see #getMouseWheelListeners()
2693:    * @since 1.4
2694:    */
2695:   public synchronized void addMouseWheelListener(MouseWheelListener listener)
2696:   {
2697:     mouseWheelListener = AWTEventMulticaster.add(mouseWheelListener, listener);
2698:     if (mouseWheelListener != null)
2699:       enableEvents(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
2700:   }
2701: 
2702:   /**
2703:    * Removes the specified listener from the component. This is harmless if
2704:    * the listener was not previously registered.
2705:    *
2706:    * @param listener the listener to remove
2707:    * @see MouseEvent
2708:    * @see MouseWheelEvent
2709:    * @see #addMouseWheelListener(MouseWheelListener)
2710:    * @see #getMouseWheelListeners()
2711:    * @since 1.4
2712:    */
2713:   public synchronized void removeMouseWheelListener(MouseWheelListener listener)
2714:   {
2715:     mouseWheelListener = AWTEventMulticaster.remove(mouseWheelListener, listener);
2716:   }
2717: 
2718:   /**
2719:    * Returns an array of all specified listeners registered on this component.
2720:    *
2721:    * @return an array of listeners
2722:    * @see #addMouseWheelListener(MouseWheelListener)
2723:    * @see #removeMouseWheelListener(MouseWheelListener)
2724:    * @since 1.4
2725:    */
2726:   public synchronized MouseWheelListener[] getMouseWheelListeners()
2727:   {
2728:     return (MouseWheelListener[])
2729:       AWTEventMulticaster.getListeners(mouseWheelListener,
2730:                                        MouseWheelListener.class);
2731:   }
2732: 
2733:   /**
2734:    * Adds the specified listener to this component. This is harmless if the
2735:    * listener is null, but if the listener has already been registered, it
2736:    * will now be registered twice.
2737:    *
2738:    * @param listener the new listener to add
2739:    * @see InputMethodEvent
2740:    * @see #removeInputMethodListener(InputMethodListener)
2741:    * @see #getInputMethodListeners()
2742:    * @see #getInputMethodRequests()
2743:    * @since 1.2
2744:    */
2745:   public synchronized void addInputMethodListener(InputMethodListener listener)
2746:   {
2747:     inputMethodListener = AWTEventMulticaster.add(inputMethodListener, listener);
2748:     if (inputMethodListener != null)
2749:       enableEvents(AWTEvent.INPUT_METHOD_EVENT_MASK);
2750:   }
2751: 
2752:   /**
2753:    * Removes the specified listener from the component. This is harmless if
2754:    * the listener was not previously registered.
2755:    *
2756:    * @param listener the listener to remove
2757:    * @see InputMethodEvent
2758:    * @see #addInputMethodListener(InputMethodListener)
2759:    * @see #getInputMethodRequests()
2760:    * @since 1.2
2761:    */
2762:   public synchronized void removeInputMethodListener(InputMethodListener listener)
2763:   {
2764:     inputMethodListener = AWTEventMulticaster.remove(inputMethodListener, listener);
2765:   }
2766: 
2767:   /**
2768:    * Returns an array of all specified listeners registered on this component.
2769:    *
2770:    * @return an array of listeners
2771:    * @see #addInputMethodListener(InputMethodListener)
2772:    * @see #removeInputMethodListener(InputMethodListener)
2773:    * @since 1.4
2774:    */
2775:   public synchronized InputMethodListener[] getInputMethodListeners()
2776:   {
2777:     return (InputMethodListener[])
2778:       AWTEventMulticaster.getListeners(inputMethodListener,
2779:                                        InputMethodListener.class);
2780:   }
2781: 
2782:   /**
2783:    * Returns all registered {@link EventListener}s of the given 
2784:    * <code>listenerType</code>.
2785:    *
2786:    * @param listenerType the class of listeners to filter (<code>null</code> 
2787:    *                     not permitted).
2788:    *                     
2789:    * @return An array of registered listeners.
2790:    * 
2791:    * @throws ClassCastException if <code>listenerType</code> does not implement
2792:    *                            the {@link EventListener} interface.
2793:    * @throws NullPointerException if <code>listenerType</code> is 
2794:    *                              <code>null</code>.
2795:    *                            
2796:    * @see #getComponentListeners()
2797:    * @see #getFocusListeners()
2798:    * @see #getHierarchyListeners()
2799:    * @see #getHierarchyBoundsListeners()
2800:    * @see #getKeyListeners()
2801:    * @see #getMouseListeners()
2802:    * @see #getMouseMotionListeners()
2803:    * @see #getMouseWheelListeners()
2804:    * @see #getInputMethodListeners()
2805:    * @see #getPropertyChangeListeners()
2806:    * @since 1.3
2807:    */
2808:   public EventListener[] getListeners(Class listenerType)
2809:   {
2810:     if (listenerType == ComponentListener.class)
2811:       return getComponentListeners();
2812:     if (listenerType == FocusListener.class)
2813:       return getFocusListeners();
2814:     if (listenerType == HierarchyListener.class)
2815:       return getHierarchyListeners();
2816:     if (listenerType == HierarchyBoundsListener.class)
2817:       return getHierarchyBoundsListeners();
2818:     if (listenerType == KeyListener.class)
2819:       return getKeyListeners();
2820:     if (listenerType == MouseListener.class)
2821:       return getMouseListeners();
2822:     if (listenerType == MouseMotionListener.class)
2823:       return getMouseMotionListeners();
2824:     if (listenerType == MouseWheelListener.class)
2825:       return getMouseWheelListeners();
2826:     if (listenerType == InputMethodListener.class)
2827:       return getInputMethodListeners();
2828:     if (listenerType == PropertyChangeListener.class)
2829:       return getPropertyChangeListeners();
2830:     return (EventListener[]) Array.newInstance(listenerType, 0);
2831:   }
2832: 
2833:   /**
2834:    * Returns the input method request handler, for subclasses which support
2835:    * on-the-spot text input. By default, input methods are handled by AWT,
2836:    * and this returns null.
2837:    *
2838:    * @return the input method handler, null by default
2839:    * @since 1.2
2840:    */
2841:   public InputMethodRequests getInputMethodRequests()
2842:   {
2843:     return null;
2844:   }
2845: 
2846:   /**
2847:    * Gets the input context of this component, which is inherited from the
2848:    * parent unless this is overridden.
2849:    *
2850:    * @return the text input context
2851:    * @since 1.2
2852:    */
2853:   public InputContext getInputContext()
2854:   {
2855:     return parent == null ? null : parent.getInputContext();
2856:   }
2857: 
2858:   /**
2859:    * Enables the specified events. The events to enable are specified
2860:    * by OR-ing together the desired masks from <code>AWTEvent</code>.
2861:    *
2862:    * <p>Events are enabled by default when a listener is attached to the
2863:    * component for that event type. This method can be used by subclasses
2864:    * to ensure the delivery of a specified event regardless of whether
2865:    * or not a listener is attached.
2866:    *
2867:    * @param eventsToEnable the desired events to enable
2868:    * @see #processEvent(AWTEvent)
2869:    * @see #disableEvents(long)
2870:    * @see AWTEvent
2871:    * @since 1.1
2872:    */
2873:   protected final void enableEvents(long eventsToEnable)
2874:   {
2875:     eventMask |= eventsToEnable;
2876:     // TODO: Unlike Sun's implementation, I think we should try and
2877:     // enable/disable events at the peer (gtk/X) level. This will avoid
2878:     // clogging the event pipeline with useless mousemove events that
2879:     // we arn't interested in, etc. This will involve extending the peer
2880:     // interface, but thats okay because the peer interfaces have been
2881:     // deprecated for a long time, and no longer feature in the
2882:     // API specification at all.
2883:     if (isLightweight() && parent != null)
2884:       parent.enableEvents(eventsToEnable);
2885:     else if (peer != null)
2886:       peer.setEventMask(eventMask);
2887:   }
2888: 
2889:   /**
2890:    * Disables the specified events. The events to disable are specified
2891:    * by OR-ing together the desired masks from <code>AWTEvent</code>.
2892:    *
2893:    * @param eventsToDisable the desired events to disable
2894:    * @see #enableEvents(long)
2895:    * @since 1.1
2896:    */
2897:   protected final void disableEvents(long eventsToDisable)
2898:   {
2899:     eventMask &= ~eventsToDisable;
2900:     // forward new event mask to peer?
2901:   }
2902: 
2903:   /**
2904:    * This is called by the EventQueue if two events with the same event id
2905:    * and owner component are queued. Returns a new combined event, or null if
2906:    * no combining is done. The coelesced events are currently mouse moves
2907:    * (intermediate ones are discarded) and paint events (a merged paint is
2908:    * created in place of the two events).
2909:    *
2910:    * @param existingEvent the event on the queue
2911:    * @param newEvent the new event that might be entered on the queue
2912:    * @return null if both events are kept, or the replacement coelesced event
2913:    */
2914:   protected AWTEvent coalesceEvents(AWTEvent existingEvent, AWTEvent newEvent)
2915:   {
2916:     switch (existingEvent.id)
2917:       {
2918:       case MouseEvent.MOUSE_MOVED:
2919:       case MouseEvent.MOUSE_DRAGGED:
2920:         // Just drop the old (intermediate) event and return the new one.
2921:         return newEvent;
2922:       case PaintEvent.PAINT:
2923:       case PaintEvent.UPDATE:
2924:         return coalescePaintEvents((PaintEvent) existingEvent,
2925:                                    (PaintEvent) newEvent);
2926:       default:
2927:         return null;
2928:       }
2929:   }
2930: 
2931:   /**
2932:    * Processes the specified event. In this class, this method simply
2933:    * calls one of the more specific event handlers.
2934:    *
2935:    * @param e the event to process
2936:    * @throws NullPointerException if e is null
2937:    * @see #processComponentEvent(ComponentEvent)
2938:    * @see #processFocusEvent(FocusEvent)
2939:    * @see #processKeyEvent(KeyEvent)
2940:    * @see #processMouseEvent(MouseEvent)
2941:    * @see #processMouseMotionEvent(MouseEvent)
2942:    * @see #processInputMethodEvent(InputMethodEvent)
2943:    * @see #processHierarchyEvent(HierarchyEvent)
2944:    * @see #processMouseWheelEvent(MouseWheelEvent)
2945:    * @since 1.1
2946:    */
2947:   protected void processEvent(AWTEvent e)
2948:   {
2949:     /* Note: the order of these if statements are
2950:        important. Subclasses must be checked first. Eg. MouseEvent
2951:        must be checked before ComponentEvent, since a MouseEvent
2952:        object is also an instance of a ComponentEvent. */
2953: 
2954:     if (e instanceof FocusEvent)
2955:       processFocusEvent((FocusEvent) e);
2956:     else if (e instanceof MouseWheelEvent)
2957:       processMouseWheelEvent((MouseWheelEvent) e);
2958:     else if (e instanceof MouseEvent)
2959:       {
2960:         if (e.id == MouseEvent.MOUSE_MOVED
2961:             || e.id == MouseEvent.MOUSE_DRAGGED)
2962:           processMouseMotionEvent((MouseEvent) e);
2963:         else
2964:           processMouseEvent((MouseEvent) e);
2965:       }
2966:     else if (e instanceof KeyEvent)
2967:       processKeyEvent((KeyEvent) e);
2968:     else if (e instanceof InputMethodEvent)
2969:       processInputMethodEvent((InputMethodEvent) e);
2970:     else if (e instanceof ComponentEvent)
2971:       processComponentEvent((ComponentEvent) e);
2972:     else if (e instanceof HierarchyEvent)
2973:       {
2974:         if (e.id == HierarchyEvent.HIERARCHY_CHANGED)
2975:           processHierarchyEvent((HierarchyEvent) e);
2976:         else
2977:           processHierarchyBoundsEvent((HierarchyEvent) e);
2978:       }
2979:   }
2980: 
2981:   /**
2982:    * Called when a component event is dispatched and component events are
2983:    * enabled. This method passes the event along to any listeners
2984:    * that are attached.
2985:    *
2986:    * @param e the <code>ComponentEvent</code> to process
2987:    * @throws NullPointerException if e is null
2988:    * @see ComponentListener
2989:    * @see #addComponentListener(ComponentListener)
2990:    * @see #enableEvents(long)
2991:    * @since 1.1
2992:    */
2993:   protected void processComponentEvent(ComponentEvent e)
2994:   {
2995:     if (componentListener == null)
2996:       return;
2997:     switch (e.id)
2998:       {
2999:       case ComponentEvent.COMPONENT_HIDDEN:
3000:         componentListener.componentHidden(e);
3001:         break;
3002:       case ComponentEvent.COMPONENT_MOVED:
3003:         componentListener.componentMoved(e);
3004:         break;
3005:       case ComponentEvent.COMPONENT_RESIZED:
3006:         componentListener.componentResized(e);
3007:         break;
3008:       case ComponentEvent.COMPONENT_SHOWN:
3009:         componentListener.componentShown(e);
3010:         break;
3011:       }
3012:   }
3013: 
3014:   /**
3015:    * Called when a focus event is dispatched and component events are
3016:    * enabled. This method passes the event along to any listeners
3017:    * that are attached.
3018:    *
3019:    * @param e the <code>FocusEvent</code> to process
3020:    * @throws NullPointerException if e is null
3021:    * @see FocusListener
3022:    * @see #addFocusListener(FocusListener)
3023:    * @see #enableEvents(long)
3024:    * @since 1.1
3025:    */
3026:   protected void processFocusEvent(FocusEvent e)
3027:   {
3028:     if (focusListener == null)
3029:       return;
3030: 
3031:     switch (e.id)
3032:       {
3033:         case FocusEvent.FOCUS_GAINED:
3034:           focusListener.focusGained(e);
3035:         break;
3036:         case FocusEvent.FOCUS_LOST:
3037:           focusListener.focusLost(e);
3038:         break;
3039:       }
3040:   }
3041: 
3042:   /**
3043:    * Called when a key event is dispatched and component events are
3044:    * enabled. This method passes the event along to any listeners
3045:    * that are attached.
3046:    *
3047:    * @param e the <code>KeyEvent</code> to process
3048:    * @throws NullPointerException if e is null
3049:    * @see KeyListener
3050:    * @see #addKeyListener(KeyListener)
3051:    * @see #enableEvents(long)
3052:    * @since 1.1
3053:    */
3054:   protected void processKeyEvent(KeyEvent e)
3055:   {
3056:     if (keyListener == null)
3057:       return;
3058:     switch (e.id)
3059:       {
3060:         case KeyEvent.KEY_PRESSED:
3061:           keyListener.keyPressed(e);
3062:         break;
3063:         case KeyEvent.KEY_RELEASED:
3064:           keyListener.keyReleased(e);
3065:         break;
3066:         case KeyEvent.KEY_TYPED:
3067:           keyListener.keyTyped(e);
3068:         break;
3069:       }
3070:   }
3071: 
3072:   /**
3073:    * Called when a regular mouse event is dispatched and component events are
3074:    * enabled. This method passes the event along to any listeners
3075:    * that are attached.
3076:    *
3077:    * @param e the <code>MouseEvent</code> to process
3078:    * @throws NullPointerException if e is null
3079:    * @see MouseListener
3080:    * @see #addMouseListener(MouseListener)
3081:    * @see #enableEvents(long)
3082:    * @since 1.1
3083:    */
3084:   protected void processMouseEvent(MouseEvent e)
3085:   {
3086:     if (mouseListener == null)
3087:       return;
3088:     switch (e.id)
3089:       {
3090:         case MouseEvent.MOUSE_CLICKED:
3091:           mouseListener.mouseClicked(e);
3092:         break;
3093:         case MouseEvent.MOUSE_ENTERED:
3094:        if( isLightweight() )
3095:          setCursor( getCursor() );
3096:           mouseListener.mouseEntered(e);
3097:         break;
3098:         case MouseEvent.MOUSE_EXITED:
3099:           mouseListener.mouseExited(e);
3100:         break;
3101:         case MouseEvent.MOUSE_PRESSED:
3102:           mouseListener.mousePressed(e);
3103:         break;
3104:         case MouseEvent.MOUSE_RELEASED:
3105:           mouseListener.mouseReleased(e);
3106:         break;
3107:       }
3108:   }
3109: 
3110:   /**
3111:    * Called when a mouse motion event is dispatched and component events are
3112:    * enabled. This method passes the event along to any listeners
3113:    * that are attached.
3114:    *
3115:    * @param e the <code>MouseMotionEvent</code> to process
3116:    * @throws NullPointerException if e is null
3117:    * @see MouseMotionListener
3118:    * @see #addMouseMotionListener(MouseMotionListener)
3119:    * @see #enableEvents(long)
3120:    * @since 1.1
3121:    */
3122:   protected void processMouseMotionEvent(MouseEvent e)
3123:   {
3124:     if (mouseMotionListener == null)
3125:       return;
3126:     switch (e.id)
3127:       {
3128:         case MouseEvent.MOUSE_DRAGGED:
3129:           mouseMotionListener.mouseDragged(e);
3130:         break;
3131:         case MouseEvent.MOUSE_MOVED:
3132:           mouseMotionListener.mouseMoved(e);
3133:         break;
3134:       }
3135:       e.consume();
3136:   }
3137: 
3138:   /**
3139:    * Called when a mouse wheel event is dispatched and component events are
3140:    * enabled. This method passes the event along to any listeners that are
3141:    * attached.
3142:    *
3143:    * @param e the <code>MouseWheelEvent</code> to process
3144:    * @throws NullPointerException if e is null
3145:    * @see MouseWheelListener
3146:    * @see #addMouseWheelListener(MouseWheelListener)
3147:    * @see #enableEvents(long)
3148:    * @since 1.4
3149:    */
3150:   protected void processMouseWheelEvent(MouseWheelEvent e)
3151:   {
3152:     if (mouseWheelListener != null
3153:         && e.id == MouseEvent.MOUSE_WHEEL)
3154:     {
3155:       mouseWheelListener.mouseWheelMoved(e);
3156:       e.consume();
3157:     }    
3158:   }
3159: 
3160:   /**
3161:    * Called when an input method event is dispatched and component events are
3162:    * enabled. This method passes the event along to any listeners that are
3163:    * attached.
3164:    *
3165:    * @param e the <code>InputMethodEvent</code> to process
3166:    * @throws NullPointerException if e is null
3167:    * @see InputMethodListener
3168:    * @see #addInputMethodListener(InputMethodListener)
3169:    * @see #enableEvents(long)
3170:    * @since 1.2
3171:    */
3172:   protected void processInputMethodEvent(InputMethodEvent e)
3173:   {
3174:     if (inputMethodListener == null)
3175:       return;
3176:     switch (e.id)
3177:       {
3178:         case InputMethodEvent.CARET_POSITION_CHANGED:
3179:           inputMethodListener.caretPositionChanged(e);
3180:         break;
3181:         case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
3182:           inputMethodListener.inputMethodTextChanged(e);
3183:         break;
3184:       }
3185:   }
3186: 
3187:   /**
3188:    * Called when a hierarchy change event is dispatched and component events
3189:    * are enabled. This method passes the event along to any listeners that are
3190:    * attached.
3191:    *
3192:    * @param e the <code>HierarchyEvent</code> to process
3193:    * @throws NullPointerException if e is null
3194:    * @see HierarchyListener
3195:    * @see #addHierarchyListener(HierarchyListener)
3196:    * @see #enableEvents(long)
3197:    * @since 1.3
3198:    */
3199:   protected void processHierarchyEvent(HierarchyEvent e)
3200:   {
3201:     if (hierarchyListener == null)
3202:       return;
3203:     if (e.id == HierarchyEvent.HIERARCHY_CHANGED)
3204:       hierarchyListener.hierarchyChanged(e);
3205:   }
3206: 
3207:   /**
3208:    * Called when a hierarchy bounds event is dispatched and component events
3209:    * are enabled. This method passes the event along to any listeners that are
3210:    * attached.
3211:    *
3212:    * @param e the <code>HierarchyEvent</code> to process
3213:    * @throws NullPointerException if e is null
3214:    * @see HierarchyBoundsListener
3215:    * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
3216:    * @see #enableEvents(long)
3217:    * @since 1.3
3218:    */
3219:   protected void processHierarchyBoundsEvent(HierarchyEvent e)
3220:   {
3221:     if (hierarchyBoundsListener == null)
3222:       return;
3223:     switch (e.id)
3224:       {
3225:         case HierarchyEvent.ANCESTOR_MOVED:
3226:           hierarchyBoundsListener.ancestorMoved(e);
3227:         break;
3228:         case HierarchyEvent.ANCESTOR_RESIZED:
3229:           hierarchyBoundsListener.ancestorResized(e);
3230:         break;
3231:       }
3232:   }
3233: 
3234:   /**
3235:    * AWT 1.0 event handler.
3236:    *
3237:    * This method calls one of the event-specific handler methods.  For
3238:    * example for key events, either {@link #keyDown(Event,int)}
3239:    * or {@link #keyUp(Event,int)} is called.  A derived
3240:    * component can override one of these event-specific methods if it
3241:    * only needs to handle certain event types.  Otherwise it can
3242:    * override handleEvent itself and handle any event.
3243:    *
3244:    * @param evt the event to handle
3245:    * @return true if the event was handled, false otherwise
3246:    * @deprecated use {@link #processEvent(AWTEvent)} instead
3247:    */
3248:   public boolean handleEvent (Event evt)
3249:   {
3250:     switch (evt.id)
3251:       {
3252:     // Handle key events.
3253:       case Event.KEY_ACTION:
3254:       case Event.KEY_PRESS:
3255:     return keyDown (evt, evt.key);
3256:       case Event.KEY_ACTION_RELEASE:
3257:       case Event.KEY_RELEASE:
3258:     return keyUp (evt, evt.key);
3259: 
3260:     // Handle mouse events.
3261:       case Event.MOUSE_DOWN:
3262:     return mouseDown (evt, evt.x, evt.y);
3263:       case Event.MOUSE_UP:
3264:     return mouseUp (evt, evt.x, evt.y);
3265:       case Event.MOUSE_MOVE:
3266:     return mouseMove (evt, evt.x, evt.y);
3267:       case Event.MOUSE_DRAG:
3268:     return mouseDrag (evt, evt.x, evt.y);
3269:       case Event.MOUSE_ENTER:
3270:     return mouseEnter (evt, evt.x, evt.y);
3271:       case Event.MOUSE_EXIT:
3272:     return mouseExit (evt, evt.x, evt.y);
3273: 
3274:     // Handle focus events.
3275:       case Event.GOT_FOCUS:
3276:     return gotFocus (evt, evt.arg);
3277:       case Event.LOST_FOCUS:
3278:     return lostFocus (evt, evt.arg);
3279: 
3280:     // Handle action event.
3281:       case Event.ACTION_EVENT:
3282:     return action (evt, evt.arg);
3283:       }
3284:     // Unknown event.
3285:     return false;
3286:   }
3287: 
3288:   /**
3289:    * AWT 1.0 MOUSE_DOWN event handler.  This method is meant to be
3290:    * overridden by components providing their own MOUSE_DOWN handler.
3291:    * The default implementation simply returns false.
3292:    *
3293:    * @param evt the event to handle
3294:    * @param x the x coordinate, ignored
3295:    * @param y the y coordinate, ignored
3296:    * @return false
3297:    * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
3298:    */
3299:   public boolean mouseDown(Event evt, int x, int y)
3300:   {
3301:     return false;
3302:   }
3303: 
3304:   /**
3305:    * AWT 1.0 MOUSE_DRAG event handler.  This method is meant to be
3306:    * overridden by components providing their own MOUSE_DRAG handler.
3307:    * The default implementation simply returns false.
3308:    *
3309:    * @param evt the event to handle
3310:    * @param x the x coordinate, ignored
3311:    * @param y the y coordinate, ignored
3312:    * @return false
3313:    * @deprecated use {@link #processMouseMotionEvent(MouseEvent)} instead
3314:    */
3315:   public boolean mouseDrag(Event evt, int x, int y)
3316:   {
3317:     return false;
3318:   }
3319: 
3320:   /**
3321:    * AWT 1.0 MOUSE_UP event handler.  This method is meant to be
3322:    * overridden by components providing their own MOUSE_UP handler.
3323:    * The default implementation simply returns false.
3324:    *
3325:    * @param evt the event to handle
3326:    * @param x the x coordinate, ignored
3327:    * @param y the y coordinate, ignored
3328:    * @return false
3329:    * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
3330:    */
3331:   public boolean mouseUp(Event evt, int x, int y)
3332:   {
3333:     return false;
3334:   }
3335: 
3336:   /**
3337:    * AWT 1.0 MOUSE_MOVE event handler.  This method is meant to be
3338:    * overridden by components providing their own MOUSE_MOVE handler.
3339:    * The default implementation simply returns false.
3340:    *
3341:    * @param evt the event to handle
3342:    * @param x the x coordinate, ignored
3343:    * @param y the y coordinate, ignored
3344:    * @return false
3345:    * @deprecated use {@link #processMouseMotionEvent(MouseEvent)} instead
3346:    */
3347:   public boolean mouseMove(Event evt, int x, int y)
3348:   {
3349:     return false;
3350:   }
3351: 
3352:   /**
3353:    * AWT 1.0 MOUSE_ENTER event handler.  This method is meant to be
3354:    * overridden by components providing their own MOUSE_ENTER handler.
3355:    * The default implementation simply returns false.
3356:    *
3357:    * @param evt the event to handle
3358:    * @param x the x coordinate, ignored
3359:    * @param y the y coordinate, ignored
3360:    * @return false
3361:    * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
3362:    */
3363:   public boolean mouseEnter(Event evt, int x, int y)
3364:   {
3365:     return false;
3366:   }
3367: 
3368:   /**
3369:    * AWT 1.0 MOUSE_EXIT event handler.  This method is meant to be
3370:    * overridden by components providing their own MOUSE_EXIT handler.
3371:    * The default implementation simply returns false.
3372:    *
3373:    * @param evt the event to handle
3374:    * @param x the x coordinate, ignored
3375:    * @param y the y coordinate, ignored
3376:    * @return false
3377:    * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
3378:    */
3379:   public boolean mouseExit(Event evt, int x, int y)
3380:   {
3381:     return false;
3382:   }
3383: 
3384:   /**
3385:    * AWT 1.0 KEY_PRESS and KEY_ACTION event handler.  This method is
3386:    * meant to be overridden by components providing their own key
3387:    * press handler.  The default implementation simply returns false.
3388:    *
3389:    * @param evt the event to handle
3390:    * @param key the key pressed, ignored
3391:    * @return false
3392:    * @deprecated use {@link #processKeyEvent(KeyEvent)} instead
3393:    */
3394:   public boolean keyDown(Event evt, int key)
3395:   {
3396:     return false;
3397:   }
3398: 
3399:   /**
3400:    * AWT 1.0 KEY_RELEASE and KEY_ACTION_RELEASE event handler.  This
3401:    * method is meant to be overridden by components providing their
3402:    * own key release handler.  The default implementation simply
3403:    * returns false.
3404:    *
3405:    * @param evt the event to handle
3406:    * @param key the key pressed, ignored
3407:    * @return false
3408:    * @deprecated use {@link #processKeyEvent(KeyEvent)} instead
3409:    */
3410:   public boolean keyUp(Event evt, int key)
3411:   {
3412:     return false;
3413:   }
3414: 
3415:   /**
3416:    * AWT 1.0 ACTION_EVENT event handler.  This method is meant to be
3417:    * overridden by components providing their own action event
3418:    * handler.  The default implementation simply returns false.
3419:    *
3420:    * @param evt the event to handle
3421:    * @param what the object acted on, ignored
3422:    * @return false
3423:    * @deprecated in classes which support actions, use
3424:    *             <code>processActionEvent(ActionEvent)</code> instead
3425:    */
3426:   public boolean action(Event evt, Object what)
3427:   {
3428:     return false;
3429:   }
3430: 
3431:   /**
3432:    * Called when the parent of this Component is made visible or when
3433:    * the Component is added to an already visible Container and needs
3434:    * to be shown.  A native peer - if any - is created at this
3435:    * time. This method is called automatically by the AWT system and
3436:    * should not be called by user level code.
3437:    *
3438:    * @see #isDisplayable()
3439:    * @see #removeNotify()
3440:    */
3441:   public void addNotify()
3442:   {
3443:     if (peer == null)
3444:       peer = getToolkit().createComponent(this);
3445:     else if (parent != null && parent.isLightweight())
3446:       new HeavyweightInLightweightListener(parent);
3447:     /* Now that all the children has gotten their peers, we should
3448:        have the event mask needed for this component and its
3449:        lightweight subcomponents. */
3450:     peer.setEventMask(eventMask);
3451:     /* We do not invalidate here, but rather leave that job up to
3452:        the peer. For efficiency, the peer can choose not to
3453:        invalidate if it is happy with the current dimensions,
3454:        etc. */
3455:   }
3456: 
3457:   /**
3458:    * Called to inform this component is has been removed from its
3459:    * container. Its native peer - if any - is destroyed at this time.
3460:    * This method is called automatically by the AWT system and should
3461:    * not be called by user level code.
3462:    *
3463:    * @see #isDisplayable()
3464:    * @see #addNotify()
3465:    */
3466:   public void removeNotify()
3467:   {
3468:     // We null our peer field before disposing of it, such that if we're
3469:     // not the event dispatch thread and the dispatch thread is awoken by
3470:     // the dispose call, there will be no race checking the peer's null
3471:     // status.
3472: 
3473:     ComponentPeer tmp = peer;
3474:     peer = null;
3475:     if (tmp != null)
3476:       {
3477:         tmp.hide();
3478:         tmp.dispose();
3479:       }
3480:   }
3481: 
3482:   /**
3483:    * AWT 1.0 GOT_FOCUS event handler.  This method is meant to be
3484:    * overridden by components providing their own GOT_FOCUS handler.
3485:    * The default implementation simply returns false.
3486:    *
3487:    * @param evt the event to handle
3488:    * @param what the Object focused, ignored
3489:    * @return false
3490:    * @deprecated use {@link #processFocusEvent(FocusEvent)} instead
3491:    */
3492:   public boolean gotFocus(Event evt, Object what)
3493:   {
3494:     return false;
3495:   }
3496: 
3497:   /**
3498:    * AWT 1.0 LOST_FOCUS event handler.  This method is meant to be
3499:    * overridden by components providing their own LOST_FOCUS handler.
3500:    * The default implementation simply returns false.
3501:    *
3502:    * @param evt the event to handle
3503:    * @param what the Object focused, ignored
3504:    * @return false
3505:    * @deprecated use {@link #processFocusEvent(FocusEvent)} instead
3506:    */
3507:   public boolean lostFocus(Event evt, Object what)
3508:   {
3509:     return false;
3510:   }
3511: 
3512:   /**
3513:    * Tests whether or not this component is in the group that can be
3514:    * traversed using the keyboard traversal mechanism (such as the TAB key).
3515:    *
3516:    * @return true if the component is traversed via the TAB key
3517:    * @see #setFocusable(boolean)
3518:    * @since 1.1
3519:    * @deprecated use {@link #isFocusable()} instead
3520:    */
3521:   public boolean isFocusTraversable()
3522:   {
3523:     return enabled && visible && (peer == null || isLightweight() || peer.isFocusTraversable());
3524:   }
3525: 
3526:   /**
3527:    * Tests if this component can receive focus.
3528:    *
3529:    * @return true if this component can receive focus
3530:    * @since 1.4
3531:    */
3532:   public boolean isFocusable()
3533:   {
3534:     return focusable;
3535:   }
3536: 
3537:   /**
3538:    * Specify whether this component can receive focus. This method also
3539:    * sets the {@link #isFocusTraversableOverridden} field to 1, which
3540:    * appears to be the undocumented way {@link
3541:    * DefaultFocusTraversalPolicy#accept(Component)} determines whether to
3542:    * respect the {@link #isFocusable()} method of the component.
3543:    *
3544:    * @param focusable the new focusable status
3545:    * @since 1.4
3546:    */
3547:   public void setFocusable(boolean focusable)
3548:   {
3549:     firePropertyChange("focusable", this.focusable, focusable);
3550:     this.focusable = focusable;
3551:     this.isFocusTraversableOverridden = 1;
3552:   }
3553: 
3554:   /**
3555:    * Sets the focus traversal keys for one of the three focus
3556:    * traversal directions supported by Components:
3557:    * {@link KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS},
3558:    * {@link KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS}, or
3559:    * {@link KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS}. Normally, the
3560:    * default values should match the operating system's native
3561:    * choices. To disable a given traversal, use
3562:    * <code>Collections.EMPTY_SET</code>. The event dispatcher will
3563:    * consume PRESSED, RELEASED, and TYPED events for the specified
3564:    * key, although focus can only transfer on PRESSED or RELEASED.
3565:    *
3566:    * <p>The defaults are:
3567:    * <table>
3568:    *   <th><td>Identifier</td><td>Meaning</td><td>Default</td></th>
3569:    *   <tr><td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</td>
3570:    *     <td>Normal forward traversal</td>
3571:    *     <td>TAB on KEY_PRESSED, Ctrl-TAB on KEY_PRESSED</td></tr>
3572:    *   <tr><td>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</td>
3573:    *     <td>Normal backward traversal</td>
3574:    *     <td>Shift-TAB on KEY_PRESSED, Ctrl-Shift-TAB on KEY_PRESSED</td></tr>
3575:    *   <tr><td>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</td>
3576:    *     <td>Go up a traversal cycle</td><td>None</td></tr>
3577:    * </table>
3578:    *
3579:    * If keystrokes is null, this component's focus traversal key set
3580:    * is inherited from one of its ancestors.  If none of its ancestors
3581:    * has its own set of focus traversal keys, the focus traversal keys
3582:    * are set to the defaults retrieved from the current
3583:    * KeyboardFocusManager.  If not null, the set must contain only
3584:    * AWTKeyStrokes that are not already focus keys and are not
3585:    * KEY_TYPED events.
3586:    *
3587:    * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS, or
3588:    *        UP_CYCLE_TRAVERSAL_KEYS
3589:    * @param keystrokes a set of keys, or null
3590:    * @throws IllegalArgumentException if id or keystrokes is invalid
3591:    * @see #getFocusTraversalKeys(int)
3592:    * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
3593:    * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
3594:    * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
3595:    * @since 1.4
3596:    */
3597:   public void setFocusTraversalKeys(int id, Set keystrokes)
3598:   {
3599:     if (keystrokes == null)
3600:       {
3601:         Container parent = getParent ();
3602: 
3603:         while (parent != null)
3604:           {
3605:             if (parent.areFocusTraversalKeysSet (id))
3606:               {
3607:                 keystrokes = parent.getFocusTraversalKeys (id);
3608:                 break;
3609:               }
3610:             parent = parent.getParent ();
3611:           }
3612: 
3613:         if (keystrokes == null)
3614:           keystrokes = KeyboardFocusManager.getCurrentKeyboardFocusManager ().
3615:             getDefaultFocusTraversalKeys (id);
3616:       }
3617: 
3618:     Set sa;
3619:     Set sb;
3620:     String name;
3621:     switch (id)
3622:       {
3623:       case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS:
3624:         sa = getFocusTraversalKeys
3625:           (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
3626:         sb = getFocusTraversalKeys
3627:           (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
3628:         name = "forwardFocusTraversalKeys";
3629:         break;
3630:       case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS:
3631:         sa = getFocusTraversalKeys
3632:           (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
3633:         sb = getFocusTraversalKeys
3634:           (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
3635:         name = "backwardFocusTraversalKeys";
3636:         break;
3637:       case KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS:
3638:         sa = getFocusTraversalKeys
3639:           (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
3640:         sb = getFocusTraversalKeys
3641:           (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
3642:         name = "upCycleFocusTraversalKeys";
3643:         break;
3644:       default:
3645:         throw new IllegalArgumentException ();
3646:       }
3647: 
3648:     int i = keystrokes.size ();
3649:     Iterator iter = keystrokes.iterator ();
3650: 
3651:     while (--i >= 0)
3652:       {
3653:         Object o = iter.next ();
3654:         if (!(o instanceof AWTKeyStroke)
3655:             || sa.contains (o) || sb.contains (o)
3656:             || ((AWTKeyStroke) o).keyCode == KeyEvent.VK_UNDEFINED)
3657:           throw new IllegalArgumentException ();
3658:       }
3659: 
3660:     if (focusTraversalKeys == null)
3661:       focusTraversalKeys = new Set[3];
3662: 
3663:     keystrokes = Collections.unmodifiableSet (new HashSet (keystrokes));
3664:     firePropertyChange (name, focusTraversalKeys[id], keystrokes);
3665: 
3666:     focusTraversalKeys[id] = keystrokes;
3667:   }
3668: 
3669:   /**
3670:    * Returns the set of keys for a given focus traversal action, as
3671:    * defined in <code>setFocusTraversalKeys</code>.  If not set, this
3672:    * is inherited from the parent component, which may have gotten it
3673:    * from the KeyboardFocusManager.
3674:    *
3675:    * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS,
3676:    * or UP_CYCLE_TRAVERSAL_KEYS
3677:    *
3678:    * @return set of traversal keys
3679:    *
3680:    * @throws IllegalArgumentException if id is invalid
3681:    * 
3682:    * @see #setFocusTraversalKeys (int, Set)
3683:    * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
3684:    * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
3685:    * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
3686:    * 
3687:    * @since 1.4
3688:    */
3689:   public Set getFocusTraversalKeys (int id)
3690:   {
3691:     if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
3692:         id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
3693:         id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS)
3694:       throw new IllegalArgumentException();
3695: 
3696:     Set s = null;
3697: 
3698:     if (focusTraversalKeys != null)
3699:       s = focusTraversalKeys[id];
3700: 
3701:     if (s == null && parent != null)
3702:       s = parent.getFocusTraversalKeys (id);
3703: 
3704:     return s == null ? (KeyboardFocusManager.getCurrentKeyboardFocusManager()
3705:                         .getDefaultFocusTraversalKeys(id)) : s;
3706:   }
3707: 
3708:   /**
3709:    * Tests whether the focus traversal keys for a given action are explicitly
3710:    * set or inherited.
3711:    *
3712:    * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS,
3713:    * or UP_CYCLE_TRAVERSAL_KEYS
3714:    * @return true if that set is explicitly specified
3715:    * @throws IllegalArgumentException if id is invalid
3716:    * @see #getFocusTraversalKeys (int)
3717:    * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
3718:    * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
3719:    * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
3720:    * @since 1.4
3721:    */
3722:   public boolean areFocusTraversalKeysSet (int id)
3723:   {
3724:     if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
3725:         id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
3726:         id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS)
3727:       throw new IllegalArgumentException ();
3728: 
3729:     return focusTraversalKeys != null && focusTraversalKeys[id] != null;
3730:   }
3731: 
3732:   /**
3733:    * Enable or disable focus traversal keys on this Component.  If
3734:    * they are, then the keyboard focus manager consumes and acts on
3735:    * key press and release events that trigger focus traversal, and
3736:    * discards the corresponding key typed events.  If focus traversal
3737:    * keys are disabled, then all key events that would otherwise
3738:    * trigger focus traversal are sent to this Component.
3739:    *
3740:    * @param focusTraversalKeysEnabled the new value of the flag
3741:    * @see #getFocusTraversalKeysEnabled ()
3742:    * @see #setFocusTraversalKeys (int, Set)
3743:    * @see #getFocusTraversalKeys (int)
3744:    * @since 1.4
3745:    */
3746:   public void setFocusTraversalKeysEnabled (boolean focusTraversalKeysEnabled)
3747:   {
3748:     firePropertyChange ("focusTraversalKeysEnabled",
3749:             this.focusTraversalKeysEnabled,
3750:             focusTraversalKeysEnabled);
3751:     this.focusTraversalKeysEnabled = focusTraversalKeysEnabled;
3752:   }
3753: 
3754:   /**
3755:    * Check whether or not focus traversal keys are enabled on this
3756:    * Component.  If they are, then the keyboard focus manager consumes
3757:    * and acts on key press and release events that trigger focus
3758:    * traversal, and discards the corresponding key typed events.  If
3759:    * focus traversal keys are disabled, then all key events that would
3760:    * otherwise trigger focus traversal are sent to this Component.
3761:    *
3762:    * @return true if focus traversal keys are enabled
3763:    * @see #setFocusTraversalKeysEnabled (boolean)
3764:    * @see #setFocusTraversalKeys (int, Set)
3765:    * @see #getFocusTraversalKeys (int)
3766:    * @since 1.4
3767:    */
3768:   public boolean getFocusTraversalKeysEnabled ()
3769:   {
3770:     return focusTraversalKeysEnabled;
3771:   }
3772: 
3773:   /**
3774:    * Request that this Component be given the keyboard input focus and
3775:    * that its top-level ancestor become the focused Window.
3776:    *
3777:    * For the request to be granted, the Component must be focusable,
3778:    * displayable and showing and the top-level Window to which it
3779:    * belongs must be focusable.  If the request is initially denied on
3780:    * the basis that the top-level Window is not focusable, the request
3781:    * will be remembered and granted when the Window does become
3782:    * focused.
3783:    *
3784:    * Never assume that this Component is the focus owner until it
3785:    * receives a FOCUS_GAINED event.
3786:    *
3787:    * The behaviour of this method is platform-dependent.
3788:    * {@link #requestFocusInWindow()} should be used instead.
3789:    *
3790:    * @see #requestFocusInWindow ()
3791:    * @see FocusEvent
3792:    * @see #addFocusListener (FocusListener)
3793:    * @see #isFocusable ()
3794:    * @see #isDisplayable ()
3795:    * @see KeyboardFocusManager#clearGlobalFocusOwner ()
3796:    */
3797:   public void requestFocus ()
3798:   {
3799:     if (isDisplayable ()
3800:     && isShowing ()
3801:     && isFocusable ())
3802:       {
3803:         synchronized (getTreeLock ())
3804:           {
3805:             // Find this Component's top-level ancestor.            
3806:             Container parent = (this instanceof Container) ? (Container) this
3807:                                                           : getParent();            
3808:             while (parent != null
3809:                    && !(parent instanceof Window))
3810:               parent = parent.getParent ();
3811: 
3812:             if (parent == null)
3813:               return;
3814:             
3815:             Window toplevel = (Window) parent;
3816:             if (toplevel.isFocusableWindow ())
3817:               {
3818:                 if (peer != null && !isLightweight())
3819:                   // This call will cause a FOCUS_GAINED event to be
3820:                   // posted to the system event queue if the native
3821:                   // windowing system grants the focus request.
3822:                   peer.requestFocus ();
3823:                 else
3824:                   {
3825:                     // Either our peer hasn't been created yet or we're a
3826:                     // lightweight component.  In either case we want to
3827:                     // post a FOCUS_GAINED event.
3828:                     EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
3829:                     synchronized (eq)
3830:                       {
3831:                         KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
3832:                         Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
3833:                         if (currentFocusOwner != null)
3834:                           {
3835:                             eq.postEvent (new FocusEvent(currentFocusOwner, FocusEvent.FOCUS_LOST,
3836:                                                          false, this));
3837:                             eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, false,
3838:                                                          currentFocusOwner));
3839:                           }
3840:                         else
3841:                           eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, false));
3842:                       }
3843:                   }
3844:               }
3845:             else
3846:               pendingFocusRequest = new FocusEvent(this, FocusEvent.FOCUS_GAINED);
3847:           }
3848:       }
3849:   }
3850: 
3851:   /**
3852:    * Request that this Component be given the keyboard input focus and
3853:    * that its top-level ancestor become the focused Window.
3854:    *
3855:    * For the request to be granted, the Component must be focusable,
3856:    * displayable and showing and the top-level Window to which it
3857:    * belongs must be focusable.  If the request is initially denied on
3858:    * the basis that the top-level Window is not focusable, the request
3859:    * will be remembered and granted when the Window does become
3860:    * focused.
3861:    *
3862:    * Never assume that this Component is the focus owner until it
3863:    * receives a FOCUS_GAINED event.
3864:    *
3865:    * The behaviour of this method is platform-dependent.
3866:    * {@link #requestFocusInWindow()} should be used instead.
3867:    *
3868:    * If the return value is false, the request is guaranteed to fail.
3869:    * If the return value is true, the request will succeed unless it
3870:    * is vetoed or something in the native windowing system intervenes,
3871:    * preventing this Component's top-level ancestor from becoming
3872:    * focused.  This method is meant to be called by derived
3873:    * lightweight Components that want to avoid unnecessary repainting
3874:    * when they know a given focus transfer need only be temporary.
3875:    *
3876:    * @param temporary true if the focus request is temporary
3877:    * @return true if the request has a chance of success
3878:    * @see #requestFocusInWindow ()
3879:    * @see FocusEvent
3880:    * @see #addFocusListener (FocusListener)
3881:    * @see #isFocusable ()
3882:    * @see #isDisplayable ()
3883:    * @see KeyboardFocusManager#clearGlobalFocusOwner ()
3884:    * @since 1.4
3885:    */
3886:   protected boolean requestFocus (boolean temporary)
3887:   {
3888:     if (isDisplayable ()
3889:     && isShowing ()
3890:     && isFocusable ())
3891:       {
3892:         synchronized (getTreeLock ())
3893:           {
3894:             // Find this Component's top-level ancestor.
3895:             Container parent = getParent ();
3896: 
3897:             while (parent != null
3898:                    && !(parent instanceof Window))
3899:               parent = parent.getParent ();
3900: 
3901:             Window toplevel = (Window) parent;
3902:             if (toplevel.isFocusableWindow ())
3903:               {
3904:                 if (peer != null && !isLightweight())
3905:                   // This call will cause a FOCUS_GAINED event to be
3906:                   // posted to the system event queue if the native
3907:                   // windowing system grants the focus request.
3908:                   peer.requestFocus ();
3909:                 else
3910:                   {
3911:                     // Either our peer hasn't been created yet or we're a
3912:                     // lightweight component.  In either case we want to
3913:                     // post a FOCUS_GAINED event.
3914:                     EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
3915:                     synchronized (eq)
3916:                       {
3917:                         KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
3918:                         Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
3919:                         if (currentFocusOwner != null)
3920:                           {
3921:                             eq.postEvent (new FocusEvent(currentFocusOwner,
3922:                                                          FocusEvent.FOCUS_LOST,
3923:                                                          temporary, this));
3924:                             eq.postEvent (new FocusEvent(this,
3925:                                                          FocusEvent.FOCUS_GAINED,
3926:                                                          temporary,
3927:                                                          currentFocusOwner));
3928:                           }
3929:                         else
3930:                           eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary));
3931:                       }
3932:                   }
3933:               }
3934:             else
3935:               // FIXME: need to add a focus listener to our top-level
3936:               // ancestor, so that we can post this event when it becomes
3937:               // the focused window.
3938:               pendingFocusRequest = new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary);
3939:           }
3940:       }
3941:     // Always return true.
3942:     return true;
3943:   }
3944: 
3945:   /**
3946:    * Request that this component be given the keyboard input focus, if
3947:    * its top-level ancestor is the currently focused Window.  A
3948:    * <code>FOCUS_GAINED</code> event will be fired if and only if this
3949:    * request is successful. To be successful, the component must be
3950:    * displayable, showing, and focusable, and its ancestor top-level
3951:    * Window must be focused.
3952:    *
3953:    * If the return value is false, the request is guaranteed to fail.
3954:    * If the return value is true, the request will succeed unless it
3955:    * is vetoed or something in the native windowing system intervenes,
3956:    * preventing this Component's top-level ancestor from becoming
3957:    * focused.
3958:    *
3959:    * @return true if the request has a chance of success
3960:    * @see #requestFocus ()
3961:    * @see FocusEvent
3962:    * @see #addFocusListener (FocusListener)
3963:    * @see #isFocusable ()
3964:    * @see #isDisplayable ()
3965:    * @see KeyboardFocusManager#clearGlobalFocusOwner ()
3966:    * @since 1.4
3967:    */
3968:   public boolean requestFocusInWindow ()
3969:   {
3970:     return requestFocusInWindow (false);
3971:   }
3972: 
3973:   /**
3974:    * Request that this component be given the keyboard input focus, if
3975:    * its top-level ancestor is the currently focused Window.  A
3976:    * <code>FOCUS_GAINED</code> event will be fired if and only if this
3977:    * request is successful. To be successful, the component must be
3978:    * displayable, showing, and focusable, and its ancestor top-level
3979:    * Window must be focused.
3980:    *
3981:    * If the return value is false, the request is guaranteed to fail.
3982:    * If the return value is true, the request will succeed unless it
3983:    * is vetoed or something in the native windowing system intervenes,
3984:    * preventing this Component's top-level ancestor from becoming
3985:    * focused.  This method is meant to be called by derived
3986:    * lightweight Components that want to avoid unnecessary repainting
3987:    * when they know a given focus transfer need only be temporary.
3988:    *
3989:    * @param temporary true if the focus request is temporary
3990:    * @return true if the request has a chance of success
3991:    * @see #requestFocus ()
3992:    * @see FocusEvent
3993:    * @see #addFocusListener (FocusListener)
3994:    * @see #isFocusable ()
3995:    * @see #isDisplayable ()
3996:    * @see KeyboardFocusManager#clearGlobalFocusOwner ()
3997:    * @since 1.4
3998:    */
3999:   protected boolean requestFocusInWindow (boolean temporary)
4000:   {
4001:     KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
4002: 
4003:     Window focusedWindow = manager.getFocusedWindow ();
4004: 
4005:     if (isDisplayable ()
4006:     && isShowing ()
4007:     && isFocusable ())
4008:       {
4009:         if (focusedWindow != null)
4010:           {
4011:             synchronized (getTreeLock ())
4012:               {
4013:                 Container parent = getParent ();
4014: 
4015:                 while (parent != null
4016:                        && !(parent instanceof Window))
4017:                   parent = parent.getParent ();
4018: 
4019:                 Window toplevel = (Window) parent;
4020: 
4021:                 // Check if top-level ancestor is currently focused window.
4022:                 if (focusedWindow == toplevel)
4023:                   {
4024:                     if (peer != null
4025:                         && !isLightweight()
4026:                         && !(this instanceof Window))
4027:                       // This call will cause a FOCUS_GAINED event to be
4028:                       // posted to the system event queue if the native
4029:                       // windowing system grants the focus request.
4030:                       peer.requestFocus ();
4031:                     else
4032:                       {
4033:                         // Either our peer hasn't been created yet or we're a
4034:                         // lightweight component.  In either case we want to
4035:                         // post a FOCUS_GAINED event.
4036:                         EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
4037:                         synchronized (eq)
4038:                           {
4039:                             Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
4040:                             if (currentFocusOwner != null)
4041:                               {
4042:                                 eq.postEvent (new FocusEvent(currentFocusOwner, FocusEvent.FOCUS_LOST,
4043:                                                              temporary, this));
4044:                                 eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary,
4045:                                                              currentFocusOwner));
4046:                               }
4047:                             else
4048:                               eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary));
4049:                           }
4050:                       }
4051:                   }
4052:                 else
4053:                   return false;
4054:               }
4055:           }
4056: 
4057:         return true;
4058:       }
4059:     return false;
4060:   }
4061: 
4062:   /**
4063:    * Transfers focus to the next component in the focus traversal
4064:    * order, as though this were the current focus owner.
4065:    *
4066:    * @see #requestFocus()
4067:    * @since 1.1
4068:    */
4069:   public void transferFocus ()
4070:   {
4071:     nextFocus ();
4072:   }
4073: 
4074:   /**
4075:    * Returns the root container that owns the focus cycle where this
4076:    * component resides. A focus cycle root is in two cycles, one as
4077:    * the ancestor, and one as the focusable element; this call always
4078:    * returns the ancestor.
4079:    *
4080:    * @return the ancestor container that owns the focus cycle
4081:    * @since 1.4
4082:    */
4083:   public Container getFocusCycleRootAncestor ()
4084:   {
4085:     Container parent = getParent ();
4086: 
4087:     while (parent != null && !parent.isFocusCycleRoot())
4088:       parent = parent.getParent ();
4089: 
4090:     return parent;
4091:   }
4092: 
4093:   /**
4094:    * Tests if the container is the ancestor of the focus cycle that
4095:    * this component belongs to.
4096:    *
4097:    * @param c the container to test
4098:    * @return true if c is the focus cycle root
4099:    * @since 1.4
4100:    */
4101:   public boolean isFocusCycleRoot (Container c)
4102:   {
4103:     return c == getFocusCycleRootAncestor ();
4104:   }
4105: 
4106:   /**
4107:    * AWT 1.0 focus event processor.  Transfers focus to the next
4108:    * component in the focus traversal order, as though this were the
4109:    * current focus owner.
4110:    *
4111:    * @deprecated use {@link #transferFocus ()} instead
4112:    */
4113:   public void nextFocus ()
4114:   {
4115:     // Find the nearest valid (== showing && focusable && enabled) focus
4116:     // cycle root ancestor and the focused component in it.
4117:     Container focusRoot = getFocusCycleRootAncestor();
4118:     Component focusComp = this;
4119:     while (focusRoot != null
4120:            && ! (focusRoot.isShowing() && focusRoot.isFocusable()
4121:                  && focusRoot.isEnabled()))
4122:       {
4123:         focusComp = focusRoot;
4124:         focusRoot = focusComp.getFocusCycleRootAncestor();
4125:       }
4126: 
4127:     if (focusRoot != null)
4128:       {
4129:         // First try to get the componentBefore from the policy.
4130:         FocusTraversalPolicy policy = focusRoot.getFocusTraversalPolicy();
4131:         Component nextFocus = policy.getComponentAfter(focusRoot, focusComp);
4132: 
4133:         // If this fails, then ask for the defaultComponent.
4134:         if (nextFocus == null)
4135:           nextFocus = policy.getDefaultComponent(focusRoot);
4136: 
4137:         // Request focus on this component, if not null.
4138:         if (nextFocus != null)
4139:           nextFocus.requestFocus();
4140:       }
4141:   }
4142: 
4143:   /**
4144:    * Transfers focus to the previous component in the focus traversal
4145:    * order, as though this were the current focus owner.
4146:    *
4147:    * @see #requestFocus ()
4148:    * @since 1.4
4149:    */
4150:   public void transferFocusBackward ()
4151:   {
4152:     // Find the nearest valid (== showing && focusable && enabled) focus
4153:     // cycle root ancestor and the focused component in it.
4154:     Container focusRoot = getFocusCycleRootAncestor();
4155:     Component focusComp = this;
4156:     while (focusRoot != null
4157:            && ! (focusRoot.isShowing() && focusRoot.isFocusable()
4158:                  && focusRoot.isEnabled()))
4159:       {
4160:         focusComp = focusRoot;
4161:         focusRoot = focusComp.getFocusCycleRootAncestor();
4162:       }
4163: 
4164:     if (focusRoot != null)
4165:       {
4166:         // First try to get the componentBefore from the policy.
4167:         FocusTraversalPolicy policy = focusRoot.getFocusTraversalPolicy();
4168:         Component nextFocus = policy.getComponentBefore(focusRoot, focusComp);
4169: 
4170:         // If this fails, then ask for the defaultComponent.
4171:         if (nextFocus == null)
4172:           nextFocus = policy.getDefaultComponent(focusRoot);
4173: 
4174:         // Request focus on this component, if not null.
4175:         if (nextFocus != null)
4176:           nextFocus.requestFocus();
4177:       }
4178:   }
4179: 
4180:   /**
4181:    * Transfers focus to the focus cycle root of this component.
4182:    * However, if this is a Window, the default focus owner in the
4183:    * window in the current focus cycle is focused instead.
4184:    *
4185:    * @see #requestFocus()
4186:    * @see #isFocusCycleRoot(Container)
4187:    * @since 1.4
4188:    */
4189:   public void transferFocusUpCycle ()
4190:   {
4191:     // Find the nearest focus cycle root ancestor that is itself
4192:     // focusable, showing and enabled.
4193:     Container focusCycleRoot = getFocusCycleRootAncestor();
4194:     while (focusCycleRoot != null &&
4195:            ! (focusCycleRoot.isShowing() && focusCycleRoot.isFocusable()
4196:               && focusCycleRoot.isEnabled()))
4197:       {
4198:         focusCycleRoot = focusCycleRoot.getFocusCycleRootAncestor();
4199:       }
4200: 
4201:     KeyboardFocusManager fm =
4202:       KeyboardFocusManager.getCurrentKeyboardFocusManager();
4203: 
4204:     if (focusCycleRoot != null)
4205:       {
4206:         // If we found a focus cycle root, then we make this the new
4207:         // focused component, and make it's focus cycle root the new
4208:         // global focus cycle root. If the found root has no focus cycle
4209:         // root ancestor itself, then the component will be both the focused
4210:         // component and the new global focus cycle root.
4211:         Container focusCycleAncestor =
4212:           focusCycleRoot.getFocusCycleRootAncestor();
4213:         Container globalFocusCycleRoot;
4214:         if (focusCycleAncestor == null)
4215:           globalFocusCycleRoot = focusCycleRoot;
4216:         else
4217:           globalFocusCycleRoot = focusCycleAncestor;
4218: 
4219:         fm.setGlobalCurrentFocusCycleRoot(globalFocusCycleRoot);
4220:         focusCycleRoot.requestFocus();
4221:       }
4222:     else
4223:       {
4224:         // If this component has no applicable focus cycle root, we try
4225:         // find the nearest window and set this as the new global focus cycle
4226:         // root and the default focus component of this window the new focused
4227:         // component.
4228:         Container cont;
4229:         if (this instanceof Container)
4230:           cont = (Container) this;
4231:         else
4232:           cont = getParent();
4233: 
4234:         while (cont != null && !(cont instanceof Window))
4235:           cont = cont.getParent();
4236: 
4237:         if (cont != null)
4238:           {
4239:             FocusTraversalPolicy policy = cont.getFocusTraversalPolicy();
4240:             Component focusComp = policy.getDefaultComponent(cont);
4241:             if (focusComp != null)
4242:               {
4243:                 fm.setGlobalCurrentFocusCycleRoot(cont);
4244:                 focusComp.requestFocus();
4245:               }
4246:           }
4247:       }
4248:   }
4249: 
4250:   /**
4251:    * Tests if this component is the focus owner. Use {@link
4252:    * #isFocusOwner ()} instead.
4253:    *
4254:    * @return true if this component owns focus
4255:    * @since 1.2
4256:    */
4257:   public boolean hasFocus ()
4258:   {
4259:     KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
4260: 
4261:     Component focusOwner = manager.getFocusOwner ();
4262: 
4263:     return this == focusOwner;
4264:   }
4265: 
4266:   /**
4267:    * Tests if this component is the focus owner.
4268:    *
4269:    * @return true if this component owns focus
4270:    * @since 1.4
4271:    */
4272:   public boolean isFocusOwner()
4273:   {
4274:     return hasFocus ();
4275:   }
4276: 
4277:   /**
4278:    * Adds the specified popup menu to this component.
4279:    *
4280:    * @param popup the popup menu to be added
4281:    * 
4282:    * @see #remove(MenuComponent)
4283:    * 
4284:    * @since 1.1
4285:    */
4286:   public synchronized void add(PopupMenu popup)
4287:   {
4288:     if (popups == null)
4289:       popups = new Vector();
4290:     popups.add(popup);
4291: 
4292:     if (popup.parent != null)
4293:       popup.parent.remove(popup);
4294:     popup.parent = this;
4295:     if (peer != null)
4296:       popup.addNotify();
4297:   }
4298: 
4299:   /**
4300:    * Removes the specified popup menu from this component.
4301:    *
4302:    * @param popup the popup menu to remove
4303:    * @see #add(PopupMenu)
4304:    * @since 1.1
4305:    */
4306:   public synchronized void remove(MenuComponent popup)
4307:   {
4308:     if (popups != null)
4309:       popups.remove(popup);
4310:   }
4311: 
4312:   /**
4313:    * Returns a debugging string representing this component. The string may
4314:    * be empty but not null.
4315:    *
4316:    * @return a string representing this component
4317:    */
4318:   protected String paramString()
4319:   {
4320:     StringBuffer param = new StringBuffer();
4321:     String name = getName();
4322:     if (name != null)
4323:       param.append(name).append(",");
4324:     param.append(x).append(",").append(y).append(",").append(width)
4325:       .append("x").append(height);
4326:     if (! isValid())
4327:       param.append(",invalid");
4328:     if (! isVisible())
4329:       param.append(",invisible");
4330:     if (! isEnabled())
4331:       param.append(",disabled");
4332:     if (! isOpaque())
4333:       param.append(",translucent");
4334:     if (isDoubleBuffered())
4335:       param.append(",doublebuffered");
4336:     if (parent == null)
4337:       param.append(",parent=null");
4338:     else
4339:       param.append(",parent=").append(parent.getName());
4340:     return param.toString();
4341:   }
4342: 
4343:   /**
4344:    * Returns a string representation of this component. This is implemented
4345:    * as <code>getClass().getName() + '[' + paramString() + ']'</code>.
4346:    *
4347:    * @return a string representation of this component
4348:    */
4349:   public String toString()
4350:   {
4351:     return getClass().getName() + '[' + paramString() + ']';
4352:   }
4353: 
4354:   /**
4355:    * Prints a listing of this component to <code>System.out</code>.
4356:    *
4357:    * @see #list(PrintStream)
4358:    */
4359:   public void list()
4360:   {
4361:     list(System.out, 0);
4362:   }
4363: 
4364:   /**
4365:    * Prints a listing of this component to the specified print stream.
4366:    *
4367:    * @param out the <code>PrintStream</code> to print to
4368:    */
4369:   public void list(PrintStream out)
4370:   {
4371:     list(out, 0);
4372:   }
4373: 
4374:   /**
4375:    * Prints a listing of this component to the specified print stream,
4376:    * starting at the specified indentation point.
4377:    *
4378:    * @param out the <code>PrintStream</code> to print to
4379:    * @param indent the indentation point
4380:    */
4381:   public void list(PrintStream out, int indent)
4382:   {
4383:     for (int i = 0; i < indent; ++i)
4384:       out.print(' ');
4385:     out.println(toString());
4386:   }
4387: 
4388:   /**
4389:    * Prints a listing of this component to the specified print writer.
4390:    *
4391:    * @param out the <code>PrintWrinter</code> to print to
4392:    * @since 1.1
4393:    */
4394:   public void list(PrintWriter out)
4395:   {
4396:     list(out, 0);
4397:   }
4398: 
4399:   /**
4400:    * Prints a listing of this component to the specified print writer,
4401:    * starting at the specified indentation point.
4402:    *
4403:    * @param out the <code>PrintWriter</code> to print to
4404:    * @param indent the indentation point
4405:    * @since 1.1
4406:    */
4407:   public void list(PrintWriter out, int indent)
4408:   {
4409:     for (int i = 0; i < indent; ++i)
4410:       out.print(' ');
4411:     out.println(toString());
4412:   }
4413: 
4414:   /**
4415:    * Adds the specified property listener to this component. This is harmless
4416:    * if the listener is null, but if the listener has already been registered,
4417:    * it will now be registered twice. The property listener ignores inherited
4418:    * properties. Recognized properties include:<br>
4419:    * <ul>
4420:    * <li>the font (<code>"font"</code>)</li>
4421:    * <li>the background color (<code>"background"</code>)</li>
4422:    * <li>the foreground color (<code>"foreground"</code>)</li>
4423:    * <li>the focusability (<code>"focusable"</code>)</li>
4424:    * <li>the focus key traversal enabled state
4425:    *     (<code>"focusTraversalKeysEnabled"</code>)</li>
4426:    * <li>the set of forward traversal keys
4427:    *     (<code>"forwardFocusTraversalKeys"</code>)</li>
4428:    * <li>the set of backward traversal keys
4429:    *     (<code>"backwardFocusTraversalKeys"</code>)</li>
4430:    * <li>the set of up-cycle traversal keys
4431:    *     (<code>"upCycleFocusTraversalKeys"</code>)</li>
4432:    * </ul>
4433:    *
4434:    * @param listener the new listener to add
4435:    * @see #removePropertyChangeListener(PropertyChangeListener)
4436:    * @see #getPropertyChangeListeners()
4437:    * @see #addPropertyChangeListener(String, PropertyChangeListener)
4438:    * @since 1.1
4439:    */
4440:   public void addPropertyChangeListener(PropertyChangeListener listener)
4441:   {
4442:     if (changeSupport == null)
4443:       changeSupport = new PropertyChangeSupport(this);
4444:     changeSupport.addPropertyChangeListener(listener);
4445:   }
4446: 
4447:   /**
4448:    * Removes the specified property listener from the component. This is
4449:    * harmless if the listener was not previously registered.
4450:    *
4451:    * @param listener the listener to remove
4452:    * @see #addPropertyChangeListener(PropertyChangeListener)
4453:    * @see #getPropertyChangeListeners()
4454:    * @see #removePropertyChangeListener(String, PropertyChangeListener)
4455:    * @since 1.1
4456:    */
4457:   public void removePropertyChangeListener(PropertyChangeListener listener)
4458:   {
4459:     if (changeSupport != null)
4460:       changeSupport.removePropertyChangeListener(listener);
4461:   }
4462: 
4463:   /**
4464:    * Returns an array of all specified listeners registered on this component.
4465:    *
4466:    * @return an array of listeners
4467:    * @see #addPropertyChangeListener(PropertyChangeListener)
4468:    * @see #removePropertyChangeListener(PropertyChangeListener)
4469:    * @see #getPropertyChangeListeners(String)
4470:    * @since 1.4
4471:    */
4472:   public PropertyChangeListener[] getPropertyChangeListeners()
4473:   {
4474:     return changeSupport == null ? new PropertyChangeListener[0]
4475:       : changeSupport.getPropertyChangeListeners();
4476:   }
4477: 
4478:   /**
4479:    * Adds the specified property listener to this component. This is harmless
4480:    * if the listener is null, but if the listener has already been registered,
4481:    * it will now be registered twice. The property listener ignores inherited
4482:    * properties. The listener is keyed to a single property. Recognized
4483:    * properties include:<br>
4484:    * <ul>
4485:    * <li>the font (<code>"font"</code>)</li>
4486:    * <li>the background color (<code>"background"</code>)</li>
4487:    * <li>the foreground color (<code>"foreground"</code>)</li>
4488:    * <li>the focusability (<code>"focusable"</code>)</li>
4489:    * <li>the focus key traversal enabled state
4490:    *     (<code>"focusTraversalKeysEnabled"</code>)</li>
4491:    * <li>the set of forward traversal keys
4492:    *     (<code>"forwardFocusTraversalKeys"</code>)</li>
4493: p   * <li>the set of backward traversal keys
4494:    *     (<code>"backwardFocusTraversalKeys"</code>)</li>
4495:    * <li>the set of up-cycle traversal keys
4496:    *     (<code>"upCycleFocusTraversalKeys"</code>)</li>
4497:    * </ul>
4498:    *
4499:    * @param propertyName the property name to filter on
4500:    * @param listener the new listener to add
4501:    * @see #removePropertyChangeListener(String, PropertyChangeListener)
4502:    * @see #getPropertyChangeListeners(String)
4503:    * @see #addPropertyChangeListener(PropertyChangeListener)
4504:    * @since 1.1
4505:    */
4506:   public void addPropertyChangeListener(String propertyName,
4507:                                         PropertyChangeListener listener)
4508:   {
4509:     if (changeSupport == null)
4510:       changeSupport = new PropertyChangeSupport(this);
4511:     changeSupport.addPropertyChangeListener(propertyName, listener);
4512:   }
4513: 
4514:   /**
4515:    * Removes the specified property listener on a particular property from
4516:    * the component. This is harmless if the listener was not previously
4517:    * registered.
4518:    *
4519:    * @param propertyName the property name to filter on
4520:    * @param listener the listener to remove
4521:    * @see #addPropertyChangeListener(String, PropertyChangeListener)
4522:    * @see #getPropertyChangeListeners(String)
4523:    * @see #removePropertyChangeListener(PropertyChangeListener)
4524:    * @since 1.1
4525:    */
4526:   public void removePropertyChangeListener(String propertyName,
4527:                                            PropertyChangeListener listener)
4528:   {
4529:     if (changeSupport != null)
4530:       changeSupport.removePropertyChangeListener(propertyName, listener);
4531:   }
4532: 
4533:   /**
4534:    * Returns an array of all specified listeners on the named property that
4535:    * are registered on this component.
4536:    *
4537:    * @return an array of listeners
4538:    * @see #addPropertyChangeListener(String, PropertyChangeListener)
4539:    * @see #removePropertyChangeListener(String, PropertyChangeListener)
4540:    * @see #getPropertyChangeListeners()
4541:    * @since 1.4
4542:    */
4543:   public PropertyChangeListener[] getPropertyChangeListeners(String property)
4544:   {
4545:     return changeSupport == null ? new PropertyChangeListener[0]
4546:       : changeSupport.getPropertyChangeListeners(property);
4547:   }
4548: 
4549:   /**
4550:    * Report a change in a bound property to any registered property listeners.
4551:    *
4552:    * @param propertyName the property that changed
4553:    * @param oldValue the old property value
4554:    * @param newValue the new property value
4555:    */
4556:   protected void firePropertyChange(String propertyName, Object oldValue,
4557:                                     Object newValue)
4558:   {
4559:     if (changeSupport != null)
4560:       changeSupport.firePropertyChange(propertyName, oldValue, newValue);
4561:   }
4562: 
4563:   /**
4564:    * Report a change in a bound property to any registered property listeners.
4565:    *
4566:    * @param propertyName the property that changed
4567:    * @param oldValue the old property value
4568:    * @param newValue the new property value
4569:    */
4570:   protected void firePropertyChange(String propertyName, boolean oldValue,
4571:                                     boolean newValue)
4572:   {
4573:     if (changeSupport != null)
4574:       changeSupport.firePropertyChange(propertyName, oldValue, newValue);
4575:   }
4576: 
4577:   /**
4578:    * Report a change in a bound property to any registered property listeners.
4579:    *
4580:    * @param propertyName the property that changed
4581:    * @param oldValue the old property value
4582:    * @param newValue the new property value
4583:    */
4584:   protected void firePropertyChange(String propertyName, int oldValue,
4585:                                     int newValue)
4586:   {
4587:     if (changeSupport != null)
4588:       changeSupport.firePropertyChange(propertyName, oldValue, newValue);
4589:   }
4590: 
4591:   /**
4592:    * Report a change in a bound property to any registered property listeners.
4593:    *
4594:    * @param propertyName the property that changed
4595:    * @param oldValue the old property value
4596:    * @param newValue the new property value
4597:    *
4598:    * @since 1.5
4599:    */
4600:   public void firePropertyChange(String propertyName, byte oldValue,
4601:                                     byte newValue)
4602:   {
4603:     if (changeSupport != null)
4604:       changeSupport.firePropertyChange(propertyName, new Byte(oldValue),
4605:                                        new Byte(newValue));
4606:   }
4607: 
4608:   /**
4609:    * Report a change in a bound property to any registered property listeners.
4610:    *
4611:    * @param propertyName the property that changed
4612:    * @param oldValue the old property value
4613:    * @param newValue the new property value
4614:    *
4615:    * @since 1.5
4616:    */
4617:   public void firePropertyChange(String propertyName, char oldValue,
4618:                                     char newValue)
4619:   {
4620:     if (changeSupport != null)
4621:       changeSupport.firePropertyChange(propertyName, new Character(oldValue),
4622:                                        new Character(newValue));
4623:   }
4624: 
4625:   /**
4626:    * Report a change in a bound property to any registered property listeners.
4627:    *
4628:    * @param propertyName the property that changed
4629:    * @param oldValue the old property value
4630:    * @param newValue the new property value
4631:    *
4632:    * @since 1.5
4633:    */
4634:   public void firePropertyChange(String propertyName, short oldValue,
4635:                                     short newValue)
4636:   {
4637:     if (changeSupport != null)
4638:       changeSupport.firePropertyChange(propertyName, new Short(oldValue),
4639:                                        new Short(newValue));
4640:   }
4641: 
4642:   /**
4643:    * Report a change in a bound property to any registered property listeners.
4644:    *
4645:    * @param propertyName the property that changed
4646:    * @param oldValue the old property value
4647:    * @param newValue the new property value
4648:    *
4649:    * @since 1.5
4650:    */
4651:   public void firePropertyChange(String propertyName, long oldValue,
4652:                                     long newValue)
4653:   {
4654:     if (changeSupport != null)
4655:       changeSupport.firePropertyChange(propertyName, new Long(oldValue),
4656:                                        new Long(newValue));
4657:   }
4658: 
4659:   /**
4660:    * Report a change in a bound property to any registered property listeners.
4661:    *
4662:    * @param propertyName the property that changed
4663:    * @param oldValue the old property value
4664:    * @param newValue the new property value
4665:    *
4666:    * @since 1.5
4667:    */
4668:   public void firePropertyChange(String propertyName, float oldValue,
4669:                                     float newValue)
4670:   {
4671:     if (changeSupport != null)
4672:       changeSupport.firePropertyChange(propertyName, new Float(oldValue),
4673:                                        new Float(newValue));
4674:   }
4675: 
4676: 
4677:   /**
4678:    * Report a change in a bound property to any registered property listeners.
4679:    *
4680:    * @param propertyName the property that changed
4681:    * @param oldValue the old property value
4682:    * @param newValue the new property value
4683:    *
4684:    * @since 1.5
4685:    */
4686:   public void firePropertyChange(String propertyName, double oldValue,
4687:                                  double newValue)
4688:   {
4689:     if (changeSupport != null)
4690:       changeSupport.firePropertyChange(propertyName, new Double(oldValue),
4691:                                        new Double(newValue));
4692:   }
4693: 
4694:   /**
4695:    * Sets the text layout orientation of this component. New components default
4696:    * to UNKNOWN (which behaves like LEFT_TO_RIGHT). This method affects only
4697:    * the current component, while
4698:    * {@link #applyComponentOrientation(ComponentOrientation)} affects the
4699:    * entire hierarchy.
4700:    *
4701:    * @param o the new orientation
4702:    * @throws NullPointerException if o is null
4703:    * @see #getComponentOrientation()
4704:    */
4705:   public void setComponentOrientation(ComponentOrientation o)
4706:   {
4707:     if (o == null)
4708:       throw new NullPointerException();
4709:     ComponentOrientation oldOrientation = orientation;
4710:     orientation = o;
4711:     firePropertyChange("componentOrientation", oldOrientation, o);
4712:   }
4713: 
4714:   /**
4715:    * Determines the text layout orientation used by this component.
4716:    *
4717:    * @return the component orientation
4718:    * @see #setComponentOrientation(ComponentOrientation)
4719:    */
4720:   public ComponentOrientation getComponentOrientation()
4721:   {
4722:     return orientation;
4723:   }
4724: 
4725:   /**
4726:    * Sets the text layout orientation of this component. New components default
4727:    * to UNKNOWN (which behaves like LEFT_TO_RIGHT). This method affects the
4728:    * entire hierarchy, while
4729:    * {@link #setComponentOrientation(ComponentOrientation)} affects only the
4730:    * current component.
4731:    *
4732:    * @param o the new orientation
4733:    * @throws NullPointerException if o is null
4734:    * @see #getComponentOrientation()
4735:    * @since 1.4
4736:    */
4737:   public void applyComponentOrientation(ComponentOrientation o)
4738:   {
4739:     setComponentOrientation(o);
4740:   }
4741: 
4742:   /**
4743:    * Returns the accessibility framework context of this class. Component is
4744:    * not accessible, so the default implementation returns null. Subclasses
4745:    * must override this behavior, and return an appropriate subclass of
4746:    * {@link AccessibleAWTComponent}.
4747:    *
4748:    * @return the accessibility context
4749:    */
4750:   public AccessibleContext getAccessibleContext()
4751:   {
4752:     return null;
4753:   }
4754: 
4755: 
4756:   // Helper methods; some are package visible for use by subclasses.
4757: 
4758:   /**
4759:    * Subclasses should override this to return unique component names like
4760:    * "menuitem0".
4761:    *
4762:    * @return the generated name for this component
4763:    */
4764:   String generateName()
4765:   {
4766:     // Component is abstract.
4767:     return null;
4768:   }
4769: 
4770:   /**
4771:    * Sets the peer for this component.
4772:    *
4773:    * @param peer the new peer
4774:    */
4775:   final void setPeer(ComponentPeer peer)
4776:   {
4777:     this.peer = peer;
4778:   }
4779: 
4780:   /**
4781:    * Implementation method that allows classes such as Canvas and Window to
4782:    * override the graphics configuration without violating the published API.
4783:    *
4784:    * @return the graphics configuration
4785:    */
4786:   GraphicsConfiguration getGraphicsConfigurationImpl()
4787:   {
4788:     if (peer != null)
4789:       {
4790:         GraphicsConfiguration config = peer.getGraphicsConfiguration();
4791:         if (config != null)
4792:           return config;
4793:       }
4794: 
4795:     if (parent != null)
4796:       return parent.getGraphicsConfiguration();
4797: 
4798:     return null;
4799:   }
4800: 
4801:   /**
4802:    * Translate an AWT 1.1 event ({@link AWTEvent}) into an AWT 1.0
4803:    * event ({@link Event}).
4804:    *
4805:    * @param e an AWT 1.1 event to translate
4806:    *
4807:    * @return an AWT 1.0 event representing e
4808:    */
4809:   static Event translateEvent (AWTEvent e)
4810:   {
4811:     Object target = e.getSource ();
4812:     Event translated = null;
4813: 
4814:     if (e instanceof InputEvent)
4815:       {
4816:         InputEvent ie = (InputEvent) e;
4817:         long when = ie.getWhen ();
4818: 
4819:         int oldID = 0;
4820:         int id = e.getID ();
4821: 
4822:         int oldMods = 0;
4823:         int mods = ie.getModifiersEx ();
4824: 
4825:         if ((mods & InputEvent.BUTTON2_DOWN_MASK) != 0)
4826:           oldMods |= Event.META_MASK;
4827:         else if ((mods & InputEvent.BUTTON3_DOWN_MASK) != 0)
4828:           oldMods |= Event.ALT_MASK;
4829: 
4830:         if ((mods & InputEvent.SHIFT_DOWN_MASK) != 0)
4831:           oldMods |= Event.SHIFT_MASK;
4832: 
4833:         if ((mods & InputEvent.CTRL_DOWN_MASK) != 0)
4834:           oldMods |= Event.CTRL_MASK;
4835: 
4836:         if ((mods & InputEvent.META_DOWN_MASK) != 0)
4837:           oldMods |= Event.META_MASK;
4838: 
4839:         if ((mods & InputEvent.ALT_DOWN_MASK) != 0)
4840:           oldMods |= Event.ALT_MASK;
4841: 
4842:         if (e instanceof MouseEvent)
4843:           {
4844:             if (id == MouseEvent.MOUSE_PRESSED)
4845:               oldID = Event.MOUSE_DOWN;
4846:             else if (id == MouseEvent.MOUSE_RELEASED)
4847:               oldID = Event.MOUSE_UP;
4848:             else if (id == MouseEvent.MOUSE_MOVED)
4849:               oldID = Event.MOUSE_MOVE;
4850:             else if (id == MouseEvent.MOUSE_DRAGGED)
4851:               oldID = Event.MOUSE_DRAG;
4852:             else if (id == MouseEvent.MOUSE_ENTERED)
4853:               oldID = Event.MOUSE_ENTER;
4854:             else if (id == MouseEvent.MOUSE_EXITED)
4855:               oldID = Event.MOUSE_EXIT;
4856:             else
4857:               // No analogous AWT 1.0 mouse event.
4858:               return null;
4859: 
4860:             MouseEvent me = (MouseEvent) e;
4861: 
4862:             translated = new Event (target, when, oldID,
4863:                                     me.getX (), me.getY (), 0, oldMods);
4864:           }
4865:         else if (e instanceof KeyEvent)
4866:           {
4867:             if (id == KeyEvent.KEY_PRESSED)
4868:               oldID = Event.KEY_PRESS;
4869:             else if (e.getID () == KeyEvent.KEY_RELEASED)
4870:               oldID = Event.KEY_RELEASE;
4871:             else
4872:               // No analogous AWT 1.0 key event.
4873:               return null;
4874: 
4875:             int oldKey = 0;
4876:             int newKey = ((KeyEvent) e).getKeyCode ();
4877:             switch (newKey)
4878:               {
4879:               case KeyEvent.VK_BACK_SPACE:
4880:                 oldKey = Event.BACK_SPACE;
4881:                 break;
4882:               case KeyEvent.VK_CAPS_LOCK:
4883:                 oldKey = Event.CAPS_LOCK;
4884:                 break;
4885:               case KeyEvent.VK_DELETE:
4886:                 oldKey = Event.DELETE;
4887:                 break;
4888:               case KeyEvent.VK_DOWN:
4889:               case KeyEvent.VK_KP_DOWN:
4890:                 oldKey = Event.DOWN;
4891:                 break;
4892:               case KeyEvent.VK_END:
4893:                 oldKey = Event.END;
4894:                 break;
4895:               case KeyEvent.VK_ENTER:
4896:                 oldKey = Event.ENTER;
4897:                 break;
4898:               case KeyEvent.VK_ESCAPE:
4899:                 oldKey = Event.ESCAPE;
4900:                 break;
4901:               case KeyEvent.VK_F1:
4902:                 oldKey = Event.F1;
4903:                 break;
4904:               case KeyEvent.VK_F10:
4905:                 oldKey = Event.F10;
4906:                 break;
4907:               case KeyEvent.VK_F11:
4908:                 oldKey = Event.F11;
4909:                 break;
4910:               case KeyEvent.VK_F12:
4911:                 oldKey = Event.F12;
4912:                 break;
4913:               case KeyEvent.VK_F2:
4914:                 oldKey = Event.F2;
4915:                 break;
4916:               case KeyEvent.VK_F3:
4917:                 oldKey = Event.F3;
4918:                 break;
4919:               case KeyEvent.VK_F4:
4920:                 oldKey = Event.F4;
4921:                 break;
4922:               case KeyEvent.VK_F5:
4923:                 oldKey = Event.F5;
4924:                 break;
4925:               case KeyEvent.VK_F6:
4926:                 oldKey = Event.F6;
4927:                 break;
4928:               case KeyEvent.VK_F7:
4929:                 oldKey = Event.F7;
4930:                 break;
4931:               case KeyEvent.VK_F8:
4932:                 oldKey = Event.F8;
4933:                 break;
4934:               case KeyEvent.VK_F9:
4935:                 oldKey = Event.F9;
4936:                 break;
4937:               case KeyEvent.VK_HOME:
4938:                 oldKey = Event.HOME;
4939:                 break;
4940:               case KeyEvent.VK_INSERT:
4941:                 oldKey = Event.INSERT;
4942:                 break;
4943:               case KeyEvent.VK_LEFT:
4944:               case KeyEvent.VK_KP_LEFT:
4945:                 oldKey = Event.LEFT;
4946:                 break;
4947:               case KeyEvent.VK_NUM_LOCK:
4948:                 oldKey = Event.NUM_LOCK;
4949:                 break;
4950:               case KeyEvent.VK_PAUSE:
4951:                 oldKey = Event.PAUSE;
4952:                 break;
4953:               case KeyEvent.VK_PAGE_DOWN:
4954:                 oldKey = Event.PGDN;
4955:                 break;
4956:               case KeyEvent.VK_PAGE_UP:
4957:                 oldKey = Event.PGUP;
4958:                 break;
4959:               case KeyEvent.VK_PRINTSCREEN:
4960:                 oldKey = Event.PRINT_SCREEN;
4961:                 break;
4962:               case KeyEvent.VK_RIGHT:
4963:               case KeyEvent.VK_KP_RIGHT:
4964:                 oldKey = Event.RIGHT;
4965:                 break;
4966:               case KeyEvent.VK_SCROLL_LOCK:
4967:                 oldKey = Event.SCROLL_LOCK;
4968:                 break;
4969:               case KeyEvent.VK_TAB:
4970:                 oldKey = Event.TAB;
4971:                 break;
4972:               case KeyEvent.VK_UP:
4973:               case KeyEvent.VK_KP_UP:
4974:                 oldKey = Event.UP;
4975:                 break;
4976:               default:
4977:                 oldKey = (int) ((KeyEvent) e).getKeyChar();
4978:               }
4979: 
4980:             translated = new Event (target, when, oldID,
4981:                                     0, 0, oldKey, oldMods);
4982:           }
4983:       }
4984:     else if (e instanceof AdjustmentEvent)
4985:       {
4986:     AdjustmentEvent ae = (AdjustmentEvent) e;
4987:     int type = ae.getAdjustmentType();
4988:     int oldType;
4989:     if (type == AdjustmentEvent.BLOCK_DECREMENT)
4990:       oldType = Event.SCROLL_PAGE_UP;
4991:     else if (type == AdjustmentEvent.BLOCK_INCREMENT)
4992:       oldType = Event.SCROLL_PAGE_DOWN;
4993:     else if (type == AdjustmentEvent.TRACK)
4994:       oldType = Event.SCROLL_ABSOLUTE;
4995:     else if (type == AdjustmentEvent.UNIT_DECREMENT)
4996:       oldType = Event.SCROLL_LINE_UP;
4997:     else if (type == AdjustmentEvent.UNIT_INCREMENT)
4998:       oldType = Event.SCROLL_LINE_DOWN;
4999:     else
5000:       oldType = type;
5001:     translated = new Event(target, oldType, new Integer(ae.getValue()));
5002:       }
5003:     else if (e instanceof ActionEvent)
5004:       translated = new Event (target, Event.ACTION_EVENT,
5005:                               ((ActionEvent) e).getActionCommand ());
5006: 
5007:     return translated;
5008:   }
5009: 
5010:   /**
5011:    * Implementation of dispatchEvent. Allows trusted package classes
5012:    * to dispatch additional events first.  This implementation first
5013:    * translates <code>e</code> to an AWT 1.0 event and sends the
5014:    * result to {@link #postEvent}.  If the AWT 1.0 event is not
5015:    * handled, and events of type <code>e</code> are enabled for this
5016:    * component, e is passed on to {@link #processEvent}.
5017:    *
5018:    * @param e the event to dispatch
5019:    */
5020: 
5021:   void dispatchEventImpl(AWTEvent e)
5022:   {
5023:     // This boolean tells us not to process focus events when the focus
5024:     // opposite component is the same as the focus component.
5025:     boolean ignoreFocus = 
5026:       (e instanceof FocusEvent && 
5027:        ((FocusEvent)e).getComponent() == ((FocusEvent)e).getOppositeComponent());
5028:     
5029:     if (eventTypeEnabled (e.id))
5030:       {
5031:         if (e.id != PaintEvent.PAINT && e.id != PaintEvent.UPDATE
5032:             && !ignoreFocus)
5033:           processEvent(e);
5034:         
5035:         // the trick we use to communicate between dispatch and redispatch
5036:         // is to have KeyboardFocusManager.redispatch synchronize on the
5037:         // object itself. we then do not redispatch to KeyboardFocusManager
5038:         // if we are already holding the lock.
5039:         if (! Thread.holdsLock(e))
5040:           {
5041:             switch (e.id)
5042:               {
5043:               case WindowEvent.WINDOW_GAINED_FOCUS:
5044:               case WindowEvent.WINDOW_LOST_FOCUS:
5045:               case KeyEvent.KEY_PRESSED:
5046:               case KeyEvent.KEY_RELEASED:
5047:               case KeyEvent.KEY_TYPED:
5048:               case FocusEvent.FOCUS_GAINED:
5049:               case FocusEvent.FOCUS_LOST:
5050:                 if (KeyboardFocusManager
5051:                     .getCurrentKeyboardFocusManager()
5052:                     .dispatchEvent(e))
5053:                     return;
5054:               case MouseEvent.MOUSE_PRESSED:
5055:                 if (isLightweight() && !e.isConsumed())
5056:                     requestFocus();
5057:                 break;
5058:               }
5059:           }
5060:       }
5061: 
5062:     if (peer != null)
5063:       peer.handleEvent(e);
5064:   }
5065: 
5066:   /**
5067:    * Tells whether or not an event type is enabled.
5068:    */
5069:   boolean eventTypeEnabled (int type)
5070:   {
5071:     if (type > AWTEvent.RESERVED_ID_MAX)
5072:       return true;
5073: 
5074:     switch (type)
5075:       {
5076:       case HierarchyEvent.HIERARCHY_CHANGED:
5077:         return (hierarchyListener != null 
5078:             || (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0);
5079:         
5080:       case HierarchyEvent.ANCESTOR_MOVED:
5081:       case HierarchyEvent.ANCESTOR_RESIZED:
5082:         return (hierarchyBoundsListener != null 
5083:             || (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0);
5084:         
5085:       case ComponentEvent.COMPONENT_HIDDEN:
5086:       case ComponentEvent.COMPONENT_MOVED:
5087:       case ComponentEvent.COMPONENT_RESIZED:
5088:       case ComponentEvent.COMPONENT_SHOWN:
5089:         return (componentListener != null
5090:                 || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0);
5091: 
5092:       case KeyEvent.KEY_PRESSED:
5093:       case KeyEvent.KEY_RELEASED:
5094:       case KeyEvent.KEY_TYPED:
5095:         return (keyListener != null
5096:                 || (eventMask & AWTEvent.KEY_EVENT_MASK) != 0);
5097: 
5098:       case MouseEvent.MOUSE_CLICKED:
5099:       case MouseEvent.MOUSE_ENTERED:
5100:       case MouseEvent.MOUSE_EXITED:
5101:       case MouseEvent.MOUSE_PRESSED:
5102:       case MouseEvent.MOUSE_RELEASED:
5103:         return (mouseListener != null
5104:                 || (eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0);
5105:       case MouseEvent.MOUSE_MOVED:
5106:       case MouseEvent.MOUSE_DRAGGED:
5107:         return (mouseMotionListener != null
5108:                 || (eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0);
5109:       case MouseEvent.MOUSE_WHEEL:
5110:         return (mouseWheelListener != null
5111:                 || (eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0);
5112:         
5113:       case FocusEvent.FOCUS_GAINED:
5114:       case FocusEvent.FOCUS_LOST:
5115:         return (focusListener != null
5116:                 || (eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0);
5117: 
5118:       case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
5119:       case InputMethodEvent.CARET_POSITION_CHANGED:
5120:         return (inputMethodListener != null
5121:                 || (eventMask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0);
5122:         
5123:       case PaintEvent.PAINT:
5124:       case PaintEvent.UPDATE:
5125:         return (eventMask & AWTEvent.PAINT_EVENT_MASK) != 0;
5126:         
5127:       default:
5128:         return false;
5129:       }
5130:   }
5131: 
5132:   /**
5133:    * Coalesce paint events. Current heuristic is: Merge if the union of
5134:    * areas is less than twice that of the sum of the areas. The X server
5135:    * tend to create a lot of paint events that are adjacent but not
5136:    * overlapping.
5137:    *
5138:    * <pre>
5139:    * +------+
5140:    * |      +-----+  ...will be merged
5141:    * |      |     |
5142:    * |      |     |
5143:    * +------+     |
5144:    *        +-----+
5145:    *
5146:    * +---------------+--+
5147:    * |               |  |  ...will not be merged
5148:    * +---------------+  |
5149:    *                 |  |
5150:    *                 |  |
5151:    *                 |  |
5152:    *                 |  |
5153:    *                 |  |
5154:    *                 +--+
5155:    * </pre>
5156:    *
5157:    * @param queuedEvent the first paint event
5158:    * @param newEvent the second paint event
5159:    * @return the combined paint event, or null
5160:    */
5161:   private PaintEvent coalescePaintEvents(PaintEvent queuedEvent,
5162:                                          PaintEvent newEvent)
5163:   {
5164:     Rectangle r1 = queuedEvent.getUpdateRect();
5165:     Rectangle r2 = newEvent.getUpdateRect();
5166:     Rectangle union = r1.union(r2);
5167:     newEvent.setUpdateRect(union);
5168:     return newEvent;
5169:   }
5170: 
5171:   /**
5172:    * This method is used to implement transferFocus(). CHILD is the child
5173:    * making the request. This is overridden by Container; when called for an
5174:    * ordinary component there is no child and so we always return null.
5175:    *
5176:    * FIXME: is this still needed, in light of focus traversal policies?
5177:    *
5178:    * @param child the component making the request
5179:    * @return the next component to focus on
5180:    */
5181:   Component findNextFocusComponent(Component child)
5182:   {
5183:     return null;
5184:   }
5185: 
5186:   /**
5187:    * Deserializes this component. This regenerates all serializable listeners
5188:    * which were registered originally.
5189:    *
5190:    * @param s the stream to read from
5191:    * @throws ClassNotFoundException if deserialization fails
5192:    * @throws IOException if the stream fails
5193:    */
5194:   private void readObject(ObjectInputStream s)
5195:     throws ClassNotFoundException, IOException
5196:   {
5197:     s.defaultReadObject();
5198:     String key = (String) s.readObject();
5199:     while (key != null)
5200:       {
5201:         Object listener = s.readObject();
5202:         if ("componentL".equals(key))
5203:           addComponentListener((ComponentListener) listener);
5204:         else if ("focusL".equals(key))
5205:           addFocusListener((FocusListener) listener);
5206:         else if ("keyL".equals(key))
5207:           addKeyListener((KeyListener) listener);
5208:         else if ("mouseL".equals(key))
5209:           addMouseListener((MouseListener) listener);
5210:         else if ("mouseMotionL".equals(key))
5211:           addMouseMotionListener((MouseMotionListener) listener);
5212:         else if ("inputMethodL".equals(key))
5213:           addInputMethodListener((InputMethodListener) listener);
5214:         else if ("hierarchyL".equals(key))
5215:           addHierarchyListener((HierarchyListener) listener);
5216:         else if ("hierarchyBoundsL".equals(key))
5217:           addHierarchyBoundsListener((HierarchyBoundsListener) listener);
5218:         else if ("mouseWheelL".equals(key))
5219:           addMouseWheelListener((MouseWheelListener) listener);
5220:         key = (String) s.readObject();
5221:       }
5222:   }
5223: 
5224:   /**
5225:    * Serializes this component. This ignores all listeners which do not
5226:    * implement Serializable, but includes those that do.
5227:    *
5228:    * @param s the stream to write to
5229:    * @throws IOException if the stream fails
5230:    */
5231:   private void writeObject(ObjectOutputStream s) throws IOException
5232:   {
5233:     s.defaultWriteObject();
5234:     AWTEventMulticaster.save(s, "componentL", componentListener);
5235:     AWTEventMulticaster.save(s, "focusL", focusListener);
5236:     AWTEventMulticaster.save(s, "keyL", keyListener);
5237:     AWTEventMulticaster.save(s, "mouseL", mouseListener);
5238:     AWTEventMulticaster.save(s, "mouseMotionL", mouseMotionListener);
5239:     AWTEventMulticaster.save(s, "inputMethodL", inputMethodListener);
5240:     AWTEventMulticaster.save(s, "hierarchyL", hierarchyListener);
5241:     AWTEventMulticaster.save(s, "hierarchyBoundsL", hierarchyBoundsListener);
5242:     AWTEventMulticaster.save(s, "mouseWheelL", mouseWheelListener);
5243:     s.writeObject(null);
5244:   }
5245: 
5246:   
5247:   // Nested classes.
5248:   
5249:   /**
5250:    * This class fixes the bounds for a Heavyweight component that
5251:    * is placed inside a Lightweight container. When the lightweight is
5252:    * moved or resized, setBounds for the lightweight peer does nothing.
5253:    * Therefore, it was never moved on the screen. This class is 
5254:    * attached to the lightweight, and it adjusts the position and size
5255:    * of the peer when notified.
5256:    * This is the same for show and hide.
5257:    */
5258:   class HeavyweightInLightweightListener
5259:       implements ComponentListener
5260:   {
5261:     
5262:     /**
5263:      * Constructor. Adds component listener to lightweight parent.
5264:      * 
5265:      * @param parent - the lightweight container.
5266:      */
5267:     public HeavyweightInLightweightListener(Container parent)
5268:     {
5269:       parent.addComponentListener(this);
5270:     }
5271:     
5272:     /**
5273:      * This method is called when the component is resized.
5274:      * 
5275:      * @param event the <code>ComponentEvent</code> indicating the resize
5276:      */
5277:     public void componentResized(ComponentEvent event)
5278:     {
5279:       // Nothing to do here, componentMoved will be called.
5280:     }
5281: 
5282:     /**
5283:      * This method is called when the component is moved.
5284:      * 
5285:      * @param event the <code>ComponentEvent</code> indicating the move
5286:      */
5287:     public void componentMoved(ComponentEvent event)
5288:     {
5289:       if (peer != null)
5290:         peer.setBounds(x, y, width, height);
5291:     }
5292: 
5293:     /**
5294:      * This method is called when the component is made visible.
5295:      * 
5296:      * @param event the <code>ComponentEvent</code> indicating the visibility
5297:      */
5298:     public void componentShown(ComponentEvent event)
5299:     {
5300:       if (isShowing())
5301:         peer.show();
5302:     }
5303: 
5304:     /**
5305:      * This method is called when the component is hidden.
5306:      * 
5307:      * @param event the <code>ComponentEvent</code> indicating the visibility
5308:      */
5309:     public void componentHidden(ComponentEvent event)
5310:     {
5311:       if (!isShowing())
5312:         peer.hide();
5313:     }
5314:   }
5315:   
5316:   /**
5317:    * This class provides accessibility support for subclasses of container.
5318:    *
5319:    * @author Eric Blake (ebb9@email.byu.edu)
5320:    * @since 1.3
5321:    * @status updated to 1.4
5322:    */
5323:   protected abstract class AccessibleAWTComponent extends AccessibleContext
5324:     implements Serializable, AccessibleComponent
5325:   {
5326:     /**
5327:      * Compatible with JDK 1.3+.
5328:      */
5329:     private static final long serialVersionUID = 642321655757800191L;
5330: 
5331:     /**
5332:      * Converts show/hide events to PropertyChange events, and is registered
5333:      * as a component listener on this component.
5334:      *
5335:      * @serial the component handler
5336:      */
5337:     protected ComponentListener accessibleAWTComponentHandler
5338:       = new AccessibleAWTComponentHandler();
5339: 
5340:     /**
5341:      * Converts focus events to PropertyChange events, and is registered
5342:      * as a focus listener on this component.
5343:      *
5344:      * @serial the focus handler
5345:      */
5346:     protected FocusListener accessibleAWTFocusHandler
5347:       = new AccessibleAWTFocusHandler();
5348: 
5349:     /**
5350:      * The default constructor.
5351:      */
5352:     protected AccessibleAWTComponent()
5353:     {
5354:       Component.this.addComponentListener(accessibleAWTComponentHandler);
5355:       Component.this.addFocusListener(accessibleAWTFocusHandler);
5356:     }
5357: 
5358:     /**
5359:      * Adds a global property change listener to the accessible component.
5360:      *
5361:      * @param l the listener to add
5362:      * @see #ACCESSIBLE_NAME_PROPERTY
5363:      * @see #ACCESSIBLE_DESCRIPTION_PROPERTY
5364:      * @see #ACCESSIBLE_STATE_PROPERTY
5365:      * @see #ACCESSIBLE_VALUE_PROPERTY
5366:      * @see #ACCESSIBLE_SELECTION_PROPERTY
5367:      * @see #ACCESSIBLE_TEXT_PROPERTY
5368:      * @see #ACCESSIBLE_VISIBLE_DATA_PROPERTY
5369:      */
5370:     public void addPropertyChangeListener(PropertyChangeListener l)
5371:     {
5372:       Component.this.addPropertyChangeListener(l);
5373:       super.addPropertyChangeListener(l);
5374:     }
5375: 
5376:     /**
5377:      * Removes a global property change listener from this accessible
5378:      * component.
5379:      *
5380:      * @param l the listener to remove
5381:      */
5382:     public void removePropertyChangeListener(PropertyChangeListener l)
5383:     {
5384:       Component.this.removePropertyChangeListener(l);
5385:       super.removePropertyChangeListener(l);
5386:     }
5387: 
5388:     /**
5389:      * Returns the accessible name of this component. It is almost always
5390:      * wrong to return getName(), since it is not localized. In fact, for
5391:      * things like buttons, this should be the text of the button, not the
5392:      * name of the object. The tooltip text might also be appropriate.
5393:      *
5394:      * @return the name
5395:      * @see #setAccessibleName(String)
5396:      */
5397:     public String getAccessibleName()
5398:     {
5399:       return accessibleName;
5400:     }
5401: 
5402:     /**
5403:      * Returns a brief description of this accessible context. This should
5404:      * be localized.
5405:      *
5406:      * @return a description of this component
5407:      * @see #setAccessibleDescription(String)
5408:      */
5409:     public String getAccessibleDescription()
5410:     {
5411:       return accessibleDescription;
5412:     }
5413: 
5414:     /**
5415:      * Returns the role of this component.
5416:      *
5417:      * @return the accessible role
5418:      */
5419:     public AccessibleRole getAccessibleRole()
5420:     {
5421:       return AccessibleRole.AWT_COMPONENT;
5422:     }
5423: 
5424:     /**
5425:      * Returns a state set describing this component's state.
5426:      *
5427:      * @return a new state set
5428:      * @see AccessibleState
5429:      */
5430:     public AccessibleStateSet getAccessibleStateSet()
5431:     {
5432:       AccessibleStateSet s = new AccessibleStateSet();
5433:       if (Component.this.isEnabled())
5434:         s.add(AccessibleState.ENABLED);
5435:       if (isFocusable())
5436:         s.add(AccessibleState.FOCUSABLE);
5437:       if (isFocusOwner())
5438:         s.add(AccessibleState.FOCUSED);
5439:       // Note: While the java.awt.Component has an 'opaque' property, it
5440:       // seems that it is not added to the accessible state set here, even
5441:       // if this property is true. However, it is handled for
5442:       // javax.swing.JComponent, so we add it there.
5443:       if (Component.this.isShowing())
5444:         s.add(AccessibleState.SHOWING);
5445:       if (Component.this.isVisible())
5446:         s.add(AccessibleState.VISIBLE);
5447:       return s;
5448:     }
5449: 
5450:     /**
5451:      * Returns the parent of this component, if it is accessible.
5452:      *
5453:      * @return the accessible parent
5454:      */
5455:     public Accessible getAccessibleParent()
5456:     {
5457:       if (accessibleParent == null)
5458:         {
5459:           Container parent = getParent();
5460:           accessibleParent = parent instanceof Accessible
5461:             ? (Accessible) parent : null;
5462:         }
5463:       return accessibleParent;
5464:     }
5465: 
5466:     /**
5467:      * Returns the index of this component in its accessible parent.
5468:      *
5469:      * @return the index, or -1 if the parent is not accessible
5470:      * @see #getAccessibleParent()
5471:      */
5472:     public int getAccessibleIndexInParent()
5473:     {
5474:       if (getAccessibleParent() == null)
5475:         return -1;
5476:       AccessibleContext context
5477:         = ((Component) accessibleParent).getAccessibleContext();
5478:       if (context == null)
5479:         return -1;
5480:       for (int i = context.getAccessibleChildrenCount(); --i >= 0; )
5481:         if (context.getAccessibleChild(i) == Component.this)
5482:           return i;
5483:       return -1;
5484:     }
5485: 
5486:     /**
5487:      * Returns the number of children of this component which implement
5488:      * Accessible. Subclasses must override this if they can have children.
5489:      *
5490:      * @return the number of accessible children, default 0
5491:      */
5492:     public int getAccessibleChildrenCount()
5493:     {
5494:       return 0;
5495:     }
5496: 
5497:     /**
5498:      * Returns the ith accessible child. Subclasses must override this if
5499:      * they can have children.
5500:      *
5501:      * @return the ith accessible child, or null
5502:      * @see #getAccessibleChildrenCount()
5503:      */
5504:     public Accessible getAccessibleChild(int i)
5505:     {
5506:       return null;
5507:     }
5508: 
5509:     /**
5510:      * Returns the locale of this component.
5511:      *
5512:      * @return the locale
5513:      * @throws IllegalComponentStateException if the locale is unknown
5514:      */
5515:     public Locale getLocale()
5516:     {
5517:       return Component.this.getLocale();
5518:     }
5519: 
5520:     /**
5521:      * Returns this, since it is an accessible component.
5522:      *
5523:      * @return the accessible component
5524:      */
5525:     public AccessibleComponent getAccessibleComponent()
5526:     {
5527:       return this;
5528:     }
5529: 
5530:     /**
5531:      * Gets the background color.
5532:      *
5533:      * @return the background color
5534:      * @see #setBackground(Color)
5535:      */
5536:     public Color getBackground()
5537:     {
5538:       return Component.this.getBackground();
5539:     }
5540: 
5541:     /**
5542:      * Sets the background color.
5543:      *
5544:      * @param c the background color
5545:      * @see #getBackground()
5546:      * @see #isOpaque()
5547:      */
5548:     public void setBackground(Color c)
5549:     {
5550:       Component.this.setBackground(c);
5551:     }
5552: 
5553:     /**
5554:      * Gets the foreground color.
5555:      *
5556:      * @return the foreground color
5557:      * @see #setForeground(Color)
5558:      */
5559:     public Color getForeground()
5560:     {
5561:       return Component.this.getForeground();
5562:     }
5563: 
5564:     /**
5565:      * Sets the foreground color.
5566:      *
5567:      * @param c the foreground color
5568:      * @see #getForeground()
5569:      */
5570:     public void setForeground(Color c)
5571:     {
5572:       Component.this.setForeground(c);
5573:     }
5574: 
5575:     /**
5576:      * Gets the cursor.
5577:      *
5578:      * @return the cursor
5579:      * @see #setCursor(Cursor)
5580:      */
5581:     public Cursor getCursor()
5582:     {
5583:       return Component.this.getCursor();
5584:     }
5585: 
5586:     /**
5587:      * Sets the cursor.
5588:      *
5589:      * @param cursor the cursor
5590:      * @see #getCursor()
5591:      */
5592:     public void setCursor(Cursor cursor)
5593:     {
5594:       Component.this.setCursor(cursor);
5595:     }
5596: 
5597:     /**
5598:      * Gets the font.
5599:      *
5600:      * @return the font
5601:      * @see #setFont(Font)
5602:      */
5603:     public Font getFont()
5604:     {
5605:       return Component.this.getFont();
5606:     }
5607: 
5608:     /**
5609:      * Sets the font.
5610:      *
5611:      * @param f the font
5612:      * @see #getFont()
5613:      */
5614:     public void setFont(Font f)
5615:     {
5616:       Component.this.setFont(f);
5617:     }
5618: 
5619:     /**
5620:      * Gets the font metrics for a font.
5621:      *
5622:      * @param f the font to look up
5623:      * @return its metrics
5624:      * @throws NullPointerException if f is null
5625:      * @see #getFont()
5626:      */
5627:     public FontMetrics getFontMetrics(Font f)
5628:     {
5629:       return Component.this.getFontMetrics(f);
5630:     }
5631: 
5632:     /**
5633:      * Tests if the component is enabled.
5634:      *
5635:      * @return true if the component is enabled
5636:      * @see #setEnabled(boolean)
5637:      * @see #getAccessibleStateSet()
5638:      * @see AccessibleState#ENABLED
5639:      */
5640:     public boolean isEnabled()
5641:     {
5642:       return Component.this.isEnabled();
5643:     }
5644: 
5645:     /**
5646:      * Set whether the component is enabled.
5647:      *
5648:      * @param b the new enabled status
5649:      * @see #isEnabled()
5650:      */
5651:     public void setEnabled(boolean b)
5652:     {
5653:       Component.this.setEnabled(b);
5654:     }
5655: 
5656:     /**
5657:      * Test whether the component is visible (not necesarily showing).
5658:      *
5659:      * @return true if it is visible
5660:      * @see #setVisible(boolean)
5661:      * @see #getAccessibleStateSet()
5662:      * @see AccessibleState#VISIBLE
5663:      */
5664:     public boolean isVisible()
5665:     {
5666:       return Component.this.isVisible();
5667:     }
5668: 
5669:     /**
5670:      * Sets the visibility of this component.
5671:      *
5672:      * @param b the desired visibility
5673:      * @see #isVisible()
5674:      */
5675:     public void setVisible(boolean b)
5676:     {
5677:       Component.this.setVisible(b);
5678:     }
5679: 
5680:     /**
5681:      * Tests if the component is showing.
5682:      *
5683:      * @return true if this is showing
5684:      */
5685:     public boolean isShowing()
5686:     {
5687:       return Component.this.isShowing();
5688:     }
5689: 
5690:     /**
5691:      * Tests if the point is contained in this component.
5692:      *
5693:      * @param p the point to check
5694:      * @return true if it is contained
5695:      * @throws NullPointerException if p is null
5696:      */
5697:     public boolean contains(Point p)
5698:     {
5699:       return Component.this.contains(p.x, p.y);
5700:     }
5701: 
5702:     /**
5703:      * Returns the location of this object on the screen, or null if it is
5704:      * not showing.
5705:      *
5706:      * @return the location relative to screen coordinates, if showing
5707:      * @see #getBounds()
5708:      * @see #getLocation()
5709:      */
5710:     public Point getLocationOnScreen()
5711:     {
5712:       return Component.this.isShowing() ? Component.this.getLocationOnScreen()
5713:         : null;
5714:     }
5715: 
5716:     /**
5717:      * Returns the location of this object relative to its parent's coordinate
5718:      * system, or null if it is not showing.
5719:      *
5720:      * @return the location
5721:      * @see #getBounds()
5722:      * @see #getLocationOnScreen()
5723:      */
5724:     public Point getLocation()
5725:     {
5726:       return Component.this.getLocation();
5727:     }
5728: 
5729:     /**
5730:      * Sets the location of this relative to its parent's coordinate system.
5731:      *
5732:      * @param p the location
5733:      * @throws NullPointerException if p is null
5734:      * @see #getLocation()
5735:      */
5736:     public void setLocation(Point p)
5737:     {
5738:       Component.this.setLocation(p.x, p.y);
5739:     }
5740: 
5741:     /**
5742:      * Gets the bounds of this component, or null if it is not on screen.
5743:      *
5744:      * @return the bounds
5745:      * @see #contains(Point)
5746:      * @see #setBounds(Rectangle)
5747:      */
5748:     public Rectangle getBounds()
5749:     {
5750:       return Component.this.getBounds();
5751:     }
5752: 
5753:     /**
5754:      * Sets the bounds of this component.
5755:      *
5756:      * @param r the bounds
5757:      * @throws NullPointerException if r is null
5758:      * @see #getBounds()
5759:      */
5760:     public void setBounds(Rectangle r)
5761:     {
5762:       Component.this.setBounds(r.x, r.y, r.width, r.height);
5763:     }
5764: 
5765:     /**
5766:      * Gets the size of this component, or null if it is not showing.
5767:      *
5768:      * @return the size
5769:      * @see #setSize(Dimension)
5770:      */
5771:     public Dimension getSize()
5772:     {
5773:       return Component.this.getSize();
5774:     }
5775: 
5776:     /**
5777:      * Sets the size of this component.
5778:      *
5779:      * @param d the size
5780:      * @throws NullPointerException if d is null
5781:      * @see #getSize()
5782:      */
5783:     public void setSize(Dimension d)
5784:     {
5785:       Component.this.setSize(d.width, d.height);
5786:     }
5787: 
5788:     /**
5789:      * Returns the Accessible child at a point relative to the coordinate
5790:      * system of this component, if one exists, or null. Since components
5791:      * have no children, subclasses must override this to get anything besides
5792:      * null.
5793:      *
5794:      * @param p the point to check
5795:      * @return the accessible child at that point
5796:      * @throws NullPointerException if p is null
5797:      */
5798:     public Accessible getAccessibleAt(Point p)
5799:     {
5800:       return null;
5801:     }
5802: 
5803:     /**
5804:      * Tests whether this component can accept focus.
5805:      *
5806:      * @return true if this is focus traversable
5807:      * @see #getAccessibleStateSet ()
5808:      * @see AccessibleState#FOCUSABLE
5809:      * @see AccessibleState#FOCUSED
5810:      */
5811:     public boolean isFocusTraversable ()
5812:     {
5813:       return Component.this.isFocusTraversable ();
5814:     }
5815: 
5816:     /**
5817:      * Requests focus for this component.
5818:      *
5819:      * @see #isFocusTraversable ()
5820:      */
5821:     public void requestFocus ()
5822:     {
5823:       Component.this.requestFocus ();
5824:     }
5825: 
5826:     /**
5827:      * Adds a focus listener.
5828:      *
5829:      * @param l the listener to add
5830:      */
5831:     public void addFocusListener(FocusListener l)
5832:     {
5833:       Component.this.addFocusListener(l);
5834:     }
5835: 
5836:     /**
5837:      * Removes a focus listener.
5838:      *
5839:      * @param l the listener to remove
5840:      */
5841:     public void removeFocusListener(FocusListener l)
5842:     {
5843:       Component.this.removeFocusListener(l);
5844:     }
5845: 
5846:     /**
5847:      * Converts component changes into property changes.
5848:      *
5849:      * @author Eric Blake (ebb9@email.byu.edu)
5850:      * @since 1.3
5851:      * @status updated to 1.4
5852:      */
5853:     protected class AccessibleAWTComponentHandler implements ComponentListener
5854:     {
5855:       /**
5856:        * Default constructor.
5857:        */
5858:       protected AccessibleAWTComponentHandler()
5859:       {
5860:         // Nothing to do here.
5861:       }
5862: 
5863:       /**
5864:        * Convert a component hidden to a property change.
5865:        *
5866:        * @param e the event to convert
5867:        */
5868:       public void componentHidden(ComponentEvent e)
5869:       {
5870:         AccessibleAWTComponent.this.firePropertyChange
5871:           (ACCESSIBLE_STATE_PROPERTY, AccessibleState.VISIBLE, null);
5872:       }
5873: 
5874:       /**
5875:        * Convert a component shown to a property change.
5876:        *
5877:        * @param e the event to convert
5878:        */
5879:       public void componentShown(ComponentEvent e)
5880:       {
5881:         AccessibleAWTComponent.this.firePropertyChange
5882:           (ACCESSIBLE_STATE_PROPERTY, null, AccessibleState.VISIBLE);
5883:       }
5884: 
5885:       /**
5886:        * Moving a component does not affect properties.
5887:        *
5888:        * @param e ignored
5889:        */
5890:       public void componentMoved(ComponentEvent e)
5891:       {
5892:         // Nothing to do here.
5893:       }
5894: 
5895:       /**
5896:        * Resizing a component does not affect properties.
5897:        *
5898:        * @param e ignored
5899:        */
5900:       public void componentResized(ComponentEvent e)
5901:       {
5902:         // Nothing to do here.
5903:       }
5904:     } // class AccessibleAWTComponentHandler
5905: 
5906:     /**
5907:      * Converts focus changes into property changes.
5908:      *
5909:      * @author Eric Blake (ebb9@email.byu.edu)
5910:      * @since 1.3
5911:      * @status updated to 1.4
5912:      */
5913:     protected class AccessibleAWTFocusHandler implements FocusListener
5914:     {
5915:       /**
5916:        * Default constructor.
5917:        */
5918:       protected AccessibleAWTFocusHandler()
5919:       {
5920:         // Nothing to do here.
5921:       }
5922: 
5923:       /**
5924:        * Convert a focus gained to a property change.
5925:        *
5926:        * @param e the event to convert
5927:        */
5928:       public void focusGained(FocusEvent e)
5929:       {
5930:         AccessibleAWTComponent.this.firePropertyChange
5931:           (ACCESSIBLE_STATE_PROPERTY, null, AccessibleState.FOCUSED);
5932:       }
5933: 
5934:       /**
5935:        * Convert a focus lost to a property change.
5936:        *
5937:        * @param e the event to convert
5938:        */
5939:       public void focusLost(FocusEvent e)
5940:       {
5941:         AccessibleAWTComponent.this.firePropertyChange
5942:           (ACCESSIBLE_STATE_PROPERTY, AccessibleState.FOCUSED, null);
5943:       }
5944:     } // class AccessibleAWTComponentHandler
5945:   } // class AccessibleAWTComponent
5946: 
5947:   /**
5948:    * This class provides support for blitting offscreen surfaces to a
5949:    * component.
5950:    *
5951:    * @see BufferStrategy
5952:    *
5953:    * @since 1.4
5954:    */
5955:   protected class BltBufferStrategy extends BufferStrategy
5956:   {
5957:     /**
5958:      * The capabilities of the image buffer.
5959:      */
5960:     protected BufferCapabilities caps;
5961: 
5962:     /**
5963:      * The back buffers used in this strategy.
5964:      */
5965:     protected VolatileImage[] backBuffers;
5966: 
5967:     /**
5968:      * Whether or not the image buffer resources are allocated and
5969:      * ready to be drawn into.
5970:      */
5971:     protected boolean validatedContents;
5972: 
5973:     /**
5974:      * The width of the back buffers.
5975:      */
5976:     protected int width;
5977: 
5978:     /**
5979:      * The height of the back buffers.
5980:      */
5981:     protected int height;
5982: 
5983:     /**
5984:      * The front buffer.
5985:      */
5986:     private VolatileImage frontBuffer;
5987: 
5988:     /**
5989:      * Creates a blitting buffer strategy.
5990:      *
5991:      * @param numBuffers the number of buffers, including the front
5992:      * buffer
5993:      * @param caps the capabilities of this strategy
5994:      */
5995:     protected BltBufferStrategy(int numBuffers, BufferCapabilities caps)
5996:     {
5997:       this.caps = caps;
5998:       createBackBuffers(numBuffers - 1);
5999:       width = getWidth();
6000:       height = getHeight();
6001:     }
6002: 
6003:     /**
6004:      * Initializes the backBuffers field with an array of numBuffers
6005:      * VolatileImages.
6006:      *
6007:      * @param numBuffers the number of backbuffers to create
6008:      */
6009:     protected void createBackBuffers(int numBuffers)
6010:     {
6011:       GraphicsConfiguration c =
6012:     GraphicsEnvironment.getLocalGraphicsEnvironment()
6013:     .getDefaultScreenDevice().getDefaultConfiguration();
6014: 
6015:       backBuffers = new VolatileImage[numBuffers];
6016: 
6017:       for (int i = 0; i < numBuffers; i++)
6018:     backBuffers[i] = c.createCompatibleVolatileImage(width, height);
6019:     }
6020: 
6021:     /**
6022:      * Retrieves the capabilities of this buffer strategy.
6023:      *
6024:      * @return the capabilities of this buffer strategy
6025:      */
6026:     public BufferCapabilities getCapabilities()
6027:     {
6028:       return caps;
6029:     }
6030: 
6031:     /**
6032:      * Retrieves a graphics object that can be used to draw into this
6033:      * strategy's image buffer.
6034:      *
6035:      * @return a graphics object
6036:      */
6037:     public Graphics getDrawGraphics()
6038:     {
6039:       // Return the backmost buffer's graphics.
6040:       return backBuffers[0].getGraphics();
6041:     }
6042: 
6043:     /**
6044:      * Bring the contents of the back buffer to the front buffer.
6045:      */
6046:     public void show()
6047:     {
6048:       GraphicsConfiguration c =
6049:     GraphicsEnvironment.getLocalGraphicsEnvironment()
6050:     .getDefaultScreenDevice().getDefaultConfiguration();
6051: 
6052:       // draw the front buffer.
6053:       getGraphics().drawImage(backBuffers[backBuffers.length - 1],
6054:                   width, height, null);
6055: 
6056:       BufferCapabilities.FlipContents f = getCapabilities().getFlipContents();
6057: 
6058:       // blit the back buffers.
6059:       for (int i = backBuffers.length - 1; i > 0 ; i--)
6060:     backBuffers[i] = backBuffers[i - 1];
6061: 
6062:       // create new backmost buffer.
6063:       if (f == BufferCapabilities.FlipContents.UNDEFINED)
6064:     backBuffers[0] = c.createCompatibleVolatileImage(width, height);
6065: 
6066:       // create new backmost buffer and clear it to the background
6067:       // color.
6068:       if (f == BufferCapabilities.FlipContents.BACKGROUND)
6069:     {
6070:       backBuffers[0] = c.createCompatibleVolatileImage(width, height);
6071:       backBuffers[0].getGraphics().clearRect(0, 0, width, height);
6072:     }
6073: 
6074:       // FIXME: set the backmost buffer to the prior contents of the
6075:       // front buffer.  How do we retrieve the contents of the front
6076:       // buffer?
6077:       //
6078:       //      if (f == BufferCapabilities.FlipContents.PRIOR)
6079: 
6080:       // set the backmost buffer to a copy of the new front buffer.
6081:       if (f == BufferCapabilities.FlipContents.COPIED)
6082:     backBuffers[0] = backBuffers[backBuffers.length - 1];
6083:     }
6084: 
6085:     /**
6086:      * Re-create the image buffer resources if they've been lost.
6087:      */
6088:     protected void revalidate()
6089:     {
6090:       GraphicsConfiguration c =
6091:     GraphicsEnvironment.getLocalGraphicsEnvironment()
6092:     .getDefaultScreenDevice().getDefaultConfiguration();
6093: 
6094:       for (int i = 0; i < backBuffers.length; i++)
6095:     {
6096:       int result = backBuffers[i].validate(c);
6097:       if (result == VolatileImage.IMAGE_INCOMPATIBLE)
6098:         backBuffers[i] = c.createCompatibleVolatileImage(width, height);
6099:     }
6100:       validatedContents = true;
6101:     }
6102: 
6103:     /**
6104:      * Returns whether or not the image buffer resources have been
6105:      * lost.
6106:      *
6107:      * @return true if the resources have been lost, false otherwise
6108:      */
6109:     public boolean contentsLost()
6110:     {
6111:       for (int i = 0; i < backBuffers.length; i++)
6112:     {
6113:       if (backBuffers[i].contentsLost())
6114:         {
6115:           validatedContents = false;
6116:           return true;
6117:         }
6118:     }
6119:       // we know that the buffer resources are valid now because we
6120:       // just checked them
6121:       validatedContents = true;
6122:       return false;
6123:     }
6124: 
6125:     /**
6126:      * Returns whether or not the image buffer resources have been
6127:      * restored.
6128:      *
6129:      * @return true if the resources have been restored, false
6130:      * otherwise
6131:      */
6132:     public boolean contentsRestored()
6133:     {
6134:       GraphicsConfiguration c =
6135:     GraphicsEnvironment.getLocalGraphicsEnvironment()
6136:     .getDefaultScreenDevice().getDefaultConfiguration();
6137: 
6138:       boolean imageRestored = false;
6139: 
6140:       for (int i = 0; i < backBuffers.length; i++)
6141:     {
6142:       int result = backBuffers[i].validate(c);
6143:       if (result == VolatileImage.IMAGE_RESTORED)
6144:         imageRestored = true;
6145:       else if (result == VolatileImage.IMAGE_INCOMPATIBLE)
6146:         return false;
6147:     }
6148:       // we know that the buffer resources are valid now because we
6149:       // just checked them
6150:       validatedContents = true;
6151:       return imageRestored;
6152:     }
6153:   }
6154: 
6155:   /**
6156:    * This class provides support for flipping component buffers. It
6157:    * can only be used on Canvases and Windows.
6158:    *
6159:    * @since 1.4
6160:    */
6161:   protected class FlipBufferStrategy extends BufferStrategy
6162:   {
6163:     /**
6164:      * The number of buffers.
6165:      */
6166:     protected int numBuffers;
6167: 
6168:     /**
6169:      * The capabilities of this buffering strategy.
6170:      */
6171:     protected BufferCapabilities caps;
6172: 
6173:     /**
6174:      * An Image reference to the drawing buffer.
6175:      */
6176:     protected Image drawBuffer;
6177: 
6178:     /**
6179:      * A VolatileImage reference to the drawing buffer.
6180:      */
6181:     protected VolatileImage drawVBuffer;
6182: 
6183:     /**
6184:      * Whether or not the image buffer resources are allocated and
6185:      * ready to be drawn into.
6186:      */
6187:     protected boolean validatedContents;
6188: 
6189:     /**
6190:      * The width of the back buffer.
6191:      */
6192:     private int width;
6193: 
6194:     /**
6195:      * The height of the back buffer.
6196:      */
6197:     private int height;
6198: 
6199:     /**
6200:      * Creates a flipping buffer strategy.  The only supported
6201:      * strategy for FlipBufferStrategy itself is a double-buffer page
6202:      * flipping strategy.  It forms the basis for more complex derived
6203:      * strategies.
6204:      *
6205:      * @param numBuffers the number of buffers
6206:      * @param caps the capabilities of this buffering strategy
6207:      *
6208:      * @throws AWTException if the requested
6209:      * number-of-buffers/capabilities combination is not supported
6210:      */
6211:     protected FlipBufferStrategy(int numBuffers, BufferCapabilities caps)
6212:       throws AWTException
6213:     {
6214:       this.caps = caps;
6215:       width = getWidth();
6216:       height = getHeight();
6217: 
6218:       if (numBuffers > 1)
6219:     createBuffers(numBuffers, caps);
6220:       else
6221:     {
6222:       drawVBuffer = peer.createVolatileImage(width, height);
6223:       drawBuffer = drawVBuffer;
6224:     }
6225:     }
6226: 
6227:     /**
6228:      * Creates a multi-buffer flipping strategy.  The number of
6229:      * buffers must be greater than one and the buffer capabilities
6230:      * must specify page flipping.
6231:      *
6232:      * @param numBuffers the number of flipping buffers; must be
6233:      * greater than one
6234:      * @param caps the buffering capabilities; caps.isPageFlipping()
6235:      * must return true
6236:      *
6237:      * @throws IllegalArgumentException if numBuffers is not greater
6238:      * than one or if the page flipping capability is not requested
6239:      *
6240:      * @throws AWTException if the requested flipping strategy is not
6241:      * supported
6242:      */
6243:     protected void createBuffers(int numBuffers, BufferCapabilities caps)
6244:       throws AWTException
6245:     {
6246:       if (numBuffers <= 1)
6247:     throw new IllegalArgumentException("FlipBufferStrategy.createBuffers:"
6248:                        + " numBuffers must be greater than"
6249:                        + " one.");
6250: 
6251:       if (!caps.isPageFlipping())
6252:     throw new IllegalArgumentException("FlipBufferStrategy.createBuffers:"
6253:                        + " flipping must be a specified"
6254:                        + " capability.");
6255: 
6256:       peer.createBuffers(numBuffers, caps);
6257:     }
6258: 
6259:     /**
6260:      * Return a direct reference to the back buffer image.
6261:      *
6262:      * @return a direct reference to the back buffer image.
6263:      */
6264:     protected Image getBackBuffer()
6265:     {
6266:       return peer.getBackBuffer();
6267:     }
6268: 
6269:     /**
6270:      * Perform a flip operation to transfer the contents of the back
6271:      * buffer to the front buffer.
6272:      */
6273:     protected void flip(BufferCapabilities.FlipContents flipAction)
6274:     {
6275:       peer.flip(flipAction);
6276:     }
6277: 
6278:     /**
6279:      * Release the back buffer's resources.
6280:      */
6281:     protected void destroyBuffers()
6282:     {
6283:       peer.destroyBuffers();
6284:     }
6285: 
6286:     /**
6287:      * Retrieves the capabilities of this buffer strategy.
6288:      *
6289:      * @return the capabilities of this buffer strategy
6290:      */
6291:     public BufferCapabilities getCapabilities()
6292:     {
6293:       return caps;
6294:     }
6295: 
6296:     /**
6297:      * Retrieves a graphics object that can be used to draw into this
6298:      * strategy's image buffer.
6299:      *
6300:      * @return a graphics object
6301:      */
6302:     public Graphics getDrawGraphics()
6303:     {
6304:       return drawVBuffer.getGraphics();
6305:     }
6306: 
6307:     /**
6308:      * Re-create the image buffer resources if they've been lost.
6309:      */
6310:     protected void revalidate()
6311:     {
6312:       GraphicsConfiguration c =
6313:     GraphicsEnvironment.getLocalGraphicsEnvironment()
6314:     .getDefaultScreenDevice().getDefaultConfiguration();
6315: 
6316:       if (drawVBuffer.validate(c) == VolatileImage.IMAGE_INCOMPATIBLE)
6317:     drawVBuffer = peer.createVolatileImage(width, height);
6318:       validatedContents = true;
6319:     }
6320: 
6321:     /**
6322:      * Returns whether or not the image buffer resources have been
6323:      * lost.
6324:      *
6325:      * @return true if the resources have been lost, false otherwise
6326:      */
6327:     public boolean contentsLost()
6328:     {
6329:       if (drawVBuffer.contentsLost())
6330:     {
6331:       validatedContents = false;
6332:       return true;
6333:     }
6334:       // we know that the buffer resources are valid now because we
6335:       // just checked them
6336:       validatedContents = true;
6337:       return false;
6338:     }
6339: 
6340:     /**
6341:      * Returns whether or not the image buffer resources have been
6342:      * restored.
6343:      *
6344:      * @return true if the resources have been restored, false
6345:      * otherwise
6346:      */
6347:     public boolean contentsRestored()
6348:     {
6349:       GraphicsConfiguration c =
6350:     GraphicsEnvironment.getLocalGraphicsEnvironment()
6351:     .getDefaultScreenDevice().getDefaultConfiguration();
6352: 
6353:       int result = drawVBuffer.validate(c);
6354: 
6355:       boolean imageRestored = false;
6356: 
6357:       if (result == VolatileImage.IMAGE_RESTORED)
6358:     imageRestored = true;
6359:       else if (result == VolatileImage.IMAGE_INCOMPATIBLE)
6360:     return false;
6361: 
6362:       // we know that the buffer resources are valid now because we
6363:       // just checked them
6364:       validatedContents = true;
6365:       return imageRestored;
6366:     }
6367: 
6368:     /**
6369:      * Bring the contents of the back buffer to the front buffer.
6370:      */
6371:     public void show()
6372:     {
6373:       flip(caps.getFlipContents());
6374:     }
6375:   }
6376: }