Source for java.awt.Component

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