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