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