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