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