1 /*
   2  * Copyright 1995-2009 Sun Microsystems, Inc.  All Rights Reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Sun designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Sun in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22  * CA 95054 USA or visit www.sun.com if you need additional information or
  23  * have any questions.
  24  */
  25 package java.awt;
  26 
  27 import java.io.PrintStream;
  28 import java.io.PrintWriter;
  29 import java.util.Vector;
  30 import java.util.Locale;
  31 import java.util.EventListener;
  32 import java.util.Iterator;
  33 import java.util.HashSet;
  34 import java.util.Map;
  35 import java.util.Set;
  36 import java.util.Collections;
  37 import java.awt.peer.ComponentPeer;
  38 import java.awt.peer.ContainerPeer;
  39 import java.awt.peer.LightweightPeer;
  40 import java.awt.image.BufferStrategy;
  41 import java.awt.image.ImageObserver;
  42 import java.awt.image.ImageProducer;
  43 import java.awt.image.ColorModel;
  44 import java.awt.image.VolatileImage;
  45 import java.awt.event.*;
  46 import java.io.Serializable;
  47 import java.io.ObjectOutputStream;
  48 import java.io.ObjectInputStream;
  49 import java.io.IOException;
  50 import java.beans.PropertyChangeListener;
  51 import java.beans.PropertyChangeSupport;
  52 import java.beans.Transient;
  53 import java.awt.event.InputMethodListener;
  54 import java.awt.event.InputMethodEvent;
  55 import java.awt.im.InputContext;
  56 import java.awt.im.InputMethodRequests;
  57 import java.awt.dnd.DropTarget;
  58 import java.lang.reflect.InvocationTargetException;
  59 import java.lang.reflect.Method;
  60 import java.security.AccessController;
  61 import java.security.PrivilegedAction;
  62 import javax.accessibility.*;
  63 import java.util.logging.*;
  64 import java.applet.Applet;
  65 
  66 import sun.security.action.GetPropertyAction;
  67 import sun.awt.AppContext;
  68 import sun.awt.AWTAccessor;
  69 import sun.awt.ConstrainableGraphics;
  70 import sun.awt.SubRegionShowable;
  71 import sun.awt.SunToolkit;
  72 import sun.awt.WindowClosingListener;
  73 import sun.awt.CausedFocusEvent;
  74 import sun.awt.EmbeddedFrame;
  75 import sun.awt.dnd.SunDropTargetEvent;
  76 import sun.awt.im.CompositionArea;
  77 import sun.java2d.SunGraphics2D;
  78 import sun.java2d.pipe.Region;
  79 import sun.awt.image.VSyncedBSManager;
  80 import sun.java2d.pipe.hw.ExtendedBufferCapabilities;
  81 import static sun.java2d.pipe.hw.ExtendedBufferCapabilities.VSyncType.*;
  82 import sun.awt.RequestFocusController;
  83 import sun.java2d.SunGraphicsEnvironment;
  84 
  85 /**
  86  * A <em>component</em> is an object having a graphical representation
  87  * that can be displayed on the screen and that can interact with the
  88  * user. Examples of components are the buttons, checkboxes, and scrollbars
  89  * of a typical graphical user interface. <p>
  90  * The <code>Component</code> class is the abstract superclass of
  91  * the nonmenu-related Abstract Window Toolkit components. Class
  92  * <code>Component</code> can also be extended directly to create a
  93  * lightweight component. A lightweight component is a component that is
  94  * not associated with a native opaque window.
  95  * <p>
  96  * <h3>Serialization</h3>
  97  * It is important to note that only AWT listeners which conform
  98  * to the <code>Serializable</code> protocol will be saved when
  99  * the object is stored.  If an AWT object has listeners that
 100  * aren't marked serializable, they will be dropped at
 101  * <code>writeObject</code> time.  Developers will need, as always,
 102  * to consider the implications of making an object serializable.
 103  * One situation to watch out for is this:
 104  * <pre>
 105  *    import java.awt.*;
 106  *    import java.awt.event.*;
 107  *    import java.io.Serializable;
 108  *
 109  *    class MyApp implements ActionListener, Serializable
 110  *    {
 111  *        BigObjectThatShouldNotBeSerializedWithAButton bigOne;
 112  *        Button aButton = new Button();
 113  *
 114  *        MyApp()
 115  *        {
 116  *            // Oops, now aButton has a listener with a reference
 117  *            // to bigOne!
 118  *            aButton.addActionListener(this);
 119  *        }
 120  *
 121  *        public void actionPerformed(ActionEvent e)
 122  *        {
 123  *            System.out.println("Hello There");
 124  *        }
 125  *    }
 126  * </pre>
 127  * In this example, serializing <code>aButton</code> by itself
 128  * will cause <code>MyApp</code> and everything it refers to
 129  * to be serialized as well.  The problem is that the listener
 130  * is serializable by coincidence, not by design.  To separate
 131  * the decisions about <code>MyApp</code> and the
 132  * <code>ActionListener</code> being serializable one can use a
 133  * nested class, as in the following example:
 134  * <pre>
 135  *    import java.awt.*;
 136  *    import java.awt.event.*;
 137  *    import java.io.Serializable;
 138  *
 139  *    class MyApp java.io.Serializable
 140  *    {
 141  *         BigObjectThatShouldNotBeSerializedWithAButton bigOne;
 142  *         Button aButton = new Button();
 143  *
 144  *         static class MyActionListener implements ActionListener
 145  *         {
 146  *             public void actionPerformed(ActionEvent e)
 147  *             {
 148  *                 System.out.println("Hello There");
 149  *             }
 150  *         }
 151  *
 152  *         MyApp()
 153  *         {
 154  *             aButton.addActionListener(new MyActionListener());
 155  *         }
 156  *    }
 157  * </pre>
 158  * <p>
 159  * <b>Note</b>: For more information on the paint mechanisms utilitized
 160  * by AWT and Swing, including information on how to write the most
 161  * efficient painting code, see
 162  * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
 163  * <p>
 164  * For details on the focus subsystem, see
 165  * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
 166  * How to Use the Focus Subsystem</a>,
 167  * a section in <em>The Java Tutorial</em>, and the
 168  * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
 169  * for more information.
 170  *
 171  * @author      Arthur van Hoff
 172  * @author      Sami Shaio
 173  */
 174 public abstract class Component implements ImageObserver, MenuContainer,
 175                                            Serializable
 176 {
 177 
 178     private static final Logger log = Logger.getLogger("java.awt.Component");
 179     private static final Logger eventLog = Logger.getLogger("java.awt.event.Component");
 180     private static final Logger focusLog = Logger.getLogger("java.awt.focus.Component");
 181     private static final Logger mixingLog = Logger.getLogger("java.awt.mixing.Component");
 182 
 183     /**
 184      * The peer of the component. The peer implements the component's
 185      * behavior. The peer is set when the <code>Component</code> is
 186      * added to a container that also is a peer.
 187      * @see #addNotify
 188      * @see #removeNotify
 189      */
 190     transient ComponentPeer peer;
 191 
 192     /**
 193      * The parent of the object. It may be <code>null</code>
 194      * for top-level components.
 195      * @see #getParent
 196      */
 197     transient Container parent;
 198 
 199     /**
 200      * The <code>AppContext</code> of the component. Applets/Plugin may
 201      * change the AppContext.
 202      */
 203     transient AppContext appContext;
 204 
 205     /**
 206      * The x position of the component in the parent's coordinate system.
 207      *
 208      * @serial
 209      * @see #getLocation
 210      */
 211     int x;
 212 
 213     /**
 214      * The y position of the component in the parent's coordinate system.
 215      *
 216      * @serial
 217      * @see #getLocation
 218      */
 219     int y;
 220 
 221     /**
 222      * The width of the component.
 223      *
 224      * @serial
 225      * @see #getSize
 226      */
 227     int width;
 228 
 229     /**
 230      * The height of the component.
 231      *
 232      * @serial
 233      * @see #getSize
 234      */
 235     int height;
 236 
 237     /**
 238      * The foreground color for this component.
 239      * <code>foreground</code> can be <code>null</code>.
 240      *
 241      * @serial
 242      * @see #getForeground
 243      * @see #setForeground
 244      */
 245     Color       foreground;
 246 
 247     /**
 248      * The background color for this component.
 249      * <code>background</code> can be <code>null</code>.
 250      *
 251      * @serial
 252      * @see #getBackground
 253      * @see #setBackground
 254      */
 255     Color       background;
 256 
 257     /**
 258      * The font used by this component.
 259      * The <code>font</code> can be <code>null</code>.
 260      *
 261      * @serial
 262      * @see #getFont
 263      * @see #setFont
 264      */
 265     Font        font;
 266 
 267     /**
 268      * The font which the peer is currently using.
 269      * (<code>null</code> if no peer exists.)
 270      */
 271     Font        peerFont;
 272 
 273     /**
 274      * The cursor displayed when pointer is over this component.
 275      * This value can be <code>null</code>.
 276      *
 277      * @serial
 278      * @see #getCursor
 279      * @see #setCursor
 280      */
 281     Cursor      cursor;
 282 
 283     /**
 284      * The locale for the component.
 285      *
 286      * @serial
 287      * @see #getLocale
 288      * @see #setLocale
 289      */
 290     Locale      locale;
 291 
 292     /**
 293      * A reference to a <code>GraphicsConfiguration</code> object
 294      * used to describe the characteristics of a graphics
 295      * destination.
 296      * This value can be <code>null</code>.
 297      *
 298      * @since 1.3
 299      * @serial
 300      * @see GraphicsConfiguration
 301      * @see #getGraphicsConfiguration
 302      */
 303     private transient GraphicsConfiguration graphicsConfig = null;
 304 
 305     /**
 306      * A reference to a <code>BufferStrategy</code> object
 307      * used to manipulate the buffers on this component.
 308      *
 309      * @since 1.4
 310      * @see java.awt.image.BufferStrategy
 311      * @see #getBufferStrategy()
 312      */
 313     transient BufferStrategy bufferStrategy = null;
 314 
 315     /**
 316      * True when the object should ignore all repaint events.
 317      *
 318      * @since 1.4
 319      * @serial
 320      * @see #setIgnoreRepaint
 321      * @see #getIgnoreRepaint
 322      */
 323     boolean ignoreRepaint = false;
 324 
 325     /**
 326      * True when the object is visible. An object that is not
 327      * visible is not drawn on the screen.
 328      *
 329      * @serial
 330      * @see #isVisible
 331      * @see #setVisible
 332      */
 333     boolean visible = true;
 334 
 335     /**
 336      * True when the object is enabled. An object that is not
 337      * enabled does not interact with the user.
 338      *
 339      * @serial
 340      * @see #isEnabled
 341      * @see #setEnabled
 342      */
 343     boolean enabled = true;
 344 
 345     /**
 346      * True when the object is valid. An invalid object needs to
 347      * be layed out. This flag is set to false when the object
 348      * size is changed.
 349      *
 350      * @serial
 351      * @see #isValid
 352      * @see #validate
 353      * @see #invalidate
 354      */
 355     private volatile boolean valid = false;
 356 
 357     /**
 358      * The <code>DropTarget</code> associated with this component.
 359      *
 360      * @since 1.2
 361      * @serial
 362      * @see #setDropTarget
 363      * @see #getDropTarget
 364      */
 365     DropTarget dropTarget;
 366 
 367     /**
 368      * @serial
 369      * @see #add
 370      */
 371     Vector popups;
 372 
 373     /**
 374      * A component's name.
 375      * This field can be <code>null</code>.
 376      *
 377      * @serial
 378      * @see #getName
 379      * @see #setName(String)
 380      */
 381     private String name;
 382 
 383     /**
 384      * A bool to determine whether the name has
 385      * been set explicitly. <code>nameExplicitlySet</code> will
 386      * be false if the name has not been set and
 387      * true if it has.
 388      *
 389      * @serial
 390      * @see #getName
 391      * @see #setName(String)
 392      */
 393     private boolean nameExplicitlySet = false;
 394 
 395     /**
 396      * Indicates whether this Component can be focused.
 397      *
 398      * @serial
 399      * @see #setFocusable
 400      * @see #isFocusable
 401      * @since 1.4
 402      */
 403     private boolean focusable = true;
 404 
 405     private static final int FOCUS_TRAVERSABLE_UNKNOWN = 0;
 406     private static final int FOCUS_TRAVERSABLE_DEFAULT = 1;
 407     private static final int FOCUS_TRAVERSABLE_SET = 2;
 408 
 409     /**
 410      * Tracks whether this Component is relying on default focus travesability.
 411      *
 412      * @serial
 413      * @since 1.4
 414      */
 415     private int isFocusTraversableOverridden = FOCUS_TRAVERSABLE_UNKNOWN;
 416 
 417     /**
 418      * The focus traversal keys. These keys will generate focus traversal
 419      * behavior for Components for which focus traversal keys are enabled. If a
 420      * value of null is specified for a traversal key, this Component inherits
 421      * that traversal key from its parent. If all ancestors of this Component
 422      * have null specified for that traversal key, then the current
 423      * KeyboardFocusManager's default traversal key is used.
 424      *
 425      * @serial
 426      * @see #setFocusTraversalKeys
 427      * @see #getFocusTraversalKeys
 428      * @since 1.4
 429      */
 430     Set[] focusTraversalKeys;
 431 
 432     private static final String[] focusTraversalKeyPropertyNames = {
 433         "forwardFocusTraversalKeys",
 434         "backwardFocusTraversalKeys",
 435         "upCycleFocusTraversalKeys",
 436         "downCycleFocusTraversalKeys"
 437     };
 438 
 439     /**
 440      * Indicates whether focus traversal keys are enabled for this Component.
 441      * Components for which focus traversal keys are disabled receive key
 442      * events for focus traversal keys. Components for which focus traversal
 443      * keys are enabled do not see these events; instead, the events are
 444      * automatically converted to traversal operations.
 445      *
 446      * @serial
 447      * @see #setFocusTraversalKeysEnabled
 448      * @see #getFocusTraversalKeysEnabled
 449      * @since 1.4
 450      */
 451     private boolean focusTraversalKeysEnabled = true;
 452 
 453     /**
 454      * The locking object for AWT component-tree and layout operations.
 455      *
 456      * @see #getTreeLock
 457      */
 458     static final Object LOCK = new AWTTreeLock();
 459     static class AWTTreeLock {}
 460 
 461     /**
 462      * Minimum size.
 463      * (This field perhaps should have been transient).
 464      *
 465      * @serial
 466      */
 467     Dimension minSize;
 468 
 469     /**
 470      * Whether or not setMinimumSize has been invoked with a non-null value.
 471      */
 472     boolean minSizeSet;
 473 
 474     /**
 475      * Preferred size.
 476      * (This field perhaps should have been transient).
 477      *
 478      * @serial
 479      */
 480     Dimension prefSize;
 481 
 482     /**
 483      * Whether or not setPreferredSize has been invoked with a non-null value.
 484      */
 485     boolean prefSizeSet;
 486 
 487     /**
 488      * Maximum size
 489      *
 490      * @serial
 491      */
 492     Dimension maxSize;
 493 
 494     /**
 495      * Whether or not setMaximumSize has been invoked with a non-null value.
 496      */
 497     boolean maxSizeSet;
 498 
 499     /**
 500      * The orientation for this component.
 501      * @see #getComponentOrientation
 502      * @see #setComponentOrientation
 503      */
 504     transient ComponentOrientation componentOrientation
 505     = ComponentOrientation.UNKNOWN;
 506 
 507     /**
 508      * <code>newEventsOnly</code> will be true if the event is
 509      * one of the event types enabled for the component.
 510      * It will then allow for normal processing to
 511      * continue.  If it is false the event is passed
 512      * to the component's parent and up the ancestor
 513      * tree until the event has been consumed.
 514      *
 515      * @serial
 516      * @see #dispatchEvent
 517      */
 518     boolean newEventsOnly = false;
 519     transient ComponentListener componentListener;
 520     transient FocusListener focusListener;
 521     transient HierarchyListener hierarchyListener;
 522     transient HierarchyBoundsListener hierarchyBoundsListener;
 523     transient KeyListener keyListener;
 524     transient MouseListener mouseListener;
 525     transient MouseMotionListener mouseMotionListener;
 526     transient MouseWheelListener mouseWheelListener;
 527     transient InputMethodListener inputMethodListener;
 528 
 529     transient RuntimeException windowClosingException = null;
 530 
 531     /** Internal, constants for serialization */
 532     final static String actionListenerK = "actionL";
 533     final static String adjustmentListenerK = "adjustmentL";
 534     final static String componentListenerK = "componentL";
 535     final static String containerListenerK = "containerL";
 536     final static String focusListenerK = "focusL";
 537     final static String itemListenerK = "itemL";
 538     final static String keyListenerK = "keyL";
 539     final static String mouseListenerK = "mouseL";
 540     final static String mouseMotionListenerK = "mouseMotionL";
 541     final static String mouseWheelListenerK = "mouseWheelL";
 542     final static String textListenerK = "textL";
 543     final static String ownedWindowK = "ownedL";
 544     final static String windowListenerK = "windowL";
 545     final static String inputMethodListenerK = "inputMethodL";
 546     final static String hierarchyListenerK = "hierarchyL";
 547     final static String hierarchyBoundsListenerK = "hierarchyBoundsL";
 548     final static String windowStateListenerK = "windowStateL";
 549     final static String windowFocusListenerK = "windowFocusL";
 550 
 551     /**
 552      * The <code>eventMask</code> is ONLY set by subclasses via
 553      * <code>enableEvents</code>.
 554      * The mask should NOT be set when listeners are registered
 555      * so that we can distinguish the difference between when
 556      * listeners request events and subclasses request them.
 557      * One bit is used to indicate whether input methods are
 558      * enabled; this bit is set by <code>enableInputMethods</code> and is
 559      * on by default.
 560      *
 561      * @serial
 562      * @see #enableInputMethods
 563      * @see AWTEvent
 564      */
 565     long eventMask = AWTEvent.INPUT_METHODS_ENABLED_MASK;
 566 
 567     /**
 568      * Static properties for incremental drawing.
 569      * @see #imageUpdate
 570      */
 571     static boolean isInc;
 572     static int incRate;
 573     static {
 574         /* ensure that the necessary native libraries are loaded */
 575         Toolkit.loadLibraries();
 576         /* initialize JNI field and method ids */
 577         if (!GraphicsEnvironment.isHeadless()) {
 578             initIDs();
 579         }
 580 
 581         String s = (String) java.security.AccessController.doPrivileged(
 582                                                                         new GetPropertyAction("awt.image.incrementaldraw"));
 583         isInc = (s == null || s.equals("true"));
 584 
 585         s = (String) java.security.AccessController.doPrivileged(
 586                                                                  new GetPropertyAction("awt.image.redrawrate"));
 587         incRate = (s != null) ? Integer.parseInt(s) : 100;
 588     }
 589 
 590     /**
 591      * Ease-of-use constant for <code>getAlignmentY()</code>.
 592      * Specifies an alignment to the top of the component.
 593      * @see     #getAlignmentY
 594      */
 595     public static final float TOP_ALIGNMENT = 0.0f;
 596 
 597     /**
 598      * Ease-of-use constant for <code>getAlignmentY</code> and
 599      * <code>getAlignmentX</code>. Specifies an alignment to
 600      * the center of the component
 601      * @see     #getAlignmentX
 602      * @see     #getAlignmentY
 603      */
 604     public static final float CENTER_ALIGNMENT = 0.5f;
 605 
 606     /**
 607      * Ease-of-use constant for <code>getAlignmentY</code>.
 608      * Specifies an alignment to the bottom of the component.
 609      * @see     #getAlignmentY
 610      */
 611     public static final float BOTTOM_ALIGNMENT = 1.0f;
 612 
 613     /**
 614      * Ease-of-use constant for <code>getAlignmentX</code>.
 615      * Specifies an alignment to the left side of the component.
 616      * @see     #getAlignmentX
 617      */
 618     public static final float LEFT_ALIGNMENT = 0.0f;
 619 
 620     /**
 621      * Ease-of-use constant for <code>getAlignmentX</code>.
 622      * Specifies an alignment to the right side of the component.
 623      * @see     #getAlignmentX
 624      */
 625     public static final float RIGHT_ALIGNMENT = 1.0f;
 626 
 627     /*
 628      * JDK 1.1 serialVersionUID
 629      */
 630     private static final long serialVersionUID = -7644114512714619750L;
 631 
 632     /**
 633      * If any <code>PropertyChangeListeners</code> have been registered,
 634      * the <code>changeSupport</code> field describes them.
 635      *
 636      * @serial
 637      * @since 1.2
 638      * @see #addPropertyChangeListener
 639      * @see #removePropertyChangeListener
 640      * @see #firePropertyChange
 641      */
 642     private PropertyChangeSupport changeSupport;
 643 
 644     /*
 645      * In some cases using "this" as an object to synchronize by
 646      * can lead to a deadlock if client code also uses synchronization
 647      * by a component object. For every such situation revealed we should
 648      * consider possibility of replacing "this" with the package private
 649      * objectLock object introduced below. So far there're 2 issues known:
 650      * - CR 6708322 (the getName/setName methods);
 651      * - CR 6608764 (the PropertyChangeListener machinery).
 652      *
 653      * Note: this field is considered final, though readObject() prohibits
 654      * initializing final fields.
 655      */
 656     private transient Object objectLock = new Object();
 657     Object getObjectLock() {
 658         return objectLock;
 659     }
 660 
 661     /**
 662      * Indicates if the window has been packed via pack().
 663      *
 664      * Note that this field belongs to the Window class, but it cannot be
 665      * moved to that class because it is not transient, and therefore must
 666      * stay at the Component class for backward-compatibility purposes.
 667      * The field SHOULD NOT be used anywhere outside of the Window class.
 668      */
 669     boolean isPacked = false;
 670 
 671     /**
 672      * Pseudoparameter for direct Geometry API (setLocation, setBounds setSize
 673      * to signal setBounds what's changing. Should be used under TreeLock.
 674      * This is only needed due to the inability to change the cross-calling
 675      * order of public and deprecated methods.
 676      */
 677     private int boundsOp = ComponentPeer.DEFAULT_OPERATION;
 678 
 679     /**
 680      * Enumeration of the common ways the baseline of a component can
 681      * change as the size changes.  The baseline resize behavior is
 682      * primarily for layout managers that need to know how the
 683      * position of the baseline changes as the component size changes.
 684      * In general the baseline resize behavior will be valid for sizes
 685      * greater than or equal to the minimum size (the actual minimum
 686      * size; not a developer specified minimum size).  For sizes
 687      * smaller than the minimum size the baseline may change in a way
 688      * other than the baseline resize behavior indicates.  Similarly,
 689      * as the size approaches <code>Integer.MAX_VALUE</code> and/or
 690      * <code>Short.MAX_VALUE</code> the baseline may change in a way
 691      * other than the baseline resize behavior indicates.
 692      *
 693      * @see #getBaselineResizeBehavior
 694      * @see #getBaseline(int,int)
 695      * @since 1.6
 696      */
 697     public enum BaselineResizeBehavior {
 698         /**
 699          * Indicates the baseline remains fixed relative to the
 700          * y-origin.  That is, <code>getBaseline</code> returns
 701          * the same value regardless of the height or width.  For example, a
 702          * <code>JLabel</code> containing non-empty text with a
 703          * vertical alignment of <code>TOP</code> should have a
 704          * baseline type of <code>CONSTANT_ASCENT</code>.
 705          */
 706         CONSTANT_ASCENT,
 707 
 708         /**
 709          * Indicates the baseline remains fixed relative to the height
 710          * and does not change as the width is varied.  That is, for
 711          * any height H the difference between H and
 712          * <code>getBaseline(w, H)</code> is the same.  For example, a
 713          * <code>JLabel</code> containing non-empty text with a
 714          * vertical alignment of <code>BOTTOM</code> should have a
 715          * baseline type of <code>CONSTANT_DESCENT</code>.
 716          */
 717         CONSTANT_DESCENT,
 718 
 719         /**
 720          * Indicates the baseline remains a fixed distance from
 721          * the center of the component.  That is, for any height H the
 722          * difference between <code>getBaseline(w, H)</code> and
 723          * <code>H / 2</code> is the same (plus or minus one depending upon
 724          * rounding error).
 725          * <p>
 726          * Because of possible rounding errors it is recommended
 727          * you ask for the baseline with two consecutive heights and use
 728          * the return value to determine if you need to pad calculations
 729          * by 1.  The following shows how to calculate the baseline for
 730          * any height:
 731          * <pre>
 732          *   Dimension preferredSize = component.getPreferredSize();
 733          *   int baseline = getBaseline(preferredSize.width,
 734          *                              preferredSize.height);
 735          *   int nextBaseline = getBaseline(preferredSize.width,
 736          *                                  preferredSize.height + 1);
 737          *   // Amount to add to height when calculating where baseline
 738          *   // lands for a particular height:
 739          *   int padding = 0;
 740          *   // Where the baseline is relative to the mid point
 741          *   int baselineOffset = baseline - height / 2;
 742          *   if (preferredSize.height % 2 == 0 &amp;&amp;
 743          *       baseline != nextBaseline) {
 744          *       padding = 1;
 745          *   }
 746          *   else if (preferredSize.height % 2 == 1 &amp;&amp;
 747          *            baseline == nextBaseline) {
 748          *       baselineOffset--;
 749          *       padding = 1;
 750          *   }
 751          *   // The following calculates where the baseline lands for
 752          *   // the height z:
 753          *   int calculatedBaseline = (z + padding) / 2 + baselineOffset;
 754          * </pre>
 755          */
 756         CENTER_OFFSET,
 757 
 758         /**
 759          * Indicates the baseline resize behavior can not be expressed using
 760          * any of the other constants.  This may also indicate the baseline
 761          * varies with the width of the component.  This is also returned
 762          * by components that do not have a baseline.
 763          */
 764         OTHER
 765     }
 766 
 767     /*
 768      * The shape set with the applyCompoundShape() method. It uncludes the result
 769      * of the HW/LW mixing related shape computation. It may also include
 770      * the user-specified shape of the component.
 771      * The 'null' value means the component has normal shape (or has no shape at all)
 772      * and applyCompoundShape() will skip the following shape identical to normal.
 773      */
 774     private transient Region compoundShape = null;
 775 
 776     /*
 777      * Represents the shape of this lightweight component to be cut out from
 778      * heavyweight components should they intersect. Possible values:
 779      *    1. null - consider the shape rectangular
 780      *    2. EMPTY_REGION - nothing gets cut out (children still get cut out)
 781      *    3. non-empty - this shape gets cut out.
 782      */
 783     private transient Region mixingCutoutRegion = null;
 784 
 785     /*
 786      * Indicates whether addNotify() is complete
 787      * (i.e. the peer is created).
 788      */
 789     private transient boolean isAddNotifyComplete = false;
 790 
 791     /**
 792      * Should only be used in subclass getBounds to check that part of bounds
 793      * is actualy changing
 794      */
 795     int getBoundsOp() {
 796         assert Thread.holdsLock(getTreeLock());
 797         return boundsOp;
 798     }
 799 
 800     void setBoundsOp(int op) {
 801         assert Thread.holdsLock(getTreeLock());
 802         if (op == ComponentPeer.RESET_OPERATION) {
 803             boundsOp = ComponentPeer.DEFAULT_OPERATION;
 804         } else
 805             if (boundsOp == ComponentPeer.DEFAULT_OPERATION) {
 806                 boundsOp = op;
 807             }
 808     }
 809 
 810     // Whether this Component has had the background erase flag
 811     // specified via SunToolkit.disableBackgroundErase(). This is
 812     // needed in order to make this function work on X11 platforms,
 813     // where currently there is no chance to interpose on the creation
 814     // of the peer and therefore the call to XSetBackground.
 815     transient boolean backgroundEraseDisabled;
 816 
 817     static {
 818         AWTAccessor.setComponentAccessor(new AWTAccessor.ComponentAccessor() {
 819             public void setBackgroundEraseDisabled(Component comp, boolean disabled) {
 820                 comp.backgroundEraseDisabled = disabled;
 821             }
 822             public boolean getBackgroundEraseDisabled(Component comp) {
 823                 return comp.backgroundEraseDisabled;
 824             }
 825             public Rectangle getBounds(Component comp) {
 826                 return new Rectangle(comp.x, comp.y, comp.width, comp.height);
 827             }
 828             public void setMixingCutoutShape(Component comp, Shape shape) {
 829                 Region region = shape == null ?  null :
 830                     Region.getInstance(shape, null);
 831 
 832                 synchronized (comp.getTreeLock()) {
 833                     boolean needShowing = false;
 834                     boolean needHiding = false;
 835 
 836                     if (!comp.isNonOpaqueForMixing()) {
 837                         needHiding = true;
 838                     }
 839 
 840                     comp.mixingCutoutRegion = region;
 841 
 842                     if (!comp.isNonOpaqueForMixing()) {
 843                         needShowing = true;
 844                     }
 845 
 846                     if (comp.isMixingNeeded()) {
 847                         if (needHiding) {
 848                             comp.mixOnHiding(comp.isLightweight());
 849                         }
 850                         if (needShowing) {
 851                             comp.mixOnShowing();
 852                         }
 853                     }
 854                 }
 855             }
 856 
 857             public void setGraphicsConfiguration(Component comp,
 858                     GraphicsConfiguration gc)
 859             {
 860                 comp.setGraphicsConfiguration(gc);
 861             }
 862             public boolean requestFocus(Component comp, CausedFocusEvent.Cause cause) {
 863                 return comp.requestFocus(cause);
 864             }
 865             public boolean canBeFocusOwner(Component comp) {
 866                 return comp.canBeFocusOwner();
 867             }
 868 
 869             public boolean isVisible_NoClientCode(Component comp) {
 870                 return comp.isVisible_NoClientCode();
 871             }
 872         });
 873     }
 874 
 875     /**
 876      * Constructs a new component. Class <code>Component</code> can be
 877      * extended directly to create a lightweight component that does not
 878      * utilize an opaque native window. A lightweight component must be
 879      * hosted by a native container somewhere higher up in the component
 880      * tree (for example, by a <code>Frame</code> object).
 881      */
 882     protected Component() {
 883         appContext = AppContext.getAppContext();
 884     }
 885 
 886     void initializeFocusTraversalKeys() {
 887         focusTraversalKeys = new Set[3];
 888     }
 889 
 890     /**
 891      * Constructs a name for this component.  Called by <code>getName</code>
 892      * when the name is <code>null</code>.
 893      */
 894     String constructComponentName() {
 895         return null; // For strict compliance with prior platform versions, a Component
 896                      // that doesn't set its name should return null from
 897                      // getName()
 898     }
 899 
 900     /**
 901      * Gets the name of the component.
 902      * @return this component's name
 903      * @see    #setName
 904      * @since JDK1.1
 905      */
 906     public String getName() {
 907         if (name == null && !nameExplicitlySet) {
 908             synchronized(getObjectLock()) {
 909                 if (name == null && !nameExplicitlySet)
 910                     name = constructComponentName();
 911             }
 912         }
 913         return name;
 914     }
 915 
 916     /**
 917      * Sets the name of the component to the specified string.
 918      * @param name  the string that is to be this
 919      *           component's name
 920      * @see #getName
 921      * @since JDK1.1
 922      */
 923     public void setName(String name) {
 924         String oldName;
 925         synchronized(getObjectLock()) {
 926             oldName = this.name;
 927             this.name = name;
 928             nameExplicitlySet = true;
 929         }
 930         firePropertyChange("name", oldName, name);
 931     }
 932 
 933     /**
 934      * Gets the parent of this component.
 935      * @return the parent container of this component
 936      * @since JDK1.0
 937      */
 938     public Container getParent() {
 939         return getParent_NoClientCode();
 940     }
 941 
 942     // NOTE: This method may be called by privileged threads.
 943     //       This functionality is implemented in a package-private method
 944     //       to insure that it cannot be overridden by client subclasses.
 945     //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
 946     final Container getParent_NoClientCode() {
 947         return parent;
 948     }
 949 
 950     // This method is overriden in the Window class to return null,
 951     //    because the parent field of the Window object contains
 952     //    the owner of the window, not its parent.
 953     Container getContainer() {
 954         return getParent();
 955     }
 956 
 957     /**
 958      * @deprecated As of JDK version 1.1,
 959      * programs should not directly manipulate peers;
 960      * replaced by <code>boolean isDisplayable()</code>.
 961      */
 962     @Deprecated
 963     public ComponentPeer getPeer() {
 964         return peer;
 965     }
 966 
 967     /**
 968      * Associate a <code>DropTarget</code> with this component.
 969      * The <code>Component</code> will receive drops only if it
 970      * is enabled.
 971      *
 972      * @see #isEnabled
 973      * @param dt The DropTarget
 974      */
 975 
 976     public synchronized void setDropTarget(DropTarget dt) {
 977         if (dt == dropTarget || (dropTarget != null && dropTarget.equals(dt)))
 978             return;
 979 
 980         DropTarget old;
 981 
 982         if ((old = dropTarget) != null) {
 983             if (peer != null) dropTarget.removeNotify(peer);
 984 
 985             DropTarget t = dropTarget;
 986 
 987             dropTarget = null;
 988 
 989             try {
 990                 t.setComponent(null);
 991             } catch (IllegalArgumentException iae) {
 992                 // ignore it.
 993             }
 994         }
 995 
 996         // if we have a new one, and we have a peer, add it!
 997 
 998         if ((dropTarget = dt) != null) {
 999             try {
1000                 dropTarget.setComponent(this);
1001                 if (peer != null) dropTarget.addNotify(peer);
1002             } catch (IllegalArgumentException iae) {
1003                 if (old != null) {
1004                     try {
1005                         old.setComponent(this);
1006                         if (peer != null) dropTarget.addNotify(peer);
1007                     } catch (IllegalArgumentException iae1) {
1008                         // ignore it!
1009                     }
1010                 }
1011             }
1012         }
1013     }
1014 
1015     /**
1016      * Gets the <code>DropTarget</code> associated with this
1017      * <code>Component</code>.
1018      */
1019 
1020     public synchronized DropTarget getDropTarget() { return dropTarget; }
1021 
1022     /**
1023      * Gets the <code>GraphicsConfiguration</code> associated with this
1024      * <code>Component</code>.
1025      * If the <code>Component</code> has not been assigned a specific
1026      * <code>GraphicsConfiguration</code>,
1027      * the <code>GraphicsConfiguration</code> of the
1028      * <code>Component</code> object's top-level container is
1029      * returned.
1030      * If the <code>Component</code> has been created, but not yet added
1031      * to a <code>Container</code>, this method returns <code>null</code>.
1032      *
1033      * @return the <code>GraphicsConfiguration</code> used by this
1034      *          <code>Component</code> or <code>null</code>
1035      * @since 1.3
1036      */
1037     public GraphicsConfiguration getGraphicsConfiguration() {
1038         synchronized(getTreeLock()) {
1039             return getGraphicsConfiguration_NoClientCode();
1040         }
1041     }
1042 
1043     final GraphicsConfiguration getGraphicsConfiguration_NoClientCode() {
1044         return graphicsConfig;
1045     }
1046 
1047     void setGraphicsConfiguration(GraphicsConfiguration gc) {
1048         synchronized(getTreeLock()) {
1049             if (updateGraphicsData(gc)) {
1050                 removeNotify();
1051                 addNotify();
1052             }
1053         }
1054     }
1055 
1056     boolean updateGraphicsData(GraphicsConfiguration gc) {
1057         checkTreeLock();
1058 
1059         graphicsConfig = gc;
1060 
1061         ComponentPeer peer = getPeer();
1062         if (peer != null) {
1063             return peer.updateGraphicsData(gc);
1064         }
1065         return false;
1066     }
1067 
1068     /**
1069      * Checks that this component's <code>GraphicsDevice</code>
1070      * <code>idString</code> matches the string argument.
1071      */
1072     void checkGD(String stringID) {
1073         if (graphicsConfig != null) {
1074             if (!graphicsConfig.getDevice().getIDstring().equals(stringID)) {
1075                 throw new IllegalArgumentException(
1076                                                    "adding a container to a container on a different GraphicsDevice");
1077             }
1078         }
1079     }
1080 
1081     /**
1082      * Gets this component's locking object (the object that owns the thread
1083      * synchronization monitor) for AWT component-tree and layout
1084      * operations.
1085      * @return this component's locking object
1086      */
1087     public final Object getTreeLock() {
1088         return LOCK;
1089     }
1090 
1091     final void checkTreeLock() {
1092         if (!Thread.holdsLock(getTreeLock())) {
1093             throw new IllegalStateException("This function should be called while holding treeLock");
1094         }
1095     }
1096 
1097     /**
1098      * Gets the toolkit of this component. Note that
1099      * the frame that contains a component controls which
1100      * toolkit is used by that component. Therefore if the component
1101      * is moved from one frame to another, the toolkit it uses may change.
1102      * @return  the toolkit of this component
1103      * @since JDK1.0
1104      */
1105     public Toolkit getToolkit() {
1106         return getToolkitImpl();
1107     }
1108 
1109     /*
1110      * This is called by the native code, so client code can't
1111      * be called on the toolkit thread.
1112      */
1113     final Toolkit getToolkitImpl() {
1114         ComponentPeer peer = this.peer;
1115         if ((peer != null) && ! (peer instanceof LightweightPeer)){
1116             return peer.getToolkit();
1117         }
1118         Container parent = this.parent;
1119         if (parent != null) {
1120             return parent.getToolkitImpl();
1121         }
1122         return Toolkit.getDefaultToolkit();
1123     }
1124 
1125     /**
1126      * Determines whether this component is valid. A component is valid
1127      * when it is correctly sized and positioned within its parent
1128      * container and all its children are also valid.
1129      * In order to account for peers' size requirements, components are invalidated
1130      * before they are first shown on the screen. By the time the parent container
1131      * is fully realized, all its components will be valid.
1132      * @return <code>true</code> if the component is valid, <code>false</code>
1133      * otherwise
1134      * @see #validate
1135      * @see #invalidate
1136      * @since JDK1.0
1137      */
1138     public boolean isValid() {
1139         return (peer != null) && valid;
1140     }
1141 
1142     /**
1143      * Determines whether this component is displayable. A component is
1144      * displayable when it is connected to a native screen resource.
1145      * <p>
1146      * A component is made displayable either when it is added to
1147      * a displayable containment hierarchy or when its containment
1148      * hierarchy is made displayable.
1149      * A containment hierarchy is made displayable when its ancestor
1150      * window is either packed or made visible.
1151      * <p>
1152      * A component is made undisplayable either when it is removed from
1153      * a displayable containment hierarchy or when its containment hierarchy
1154      * is made undisplayable.  A containment hierarchy is made
1155      * undisplayable when its ancestor window is disposed.
1156      *
1157      * @return <code>true</code> if the component is displayable,
1158      * <code>false</code> otherwise
1159      * @see Container#add(Component)
1160      * @see Window#pack
1161      * @see Window#show
1162      * @see Container#remove(Component)
1163      * @see Window#dispose
1164      * @since 1.2
1165      */
1166     public boolean isDisplayable() {
1167         return getPeer() != null;
1168     }
1169 
1170     /**
1171      * Determines whether this component should be visible when its
1172      * parent is visible. Components are
1173      * initially visible, with the exception of top level components such
1174      * as <code>Frame</code> objects.
1175      * @return <code>true</code> if the component is visible,
1176      * <code>false</code> otherwise
1177      * @see #setVisible
1178      * @since JDK1.0
1179      */
1180     @Transient
1181     public boolean isVisible() {
1182         return isVisible_NoClientCode();
1183     }
1184     final boolean isVisible_NoClientCode() {
1185         return visible;
1186     }
1187 
1188     /**
1189      * Determines whether this component will be displayed on the screen.
1190      * @return <code>true</code> if the component and all of its ancestors
1191      *          until a toplevel window or null parent are visible,
1192      *          <code>false</code> otherwise
1193      */
1194     boolean isRecursivelyVisible() {
1195         return visible && (parent == null || parent.isRecursivelyVisible());
1196     }
1197 
1198     /**
1199      * Translates absolute coordinates into coordinates in the coordinate
1200      * space of this component.
1201      */
1202     Point pointRelativeToComponent(Point absolute) {
1203         Point compCoords = getLocationOnScreen();
1204         return new Point(absolute.x - compCoords.x,
1205                          absolute.y - compCoords.y);
1206     }
1207 
1208     /**
1209      * Assuming that mouse location is stored in PointerInfo passed
1210      * to this method, it finds a Component that is in the same
1211      * Window as this Component and is located under the mouse pointer.
1212      * If no such Component exists, null is returned.
1213      * NOTE: this method should be called under the protection of
1214      * tree lock, as it is done in Component.getMousePosition() and
1215      * Container.getMousePosition(boolean).
1216      */
1217     Component findUnderMouseInWindow(PointerInfo pi) {
1218         if (!isShowing()) {
1219             return null;
1220         }
1221         Window win = getContainingWindow();
1222         if (!Toolkit.getDefaultToolkit().getMouseInfoPeer().isWindowUnderMouse(win)) {
1223             return null;
1224         }
1225         final boolean INCLUDE_DISABLED = true;
1226         Point relativeToWindow = win.pointRelativeToComponent(pi.getLocation());
1227         Component inTheSameWindow = win.findComponentAt(relativeToWindow.x,
1228                                                         relativeToWindow.y,
1229                                                         INCLUDE_DISABLED);
1230         return inTheSameWindow;
1231     }
1232 
1233     /**
1234      * Returns the position of the mouse pointer in this <code>Component</code>'s
1235      * coordinate space if the <code>Component</code> is directly under the mouse
1236      * pointer, otherwise returns <code>null</code>.
1237      * If the <code>Component</code> is not showing on the screen, this method
1238      * returns <code>null</code> even if the mouse pointer is above the area
1239      * where the <code>Component</code> would be displayed.
1240      * If the <code>Component</code> is partially or fully obscured by other
1241      * <code>Component</code>s or native windows, this method returns a non-null
1242      * value only if the mouse pointer is located above the unobscured part of the
1243      * <code>Component</code>.
1244      * <p>
1245      * For <code>Container</code>s it returns a non-null value if the mouse is
1246      * above the <code>Container</code> itself or above any of its descendants.
1247      * Use {@link Container#getMousePosition(boolean)} if you need to exclude children.
1248      * <p>
1249      * Sometimes the exact mouse coordinates are not important, and the only thing
1250      * that matters is whether a specific <code>Component</code> is under the mouse
1251      * pointer. If the return value of this method is <code>null</code>, mouse
1252      * pointer is not directly above the <code>Component</code>.
1253      *
1254      * @exception HeadlessException if GraphicsEnvironment.isHeadless() returns true
1255      * @see       #isShowing
1256      * @see       Container#getMousePosition
1257      * @return    mouse coordinates relative to this <code>Component</code>, or null
1258      * @since     1.5
1259      */
1260     public Point getMousePosition() throws HeadlessException {
1261         if (GraphicsEnvironment.isHeadless()) {
1262             throw new HeadlessException();
1263         }
1264 
1265         PointerInfo pi = (PointerInfo)java.security.AccessController.doPrivileged(
1266                                                                                   new java.security.PrivilegedAction() {
1267                                                                                       public Object run() {
1268                                                                                           return MouseInfo.getPointerInfo();
1269                                                                                       }
1270                                                                                   }
1271                                                                                   );
1272 
1273         synchronized (getTreeLock()) {
1274             Component inTheSameWindow = findUnderMouseInWindow(pi);
1275             if (!isSameOrAncestorOf(inTheSameWindow, true)) {
1276                 return null;
1277             }
1278             return pointRelativeToComponent(pi.getLocation());
1279         }
1280     }
1281 
1282     /**
1283      * Overridden in Container. Must be called under TreeLock.
1284      */
1285     boolean isSameOrAncestorOf(Component comp, boolean allowChildren) {
1286         return comp == this;
1287     }
1288 
1289     /**
1290      * Determines whether this component is showing on screen. This means
1291      * that the component must be visible, and it must be in a container
1292      * that is visible and showing.
1293      * <p>
1294      * <strong>Note:</strong> sometimes there is no way to detect whether the
1295      * {@code Component} is actually visible to the user.  This can happen when:
1296      * <ul>
1297      * <li>the component has been added to a visible {@code ScrollPane} but
1298      * the {@code Component} is not currently in the scroll pane's view port.
1299      * <li>the {@code Component} is obscured by another {@code Component} or
1300      * {@code Container}.
1301      * </ul>
1302      * @return <code>true</code> if the component is showing,
1303      *          <code>false</code> otherwise
1304      * @see #setVisible
1305      * @since JDK1.0
1306      */
1307     public boolean isShowing() {
1308         if (visible && (peer != null)) {
1309             Container parent = this.parent;
1310             return (parent == null) || parent.isShowing();
1311         }
1312         return false;
1313     }
1314 
1315     /**
1316      * Determines whether this component is enabled. An enabled component
1317      * can respond to user input and generate events. Components are
1318      * enabled initially by default. A component may be enabled or disabled by
1319      * calling its <code>setEnabled</code> method.
1320      * @return <code>true</code> if the component is enabled,
1321      *          <code>false</code> otherwise
1322      * @see #setEnabled
1323      * @since JDK1.0
1324      */
1325     public boolean isEnabled() {
1326         return isEnabledImpl();
1327     }
1328 
1329     /*
1330      * This is called by the native code, so client code can't
1331      * be called on the toolkit thread.
1332      */
1333     final boolean isEnabledImpl() {
1334         return enabled;
1335     }
1336 
1337     /**
1338      * Enables or disables this component, depending on the value of the
1339      * parameter <code>b</code>. An enabled component can respond to user
1340      * input and generate events. Components are enabled initially by default.
1341      *
1342      * <p>Note: Disabling a lightweight component does not prevent it from
1343      * receiving MouseEvents.
1344      * <p>Note: Disabling a heavyweight container prevents all components
1345      * in this container from receiving any input events.  But disabling a
1346      * lightweight container affects only this container.
1347      *
1348      * @param     b   If <code>true</code>, this component is
1349      *            enabled; otherwise this component is disabled
1350      * @see #isEnabled
1351      * @see #isLightweight
1352      * @since JDK1.1
1353      */
1354     public void setEnabled(boolean b) {
1355         enable(b);
1356     }
1357 
1358     /**
1359      * @deprecated As of JDK version 1.1,
1360      * replaced by <code>setEnabled(boolean)</code>.
1361      */
1362     @Deprecated
1363     public void enable() {
1364         if (!enabled) {
1365             synchronized (getTreeLock()) {
1366                 enabled = true;
1367                 ComponentPeer peer = this.peer;
1368                 if (peer != null) {
1369                     peer.setEnabled(true);
1370                     if (visible) {
1371                         updateCursorImmediately();
1372                     }
1373                 }
1374             }
1375             if (accessibleContext != null) {
1376                 accessibleContext.firePropertyChange(
1377                                                      AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
1378                                                      null, AccessibleState.ENABLED);
1379             }
1380         }
1381     }
1382 
1383     /**
1384      * @deprecated As of JDK version 1.1,
1385      * replaced by <code>setEnabled(boolean)</code>.
1386      */
1387     @Deprecated
1388     public void enable(boolean b) {
1389         if (b) {
1390             enable();
1391         } else {
1392             disable();
1393         }
1394     }
1395 
1396     /**
1397      * @deprecated As of JDK version 1.1,
1398      * replaced by <code>setEnabled(boolean)</code>.
1399      */
1400     @Deprecated
1401     public void disable() {
1402         if (enabled) {
1403             KeyboardFocusManager.clearMostRecentFocusOwner(this);
1404             synchronized (getTreeLock()) {
1405                 enabled = false;
1406                 // A disabled lw container is allowed to contain a focus owner.
1407                 if ((isFocusOwner() || (containsFocus() && !isLightweight())) &&
1408                     KeyboardFocusManager.isAutoFocusTransferEnabled())
1409                 {
1410                     // Don't clear the global focus owner. If transferFocus
1411                     // fails, we want the focus to stay on the disabled
1412                     // Component so that keyboard traversal, et. al. still
1413                     // makes sense to the user.
1414                     transferFocus(false);
1415                 }
1416                 ComponentPeer peer = this.peer;
1417                 if (peer != null) {
1418                     peer.setEnabled(false);
1419                     if (visible) {
1420                         updateCursorImmediately();
1421                     }
1422                 }
1423             }
1424             if (accessibleContext != null) {
1425                 accessibleContext.firePropertyChange(
1426                                                      AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
1427                                                      null, AccessibleState.ENABLED);
1428             }
1429         }
1430     }
1431 
1432     /**
1433      * Returns true if this component is painted to an offscreen image
1434      * ("buffer") that's copied to the screen later.  Component
1435      * subclasses that support double buffering should override this
1436      * method to return true if double buffering is enabled.
1437      *
1438      * @return false by default
1439      */
1440     public boolean isDoubleBuffered() {
1441         return false;
1442     }
1443 
1444     /**
1445      * Enables or disables input method support for this component. If input
1446      * method support is enabled and the component also processes key events,
1447      * incoming events are offered to
1448      * the current input method and will only be processed by the component or
1449      * dispatched to its listeners if the input method does not consume them.
1450      * By default, input method support is enabled.
1451      *
1452      * @param enable true to enable, false to disable
1453      * @see #processKeyEvent
1454      * @since 1.2
1455      */
1456     public void enableInputMethods(boolean enable) {
1457         if (enable) {
1458             if ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0)
1459                 return;
1460 
1461             // If this component already has focus, then activate the
1462             // input method by dispatching a synthesized focus gained
1463             // event.
1464             if (isFocusOwner()) {
1465                 InputContext inputContext = getInputContext();
1466                 if (inputContext != null) {
1467                     FocusEvent focusGainedEvent =
1468                         new FocusEvent(this, FocusEvent.FOCUS_GAINED);
1469                     inputContext.dispatchEvent(focusGainedEvent);
1470                 }
1471             }
1472 
1473             eventMask |= AWTEvent.INPUT_METHODS_ENABLED_MASK;
1474         } else {
1475             if ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) {
1476                 InputContext inputContext = getInputContext();
1477                 if (inputContext != null) {
1478                     inputContext.endComposition();
1479                     inputContext.removeNotify(this);
1480                 }
1481             }
1482             eventMask &= ~AWTEvent.INPUT_METHODS_ENABLED_MASK;
1483         }
1484     }
1485 
1486     /**
1487      * Shows or hides this component depending on the value of parameter
1488      * <code>b</code>.
1489      * @param b  if <code>true</code>, shows this component;
1490      * otherwise, hides this component
1491      * @see #isVisible
1492      * @since JDK1.1
1493      */
1494     public void setVisible(boolean b) {
1495         show(b);
1496     }
1497 
1498     /**
1499      * @deprecated As of JDK version 1.1,
1500      * replaced by <code>setVisible(boolean)</code>.
1501      */
1502     @Deprecated
1503     public void show() {
1504         if (!visible) {
1505             synchronized (getTreeLock()) {
1506                 visible = true;
1507                 mixOnShowing();
1508                 ComponentPeer peer = this.peer;
1509                 if (peer != null) {
1510                     peer.setVisible(true);
1511                     createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED,
1512                                           this, parent,
1513                                           HierarchyEvent.SHOWING_CHANGED,
1514                                           Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
1515                     if (peer instanceof LightweightPeer) {
1516                         repaint();
1517                     }
1518                     updateCursorImmediately();
1519                 }
1520 
1521                 if (componentListener != null ||
1522                     (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 ||
1523                     Toolkit.enabledOnToolkit(AWTEvent.COMPONENT_EVENT_MASK)) {
1524                     ComponentEvent e = new ComponentEvent(this,
1525                                                           ComponentEvent.COMPONENT_SHOWN);
1526                     Toolkit.getEventQueue().postEvent(e);
1527                 }
1528             }
1529             Container parent = this.parent;
1530             if (parent != null) {
1531                 parent.invalidate();
1532             }
1533         }
1534     }
1535 
1536     /**
1537      * @deprecated As of JDK version 1.1,
1538      * replaced by <code>setVisible(boolean)</code>.
1539      */
1540     @Deprecated
1541     public void show(boolean b) {
1542         if (b) {
1543             show();
1544         } else {
1545             hide();
1546         }
1547     }
1548 
1549     boolean containsFocus() {
1550         return isFocusOwner();
1551     }
1552 
1553     void clearMostRecentFocusOwnerOnHide() {
1554         KeyboardFocusManager.clearMostRecentFocusOwner(this);
1555     }
1556 
1557     void clearCurrentFocusCycleRootOnHide() {
1558         /* do nothing */
1559     }
1560 
1561     /**
1562      * @deprecated As of JDK version 1.1,
1563      * replaced by <code>setVisible(boolean)</code>.
1564      */
1565     @Deprecated
1566     public void hide() {
1567         if (visible) {
1568             clearCurrentFocusCycleRootOnHide();
1569             clearMostRecentFocusOwnerOnHide();
1570             synchronized (getTreeLock()) {
1571                 visible = false;
1572                 mixOnHiding(isLightweight());
1573                 if (containsFocus() && KeyboardFocusManager.isAutoFocusTransferEnabled()) {
1574                     transferFocus(true);
1575                 }
1576                 ComponentPeer peer = this.peer;
1577                 if (peer != null) {
1578                     peer.setVisible(false);
1579                     createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED,
1580                                           this, parent,
1581                                           HierarchyEvent.SHOWING_CHANGED,
1582                                           Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
1583                     if (peer instanceof LightweightPeer) {
1584                         repaint();
1585                     }
1586                     updateCursorImmediately();
1587                 }
1588                 if (componentListener != null ||
1589                     (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 ||
1590                     Toolkit.enabledOnToolkit(AWTEvent.COMPONENT_EVENT_MASK)) {
1591                     ComponentEvent e = new ComponentEvent(this,
1592                                                           ComponentEvent.COMPONENT_HIDDEN);
1593                     Toolkit.getEventQueue().postEvent(e);
1594                 }
1595             }
1596             Container parent = this.parent;
1597             if (parent != null) {
1598                 parent.invalidate();
1599             }
1600         }
1601     }
1602 
1603     /**
1604      * Gets the foreground color of this component.
1605      * @return this component's foreground color; if this component does
1606      * not have a foreground color, the foreground color of its parent
1607      * is returned
1608      * @see #setForeground
1609      * @since JDK1.0
1610      * @beaninfo
1611      *       bound: true
1612      */
1613     @Transient
1614     public Color getForeground() {
1615         Color foreground = this.foreground;
1616         if (foreground != null) {
1617             return foreground;
1618         }
1619         Container parent = this.parent;
1620         return (parent != null) ? parent.getForeground() : null;
1621     }
1622 
1623     /**
1624      * Sets the foreground color of this component.
1625      * @param c the color to become this component's
1626      *          foreground color; if this parameter is <code>null</code>
1627      *          then this component will inherit
1628      *          the foreground color of its parent
1629      * @see #getForeground
1630      * @since JDK1.0
1631      */
1632     public void setForeground(Color c) {
1633         Color oldColor = foreground;
1634         ComponentPeer peer = this.peer;
1635         foreground = c;
1636         if (peer != null) {
1637             c = getForeground();
1638             if (c != null) {
1639                 peer.setForeground(c);
1640             }
1641         }
1642         // This is a bound property, so report the change to
1643         // any registered listeners.  (Cheap if there are none.)
1644         firePropertyChange("foreground", oldColor, c);
1645     }
1646 
1647     /**
1648      * Returns whether the foreground color has been explicitly set for this
1649      * Component. If this method returns <code>false</code>, this Component is
1650      * inheriting its foreground color from an ancestor.
1651      *
1652      * @return <code>true</code> if the foreground color has been explicitly
1653      *         set for this Component; <code>false</code> otherwise.
1654      * @since 1.4
1655      */
1656     public boolean isForegroundSet() {
1657         return (foreground != null);
1658     }
1659 
1660     /**
1661      * Gets the background color of this component.
1662      * @return this component's background color; if this component does
1663      *          not have a background color,
1664      *          the background color of its parent is returned
1665      * @see #setBackground
1666      * @since JDK1.0
1667      */
1668     @Transient
1669     public Color getBackground() {
1670         Color background = this.background;
1671         if (background != null) {
1672             return background;
1673         }
1674         Container parent = this.parent;
1675         return (parent != null) ? parent.getBackground() : null;
1676     }
1677 
1678     /**
1679      * Sets the background color of this component.
1680      * <p>
1681      * The background color affects each component differently and the
1682      * parts of the component that are affected by the background color
1683      * may differ between operating systems.
1684      *
1685      * @param c the color to become this component's color;
1686      *          if this parameter is <code>null</code>, then this
1687      *          component will inherit the background color of its parent
1688      * @see #getBackground
1689      * @since JDK1.0
1690      * @beaninfo
1691      *       bound: true
1692      */
1693     public void setBackground(Color c) {
1694         Color oldColor = background;
1695         ComponentPeer peer = this.peer;
1696         background = c;
1697         if (peer != null) {
1698             c = getBackground();
1699             if (c != null) {
1700                 peer.setBackground(c);
1701             }
1702         }
1703         // This is a bound property, so report the change to
1704         // any registered listeners.  (Cheap if there are none.)
1705         firePropertyChange("background", oldColor, c);
1706     }
1707 
1708     /**
1709      * Returns whether the background color has been explicitly set for this
1710      * Component. If this method returns <code>false</code>, this Component is
1711      * inheriting its background color from an ancestor.
1712      *
1713      * @return <code>true</code> if the background color has been explicitly
1714      *         set for this Component; <code>false</code> otherwise.
1715      * @since 1.4
1716      */
1717     public boolean isBackgroundSet() {
1718         return (background != null);
1719     }
1720 
1721     /**
1722      * Gets the font of this component.
1723      * @return this component's font; if a font has not been set
1724      * for this component, the font of its parent is returned
1725      * @see #setFont
1726      * @since JDK1.0
1727      */
1728     @Transient
1729     public Font getFont() {
1730         return getFont_NoClientCode();
1731     }
1732 
1733     // NOTE: This method may be called by privileged threads.
1734     //       This functionality is implemented in a package-private method
1735     //       to insure that it cannot be overridden by client subclasses.
1736     //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
1737     final Font getFont_NoClientCode() {
1738         Font font = this.font;
1739         if (font != null) {
1740             return font;
1741         }
1742         Container parent = this.parent;
1743         return (parent != null) ? parent.getFont_NoClientCode() : null;
1744     }
1745 
1746     /**
1747      * Sets the font of this component.
1748      * @param f the font to become this component's font;
1749      *          if this parameter is <code>null</code> then this
1750      *          component will inherit the font of its parent
1751      * @see #getFont
1752      * @since JDK1.0
1753      * @beaninfo
1754      *       bound: true
1755      */
1756     public void setFont(Font f) {
1757         Font oldFont, newFont;
1758         synchronized(getTreeLock()) {
1759             synchronized (this) {
1760                 oldFont = font;
1761                 newFont = font = f;
1762             }
1763             ComponentPeer peer = this.peer;
1764             if (peer != null) {
1765                 f = getFont();
1766                 if (f != null) {
1767                     peer.setFont(f);
1768                     peerFont = f;
1769                 }
1770             }
1771         }
1772         // This is a bound property, so report the change to
1773         // any registered listeners.  (Cheap if there are none.)
1774         firePropertyChange("font", oldFont, newFont);
1775 
1776         // This could change the preferred size of the Component.
1777         // Fix for 6213660. Should compare old and new fonts and do not
1778         // call invalidate() if they are equal.
1779         if (f != oldFont && (oldFont == null ||
1780                                       !oldFont.equals(f))) {
1781             invalidateIfValid();
1782         }
1783     }
1784 
1785     /**
1786      * Returns whether the font has been explicitly set for this Component. If
1787      * this method returns <code>false</code>, this Component is inheriting its
1788      * font from an ancestor.
1789      *
1790      * @return <code>true</code> if the font has been explicitly set for this
1791      *         Component; <code>false</code> otherwise.
1792      * @since 1.4
1793      */
1794     public boolean isFontSet() {
1795         return (font != null);
1796     }
1797 
1798     /**
1799      * Gets the locale of this component.
1800      * @return this component's locale; if this component does not
1801      *          have a locale, the locale of its parent is returned
1802      * @see #setLocale
1803      * @exception IllegalComponentStateException if the <code>Component</code>
1804      *          does not have its own locale and has not yet been added to
1805      *          a containment hierarchy such that the locale can be determined
1806      *          from the containing parent
1807      * @since  JDK1.1
1808      */
1809     public Locale getLocale() {
1810         Locale locale = this.locale;
1811         if (locale != null) {
1812             return locale;
1813         }
1814         Container parent = this.parent;
1815 
1816         if (parent == null) {
1817             throw new IllegalComponentStateException("This component must have a parent in order to determine its locale");
1818         } else {
1819             return parent.getLocale();
1820         }
1821     }
1822 
1823     /**
1824      * Sets the locale of this component.  This is a bound property.
1825      * @param l the locale to become this component's locale
1826      * @see #getLocale
1827      * @since JDK1.1
1828      */
1829     public void setLocale(Locale l) {
1830         Locale oldValue = locale;
1831         locale = l;
1832 
1833         // This is a bound property, so report the change to
1834         // any registered listeners.  (Cheap if there are none.)
1835         firePropertyChange("locale", oldValue, l);
1836 
1837         // This could change the preferred size of the Component.
1838         invalidateIfValid();
1839     }
1840 
1841     /**
1842      * Gets the instance of <code>ColorModel</code> used to display
1843      * the component on the output device.
1844      * @return the color model used by this component
1845      * @see java.awt.image.ColorModel
1846      * @see java.awt.peer.ComponentPeer#getColorModel()
1847      * @see Toolkit#getColorModel()
1848      * @since JDK1.0
1849      */
1850     public ColorModel getColorModel() {
1851         ComponentPeer peer = this.peer;
1852         if ((peer != null) && ! (peer instanceof LightweightPeer)) {
1853             return peer.getColorModel();
1854         } else if (GraphicsEnvironment.isHeadless()) {
1855             return ColorModel.getRGBdefault();
1856         } // else
1857         return getToolkit().getColorModel();
1858     }
1859 
1860     /**
1861      * Gets the location of this component in the form of a
1862      * point specifying the component's top-left corner.
1863      * The location will be relative to the parent's coordinate space.
1864      * <p>
1865      * Due to the asynchronous nature of native event handling, this
1866      * method can return outdated values (for instance, after several calls
1867      * of <code>setLocation()</code> in rapid succession).  For this
1868      * reason, the recommended method of obtaining a component's position is
1869      * within <code>java.awt.event.ComponentListener.componentMoved()</code>,
1870      * which is called after the operating system has finished moving the
1871      * component.
1872      * </p>
1873      * @return an instance of <code>Point</code> representing
1874      *          the top-left corner of the component's bounds in
1875      *          the coordinate space of the component's parent
1876      * @see #setLocation
1877      * @see #getLocationOnScreen
1878      * @since JDK1.1
1879      */
1880     public Point getLocation() {
1881         return location();
1882     }
1883 
1884     /**
1885      * Gets the location of this component in the form of a point
1886      * specifying the component's top-left corner in the screen's
1887      * coordinate space.
1888      * @return an instance of <code>Point</code> representing
1889      *          the top-left corner of the component's bounds in the
1890      *          coordinate space of the screen
1891      * @throws <code>IllegalComponentStateException</code> if the
1892      *          component is not showing on the screen
1893      * @see #setLocation
1894      * @see #getLocation
1895      */
1896     public Point getLocationOnScreen() {
1897         synchronized (getTreeLock()) {
1898             return getLocationOnScreen_NoTreeLock();
1899         }
1900     }
1901 
1902     /*
1903      * a package private version of getLocationOnScreen
1904      * used by GlobalCursormanager to update cursor
1905      */
1906     final Point getLocationOnScreen_NoTreeLock() {
1907 
1908         if (peer != null && isShowing()) {
1909             if (peer instanceof LightweightPeer) {
1910                 // lightweight component location needs to be translated
1911                 // relative to a native component.
1912                 Container host = getNativeContainer();
1913                 Point pt = host.peer.getLocationOnScreen();
1914                 for(Component c = this; c != host; c = c.getParent()) {
1915                     pt.x += c.x;
1916                     pt.y += c.y;
1917                 }
1918                 return pt;
1919             } else {
1920                 Point pt = peer.getLocationOnScreen();
1921                 return pt;
1922             }
1923         } else {
1924             throw new IllegalComponentStateException("component must be showing on the screen to determine its location");
1925         }
1926     }
1927 
1928 
1929     /**
1930      * @deprecated As of JDK version 1.1,
1931      * replaced by <code>getLocation()</code>.
1932      */
1933     @Deprecated
1934     public Point location() {
1935         return location_NoClientCode();
1936     }
1937 
1938     private Point location_NoClientCode() {
1939         return new Point(x, y);
1940     }
1941 
1942     /**
1943      * Moves this component to a new location. The top-left corner of
1944      * the new location is specified by the <code>x</code> and <code>y</code>
1945      * parameters in the coordinate space of this component's parent.
1946      * @param x the <i>x</i>-coordinate of the new location's
1947      *          top-left corner in the parent's coordinate space
1948      * @param y the <i>y</i>-coordinate of the new location's
1949      *          top-left corner in the parent's coordinate space
1950      * @see #getLocation
1951      * @see #setBounds
1952      * @since JDK1.1
1953      */
1954     public void setLocation(int x, int y) {
1955         move(x, y);
1956     }
1957 
1958     /**
1959      * @deprecated As of JDK version 1.1,
1960      * replaced by <code>setLocation(int, int)</code>.
1961      */
1962     @Deprecated
1963     public void move(int x, int y) {
1964         synchronized(getTreeLock()) {
1965             setBoundsOp(ComponentPeer.SET_LOCATION);
1966             setBounds(x, y, width, height);
1967         }
1968     }
1969 
1970     /**
1971      * Moves this component to a new location. The top-left corner of
1972      * the new location is specified by point <code>p</code>. Point
1973      * <code>p</code> is given in the parent's coordinate space.
1974      * @param p the point defining the top-left corner
1975      *          of the new location, given in the coordinate space of this
1976      *          component's parent
1977      * @see #getLocation
1978      * @see #setBounds
1979      * @since JDK1.1
1980      */
1981     public void setLocation(Point p) {
1982         setLocation(p.x, p.y);
1983     }
1984 
1985     /**
1986      * Returns the size of this component in the form of a
1987      * <code>Dimension</code> object. The <code>height</code>
1988      * field of the <code>Dimension</code> object contains
1989      * this component's height, and the <code>width</code>
1990      * field of the <code>Dimension</code> object contains
1991      * this component's width.
1992      * @return a <code>Dimension</code> object that indicates the
1993      *          size of this component
1994      * @see #setSize
1995      * @since JDK1.1
1996      */
1997     public Dimension getSize() {
1998         return size();
1999     }
2000 
2001     /**
2002      * @deprecated As of JDK version 1.1,
2003      * replaced by <code>getSize()</code>.
2004      */
2005     @Deprecated
2006     public Dimension size() {
2007         return new Dimension(width, height);
2008     }
2009 
2010     /**
2011      * Resizes this component so that it has width <code>width</code>
2012      * and height <code>height</code>.
2013      * @param width the new width of this component in pixels
2014      * @param height the new height of this component in pixels
2015      * @see #getSize
2016      * @see #setBounds
2017      * @since JDK1.1
2018      */
2019     public void setSize(int width, int height) {
2020         resize(width, height);
2021     }
2022 
2023     /**
2024      * @deprecated As of JDK version 1.1,
2025      * replaced by <code>setSize(int, int)</code>.
2026      */
2027     @Deprecated
2028     public void resize(int width, int height) {
2029         synchronized(getTreeLock()) {
2030             setBoundsOp(ComponentPeer.SET_SIZE);
2031             setBounds(x, y, width, height);
2032         }
2033     }
2034 
2035     /**
2036      * Resizes this component so that it has width <code>d.width</code>
2037      * and height <code>d.height</code>.
2038      * @param d the dimension specifying the new size
2039      *          of this component
2040      * @see #setSize
2041      * @see #setBounds
2042      * @since JDK1.1
2043      */
2044     public void setSize(Dimension d) {
2045         resize(d);
2046     }
2047 
2048     /**
2049      * @deprecated As of JDK version 1.1,
2050      * replaced by <code>setSize(Dimension)</code>.
2051      */
2052     @Deprecated
2053     public void resize(Dimension d) {
2054         setSize(d.width, d.height);
2055     }
2056 
2057     /**
2058      * Gets the bounds of this component in the form of a
2059      * <code>Rectangle</code> object. The bounds specify this
2060      * component's width, height, and location relative to
2061      * its parent.
2062      * @return a rectangle indicating this component's bounds
2063      * @see #setBounds
2064      * @see #getLocation
2065      * @see #getSize
2066      */
2067     public Rectangle getBounds() {
2068         return bounds();
2069     }
2070 
2071     /**
2072      * @deprecated As of JDK version 1.1,
2073      * replaced by <code>getBounds()</code>.
2074      */
2075     @Deprecated
2076     public Rectangle bounds() {
2077         return new Rectangle(x, y, width, height);
2078     }
2079 
2080     /**
2081      * Moves and resizes this component. The new location of the top-left
2082      * corner is specified by <code>x</code> and <code>y</code>, and the
2083      * new size is specified by <code>width</code> and <code>height</code>.
2084      * @param x the new <i>x</i>-coordinate of this component
2085      * @param y the new <i>y</i>-coordinate of this component
2086      * @param width the new <code>width</code> of this component
2087      * @param height the new <code>height</code> of this
2088      *          component
2089      * @see #getBounds
2090      * @see #setLocation(int, int)
2091      * @see #setLocation(Point)
2092      * @see #setSize(int, int)
2093      * @see #setSize(Dimension)
2094      * @since JDK1.1
2095      */
2096     public void setBounds(int x, int y, int width, int height) {
2097         reshape(x, y, width, height);
2098     }
2099 
2100     /**
2101      * @deprecated As of JDK version 1.1,
2102      * replaced by <code>setBounds(int, int, int, int)</code>.
2103      */
2104     @Deprecated
2105     public void reshape(int x, int y, int width, int height) {
2106         synchronized (getTreeLock()) {
2107             try {
2108                 setBoundsOp(ComponentPeer.SET_BOUNDS);
2109                 boolean resized = (this.width != width) || (this.height != height);
2110                 boolean moved = (this.x != x) || (this.y != y);
2111                 if (!resized && !moved) {
2112                     return;
2113                 }
2114                 int oldX = this.x;
2115                 int oldY = this.y;
2116                 int oldWidth = this.width;
2117                 int oldHeight = this.height;
2118                 this.x = x;
2119                 this.y = y;
2120                 this.width = width;
2121                 this.height = height;
2122 
2123                 boolean needNotify = true;
2124                 mixOnReshaping();
2125                 if (peer != null) {
2126                     // LightwightPeer is an empty stub so can skip peer.reshape
2127                     if (!(peer instanceof LightweightPeer)) {
2128                         reshapeNativePeer(x, y, width, height, getBoundsOp());
2129                         // Check peer actualy changed coordinates
2130                         resized = (oldWidth != this.width) || (oldHeight != this.height);
2131                         moved = (oldX != this.x) || (oldY != this.y);
2132                         // fix for 5025858: do not send ComponentEvents for toplevel
2133                         // windows here as it is done from peer or native code when
2134                         // the window is really resized or moved, otherwise some
2135                         // events may be sent twice
2136                         if (this instanceof Window) {
2137                             needNotify = false;
2138                         }
2139                     }
2140                     if (resized) {
2141                         invalidate();
2142                     }
2143                     if (parent != null) {
2144                         parent.invalidateIfValid();
2145                     }
2146                 }
2147                 if (needNotify) {
2148                     notifyNewBounds(resized, moved);
2149                 }
2150                 repaintParentIfNeeded(oldX, oldY, oldWidth, oldHeight);
2151             } finally {
2152                 setBoundsOp(ComponentPeer.RESET_OPERATION);
2153             }
2154         }
2155     }
2156 
2157     private void repaintParentIfNeeded(int oldX, int oldY, int oldWidth,
2158                                        int oldHeight)
2159     {
2160         if (parent != null && peer instanceof LightweightPeer && isShowing()) {
2161             // Have the parent redraw the area this component occupied.
2162             parent.repaint(oldX, oldY, oldWidth, oldHeight);
2163             // Have the parent redraw the area this component *now* occupies.
2164             repaint();
2165         }
2166     }
2167 
2168     private void reshapeNativePeer(int x, int y, int width, int height, int op) {
2169         // native peer might be offset by more than direct
2170         // parent since parent might be lightweight.
2171         int nativeX = x;
2172         int nativeY = y;
2173         for (Component c = parent;
2174              (c != null) && (c.peer instanceof LightweightPeer);
2175              c = c.parent)
2176         {
2177             nativeX += c.x;
2178             nativeY += c.y;
2179         }
2180         peer.setBounds(nativeX, nativeY, width, height, op);
2181     }
2182 
2183 
2184     private void notifyNewBounds(boolean resized, boolean moved) {
2185         if (componentListener != null
2186             || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0
2187             || Toolkit.enabledOnToolkit(AWTEvent.COMPONENT_EVENT_MASK))
2188             {
2189                 if (resized) {
2190                     ComponentEvent e = new ComponentEvent(this,
2191                                                           ComponentEvent.COMPONENT_RESIZED);
2192                     Toolkit.getEventQueue().postEvent(e);
2193                 }
2194                 if (moved) {
2195                     ComponentEvent e = new ComponentEvent(this,
2196                                                           ComponentEvent.COMPONENT_MOVED);
2197                     Toolkit.getEventQueue().postEvent(e);
2198                 }
2199             } else {
2200                 if (this instanceof Container && ((Container)this).countComponents() > 0) {
2201                     boolean enabledOnToolkit =
2202                         Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK);
2203                     if (resized) {
2204 
2205                         ((Container)this).createChildHierarchyEvents(
2206                                                                      HierarchyEvent.ANCESTOR_RESIZED, 0, enabledOnToolkit);
2207                     }
2208                     if (moved) {
2209                         ((Container)this).createChildHierarchyEvents(
2210                                                                      HierarchyEvent.ANCESTOR_MOVED, 0, enabledOnToolkit);
2211                     }
2212                 }
2213                 }
2214     }
2215 
2216     /**
2217      * Moves and resizes this component to conform to the new
2218      * bounding rectangle <code>r</code>. This component's new
2219      * position is specified by <code>r.x</code> and <code>r.y</code>,
2220      * and its new size is specified by <code>r.width</code> and
2221      * <code>r.height</code>
2222      * @param r the new bounding rectangle for this component
2223      * @see       #getBounds
2224      * @see       #setLocation(int, int)
2225      * @see       #setLocation(Point)
2226      * @see       #setSize(int, int)
2227      * @see       #setSize(Dimension)
2228      * @since     JDK1.1
2229      */
2230     public void setBounds(Rectangle r) {
2231         setBounds(r.x, r.y, r.width, r.height);
2232     }
2233 
2234 
2235     /**
2236      * Returns the current x coordinate of the components origin.
2237      * This method is preferable to writing
2238      * <code>component.getBounds().x</code>,
2239      * or <code>component.getLocation().x</code> because it doesn't
2240      * cause any heap allocations.
2241      *
2242      * @return the current x coordinate of the components origin
2243      * @since 1.2
2244      */
2245     public int getX() {
2246         return x;
2247     }
2248 
2249 
2250     /**
2251      * Returns the current y coordinate of the components origin.
2252      * This method is preferable to writing
2253      * <code>component.getBounds().y</code>,
2254      * or <code>component.getLocation().y</code> because it
2255      * doesn't cause any heap allocations.
2256      *
2257      * @return the current y coordinate of the components origin
2258      * @since 1.2
2259      */
2260     public int getY() {
2261         return y;
2262     }
2263 
2264 
2265     /**
2266      * Returns the current width of this component.
2267      * This method is preferable to writing
2268      * <code>component.getBounds().width</code>,
2269      * or <code>component.getSize().width</code> because it
2270      * doesn't cause any heap allocations.
2271      *
2272      * @return the current width of this component
2273      * @since 1.2
2274      */
2275     public int getWidth() {
2276         return width;
2277     }
2278 
2279 
2280     /**
2281      * Returns the current height of this component.
2282      * This method is preferable to writing
2283      * <code>component.getBounds().height</code>,
2284      * or <code>component.getSize().height</code> because it
2285      * doesn't cause any heap allocations.
2286      *
2287      * @return the current height of this component
2288      * @since 1.2
2289      */
2290     public int getHeight() {
2291         return height;
2292     }
2293 
2294     /**
2295      * Stores the bounds of this component into "return value" <b>rv</b> and
2296      * return <b>rv</b>.  If rv is <code>null</code> a new
2297      * <code>Rectangle</code> is allocated.
2298      * This version of <code>getBounds</code> is useful if the caller
2299      * wants to avoid allocating a new <code>Rectangle</code> object
2300      * on the heap.
2301      *
2302      * @param rv the return value, modified to the components bounds
2303      * @return rv
2304      */
2305     public Rectangle getBounds(Rectangle rv) {
2306         if (rv == null) {
2307             return new Rectangle(getX(), getY(), getWidth(), getHeight());
2308         }
2309         else {
2310             rv.setBounds(getX(), getY(), getWidth(), getHeight());
2311             return rv;
2312         }
2313     }
2314 
2315     /**
2316      * Stores the width/height of this component into "return value" <b>rv</b>
2317      * and return <b>rv</b>.   If rv is <code>null</code> a new
2318      * <code>Dimension</code> object is allocated.  This version of
2319      * <code>getSize</code> is useful if the caller wants to avoid
2320      * allocating a new <code>Dimension</code> object on the heap.
2321      *
2322      * @param rv the return value, modified to the components size
2323      * @return rv
2324      */
2325     public Dimension getSize(Dimension rv) {
2326         if (rv == null) {
2327             return new Dimension(getWidth(), getHeight());
2328         }
2329         else {
2330             rv.setSize(getWidth(), getHeight());
2331             return rv;
2332         }
2333     }
2334 
2335     /**
2336      * Stores the x,y origin of this component into "return value" <b>rv</b>
2337      * and return <b>rv</b>.   If rv is <code>null</code> a new
2338      * <code>Point</code> is allocated.
2339      * This version of <code>getLocation</code> is useful if the
2340      * caller wants to avoid allocating a new <code>Point</code>
2341      * object on the heap.
2342      *
2343      * @param rv the return value, modified to the components location
2344      * @return rv
2345      */
2346     public Point getLocation(Point rv) {
2347         if (rv == null) {
2348             return new Point(getX(), getY());
2349         }
2350         else {
2351             rv.setLocation(getX(), getY());
2352             return rv;
2353         }
2354     }
2355 
2356     /**
2357      * Returns true if this component is completely opaque, returns
2358      * false by default.
2359      * <p>
2360      * An opaque component paints every pixel within its
2361      * rectangular region. A non-opaque component paints only some of
2362      * its pixels, allowing the pixels underneath it to "show through".
2363      * A component that does not fully paint its pixels therefore
2364      * provides a degree of transparency.  Only lightweight
2365      * components can be transparent.
2366      * <p>
2367      * Subclasses that guarantee to always completely paint their
2368      * contents should override this method and return true.  All
2369      * of the "heavyweight" AWT components are opaque.
2370      *
2371      * @return true if this component is completely opaque
2372      * @see #isLightweight
2373      * @since 1.2
2374      */
2375     public boolean isOpaque() {
2376         if (getPeer() == null) {
2377             return false;
2378         }
2379         else {
2380             return !isLightweight();
2381         }
2382     }
2383 
2384 
2385     /**
2386      * A lightweight component doesn't have a native toolkit peer.
2387      * Subclasses of <code>Component</code> and <code>Container</code>,
2388      * other than the ones defined in this package like <code>Button</code>
2389      * or <code>Scrollbar</code>, are lightweight.
2390      * All of the Swing components are lightweights.
2391      * <p>
2392      * This method will always return <code>false</code> if this component
2393      * is not displayable because it is impossible to determine the
2394      * weight of an undisplayable component.
2395      *
2396      * @return true if this component has a lightweight peer; false if
2397      *         it has a native peer or no peer
2398      * @see #isDisplayable
2399      * @since 1.2
2400      */
2401     public boolean isLightweight() {
2402         return getPeer() instanceof LightweightPeer;
2403     }
2404 
2405 
2406     /**
2407      * Sets the preferred size of this component to a constant
2408      * value.  Subsequent calls to <code>getPreferredSize</code> will always
2409      * return this value.  Setting the preferred size to <code>null</code>
2410      * restores the default behavior.
2411      *
2412      * @param preferredSize The new preferred size, or null
2413      * @see #getPreferredSize
2414      * @see #isPreferredSizeSet
2415      * @since 1.5
2416      */
2417     public void setPreferredSize(Dimension preferredSize) {
2418         Dimension old;
2419         // If the preferred size was set, use it as the old value, otherwise
2420         // use null to indicate we didn't previously have a set preferred
2421         // size.
2422         if (prefSizeSet) {
2423             old = this.prefSize;
2424         }
2425         else {
2426             old = null;
2427         }
2428         this.prefSize = preferredSize;
2429         prefSizeSet = (preferredSize != null);
2430         firePropertyChange("preferredSize", old, preferredSize);
2431     }
2432 
2433 
2434     /**
2435      * Returns true if the preferred size has been set to a
2436      * non-<code>null</code> value otherwise returns false.
2437      *
2438      * @return true if <code>setPreferredSize</code> has been invoked
2439      *         with a non-null value.
2440      * @since 1.5
2441      */
2442     public boolean isPreferredSizeSet() {
2443         return prefSizeSet;
2444     }
2445 
2446 
2447     /**
2448      * Gets the preferred size of this component.
2449      * @return a dimension object indicating this component's preferred size
2450      * @see #getMinimumSize
2451      * @see LayoutManager
2452      */
2453     public Dimension getPreferredSize() {
2454         return preferredSize();
2455     }
2456 
2457 
2458     /**
2459      * @deprecated As of JDK version 1.1,
2460      * replaced by <code>getPreferredSize()</code>.
2461      */
2462     @Deprecated
2463     public Dimension preferredSize() {
2464         /* Avoid grabbing the lock if a reasonable cached size value
2465          * is available.
2466          */
2467         Dimension dim = prefSize;
2468         if (dim == null || !(isPreferredSizeSet() || isValid())) {
2469             synchronized (getTreeLock()) {
2470                 prefSize = (peer != null) ?
2471                     peer.getPreferredSize() :
2472                     getMinimumSize();
2473                 dim = prefSize;
2474             }
2475         }
2476         return new Dimension(dim);
2477     }
2478 
2479     /**
2480      * Sets the minimum size of this component to a constant
2481      * value.  Subsequent calls to <code>getMinimumSize</code> will always
2482      * return this value.  Setting the minimum size to <code>null</code>
2483      * restores the default behavior.
2484      *
2485      * @param minimumSize the new minimum size of this component
2486      * @see #getMinimumSize
2487      * @see #isMinimumSizeSet
2488      * @since 1.5
2489      */
2490     public void setMinimumSize(Dimension minimumSize) {
2491         Dimension old;
2492         // If the minimum size was set, use it as the old value, otherwise
2493         // use null to indicate we didn't previously have a set minimum
2494         // size.
2495         if (minSizeSet) {
2496             old = this.minSize;
2497         }
2498         else {
2499             old = null;
2500         }
2501         this.minSize = minimumSize;
2502         minSizeSet = (minimumSize != null);
2503         firePropertyChange("minimumSize", old, minimumSize);
2504     }
2505 
2506     /**
2507      * Returns whether or not <code>setMinimumSize</code> has been
2508      * invoked with a non-null value.
2509      *
2510      * @return true if <code>setMinimumSize</code> has been invoked with a
2511      *              non-null value.
2512      * @since 1.5
2513      */
2514     public boolean isMinimumSizeSet() {
2515         return minSizeSet;
2516     }
2517 
2518     /**
2519      * Gets the mininimum size of this component.
2520      * @return a dimension object indicating this component's minimum size
2521      * @see #getPreferredSize
2522      * @see LayoutManager
2523      */
2524     public Dimension getMinimumSize() {
2525         return minimumSize();
2526     }
2527 
2528     /**
2529      * @deprecated As of JDK version 1.1,
2530      * replaced by <code>getMinimumSize()</code>.
2531      */
2532     @Deprecated
2533     public Dimension minimumSize() {
2534         /* Avoid grabbing the lock if a reasonable cached size value
2535          * is available.
2536          */
2537         Dimension dim = minSize;
2538         if (dim == null || !(isMinimumSizeSet() || isValid())) {
2539             synchronized (getTreeLock()) {
2540                 minSize = (peer != null) ?
2541                     peer.getMinimumSize() :
2542                     size();
2543                 dim = minSize;
2544             }
2545         }
2546         return new Dimension(dim);
2547     }
2548 
2549     /**
2550      * Sets the maximum size of this component to a constant
2551      * value.  Subsequent calls to <code>getMaximumSize</code> will always
2552      * return this value.  Setting the maximum size to <code>null</code>
2553      * restores the default behavior.
2554      *
2555      * @param maximumSize a <code>Dimension</code> containing the
2556      *          desired maximum allowable size
2557      * @see #getMaximumSize
2558      * @see #isMaximumSizeSet
2559      * @since 1.5
2560      */
2561     public void setMaximumSize(Dimension maximumSize) {
2562         // If the maximum size was set, use it as the old value, otherwise
2563         // use null to indicate we didn't previously have a set maximum
2564         // size.
2565         Dimension old;
2566         if (maxSizeSet) {
2567             old = this.maxSize;
2568         }
2569         else {
2570             old = null;
2571         }
2572         this.maxSize = maximumSize;
2573         maxSizeSet = (maximumSize != null);
2574         firePropertyChange("maximumSize", old, maximumSize);
2575     }
2576 
2577     /**
2578      * Returns true if the maximum size has been set to a non-<code>null</code>
2579      * value otherwise returns false.
2580      *
2581      * @return true if <code>maximumSize</code> is non-<code>null</code>,
2582      *          false otherwise
2583      * @since 1.5
2584      */
2585     public boolean isMaximumSizeSet() {
2586         return maxSizeSet;
2587     }
2588 
2589     /**
2590      * Gets the maximum size of this component.
2591      * @return a dimension object indicating this component's maximum size
2592      * @see #getMinimumSize
2593      * @see #getPreferredSize
2594      * @see LayoutManager
2595      */
2596     public Dimension getMaximumSize() {
2597         if (isMaximumSizeSet()) {
2598             return new Dimension(maxSize);
2599         }
2600         return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
2601     }
2602 
2603     /**
2604      * Returns the alignment along the x axis.  This specifies how
2605      * the component would like to be aligned relative to other
2606      * components.  The value should be a number between 0 and 1
2607      * where 0 represents alignment along the origin, 1 is aligned
2608      * the furthest away from the origin, 0.5 is centered, etc.
2609      */
2610     public float getAlignmentX() {
2611         return CENTER_ALIGNMENT;
2612     }
2613 
2614     /**
2615      * Returns the alignment along the y axis.  This specifies how
2616      * the component would like to be aligned relative to other
2617      * components.  The value should be a number between 0 and 1
2618      * where 0 represents alignment along the origin, 1 is aligned
2619      * the furthest away from the origin, 0.5 is centered, etc.
2620      */
2621     public float getAlignmentY() {
2622         return CENTER_ALIGNMENT;
2623     }
2624 
2625     /**
2626      * Returns the baseline.  The baseline is measured from the top of
2627      * the component.  This method is primarily meant for
2628      * <code>LayoutManager</code>s to align components along their
2629      * baseline.  A return value less than 0 indicates this component
2630      * does not have a reasonable baseline and that
2631      * <code>LayoutManager</code>s should not align this component on
2632      * its baseline.
2633      * <p>
2634      * The default implementation returns -1.  Subclasses that support
2635      * baseline should override appropriately.  If a value &gt;= 0 is
2636      * returned, then the component has a valid baseline for any
2637      * size &gt;= the minimum size and <code>getBaselineResizeBehavior</code>
2638      * can be used to determine how the baseline changes with size.
2639      *
2640      * @param width the width to get the baseline for
2641      * @param height the height to get the baseline for
2642      * @return the baseline or &lt; 0 indicating there is no reasonable
2643      *         baseline
2644      * @throws IllegalArgumentException if width or height is &lt; 0
2645      * @see #getBaselineResizeBehavior
2646      * @see java.awt.FontMetrics
2647      * @since 1.6
2648      */
2649     public int getBaseline(int width, int height) {
2650         if (width < 0 || height < 0) {
2651             throw new IllegalArgumentException(
2652                     "Width and height must be >= 0");
2653         }
2654         return -1;
2655     }
2656 
2657     /**
2658      * Returns an enum indicating how the baseline of the component
2659      * changes as the size changes.  This method is primarily meant for
2660      * layout managers and GUI builders.
2661      * <p>
2662      * The default implementation returns
2663      * <code>BaselineResizeBehavior.OTHER</code>.  Subclasses that have a
2664      * baseline should override appropriately.  Subclasses should
2665      * never return <code>null</code>; if the baseline can not be
2666      * calculated return <code>BaselineResizeBehavior.OTHER</code>.  Callers
2667      * should first ask for the baseline using
2668      * <code>getBaseline</code> and if a value &gt;= 0 is returned use
2669      * this method.  It is acceptable for this method to return a
2670      * value other than <code>BaselineResizeBehavior.OTHER</code> even if
2671      * <code>getBaseline</code> returns a value less than 0.
2672      *
2673      * @return an enum indicating how the baseline changes as the component
2674      *         size changes
2675      * @see #getBaseline(int, int)
2676      * @since 1.6
2677      */
2678     public BaselineResizeBehavior getBaselineResizeBehavior() {
2679         return BaselineResizeBehavior.OTHER;
2680     }
2681 
2682     /**
2683      * Prompts the layout manager to lay out this component. This is
2684      * usually called when the component (more specifically, container)
2685      * is validated.
2686      * @see #validate
2687      * @see LayoutManager
2688      */
2689     public void doLayout() {
2690         layout();
2691     }
2692 
2693     /**
2694      * @deprecated As of JDK version 1.1,
2695      * replaced by <code>doLayout()</code>.
2696      */
2697     @Deprecated
2698     public void layout() {
2699     }
2700 
2701     /**
2702      * Ensures that this component has a valid layout.  This method is
2703      * primarily intended to operate on instances of <code>Container</code>.
2704      * @see       #invalidate
2705      * @see       #doLayout()
2706      * @see       LayoutManager
2707      * @see       Container#validate
2708      * @since     JDK1.0
2709      */
2710     public void validate() {
2711         synchronized (getTreeLock()) {
2712             ComponentPeer peer = this.peer;
2713             boolean wasValid = isValid();
2714             if (!wasValid && peer != null) {
2715                 Font newfont = getFont();
2716                 Font oldfont = peerFont;
2717                 if (newfont != oldfont && (oldfont == null
2718                                            || !oldfont.equals(newfont))) {
2719                     peer.setFont(newfont);
2720                     peerFont = newfont;
2721                 }
2722                 peer.layout();
2723             }
2724             valid = true;
2725             if (!wasValid) {
2726                 mixOnValidating();
2727             }
2728         }
2729     }
2730 
2731     /**
2732      * Invalidates this component.  This component and all parents
2733      * above it are marked as needing to be laid out.  This method can
2734      * be called often, so it needs to execute quickly.
2735      * @see       #validate
2736      * @see       #doLayout
2737      * @see       LayoutManager
2738      * @since     JDK1.0
2739      */
2740     public void invalidate() {
2741         synchronized (getTreeLock()) {
2742             /* Nullify cached layout and size information.
2743              * For efficiency, propagate invalidate() upwards only if
2744              * some other component hasn't already done so first.
2745              */
2746             valid = false;
2747             if (!isPreferredSizeSet()) {
2748                 prefSize = null;
2749             }
2750             if (!isMinimumSizeSet()) {
2751                 minSize = null;
2752             }
2753             if (!isMaximumSizeSet()) {
2754                 maxSize = null;
2755             }
2756             if (parent != null) {
2757                 parent.invalidateIfValid();
2758             }
2759         }
2760     }
2761 
2762     /** Invalidates the component unless it is already invalid.
2763      */
2764     final void invalidateIfValid() {
2765         if (isValid()) {
2766             invalidate();
2767         }
2768     }
2769 
2770     /**
2771      * Creates a graphics context for this component. This method will
2772      * return <code>null</code> if this component is currently not
2773      * displayable.
2774      * @return a graphics context for this component, or <code>null</code>
2775      *             if it has none
2776      * @see       #paint
2777      * @since     JDK1.0
2778      */
2779     public Graphics getGraphics() {
2780         if (peer instanceof LightweightPeer) {
2781             // This is for a lightweight component, need to
2782             // translate coordinate spaces and clip relative
2783             // to the parent.
2784             if (parent == null) return null;
2785             Graphics g = parent.getGraphics();
2786             if (g == null) return null;
2787             if (g instanceof ConstrainableGraphics) {
2788                 ((ConstrainableGraphics) g).constrain(x, y, width, height);
2789             } else {
2790                 g.translate(x,y);
2791                 g.setClip(0, 0, width, height);
2792             }
2793             g.setFont(getFont());
2794             return g;
2795         } else {
2796             ComponentPeer peer = this.peer;
2797             return (peer != null) ? peer.getGraphics() : null;
2798         }
2799     }
2800 
2801     final Graphics getGraphics_NoClientCode() {
2802         ComponentPeer peer = this.peer;
2803         if (peer instanceof LightweightPeer) {
2804             // This is for a lightweight component, need to
2805             // translate coordinate spaces and clip relative
2806             // to the parent.
2807             Container parent = this.parent;
2808             if (parent == null) return null;
2809             Graphics g = parent.getGraphics_NoClientCode();
2810             if (g == null) return null;
2811             if (g instanceof ConstrainableGraphics) {
2812                 ((ConstrainableGraphics) g).constrain(x, y, width, height);
2813             } else {
2814                 g.translate(x,y);
2815                 g.setClip(0, 0, width, height);
2816             }
2817             g.setFont(getFont_NoClientCode());
2818             return g;
2819         } else {
2820             return (peer != null) ? peer.getGraphics() : null;
2821         }
2822     }
2823 
2824     /**
2825      * Gets the font metrics for the specified font.
2826      * Warning: Since Font metrics are affected by the
2827      * {@link java.awt.font.FontRenderContext FontRenderContext} and
2828      * this method does not provide one, it can return only metrics for
2829      * the default render context which may not match that used when
2830      * rendering on the Component if {@link Graphics2D} functionality is being
2831      * used. Instead metrics can be obtained at rendering time by calling
2832      * {@link Graphics#getFontMetrics()} or text measurement APIs on the
2833      * {@link Font Font} class.
2834      * @param font the font for which font metrics is to be
2835      *          obtained
2836      * @return the font metrics for <code>font</code>
2837      * @see       #getFont
2838      * @see       #getPeer
2839      * @see       java.awt.peer.ComponentPeer#getFontMetrics(Font)
2840      * @see       Toolkit#getFontMetrics(Font)
2841      * @since     JDK1.0
2842      */
2843     public FontMetrics getFontMetrics(Font font) {
2844         // REMIND: PlatformFont flag should be obsolete soon...
2845         if (sun.font.FontManager.usePlatformFontMetrics()) {
2846             if (peer != null &&
2847                 !(peer instanceof LightweightPeer)) {
2848                 return peer.getFontMetrics(font);
2849             }
2850         }
2851         return sun.font.FontDesignMetrics.getMetrics(font);
2852     }
2853 
2854     /**
2855      * Sets the cursor image to the specified cursor.  This cursor
2856      * image is displayed when the <code>contains</code> method for
2857      * this component returns true for the current cursor location, and
2858      * this Component is visible, displayable, and enabled. Setting the
2859      * cursor of a <code>Container</code> causes that cursor to be displayed
2860      * within all of the container's subcomponents, except for those
2861      * that have a non-<code>null</code> cursor.
2862      * <p>
2863      * The method may have no visual effect if the Java platform
2864      * implementation and/or the native system do not support
2865      * changing the mouse cursor shape.
2866      * @param cursor One of the constants defined
2867      *          by the <code>Cursor</code> class;
2868      *          if this parameter is <code>null</code>
2869      *          then this component will inherit
2870      *          the cursor of its parent
2871      * @see       #isEnabled
2872      * @see       #isShowing
2873      * @see       #getCursor
2874      * @see       #contains
2875      * @see       Toolkit#createCustomCursor
2876      * @see       Cursor
2877      * @since     JDK1.1
2878      */
2879     public void setCursor(Cursor cursor) {
2880         this.cursor = cursor;
2881         updateCursorImmediately();
2882     }
2883 
2884     /**
2885      * Updates the cursor.  May not be invoked from the native
2886      * message pump.
2887      */
2888     final void updateCursorImmediately() {
2889         if (peer instanceof LightweightPeer) {
2890             Container nativeContainer = getNativeContainer();
2891 
2892             if (nativeContainer == null) return;
2893 
2894             ComponentPeer cPeer = nativeContainer.getPeer();
2895 
2896             if (cPeer != null) {
2897                 cPeer.updateCursorImmediately();
2898             }
2899         } else if (peer != null) {
2900             peer.updateCursorImmediately();
2901         }
2902     }
2903 
2904     /**
2905      * Gets the cursor set in the component. If the component does
2906      * not have a cursor set, the cursor of its parent is returned.
2907      * If no cursor is set in the entire hierarchy,
2908      * <code>Cursor.DEFAULT_CURSOR</code> is returned.
2909      * @see #setCursor
2910      * @since      JDK1.1
2911      */
2912     public Cursor getCursor() {
2913         return getCursor_NoClientCode();
2914     }
2915 
2916     final Cursor getCursor_NoClientCode() {
2917         Cursor cursor = this.cursor;
2918         if (cursor != null) {
2919             return cursor;
2920         }
2921         Container parent = this.parent;
2922         if (parent != null) {
2923             return parent.getCursor_NoClientCode();
2924         } else {
2925             return Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
2926         }
2927     }
2928 
2929     /**
2930      * Returns whether the cursor has been explicitly set for this Component.
2931      * If this method returns <code>false</code>, this Component is inheriting
2932      * its cursor from an ancestor.
2933      *
2934      * @return <code>true</code> if the cursor has been explicitly set for this
2935      *         Component; <code>false</code> otherwise.
2936      * @since 1.4
2937      */
2938     public boolean isCursorSet() {
2939         return (cursor != null);
2940     }
2941 
2942     /**
2943      * Paints this component.
2944      * <p>
2945      * This method is called when the contents of the component should
2946      * be painted; such as when the component is first being shown or
2947      * is damaged and in need of repair.  The clip rectangle in the
2948      * <code>Graphics</code> parameter is set to the area
2949      * which needs to be painted.
2950      * Subclasses of <code>Component</code> that override this
2951      * method need not call <code>super.paint(g)</code>.
2952      * <p>
2953      * For performance reasons, <code>Component</code>s with zero width
2954      * or height aren't considered to need painting when they are first shown,
2955      * and also aren't considered to need repair.
2956      * <p>
2957      * <b>Note</b>: For more information on the paint mechanisms utilitized
2958      * by AWT and Swing, including information on how to write the most
2959      * efficient painting code, see
2960      * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
2961      *
2962      * @param g the graphics context to use for painting
2963      * @see       #update
2964      * @since     JDK1.0
2965      */
2966     public void paint(Graphics g) {
2967     }
2968 
2969     /**
2970      * Updates this component.
2971      * <p>
2972      * If this component is not a lightweight component, the
2973      * AWT calls the <code>update</code> method in response to
2974      * a call to <code>repaint</code>.  You can assume that
2975      * the background is not cleared.
2976      * <p>
2977      * The <code>update</code> method of <code>Component</code>
2978      * calls this component's <code>paint</code> method to redraw
2979      * this component.  This method is commonly overridden by subclasses
2980      * which need to do additional work in response to a call to
2981      * <code>repaint</code>.
2982      * Subclasses of Component that override this method should either
2983      * call <code>super.update(g)</code>, or call <code>paint(g)</code>
2984      * directly from their <code>update</code> method.
2985      * <p>
2986      * The origin of the graphics context, its
2987      * (<code>0</code>,&nbsp;<code>0</code>) coordinate point, is the
2988      * top-left corner of this component. The clipping region of the
2989      * graphics context is the bounding rectangle of this component.
2990      *
2991      * <p>
2992      * <b>Note</b>: For more information on the paint mechanisms utilitized
2993      * by AWT and Swing, including information on how to write the most
2994      * efficient painting code, see
2995      * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
2996      *
2997      * @param g the specified context to use for updating
2998      * @see       #paint
2999      * @see       #repaint()
3000      * @since     JDK1.0
3001      */
3002     public void update(Graphics g) {
3003         paint(g);
3004     }
3005 
3006     /**
3007      * Paints this component and all of its subcomponents.
3008      * <p>
3009      * The origin of the graphics context, its
3010      * (<code>0</code>,&nbsp;<code>0</code>) coordinate point, is the
3011      * top-left corner of this component. The clipping region of the
3012      * graphics context is the bounding rectangle of this component.
3013      *
3014      * @param     g   the graphics context to use for painting
3015      * @see       #paint
3016      * @since     JDK1.0
3017      */
3018     public void paintAll(Graphics g) {
3019         if (isShowing()) {
3020             GraphicsCallback.PeerPaintCallback.getInstance().
3021                 runOneComponent(this, new Rectangle(0, 0, width, height),
3022                                 g, g.getClip(),
3023                                 GraphicsCallback.LIGHTWEIGHTS |
3024                                 GraphicsCallback.HEAVYWEIGHTS);
3025         }
3026     }
3027 
3028     /**
3029      * Simulates the peer callbacks into java.awt for painting of
3030      * lightweight Components.
3031      * @param     g   the graphics context to use for painting
3032      * @see       #paintAll
3033      */
3034     void lightweightPaint(Graphics g) {
3035         paint(g);
3036     }
3037 
3038     /**
3039      * Paints all the heavyweight subcomponents.
3040      */
3041     void paintHeavyweightComponents(Graphics g) {
3042     }
3043 
3044     /**
3045      * Repaints this component.
3046      * <p>
3047      * If this component is a lightweight component, this method
3048      * causes a call to this component's <code>paint</code>
3049      * method as soon as possible.  Otherwise, this method causes
3050      * a call to this component's <code>update</code> method as soon
3051      * as possible.
3052      * <p>
3053      * <b>Note</b>: For more information on the paint mechanisms utilitized
3054      * by AWT and Swing, including information on how to write the most
3055      * efficient painting code, see
3056      * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
3057 
3058      *
3059      * @see       #update(Graphics)
3060      * @since     JDK1.0
3061      */
3062     public void repaint() {
3063         repaint(0, 0, 0, width, height);
3064     }
3065 
3066     /**
3067      * Repaints the component.  If this component is a lightweight
3068      * component, this results in a call to <code>paint</code>
3069      * within <code>tm</code> milliseconds.
3070      * <p>
3071      * <b>Note</b>: For more information on the paint mechanisms utilitized
3072      * by AWT and Swing, including information on how to write the most
3073      * efficient painting code, see
3074      * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
3075      *
3076      * @param tm maximum time in milliseconds before update
3077      * @see #paint
3078      * @see #update(Graphics)
3079      * @since JDK1.0
3080      */
3081     public void repaint(long tm) {
3082         repaint(tm, 0, 0, width, height);
3083     }
3084 
3085     /**
3086      * Repaints the specified rectangle of this component.
3087      * <p>
3088      * If this component is a lightweight component, this method
3089      * causes a call to this component's <code>paint</code> method
3090      * as soon as possible.  Otherwise, this method causes a call to
3091      * this component's <code>update</code> method as soon as possible.
3092      * <p>
3093      * <b>Note</b>: For more information on the paint mechanisms utilitized
3094      * by AWT and Swing, including information on how to write the most
3095      * efficient painting code, see
3096      * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
3097      *
3098      * @param     x   the <i>x</i> coordinate
3099      * @param     y   the <i>y</i> coordinate
3100      * @param     width   the width
3101      * @param     height  the height
3102      * @see       #update(Graphics)
3103      * @since     JDK1.0
3104      */
3105     public void repaint(int x, int y, int width, int height) {
3106         repaint(0, x, y, width, height);
3107     }
3108 
3109     /**
3110      * Repaints the specified rectangle of this component within
3111      * <code>tm</code> milliseconds.
3112      * <p>
3113      * If this component is a lightweight component, this method causes
3114      * a call to this component's <code>paint</code> method.
3115      * Otherwise, this method causes a call to this component's
3116      * <code>update</code> method.
3117      * <p>
3118      * <b>Note</b>: For more information on the paint mechanisms utilitized
3119      * by AWT and Swing, including information on how to write the most
3120      * efficient painting code, see
3121      * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
3122      *
3123      * @param     tm   maximum time in milliseconds before update
3124      * @param     x    the <i>x</i> coordinate
3125      * @param     y    the <i>y</i> coordinate
3126      * @param     width    the width
3127      * @param     height   the height
3128      * @see       #update(Graphics)
3129      * @since     JDK1.0
3130      */
3131     public void repaint(long tm, int x, int y, int width, int height) {
3132         if (this.peer instanceof LightweightPeer) {
3133             // Needs to be translated to parent coordinates since
3134             // a parent native container provides the actual repaint
3135             // services.  Additionally, the request is restricted to
3136             // the bounds of the component.
3137             if (parent != null) {
3138                 if (x < 0) {
3139                     width += x;
3140                     x = 0;
3141                 }
3142                 if (y < 0) {
3143                     height += y;
3144                     y = 0;
3145                 }
3146 
3147                 int pwidth = (width > this.width) ? this.width : width;
3148                 int pheight = (height > this.height) ? this.height : height;
3149 
3150                 if (pwidth <= 0 || pheight <= 0) {
3151                     return;
3152                 }
3153 
3154                 int px = this.x + x;
3155                 int py = this.y + y;
3156                 parent.repaint(tm, px, py, pwidth, pheight);
3157             }
3158         } else {
3159             if (isVisible() && (this.peer != null) &&
3160                 (width > 0) && (height > 0)) {
3161                 PaintEvent e = new PaintEvent(this, PaintEvent.UPDATE,
3162                                               new Rectangle(x, y, width, height));
3163                 Toolkit.getEventQueue().postEvent(e);
3164             }
3165         }
3166     }
3167 
3168     /**
3169      * Prints this component. Applications should override this method
3170      * for components that must do special processing before being
3171      * printed or should be printed differently than they are painted.
3172      * <p>
3173      * The default implementation of this method calls the
3174      * <code>paint</code> method.
3175      * <p>
3176      * The origin of the graphics context, its
3177      * (<code>0</code>,&nbsp;<code>0</code>) coordinate point, is the
3178      * top-left corner of this component. The clipping region of the
3179      * graphics context is the bounding rectangle of this component.
3180      * @param     g   the graphics context to use for printing
3181      * @see       #paint(Graphics)
3182      * @since     JDK1.0
3183      */
3184     public void print(Graphics g) {
3185         paint(g);
3186     }
3187 
3188     /**
3189      * Prints this component and all of its subcomponents.
3190      * <p>
3191      * The origin of the graphics context, its
3192      * (<code>0</code>,&nbsp;<code>0</code>) coordinate point, is the
3193      * top-left corner of this component. The clipping region of the
3194      * graphics context is the bounding rectangle of this component.
3195      * @param     g   the graphics context to use for printing
3196      * @see       #print(Graphics)
3197      * @since     JDK1.0
3198      */
3199     public void printAll(Graphics g) {
3200         if (isShowing()) {
3201             GraphicsCallback.PeerPrintCallback.getInstance().
3202                 runOneComponent(this, new Rectangle(0, 0, width, height),
3203                                 g, g.getClip(),
3204                                 GraphicsCallback.LIGHTWEIGHTS |
3205                                 GraphicsCallback.HEAVYWEIGHTS);
3206         }
3207     }
3208 
3209     /**
3210      * Simulates the peer callbacks into java.awt for printing of
3211      * lightweight Components.
3212      * @param     g   the graphics context to use for printing
3213      * @see       #printAll
3214      */
3215     void lightweightPrint(Graphics g) {
3216         print(g);
3217     }
3218 
3219     /**
3220      * Prints all the heavyweight subcomponents.
3221      */
3222     void printHeavyweightComponents(Graphics g) {
3223     }
3224 
3225     private Insets getInsets_NoClientCode() {
3226         ComponentPeer peer = this.peer;
3227         if (peer instanceof ContainerPeer) {
3228             return (Insets)((ContainerPeer)peer).getInsets().clone();
3229         }
3230         return new Insets(0, 0, 0, 0);
3231     }
3232 
3233     /**
3234      * Repaints the component when the image has changed.
3235      * This <code>imageUpdate</code> method of an <code>ImageObserver</code>
3236      * is called when more information about an
3237      * image which had been previously requested using an asynchronous
3238      * routine such as the <code>drawImage</code> method of
3239      * <code>Graphics</code> becomes available.
3240      * See the definition of <code>imageUpdate</code> for
3241      * more information on this method and its arguments.
3242      * <p>
3243      * The <code>imageUpdate</code> method of <code>Component</code>
3244      * incrementally draws an image on the component as more of the bits
3245      * of the image are available.
3246      * <p>
3247      * If the system property <code>awt.image.incrementaldraw</code>
3248      * is missing or has the value <code>true</code>, the image is
3249      * incrementally drawn. If the system property has any other value,
3250      * then the image is not drawn until it has been completely loaded.
3251      * <p>
3252      * Also, if incremental drawing is in effect, the value of the
3253      * system property <code>awt.image.redrawrate</code> is interpreted
3254      * as an integer to give the maximum redraw rate, in milliseconds. If
3255      * the system property is missing or cannot be interpreted as an
3256      * integer, the redraw rate is once every 100ms.
3257      * <p>
3258      * The interpretation of the <code>x</code>, <code>y</code>,
3259      * <code>width</code>, and <code>height</code> arguments depends on
3260      * the value of the <code>infoflags</code> argument.
3261      *
3262      * @param     img   the image being observed
3263      * @param     infoflags   see <code>imageUpdate</code> for more information
3264      * @param     x   the <i>x</i> coordinate
3265      * @param     y   the <i>y</i> coordinate
3266      * @param     w   the width
3267      * @param     h   the height
3268      * @return    <code>false</code> if the infoflags indicate that the
3269      *            image is completely loaded; <code>true</code> otherwise.
3270      *
3271      * @see     java.awt.image.ImageObserver
3272      * @see     Graphics#drawImage(Image, int, int, Color, java.awt.image.ImageObserver)
3273      * @see     Graphics#drawImage(Image, int, int, java.awt.image.ImageObserver)
3274      * @see     Graphics#drawImage(Image, int, int, int, int, Color, java.awt.image.ImageObserver)
3275      * @see     Graphics#drawImage(Image, int, int, int, int, java.awt.image.ImageObserver)
3276      * @see     java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
3277      * @since   JDK1.0
3278      */
3279     public boolean imageUpdate(Image img, int infoflags,
3280                                int x, int y, int w, int h) {
3281         int rate = -1;
3282         if ((infoflags & (FRAMEBITS|ALLBITS)) != 0) {
3283             rate = 0;
3284         } else if ((infoflags & SOMEBITS) != 0) {
3285             if (isInc) {
3286                 rate = incRate;
3287                 if (rate < 0) {
3288                     rate = 0;
3289                 }
3290             }
3291         }
3292         if (rate >= 0) {
3293             repaint(rate, 0, 0, width, height);
3294         }
3295         return (infoflags & (ALLBITS|ABORT)) == 0;
3296     }
3297 
3298     /**
3299      * Creates an image from the specified image producer.
3300      * @param     producer  the image producer
3301      * @return    the image produced
3302      * @since     JDK1.0
3303      */
3304     public Image createImage(ImageProducer producer) {
3305         ComponentPeer peer = this.peer;
3306         if ((peer != null) && ! (peer instanceof LightweightPeer)) {
3307             return peer.createImage(producer);
3308         }
3309         return getToolkit().createImage(producer);
3310     }
3311 
3312     /**
3313      * Creates an off-screen drawable image
3314      *     to be used for double buffering.
3315      * @param     width the specified width
3316      * @param     height the specified height
3317      * @return    an off-screen drawable image, which can be used for double
3318      *    buffering.  The return value may be <code>null</code> if the
3319      *    component is not displayable.  This will always happen if
3320      *    <code>GraphicsEnvironment.isHeadless()</code> returns
3321      *    <code>true</code>.
3322      * @see #isDisplayable
3323      * @see GraphicsEnvironment#isHeadless
3324      * @since     JDK1.0
3325      */
3326     public Image createImage(int width, int height) {
3327         ComponentPeer peer = this.peer;
3328         if (peer instanceof LightweightPeer) {
3329             if (parent != null) { return parent.createImage(width, height); }
3330             else { return null;}
3331         } else {
3332             return (peer != null) ? peer.createImage(width, height) : null;
3333         }
3334     }
3335 
3336     /**
3337      * Creates a volatile off-screen drawable image
3338      *     to be used for double buffering.
3339      * @param     width the specified width.
3340      * @param     height the specified height.
3341      * @return    an off-screen drawable image, which can be used for double
3342      *    buffering.  The return value may be <code>null</code> if the
3343      *    component is not displayable.  This will always happen if
3344      *    <code>GraphicsEnvironment.isHeadless()</code> returns
3345      *    <code>true</code>.
3346      * @see java.awt.image.VolatileImage
3347      * @see #isDisplayable
3348      * @see GraphicsEnvironment#isHeadless
3349      * @since     1.4
3350      */
3351     public VolatileImage createVolatileImage(int width, int height) {
3352         ComponentPeer peer = this.peer;
3353         if (peer instanceof LightweightPeer) {
3354             if (parent != null) {
3355                 return parent.createVolatileImage(width, height);
3356             }
3357             else { return null;}
3358         } else {
3359             return (peer != null) ?
3360                 peer.createVolatileImage(width, height) : null;
3361         }
3362     }
3363 
3364     /**
3365      * Creates a volatile off-screen drawable image, with the given capabilities.
3366      * The contents of this image may be lost at any time due
3367      * to operating system issues, so the image must be managed
3368      * via the <code>VolatileImage</code> interface.
3369      * @param width the specified width.
3370      * @param height the specified height.
3371      * @param caps the image capabilities
3372      * @exception AWTException if an image with the specified capabilities cannot
3373      * be created
3374      * @return a VolatileImage object, which can be used
3375      * to manage surface contents loss and capabilities.
3376      * @see java.awt.image.VolatileImage
3377      * @since 1.4
3378      */
3379     public VolatileImage createVolatileImage(int width, int height,
3380                                              ImageCapabilities caps) throws AWTException {
3381         // REMIND : check caps
3382         return createVolatileImage(width, height);
3383     }
3384 
3385     /**
3386      * Prepares an image for rendering on this component.  The image
3387      * data is downloaded asynchronously in another thread and the
3388      * appropriate screen representation of the image is generated.
3389      * @param     image   the <code>Image</code> for which to
3390      *                    prepare a screen representation
3391      * @param     observer   the <code>ImageObserver</code> object
3392      *                       to be notified as the image is being prepared
3393      * @return    <code>true</code> if the image has already been fully
3394      *           prepared; <code>false</code> otherwise
3395      * @since     JDK1.0
3396      */
3397     public boolean prepareImage(Image image, ImageObserver observer) {
3398         return prepareImage(image, -1, -1, observer);
3399     }
3400 
3401     /**
3402      * Prepares an image for rendering on this component at the
3403      * specified width and height.
3404      * <p>
3405      * The image data is downloaded asynchronously in another thread,
3406      * and an appropriately scaled screen representation of the image is
3407      * generated.
3408      * @param     image    the instance of <code>Image</code>
3409      *            for which to prepare a screen representation
3410      * @param     width    the width of the desired screen representation
3411      * @param     height   the height of the desired screen representation
3412      * @param     observer   the <code>ImageObserver</code> object
3413      *            to be notified as the image is being prepared
3414      * @return    <code>true</code> if the image has already been fully
3415      *          prepared; <code>false</code> otherwise
3416      * @see       java.awt.image.ImageObserver
3417      * @since     JDK1.0
3418      */
3419     public boolean prepareImage(Image image, int width, int height,
3420                                 ImageObserver observer) {
3421         ComponentPeer peer = this.peer;
3422         if (peer instanceof LightweightPeer) {
3423             return (parent != null)
3424                 ? parent.prepareImage(image, width, height, observer)
3425                 : getToolkit().prepareImage(image, width, height, observer);
3426         } else {
3427             return (peer != null)
3428                 ? peer.prepareImage(image, width, height, observer)
3429                 : getToolkit().prepareImage(image, width, height, observer);
3430         }
3431     }
3432 
3433     /**
3434      * Returns the status of the construction of a screen representation
3435      * of the specified image.
3436      * <p>
3437      * This method does not cause the image to begin loading. An
3438      * application must use the <code>prepareImage</code> method
3439      * to force the loading of an image.
3440      * <p>
3441      * Information on the flags returned by this method can be found
3442      * with the discussion of the <code>ImageObserver</code> interface.
3443      * @param     image   the <code>Image</code> object whose status
3444      *            is being checked
3445      * @param     observer   the <code>ImageObserver</code>
3446      *            object to be notified as the image is being prepared
3447      * @return  the bitwise inclusive <b>OR</b> of
3448      *            <code>ImageObserver</code> flags indicating what
3449      *            information about the image is currently available
3450      * @see      #prepareImage(Image, int, int, java.awt.image.ImageObserver)
3451      * @see      Toolkit#checkImage(Image, int, int, java.awt.image.ImageObserver)
3452      * @see      java.awt.image.ImageObserver
3453      * @since    JDK1.0
3454      */
3455     public int checkImage(Image image, ImageObserver observer) {
3456         return checkImage(image, -1, -1, observer);
3457     }
3458 
3459     /**
3460      * Returns the status of the construction of a screen representation
3461      * of the specified image.
3462      * <p>
3463      * This method does not cause the image to begin loading. An
3464      * application must use the <code>prepareImage</code> method
3465      * to force the loading of an image.
3466      * <p>
3467      * The <code>checkImage</code> method of <code>Component</code>
3468      * calls its peer's <code>checkImage</code> method to calculate
3469      * the flags. If this component does not yet have a peer, the
3470      * component's toolkit's <code>checkImage</code> method is called
3471      * instead.
3472      * <p>
3473      * Information on the flags returned by this method can be found
3474      * with the discussion of the <code>ImageObserver</code> interface.
3475      * @param     image   the <code>Image</code> object whose status
3476      *                    is being checked
3477      * @param     width   the width of the scaled version
3478      *                    whose status is to be checked
3479      * @param     height  the height of the scaled version
3480      *                    whose status is to be checked
3481      * @param     observer   the <code>ImageObserver</code> object
3482      *                    to be notified as the image is being prepared
3483      * @return    the bitwise inclusive <b>OR</b> of
3484      *            <code>ImageObserver</code> flags indicating what
3485      *            information about the image is currently available
3486      * @see      #prepareImage(Image, int, int, java.awt.image.ImageObserver)
3487      * @see      Toolkit#checkImage(Image, int, int, java.awt.image.ImageObserver)
3488      * @see      java.awt.image.ImageObserver
3489      * @since    JDK1.0
3490      */
3491     public int checkImage(Image image, int width, int height,
3492                           ImageObserver observer) {
3493         ComponentPeer peer = this.peer;
3494         if (peer instanceof LightweightPeer) {
3495             return (parent != null)
3496                 ? parent.checkImage(image, width, height, observer)
3497                 : getToolkit().checkImage(image, width, height, observer);
3498         } else {
3499             return (peer != null)
3500                 ? peer.checkImage(image, width, height, observer)
3501                 : getToolkit().checkImage(image, width, height, observer);
3502         }
3503     }
3504 
3505     /**
3506      * Creates a new strategy for multi-buffering on this component.
3507      * Multi-buffering is useful for rendering performance.  This method
3508      * attempts to create the best strategy available with the number of
3509      * buffers supplied.  It will always create a <code>BufferStrategy</code>
3510      * with that number of buffers.
3511      * A page-flipping strategy is attempted first, then a blitting strategy
3512      * using accelerated buffers.  Finally, an unaccelerated blitting
3513      * strategy is used.
3514      * <p>
3515      * Each time this method is called,
3516      * the existing buffer strategy for this component is discarded.
3517      * @param numBuffers number of buffers to create, including the front buffer
3518      * @exception IllegalArgumentException if numBuffers is less than 1.
3519      * @exception IllegalStateException if the component is not displayable
3520      * @see #isDisplayable
3521      * @see Window#getBufferStrategy()
3522      * @see Canvas#getBufferStrategy()
3523      * @since 1.4
3524      */
3525     void createBufferStrategy(int numBuffers) {
3526         BufferCapabilities bufferCaps;
3527         if (numBuffers > 1) {
3528             // Try to create a page-flipping strategy
3529             bufferCaps = new BufferCapabilities(new ImageCapabilities(true),
3530                                                 new ImageCapabilities(true),
3531                                                 BufferCapabilities.FlipContents.UNDEFINED);
3532             try {
3533                 createBufferStrategy(numBuffers, bufferCaps);
3534                 return; // Success
3535             } catch (AWTException e) {
3536                 // Failed
3537             }
3538         }
3539         // Try a blitting (but still accelerated) strategy
3540         bufferCaps = new BufferCapabilities(new ImageCapabilities(true),
3541                                             new ImageCapabilities(true),
3542                                             null);
3543         try {
3544             createBufferStrategy(numBuffers, bufferCaps);
3545             return; // Success
3546         } catch (AWTException e) {
3547             // Failed
3548         }
3549         // Try an unaccelerated blitting strategy
3550         bufferCaps = new BufferCapabilities(new ImageCapabilities(false),
3551                                             new ImageCapabilities(false),
3552                                             null);
3553         try {
3554             createBufferStrategy(numBuffers, bufferCaps);
3555             return; // Success
3556         } catch (AWTException e) {
3557             // Failed
3558         }
3559         // Code should never reach here (an unaccelerated blitting
3560         // strategy should always work)
3561         throw new InternalError("Could not create a buffer strategy");
3562     }
3563 
3564     /**
3565      * Creates a new strategy for multi-buffering on this component with the
3566      * required buffer capabilities.  This is useful, for example, if only
3567      * accelerated memory or page flipping is desired (as specified by the
3568      * buffer capabilities).
3569      * <p>
3570      * Each time this method
3571      * is called, <code>dispose</code> will be invoked on the existing
3572      * <code>BufferStrategy</code>.
3573      * @param numBuffers number of buffers to create
3574      * @param caps the required capabilities for creating the buffer strategy;
3575      * cannot be <code>null</code>
3576      * @exception AWTException if the capabilities supplied could not be
3577      * supported or met; this may happen, for example, if there is not enough
3578      * accelerated memory currently available, or if page flipping is specified
3579      * but not possible.
3580      * @exception IllegalArgumentException if numBuffers is less than 1, or if
3581      * caps is <code>null</code>
3582      * @see Window#getBufferStrategy()
3583      * @see Canvas#getBufferStrategy()
3584      * @since 1.4
3585      */
3586     void createBufferStrategy(int numBuffers,
3587                               BufferCapabilities caps) throws AWTException {
3588         // Check arguments
3589         if (numBuffers < 1) {
3590             throw new IllegalArgumentException(
3591                 "Number of buffers must be at least 1");
3592         }
3593         if (caps == null) {
3594             throw new IllegalArgumentException("No capabilities specified");
3595         }
3596         // Destroy old buffers
3597         if (bufferStrategy != null) {
3598             bufferStrategy.dispose();
3599         }
3600         if (numBuffers == 1) {
3601             bufferStrategy = new SingleBufferStrategy(caps);
3602         } else {
3603             SunGraphicsEnvironment sge = (SunGraphicsEnvironment)
3604                 GraphicsEnvironment.getLocalGraphicsEnvironment();
3605             if (!caps.isPageFlipping() && sge.isFlipStrategyPreferred(peer)) {
3606                 caps = new ProxyCapabilities(caps);
3607             }
3608             // assert numBuffers > 1;
3609             if (caps.isPageFlipping()) {
3610                 bufferStrategy = new FlipSubRegionBufferStrategy(numBuffers, caps);
3611             } else {
3612                 bufferStrategy = new BltSubRegionBufferStrategy(numBuffers, caps);
3613             }
3614         }
3615     }
3616 
3617     /**
3618      * This is a proxy capabilities class used when a FlipBufferStrategy
3619      * is created instead of the requested Blit strategy.
3620      *
3621      * @see sun.awt.SunGraphicsEnvironment#isFlipStrategyPreferred(ComponentPeer)
3622      */
3623     private class ProxyCapabilities extends ExtendedBufferCapabilities {
3624         private BufferCapabilities orig;
3625         private ProxyCapabilities(BufferCapabilities orig) {
3626             super(orig.getFrontBufferCapabilities(),
3627                   orig.getBackBufferCapabilities(),
3628                   orig.getFlipContents() ==
3629                       BufferCapabilities.FlipContents.BACKGROUND ?
3630                       BufferCapabilities.FlipContents.BACKGROUND :
3631                       BufferCapabilities.FlipContents.COPIED);
3632             this.orig = orig;
3633         }
3634     }
3635 
3636     /**
3637      * @return the buffer strategy used by this component
3638      * @see Window#createBufferStrategy
3639      * @see Canvas#createBufferStrategy
3640      * @since 1.4
3641      */
3642     BufferStrategy getBufferStrategy() {
3643         return bufferStrategy;
3644     }
3645 
3646     /**
3647      * @return the back buffer currently used by this component's
3648      * BufferStrategy.  If there is no BufferStrategy or no
3649      * back buffer, this method returns null.
3650      */
3651     Image getBackBuffer() {
3652         if (bufferStrategy != null) {
3653             if (bufferStrategy instanceof BltBufferStrategy) {
3654                 BltBufferStrategy bltBS = (BltBufferStrategy)bufferStrategy;
3655                 return bltBS.getBackBuffer();
3656             } else if (bufferStrategy instanceof FlipBufferStrategy) {
3657                 FlipBufferStrategy flipBS = (FlipBufferStrategy)bufferStrategy;
3658                 return flipBS.getBackBuffer();
3659             }
3660         }
3661         return null;
3662     }
3663 
3664     /**
3665      * Inner class for flipping buffers on a component.  That component must
3666      * be a <code>Canvas</code> or <code>Window</code>.
3667      * @see Canvas
3668      * @see Window
3669      * @see java.awt.image.BufferStrategy
3670      * @author Michael Martak
3671      * @since 1.4
3672      */
3673     protected class FlipBufferStrategy extends BufferStrategy {
3674         /**
3675          * The number of buffers
3676          */
3677         protected int numBuffers; // = 0
3678         /**
3679          * The buffering capabilities
3680          */
3681         protected BufferCapabilities caps; // = null
3682         /**
3683          * The drawing buffer
3684          */
3685         protected Image drawBuffer; // = null
3686         /**
3687          * The drawing buffer as a volatile image
3688          */
3689         protected VolatileImage drawVBuffer; // = null
3690         /**
3691          * Whether or not the drawing buffer has been recently restored from
3692          * a lost state.
3693          */
3694         protected boolean validatedContents; // = false
3695         /**
3696          * Size of the back buffers.  (Note: these fields were added in 6.0
3697          * but kept package-private to avoid exposing them in the spec.
3698          * None of these fields/methods really should have been marked
3699          * protected when they were introduced in 1.4, but now we just have
3700          * to live with that decision.)
3701          */
3702         int width;
3703         int height;
3704 
3705         /**
3706          * Creates a new flipping buffer strategy for this component.
3707          * The component must be a <code>Canvas</code> or <code>Window</code>.
3708          * @see Canvas
3709          * @see Window
3710          * @param numBuffers the number of buffers
3711          * @param caps the capabilities of the buffers
3712          * @exception AWTException if the capabilities supplied could not be
3713          * supported or met
3714          * @exception ClassCastException if the component is not a canvas or
3715          * window.
3716          */
3717         protected FlipBufferStrategy(int numBuffers, BufferCapabilities caps)
3718             throws AWTException
3719         {
3720             if (!(Component.this instanceof Window) &&
3721                 !(Component.this instanceof Canvas))
3722             {
3723                 throw new ClassCastException(
3724                     "Component must be a Canvas or Window");
3725             }
3726             this.numBuffers = numBuffers;
3727             this.caps = caps;
3728             createBuffers(numBuffers, caps);
3729         }
3730 
3731         /**
3732          * Creates one or more complex, flipping buffers with the given
3733          * capabilities.
3734          * @param numBuffers number of buffers to create; must be greater than
3735          * one
3736          * @param caps the capabilities of the buffers.
3737          * <code>BufferCapabilities.isPageFlipping</code> must be
3738          * <code>true</code>.
3739          * @exception AWTException if the capabilities supplied could not be
3740          * supported or met
3741          * @exception IllegalStateException if the component has no peer
3742          * @exception IllegalArgumentException if numBuffers is less than two,
3743          * or if <code>BufferCapabilities.isPageFlipping</code> is not
3744          * <code>true</code>.
3745          * @see java.awt.BufferCapabilities#isPageFlipping()
3746          */
3747         protected void createBuffers(int numBuffers, BufferCapabilities caps)
3748             throws AWTException
3749         {
3750             if (numBuffers < 2) {
3751                 throw new IllegalArgumentException(
3752                     "Number of buffers cannot be less than two");
3753             } else if (peer == null) {
3754                 throw new IllegalStateException(
3755                     "Component must have a valid peer");
3756             } else if (caps == null || !caps.isPageFlipping()) {
3757                 throw new IllegalArgumentException(
3758                     "Page flipping capabilities must be specified");
3759             }
3760 
3761             // save the current bounds
3762             width = getWidth();
3763             height = getHeight();
3764 
3765             if (drawBuffer != null) {
3766                 // dispose the existing backbuffers
3767                 drawBuffer = null;
3768                 drawVBuffer = null;
3769                 destroyBuffers();
3770                 // ... then recreate the backbuffers
3771             }
3772 
3773             if (caps instanceof ExtendedBufferCapabilities) {
3774                 ExtendedBufferCapabilities ebc =
3775                     (ExtendedBufferCapabilities)caps;
3776                 if (ebc.getVSync() == VSYNC_ON) {
3777                     // if this buffer strategy is not allowed to be v-synced,
3778                     // change the caps that we pass to the peer but keep on
3779                     // trying to create v-synced buffers;
3780                     // do not throw IAE here in case it is disallowed, see
3781                     // ExtendedBufferCapabilities for more info
3782                     if (!VSyncedBSManager.vsyncAllowed(this)) {
3783                         caps = ebc.derive(VSYNC_DEFAULT);
3784                     }
3785                 }
3786             }
3787 
3788             peer.createBuffers(numBuffers, caps);
3789             updateInternalBuffers();
3790         }
3791 
3792         /**
3793          * Updates internal buffers (both volatile and non-volatile)
3794          * by requesting the back-buffer from the peer.
3795          */
3796         private void updateInternalBuffers() {
3797             // get the images associated with the draw buffer
3798             drawBuffer = getBackBuffer();
3799             if (drawBuffer instanceof VolatileImage) {
3800                 drawVBuffer = (VolatileImage)drawBuffer;
3801             } else {
3802                 drawVBuffer = null;
3803             }
3804         }
3805 
3806         /**
3807          * @return direct access to the back buffer, as an image.
3808          * @exception IllegalStateException if the buffers have not yet
3809          * been created
3810          */
3811         protected Image getBackBuffer() {
3812             if (peer != null) {
3813                 return peer.getBackBuffer();
3814             } else {
3815                 throw new IllegalStateException(
3816                     "Component must have a valid peer");
3817             }
3818         }
3819 
3820         /**
3821          * Flipping moves the contents of the back buffer to the front buffer,
3822          * either by copying or by moving the video pointer.
3823          * @param flipAction an integer value describing the flipping action
3824          * for the contents of the back buffer.  This should be one of the
3825          * values of the <code>BufferCapabilities.FlipContents</code>
3826          * property.
3827          * @exception IllegalStateException if the buffers have not yet
3828          * been created
3829          * @see java.awt.BufferCapabilities#getFlipContents()
3830          */
3831         protected void flip(BufferCapabilities.FlipContents flipAction) {
3832             if (peer != null) {
3833                 Image backBuffer = getBackBuffer();
3834                 if (backBuffer != null) {
3835                     peer.flip(0, 0,
3836                               backBuffer.getWidth(null),
3837                               backBuffer.getHeight(null), flipAction);
3838                 }
3839             } else {
3840                 throw new IllegalStateException(
3841                     "Component must have a valid peer");
3842             }
3843         }
3844 
3845         void flipSubRegion(int x1, int y1, int x2, int y2,
3846                       BufferCapabilities.FlipContents flipAction)
3847         {
3848             if (peer != null) {
3849                 peer.flip(x1, y1, x2, y2, flipAction);
3850             } else {
3851                 throw new IllegalStateException(
3852                     "Component must have a valid peer");
3853             }
3854         }
3855 
3856         /**
3857          * Destroys the buffers created through this object
3858          */
3859         protected void destroyBuffers() {
3860             VSyncedBSManager.releaseVsync(this);
3861             if (peer != null) {
3862                 peer.destroyBuffers();
3863             } else {
3864                 throw new IllegalStateException(
3865                     "Component must have a valid peer");
3866             }
3867         }
3868 
3869         /**
3870          * @return the buffering capabilities of this strategy
3871          */
3872         public BufferCapabilities getCapabilities() {
3873             if (caps instanceof ProxyCapabilities) {
3874                 return ((ProxyCapabilities)caps).orig;
3875             } else {
3876                 return caps;
3877             }
3878         }
3879 
3880         /**
3881          * @return the graphics on the drawing buffer.  This method may not
3882          * be synchronized for performance reasons; use of this method by multiple
3883          * threads should be handled at the application level.  Disposal of the
3884          * graphics object must be handled by the application.
3885          */
3886         public Graphics getDrawGraphics() {
3887             revalidate();
3888             return drawBuffer.getGraphics();
3889         }
3890 
3891         /**
3892          * Restore the drawing buffer if it has been lost
3893          */
3894         protected void revalidate() {
3895             revalidate(true);
3896         }
3897 
3898         void revalidate(boolean checkSize) {
3899             validatedContents = false;
3900 
3901             if (checkSize && (getWidth() != width || getHeight() != height)) {
3902                 // component has been resized; recreate the backbuffers
3903                 try {
3904                     createBuffers(numBuffers, caps);
3905                 } catch (AWTException e) {
3906                     // shouldn't be possible
3907                 }
3908                 validatedContents = true;
3909             }
3910 
3911             // get the buffers from the peer every time since they
3912             // might have been replaced in response to a display change event
3913             updateInternalBuffers();
3914 
3915             // now validate the backbuffer
3916             if (drawVBuffer != null) {
3917                 GraphicsConfiguration gc =
3918                         getGraphicsConfiguration_NoClientCode();
3919                 int returnCode = drawVBuffer.validate(gc);
3920                 if (returnCode == VolatileImage.IMAGE_INCOMPATIBLE) {
3921                     try {
3922                         createBuffers(numBuffers, caps);
3923                     } catch (AWTException e) {
3924                         // shouldn't be possible
3925                     }
3926                     if (drawVBuffer != null) {
3927                         // backbuffers were recreated, so validate again
3928                         drawVBuffer.validate(gc);
3929                     }
3930                     validatedContents = true;
3931                 } else if (returnCode == VolatileImage.IMAGE_RESTORED) {
3932                     validatedContents = true;
3933                 }
3934             }
3935         }
3936 
3937         /**
3938          * @return whether the drawing buffer was lost since the last call to
3939          * <code>getDrawGraphics</code>
3940          */
3941         public boolean contentsLost() {
3942             if (drawVBuffer == null) {
3943                 return false;
3944             }
3945             return drawVBuffer.contentsLost();
3946         }
3947 
3948         /**
3949          * @return whether the drawing buffer was recently restored from a lost
3950          * state and reinitialized to the default background color (white)
3951          */
3952         public boolean contentsRestored() {
3953             return validatedContents;
3954         }
3955 
3956         /**
3957          * Makes the next available buffer visible by either blitting or
3958          * flipping.
3959          */
3960         public void show() {
3961             flip(caps.getFlipContents());
3962         }
3963 
3964         /**
3965          * Makes specified region of the the next available buffer visible
3966          * by either blitting or flipping.
3967          */
3968         void showSubRegion(int x1, int y1, int x2, int y2) {
3969             flipSubRegion(x1, y1, x2, y2, caps.getFlipContents());
3970         }
3971 
3972         /**
3973          * {@inheritDoc}
3974          * @since 1.6
3975          */
3976         public void dispose() {
3977             if (Component.this.bufferStrategy == this) {
3978                 Component.this.bufferStrategy = null;
3979                 if (peer != null) {
3980                     destroyBuffers();
3981                 }
3982             }
3983         }
3984 
3985     } // Inner class FlipBufferStrategy
3986 
3987     /**
3988      * Inner class for blitting offscreen surfaces to a component.
3989      *
3990      * @author Michael Martak
3991      * @since 1.4
3992      */
3993     protected class BltBufferStrategy extends BufferStrategy {
3994 
3995         /**
3996          * The buffering capabilities
3997          */
3998         protected BufferCapabilities caps; // = null
3999         /**
4000          * The back buffers
4001          */
4002         protected VolatileImage[] backBuffers; // = null
4003         /**
4004          * Whether or not the drawing buffer has been recently restored from
4005          * a lost state.
4006          */
4007         protected boolean validatedContents; // = false
4008         /**
4009          * Size of the back buffers
4010          */
4011         protected int width;
4012         protected int height;
4013 
4014         /**
4015          * Insets for the hosting Component.  The size of the back buffer
4016          * is constrained by these.
4017          */
4018         private Insets insets;
4019 
4020         /**
4021          * Creates a new blt buffer strategy around a component
4022          * @param numBuffers number of buffers to create, including the
4023          * front buffer
4024          * @param caps the capabilities of the buffers
4025          */
4026         protected BltBufferStrategy(int numBuffers, BufferCapabilities caps) {
4027             this.caps = caps;
4028             createBackBuffers(numBuffers - 1);
4029         }
4030 
4031         /**
4032          * {@inheritDoc}
4033          * @since 1.6
4034          */
4035         public void dispose() {
4036             if (backBuffers != null) {
4037                 for (int counter = backBuffers.length - 1; counter >= 0;
4038                      counter--) {
4039                     if (backBuffers[counter] != null) {
4040                         backBuffers[counter].flush();
4041                         backBuffers[counter] = null;
4042                     }
4043                 }
4044             }
4045             if (Component.this.bufferStrategy == this) {
4046                 Component.this.bufferStrategy = null;
4047             }
4048         }
4049 
4050         /**
4051          * Creates the back buffers
4052          */
4053         protected void createBackBuffers(int numBuffers) {
4054             if (numBuffers == 0) {
4055                 backBuffers = null;
4056             } else {
4057                 // save the current bounds
4058                 width = getWidth();
4059                 height = getHeight();
4060                 insets = getInsets_NoClientCode();
4061                 int iWidth = width - insets.left - insets.right;
4062                 int iHeight = height - insets.top - insets.bottom;
4063 
4064                 // It is possible for the component's width and/or height
4065                 // to be 0 here.  Force the size of the backbuffers to
4066                 // be > 0 so that creating the image won't fail.
4067                 iWidth = Math.max(1, iWidth);
4068                 iHeight = Math.max(1, iHeight);
4069                 if (backBuffers == null) {
4070                     backBuffers = new VolatileImage[numBuffers];
4071                 } else {
4072                     // flush any existing backbuffers
4073                     for (int i = 0; i < numBuffers; i++) {
4074                         if (backBuffers[i] != null) {
4075                             backBuffers[i].flush();
4076                             backBuffers[i] = null;
4077                         }
4078                     }
4079                 }
4080 
4081                 // create the backbuffers
4082                 for (int i = 0; i < numBuffers; i++) {
4083                     backBuffers[i] = createVolatileImage(iWidth, iHeight);
4084                 }
4085             }
4086         }
4087 
4088         /**
4089          * @return the buffering capabilities of this strategy
4090          */
4091         public BufferCapabilities getCapabilities() {
4092             return caps;
4093         }
4094 
4095         /**
4096          * @return the draw graphics
4097          */
4098         public Graphics getDrawGraphics() {
4099             revalidate();
4100             Image backBuffer = getBackBuffer();
4101             if (backBuffer == null) {
4102                 return getGraphics();
4103             }
4104             SunGraphics2D g = (SunGraphics2D)backBuffer.getGraphics();
4105             g.constrain(-insets.left, -insets.top,
4106                         backBuffer.getWidth(null) + insets.left,
4107                         backBuffer.getHeight(null) + insets.top);
4108             return g;
4109         }
4110 
4111         /**
4112          * @return direct access to the back buffer, as an image.
4113          * If there is no back buffer, returns null.
4114          */
4115         Image getBackBuffer() {
4116             if (backBuffers != null) {
4117                 return backBuffers[backBuffers.length - 1];
4118             } else {
4119                 return null;
4120             }
4121         }
4122 
4123         /**
4124          * Makes the next available buffer visible.
4125          */
4126         public void show() {
4127             showSubRegion(insets.left, insets.top,
4128                           width - insets.right,
4129                           height - insets.bottom);
4130         }
4131 
4132         /**
4133          * Package-private method to present a specific rectangular area
4134          * of this buffer.  This class currently shows only the entire
4135          * buffer, by calling showSubRegion() with the full dimensions of
4136          * the buffer.  Subclasses (e.g., BltSubRegionBufferStrategy
4137          * and FlipSubRegionBufferStrategy) may have region-specific show
4138          * methods that call this method with actual sub regions of the
4139          * buffer.
4140          */
4141         void showSubRegion(int x1, int y1, int x2, int y2) {
4142             if (backBuffers == null) {
4143                 return;
4144             }
4145             // Adjust location to be relative to client area.
4146             x1 -= insets.left;
4147             x2 -= insets.left;
4148             y1 -= insets.top;
4149             y2 -= insets.top;
4150             Graphics g = getGraphics_NoClientCode();
4151             if (g == null) {
4152                 // Not showing, bail
4153                 return;
4154             }
4155             try {
4156                 // First image copy is in terms of Frame's coordinates, need
4157                 // to translate to client area.
4158                 g.translate(insets.left, insets.top);
4159                 for (int i = 0; i < backBuffers.length; i++) {
4160                     g.drawImage(backBuffers[i],
4161                                 x1, y1, x2, y2,
4162                                 x1, y1, x2, y2,
4163                                 null);
4164                     g.dispose();
4165                     g = null;
4166                     g = backBuffers[i].getGraphics();
4167                 }
4168             } finally {
4169                 if (g != null) {
4170                     g.dispose();
4171                 }
4172             }
4173         }
4174 
4175         /**
4176          * Restore the drawing buffer if it has been lost
4177          */
4178         protected void revalidate() {
4179             revalidate(true);
4180         }
4181 
4182         void revalidate(boolean checkSize) {
4183             validatedContents = false;
4184 
4185             if (backBuffers == null) {
4186                 return;
4187             }
4188 
4189             if (checkSize) {
4190                 Insets insets = getInsets_NoClientCode();
4191                 if (getWidth() != width || getHeight() != height ||
4192                     !insets.equals(this.insets)) {
4193                     // component has been resized; recreate the backbuffers
4194                     createBackBuffers(backBuffers.length);
4195                     validatedContents = true;
4196                 }
4197             }
4198 
4199             // now validate the backbuffer
4200             GraphicsConfiguration gc = getGraphicsConfiguration_NoClientCode();
4201             int returnCode =
4202                 backBuffers[backBuffers.length - 1].validate(gc);
4203             if (returnCode == VolatileImage.IMAGE_INCOMPATIBLE) {
4204                 if (checkSize) {
4205                     createBackBuffers(backBuffers.length);
4206                     // backbuffers were recreated, so validate again
4207                     backBuffers[backBuffers.length - 1].validate(gc);
4208                 }
4209                 // else case means we're called from Swing on the toolkit
4210                 // thread, don't recreate buffers as that'll deadlock
4211                 // (creating VolatileImages invokes getting GraphicsConfig
4212                 // which grabs treelock).
4213                 validatedContents = true;
4214             } else if (returnCode == VolatileImage.IMAGE_RESTORED) {
4215                 validatedContents = true;
4216             }
4217         }
4218 
4219         /**
4220          * @return whether the drawing buffer was lost since the last call to
4221          * <code>getDrawGraphics</code>
4222          */
4223         public boolean contentsLost() {
4224             if (backBuffers == null) {
4225                 return false;
4226             } else {
4227                 return backBuffers[backBuffers.length - 1].contentsLost();
4228             }
4229         }
4230 
4231         /**
4232          * @return whether the drawing buffer was recently restored from a lost
4233          * state and reinitialized to the default background color (white)
4234          */
4235         public boolean contentsRestored() {
4236             return validatedContents;
4237         }
4238     } // Inner class BltBufferStrategy
4239 
4240     /**
4241      * Private class to perform sub-region flipping.
4242      */
4243     private class FlipSubRegionBufferStrategy extends FlipBufferStrategy
4244         implements SubRegionShowable
4245     {
4246 
4247         protected FlipSubRegionBufferStrategy(int numBuffers,
4248                                               BufferCapabilities caps)
4249             throws AWTException
4250         {
4251             super(numBuffers, caps);
4252         }
4253 
4254         public void show(int x1, int y1, int x2, int y2) {
4255             showSubRegion(x1, y1, x2, y2);
4256         }
4257 
4258         // This is invoked by Swing on the toolkit thread.
4259         public boolean showIfNotLost(int x1, int y1, int x2, int y2) {
4260             if (!contentsLost()) {
4261                 showSubRegion(x1, y1, x2, y2);
4262                 return !contentsLost();
4263             }
4264             return false;
4265         }
4266     }
4267 
4268     /**
4269      * Private class to perform sub-region blitting.  Swing will use
4270      * this subclass via the SubRegionShowable interface in order to
4271      * copy only the area changed during a repaint.
4272      * @see javax.swing.BufferStrategyPaintManager
4273      */
4274     private class BltSubRegionBufferStrategy extends BltBufferStrategy
4275         implements SubRegionShowable
4276     {
4277 
4278         protected BltSubRegionBufferStrategy(int numBuffers,
4279                                              BufferCapabilities caps)
4280         {
4281             super(numBuffers, caps);
4282         }
4283 
4284         public void show(int x1, int y1, int x2, int y2) {
4285             showSubRegion(x1, y1, x2, y2);
4286         }
4287 
4288         // This method is called by Swing on the toolkit thread.
4289         public boolean showIfNotLost(int x1, int y1, int x2, int y2) {
4290             if (!contentsLost()) {
4291                 showSubRegion(x1, y1, x2, y2);
4292                 return !contentsLost();
4293             }
4294             return false;
4295         }
4296     }
4297 
4298     /**
4299      * Inner class for flipping buffers on a component.  That component must
4300      * be a <code>Canvas</code> or <code>Window</code>.
4301      * @see Canvas
4302      * @see Window
4303      * @see java.awt.image.BufferStrategy
4304      * @author Michael Martak
4305      * @since 1.4
4306      */
4307     private class SingleBufferStrategy extends BufferStrategy {
4308 
4309         private BufferCapabilities caps;
4310 
4311         public SingleBufferStrategy(BufferCapabilities caps) {
4312             this.caps = caps;
4313         }
4314         public BufferCapabilities getCapabilities() {
4315             return caps;
4316         }
4317         public Graphics getDrawGraphics() {
4318             return getGraphics();
4319         }
4320         public boolean contentsLost() {
4321             return false;
4322         }
4323         public boolean contentsRestored() {
4324             return false;
4325         }
4326         public void show() {
4327             // Do nothing
4328         }
4329     } // Inner class SingleBufferStrategy
4330 
4331     /**
4332      * Sets whether or not paint messages received from the operating system
4333      * should be ignored.  This does not affect paint events generated in
4334      * software by the AWT, unless they are an immediate response to an
4335      * OS-level paint message.
4336      * <p>
4337      * This is useful, for example, if running under full-screen mode and
4338      * better performance is desired, or if page-flipping is used as the
4339      * buffer strategy.
4340      *
4341      * @since 1.4
4342      * @see #getIgnoreRepaint
4343      * @see Canvas#createBufferStrategy
4344      * @see Window#createBufferStrategy
4345      * @see java.awt.image.BufferStrategy
4346      * @see GraphicsDevice#setFullScreenWindow
4347      */
4348     public void setIgnoreRepaint(boolean ignoreRepaint) {
4349         this.ignoreRepaint = ignoreRepaint;
4350     }
4351 
4352     /**
4353      * @return whether or not paint messages received from the operating system
4354      * should be ignored.
4355      *
4356      * @since 1.4
4357      * @see #setIgnoreRepaint
4358      */
4359     public boolean getIgnoreRepaint() {
4360         return ignoreRepaint;
4361     }
4362 
4363     /**
4364      * Checks whether this component "contains" the specified point,
4365      * where <code>x</code> and <code>y</code> are defined to be
4366      * relative to the coordinate system of this component.
4367      * @param     x   the <i>x</i> coordinate of the point
4368      * @param     y   the <i>y</i> coordinate of the point
4369      * @see       #getComponentAt(int, int)
4370      * @since     JDK1.1
4371      */
4372     public boolean contains(int x, int y) {
4373         return inside(x, y);
4374     }
4375 
4376     /**
4377      * @deprecated As of JDK version 1.1,
4378      * replaced by contains(int, int).
4379      */
4380     @Deprecated
4381     public boolean inside(int x, int y) {
4382         return (x >= 0) && (x < width) && (y >= 0) && (y < height);
4383     }
4384 
4385     /**
4386      * Checks whether this component "contains" the specified point,
4387      * where the point's <i>x</i> and <i>y</i> coordinates are defined
4388      * to be relative to the coordinate system of this component.
4389      * @param     p     the point
4390      * @see       #getComponentAt(Point)
4391      * @since     JDK1.1
4392      */
4393     public boolean contains(Point p) {
4394         return contains(p.x, p.y);
4395     }
4396 
4397     /**
4398      * Determines if this component or one of its immediate
4399      * subcomponents contains the (<i>x</i>,&nbsp;<i>y</i>) location,
4400      * and if so, returns the containing component. This method only
4401      * looks one level deep. If the point (<i>x</i>,&nbsp;<i>y</i>) is
4402      * inside a subcomponent that itself has subcomponents, it does not
4403      * go looking down the subcomponent tree.
4404      * <p>
4405      * The <code>locate</code> method of <code>Component</code> simply
4406      * returns the component itself if the (<i>x</i>,&nbsp;<i>y</i>)
4407      * coordinate location is inside its bounding box, and <code>null</code>
4408      * otherwise.
4409      * @param     x   the <i>x</i> coordinate
4410      * @param     y   the <i>y</i> coordinate
4411      * @return    the component or subcomponent that contains the
4412      *                (<i>x</i>,&nbsp;<i>y</i>) location;
4413      *                <code>null</code> if the location
4414      *                is outside this component
4415      * @see       #contains(int, int)
4416      * @since     JDK1.0
4417      */
4418     public Component getComponentAt(int x, int y) {
4419         return locate(x, y);
4420     }
4421 
4422     /**
4423      * @deprecated As of JDK version 1.1,
4424      * replaced by getComponentAt(int, int).
4425      */
4426     @Deprecated
4427     public Component locate(int x, int y) {
4428         return contains(x, y) ? this : null;
4429     }
4430 
4431     /**
4432      * Returns the component or subcomponent that contains the
4433      * specified point.
4434      * @param     p   the point
4435      * @see       java.awt.Component#contains
4436      * @since     JDK1.1
4437      */
4438     public Component getComponentAt(Point p) {
4439         return getComponentAt(p.x, p.y);
4440     }
4441 
4442     /**
4443      * @deprecated As of JDK version 1.1,
4444      * replaced by <code>dispatchEvent(AWTEvent e)</code>.
4445      */
4446     @Deprecated
4447     public void deliverEvent(Event e) {
4448         postEvent(e);
4449     }
4450 
4451     /**
4452      * Dispatches an event to this component or one of its sub components.
4453      * Calls <code>processEvent</code> before returning for 1.1-style
4454      * events which have been enabled for the <code>Component</code>.
4455      * @param e the event
4456      */
4457     public final void dispatchEvent(AWTEvent e) {
4458         dispatchEventImpl(e);
4459     }
4460 
4461     void dispatchEventImpl(AWTEvent e) {
4462         int id = e.getID();
4463 
4464         // Check that this component belongs to this app-context
4465         AppContext compContext = appContext;
4466         if (compContext != null && !compContext.equals(AppContext.getAppContext())) {
4467             if (eventLog.isLoggable(Level.FINE)) {
4468                 eventLog.log(Level.FINE, "Event " + e + " is being dispatched on the wrong AppContext");
4469             }
4470         }
4471 
4472         if (eventLog.isLoggable(Level.FINEST)) {
4473             eventLog.log(Level.FINEST, "{0}", e);
4474         }
4475 
4476         /*
4477          * 0. Set timestamp and modifiers of current event.
4478          */
4479         EventQueue.setCurrentEventAndMostRecentTime(e);
4480 
4481         /*
4482          * 1. Pre-dispatchers. Do any necessary retargeting/reordering here
4483          *    before we notify AWTEventListeners.
4484          */
4485 
4486         if (e instanceof SunDropTargetEvent) {
4487             ((SunDropTargetEvent)e).dispatch();
4488             return;
4489         }
4490 
4491         if (!e.focusManagerIsDispatching) {
4492             // Invoke the private focus retargeting method which provides
4493             // lightweight Component support
4494             if (e.isPosted) {
4495                 e = KeyboardFocusManager.retargetFocusEvent(e);
4496                 e.isPosted = true;
4497             }
4498 
4499             // Now, with the event properly targeted to a lightweight
4500             // descendant if necessary, invoke the public focus retargeting
4501             // and dispatching function
4502             if (KeyboardFocusManager.getCurrentKeyboardFocusManager().
4503                 dispatchEvent(e))
4504             {
4505                 return;
4506             }
4507         }
4508         if ((e instanceof FocusEvent) && focusLog.isLoggable(Level.FINEST)) {
4509             focusLog.log(Level.FINEST, "" + e);
4510         }
4511         // MouseWheel may need to be retargeted here so that
4512         // AWTEventListener sees the event go to the correct
4513         // Component.  If the MouseWheelEvent needs to go to an ancestor,
4514         // the event is dispatched to the ancestor, and dispatching here
4515         // stops.
4516         if (id == MouseEvent.MOUSE_WHEEL &&
4517             (!eventTypeEnabled(id)) &&
4518             (peer != null && !peer.handlesWheelScrolling()) &&
4519             (dispatchMouseWheelToAncestor((MouseWheelEvent)e)))
4520         {
4521             return;
4522         }
4523 
4524         /*
4525          * 2. Allow the Toolkit to pass this to AWTEventListeners.
4526          */
4527         Toolkit toolkit = Toolkit.getDefaultToolkit();
4528         toolkit.notifyAWTEventListeners(e);
4529 
4530 
4531         /*
4532          * 3. If no one has consumed a key event, allow the
4533          *    KeyboardFocusManager to process it.
4534          */
4535         if (!e.isConsumed()) {
4536             if (e instanceof java.awt.event.KeyEvent) {
4537                 KeyboardFocusManager.getCurrentKeyboardFocusManager().
4538                     processKeyEvent(this, (KeyEvent)e);
4539                 if (e.isConsumed()) {
4540                     return;
4541                 }
4542             }
4543         }
4544 
4545         /*
4546          * 4. Allow input methods to process the event
4547          */
4548         if (areInputMethodsEnabled()) {
4549             // We need to pass on InputMethodEvents since some host
4550             // input method adapters send them through the Java
4551             // event queue instead of directly to the component,
4552             // and the input context also handles the Java composition window
4553             if(((e instanceof InputMethodEvent) && !(this instanceof CompositionArea))
4554                ||
4555                // Otherwise, we only pass on input and focus events, because
4556                // a) input methods shouldn't know about semantic or component-level events
4557                // b) passing on the events takes time
4558                // c) isConsumed() is always true for semantic events.
4559                (e instanceof InputEvent) || (e instanceof FocusEvent)) {
4560                 InputContext inputContext = getInputContext();
4561 
4562 
4563                 if (inputContext != null) {
4564                     inputContext.dispatchEvent(e);
4565                     if (e.isConsumed()) {
4566                         if ((e instanceof FocusEvent) && focusLog.isLoggable(Level.FINEST)) {
4567                             focusLog.log(Level.FINEST, "3579: Skipping " + e);
4568                         }
4569                         return;
4570                     }
4571                 }
4572             }
4573         } else {
4574             // When non-clients get focus, we need to explicitly disable the native
4575             // input method. The native input method is actually not disabled when
4576             // the active/passive/peered clients loose focus.
4577             if (id == FocusEvent.FOCUS_GAINED) {
4578                 InputContext inputContext = getInputContext();
4579                 if (inputContext != null && inputContext instanceof sun.awt.im.InputContext) {
4580                     ((sun.awt.im.InputContext)inputContext).disableNativeIM();
4581                 }
4582             }
4583         }
4584 
4585 
4586         /*
4587          * 5. Pre-process any special events before delivery
4588          */
4589         switch(id) {
4590             // Handling of the PAINT and UPDATE events is now done in the
4591             // peer's handleEvent() method so the background can be cleared
4592             // selectively for non-native components on Windows only.
4593             // - Fred.Ecks@Eng.sun.com, 5-8-98
4594 
4595           case KeyEvent.KEY_PRESSED:
4596           case KeyEvent.KEY_RELEASED:
4597               Container p = (Container)((this instanceof Container) ? this : parent);
4598               if (p != null) {
4599                   p.preProcessKeyEvent((KeyEvent)e);
4600                   if (e.isConsumed()) {
4601                         if (focusLog.isLoggable(Level.FINEST)) {
4602                             focusLog.log(Level.FINEST, "Pre-process consumed event");
4603                         }
4604                       return;
4605                   }
4606               }
4607               break;
4608 
4609           case WindowEvent.WINDOW_CLOSING:
4610               if (toolkit instanceof WindowClosingListener) {
4611                   windowClosingException = ((WindowClosingListener)
4612                                             toolkit).windowClosingNotify((WindowEvent)e);
4613                   if (checkWindowClosingException()) {
4614                       return;
4615                   }
4616               }
4617               break;
4618 
4619           default:
4620               break;
4621         }
4622 
4623         /*
4624          * 6. Deliver event for normal processing
4625          */
4626         if (newEventsOnly) {
4627             // Filtering needs to really be moved to happen at a lower
4628             // level in order to get maximum performance gain;  it is
4629             // here temporarily to ensure the API spec is honored.
4630             //
4631             if (eventEnabled(e)) {
4632                 processEvent(e);
4633             }
4634         } else if (id == MouseEvent.MOUSE_WHEEL) {
4635             // newEventsOnly will be false for a listenerless ScrollPane, but
4636             // MouseWheelEvents still need to be dispatched to it so scrolling
4637             // can be done.
4638             autoProcessMouseWheel((MouseWheelEvent)e);
4639         } else if (!(e instanceof MouseEvent && !postsOldMouseEvents())) {
4640             //
4641             // backward compatibility
4642             //
4643             Event olde = e.convertToOld();
4644             if (olde != null) {
4645                 int key = olde.key;
4646                 int modifiers = olde.modifiers;
4647 
4648                 postEvent(olde);
4649                 if (olde.isConsumed()) {
4650                     e.consume();
4651                 }
4652                 // if target changed key or modifier values, copy them
4653                 // back to original event
4654                 //
4655                 switch(olde.id) {
4656                   case Event.KEY_PRESS:
4657                   case Event.KEY_RELEASE:
4658                   case Event.KEY_ACTION:
4659                   case Event.KEY_ACTION_RELEASE:
4660                       if (olde.key != key) {
4661                           ((KeyEvent)e).setKeyChar(olde.getKeyEventChar());
4662                       }
4663                       if (olde.modifiers != modifiers) {
4664                           ((KeyEvent)e).setModifiers(olde.modifiers);
4665                       }
4666                       break;
4667                   default:
4668                       break;
4669                 }
4670             }
4671         }
4672 
4673         /*
4674          * 8. Special handling for 4061116 : Hook for browser to close modal
4675          *    dialogs.
4676          */
4677         if (id == WindowEvent.WINDOW_CLOSING && !e.isConsumed()) {
4678             if (toolkit instanceof WindowClosingListener) {
4679                 windowClosingException =
4680                     ((WindowClosingListener)toolkit).
4681                     windowClosingDelivered((WindowEvent)e);
4682                 if (checkWindowClosingException()) {
4683                     return;
4684                 }
4685             }
4686         }
4687 
4688         /*
4689          * 9. Allow the peer to process the event.
4690          * Except KeyEvents, they will be processed by peer after
4691          * all KeyEventPostProcessors
4692          * (see DefaultKeyboardFocusManager.dispatchKeyEvent())
4693          */
4694         if (!(e instanceof KeyEvent)) {
4695             ComponentPeer tpeer = peer;
4696             if (e instanceof FocusEvent && (tpeer == null || tpeer instanceof LightweightPeer)) {
4697                 // if focus owner is lightweight then its native container
4698                 // processes event
4699                 Component source = (Component)e.getSource();
4700                 if (source != null) {
4701                     Container target = source.getNativeContainer();
4702                     if (target != null) {
4703                         tpeer = target.getPeer();
4704                     }
4705                 }
4706             }
4707             if (tpeer != null) {
4708                 tpeer.handleEvent(e);
4709             }
4710         }
4711     } // dispatchEventImpl()
4712 
4713     /*
4714      * If newEventsOnly is false, method is called so that ScrollPane can
4715      * override it and handle common-case mouse wheel scrolling.  NOP
4716      * for Component.
4717      */
4718     void autoProcessMouseWheel(MouseWheelEvent e) {}
4719 
4720     /*
4721      * Dispatch given MouseWheelEvent to the first ancestor for which
4722      * MouseWheelEvents are enabled.
4723      *
4724      * Returns whether or not event was dispatched to an ancestor
4725      */
4726     boolean dispatchMouseWheelToAncestor(MouseWheelEvent e) {
4727         int newX, newY;
4728         newX = e.getX() + getX(); // Coordinates take into account at least
4729         newY = e.getY() + getY(); // the cursor's position relative to this
4730                                   // Component (e.getX()), and this Component's
4731                                   // position relative to its parent.
4732         MouseWheelEvent newMWE;
4733 
4734         if (eventLog.isLoggable(Level.FINEST)) {
4735             eventLog.log(Level.FINEST, "dispatchMouseWheelToAncestor");
4736             eventLog.log(Level.FINEST, "orig event src is of " + e.getSource().getClass());
4737         }
4738 
4739         /* parent field for Window refers to the owning Window.
4740          * MouseWheelEvents should NOT be propagated into owning Windows
4741          */
4742         synchronized (getTreeLock()) {
4743             Container anc = getParent();
4744             while (anc != null && !anc.eventEnabled(e)) {
4745                 // fix coordinates to be relative to new event source
4746                 newX += anc.getX();
4747                 newY += anc.getY();
4748 
4749                 if (!(anc instanceof Window)) {
4750                     anc = anc.getParent();
4751                 }
4752                 else {
4753                     break;
4754                 }
4755             }
4756 
4757             if (eventLog.isLoggable(Level.FINEST)) {
4758                 eventLog.log(Level.FINEST, "new event src is " + anc.getClass());
4759             }
4760 
4761             if (anc != null && anc.eventEnabled(e)) {
4762                 // Change event to be from new source, with new x,y
4763                 // For now, just create a new event - yucky
4764 
4765                 newMWE = new MouseWheelEvent(anc, // new source
4766                                              e.getID(),
4767                                              e.getWhen(),
4768                                              e.getModifiers(),
4769                                              newX, // x relative to new source
4770                                              newY, // y relative to new source
4771                                              e.getXOnScreen(),
4772                                              e.getYOnScreen(),
4773                                              e.getClickCount(),
4774                                              e.isPopupTrigger(),
4775                                              e.getScrollType(),
4776                                              e.getScrollAmount(),
4777                                              e.getWheelRotation(),
4778                                              e.getPreciseWheelRotation());
4779                 ((AWTEvent)e).copyPrivateDataInto(newMWE);
4780                 // When dispatching a wheel event to
4781                 // ancestor, there is no need trying to find descendant
4782                 // lightweights to dispatch event to.
4783                 // If we dispatch the event to toplevel ancestor,
4784                 // this could encolse the loop: 6480024.
4785                 anc.dispatchEventToSelf(newMWE);
4786             }
4787         }
4788         return true;
4789     }
4790 
4791     boolean checkWindowClosingException() {
4792         if (windowClosingException != null) {
4793             if (this instanceof Dialog) {
4794                 ((Dialog)this).interruptBlocking();
4795             } else {
4796                 windowClosingException.fillInStackTrace();
4797                 windowClosingException.printStackTrace();
4798                 windowClosingException = null;
4799             }
4800             return true;
4801         }
4802         return false;
4803     }
4804 
4805     boolean areInputMethodsEnabled() {
4806         // in 1.2, we assume input method support is required for all
4807         // components that handle key events, but components can turn off
4808         // input methods by calling enableInputMethods(false).
4809         return ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) &&
4810             ((eventMask & AWTEvent.KEY_EVENT_MASK) != 0 || keyListener != null);
4811     }
4812 
4813     // REMIND: remove when filtering is handled at lower level
4814     boolean eventEnabled(AWTEvent e) {
4815         return eventTypeEnabled(e.id);
4816     }
4817 
4818     boolean eventTypeEnabled(int type) {
4819         switch(type) {
4820           case ComponentEvent.COMPONENT_MOVED:
4821           case ComponentEvent.COMPONENT_RESIZED:
4822           case ComponentEvent.COMPONENT_SHOWN:
4823           case ComponentEvent.COMPONENT_HIDDEN:
4824               if ((eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 ||
4825                   componentListener != null) {
4826                   return true;
4827               }
4828               break;
4829           case FocusEvent.FOCUS_GAINED:
4830           case FocusEvent.FOCUS_LOST:
4831               if ((eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0 ||
4832                   focusListener != null) {
4833                   return true;
4834               }
4835               break;
4836           case KeyEvent.KEY_PRESSED:
4837           case KeyEvent.KEY_RELEASED:
4838           case KeyEvent.KEY_TYPED:
4839               if ((eventMask & AWTEvent.KEY_EVENT_MASK) != 0 ||
4840                   keyListener != null) {
4841                   return true;
4842               }
4843               break;
4844           case MouseEvent.MOUSE_PRESSED:
4845           case MouseEvent.MOUSE_RELEASED:
4846           case MouseEvent.MOUSE_ENTERED:
4847           case MouseEvent.MOUSE_EXITED:
4848           case MouseEvent.MOUSE_CLICKED:
4849               if ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0 ||
4850                   mouseListener != null) {
4851                   return true;
4852               }
4853               break;
4854           case MouseEvent.MOUSE_MOVED:
4855           case MouseEvent.MOUSE_DRAGGED:
4856               if ((eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0 ||
4857                   mouseMotionListener != null) {
4858                   return true;
4859               }
4860               break;
4861           case MouseEvent.MOUSE_WHEEL:
4862               if ((eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0 ||
4863                   mouseWheelListener != null) {
4864                   return true;
4865               }
4866               break;
4867           case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
4868           case InputMethodEvent.CARET_POSITION_CHANGED:
4869               if ((eventMask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0 ||
4870                   inputMethodListener != null) {
4871                   return true;
4872               }
4873               break;
4874           case HierarchyEvent.HIERARCHY_CHANGED:
4875               if ((eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 ||
4876                   hierarchyListener != null) {
4877                   return true;
4878               }
4879               break;
4880           case HierarchyEvent.ANCESTOR_MOVED:
4881           case HierarchyEvent.ANCESTOR_RESIZED:
4882               if ((eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 ||
4883                   hierarchyBoundsListener != null) {
4884                   return true;
4885               }
4886               break;
4887           case ActionEvent.ACTION_PERFORMED:
4888               if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0) {
4889                   return true;
4890               }
4891               break;
4892           case TextEvent.TEXT_VALUE_CHANGED:
4893               if ((eventMask & AWTEvent.TEXT_EVENT_MASK) != 0) {
4894                   return true;
4895               }
4896               break;
4897           case ItemEvent.ITEM_STATE_CHANGED:
4898               if ((eventMask & AWTEvent.ITEM_EVENT_MASK) != 0) {
4899                   return true;
4900               }
4901               break;
4902           case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED:
4903               if ((eventMask & AWTEvent.ADJUSTMENT_EVENT_MASK) != 0) {
4904                   return true;
4905               }
4906               break;
4907           default:
4908               break;
4909         }
4910         //
4911         // Always pass on events defined by external programs.
4912         //
4913         if (type > AWTEvent.RESERVED_ID_MAX) {
4914             return true;
4915         }
4916         return false;
4917     }
4918 
4919     /**
4920      * @deprecated As of JDK version 1.1,
4921      * replaced by dispatchEvent(AWTEvent).
4922      */
4923     @Deprecated
4924     public boolean postEvent(Event e) {
4925         ComponentPeer peer = this.peer;
4926 
4927         if (handleEvent(e)) {
4928             e.consume();
4929             return true;
4930         }
4931 
4932         Component parent = this.parent;
4933         int eventx = e.x;
4934         int eventy = e.y;
4935         if (parent != null) {
4936             e.translate(x, y);
4937             if (parent.postEvent(e)) {
4938                 e.consume();
4939                 return true;
4940             }
4941             // restore coords
4942             e.x = eventx;
4943             e.y = eventy;
4944         }
4945         return false;
4946     }
4947 
4948     // Event source interfaces
4949 
4950     /**
4951      * Adds the specified component listener to receive component events from
4952      * this component.
4953      * If listener <code>l</code> is <code>null</code>,
4954      * no exception is thrown and no action is performed.
4955      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
4956      * >AWT Threading Issues</a> for details on AWT's threading model.
4957      *
4958      * @param    l   the component listener
4959      * @see      java.awt.event.ComponentEvent
4960      * @see      java.awt.event.ComponentListener
4961      * @see      #removeComponentListener
4962      * @see      #getComponentListeners
4963      * @since    JDK1.1
4964      */
4965     public synchronized void addComponentListener(ComponentListener l) {
4966         if (l == null) {
4967             return;
4968         }
4969         componentListener = AWTEventMulticaster.add(componentListener, l);
4970         newEventsOnly = true;
4971     }
4972 
4973     /**
4974      * Removes the specified component listener so that it no longer
4975      * receives component events from this component. This method performs
4976      * no function, nor does it throw an exception, if the listener
4977      * specified by the argument was not previously added to this component.
4978      * If listener <code>l</code> is <code>null</code>,
4979      * no exception is thrown and no action is performed.
4980      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
4981      * >AWT Threading Issues</a> for details on AWT's threading model.
4982      * @param    l   the component listener
4983      * @see      java.awt.event.ComponentEvent
4984      * @see      java.awt.event.ComponentListener
4985      * @see      #addComponentListener
4986      * @see      #getComponentListeners
4987      * @since    JDK1.1
4988      */
4989     public synchronized void removeComponentListener(ComponentListener l) {
4990         if (l == null) {
4991             return;
4992         }
4993         componentListener = AWTEventMulticaster.remove(componentListener, l);
4994     }
4995 
4996     /**
4997      * Returns an array of all the component listeners
4998      * registered on this component.
4999      *
5000      * @return all of this comonent's <code>ComponentListener</code>s
5001      *         or an empty array if no component
5002      *         listeners are currently registered
5003      *
5004      * @see #addComponentListener
5005      * @see #removeComponentListener
5006      * @since 1.4
5007      */
5008     public synchronized ComponentListener[] getComponentListeners() {
5009         return (ComponentListener[]) (getListeners(ComponentListener.class));
5010     }
5011 
5012     /**
5013      * Adds the specified focus listener to receive focus events from
5014      * this component when this component gains input focus.
5015      * If listener <code>l</code> is <code>null</code>,
5016      * no exception is thrown and no action is performed.
5017      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5018      * >AWT Threading Issues</a> for details on AWT's threading model.
5019      *
5020      * @param    l   the focus listener
5021      * @see      java.awt.event.FocusEvent
5022      * @see      java.awt.event.FocusListener
5023      * @see      #removeFocusListener
5024      * @see      #getFocusListeners
5025      * @since    JDK1.1
5026      */
5027     public synchronized void addFocusListener(FocusListener l) {
5028         if (l == null) {
5029             return;
5030         }
5031         focusListener = AWTEventMulticaster.add(focusListener, l);
5032         newEventsOnly = true;
5033 
5034         // if this is a lightweight component, enable focus events
5035         // in the native container.
5036         if (peer instanceof LightweightPeer) {
5037             parent.proxyEnableEvents(AWTEvent.FOCUS_EVENT_MASK);
5038         }
5039     }
5040 
5041     /**
5042      * Removes the specified focus listener so that it no longer
5043      * receives focus events from this component. This method performs
5044      * no function, nor does it throw an exception, if the listener
5045      * specified by the argument was not previously added to this component.
5046      * If listener <code>l</code> is <code>null</code>,
5047      * no exception is thrown and no action is performed.
5048      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5049      * >AWT Threading Issues</a> for details on AWT's threading model.
5050      *
5051      * @param    l   the focus listener
5052      * @see      java.awt.event.FocusEvent
5053      * @see      java.awt.event.FocusListener
5054      * @see      #addFocusListener
5055      * @see      #getFocusListeners
5056      * @since    JDK1.1
5057      */
5058     public synchronized void removeFocusListener(FocusListener l) {
5059         if (l == null) {
5060             return;
5061         }
5062         focusListener = AWTEventMulticaster.remove(focusListener, l);
5063     }
5064 
5065     /**
5066      * Returns an array of all the focus listeners
5067      * registered on this component.
5068      *
5069      * @return all of this component's <code>FocusListener</code>s
5070      *         or an empty array if no component
5071      *         listeners are currently registered
5072      *
5073      * @see #addFocusListener
5074      * @see #removeFocusListener
5075      * @since 1.4
5076      */
5077     public synchronized FocusListener[] getFocusListeners() {
5078         return (FocusListener[]) (getListeners(FocusListener.class));
5079     }
5080 
5081     /**
5082      * Adds the specified hierarchy listener to receive hierarchy changed
5083      * events from this component when the hierarchy to which this container
5084      * belongs changes.
5085      * If listener <code>l</code> is <code>null</code>,
5086      * no exception is thrown and no action is performed.
5087      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5088      * >AWT Threading Issues</a> for details on AWT's threading model.
5089      *
5090      * @param    l   the hierarchy listener
5091      * @see      java.awt.event.HierarchyEvent
5092      * @see      java.awt.event.HierarchyListener
5093      * @see      #removeHierarchyListener
5094      * @see      #getHierarchyListeners
5095      * @since    1.3
5096      */
5097     public void addHierarchyListener(HierarchyListener l) {
5098         if (l == null) {
5099             return;
5100         }
5101         boolean notifyAncestors;
5102         synchronized (this) {
5103             notifyAncestors =
5104                 (hierarchyListener == null &&
5105                  (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) == 0);
5106             hierarchyListener = AWTEventMulticaster.add(hierarchyListener, l);
5107             notifyAncestors = (notifyAncestors && hierarchyListener != null);
5108             newEventsOnly = true;
5109         }
5110         if (notifyAncestors) {
5111             synchronized (getTreeLock()) {
5112                 adjustListeningChildrenOnParent(AWTEvent.HIERARCHY_EVENT_MASK,
5113                                                 1);
5114             }
5115         }
5116     }
5117 
5118     /**
5119      * Removes the specified hierarchy listener so that it no longer
5120      * receives hierarchy changed events from this component. This method
5121      * performs no function, nor does it throw an exception, if the listener
5122      * specified by the argument was not previously added to this component.
5123      * If listener <code>l</code> is <code>null</code>,
5124      * no exception is thrown and no action is performed.
5125      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5126      * >AWT Threading Issues</a> for details on AWT's threading model.
5127      *
5128      * @param    l   the hierarchy listener
5129      * @see      java.awt.event.HierarchyEvent
5130      * @see      java.awt.event.HierarchyListener
5131      * @see      #addHierarchyListener
5132      * @see      #getHierarchyListeners
5133      * @since    1.3
5134      */
5135     public void removeHierarchyListener(HierarchyListener l) {
5136         if (l == null) {
5137             return;
5138         }
5139         boolean notifyAncestors;
5140         synchronized (this) {
5141             notifyAncestors =
5142                 (hierarchyListener != null &&
5143                  (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) == 0);
5144             hierarchyListener =
5145                 AWTEventMulticaster.remove(hierarchyListener, l);
5146             notifyAncestors = (notifyAncestors && hierarchyListener == null);
5147         }
5148         if (notifyAncestors) {
5149             synchronized (getTreeLock()) {
5150                 adjustListeningChildrenOnParent(AWTEvent.HIERARCHY_EVENT_MASK,
5151                                                 -1);
5152             }
5153         }
5154     }
5155 
5156     /**
5157      * Returns an array of all the hierarchy listeners
5158      * registered on this component.
5159      *
5160      * @return all of this component's <code>HierarchyListener</code>s
5161      *         or an empty array if no hierarchy
5162      *         listeners are currently registered
5163      *
5164      * @see      #addHierarchyListener
5165      * @see      #removeHierarchyListener
5166      * @since    1.4
5167      */
5168     public synchronized HierarchyListener[] getHierarchyListeners() {
5169         return (HierarchyListener[])(getListeners(HierarchyListener.class));
5170     }
5171 
5172     /**
5173      * Adds the specified hierarchy bounds listener to receive hierarchy
5174      * bounds events from this component when the hierarchy to which this
5175      * container belongs changes.
5176      * If listener <code>l</code> is <code>null</code>,
5177      * no exception is thrown and no action is performed.
5178      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5179      * >AWT Threading Issues</a> for details on AWT's threading model.
5180      *
5181      * @param    l   the hierarchy bounds listener
5182      * @see      java.awt.event.HierarchyEvent
5183      * @see      java.awt.event.HierarchyBoundsListener
5184      * @see      #removeHierarchyBoundsListener
5185      * @see      #getHierarchyBoundsListeners
5186      * @since    1.3
5187      */
5188     public void addHierarchyBoundsListener(HierarchyBoundsListener l) {
5189         if (l == null) {
5190             return;
5191         }
5192         boolean notifyAncestors;
5193         synchronized (this) {
5194             notifyAncestors =
5195                 (hierarchyBoundsListener == null &&
5196                  (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) == 0);
5197             hierarchyBoundsListener =
5198                 AWTEventMulticaster.add(hierarchyBoundsListener, l);
5199             notifyAncestors = (notifyAncestors &&
5200                                hierarchyBoundsListener != null);
5201             newEventsOnly = true;
5202         }
5203         if (notifyAncestors) {
5204             synchronized (getTreeLock()) {
5205                 adjustListeningChildrenOnParent(
5206                                                 AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK, 1);
5207             }
5208         }
5209     }
5210 
5211     /**
5212      * Removes the specified hierarchy bounds listener so that it no longer
5213      * receives hierarchy bounds events from this component. This method
5214      * performs no function, nor does it throw an exception, if the listener
5215      * specified by the argument was not previously added to this component.
5216      * If listener <code>l</code> is <code>null</code>,
5217      * no exception is thrown and no action is performed.
5218      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5219      * >AWT Threading Issues</a> for details on AWT's threading model.
5220      *
5221      * @param    l   the hierarchy bounds listener
5222      * @see      java.awt.event.HierarchyEvent
5223      * @see      java.awt.event.HierarchyBoundsListener
5224      * @see      #addHierarchyBoundsListener
5225      * @see      #getHierarchyBoundsListeners
5226      * @since    1.3
5227      */
5228     public void removeHierarchyBoundsListener(HierarchyBoundsListener l) {
5229         if (l == null) {
5230             return;
5231         }
5232         boolean notifyAncestors;
5233         synchronized (this) {
5234             notifyAncestors =
5235                 (hierarchyBoundsListener != null &&
5236                  (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) == 0);
5237             hierarchyBoundsListener =
5238                 AWTEventMulticaster.remove(hierarchyBoundsListener, l);
5239             notifyAncestors = (notifyAncestors &&
5240                                hierarchyBoundsListener == null);
5241         }
5242         if (notifyAncestors) {
5243             synchronized (getTreeLock()) {
5244                 adjustListeningChildrenOnParent(
5245                                                 AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK, -1);
5246             }
5247         }
5248     }
5249 
5250     // Should only be called while holding the tree lock
5251     int numListening(long mask) {
5252         // One mask or the other, but not neither or both.
5253         if (eventLog.isLoggable(Level.FINE)) {
5254             if ((mask != AWTEvent.HIERARCHY_EVENT_MASK) &&
5255                 (mask != AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK))
5256             {
5257                 eventLog.log(Level.FINE, "Assertion failed");
5258             }
5259         }
5260         if ((mask == AWTEvent.HIERARCHY_EVENT_MASK &&
5261              (hierarchyListener != null ||
5262               (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0)) ||
5263             (mask == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK &&
5264              (hierarchyBoundsListener != null ||
5265               (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0))) {
5266             return 1;
5267         } else {
5268             return 0;
5269         }
5270     }
5271 
5272     // Should only be called while holding tree lock
5273     int countHierarchyMembers() {
5274         return 1;
5275     }
5276     // Should only be called while holding the tree lock
5277     int createHierarchyEvents(int id, Component changed,
5278                               Container changedParent, long changeFlags,
5279                               boolean enabledOnToolkit) {
5280         switch (id) {
5281           case HierarchyEvent.HIERARCHY_CHANGED:
5282               if (hierarchyListener != null ||
5283                   (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 ||
5284                   enabledOnToolkit) {
5285                   HierarchyEvent e = new HierarchyEvent(this, id, changed,
5286                                                         changedParent,
5287                                                         changeFlags);
5288                   dispatchEvent(e);
5289                   return 1;
5290               }
5291               break;
5292           case HierarchyEvent.ANCESTOR_MOVED:
5293           case HierarchyEvent.ANCESTOR_RESIZED:
5294               if (eventLog.isLoggable(Level.FINE)) {
5295                   if (changeFlags != 0) {
5296                       eventLog.log(Level.FINE, "Assertion (changeFlags == 0) failed");
5297                   }
5298               }
5299               if (hierarchyBoundsListener != null ||
5300                   (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 ||
5301                   enabledOnToolkit) {
5302                   HierarchyEvent e = new HierarchyEvent(this, id, changed,
5303                                                         changedParent);
5304                   dispatchEvent(e);
5305                   return 1;
5306               }
5307               break;
5308           default:
5309               // assert false
5310               if (eventLog.isLoggable(Level.FINE)) {
5311                   eventLog.log(Level.FINE, "This code must never be reached");
5312               }
5313               break;
5314         }
5315         return 0;
5316     }
5317 
5318     /**
5319      * Returns an array of all the hierarchy bounds listeners
5320      * registered on this component.
5321      *
5322      * @return all of this component's <code>HierarchyBoundsListener</code>s
5323      *         or an empty array if no hierarchy bounds
5324      *         listeners are currently registered
5325      *
5326      * @see      #addHierarchyBoundsListener
5327      * @see      #removeHierarchyBoundsListener
5328      * @since    1.4
5329      */
5330     public synchronized HierarchyBoundsListener[] getHierarchyBoundsListeners() {
5331         return (HierarchyBoundsListener[])
5332             (getListeners(HierarchyBoundsListener.class));
5333     }
5334 
5335     /*
5336      * Should only be called while holding the tree lock.
5337      * It's added only for overriding in java.awt.Window
5338      * because parent in Window is owner.
5339      */
5340     void adjustListeningChildrenOnParent(long mask, int num) {
5341         if (parent != null) {
5342             parent.adjustListeningChildren(mask, num);
5343         }
5344     }
5345 
5346     /**
5347      * Adds the specified key listener to receive key events from
5348      * this component.
5349      * If l is null, no exception is thrown and no action is performed.
5350      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5351      * >AWT Threading Issues</a> for details on AWT's threading model.
5352      *
5353      * @param    l   the key listener.
5354      * @see      java.awt.event.KeyEvent
5355      * @see      java.awt.event.KeyListener
5356      * @see      #removeKeyListener
5357      * @see      #getKeyListeners
5358      * @since    JDK1.1
5359      */
5360     public synchronized void addKeyListener(KeyListener l) {
5361         if (l == null) {
5362             return;
5363         }
5364         keyListener = AWTEventMulticaster.add(keyListener, l);
5365         newEventsOnly = true;
5366 
5367         // if this is a lightweight component, enable key events
5368         // in the native container.
5369         if (peer instanceof LightweightPeer) {
5370             parent.proxyEnableEvents(AWTEvent.KEY_EVENT_MASK);
5371         }
5372     }
5373 
5374     /**
5375      * Removes the specified key listener so that it no longer
5376      * receives key events from this component. This method performs
5377      * no function, nor does it throw an exception, if the listener
5378      * specified by the argument was not previously added to this component.
5379      * If listener <code>l</code> is <code>null</code>,
5380      * no exception is thrown and no action is performed.
5381      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5382      * >AWT Threading Issues</a> for details on AWT's threading model.
5383      *
5384      * @param    l   the key listener
5385      * @see      java.awt.event.KeyEvent
5386      * @see      java.awt.event.KeyListener
5387      * @see      #addKeyListener
5388      * @see      #getKeyListeners
5389      * @since    JDK1.1
5390      */
5391     public synchronized void removeKeyListener(KeyListener l) {
5392         if (l == null) {
5393             return;
5394         }
5395         keyListener = AWTEventMulticaster.remove(keyListener, l);
5396     }
5397 
5398     /**
5399      * Returns an array of all the key listeners
5400      * registered on this component.
5401      *
5402      * @return all of this component's <code>KeyListener</code>s
5403      *         or an empty array if no key
5404      *         listeners are currently registered
5405      *
5406      * @see      #addKeyListener
5407      * @see      #removeKeyListener
5408      * @since    1.4
5409      */
5410     public synchronized KeyListener[] getKeyListeners() {
5411         return (KeyListener[]) (getListeners(KeyListener.class));
5412     }
5413 
5414     /**
5415      * Adds the specified mouse listener to receive mouse events from
5416      * this component.
5417      * If listener <code>l</code> is <code>null</code>,
5418      * no exception is thrown and no action is performed.
5419      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5420      * >AWT Threading Issues</a> for details on AWT's threading model.
5421      *
5422      * @param    l   the mouse listener
5423      * @see      java.awt.event.MouseEvent
5424      * @see      java.awt.event.MouseListener
5425      * @see      #removeMouseListener
5426      * @see      #getMouseListeners
5427      * @since    JDK1.1
5428      */
5429     public synchronized void addMouseListener(MouseListener l) {
5430         if (l == null) {
5431             return;
5432         }
5433         mouseListener = AWTEventMulticaster.add(mouseListener,l);
5434         newEventsOnly = true;
5435 
5436         // if this is a lightweight component, enable mouse events
5437         // in the native container.
5438         if (peer instanceof LightweightPeer) {
5439             parent.proxyEnableEvents(AWTEvent.MOUSE_EVENT_MASK);
5440         }
5441     }
5442 
5443     /**
5444      * Removes the specified mouse listener so that it no longer
5445      * receives mouse events from this component. This method performs
5446      * no function, nor does it throw an exception, if the listener
5447      * specified by the argument was not previously added to this component.
5448      * If listener <code>l</code> is <code>null</code>,
5449      * no exception is thrown and no action is performed.
5450      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5451      * >AWT Threading Issues</a> for details on AWT's threading model.
5452      *
5453      * @param    l   the mouse listener
5454      * @see      java.awt.event.MouseEvent
5455      * @see      java.awt.event.MouseListener
5456      * @see      #addMouseListener
5457      * @see      #getMouseListeners
5458      * @since    JDK1.1
5459      */
5460     public synchronized void removeMouseListener(MouseListener l) {
5461         if (l == null) {
5462             return;
5463         }
5464         mouseListener = AWTEventMulticaster.remove(mouseListener, l);
5465     }
5466 
5467     /**
5468      * Returns an array of all the mouse listeners
5469      * registered on this component.
5470      *
5471      * @return all of this component's <code>MouseListener</code>s
5472      *         or an empty array if no mouse
5473      *         listeners are currently registered
5474      *
5475      * @see      #addMouseListener
5476      * @see      #removeMouseListener
5477      * @since    1.4
5478      */
5479     public synchronized MouseListener[] getMouseListeners() {
5480         return (MouseListener[]) (getListeners(MouseListener.class));
5481     }
5482 
5483     /**
5484      * Adds the specified mouse motion listener to receive mouse motion
5485      * events from this component.
5486      * If listener <code>l</code> is <code>null</code>,
5487      * no exception is thrown and no action is performed.
5488      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5489      * >AWT Threading Issues</a> for details on AWT's threading model.
5490      *
5491      * @param    l   the mouse motion listener
5492      * @see      java.awt.event.MouseEvent
5493      * @see      java.awt.event.MouseMotionListener
5494      * @see      #removeMouseMotionListener
5495      * @see      #getMouseMotionListeners
5496      * @since    JDK1.1
5497      */
5498     public synchronized void addMouseMotionListener(MouseMotionListener l) {
5499         if (l == null) {
5500             return;
5501         }
5502         mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener,l);
5503         newEventsOnly = true;
5504 
5505         // if this is a lightweight component, enable mouse events
5506         // in the native container.
5507         if (peer instanceof LightweightPeer) {
5508             parent.proxyEnableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
5509         }
5510     }
5511 
5512     /**
5513      * Removes the specified mouse motion listener so that it no longer
5514      * receives mouse motion events from this component. This method performs
5515      * no function, nor does it throw an exception, if the listener
5516      * specified by the argument was not previously added to this component.
5517      * If listener <code>l</code> is <code>null</code>,
5518      * no exception is thrown and no action is performed.
5519      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5520      * >AWT Threading Issues</a> for details on AWT's threading model.
5521      *
5522      * @param    l   the mouse motion listener
5523      * @see      java.awt.event.MouseEvent
5524      * @see      java.awt.event.MouseMotionListener
5525      * @see      #addMouseMotionListener
5526      * @see      #getMouseMotionListeners
5527      * @since    JDK1.1
5528      */
5529     public synchronized void removeMouseMotionListener(MouseMotionListener l) {
5530         if (l == null) {
5531             return;
5532         }
5533         mouseMotionListener = AWTEventMulticaster.remove(mouseMotionListener, l);
5534     }
5535 
5536     /**
5537      * Returns an array of all the mouse motion listeners
5538      * registered on this component.
5539      *
5540      * @return all of this component's <code>MouseMotionListener</code>s
5541      *         or an empty array if no mouse motion
5542      *         listeners are currently registered
5543      *
5544      * @see      #addMouseMotionListener
5545      * @see      #removeMouseMotionListener
5546      * @since    1.4
5547      */
5548     public synchronized MouseMotionListener[] getMouseMotionListeners() {
5549         return (MouseMotionListener[]) (getListeners(MouseMotionListener.class));
5550     }
5551 
5552     /**
5553      * Adds the specified mouse wheel listener to receive mouse wheel events
5554      * from this component.  Containers also receive mouse wheel events from
5555      * sub-components.
5556      * <p>
5557      * For information on how mouse wheel events are dispatched, see
5558      * the class description for {@link MouseWheelEvent}.
5559      * <p>
5560      * If l is <code>null</code>, no exception is thrown and no
5561      * action is performed.
5562      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5563      * >AWT Threading Issues</a> for details on AWT's threading model.
5564      *
5565      * @param    l   the mouse wheel listener
5566      * @see      java.awt.event.MouseWheelEvent
5567      * @see      java.awt.event.MouseWheelListener
5568      * @see      #removeMouseWheelListener
5569      * @see      #getMouseWheelListeners
5570      * @since    1.4
5571      */
5572     public synchronized void addMouseWheelListener(MouseWheelListener l) {
5573         if (l == null) {
5574             return;
5575         }
5576         mouseWheelListener = AWTEventMulticaster.add(mouseWheelListener,l);
5577         newEventsOnly = true;
5578 
5579         // if this is a lightweight component, enable mouse events
5580         // in the native container.
5581         if (peer instanceof LightweightPeer) {
5582             parent.proxyEnableEvents(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
5583         }
5584     }
5585 
5586     /**
5587      * Removes the specified mouse wheel listener so that it no longer
5588      * receives mouse wheel events from this component. This method performs
5589      * no function, nor does it throw an exception, if the listener
5590      * specified by the argument was not previously added to this component.
5591      * If l is null, no exception is thrown and no action is performed.
5592      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5593      * >AWT Threading Issues</a> for details on AWT's threading model.
5594      *
5595      * @param    l   the mouse wheel listener.
5596      * @see      java.awt.event.MouseWheelEvent
5597      * @see      java.awt.event.MouseWheelListener
5598      * @see      #addMouseWheelListener
5599      * @see      #getMouseWheelListeners
5600      * @since    1.4
5601      */
5602     public synchronized void removeMouseWheelListener(MouseWheelListener l) {
5603         if (l == null) {
5604             return;
5605         }
5606         mouseWheelListener = AWTEventMulticaster.remove(mouseWheelListener, l);
5607     }
5608 
5609     /**
5610      * Returns an array of all the mouse wheel listeners
5611      * registered on this component.
5612      *
5613      * @return all of this component's <code>MouseWheelListener</code>s
5614      *         or an empty array if no mouse wheel
5615      *         listeners are currently registered
5616      *
5617      * @see      #addMouseWheelListener
5618      * @see      #removeMouseWheelListener
5619      * @since    1.4
5620      */
5621     public synchronized MouseWheelListener[] getMouseWheelListeners() {
5622         return (MouseWheelListener[]) (getListeners(MouseWheelListener.class));
5623     }
5624 
5625     /**
5626      * Adds the specified input method listener to receive
5627      * input method events from this component. A component will
5628      * only receive input method events from input methods
5629      * if it also overrides <code>getInputMethodRequests</code> to return an
5630      * <code>InputMethodRequests</code> instance.
5631      * If listener <code>l</code> is <code>null</code>,
5632      * no exception is thrown and no action is performed.
5633      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5634      * >AWT Threading Issues</a> for details on AWT's threading model.
5635      *
5636      * @param    l   the input method listener
5637      * @see      java.awt.event.InputMethodEvent
5638      * @see      java.awt.event.InputMethodListener
5639      * @see      #removeInputMethodListener
5640      * @see      #getInputMethodListeners
5641      * @see      #getInputMethodRequests
5642      * @since    1.2
5643      */
5644     public synchronized void addInputMethodListener(InputMethodListener l) {
5645         if (l == null) {
5646             return;
5647         }
5648         inputMethodListener = AWTEventMulticaster.add(inputMethodListener, l);
5649         newEventsOnly = true;
5650     }
5651 
5652     /**
5653      * Removes the specified input method listener so that it no longer
5654      * receives input method events from this component. This method performs
5655      * no function, nor does it throw an exception, if the listener
5656      * specified by the argument was not previously added to this component.
5657      * If listener <code>l</code> is <code>null</code>,
5658      * no exception is thrown and no action is performed.
5659      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5660      * >AWT Threading Issues</a> for details on AWT's threading model.
5661      *
5662      * @param    l   the input method listener
5663      * @see      java.awt.event.InputMethodEvent
5664      * @see      java.awt.event.InputMethodListener
5665      * @see      #addInputMethodListener
5666      * @see      #getInputMethodListeners
5667      * @since    1.2
5668      */
5669     public synchronized void removeInputMethodListener(InputMethodListener l) {
5670         if (l == null) {
5671             return;
5672         }
5673         inputMethodListener = AWTEventMulticaster.remove(inputMethodListener, l);
5674     }
5675 
5676     /**
5677      * Returns an array of all the input method listeners
5678      * registered on this component.
5679      *
5680      * @return all of this component's <code>InputMethodListener</code>s
5681      *         or an empty array if no input method
5682      *         listeners are currently registered
5683      *
5684      * @see      #addInputMethodListener
5685      * @see      #removeInputMethodListener
5686      * @since    1.4
5687      */
5688     public synchronized InputMethodListener[] getInputMethodListeners() {
5689         return (InputMethodListener[]) (getListeners(InputMethodListener.class));
5690     }
5691 
5692     /**
5693      * Returns an array of all the objects currently registered
5694      * as <code><em>Foo</em>Listener</code>s
5695      * upon this <code>Component</code>.
5696      * <code><em>Foo</em>Listener</code>s are registered using the
5697      * <code>add<em>Foo</em>Listener</code> method.
5698      *
5699      * <p>
5700      * You can specify the <code>listenerType</code> argument
5701      * with a class literal, such as
5702      * <code><em>Foo</em>Listener.class</code>.
5703      * For example, you can query a
5704      * <code>Component</code> <code>c</code>
5705      * for its mouse listeners with the following code:
5706      *
5707      * <pre>MouseListener[] mls = (MouseListener[])(c.getListeners(MouseListener.class));</pre>
5708      *
5709      * If no such listeners exist, this method returns an empty array.
5710      *
5711      * @param listenerType the type of listeners requested; this parameter
5712      *          should specify an interface that descends from
5713      *          <code>java.util.EventListener</code>
5714      * @return an array of all objects registered as
5715      *          <code><em>Foo</em>Listener</code>s on this component,
5716      *          or an empty array if no such listeners have been added
5717      * @exception ClassCastException if <code>listenerType</code>
5718      *          doesn't specify a class or interface that implements
5719      *          <code>java.util.EventListener</code>
5720      *
5721      * @see #getComponentListeners
5722      * @see #getFocusListeners
5723      * @see #getHierarchyListeners
5724      * @see #getHierarchyBoundsListeners
5725      * @see #getKeyListeners
5726      * @see #getMouseListeners
5727      * @see #getMouseMotionListeners
5728      * @see #getMouseWheelListeners
5729      * @see #getInputMethodListeners
5730      * @see #getPropertyChangeListeners
5731      *
5732      * @since 1.3
5733      */
5734     public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
5735         EventListener l = null;
5736         if  (listenerType == ComponentListener.class) {
5737             l = componentListener;
5738         } else if (listenerType == FocusListener.class) {
5739             l = focusListener;
5740         } else if (listenerType == HierarchyListener.class) {
5741             l = hierarchyListener;
5742         } else if (listenerType == HierarchyBoundsListener.class) {
5743             l = hierarchyBoundsListener;
5744         } else if (listenerType == KeyListener.class) {
5745             l = keyListener;
5746         } else if (listenerType == MouseListener.class) {
5747             l = mouseListener;
5748         } else if (listenerType == MouseMotionListener.class) {
5749             l = mouseMotionListener;
5750         } else if (listenerType == MouseWheelListener.class) {
5751             l = mouseWheelListener;
5752         } else if (listenerType == InputMethodListener.class) {
5753             l = inputMethodListener;
5754         } else if (listenerType == PropertyChangeListener.class) {
5755             return (T[])getPropertyChangeListeners();
5756         }
5757         return AWTEventMulticaster.getListeners(l, listenerType);
5758     }
5759 
5760     /**
5761      * Gets the input method request handler which supports
5762      * requests from input methods for this component. A component
5763      * that supports on-the-spot text input must override this
5764      * method to return an <code>InputMethodRequests</code> instance.
5765      * At the same time, it also has to handle input method events.
5766      *
5767      * @return the input method request handler for this component,
5768      *          <code>null</code> by default
5769      * @see #addInputMethodListener
5770      * @since 1.2
5771      */
5772     public InputMethodRequests getInputMethodRequests() {
5773         return null;
5774     }
5775 
5776     /**
5777      * Gets the input context used by this component for handling
5778      * the communication with input methods when text is entered
5779      * in this component. By default, the input context used for
5780      * the parent component is returned. Components may
5781      * override this to return a private input context.
5782      *
5783      * @return the input context used by this component;
5784      *          <code>null</code> if no context can be determined
5785      * @since 1.2
5786      */
5787     public InputContext getInputContext() {
5788         Container parent = this.parent;
5789         if (parent == null) {
5790             return null;
5791         } else {
5792             return parent.getInputContext();
5793         }
5794     }
5795 
5796     /**
5797      * Enables the events defined by the specified event mask parameter
5798      * to be delivered to this component.
5799      * <p>
5800      * Event types are automatically enabled when a listener for
5801      * that event type is added to the component.
5802      * <p>
5803      * This method only needs to be invoked by subclasses of
5804      * <code>Component</code> which desire to have the specified event
5805      * types delivered to <code>processEvent</code> regardless of whether
5806      * or not a listener is registered.
5807      * @param      eventsToEnable   the event mask defining the event types
5808      * @see        #processEvent
5809      * @see        #disableEvents
5810      * @see        AWTEvent
5811      * @since      JDK1.1
5812      */
5813     protected final void enableEvents(long eventsToEnable) {
5814         long notifyAncestors = 0;
5815         synchronized (this) {
5816             if ((eventsToEnable & AWTEvent.HIERARCHY_EVENT_MASK) != 0 &&
5817                 hierarchyListener == null &&
5818                 (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) == 0) {
5819                 notifyAncestors |= AWTEvent.HIERARCHY_EVENT_MASK;
5820             }
5821             if ((eventsToEnable & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 &&
5822                 hierarchyBoundsListener == null &&
5823                 (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) == 0) {
5824                 notifyAncestors |= AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK;
5825             }
5826             eventMask |= eventsToEnable;
5827             newEventsOnly = true;
5828         }
5829 
5830         // if this is a lightweight component, enable mouse events
5831         // in the native container.
5832         if (peer instanceof LightweightPeer) {
5833             parent.proxyEnableEvents(eventMask);
5834         }
5835         if (notifyAncestors != 0) {
5836             synchronized (getTreeLock()) {
5837                 adjustListeningChildrenOnParent(notifyAncestors, 1);
5838             }
5839         }
5840     }
5841 
5842     /**
5843      * Disables the events defined by the specified event mask parameter
5844      * from being delivered to this component.
5845      * @param      eventsToDisable   the event mask defining the event types
5846      * @see        #enableEvents
5847      * @since      JDK1.1
5848      */
5849     protected final void disableEvents(long eventsToDisable) {
5850         long notifyAncestors = 0;
5851         synchronized (this) {
5852             if ((eventsToDisable & AWTEvent.HIERARCHY_EVENT_MASK) != 0 &&
5853                 hierarchyListener == null &&
5854                 (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0) {
5855                 notifyAncestors |= AWTEvent.HIERARCHY_EVENT_MASK;
5856             }
5857             if ((eventsToDisable & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK)!=0 &&
5858                 hierarchyBoundsListener == null &&
5859                 (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0) {
5860                 notifyAncestors |= AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK;
5861             }
5862             eventMask &= ~eventsToDisable;
5863         }
5864         if (notifyAncestors != 0) {
5865             synchronized (getTreeLock()) {
5866                 adjustListeningChildrenOnParent(notifyAncestors, -1);
5867             }
5868         }
5869     }
5870 
5871     transient sun.awt.EventQueueItem[] eventCache;
5872 
5873     /**
5874      * @see #isCoalescingEnabled
5875      * @see #checkCoalescing
5876      */
5877     transient private boolean coalescingEnabled = checkCoalescing();
5878 
5879     /**
5880      * Weak map of known coalesceEvent overriders.
5881      * Value indicates whether overriden.
5882      * Bootstrap classes are not included.
5883      */
5884     private static final Map<Class<?>, Boolean> coalesceMap =
5885         new java.util.WeakHashMap<Class<?>, Boolean>();
5886 
5887     /**
5888      * Indicates whether this class overrides coalesceEvents.
5889      * It is assumed that all classes that are loaded from the bootstrap
5890      *   do not.
5891      * The boostrap class loader is assumed to be represented by null.
5892      * We do not check that the method really overrides
5893      *   (it might be static, private or package private).
5894      */
5895      private boolean checkCoalescing() {
5896          if (getClass().getClassLoader()==null) {
5897              return false;
5898          }
5899          final Class<? extends Component> clazz = getClass();
5900          synchronized (coalesceMap) {
5901              // Check cache.
5902              Boolean value = coalesceMap.get(clazz);
5903              if (value != null) {
5904                  return value;
5905              }
5906 
5907              // Need to check non-bootstraps.
5908              Boolean enabled = java.security.AccessController.doPrivileged(
5909                  new java.security.PrivilegedAction<Boolean>() {
5910                      public Boolean run() {
5911                          return isCoalesceEventsOverriden(clazz);
5912                      }
5913                  }
5914                  );
5915              coalesceMap.put(clazz, enabled);
5916              return enabled;
5917          }
5918      }
5919 
5920     /**
5921      * Parameter types of coalesceEvents(AWTEvent,AWTEVent).
5922      */
5923     private static final Class[] coalesceEventsParams = {
5924         AWTEvent.class, AWTEvent.class
5925     };
5926 
5927     /**
5928      * Indicates whether a class or its superclasses override coalesceEvents.
5929      * Must be called with lock on coalesceMap and privileged.
5930      * @see checkCoalsecing
5931      */
5932     private static boolean isCoalesceEventsOverriden(Class<?> clazz) {
5933         assert Thread.holdsLock(coalesceMap);
5934 
5935         // First check superclass - we may not need to bother ourselves.
5936         Class<?> superclass = clazz.getSuperclass();
5937         if (superclass == null) {
5938             // Only occurs on implementations that
5939             //   do not use null to represent the bootsrap class loader.
5940             return false;
5941         }
5942         if (superclass.getClassLoader() != null) {
5943             Boolean value = coalesceMap.get(superclass);
5944             if (value == null) {
5945                 // Not done already - recurse.
5946                 if (isCoalesceEventsOverriden(superclass)) {
5947                     coalesceMap.put(superclass, true);
5948                     return true;
5949                 }
5950             } else if (value) {
5951                 return true;
5952             }
5953         }
5954 
5955         try {
5956             // Throws if not overriden.
5957             clazz.getDeclaredMethod(
5958                 "coalesceEvents", coalesceEventsParams
5959                 );
5960             return true;
5961         } catch (NoSuchMethodException e) {
5962             // Not present in this class.
5963             return false;
5964         }
5965     }
5966 
5967     /**
5968      * Indicates whether coalesceEvents may do something.
5969      */
5970     final boolean isCoalescingEnabled() {
5971         return coalescingEnabled;
5972      }
5973 
5974 
5975     /**
5976      * Potentially coalesce an event being posted with an existing
5977      * event.  This method is called by <code>EventQueue.postEvent</code>
5978      * if an event with the same ID as the event to be posted is found in
5979      * the queue (both events must have this component as their source).
5980      * This method either returns a coalesced event which replaces
5981      * the existing event (and the new event is then discarded), or
5982      * <code>null</code> to indicate that no combining should be done
5983      * (add the second event to the end of the queue).  Either event
5984      * parameter may be modified and returned, as the other one is discarded
5985      * unless <code>null</code> is returned.
5986      * <p>
5987      * This implementation of <code>coalesceEvents</code> coalesces
5988      * two event types: mouse move (and drag) events,
5989      * and paint (and update) events.
5990      * For mouse move events the last event is always returned, causing
5991      * intermediate moves to be discarded.  For paint events, the new
5992      * event is coalesced into a complex <code>RepaintArea</code> in the peer.
5993      * The new <code>AWTEvent</code> is always returned.
5994      *
5995      * @param  existingEvent  the event already on the <code>EventQueue</code>
5996      * @param  newEvent       the event being posted to the
5997      *          <code>EventQueue</code>
5998      * @return a coalesced event, or <code>null</code> indicating that no
5999      *          coalescing was done
6000      */
6001     protected AWTEvent coalesceEvents(AWTEvent existingEvent,
6002                                       AWTEvent newEvent) {
6003         return null;
6004     }
6005 
6006     /**
6007      * Processes events occurring on this component. By default this
6008      * method calls the appropriate
6009      * <code>process&lt;event&nbsp;type&gt;Event</code>
6010      * method for the given class of event.
6011      * <p>Note that if the event parameter is <code>null</code>
6012      * the behavior is unspecified and may result in an
6013      * exception.
6014      *
6015      * @param     e the event
6016      * @see       #processComponentEvent
6017      * @see       #processFocusEvent
6018      * @see       #processKeyEvent
6019      * @see       #processMouseEvent
6020      * @see       #processMouseMotionEvent
6021      * @see       #processInputMethodEvent
6022      * @see       #processHierarchyEvent
6023      * @see       #processMouseWheelEvent
6024      * @since     JDK1.1
6025      */
6026     protected void processEvent(AWTEvent e) {
6027         if (e instanceof FocusEvent) {
6028             processFocusEvent((FocusEvent)e);
6029 
6030         } else if (e instanceof MouseEvent) {
6031             switch(e.getID()) {
6032               case MouseEvent.MOUSE_PRESSED:
6033               case MouseEvent.MOUSE_RELEASED:
6034               case MouseEvent.MOUSE_CLICKED:
6035               case MouseEvent.MOUSE_ENTERED:
6036               case MouseEvent.MOUSE_EXITED:
6037                   processMouseEvent((MouseEvent)e);
6038                   break;
6039               case MouseEvent.MOUSE_MOVED:
6040               case MouseEvent.MOUSE_DRAGGED:
6041                   processMouseMotionEvent((MouseEvent)e);
6042                   break;
6043               case MouseEvent.MOUSE_WHEEL:
6044                   processMouseWheelEvent((MouseWheelEvent)e);
6045                   break;
6046             }
6047 
6048         } else if (e instanceof KeyEvent) {
6049             processKeyEvent((KeyEvent)e);
6050 
6051         } else if (e instanceof ComponentEvent) {
6052             processComponentEvent((ComponentEvent)e);
6053         } else if (e instanceof InputMethodEvent) {
6054             processInputMethodEvent((InputMethodEvent)e);
6055         } else if (e instanceof HierarchyEvent) {
6056             switch (e.getID()) {
6057               case HierarchyEvent.HIERARCHY_CHANGED:
6058                   processHierarchyEvent((HierarchyEvent)e);
6059                   break;
6060               case HierarchyEvent.ANCESTOR_MOVED:
6061               case HierarchyEvent.ANCESTOR_RESIZED:
6062                   processHierarchyBoundsEvent((HierarchyEvent)e);
6063                   break;
6064             }
6065         }
6066     }
6067 
6068     /**
6069      * Processes component events occurring on this component by
6070      * dispatching them to any registered
6071      * <code>ComponentListener</code> objects.
6072      * <p>
6073      * This method is not called unless component events are
6074      * enabled for this component. Component events are enabled
6075      * when one of the following occurs:
6076      * <p><ul>
6077      * <li>A <code>ComponentListener</code> object is registered
6078      * via <code>addComponentListener</code>.
6079      * <li>Component events are enabled via <code>enableEvents</code>.
6080      * </ul>
6081      * <p>Note that if the event parameter is <code>null</code>
6082      * the behavior is unspecified and may result in an
6083      * exception.
6084      *
6085      * @param       e the component event
6086      * @see         java.awt.event.ComponentEvent
6087      * @see         java.awt.event.ComponentListener
6088      * @see         #addComponentListener
6089      * @see         #enableEvents
6090      * @since       JDK1.1
6091      */
6092     protected void processComponentEvent(ComponentEvent e) {
6093         ComponentListener listener = componentListener;
6094         if (listener != null) {
6095             int id = e.getID();
6096             switch(id) {
6097               case ComponentEvent.COMPONENT_RESIZED:
6098                   listener.componentResized(e);
6099                   break;
6100               case ComponentEvent.COMPONENT_MOVED:
6101                   listener.componentMoved(e);
6102                   break;
6103               case ComponentEvent.COMPONENT_SHOWN:
6104                   listener.componentShown(e);
6105                   break;
6106               case ComponentEvent.COMPONENT_HIDDEN:
6107                   listener.componentHidden(e);
6108                   break;
6109             }
6110         }
6111     }
6112 
6113     /**
6114      * Processes focus events occurring on this component by
6115      * dispatching them to any registered
6116      * <code>FocusListener</code> objects.
6117      * <p>
6118      * This method is not called unless focus events are
6119      * enabled for this component. Focus events are enabled
6120      * when one of the following occurs:
6121      * <p><ul>
6122      * <li>A <code>FocusListener</code> object is registered
6123      * via <code>addFocusListener</code>.
6124      * <li>Focus events are enabled via <code>enableEvents</code>.
6125      * </ul>
6126      * <p>
6127      * If focus events are enabled for a <code>Component</code>,
6128      * the current <code>KeyboardFocusManager</code> determines
6129      * whether or not a focus event should be dispatched to
6130      * registered <code>FocusListener</code> objects.  If the
6131      * events are to be dispatched, the <code>KeyboardFocusManager</code>
6132      * calls the <code>Component</code>'s <code>dispatchEvent</code>
6133      * method, which results in a call to the <code>Component</code>'s
6134      * <code>processFocusEvent</code> method.
6135      * <p>
6136      * If focus events are enabled for a <code>Component</code>, calling
6137      * the <code>Component</code>'s <code>dispatchEvent</code> method
6138      * with a <code>FocusEvent</code> as the argument will result in a
6139      * call to the <code>Component</code>'s <code>processFocusEvent</code>
6140      * method regardless of the current <code>KeyboardFocusManager</code>.
6141      * <p>
6142      * <p>Note that if the event parameter is <code>null</code>
6143      * the behavior is unspecified and may result in an
6144      * exception.
6145      *
6146      * @param       e the focus event
6147      * @see         java.awt.event.FocusEvent
6148      * @see         java.awt.event.FocusListener
6149      * @see         java.awt.KeyboardFocusManager
6150      * @see         #addFocusListener
6151      * @see         #enableEvents
6152      * @see         #dispatchEvent
6153      * @since       JDK1.1
6154      */
6155     protected void processFocusEvent(FocusEvent e) {
6156         FocusListener listener = focusListener;
6157         if (listener != null) {
6158             int id = e.getID();
6159             switch(id) {
6160               case FocusEvent.FOCUS_GAINED:
6161                   listener.focusGained(e);
6162                   break;
6163               case FocusEvent.FOCUS_LOST:
6164                   listener.focusLost(e);
6165                   break;
6166             }
6167         }
6168     }
6169 
6170     /**
6171      * Processes key events occurring on this component by
6172      * dispatching them to any registered
6173      * <code>KeyListener</code> objects.
6174      * <p>
6175      * This method is not called unless key events are
6176      * enabled for this component. Key events are enabled
6177      * when one of the following occurs:
6178      * <p><ul>
6179      * <li>A <code>KeyListener</code> object is registered
6180      * via <code>addKeyListener</code>.
6181      * <li>Key events are enabled via <code>enableEvents</code>.
6182      * </ul>
6183      *
6184      * <p>
6185      * If key events are enabled for a <code>Component</code>,
6186      * the current <code>KeyboardFocusManager</code> determines
6187      * whether or not a key event should be dispatched to
6188      * registered <code>KeyListener</code> objects.  The
6189      * <code>DefaultKeyboardFocusManager</code> will not dispatch
6190      * key events to a <code>Component</code> that is not the focus
6191      * owner or is not showing.
6192      * <p>
6193      * As of J2SE 1.4, <code>KeyEvent</code>s are redirected to
6194      * the focus owner. Please see the
6195      * <a href="doc-files/FocusSpec.html">Focus Specification</a>
6196      * for further information.
6197      * <p>
6198      * Calling a <code>Component</code>'s <code>dispatchEvent</code>
6199      * method with a <code>KeyEvent</code> as the argument will
6200      * result in a call to the <code>Component</code>'s
6201      * <code>processKeyEvent</code> method regardless of the
6202      * current <code>KeyboardFocusManager</code> as long as the
6203      * component is showing, focused, and enabled, and key events
6204      * are enabled on it.
6205      * <p>If the event parameter is <code>null</code>
6206      * the behavior is unspecified and may result in an
6207      * exception.
6208      *
6209      * @param       e the key event
6210      * @see         java.awt.event.KeyEvent
6211      * @see         java.awt.event.KeyListener
6212      * @see         java.awt.KeyboardFocusManager
6213      * @see         java.awt.DefaultKeyboardFocusManager
6214      * @see         #processEvent
6215      * @see         #dispatchEvent
6216      * @see         #addKeyListener
6217      * @see         #enableEvents
6218      * @see         #isShowing
6219      * @since       JDK1.1
6220      */
6221     protected void processKeyEvent(KeyEvent e) {
6222         KeyListener listener = keyListener;
6223         if (listener != null) {
6224             int id = e.getID();
6225             switch(id) {
6226               case KeyEvent.KEY_TYPED:
6227                   listener.keyTyped(e);
6228                   break;
6229               case KeyEvent.KEY_PRESSED:
6230                   listener.keyPressed(e);
6231                   break;
6232               case KeyEvent.KEY_RELEASED:
6233                   listener.keyReleased(e);
6234                   break;
6235             }
6236         }
6237     }
6238 
6239     /**
6240      * Processes mouse events occurring on this component by
6241      * dispatching them to any registered
6242      * <code>MouseListener</code> objects.
6243      * <p>
6244      * This method is not called unless mouse events are
6245      * enabled for this component. Mouse events are enabled
6246      * when one of the following occurs:
6247      * <p><ul>
6248      * <li>A <code>MouseListener</code> object is registered
6249      * via <code>addMouseListener</code>.
6250      * <li>Mouse events are enabled via <code>enableEvents</code>.
6251      * </ul>
6252      * <p>Note that if the event parameter is <code>null</code>
6253      * the behavior is unspecified and may result in an
6254      * exception.
6255      *
6256      * @param       e the mouse event
6257      * @see         java.awt.event.MouseEvent
6258      * @see         java.awt.event.MouseListener
6259      * @see         #addMouseListener
6260      * @see         #enableEvents
6261      * @since       JDK1.1
6262      */
6263     protected void processMouseEvent(MouseEvent e) {
6264         MouseListener listener = mouseListener;
6265         if (listener != null) {
6266             int id = e.getID();
6267             switch(id) {
6268               case MouseEvent.MOUSE_PRESSED:
6269                   listener.mousePressed(e);
6270                   break;
6271               case MouseEvent.MOUSE_RELEASED:
6272                   listener.mouseReleased(e);
6273                   break;
6274               case MouseEvent.MOUSE_CLICKED:
6275                   listener.mouseClicked(e);
6276                   break;
6277               case MouseEvent.MOUSE_EXITED:
6278                   listener.mouseExited(e);
6279                   break;
6280               case MouseEvent.MOUSE_ENTERED:
6281                   listener.mouseEntered(e);
6282                   break;
6283             }
6284         }
6285     }
6286 
6287     /**
6288      * Processes mouse motion events occurring on this component by
6289      * dispatching them to any registered
6290      * <code>MouseMotionListener</code> objects.
6291      * <p>
6292      * This method is not called unless mouse motion events are
6293      * enabled for this component. Mouse motion events are enabled
6294      * when one of the following occurs:
6295      * <p><ul>
6296      * <li>A <code>MouseMotionListener</code> object is registered
6297      * via <code>addMouseMotionListener</code>.
6298      * <li>Mouse motion events are enabled via <code>enableEvents</code>.
6299      * </ul>
6300      * <p>Note that if the event parameter is <code>null</code>
6301      * the behavior is unspecified and may result in an
6302      * exception.
6303      *
6304      * @param       e the mouse motion event
6305      * @see         java.awt.event.MouseEvent
6306      * @see         java.awt.event.MouseMotionListener
6307      * @see         #addMouseMotionListener
6308      * @see         #enableEvents
6309      * @since       JDK1.1
6310      */
6311     protected void processMouseMotionEvent(MouseEvent e) {
6312         MouseMotionListener listener = mouseMotionListener;
6313         if (listener != null) {
6314             int id = e.getID();
6315             switch(id) {
6316               case MouseEvent.MOUSE_MOVED:
6317                   listener.mouseMoved(e);
6318                   break;
6319               case MouseEvent.MOUSE_DRAGGED:
6320                   listener.mouseDragged(e);
6321                   break;
6322             }
6323         }
6324     }
6325 
6326     /**
6327      * Processes mouse wheel events occurring on this component by
6328      * dispatching them to any registered
6329      * <code>MouseWheelListener</code> objects.
6330      * <p>
6331      * This method is not called unless mouse wheel events are
6332      * enabled for this component. Mouse wheel events are enabled
6333      * when one of the following occurs:
6334      * <p><ul>
6335      * <li>A <code>MouseWheelListener</code> object is registered
6336      * via <code>addMouseWheelListener</code>.
6337      * <li>Mouse wheel events are enabled via <code>enableEvents</code>.
6338      * </ul>
6339      * <p>
6340      * For information on how mouse wheel events are dispatched, see
6341      * the class description for {@link MouseWheelEvent}.
6342      * <p>
6343      * Note that if the event parameter is <code>null</code>
6344      * the behavior is unspecified and may result in an
6345      * exception.
6346      *
6347      * @param       e the mouse wheel event
6348      * @see         java.awt.event.MouseWheelEvent
6349      * @see         java.awt.event.MouseWheelListener
6350      * @see         #addMouseWheelListener
6351      * @see         #enableEvents
6352      * @since       1.4
6353      */
6354     protected void processMouseWheelEvent(MouseWheelEvent e) {
6355         MouseWheelListener listener = mouseWheelListener;
6356         if (listener != null) {
6357             int id = e.getID();
6358             switch(id) {
6359               case MouseEvent.MOUSE_WHEEL:
6360                   listener.mouseWheelMoved(e);
6361                   break;
6362             }
6363         }
6364     }
6365 
6366     boolean postsOldMouseEvents() {
6367         return false;
6368     }
6369 
6370     /**
6371      * Processes input method events occurring on this component by
6372      * dispatching them to any registered
6373      * <code>InputMethodListener</code> objects.
6374      * <p>
6375      * This method is not called unless input method events
6376      * are enabled for this component. Input method events are enabled
6377      * when one of the following occurs:
6378      * <p><ul>
6379      * <li>An <code>InputMethodListener</code> object is registered
6380      * via <code>addInputMethodListener</code>.
6381      * <li>Input method events are enabled via <code>enableEvents</code>.
6382      * </ul>
6383      * <p>Note that if the event parameter is <code>null</code>
6384      * the behavior is unspecified and may result in an
6385      * exception.
6386      *
6387      * @param       e the input method event
6388      * @see         java.awt.event.InputMethodEvent
6389      * @see         java.awt.event.InputMethodListener
6390      * @see         #addInputMethodListener
6391      * @see         #enableEvents
6392      * @since       1.2
6393      */
6394     protected void processInputMethodEvent(InputMethodEvent e) {
6395         InputMethodListener listener = inputMethodListener;
6396         if (listener != null) {
6397             int id = e.getID();
6398             switch (id) {
6399               case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
6400                   listener.inputMethodTextChanged(e);
6401                   break;
6402               case InputMethodEvent.CARET_POSITION_CHANGED:
6403                   listener.caretPositionChanged(e);
6404                   break;
6405             }
6406         }
6407     }
6408 
6409     /**
6410      * Processes hierarchy events occurring on this component by
6411      * dispatching them to any registered
6412      * <code>HierarchyListener</code> objects.
6413      * <p>
6414      * This method is not called unless hierarchy events
6415      * are enabled for this component. Hierarchy events are enabled
6416      * when one of the following occurs:
6417      * <p><ul>
6418      * <li>An <code>HierarchyListener</code> object is registered
6419      * via <code>addHierarchyListener</code>.
6420      * <li>Hierarchy events are enabled via <code>enableEvents</code>.
6421      * </ul>
6422      * <p>Note that if the event parameter is <code>null</code>
6423      * the behavior is unspecified and may result in an
6424      * exception.
6425      *
6426      * @param       e the hierarchy event
6427      * @see         java.awt.event.HierarchyEvent
6428      * @see         java.awt.event.HierarchyListener
6429      * @see         #addHierarchyListener
6430      * @see         #enableEvents
6431      * @since       1.3
6432      */
6433     protected void processHierarchyEvent(HierarchyEvent e) {
6434         HierarchyListener listener = hierarchyListener;
6435         if (listener != null) {
6436             int id = e.getID();
6437             switch (id) {
6438               case HierarchyEvent.HIERARCHY_CHANGED:
6439                   listener.hierarchyChanged(e);
6440                   break;
6441             }
6442         }
6443     }
6444 
6445     /**
6446      * Processes hierarchy bounds events occurring on this component by
6447      * dispatching them to any registered
6448      * <code>HierarchyBoundsListener</code> objects.
6449      * <p>
6450      * This method is not called unless hierarchy bounds events
6451      * are enabled for this component. Hierarchy bounds events are enabled
6452      * when one of the following occurs:
6453      * <p><ul>
6454      * <li>An <code>HierarchyBoundsListener</code> object is registered
6455      * via <code>addHierarchyBoundsListener</code>.
6456      * <li>Hierarchy bounds events are enabled via <code>enableEvents</code>.
6457      * </ul>
6458      * <p>Note that if the event parameter is <code>null</code>
6459      * the behavior is unspecified and may result in an
6460      * exception.
6461      *
6462      * @param       e the hierarchy event
6463      * @see         java.awt.event.HierarchyEvent
6464      * @see         java.awt.event.HierarchyBoundsListener
6465      * @see         #addHierarchyBoundsListener
6466      * @see         #enableEvents
6467      * @since       1.3
6468      */
6469     protected void processHierarchyBoundsEvent(HierarchyEvent e) {
6470         HierarchyBoundsListener listener = hierarchyBoundsListener;
6471         if (listener != null) {
6472             int id = e.getID();
6473             switch (id) {
6474               case HierarchyEvent.ANCESTOR_MOVED:
6475                   listener.ancestorMoved(e);
6476                   break;
6477               case HierarchyEvent.ANCESTOR_RESIZED:
6478                   listener.ancestorResized(e);
6479                   break;
6480             }
6481         }
6482     }
6483 
6484     /**
6485      * @deprecated As of JDK version 1.1
6486      * replaced by processEvent(AWTEvent).
6487      */
6488     @Deprecated
6489     public boolean handleEvent(Event evt) {
6490         switch (evt.id) {
6491           case Event.MOUSE_ENTER:
6492               return mouseEnter(evt, evt.x, evt.y);
6493 
6494           case Event.MOUSE_EXIT:
6495               return mouseExit(evt, evt.x, evt.y);
6496 
6497           case Event.MOUSE_MOVE:
6498               return mouseMove(evt, evt.x, evt.y);
6499 
6500           case Event.MOUSE_DOWN:
6501               return mouseDown(evt, evt.x, evt.y);
6502 
6503           case Event.MOUSE_DRAG:
6504               return mouseDrag(evt, evt.x, evt.y);
6505 
6506           case Event.MOUSE_UP:
6507               return mouseUp(evt, evt.x, evt.y);
6508 
6509           case Event.KEY_PRESS:
6510           case Event.KEY_ACTION:
6511               return keyDown(evt, evt.key);
6512 
6513           case Event.KEY_RELEASE:
6514           case Event.KEY_ACTION_RELEASE:
6515               return keyUp(evt, evt.key);
6516 
6517           case Event.ACTION_EVENT:
6518               return action(evt, evt.arg);
6519           case Event.GOT_FOCUS:
6520               return gotFocus(evt, evt.arg);
6521           case Event.LOST_FOCUS:
6522               return lostFocus(evt, evt.arg);
6523         }
6524         return false;
6525     }
6526 
6527     /**
6528      * @deprecated As of JDK version 1.1,
6529      * replaced by processMouseEvent(MouseEvent).
6530      */
6531     @Deprecated
6532     public boolean mouseDown(Event evt, int x, int y) {
6533         return false;
6534     }
6535 
6536     /**
6537      * @deprecated As of JDK version 1.1,
6538      * replaced by processMouseMotionEvent(MouseEvent).
6539      */
6540     @Deprecated
6541     public boolean mouseDrag(Event evt, int x, int y) {
6542         return false;
6543     }
6544 
6545     /**
6546      * @deprecated As of JDK version 1.1,
6547      * replaced by processMouseEvent(MouseEvent).
6548      */
6549     @Deprecated
6550     public boolean mouseUp(Event evt, int x, int y) {
6551         return false;
6552     }
6553 
6554     /**
6555      * @deprecated As of JDK version 1.1,
6556      * replaced by processMouseMotionEvent(MouseEvent).
6557      */
6558     @Deprecated
6559     public boolean mouseMove(Event evt, int x, int y) {
6560         return false;
6561     }
6562 
6563     /**
6564      * @deprecated As of JDK version 1.1,
6565      * replaced by processMouseEvent(MouseEvent).
6566      */
6567     @Deprecated
6568     public boolean mouseEnter(Event evt, int x, int y) {
6569         return false;
6570     }
6571 
6572     /**
6573      * @deprecated As of JDK version 1.1,
6574      * replaced by processMouseEvent(MouseEvent).
6575      */
6576     @Deprecated
6577     public boolean mouseExit(Event evt, int x, int y) {
6578         return false;
6579     }
6580 
6581     /**
6582      * @deprecated As of JDK version 1.1,
6583      * replaced by processKeyEvent(KeyEvent).
6584      */
6585     @Deprecated
6586     public boolean keyDown(Event evt, int key) {
6587         return false;
6588     }
6589 
6590     /**
6591      * @deprecated As of JDK version 1.1,
6592      * replaced by processKeyEvent(KeyEvent).
6593      */
6594     @Deprecated
6595     public boolean keyUp(Event evt, int key) {
6596         return false;
6597     }
6598 
6599     /**
6600      * @deprecated As of JDK version 1.1,
6601      * should register this component as ActionListener on component
6602      * which fires action events.
6603      */
6604     @Deprecated
6605     public boolean action(Event evt, Object what) {
6606         return false;
6607     }
6608 
6609     /**
6610      * Makes this <code>Component</code> displayable by connecting it to a
6611      * native screen resource.
6612      * This method is called internally by the toolkit and should
6613      * not be called directly by programs.
6614      * @see       #isDisplayable
6615      * @see       #removeNotify
6616      * @since JDK1.0
6617      */
6618     public void addNotify() {
6619         synchronized (getTreeLock()) {
6620             ComponentPeer peer = this.peer;
6621             if (peer == null || peer instanceof LightweightPeer){
6622                 if (peer == null) {
6623                     // Update both the Component's peer variable and the local
6624                     // variable we use for thread safety.
6625                     this.peer = peer = getToolkit().createComponent(this);
6626                 }
6627 
6628                 // This is a lightweight component which means it won't be
6629                 // able to get window-related events by itself.  If any
6630                 // have been enabled, then the nearest native container must
6631                 // be enabled.
6632                 if (parent != null) {
6633                     long mask = 0;
6634                     if ((mouseListener != null) || ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0)) {
6635                         mask |= AWTEvent.MOUSE_EVENT_MASK;
6636                     }
6637                     if ((mouseMotionListener != null) ||
6638                         ((eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0)) {
6639                         mask |= AWTEvent.MOUSE_MOTION_EVENT_MASK;
6640                     }
6641                     if ((mouseWheelListener != null ) ||
6642                         ((eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0)) {
6643                         mask |= AWTEvent.MOUSE_WHEEL_EVENT_MASK;
6644                     }
6645                     if (focusListener != null || (eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0) {
6646                         mask |= AWTEvent.FOCUS_EVENT_MASK;
6647                     }
6648                     if (keyListener != null || (eventMask & AWTEvent.KEY_EVENT_MASK) != 0) {
6649                         mask |= AWTEvent.KEY_EVENT_MASK;
6650                     }
6651                     if (mask != 0) {
6652                         parent.proxyEnableEvents(mask);
6653                     }
6654                 }
6655             } else {
6656                 // It's native.  If the parent is lightweight it
6657                 // will need some help.
6658                 Container parent = this.parent;
6659                 if (parent != null && parent.peer instanceof LightweightPeer) {
6660                     relocateComponent();
6661                 }
6662             }
6663             invalidate();
6664 
6665             int npopups = (popups != null? popups.size() : 0);
6666             for (int i = 0 ; i < npopups ; i++) {
6667                 PopupMenu popup = (PopupMenu)popups.elementAt(i);
6668                 popup.addNotify();
6669             }
6670 
6671             if (dropTarget != null) dropTarget.addNotify(peer);
6672 
6673             peerFont = getFont();
6674 
6675             if (getContainer() != null && !isAddNotifyComplete) {
6676                 getContainer().increaseComponentCount(this);
6677             }
6678 
6679 
6680             // Update stacking order
6681             updateZOrder();
6682 
6683             if (!isAddNotifyComplete) {
6684                 mixOnShowing();
6685             }
6686 
6687             isAddNotifyComplete = true;
6688 
6689             if (hierarchyListener != null ||
6690                 (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 ||
6691                 Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK)) {
6692                 HierarchyEvent e =
6693                     new HierarchyEvent(this, HierarchyEvent.HIERARCHY_CHANGED,
6694                                        this, parent,
6695                                        HierarchyEvent.DISPLAYABILITY_CHANGED |
6696                                        ((isRecursivelyVisible())
6697                                         ? HierarchyEvent.SHOWING_CHANGED
6698                                         : 0));
6699                 dispatchEvent(e);
6700             }
6701         }
6702     }
6703 
6704     /**
6705      * Makes this <code>Component</code> undisplayable by destroying it native
6706      * screen resource.
6707      * <p>
6708      * This method is called by the toolkit internally and should
6709      * not be called directly by programs. Code overriding
6710      * this method should call <code>super.removeNotify</code> as
6711      * the first line of the overriding method.
6712      *
6713      * @see       #isDisplayable
6714      * @see       #addNotify
6715      * @since JDK1.0
6716      */
6717     public void removeNotify() {
6718         KeyboardFocusManager.clearMostRecentFocusOwner(this);
6719         if (KeyboardFocusManager.getCurrentKeyboardFocusManager().
6720             getPermanentFocusOwner() == this)
6721         {
6722             KeyboardFocusManager.getCurrentKeyboardFocusManager().
6723                 setGlobalPermanentFocusOwner(null);
6724         }
6725 
6726         synchronized (getTreeLock()) {
6727             if (isFocusOwner() && KeyboardFocusManager.isAutoFocusTransferEnabledFor(this)) {
6728                 transferFocus(true);
6729             }
6730 
6731             if (getContainer() != null && isAddNotifyComplete) {
6732                 getContainer().decreaseComponentCount(this);
6733             }
6734 
6735             int npopups = (popups != null? popups.size() : 0);
6736             for (int i = 0 ; i < npopups ; i++) {
6737                 PopupMenu popup = (PopupMenu)popups.elementAt(i);
6738                 popup.removeNotify();
6739             }
6740             // If there is any input context for this component, notify
6741             // that this component is being removed. (This has to be done
6742             // before hiding peer.)
6743             if ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) {
6744                 InputContext inputContext = getInputContext();
6745                 if (inputContext != null) {
6746                     inputContext.removeNotify(this);
6747                 }
6748             }
6749 
6750             ComponentPeer p = peer;
6751             if (p != null) {
6752                 boolean isLightweight = isLightweight();
6753 
6754                 if (bufferStrategy instanceof FlipBufferStrategy) {
6755                     ((FlipBufferStrategy)bufferStrategy).destroyBuffers();
6756                 }
6757 
6758                 if (dropTarget != null) dropTarget.removeNotify(peer);
6759 
6760                 // Hide peer first to stop system events such as cursor moves.
6761                 if (visible) {
6762                     p.setVisible(false);
6763                 }
6764 
6765                 peer = null; // Stop peer updates.
6766                 peerFont = null;
6767 
6768                 Toolkit.getEventQueue().removeSourceEvents(this, false);
6769                 KeyboardFocusManager.getCurrentKeyboardFocusManager().
6770                     discardKeyEvents(this);
6771 
6772                 p.dispose();
6773 
6774                 mixOnHiding(isLightweight);
6775 
6776                 isAddNotifyComplete = false;
6777                 // Nullifying compoundShape means that the component has normal shape
6778                 // (or has no shape at all).
6779                 this.compoundShape = null;
6780             }
6781 
6782             if (hierarchyListener != null ||
6783                 (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 ||
6784                 Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK)) {
6785                 HierarchyEvent e =
6786                     new HierarchyEvent(this, HierarchyEvent.HIERARCHY_CHANGED,
6787                                        this, parent,
6788                                        HierarchyEvent.DISPLAYABILITY_CHANGED |
6789                                        ((isRecursivelyVisible())
6790                                         ? HierarchyEvent.SHOWING_CHANGED
6791                                         : 0));
6792                 dispatchEvent(e);
6793             }
6794         }
6795     }
6796 
6797     /**
6798      * @deprecated As of JDK version 1.1,
6799      * replaced by processFocusEvent(FocusEvent).
6800      */
6801     @Deprecated
6802     public boolean gotFocus(Event evt, Object what) {
6803         return false;
6804     }
6805 
6806     /**
6807      * @deprecated As of JDK version 1.1,
6808      * replaced by processFocusEvent(FocusEvent).
6809      */
6810     @Deprecated
6811     public boolean lostFocus(Event evt, Object what) {
6812         return false;
6813     }
6814 
6815     /**
6816      * Returns whether this <code>Component</code> can become the focus
6817      * owner.
6818      *
6819      * @return <code>true</code> if this <code>Component</code> is
6820      * focusable; <code>false</code> otherwise
6821      * @see #setFocusable
6822      * @since JDK1.1
6823      * @deprecated As of 1.4, replaced by <code>isFocusable()</code>.
6824      */
6825     @Deprecated
6826     public boolean isFocusTraversable() {
6827         if (isFocusTraversableOverridden == FOCUS_TRAVERSABLE_UNKNOWN) {
6828             isFocusTraversableOverridden = FOCUS_TRAVERSABLE_DEFAULT;
6829         }
6830         return focusable;
6831     }
6832 
6833     /**
6834      * Returns whether this Component can be focused.
6835      *
6836      * @return <code>true</code> if this Component is focusable;
6837      *         <code>false</code> otherwise.
6838      * @see #setFocusable
6839      * @since 1.4
6840      */
6841     public boolean isFocusable() {
6842         return isFocusTraversable();
6843     }
6844 
6845     /**
6846      * Sets the focusable state of this Component to the specified value. This
6847      * value overrides the Component's default focusability.
6848      *
6849      * @param focusable indicates whether this Component is focusable
6850      * @see #isFocusable
6851      * @since 1.4
6852      * @beaninfo
6853      *       bound: true
6854      */
6855     public void setFocusable(boolean focusable) {
6856         boolean oldFocusable;
6857         synchronized (this) {
6858             oldFocusable = this.focusable;
6859             this.focusable = focusable;
6860         }
6861         isFocusTraversableOverridden = FOCUS_TRAVERSABLE_SET;
6862 
6863         firePropertyChange("focusable", oldFocusable, focusable);
6864         if (oldFocusable && !focusable) {
6865             if (isFocusOwner() && KeyboardFocusManager.isAutoFocusTransferEnabled()) {
6866                 transferFocus(true);
6867             }
6868             KeyboardFocusManager.clearMostRecentFocusOwner(this);
6869         }
6870     }
6871 
6872     final boolean isFocusTraversableOverridden() {
6873         return (isFocusTraversableOverridden != FOCUS_TRAVERSABLE_DEFAULT);
6874     }
6875 
6876     /**
6877      * Sets the focus traversal keys for a given traversal operation for this
6878      * Component.
6879      * <p>
6880      * The default values for a Component's focus traversal keys are
6881      * implementation-dependent. Sun recommends that all implementations for a
6882      * particular native platform use the same default values. The
6883      * recommendations for Windows and Unix are listed below. These
6884      * recommendations are used in the Sun AWT implementations.
6885      *
6886      * <table border=1 summary="Recommended default values for a Component's focus traversal keys">
6887      * <tr>
6888      *    <th>Identifier</th>
6889      *    <th>Meaning</th>
6890      *    <th>Default</th>
6891      * </tr>
6892      * <tr>
6893      *    <td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</td>
6894      *    <td>Normal forward keyboard traversal</td>
6895      *    <td>TAB on KEY_PRESSED, CTRL-TAB on KEY_PRESSED</td>
6896      * </tr>
6897      * <tr>
6898      *    <td>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</td>
6899      *    <td>Normal reverse keyboard traversal</td>
6900      *    <td>SHIFT-TAB on KEY_PRESSED, CTRL-SHIFT-TAB on KEY_PRESSED</td>
6901      * </tr>
6902      * <tr>
6903      *    <td>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</td>
6904      *    <td>Go up one focus traversal cycle</td>
6905      *    <td>none</td>
6906      * </tr>
6907      * </table>
6908      *
6909      * To disable a traversal key, use an empty Set; Collections.EMPTY_SET is
6910      * recommended.
6911      * <p>
6912      * Using the AWTKeyStroke API, client code can specify on which of two
6913      * specific KeyEvents, KEY_PRESSED or KEY_RELEASED, the focus traversal
6914      * operation will occur. Regardless of which KeyEvent is specified,
6915      * however, all KeyEvents related to the focus traversal key, including the
6916      * associated KEY_TYPED event, will be consumed, and will not be dispatched
6917      * to any Component. It is a runtime error to specify a KEY_TYPED event as
6918      * mapping to a focus traversal operation, or to map the same event to
6919      * multiple default focus traversal operations.
6920      * <p>
6921      * If a value of null is specified for the Set, this Component inherits the
6922      * Set from its parent. If all ancestors of this Component have null
6923      * specified for the Set, then the current KeyboardFocusManager's default
6924      * Set is used.
6925      *
6926      * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
6927      *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
6928      *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
6929      * @param keystrokes the Set of AWTKeyStroke for the specified operation
6930      * @see #getFocusTraversalKeys
6931      * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
6932      * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
6933      * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
6934      * @throws IllegalArgumentException if id is not one of
6935      *         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
6936      *         KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
6937      *         KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or if keystrokes
6938      *         contains null, or if any Object in keystrokes is not an
6939      *         AWTKeyStroke, or if any keystroke represents a KEY_TYPED event,
6940      *         or if any keystroke already maps to another focus traversal
6941      *         operation for this Component
6942      * @since 1.4
6943      * @beaninfo
6944      *       bound: true
6945      */
6946     public void setFocusTraversalKeys(int id,
6947                                       Set<? extends AWTKeyStroke> keystrokes)
6948     {
6949         if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH - 1) {
6950             throw new IllegalArgumentException("invalid focus traversal key identifier");
6951         }
6952 
6953         setFocusTraversalKeys_NoIDCheck(id, keystrokes);
6954     }
6955 
6956     /**
6957      * Returns the Set of focus traversal keys for a given traversal operation
6958      * for this Component. (See
6959      * <code>setFocusTraversalKeys</code> for a full description of each key.)
6960      * <p>
6961      * If a Set of traversal keys has not been explicitly defined for this
6962      * Component, then this Component's parent's Set is returned. If no Set
6963      * has been explicitly defined for any of this Component's ancestors, then
6964      * the current KeyboardFocusManager's default Set is returned.
6965      *
6966      * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
6967      *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
6968      *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
6969      * @return the Set of AWTKeyStrokes for the specified operation. The Set
6970      *         will be unmodifiable, and may be empty. null will never be
6971      *         returned.
6972      * @see #setFocusTraversalKeys
6973      * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
6974      * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
6975      * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
6976      * @throws IllegalArgumentException if id is not one of
6977      *         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
6978      *         KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
6979      *         KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
6980      * @since 1.4
6981      */
6982     public Set<AWTKeyStroke> getFocusTraversalKeys(int id) {
6983         if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH - 1) {
6984             throw new IllegalArgumentException("invalid focus traversal key identifier");
6985         }
6986 
6987         return getFocusTraversalKeys_NoIDCheck(id);
6988     }
6989 
6990     // We define these methods so that Container does not need to repeat this
6991     // code. Container cannot call super.<method> because Container allows
6992     // DOWN_CYCLE_TRAVERSAL_KEY while Component does not. The Component method
6993     // would erroneously generate an IllegalArgumentException for
6994     // DOWN_CYCLE_TRAVERSAL_KEY.
6995     final void setFocusTraversalKeys_NoIDCheck(int id, Set<? extends AWTKeyStroke> keystrokes) {
6996         Set oldKeys;
6997 
6998         synchronized (this) {
6999             if (focusTraversalKeys == null) {
7000                 initializeFocusTraversalKeys();
7001             }
7002 
7003             if (keystrokes != null) {
7004                 for (Iterator iter = keystrokes.iterator(); iter.hasNext(); ) {
7005                     Object obj = iter.next();
7006 
7007                     if (obj == null) {
7008                         throw new IllegalArgumentException("cannot set null focus traversal key");
7009                     }
7010 
7011                     // Fix for 6195828:
7012                     //According to javadoc this method should throw IAE instead of ClassCastException
7013                     if (!(obj instanceof AWTKeyStroke)) {
7014                         throw new IllegalArgumentException("object is expected to be AWTKeyStroke");
7015                     }
7016                     AWTKeyStroke keystroke = (AWTKeyStroke)obj;
7017 
7018                     if (keystroke.getKeyChar() != KeyEvent.CHAR_UNDEFINED) {
7019                         throw new IllegalArgumentException("focus traversal keys cannot map to KEY_TYPED events");
7020                     }
7021 
7022                     for (int i = 0; i < focusTraversalKeys.length; i++) {
7023                         if (i == id) {
7024                             continue;
7025                         }
7026 
7027                         if (getFocusTraversalKeys_NoIDCheck(i).contains(keystroke))
7028                         {
7029                             throw new IllegalArgumentException("focus traversal keys must be unique for a Component");
7030                         }
7031                     }
7032                 }
7033             }
7034 
7035             oldKeys = focusTraversalKeys[id];
7036             focusTraversalKeys[id] = (keystrokes != null)
7037                 ? Collections.unmodifiableSet(new HashSet(keystrokes))
7038                 : null;
7039         }
7040 
7041         firePropertyChange(focusTraversalKeyPropertyNames[id], oldKeys,
7042                            keystrokes);
7043     }
7044     final Set getFocusTraversalKeys_NoIDCheck(int id) {
7045         // Okay to return Set directly because it is an unmodifiable view
7046         Set keystrokes = (focusTraversalKeys != null)
7047             ? focusTraversalKeys[id]
7048             : null;
7049 
7050         if (keystrokes != null) {
7051             return keystrokes;
7052         } else {
7053             Container parent = this.parent;
7054             if (parent != null) {
7055                 return parent.getFocusTraversalKeys(id);
7056             } else {
7057                 return KeyboardFocusManager.getCurrentKeyboardFocusManager().
7058                     getDefaultFocusTraversalKeys(id);
7059             }
7060         }
7061     }
7062 
7063     /**
7064      * Returns whether the Set of focus traversal keys for the given focus
7065      * traversal operation has been explicitly defined for this Component. If
7066      * this method returns <code>false</code>, this Component is inheriting the
7067      * Set from an ancestor, or from the current KeyboardFocusManager.
7068      *
7069      * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
7070      *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
7071      *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
7072      * @return <code>true</code> if the the Set of focus traversal keys for the
7073      *         given focus traversal operation has been explicitly defined for
7074      *         this Component; <code>false</code> otherwise.
7075      * @throws IllegalArgumentException if id is not one of
7076      *         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
7077      *         KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
7078      *         KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
7079      * @since 1.4
7080      */
7081     public boolean areFocusTraversalKeysSet(int id) {
7082         if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH - 1) {
7083             throw new IllegalArgumentException("invalid focus traversal key identifier");
7084         }
7085 
7086         return (focusTraversalKeys != null && focusTraversalKeys[id] != null);
7087     }
7088 
7089     /**
7090      * Sets whether focus traversal keys are enabled for this Component.
7091      * Components for which focus traversal keys are disabled receive key
7092      * events for focus traversal keys. Components for which focus traversal
7093      * keys are enabled do not see these events; instead, the events are
7094      * automatically converted to traversal operations.
7095      *
7096      * @param focusTraversalKeysEnabled whether focus traversal keys are
7097      *        enabled for this Component
7098      * @see #getFocusTraversalKeysEnabled
7099      * @see #setFocusTraversalKeys
7100      * @see #getFocusTraversalKeys
7101      * @since 1.4
7102      * @beaninfo
7103      *       bound: true
7104      */
7105     public void setFocusTraversalKeysEnabled(boolean
7106                                              focusTraversalKeysEnabled) {
7107         boolean oldFocusTraversalKeysEnabled;
7108         synchronized (this) {
7109             oldFocusTraversalKeysEnabled = this.focusTraversalKeysEnabled;
7110             this.focusTraversalKeysEnabled = focusTraversalKeysEnabled;
7111         }
7112         firePropertyChange("focusTraversalKeysEnabled",
7113                            oldFocusTraversalKeysEnabled,
7114                            focusTraversalKeysEnabled);
7115     }
7116 
7117     /**
7118      * Returns whether focus traversal keys are enabled for this Component.
7119      * Components for which focus traversal keys are disabled receive key
7120      * events for focus traversal keys. Components for which focus traversal
7121      * keys are enabled do not see these events; instead, the events are
7122      * automatically converted to traversal operations.
7123      *
7124      * @return whether focus traversal keys are enabled for this Component
7125      * @see #setFocusTraversalKeysEnabled
7126      * @see #setFocusTraversalKeys
7127      * @see #getFocusTraversalKeys
7128      * @since 1.4
7129      */
7130     public boolean getFocusTraversalKeysEnabled() {
7131         return focusTraversalKeysEnabled;
7132     }
7133 
7134     /**
7135      * Requests that this Component get the input focus, and that this
7136      * Component's top-level ancestor become the focused Window. This
7137      * component must be displayable, focusable, visible and all of
7138      * its ancestors (with the exception of the top-level Window) must
7139      * be visible for the request to be granted. Every effort will be
7140      * made to honor the request; however, in some cases it may be
7141      * impossible to do so. Developers must never assume that this
7142      * Component is the focus owner until this Component receives a
7143      * FOCUS_GAINED event. If this request is denied because this
7144      * Component's top-level Window cannot become the focused Window,
7145      * the request will be remembered and will be granted when the
7146      * Window is later focused by the user.
7147      * <p>
7148      * This method cannot be used to set the focus owner to no Component at
7149      * all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner()</code>
7150      * instead.
7151      * <p>
7152      * Because the focus behavior of this method is platform-dependent,
7153      * developers are strongly encouraged to use
7154      * <code>requestFocusInWindow</code> when possible.
7155      *
7156      * <p>Note: Not all focus transfers result from invoking this method. As
7157      * such, a component may receive focus without this or any of the other
7158      * {@code requestFocus} methods of {@code Component} being invoked.
7159      *
7160      * @see #requestFocusInWindow
7161      * @see java.awt.event.FocusEvent
7162      * @see #addFocusListener
7163      * @see #isFocusable
7164      * @see #isDisplayable
7165      * @see KeyboardFocusManager#clearGlobalFocusOwner
7166      * @since JDK1.0
7167      */
7168     public void requestFocus() {
7169         requestFocusHelper(false, true);
7170     }
7171 
7172     boolean requestFocus(CausedFocusEvent.Cause cause) {
7173         return requestFocusHelper(false, true, cause);
7174     }
7175 
7176     /**
7177      * Requests that this <code>Component</code> get the input focus,
7178      * and that this <code>Component</code>'s top-level ancestor
7179      * become the focused <code>Window</code>. This component must be
7180      * displayable, focusable, visible and all of its ancestors (with
7181      * the exception of the top-level Window) must be visible for the
7182      * request to be granted. Every effort will be made to honor the
7183      * request; however, in some cases it may be impossible to do
7184      * so. Developers must never assume that this component is the
7185      * focus owner until this component receives a FOCUS_GAINED
7186      * event. If this request is denied because this component's
7187      * top-level window cannot become the focused window, the request
7188      * will be remembered and will be granted when the window is later
7189      * focused by the user.
7190      * <p>
7191      * This method returns a boolean value. If <code>false</code> is returned,
7192      * the request is <b>guaranteed to fail</b>. If <code>true</code> is
7193      * returned, the request will succeed <b>unless</b> it is vetoed, or an
7194      * extraordinary event, such as disposal of the component's peer, occurs
7195      * before the request can be granted by the native windowing system. Again,
7196      * while a return value of <code>true</code> indicates that the request is
7197      * likely to succeed, developers must never assume that this component is
7198      * the focus owner until this component receives a FOCUS_GAINED event.
7199      * <p>
7200      * This method cannot be used to set the focus owner to no component at
7201      * all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner</code>
7202      * instead.
7203      * <p>
7204      * Because the focus behavior of this method is platform-dependent,
7205      * developers are strongly encouraged to use
7206      * <code>requestFocusInWindow</code> when possible.
7207      * <p>
7208      * Every effort will be made to ensure that <code>FocusEvent</code>s
7209      * generated as a
7210      * result of this request will have the specified temporary value. However,
7211      * because specifying an arbitrary temporary state may not be implementable
7212      * on all native windowing systems, correct behavior for this method can be
7213      * guaranteed only for lightweight <code>Component</code>s.
7214      * This method is not intended
7215      * for general use, but exists instead as a hook for lightweight component
7216      * libraries, such as Swing.
7217      *
7218      * <p>Note: Not all focus transfers result from invoking this method. As
7219      * such, a component may receive focus without this or any of the other
7220      * {@code requestFocus} methods of {@code Component} being invoked.
7221      *
7222      * @param temporary true if the focus change is temporary,
7223      *        such as when the window loses the focus; for
7224      *        more information on temporary focus changes see the
7225      *<a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
7226      * @return <code>false</code> if the focus change request is guaranteed to
7227      *         fail; <code>true</code> if it is likely to succeed
7228      * @see java.awt.event.FocusEvent
7229      * @see #addFocusListener
7230      * @see #isFocusable
7231      * @see #isDisplayable
7232      * @see KeyboardFocusManager#clearGlobalFocusOwner
7233      * @since 1.4
7234      */
7235     protected boolean requestFocus(boolean temporary) {
7236         return requestFocusHelper(temporary, true);
7237     }
7238 
7239     boolean requestFocus(boolean temporary, CausedFocusEvent.Cause cause) {
7240         return requestFocusHelper(temporary, true, cause);
7241     }
7242     /**
7243      * Requests that this Component get the input focus, if this
7244      * Component's top-level ancestor is already the focused
7245      * Window. This component must be displayable, focusable, visible
7246      * and all of its ancestors (with the exception of the top-level
7247      * Window) must be visible for the request to be granted. Every
7248      * effort will be made to honor the request; however, in some
7249      * cases it may be impossible to do so. Developers must never
7250      * assume that this Component is the focus owner until this
7251      * Component receives a FOCUS_GAINED event.
7252      * <p>
7253      * This method returns a boolean value. If <code>false</code> is returned,
7254      * the request is <b>guaranteed to fail</b>. If <code>true</code> is
7255      * returned, the request will succeed <b>unless</b> it is vetoed, or an
7256      * extraordinary event, such as disposal of the Component's peer, occurs
7257      * before the request can be granted by the native windowing system. Again,
7258      * while a return value of <code>true</code> indicates that the request is
7259      * likely to succeed, developers must never assume that this Component is
7260      * the focus owner until this Component receives a FOCUS_GAINED event.
7261      * <p>
7262      * This method cannot be used to set the focus owner to no Component at
7263      * all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner()</code>
7264      * instead.
7265      * <p>
7266      * The focus behavior of this method can be implemented uniformly across
7267      * platforms, and thus developers are strongly encouraged to use this
7268      * method over <code>requestFocus</code> when possible. Code which relies
7269      * on <code>requestFocus</code> may exhibit different focus behavior on
7270      * different platforms.
7271      *
7272      * <p>Note: Not all focus transfers result from invoking this method. As
7273      * such, a component may receive focus without this or any of the other
7274      * {@code requestFocus} methods of {@code Component} being invoked.
7275      *
7276      * @return <code>false</code> if the focus change request is guaranteed to
7277      *         fail; <code>true</code> if it is likely to succeed
7278      * @see #requestFocus
7279      * @see java.awt.event.FocusEvent
7280      * @see #addFocusListener
7281      * @see #isFocusable
7282      * @see #isDisplayable
7283      * @see KeyboardFocusManager#clearGlobalFocusOwner
7284      * @since 1.4
7285      */
7286     public boolean requestFocusInWindow() {
7287         return requestFocusHelper(false, false);
7288     }
7289 
7290     boolean requestFocusInWindow(CausedFocusEvent.Cause cause) {
7291         return requestFocusHelper(false, false, cause);
7292     }
7293 
7294     /**
7295      * Requests that this <code>Component</code> get the input focus,
7296      * if this <code>Component</code>'s top-level ancestor is already
7297      * the focused <code>Window</code>.  This component must be
7298      * displayable, focusable, visible and all of its ancestors (with
7299      * the exception of the top-level Window) must be visible for the
7300      * request to be granted. Every effort will be made to honor the
7301      * request; however, in some cases it may be impossible to do
7302      * so. Developers must never assume that this component is the
7303      * focus owner until this component receives a FOCUS_GAINED event.
7304      * <p>
7305      * This method returns a boolean value. If <code>false</code> is returned,
7306      * the request is <b>guaranteed to fail</b>. If <code>true</code> is
7307      * returned, the request will succeed <b>unless</b> it is vetoed, or an
7308      * extraordinary event, such as disposal of the component's peer, occurs
7309      * before the request can be granted by the native windowing system. Again,
7310      * while a return value of <code>true</code> indicates that the request is
7311      * likely to succeed, developers must never assume that this component is
7312      * the focus owner until this component receives a FOCUS_GAINED event.
7313      * <p>
7314      * This method cannot be used to set the focus owner to no component at
7315      * all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner</code>
7316      * instead.
7317      * <p>
7318      * The focus behavior of this method can be implemented uniformly across
7319      * platforms, and thus developers are strongly encouraged to use this
7320      * method over <code>requestFocus</code> when possible. Code which relies
7321      * on <code>requestFocus</code> may exhibit different focus behavior on
7322      * different platforms.
7323      * <p>
7324      * Every effort will be made to ensure that <code>FocusEvent</code>s
7325      * generated as a
7326      * result of this request will have the specified temporary value. However,
7327      * because specifying an arbitrary temporary state may not be implementable
7328      * on all native windowing systems, correct behavior for this method can be
7329      * guaranteed only for lightweight components. This method is not intended
7330      * for general use, but exists instead as a hook for lightweight component
7331      * libraries, such as Swing.
7332      *
7333      * <p>Note: Not all focus transfers result from invoking this method. As
7334      * such, a component may receive focus without this or any of the other
7335      * {@code requestFocus} methods of {@code Component} being invoked.
7336      *
7337      * @param temporary true if the focus change is temporary,
7338      *        such as when the window loses the focus; for
7339      *        more information on temporary focus changes see the
7340      *<a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
7341      * @return <code>false</code> if the focus change request is guaranteed to
7342      *         fail; <code>true</code> if it is likely to succeed
7343      * @see #requestFocus
7344      * @see java.awt.event.FocusEvent
7345      * @see #addFocusListener
7346      * @see #isFocusable
7347      * @see #isDisplayable
7348      * @see KeyboardFocusManager#clearGlobalFocusOwner
7349      * @since 1.4
7350      */
7351     protected boolean requestFocusInWindow(boolean temporary) {
7352         return requestFocusHelper(temporary, false);
7353     }
7354 
7355     boolean requestFocusInWindow(boolean temporary, CausedFocusEvent.Cause cause) {
7356         return requestFocusHelper(temporary, false, cause);
7357     }
7358 
7359     final boolean requestFocusHelper(boolean temporary,
7360                                      boolean focusedWindowChangeAllowed) {
7361         return requestFocusHelper(temporary, focusedWindowChangeAllowed, CausedFocusEvent.Cause.UNKNOWN);
7362     }
7363 
7364     final boolean requestFocusHelper(boolean temporary,
7365                                      boolean focusedWindowChangeAllowed,
7366                                      CausedFocusEvent.Cause cause)
7367     {
7368         if (!isRequestFocusAccepted(temporary, focusedWindowChangeAllowed, cause)) {
7369             if (focusLog.isLoggable(Level.FINEST)) {
7370                 focusLog.log(Level.FINEST, "requestFocus is not accepted");
7371             }
7372             return false;
7373         }
7374 
7375         // Update most-recent map
7376         KeyboardFocusManager.setMostRecentFocusOwner(this);
7377 
7378         Component window = this;
7379         while ( (window != null) && !(window instanceof Window)) {
7380             if (!window.isVisible()) {
7381                 if (focusLog.isLoggable(Level.FINEST)) {
7382                     focusLog.log(Level.FINEST, "component is recurively invisible");
7383                 }
7384                 return false;
7385             }
7386             window = window.parent;
7387         }
7388 
7389         ComponentPeer peer = this.peer;
7390         Component heavyweight = (peer instanceof LightweightPeer)
7391             ? getNativeContainer() : this;
7392         if (heavyweight == null || !heavyweight.isVisible()) {
7393             if (focusLog.isLoggable(Level.FINEST)) {
7394                 focusLog.log(Level.FINEST, "Component is not a part of visible hierarchy");
7395             }
7396             return false;
7397         }
7398         peer = heavyweight.peer;
7399         if (peer == null) {
7400             if (focusLog.isLoggable(Level.FINEST)) {
7401                 focusLog.log(Level.FINEST, "Peer is null");
7402             }
7403             return false;
7404         }
7405 
7406         // Focus this Component
7407         long time = EventQueue.getMostRecentEventTime();
7408         boolean success = peer.requestFocus
7409             (this, temporary, focusedWindowChangeAllowed, time, cause);
7410         if (!success) {
7411             KeyboardFocusManager.getCurrentKeyboardFocusManager
7412                 (appContext).dequeueKeyEvents(time, this);
7413             if (focusLog.isLoggable(Level.FINEST)) {
7414                 focusLog.log(Level.FINEST, "Peer request failed");
7415             }
7416         } else {
7417             if (focusLog.isLoggable(Level.FINEST)) {
7418                 focusLog.log(Level.FINEST, "Pass for " + this);
7419             }
7420         }
7421         return success;
7422     }
7423 
7424     private boolean isRequestFocusAccepted(boolean temporary,
7425                                            boolean focusedWindowChangeAllowed,
7426                                            CausedFocusEvent.Cause cause)
7427     {
7428         if (!isFocusable() || !isVisible()) {
7429             if (focusLog.isLoggable(Level.FINEST)) {
7430                 focusLog.log(Level.FINEST, "Not focusable or not visible");
7431             }
7432             return false;
7433         }
7434 
7435         ComponentPeer peer = this.peer;
7436         if (peer == null) {
7437             if (focusLog.isLoggable(Level.FINEST)) {
7438                 focusLog.log(Level.FINEST, "peer is null");
7439             }
7440             return false;
7441         }
7442 
7443         Window window = getContainingWindow();
7444         if (window == null || !((Window)window).isFocusableWindow()) {
7445             if (focusLog.isLoggable(Level.FINEST)) {
7446                 focusLog.log(Level.FINEST, "Component doesn't have toplevel");
7447             }
7448             return false;
7449         }
7450 
7451         // We have passed all regular checks for focus request,
7452         // now let's call RequestFocusController and see what it says.
7453         Component focusOwner = KeyboardFocusManager.getMostRecentFocusOwner(window);
7454         if (focusOwner == null) {
7455             // sometimes most recent focus owner may be null, but focus owner is not
7456             // e.g. we reset most recent focus owner if user removes focus owner
7457             focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
7458             if (focusOwner != null && focusOwner.getContainingWindow() != window) {
7459                 focusOwner = null;
7460             }
7461         }
7462 
7463         if (focusOwner == this || focusOwner == null) {
7464             // Controller is supposed to verify focus transfers and for this it
7465             // should know both from and to components.  And it shouldn't verify
7466             // transfers from when these components are equal.
7467             if (focusLog.isLoggable(Level.FINEST)) {
7468                 focusLog.log(Level.FINEST, "focus owner is null or this");
7469             }
7470             return true;
7471         }
7472 
7473         if (CausedFocusEvent.Cause.ACTIVATION == cause) {
7474             // we shouldn't call RequestFocusController in case we are
7475             // in activation.  We do request focus on component which
7476             // has got temporary focus lost and then on component which is
7477             // most recent focus owner.  But most recent focus owner can be
7478             // changed by requestFocsuXXX() call only, so this transfer has
7479             // been already approved.
7480             if (focusLog.isLoggable(Level.FINEST)) {
7481                 focusLog.log(Level.FINEST, "cause is activation");
7482             }
7483             return true;
7484         }
7485 
7486         boolean ret = Component.requestFocusController.acceptRequestFocus(focusOwner,
7487                                                                           this,
7488                                                                           temporary,
7489                                                                           focusedWindowChangeAllowed,
7490                                                                           cause);
7491         if (focusLog.isLoggable(Level.FINEST)) {
7492             focusLog.log(Level.FINEST, "RequestFocusController returns {0}", ret);
7493         }
7494 
7495         return ret;
7496     }
7497 
7498     private static RequestFocusController requestFocusController = new DummyRequestFocusController();
7499 
7500     // Swing access this method through reflection to implement InputVerifier's functionality.
7501     // Perhaps, we should make this method public (later ;)
7502     private static class DummyRequestFocusController implements RequestFocusController {
7503         public boolean acceptRequestFocus(Component from, Component to,
7504                                           boolean temporary, boolean focusedWindowChangeAllowed,
7505                                           CausedFocusEvent.Cause cause)
7506         {
7507             return true;
7508         }
7509     };
7510 
7511     synchronized static void setRequestFocusController(RequestFocusController requestController)
7512     {
7513         if (requestController == null) {
7514             requestFocusController = new DummyRequestFocusController();
7515         } else {
7516             requestFocusController = requestController;
7517         }
7518     }
7519 
7520     /**
7521      * Returns the Container which is the focus cycle root of this Component's
7522      * focus traversal cycle. Each focus traversal cycle has only a single
7523      * focus cycle root and each Component which is not a Container belongs to
7524      * only a single focus traversal cycle. Containers which are focus cycle
7525      * roots belong to two cycles: one rooted at the Container itself, and one
7526      * rooted at the Container's nearest focus-cycle-root ancestor. For such
7527      * Containers, this method will return the Container's nearest focus-cycle-
7528      * root ancestor.
7529      *
7530      * @return this Component's nearest focus-cycle-root ancestor
7531      * @see Container#isFocusCycleRoot()
7532      * @since 1.4
7533      */
7534     public Container getFocusCycleRootAncestor() {
7535         Container rootAncestor = this.parent;
7536         while (rootAncestor != null && !rootAncestor.isFocusCycleRoot()) {
7537             rootAncestor = rootAncestor.parent;
7538         }
7539         return rootAncestor;
7540     }
7541 
7542     /**
7543      * Returns whether the specified Container is the focus cycle root of this
7544      * Component's focus traversal cycle. Each focus traversal cycle has only
7545      * a single focus cycle root and each Component which is not a Container
7546      * belongs to only a single focus traversal cycle.
7547      *
7548      * @param container the Container to be tested
7549      * @return <code>true</code> if the specified Container is a focus-cycle-
7550      *         root of this Component; <code>false</code> otherwise
7551      * @see Container#isFocusCycleRoot()
7552      * @since 1.4
7553      */
7554     public boolean isFocusCycleRoot(Container container) {
7555         Container rootAncestor = getFocusCycleRootAncestor();
7556         return (rootAncestor == container);
7557     }
7558 
7559     Container getTraversalRoot() {
7560         return getFocusCycleRootAncestor();
7561     }
7562 
7563     /**
7564      * Transfers the focus to the next component, as though this Component were
7565      * the focus owner.
7566      * @see       #requestFocus()
7567      * @since     JDK1.1
7568      */
7569     public void transferFocus() {
7570         nextFocus();
7571     }
7572 
7573     /**
7574      * @deprecated As of JDK version 1.1,
7575      * replaced by transferFocus().
7576      */
7577     @Deprecated
7578     public void nextFocus() {
7579         transferFocus(false);
7580     }
7581 
7582     boolean transferFocus(boolean clearOnFailure) {
7583         if (focusLog.isLoggable(Level.FINER)) {
7584             focusLog.finer("clearOnFailure = " + clearOnFailure);
7585         }
7586         Component toFocus = getNextFocusCandidate();
7587         boolean res = false;
7588         if (toFocus != null && !toFocus.isFocusOwner() && toFocus != this) {
7589             res = toFocus.requestFocusInWindow(CausedFocusEvent.Cause.TRAVERSAL_FORWARD);
7590         }
7591         if (clearOnFailure && !res) {
7592             if (focusLog.isLoggable(Level.FINER)) {
7593                 focusLog.finer("clear global focus owner");
7594             }
7595             KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
7596         }
7597         if (focusLog.isLoggable(Level.FINER)) {
7598             focusLog.finer("returning result: " + res);
7599         }
7600         return res;
7601     }
7602 
7603     final Component getNextFocusCandidate() {
7604         Container rootAncestor = getTraversalRoot();
7605         Component comp = this;
7606         while (rootAncestor != null &&
7607                !(rootAncestor.isShowing() && rootAncestor.canBeFocusOwner()))
7608         {
7609             comp = rootAncestor;
7610             rootAncestor = comp.getFocusCycleRootAncestor();
7611         }
7612         if (focusLog.isLoggable(Level.FINER)) {
7613             focusLog.finer("comp = " + comp + ", root = " + rootAncestor);
7614         }
7615         Component candidate = null;
7616         if (rootAncestor != null) {
7617             FocusTraversalPolicy policy = rootAncestor.getFocusTraversalPolicy();
7618             Component toFocus = policy.getComponentAfter(rootAncestor, comp);
7619             if (focusLog.isLoggable(Level.FINER)) {
7620                 focusLog.finer("component after is " + toFocus);
7621             }
7622             if (toFocus == null) {
7623                 toFocus = policy.getDefaultComponent(rootAncestor);
7624                 if (focusLog.isLoggable(Level.FINER)) {
7625                     focusLog.finer("default component is " + toFocus);
7626                 }
7627             }
7628             if (toFocus == null) {
7629                 Applet applet = EmbeddedFrame.getAppletIfAncestorOf(this);
7630                 if (applet != null) {
7631                     toFocus = applet;
7632                 }
7633             }
7634             candidate = toFocus;
7635         }
7636         if (focusLog.isLoggable(Level.FINER)) {
7637             focusLog.finer("Focus transfer candidate: " + candidate);
7638         }
7639         return candidate;
7640     }
7641 
7642     /**
7643      * Transfers the focus to the previous component, as though this Component
7644      * were the focus owner.
7645      * @see       #requestFocus()
7646      * @since     1.4
7647      */
7648     public void transferFocusBackward() {
7649         transferFocusBackward(false);
7650     }
7651 
7652     boolean transferFocusBackward(boolean clearOnFailure) {
7653         Container rootAncestor = getTraversalRoot();
7654         Component comp = this;
7655         while (rootAncestor != null &&
7656                !(rootAncestor.isShowing() && rootAncestor.canBeFocusOwner()))
7657         {
7658             comp = rootAncestor;
7659             rootAncestor = comp.getFocusCycleRootAncestor();
7660         }
7661         boolean res = false;
7662         if (rootAncestor != null) {
7663             FocusTraversalPolicy policy = rootAncestor.getFocusTraversalPolicy();
7664             Component toFocus = policy.getComponentBefore(rootAncestor, comp);
7665             if (toFocus == null) {
7666                 toFocus = policy.getDefaultComponent(rootAncestor);
7667             }
7668             if (toFocus != null) {
7669                 res = toFocus.requestFocusInWindow(CausedFocusEvent.Cause.TRAVERSAL_BACKWARD);
7670             }
7671         }
7672         if (!res) {
7673             if (focusLog.isLoggable(Level.FINER)) {
7674                 focusLog.finer("clear global focus owner");
7675             }
7676             KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
7677         }
7678         if (focusLog.isLoggable(Level.FINER)) {
7679             focusLog.finer("returning result: " + res);
7680         }
7681         return res;
7682     }
7683 
7684     /**
7685      * Transfers the focus up one focus traversal cycle. Typically, the focus
7686      * owner is set to this Component's focus cycle root, and the current focus
7687      * cycle root is set to the new focus owner's focus cycle root. If,
7688      * however, this Component's focus cycle root is a Window, then the focus
7689      * owner is set to the focus cycle root's default Component to focus, and
7690      * the current focus cycle root is unchanged.
7691      *
7692      * @see       #requestFocus()
7693      * @see       Container#isFocusCycleRoot()
7694      * @see       Container#setFocusCycleRoot(boolean)
7695      * @since     1.4
7696      */
7697     public void transferFocusUpCycle() {
7698         Container rootAncestor;
7699         for (rootAncestor = getFocusCycleRootAncestor();
7700              rootAncestor != null && !(rootAncestor.isShowing() &&
7701                                        rootAncestor.isFocusable() &&
7702                                        rootAncestor.isEnabled());
7703              rootAncestor = rootAncestor.getFocusCycleRootAncestor()) {
7704         }
7705 
7706         if (rootAncestor != null) {
7707             Container rootAncestorRootAncestor =
7708                 rootAncestor.getFocusCycleRootAncestor();
7709             KeyboardFocusManager.getCurrentKeyboardFocusManager().
7710                 setGlobalCurrentFocusCycleRoot(
7711                                                (rootAncestorRootAncestor != null)
7712                                                ? rootAncestorRootAncestor
7713                                                : rootAncestor);
7714             rootAncestor.requestFocus(CausedFocusEvent.Cause.TRAVERSAL_UP);
7715         } else {
7716             Window window = getContainingWindow();
7717 
7718             if (window != null) {
7719                 Component toFocus = window.getFocusTraversalPolicy().
7720                     getDefaultComponent(window);
7721                 if (toFocus != null) {
7722                     KeyboardFocusManager.getCurrentKeyboardFocusManager().
7723                         setGlobalCurrentFocusCycleRoot(window);
7724                     toFocus.requestFocus(CausedFocusEvent.Cause.TRAVERSAL_UP);
7725                 }
7726             }
7727         }
7728     }
7729 
7730     /**
7731      * Returns <code>true</code> if this <code>Component</code> is the
7732      * focus owner.  This method is obsolete, and has been replaced by
7733      * <code>isFocusOwner()</code>.
7734      *
7735      * @return <code>true</code> if this <code>Component</code> is the
7736      *         focus owner; <code>false</code> otherwise
7737      * @since 1.2
7738      */
7739     public boolean hasFocus() {
7740         return (KeyboardFocusManager.getCurrentKeyboardFocusManager().
7741                 getFocusOwner() == this);
7742     }
7743 
7744     /**
7745      * Returns <code>true</code> if this <code>Component</code> is the
7746      *    focus owner.
7747      *
7748      * @return <code>true</code> if this <code>Component</code> is the
7749      *     focus owner; <code>false</code> otherwise
7750      * @since 1.4
7751      */
7752     public boolean isFocusOwner() {
7753         return hasFocus();
7754     }
7755 
7756     /*
7757      * Used to disallow auto-focus-transfer on disposal of the focus owner
7758      * in the process of disposing its parent container.
7759      */
7760     private boolean autoFocusTransferOnDisposal = true;
7761 
7762     void setAutoFocusTransferOnDisposal(boolean value) {
7763         autoFocusTransferOnDisposal = value;
7764     }
7765 
7766     boolean isAutoFocusTransferOnDisposal() {
7767         return autoFocusTransferOnDisposal;
7768     }
7769 
7770     /**
7771      * Adds the specified popup menu to the component.
7772      * @param     popup the popup menu to be added to the component.
7773      * @see       #remove(MenuComponent)
7774      * @exception NullPointerException if {@code popup} is {@code null}
7775      * @since     JDK1.1
7776      */
7777     public void add(PopupMenu popup) {
7778         synchronized (getTreeLock()) {
7779             if (popup.parent != null) {
7780                 popup.parent.remove(popup);
7781             }
7782             if (popups == null) {
7783                 popups = new Vector();
7784             }
7785             popups.addElement(popup);
7786             popup.parent = this;
7787 
7788             if (peer != null) {
7789                 if (popup.peer == null) {
7790                     popup.addNotify();
7791                 }
7792             }
7793         }
7794     }
7795 
7796     /**
7797      * Removes the specified popup menu from the component.
7798      * @param     popup the popup menu to be removed
7799      * @see       #add(PopupMenu)
7800      * @since     JDK1.1
7801      */
7802     public void remove(MenuComponent popup) {
7803         synchronized (getTreeLock()) {
7804             if (popups == null) {
7805                 return;
7806             }
7807             int index = popups.indexOf(popup);
7808             if (index >= 0) {
7809                 PopupMenu pmenu = (PopupMenu)popup;
7810                 if (pmenu.peer != null) {
7811                     pmenu.removeNotify();
7812                 }
7813                 pmenu.parent = null;
7814                 popups.removeElementAt(index);
7815                 if (popups.size() == 0) {
7816                     popups = null;
7817                 }
7818             }
7819         }
7820     }
7821 
7822     /**
7823      * Returns a string representing the state of this component. This
7824      * method is intended to be used only for debugging purposes, and the
7825      * content and format of the returned string may vary between
7826      * implementations. The returned string may be empty but may not be
7827      * <code>null</code>.
7828      *
7829      * @return  a string representation of this component's state
7830      * @since     JDK1.0
7831      */
7832     protected String paramString() {
7833         String thisName = getName();
7834         String str = (thisName != null? thisName : "") + "," + x + "," + y + "," + width + "x" + height;
7835         if (!isValid()) {
7836             str += ",invalid";
7837         }
7838         if (!visible) {
7839             str += ",hidden";
7840         }
7841         if (!enabled) {
7842             str += ",disabled";
7843         }
7844         return str;
7845     }
7846 
7847     /**
7848      * Returns a string representation of this component and its values.
7849      * @return    a string representation of this component
7850      * @since     JDK1.0
7851      */
7852     public String toString() {
7853         return getClass().getName() + "[" + paramString() + "]";
7854     }
7855 
7856     /**
7857      * Prints a listing of this component to the standard system output
7858      * stream <code>System.out</code>.
7859      * @see       java.lang.System#out
7860      * @since     JDK1.0
7861      */
7862     public void list() {
7863         list(System.out, 0);
7864     }
7865 
7866     /**
7867      * Prints a listing of this component to the specified output
7868      * stream.
7869      * @param    out   a print stream
7870      * @since    JDK1.0
7871      */
7872     public void list(PrintStream out) {
7873         list(out, 0);
7874     }
7875 
7876     /**
7877      * Prints out a list, starting at the specified indentation, to the
7878      * specified print stream.
7879      * @param     out      a print stream
7880      * @param     indent   number of spaces to indent
7881      * @see       java.io.PrintStream#println(java.lang.Object)
7882      * @since     JDK1.0
7883      */
7884     public void list(PrintStream out, int indent) {
7885         for (int i = 0 ; i < indent ; i++) {
7886             out.print(" ");
7887         }
7888         out.println(this);
7889     }
7890 
7891     /**
7892      * Prints a listing to the specified print writer.
7893      * @param  out  the print writer to print to
7894      * @since JDK1.1
7895      */
7896     public void list(PrintWriter out) {
7897         list(out, 0);
7898     }
7899 
7900     /**
7901      * Prints out a list, starting at the specified indentation, to
7902      * the specified print writer.
7903      * @param out the print writer to print to
7904      * @param indent the number of spaces to indent
7905      * @see       java.io.PrintStream#println(java.lang.Object)
7906      * @since JDK1.1
7907      */
7908     public void list(PrintWriter out, int indent) {
7909         for (int i = 0 ; i < indent ; i++) {
7910             out.print(" ");
7911         }
7912         out.println(this);
7913     }
7914 
7915     /*
7916      * Fetches the native container somewhere higher up in the component
7917      * tree that contains this component.
7918      */
7919     Container getNativeContainer() {
7920         Container p = parent;
7921         while (p != null && p.peer instanceof LightweightPeer) {
7922             p = p.getParent();
7923         }
7924         return p;
7925     }
7926 
7927     /**
7928      * Adds a PropertyChangeListener to the listener list. The listener is
7929      * registered for all bound properties of this class, including the
7930      * following:
7931      * <ul>
7932      *    <li>this Component's font ("font")</li>
7933      *    <li>this Component's background color ("background")</li>
7934      *    <li>this Component's foreground color ("foreground")</li>
7935      *    <li>this Component's focusability ("focusable")</li>
7936      *    <li>this Component's focus traversal keys enabled state
7937      *        ("focusTraversalKeysEnabled")</li>
7938      *    <li>this Component's Set of FORWARD_TRAVERSAL_KEYS
7939      *        ("forwardFocusTraversalKeys")</li>
7940      *    <li>this Component's Set of BACKWARD_TRAVERSAL_KEYS
7941      *        ("backwardFocusTraversalKeys")</li>
7942      *    <li>this Component's Set of UP_CYCLE_TRAVERSAL_KEYS
7943      *        ("upCycleFocusTraversalKeys")</li>
7944      *    <li>this Component's preferred size ("preferredSize")</li>
7945      *    <li>this Component's minimum size ("minimumSize")</li>
7946      *    <li>this Component's maximum size ("maximumSize")</li>
7947      *    <li>this Component's name ("name")</li>
7948      * </ul>
7949      * Note that if this <code>Component</code> is inheriting a bound property, then no
7950      * event will be fired in response to a change in the inherited property.
7951      * <p>
7952      * If <code>listener</code> is <code>null</code>,
7953      * no exception is thrown and no action is performed.
7954      *
7955      * @param    listener  the property change listener to be added
7956      *
7957      * @see #removePropertyChangeListener
7958      * @see #getPropertyChangeListeners
7959      * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
7960      */
7961     public void addPropertyChangeListener(
7962                                                        PropertyChangeListener listener) {
7963         synchronized (getObjectLock()) {
7964             if (listener == null) {
7965                 return;
7966             }
7967             if (changeSupport == null) {
7968                 changeSupport = new PropertyChangeSupport(this);
7969             }
7970             changeSupport.addPropertyChangeListener(listener);
7971         }
7972     }
7973 
7974     /**
7975      * Removes a PropertyChangeListener from the listener list. This method
7976      * should be used to remove PropertyChangeListeners that were registered
7977      * for all bound properties of this class.
7978      * <p>
7979      * If listener is null, no exception is thrown and no action is performed.
7980      *
7981      * @param listener the PropertyChangeListener to be removed
7982      *
7983      * @see #addPropertyChangeListener
7984      * @see #getPropertyChangeListeners
7985      * @see #removePropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
7986      */
7987     public void removePropertyChangeListener(
7988                                                           PropertyChangeListener listener) {
7989         synchronized (getObjectLock()) {
7990             if (listener == null || changeSupport == null) {
7991                 return;
7992             }
7993             changeSupport.removePropertyChangeListener(listener);
7994         }
7995     }
7996 
7997     /**
7998      * Returns an array of all the property change listeners
7999      * registered on this component.
8000      *
8001      * @return all of this component's <code>PropertyChangeListener</code>s
8002      *         or an empty array if no property change
8003      *         listeners are currently registered
8004      *
8005      * @see      #addPropertyChangeListener
8006      * @see      #removePropertyChangeListener
8007      * @see      #getPropertyChangeListeners(java.lang.String)
8008      * @see      java.beans.PropertyChangeSupport#getPropertyChangeListeners
8009      * @since    1.4
8010      */
8011     public PropertyChangeListener[] getPropertyChangeListeners() {
8012         synchronized (getObjectLock()) {
8013             if (changeSupport == null) {
8014                 return new PropertyChangeListener[0];
8015             }
8016             return changeSupport.getPropertyChangeListeners();
8017         }
8018     }
8019 
8020     /**
8021      * Adds a PropertyChangeListener to the listener list for a specific
8022      * property. The specified property may be user-defined, or one of the
8023      * following:
8024      * <ul>
8025      *    <li>this Component's font ("font")</li>
8026      *    <li>this Component's background color ("background")</li>
8027      *    <li>this Component's foreground color ("foreground")</li>
8028      *    <li>this Component's focusability ("focusable")</li>
8029      *    <li>this Component's focus traversal keys enabled state
8030      *        ("focusTraversalKeysEnabled")</li>
8031      *    <li>this Component's Set of FORWARD_TRAVERSAL_KEYS
8032      *        ("forwardFocusTraversalKeys")</li>
8033      *    <li>this Component's Set of BACKWARD_TRAVERSAL_KEYS
8034      *        ("backwardFocusTraversalKeys")</li>
8035      *    <li>this Component's Set of UP_CYCLE_TRAVERSAL_KEYS
8036      *        ("upCycleFocusTraversalKeys")</li>
8037      * </ul>
8038      * Note that if this <code>Component</code> is inheriting a bound property, then no
8039      * event will be fired in response to a change in the inherited property.
8040      * <p>
8041      * If <code>propertyName</code> or <code>listener</code> is <code>null</code>,
8042      * no exception is thrown and no action is taken.
8043      *
8044      * @param propertyName one of the property names listed above
8045      * @param listener the property change listener to be added
8046      *
8047      * @see #removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
8048      * @see #getPropertyChangeListeners(java.lang.String)
8049      * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
8050      */
8051     public void addPropertyChangeListener(
8052                                                        String propertyName,
8053                                                        PropertyChangeListener listener) {
8054         synchronized (getObjectLock()) {
8055             if (listener == null) {
8056                 return;
8057             }
8058             if (changeSupport == null) {
8059                 changeSupport = new PropertyChangeSupport(this);
8060             }
8061             changeSupport.addPropertyChangeListener(propertyName, listener);
8062         }
8063     }
8064 
8065     /**
8066      * Removes a <code>PropertyChangeListener</code> from the listener
8067      * list for a specific property. This method should be used to remove
8068      * <code>PropertyChangeListener</code>s
8069      * that were registered for a specific bound property.
8070      * <p>
8071      * If <code>propertyName</code> or <code>listener</code> is <code>null</code>,
8072      * no exception is thrown and no action is taken.
8073      *
8074      * @param propertyName a valid property name
8075      * @param listener the PropertyChangeListener to be removed
8076      *
8077      * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
8078      * @see #getPropertyChangeListeners(java.lang.String)
8079      * @see #removePropertyChangeListener(java.beans.PropertyChangeListener)
8080      */
8081     public void removePropertyChangeListener(
8082                                                           String propertyName,
8083                                                           PropertyChangeListener listener) {
8084         synchronized (getObjectLock()) {
8085             if (listener == null || changeSupport == null) {
8086                 return;
8087             }
8088             changeSupport.removePropertyChangeListener(propertyName, listener);
8089         }
8090     }
8091 
8092     /**
8093      * Returns an array of all the listeners which have been associated
8094      * with the named property.
8095      *
8096      * @return all of the <code>PropertyChangeListener</code>s associated with
8097      *         the named property; if no such listeners have been added or
8098      *         if <code>propertyName</code> is <code>null</code>, an empty
8099      *         array is returned
8100      *
8101      * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
8102      * @see #removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
8103      * @see #getPropertyChangeListeners
8104      * @since 1.4
8105      */
8106     public PropertyChangeListener[] getPropertyChangeListeners(
8107                                                                             String propertyName) {
8108         synchronized (getObjectLock()) {
8109             if (changeSupport == null) {
8110                 return new PropertyChangeListener[0];
8111             }
8112             return changeSupport.getPropertyChangeListeners(propertyName);
8113         }
8114     }
8115 
8116     /**
8117      * Support for reporting bound property changes for Object properties.
8118      * This method can be called when a bound property has changed and it will
8119      * send the appropriate PropertyChangeEvent to any registered
8120      * PropertyChangeListeners.
8121      *
8122      * @param propertyName the property whose value has changed
8123      * @param oldValue the property's previous value
8124      * @param newValue the property's new value
8125      */
8126     protected void firePropertyChange(String propertyName,
8127                                       Object oldValue, Object newValue) {
8128         PropertyChangeSupport changeSupport;
8129         synchronized (getObjectLock()) {
8130             changeSupport = this.changeSupport;
8131         }
8132         if (changeSupport == null ||
8133             (oldValue != null && newValue != null && oldValue.equals(newValue))) {
8134             return;
8135         }
8136         changeSupport.firePropertyChange(propertyName, oldValue, newValue);
8137     }
8138 
8139     /**
8140      * Support for reporting bound property changes for boolean properties.
8141      * This method can be called when a bound property has changed and it will
8142      * send the appropriate PropertyChangeEvent to any registered
8143      * PropertyChangeListeners.
8144      *
8145      * @param propertyName the property whose value has changed
8146      * @param oldValue the property's previous value
8147      * @param newValue the property's new value
8148      * @since 1.4
8149      */
8150     protected void firePropertyChange(String propertyName,
8151                                       boolean oldValue, boolean newValue) {
8152         PropertyChangeSupport changeSupport = this.changeSupport;
8153         if (changeSupport == null || oldValue == newValue) {
8154             return;
8155         }
8156         changeSupport.firePropertyChange(propertyName, oldValue, newValue);
8157     }
8158 
8159     /**
8160      * Support for reporting bound property changes for integer properties.
8161      * This method can be called when a bound property has changed and it will
8162      * send the appropriate PropertyChangeEvent to any registered
8163      * PropertyChangeListeners.
8164      *
8165      * @param propertyName the property whose value has changed
8166      * @param oldValue the property's previous value
8167      * @param newValue the property's new value
8168      * @since 1.4
8169      */
8170     protected void firePropertyChange(String propertyName,
8171                                       int oldValue, int newValue) {
8172         PropertyChangeSupport changeSupport = this.changeSupport;
8173         if (changeSupport == null || oldValue == newValue) {
8174             return;
8175         }
8176         changeSupport.firePropertyChange(propertyName, oldValue, newValue);
8177     }
8178 
8179     /**
8180      * Reports a bound property change.
8181      *
8182      * @param propertyName the programmatic name of the property
8183      *          that was changed
8184      * @param oldValue the old value of the property (as a byte)
8185      * @param newValue the new value of the property (as a byte)
8186      * @see #firePropertyChange(java.lang.String, java.lang.Object,
8187      *          java.lang.Object)
8188      * @since 1.5
8189      */
8190     public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {
8191         if (changeSupport == null || oldValue == newValue) {
8192             return;
8193         }
8194         firePropertyChange(propertyName, Byte.valueOf(oldValue), Byte.valueOf(newValue));
8195     }
8196 
8197     /**
8198      * Reports a bound property change.
8199      *
8200      * @param propertyName the programmatic name of the property
8201      *          that was changed
8202      * @param oldValue the old value of the property (as a char)
8203      * @param newValue the new value of the property (as a char)
8204      * @see #firePropertyChange(java.lang.String, java.lang.Object,
8205      *          java.lang.Object)
8206      * @since 1.5
8207      */
8208     public void firePropertyChange(String propertyName, char oldValue, char newValue) {
8209         if (changeSupport == null || oldValue == newValue) {
8210             return;
8211         }
8212         firePropertyChange(propertyName, new Character(oldValue), new Character(newValue));
8213     }
8214 
8215     /**
8216      * Reports a bound property change.
8217      *
8218      * @param propertyName the programmatic name of the property
8219      *          that was changed
8220      * @param oldValue the old value of the property (as a short)
8221      * @param newValue the old value of the property (as a short)
8222      * @see #firePropertyChange(java.lang.String, java.lang.Object,
8223      *          java.lang.Object)
8224      * @since 1.5
8225      */
8226     public void firePropertyChange(String propertyName, short oldValue, short newValue) {
8227         if (changeSupport == null || oldValue == newValue) {
8228             return;
8229         }
8230         firePropertyChange(propertyName, Short.valueOf(oldValue), Short.valueOf(newValue));
8231     }
8232 
8233 
8234     /**
8235      * Reports a bound property change.
8236      *
8237      * @param propertyName the programmatic name of the property
8238      *          that was changed
8239      * @param oldValue the old value of the property (as a long)
8240      * @param newValue the new value of the property (as a long)
8241      * @see #firePropertyChange(java.lang.String, java.lang.Object,
8242      *          java.lang.Object)
8243      * @since 1.5
8244      */
8245     public void firePropertyChange(String propertyName, long oldValue, long newValue) {
8246         if (changeSupport == null || oldValue == newValue) {
8247             return;
8248         }
8249         firePropertyChange(propertyName, Long.valueOf(oldValue), Long.valueOf(newValue));
8250     }
8251 
8252     /**
8253      * Reports a bound property change.
8254      *
8255      * @param propertyName the programmatic name of the property
8256      *          that was changed
8257      * @param oldValue the old value of the property (as a float)
8258      * @param newValue the new value of the property (as a float)
8259      * @see #firePropertyChange(java.lang.String, java.lang.Object,
8260      *          java.lang.Object)
8261      * @since 1.5
8262      */
8263     public void firePropertyChange(String propertyName, float oldValue, float newValue) {
8264         if (changeSupport == null || oldValue == newValue) {
8265             return;
8266         }
8267         firePropertyChange(propertyName, Float.valueOf(oldValue), Float.valueOf(newValue));
8268     }
8269 
8270     /**
8271      * Reports a bound property change.
8272      *
8273      * @param propertyName the programmatic name of the property
8274      *          that was changed
8275      * @param oldValue the old value of the property (as a double)
8276      * @param newValue the new value of the property (as a double)
8277      * @see #firePropertyChange(java.lang.String, java.lang.Object,
8278      *          java.lang.Object)
8279      * @since 1.5
8280      */
8281     public void firePropertyChange(String propertyName, double oldValue, double newValue) {
8282         if (changeSupport == null || oldValue == newValue) {
8283             return;
8284         }
8285         firePropertyChange(propertyName, Double.valueOf(oldValue), Double.valueOf(newValue));
8286     }
8287 
8288 
8289     // Serialization support.
8290 
8291     /**
8292      * Component Serialized Data Version.
8293      *
8294      * @serial
8295      */
8296     private int componentSerializedDataVersion = 4;
8297 
8298     /**
8299      * This hack is for Swing serialization. It will invoke
8300      * the Swing package private method <code>compWriteObjectNotify</code>.
8301      */
8302     private void doSwingSerialization() {
8303         Package swingPackage = Package.getPackage("javax.swing");
8304         // For Swing serialization to correctly work Swing needs to
8305         // be notified before Component does it's serialization.  This
8306         // hack accomodates this.
8307         //
8308         // Swing classes MUST be loaded by the bootstrap class loader,
8309         // otherwise we don't consider them.
8310         for (Class klass = Component.this.getClass(); klass != null;
8311                    klass = klass.getSuperclass()) {
8312             if (klass.getPackage() == swingPackage &&
8313                       klass.getClassLoader() == null) {
8314                 final Class swingClass = klass;
8315                 // Find the first override of the compWriteObjectNotify method
8316                 Method[] methods = (Method[])AccessController.doPrivileged(
8317                                                                            new PrivilegedAction() {
8318                                                                                public Object run() {
8319                                                                                    return swingClass.getDeclaredMethods();
8320                                                                                }
8321                                                                            });
8322                 for (int counter = methods.length - 1; counter >= 0;
8323                      counter--) {
8324                     final Method method = methods[counter];
8325                     if (method.getName().equals("compWriteObjectNotify")){
8326                         // We found it, use doPrivileged to make it accessible
8327                         // to use.
8328                         AccessController.doPrivileged(new PrivilegedAction() {
8329                                 public Object run() {
8330                                     method.setAccessible(true);
8331                                     return null;
8332                                 }
8333                             });
8334                         // Invoke the method
8335                         try {
8336                             method.invoke(this, (Object[]) null);
8337                         } catch (IllegalAccessException iae) {
8338                         } catch (InvocationTargetException ite) {
8339                         }
8340                         // We're done, bail.
8341                         return;
8342                     }
8343                 }
8344             }
8345         }
8346     }
8347 
8348     /**
8349      * Writes default serializable fields to stream.  Writes
8350      * a variety of serializable listeners as optional data.
8351      * The non-serializable listeners are detected and
8352      * no attempt is made to serialize them.
8353      *
8354      * @param s the <code>ObjectOutputStream</code> to write
8355      * @serialData <code>null</code> terminated sequence of
8356      *   0 or more pairs; the pair consists of a <code>String</code>
8357      *   and an <code>Object</code>; the <code>String</code> indicates
8358      *   the type of object and is one of the following (as of 1.4):
8359      *   <code>componentListenerK</code> indicating an
8360      *     <code>ComponentListener</code> object;
8361      *   <code>focusListenerK</code> indicating an
8362      *     <code>FocusListener</code> object;
8363      *   <code>keyListenerK</code> indicating an
8364      *     <code>KeyListener</code> object;
8365      *   <code>mouseListenerK</code> indicating an
8366      *     <code>MouseListener</code> object;
8367      *   <code>mouseMotionListenerK</code> indicating an
8368      *     <code>MouseMotionListener</code> object;
8369      *   <code>inputMethodListenerK</code> indicating an
8370      *     <code>InputMethodListener</code> object;
8371      *   <code>hierarchyListenerK</code> indicating an
8372      *     <code>HierarchyListener</code> object;
8373      *   <code>hierarchyBoundsListenerK</code> indicating an
8374      *     <code>HierarchyBoundsListener</code> object;
8375      *   <code>mouseWheelListenerK</code> indicating an
8376      *     <code>MouseWheelListener</code> object
8377      * @serialData an optional <code>ComponentOrientation</code>
8378      *    (after <code>inputMethodListener</code>, as of 1.2)
8379      *
8380      * @see AWTEventMulticaster#save(java.io.ObjectOutputStream, java.lang.String, java.util.EventListener)
8381      * @see #componentListenerK
8382      * @see #focusListenerK
8383      * @see #keyListenerK
8384      * @see #mouseListenerK
8385      * @see #mouseMotionListenerK
8386      * @see #inputMethodListenerK
8387      * @see #hierarchyListenerK
8388      * @see #hierarchyBoundsListenerK
8389      * @see #mouseWheelListenerK
8390      * @see #readObject(ObjectInputStream)
8391      */
8392     private void writeObject(ObjectOutputStream s)
8393       throws IOException
8394     {
8395         doSwingSerialization();
8396 
8397         s.defaultWriteObject();
8398 
8399         AWTEventMulticaster.save(s, componentListenerK, componentListener);
8400         AWTEventMulticaster.save(s, focusListenerK, focusListener);
8401         AWTEventMulticaster.save(s, keyListenerK, keyListener);
8402         AWTEventMulticaster.save(s, mouseListenerK, mouseListener);
8403         AWTEventMulticaster.save(s, mouseMotionListenerK, mouseMotionListener);
8404         AWTEventMulticaster.save(s, inputMethodListenerK, inputMethodListener);
8405 
8406         s.writeObject(null);
8407         s.writeObject(componentOrientation);
8408 
8409         AWTEventMulticaster.save(s, hierarchyListenerK, hierarchyListener);
8410         AWTEventMulticaster.save(s, hierarchyBoundsListenerK,
8411                                  hierarchyBoundsListener);
8412         s.writeObject(null);
8413 
8414         AWTEventMulticaster.save(s, mouseWheelListenerK, mouseWheelListener);
8415         s.writeObject(null);
8416 
8417     }
8418 
8419     /**
8420      * Reads the <code>ObjectInputStream</code> and if it isn't
8421      * <code>null</code> adds a listener to receive a variety
8422      * of events fired by the component.
8423      * Unrecognized keys or values will be ignored.
8424      *
8425      * @param s the <code>ObjectInputStream</code> to read
8426      * @see #writeObject(ObjectOutputStream)
8427      */
8428     private void readObject(ObjectInputStream s)
8429       throws ClassNotFoundException, IOException
8430     {
8431         objectLock = new Object();
8432 
8433         s.defaultReadObject();
8434 
8435         appContext = AppContext.getAppContext();
8436         coalescingEnabled = checkCoalescing();
8437         if (componentSerializedDataVersion < 4) {
8438             // These fields are non-transient and rely on default
8439             // serialization. However, the default values are insufficient,
8440             // so we need to set them explicitly for object data streams prior
8441             // to 1.4.
8442             focusable = true;
8443             isFocusTraversableOverridden = FOCUS_TRAVERSABLE_UNKNOWN;
8444             initializeFocusTraversalKeys();
8445             focusTraversalKeysEnabled = true;
8446         }
8447 
8448         Object keyOrNull;
8449         while(null != (keyOrNull = s.readObject())) {
8450             String key = ((String)keyOrNull).intern();
8451 
8452             if (componentListenerK == key)
8453                 addComponentListener((ComponentListener)(s.readObject()));
8454 
8455             else if (focusListenerK == key)
8456                 addFocusListener((FocusListener)(s.readObject()));
8457 
8458             else if (keyListenerK == key)
8459                 addKeyListener((KeyListener)(s.readObject()));
8460 
8461             else if (mouseListenerK == key)
8462                 addMouseListener((MouseListener)(s.readObject()));
8463 
8464             else if (mouseMotionListenerK == key)
8465                 addMouseMotionListener((MouseMotionListener)(s.readObject()));
8466 
8467             else if (inputMethodListenerK == key)
8468                 addInputMethodListener((InputMethodListener)(s.readObject()));
8469 
8470             else // skip value for unrecognized key
8471                 s.readObject();
8472 
8473         }
8474 
8475         // Read the component's orientation if it's present
8476         Object orient = null;
8477 
8478         try {
8479             orient = s.readObject();
8480         } catch (java.io.OptionalDataException e) {
8481             // JDK 1.1 instances will not have this optional data.
8482             // e.eof will be true to indicate that there is no more
8483             // data available for this object.
8484             // If e.eof is not true, throw the exception as it
8485             // might have been caused by reasons unrelated to
8486             // componentOrientation.
8487 
8488             if (!e.eof)  {
8489                 throw (e);
8490             }
8491         }
8492 
8493         if (orient != null) {
8494             componentOrientation = (ComponentOrientation)orient;
8495         } else {
8496             componentOrientation = ComponentOrientation.UNKNOWN;
8497         }
8498 
8499         try {
8500             while(null != (keyOrNull = s.readObject())) {
8501                 String key = ((String)keyOrNull).intern();
8502 
8503                 if (hierarchyListenerK == key) {
8504                     addHierarchyListener((HierarchyListener)(s.readObject()));
8505                 }
8506                 else if (hierarchyBoundsListenerK == key) {
8507                     addHierarchyBoundsListener((HierarchyBoundsListener)
8508                                                (s.readObject()));
8509                 }
8510                 else {
8511                     // skip value for unrecognized key
8512                     s.readObject();
8513                 }
8514             }
8515         } catch (java.io.OptionalDataException e) {
8516             // JDK 1.1/1.2 instances will not have this optional data.
8517             // e.eof will be true to indicate that there is no more
8518             // data available for this object.
8519             // If e.eof is not true, throw the exception as it
8520             // might have been caused by reasons unrelated to
8521             // hierarchy and hierarchyBounds listeners.
8522 
8523             if (!e.eof)  {
8524                 throw (e);
8525             }
8526         }
8527 
8528         try {
8529             while (null != (keyOrNull = s.readObject())) {
8530                 String key = ((String)keyOrNull).intern();
8531 
8532                 if (mouseWheelListenerK == key) {
8533                     addMouseWheelListener((MouseWheelListener)(s.readObject()));
8534                 }
8535                 else {
8536                     // skip value for unrecognized key
8537                     s.readObject();
8538                 }
8539             }
8540         } catch (java.io.OptionalDataException e) {
8541             // pre-1.3 instances will not have this optional data.
8542             // e.eof will be true to indicate that there is no more
8543             // data available for this object.
8544             // If e.eof is not true, throw the exception as it
8545             // might have been caused by reasons unrelated to
8546             // mouse wheel listeners
8547 
8548             if (!e.eof)  {
8549                 throw (e);
8550             }
8551         }
8552 
8553         if (popups != null) {
8554             int npopups = popups.size();
8555             for (int i = 0 ; i < npopups ; i++) {
8556                 PopupMenu popup = (PopupMenu)popups.elementAt(i);
8557                 popup.parent = this;
8558             }
8559         }
8560     }
8561 
8562     /**
8563      * Sets the language-sensitive orientation that is to be used to order
8564      * the elements or text within this component.  Language-sensitive
8565      * <code>LayoutManager</code> and <code>Component</code>
8566      * subclasses will use this property to
8567      * determine how to lay out and draw components.
8568      * <p>
8569      * At construction time, a component's orientation is set to
8570      * <code>ComponentOrientation.UNKNOWN</code>,
8571      * indicating that it has not been specified
8572      * explicitly.  The UNKNOWN orientation behaves the same as
8573      * <code>ComponentOrientation.LEFT_TO_RIGHT</code>.
8574      * <p>
8575      * To set the orientation of a single component, use this method.
8576      * To set the orientation of an entire component
8577      * hierarchy, use
8578      * {@link #applyComponentOrientation applyComponentOrientation}.
8579      *
8580      * @see ComponentOrientation
8581      *
8582      * @author Laura Werner, IBM
8583      * @beaninfo
8584      *       bound: true
8585      */
8586     public void setComponentOrientation(ComponentOrientation o) {
8587         ComponentOrientation oldValue = componentOrientation;
8588         componentOrientation = o;
8589 
8590         // This is a bound property, so report the change to
8591         // any registered listeners.  (Cheap if there are none.)
8592         firePropertyChange("componentOrientation", oldValue, o);
8593 
8594         // This could change the preferred size of the Component.
8595         invalidateIfValid();
8596     }
8597 
8598     /**
8599      * Retrieves the language-sensitive orientation that is to be used to order
8600      * the elements or text within this component.  <code>LayoutManager</code>
8601      * and <code>Component</code>
8602      * subclasses that wish to respect orientation should call this method to
8603      * get the component's orientation before performing layout or drawing.
8604      *
8605      * @see ComponentOrientation
8606      *
8607      * @author Laura Werner, IBM
8608      */
8609     public ComponentOrientation getComponentOrientation() {
8610         return componentOrientation;
8611     }
8612 
8613     /**
8614      * Sets the <code>ComponentOrientation</code> property of this component
8615      * and all components contained within it.
8616      *
8617      * @param orientation the new component orientation of this component and
8618      *        the components contained within it.
8619      * @exception NullPointerException if <code>orientation</code> is null.
8620      * @see #setComponentOrientation
8621      * @see #getComponentOrientation
8622      * @since 1.4
8623      */
8624     public void applyComponentOrientation(ComponentOrientation orientation) {
8625         if (orientation == null) {
8626             throw new NullPointerException();
8627         }
8628         setComponentOrientation(orientation);
8629     }
8630 
8631     final boolean canBeFocusOwner() {
8632         // It is enabled, visible, focusable.
8633         if (isEnabled() && isDisplayable() && isVisible() && isFocusable()) {
8634             return true;
8635         }
8636         return false;
8637     }
8638 
8639     /**
8640      * Checks that this component meets the prerequesites to be focus owner:
8641      * - it is enabled, visible, focusable
8642      * - it's parents are all enabled and showing
8643      * - top-level window is focusable
8644      * - if focus cycle root has DefaultFocusTraversalPolicy then it also checks that this policy accepts
8645      * this component as focus owner
8646      * @since 1.5
8647      */
8648     final boolean canBeFocusOwnerRecursively() {
8649         // - it is enabled, visible, focusable
8650         if (!canBeFocusOwner()) {
8651             return false;
8652         }
8653 
8654         // - it's parents are all enabled and showing
8655         synchronized(getTreeLock()) {
8656             if (parent != null) {
8657                 return parent.canContainFocusOwner(this);
8658             }
8659         }
8660         return true;
8661     }
8662 
8663     /**
8664      * Fix the location of the HW component in a LW container hierarchy.
8665      */
8666     final void relocateComponent() {
8667         synchronized (getTreeLock()) {
8668             if (peer == null) {
8669                 return;
8670             }
8671             int nativeX = x;
8672             int nativeY = y;
8673             for (Component cont = getContainer();
8674                     cont != null && cont.isLightweight();
8675                     cont = cont.getContainer())
8676             {
8677                 nativeX += cont.x;
8678                 nativeY += cont.y;
8679             }
8680             peer.setBounds(nativeX, nativeY, width, height,
8681                     ComponentPeer.SET_LOCATION);
8682         }
8683     }
8684 
8685     /**
8686      * Returns the <code>Window</code> ancestor of the component.
8687      * @return Window ancestor of the component or component by itself if it is Window;
8688      *         null, if component is not a part of window hierarchy
8689      */
8690     Window getContainingWindow() {
8691         return SunToolkit.getContainingWindow(this);
8692     }
8693 
8694     /**
8695      * Initialize JNI field and method IDs
8696      */
8697     private static native void initIDs();
8698 
8699     /*
8700      * --- Accessibility Support ---
8701      *
8702      *  Component will contain all of the methods in interface Accessible,
8703      *  though it won't actually implement the interface - that will be up
8704      *  to the individual objects which extend Component.
8705      */
8706 
8707     AccessibleContext accessibleContext = null;
8708 
8709     /**
8710      * Gets the <code>AccessibleContext</code> associated
8711      * with this <code>Component</code>.
8712      * The method implemented by this base
8713      * class returns null.  Classes that extend <code>Component</code>
8714      * should implement this method to return the
8715      * <code>AccessibleContext</code> associated with the subclass.
8716      *
8717      *
8718      * @return the <code>AccessibleContext</code> of this
8719      *    <code>Component</code>
8720      * @since 1.3
8721      */
8722     public AccessibleContext getAccessibleContext() {
8723         return accessibleContext;
8724     }
8725 
8726     /**
8727      * Inner class of Component used to provide default support for
8728      * accessibility.  This class is not meant to be used directly by
8729      * application developers, but is instead meant only to be
8730      * subclassed by component developers.
8731      * <p>
8732      * The class used to obtain the accessible role for this object.
8733      * @since 1.3
8734      */
8735     protected abstract class AccessibleAWTComponent extends AccessibleContext
8736         implements Serializable, AccessibleComponent {
8737 
8738         private static final long serialVersionUID = 642321655757800191L;
8739 
8740         /**
8741          * Though the class is abstract, this should be called by
8742          * all sub-classes.
8743          */
8744         protected AccessibleAWTComponent() {
8745         }
8746 
8747         protected ComponentListener accessibleAWTComponentHandler = null;
8748         protected FocusListener accessibleAWTFocusHandler = null;
8749 
8750         /**
8751          * Fire PropertyChange listener, if one is registered,
8752          * when shown/hidden..
8753          * @since 1.3
8754          */
8755         protected class AccessibleAWTComponentHandler implements ComponentListener {
8756             public void componentHidden(ComponentEvent e)  {
8757                 if (accessibleContext != null) {
8758                     accessibleContext.firePropertyChange(
8759                                                          AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
8760                                                          AccessibleState.VISIBLE, null);
8761                 }
8762             }
8763 
8764             public void componentShown(ComponentEvent e)  {
8765                 if (accessibleContext != null) {
8766                     accessibleContext.firePropertyChange(
8767                                                          AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
8768                                                          null, AccessibleState.VISIBLE);
8769                 }
8770             }
8771 
8772             public void componentMoved(ComponentEvent e)  {
8773             }
8774 
8775             public void componentResized(ComponentEvent e)  {
8776             }
8777         } // inner class AccessibleAWTComponentHandler
8778 
8779 
8780         /**
8781          * Fire PropertyChange listener, if one is registered,
8782          * when focus events happen
8783          * @since 1.3
8784          */
8785         protected class AccessibleAWTFocusHandler implements FocusListener {
8786             public void focusGained(FocusEvent event) {
8787                 if (accessibleContext != null) {
8788                     accessibleContext.firePropertyChange(
8789                                                          AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
8790                                                          null, AccessibleState.FOCUSED);
8791                 }
8792             }
8793             public void focusLost(FocusEvent event) {
8794                 if (accessibleContext != null) {
8795                     accessibleContext.firePropertyChange(
8796                                                          AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
8797                                                          AccessibleState.FOCUSED, null);
8798                 }
8799             }
8800         }  // inner class AccessibleAWTFocusHandler
8801 
8802 
8803         /**
8804          * Adds a <code>PropertyChangeListener</code> to the listener list.
8805          *
8806          * @param listener  the property change listener to be added
8807          */
8808         public void addPropertyChangeListener(PropertyChangeListener listener) {
8809             if (accessibleAWTComponentHandler == null) {
8810                 accessibleAWTComponentHandler = new AccessibleAWTComponentHandler();
8811                 Component.this.addComponentListener(accessibleAWTComponentHandler);
8812             }
8813             if (accessibleAWTFocusHandler == null) {
8814                 accessibleAWTFocusHandler = new AccessibleAWTFocusHandler();
8815                 Component.this.addFocusListener(accessibleAWTFocusHandler);
8816             }
8817             super.addPropertyChangeListener(listener);
8818         }
8819 
8820         /**
8821          * Remove a PropertyChangeListener from the listener list.
8822          * This removes a PropertyChangeListener that was registered
8823          * for all properties.
8824          *
8825          * @param listener  The PropertyChangeListener to be removed
8826          */
8827         public void removePropertyChangeListener(PropertyChangeListener listener) {
8828             if (accessibleAWTComponentHandler != null) {
8829                 Component.this.removeComponentListener(accessibleAWTComponentHandler);
8830                 accessibleAWTComponentHandler = null;
8831             }
8832             if (accessibleAWTFocusHandler != null) {
8833                 Component.this.removeFocusListener(accessibleAWTFocusHandler);
8834                 accessibleAWTFocusHandler = null;
8835             }
8836             super.removePropertyChangeListener(listener);
8837         }
8838 
8839         // AccessibleContext methods
8840         //
8841         /**
8842          * Gets the accessible name of this object.  This should almost never
8843          * return <code>java.awt.Component.getName()</code>,
8844          * as that generally isn't a localized name,
8845          * and doesn't have meaning for the user.  If the
8846          * object is fundamentally a text object (e.g. a menu item), the
8847          * accessible name should be the text of the object (e.g. "save").
8848          * If the object has a tooltip, the tooltip text may also be an
8849          * appropriate String to return.
8850          *
8851          * @return the localized name of the object -- can be
8852          *         <code>null</code> if this
8853          *         object does not have a name
8854          * @see javax.accessibility.AccessibleContext#setAccessibleName
8855          */
8856         public String getAccessibleName() {
8857             return accessibleName;
8858         }
8859 
8860         /**
8861          * Gets the accessible description of this object.  This should be
8862          * a concise, localized description of what this object is - what
8863          * is its meaning to the user.  If the object has a tooltip, the
8864          * tooltip text may be an appropriate string to return, assuming
8865          * it contains a concise description of the object (instead of just
8866          * the name of the object - e.g. a "Save" icon on a toolbar that
8867          * had "save" as the tooltip text shouldn't return the tooltip
8868          * text as the description, but something like "Saves the current
8869          * text document" instead).
8870          *
8871          * @return the localized description of the object -- can be
8872          *        <code>null</code> if this object does not have a description
8873          * @see javax.accessibility.AccessibleContext#setAccessibleDescription
8874          */
8875         public String getAccessibleDescription() {
8876             return accessibleDescription;
8877         }
8878 
8879         /**
8880          * Gets the role of this object.
8881          *
8882          * @return an instance of <code>AccessibleRole</code>
8883          *      describing the role of the object
8884          * @see javax.accessibility.AccessibleRole
8885          */
8886         public AccessibleRole getAccessibleRole() {
8887             return AccessibleRole.AWT_COMPONENT;
8888         }
8889 
8890         /**
8891          * Gets the state of this object.
8892          *
8893          * @return an instance of <code>AccessibleStateSet</code>
8894          *       containing the current state set of the object
8895          * @see javax.accessibility.AccessibleState
8896          */
8897         public AccessibleStateSet getAccessibleStateSet() {
8898             return Component.this.getAccessibleStateSet();
8899         }
8900 
8901         /**
8902          * Gets the <code>Accessible</code> parent of this object.
8903          * If the parent of this object implements <code>Accessible</code>,
8904          * this method should simply return <code>getParent</code>.
8905          *
8906          * @return the <code>Accessible</code> parent of this
8907          *      object -- can be <code>null</code> if this
8908          *      object does not have an <code>Accessible</code> parent
8909          */
8910         public Accessible getAccessibleParent() {
8911             if (accessibleParent != null) {
8912                 return accessibleParent;
8913             } else {
8914                 Container parent = getParent();
8915                 if (parent instanceof Accessible) {
8916                     return (Accessible) parent;
8917                 }
8918             }
8919             return null;
8920         }
8921 
8922         /**
8923          * Gets the index of this object in its accessible parent.
8924          *
8925          * @return the index of this object in its parent; or -1 if this
8926          *    object does not have an accessible parent
8927          * @see #getAccessibleParent
8928          */
8929         public int getAccessibleIndexInParent() {
8930             return Component.this.getAccessibleIndexInParent();
8931         }
8932 
8933         /**
8934          * Returns the number of accessible children in the object.  If all
8935          * of the children of this object implement <code>Accessible</code>,
8936          * then this method should return the number of children of this object.
8937          *
8938          * @return the number of accessible children in the object
8939          */
8940         public int getAccessibleChildrenCount() {
8941             return 0; // Components don't have children
8942         }
8943 
8944         /**
8945          * Returns the nth <code>Accessible</code> child of the object.
8946          *
8947          * @param i zero-based index of child
8948          * @return the nth <code>Accessible</code> child of the object
8949          */
8950         public Accessible getAccessibleChild(int i) {
8951             return null; // Components don't have children
8952         }
8953 
8954         /**
8955          * Returns the locale of this object.
8956          *
8957          * @return the locale of this object
8958          */
8959         public Locale getLocale() {
8960             return Component.this.getLocale();
8961         }
8962 
8963         /**
8964          * Gets the <code>AccessibleComponent</code> associated
8965          * with this object if one exists.
8966          * Otherwise return <code>null</code>.
8967          *
8968          * @return the component
8969          */
8970         public AccessibleComponent getAccessibleComponent() {
8971             return this;
8972         }
8973 
8974 
8975         // AccessibleComponent methods
8976         //
8977         /**
8978          * Gets the background color of this object.
8979          *
8980          * @return the background color, if supported, of the object;
8981          *      otherwise, <code>null</code>
8982          */
8983         public Color getBackground() {
8984             return Component.this.getBackground();
8985         }
8986 
8987         /**
8988          * Sets the background color of this object.
8989          * (For transparency, see <code>isOpaque</code>.)
8990          *
8991          * @param c the new <code>Color</code> for the background
8992          * @see Component#isOpaque
8993          */
8994         public void setBackground(Color c) {
8995             Component.this.setBackground(c);
8996         }
8997 
8998         /**
8999          * Gets the foreground color of this object.
9000          *
9001          * @return the foreground color, if supported, of the object;
9002          *     otherwise, <code>null</code>
9003          */
9004         public Color getForeground() {
9005             return Component.this.getForeground();
9006         }
9007 
9008         /**
9009          * Sets the foreground color of this object.
9010          *
9011          * @param c the new <code>Color</code> for the foreground
9012          */
9013         public void setForeground(Color c) {
9014             Component.this.setForeground(c);
9015         }
9016 
9017         /**
9018          * Gets the <code>Cursor</code> of this object.
9019          *
9020          * @return the <code>Cursor</code>, if supported,
9021          *     of the object; otherwise, <code>null</code>
9022          */
9023         public Cursor getCursor() {
9024             return Component.this.getCursor();
9025         }
9026 
9027         /**
9028          * Sets the <code>Cursor</code> of this object.
9029          * <p>
9030          * The method may have no visual effect if the Java platform
9031          * implementation and/or the native system do not support
9032          * changing the mouse cursor shape.
9033          * @param cursor the new <code>Cursor</code> for the object
9034          */
9035         public void setCursor(Cursor cursor) {
9036             Component.this.setCursor(cursor);
9037         }
9038 
9039         /**
9040          * Gets the <code>Font</code> of this object.
9041          *
9042          * @return the <code>Font</code>, if supported,
9043          *    for the object; otherwise, <code>null</code>
9044          */
9045         public Font getFont() {
9046             return Component.this.getFont();
9047         }
9048 
9049         /**
9050          * Sets the <code>Font</code> of this object.
9051          *
9052          * @param f the new <code>Font</code> for the object
9053          */
9054         public void setFont(Font f) {
9055             Component.this.setFont(f);
9056         }
9057 
9058         /**
9059          * Gets the <code>FontMetrics</code> of this object.
9060          *
9061          * @param f the <code>Font</code>
9062          * @return the <code>FontMetrics</code>, if supported,
9063          *     the object; otherwise, <code>null</code>
9064          * @see #getFont
9065          */
9066         public FontMetrics getFontMetrics(Font f) {
9067             if (f == null) {
9068                 return null;
9069             } else {
9070                 return Component.this.getFontMetrics(f);
9071             }
9072         }
9073 
9074         /**
9075          * Determines if the object is enabled.
9076          *
9077          * @return true if object is enabled; otherwise, false
9078          */
9079         public boolean isEnabled() {
9080             return Component.this.isEnabled();
9081         }
9082 
9083         /**
9084          * Sets the enabled state of the object.
9085          *
9086          * @param b if true, enables this object; otherwise, disables it
9087          */
9088         public void setEnabled(boolean b) {
9089             boolean old = Component.this.isEnabled();
9090             Component.this.setEnabled(b);
9091             if (b != old) {
9092                 if (accessibleContext != null) {
9093                     if (b) {
9094                         accessibleContext.firePropertyChange(
9095                                                              AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
9096                                                              null, AccessibleState.ENABLED);
9097                     } else {
9098                         accessibleContext.firePropertyChange(
9099                                                              AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
9100                                                              AccessibleState.ENABLED, null);
9101                     }
9102                 }
9103             }
9104         }
9105 
9106         /**
9107          * Determines if the object is visible.  Note: this means that the
9108          * object intends to be visible; however, it may not in fact be
9109          * showing on the screen because one of the objects that this object
9110          * is contained by is not visible.  To determine if an object is
9111          * showing on the screen, use <code>isShowing</code>.
9112          *
9113          * @return true if object is visible; otherwise, false
9114          */
9115         public boolean isVisible() {
9116             return Component.this.isVisible();
9117         }
9118 
9119         /**
9120          * Sets the visible state of the object.
9121          *
9122          * @param b if true, shows this object; otherwise, hides it
9123          */
9124         public void setVisible(boolean b) {
9125             boolean old = Component.this.isVisible();
9126             Component.this.setVisible(b);
9127             if (b != old) {
9128                 if (accessibleContext != null) {
9129                     if (b) {
9130                         accessibleContext.firePropertyChange(
9131                                                              AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
9132                                                              null, AccessibleState.VISIBLE);
9133                     } else {
9134                         accessibleContext.firePropertyChange(
9135                                                              AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
9136                                                              AccessibleState.VISIBLE, null);
9137                     }
9138                 }
9139             }
9140         }
9141 
9142         /**
9143          * Determines if the object is showing.  This is determined by checking
9144          * the visibility of the object and ancestors of the object.  Note:
9145          * this will return true even if the object is obscured by another
9146          * (for example, it happens to be underneath a menu that was pulled
9147          * down).
9148          *
9149          * @return true if object is showing; otherwise, false
9150          */
9151         public boolean isShowing() {
9152             return Component.this.isShowing();
9153         }
9154 
9155         /**
9156          * Checks whether the specified point is within this object's bounds,
9157          * where the point's x and y coordinates are defined to be relative to
9158          * the coordinate system of the object.
9159          *
9160          * @param p the <code>Point</code> relative to the
9161          *     coordinate system of the object
9162          * @return true if object contains <code>Point</code>; otherwise false
9163          */
9164         public boolean contains(Point p) {
9165             return Component.this.contains(p);
9166         }
9167 
9168         /**
9169          * Returns the location of the object on the screen.
9170          *
9171          * @return location of object on screen -- can be
9172          *    <code>null</code> if this object is not on the screen
9173          */
9174         public Point getLocationOnScreen() {
9175             synchronized (Component.this.getTreeLock()) {
9176                 if (Component.this.isShowing()) {
9177                     return Component.this.getLocationOnScreen();
9178                 } else {
9179                     return null;
9180                 }
9181             }
9182         }
9183 
9184         /**
9185          * Gets the location of the object relative to the parent in the form
9186          * of a point specifying the object's top-left corner in the screen's
9187          * coordinate space.
9188          *
9189          * @return an instance of Point representing the top-left corner of
9190          * the object's bounds in the coordinate space of the screen;
9191          * <code>null</code> if this object or its parent are not on the screen
9192          */
9193         public Point getLocation() {
9194             return Component.this.getLocation();
9195         }
9196 
9197         /**
9198          * Sets the location of the object relative to the parent.
9199          * @param p  the coordinates of the object
9200          */
9201         public void setLocation(Point p) {
9202             Component.this.setLocation(p);
9203         }
9204 
9205         /**
9206          * Gets the bounds of this object in the form of a Rectangle object.
9207          * The bounds specify this object's width, height, and location
9208          * relative to its parent.
9209          *
9210          * @return a rectangle indicating this component's bounds;
9211          *   <code>null</code> if this object is not on the screen
9212          */
9213         public Rectangle getBounds() {
9214             return Component.this.getBounds();
9215         }
9216 
9217         /**
9218          * Sets the bounds of this object in the form of a
9219          * <code>Rectangle</code> object.
9220          * The bounds specify this object's width, height, and location
9221          * relative to its parent.
9222          *
9223          * @param r a rectangle indicating this component's bounds
9224          */
9225         public void setBounds(Rectangle r) {
9226             Component.this.setBounds(r);
9227         }
9228 
9229         /**
9230          * Returns the size of this object in the form of a
9231          * <code>Dimension</code> object. The height field of the
9232          * <code>Dimension</code> object contains this objects's
9233          * height, and the width field of the <code>Dimension</code>
9234          * object contains this object's width.
9235          *
9236          * @return a <code>Dimension</code> object that indicates
9237          *     the size of this component; <code>null</code> if
9238          *     this object is not on the screen
9239          */
9240         public Dimension getSize() {
9241             return Component.this.getSize();
9242         }
9243 
9244         /**
9245          * Resizes this object so that it has width and height.
9246          *
9247          * @param d - the dimension specifying the new size of the object
9248          */
9249         public void setSize(Dimension d) {
9250             Component.this.setSize(d);
9251         }
9252 
9253         /**
9254          * Returns the <code>Accessible</code> child,
9255          * if one exists, contained at the local
9256          * coordinate <code>Point</code>.  Otherwise returns
9257          * <code>null</code>.
9258          *
9259          * @param p the point defining the top-left corner of
9260          *      the <code>Accessible</code>, given in the
9261          *      coordinate space of the object's parent
9262          * @return the <code>Accessible</code>, if it exists,
9263          *      at the specified location; else <code>null</code>
9264          */
9265         public Accessible getAccessibleAt(Point p) {
9266             return null; // Components don't have children
9267         }
9268 
9269         /**
9270          * Returns whether this object can accept focus or not.
9271          *
9272          * @return true if object can accept focus; otherwise false
9273          */
9274         public boolean isFocusTraversable() {
9275             return Component.this.isFocusTraversable();
9276         }
9277 
9278         /**
9279          * Requests focus for this object.
9280          */
9281         public void requestFocus() {
9282             Component.this.requestFocus();
9283         }
9284 
9285         /**
9286          * Adds the specified focus listener to receive focus events from this
9287          * component.
9288          *
9289          * @param l the focus listener
9290          */
9291         public void addFocusListener(FocusListener l) {
9292             Component.this.addFocusListener(l);
9293         }
9294 
9295         /**
9296          * Removes the specified focus listener so it no longer receives focus
9297          * events from this component.
9298          *
9299          * @param l the focus listener
9300          */
9301         public void removeFocusListener(FocusListener l) {
9302             Component.this.removeFocusListener(l);
9303         }
9304 
9305     } // inner class AccessibleAWTComponent
9306 
9307 
9308     /**
9309      * Gets the index of this object in its accessible parent.
9310      * If this object does not have an accessible parent, returns
9311      * -1.
9312      *
9313      * @return the index of this object in its accessible parent
9314      */
9315     int getAccessibleIndexInParent() {
9316         synchronized (getTreeLock()) {
9317             int index = -1;
9318             Container parent = this.getParent();
9319             if (parent != null && parent instanceof Accessible) {
9320                 Component ca[] = parent.getComponents();
9321                 for (int i = 0; i < ca.length; i++) {
9322                     if (ca[i] instanceof Accessible) {
9323                         index++;
9324                     }
9325                     if (this.equals(ca[i])) {
9326                         return index;
9327                     }
9328                 }
9329             }
9330             return -1;
9331         }
9332     }
9333 
9334     /**
9335      * Gets the current state set of this object.
9336      *
9337      * @return an instance of <code>AccessibleStateSet</code>
9338      *    containing the current state set of the object
9339      * @see AccessibleState
9340      */
9341     AccessibleStateSet getAccessibleStateSet() {
9342         synchronized (getTreeLock()) {
9343             AccessibleStateSet states = new AccessibleStateSet();
9344             if (this.isEnabled()) {
9345                 states.add(AccessibleState.ENABLED);
9346             }
9347             if (this.isFocusTraversable()) {
9348                 states.add(AccessibleState.FOCUSABLE);
9349             }
9350             if (this.isVisible()) {
9351                 states.add(AccessibleState.VISIBLE);
9352             }
9353             if (this.isShowing()) {
9354                 states.add(AccessibleState.SHOWING);
9355             }
9356             if (this.isFocusOwner()) {
9357                 states.add(AccessibleState.FOCUSED);
9358             }
9359             if (this instanceof Accessible) {
9360                 AccessibleContext ac = ((Accessible) this).getAccessibleContext();
9361                 if (ac != null) {
9362                     Accessible ap = ac.getAccessibleParent();
9363                     if (ap != null) {
9364                         AccessibleContext pac = ap.getAccessibleContext();
9365                         if (pac != null) {
9366                             AccessibleSelection as = pac.getAccessibleSelection();
9367                             if (as != null) {
9368                                 states.add(AccessibleState.SELECTABLE);
9369                                 int i = ac.getAccessibleIndexInParent();
9370                                 if (i >= 0) {
9371                                     if (as.isAccessibleChildSelected(i)) {
9372                                         states.add(AccessibleState.SELECTED);
9373                                     }
9374                                 }
9375                             }
9376                         }
9377                     }
9378                 }
9379             }
9380             if (Component.isInstanceOf(this, "javax.swing.JComponent")) {
9381                 if (((javax.swing.JComponent) this).isOpaque()) {
9382                     states.add(AccessibleState.OPAQUE);
9383                 }
9384             }
9385             return states;
9386         }
9387     }
9388 
9389     /**
9390      * Checks that the given object is instance of the given class.
9391      * @param obj Object to be checked
9392      * @param className The name of the class. Must be fully-qualified class name.
9393      * @return true, if this object is instanceof given class,
9394      *         false, otherwise, or if obj or className is null
9395      */
9396     static boolean isInstanceOf(Object obj, String className) {
9397         if (obj == null) return false;
9398         if (className == null) return false;
9399 
9400         Class cls = obj.getClass();
9401         while (cls != null) {
9402             if (cls.getName().equals(className)) {
9403                 return true;
9404             }
9405             cls = cls.getSuperclass();
9406         }
9407         return false;
9408     }
9409 
9410 
9411     // ************************** MIXING CODE *******************************
9412 
9413     /**
9414      * Check whether we can trust the current bounds of the component.
9415      * The return value of false indicates that the container of the
9416      * component is invalid, and therefore needs to be layed out, which would
9417      * probably mean changing the bounds of its children.
9418      * Null-layout of the container or absence of the container mean
9419      * the bounds of the component are final and can be trusted.
9420      */
9421     final boolean areBoundsValid() {
9422         Container cont = getContainer();
9423         return cont == null || cont.isValid() || cont.getLayout() == null;
9424     }
9425 
9426     /**
9427      * Applies the shape to the component
9428      * @param shape Shape to be applied to the component
9429      */
9430     void applyCompoundShape(Region shape) {
9431         checkTreeLock();
9432 
9433         if (!areBoundsValid()) {
9434             if (mixingLog.isLoggable(Level.FINE)) {
9435                 mixingLog.fine("this = " + this + "; areBoundsValid = " + areBoundsValid());
9436             }
9437             return;
9438         }
9439 
9440         if (!isLightweight()) {
9441             ComponentPeer peer = getPeer();
9442             if (peer != null) {
9443                 // The Region class has some optimizations. That's why
9444                 // we should manually check whether it's empty and
9445                 // substitute the object ourselves. Otherwise we end up
9446                 // with some incorrect Region object with loX being
9447                 // greater than the hiX for instance.
9448                 if (shape.isEmpty()) {
9449                     shape = Region.EMPTY_REGION;
9450                 }
9451 
9452 
9453                 // Note: the shape is not really copied/cloned. We create
9454                 // the Region object ourselves, so there's no any possibility
9455                 // to modify the object outside of the mixing code.
9456                 // Nullifying compoundShape means that the component has normal shape
9457                 // (or has no shape at all).
9458                 if (shape.equals(getNormalShape())) {
9459                     if (this.compoundShape == null) {
9460                         return;
9461                     }
9462                     this.compoundShape = null;
9463                     peer.applyShape(null);
9464                 } else {
9465                     if (shape.equals(getAppliedShape())) {
9466                         return;
9467                     }
9468                     this.compoundShape = shape;
9469                     Point compAbsolute = getLocationOnWindow();
9470                     if (mixingLog.isLoggable(Level.FINER)) {
9471                         mixingLog.fine("this = " + this +
9472                                 "; compAbsolute=" + compAbsolute + "; shape=" + shape);
9473                     }
9474                     peer.applyShape(shape.getTranslatedRegion(-compAbsolute.x, -compAbsolute.y));
9475                 }
9476             }
9477         }
9478     }
9479 
9480     /**
9481      * Returns the shape previously set with applyCompoundShape().
9482      * If the component is LW or no shape was applied yet,
9483      * the method returns the normal shape.
9484      */
9485     private Region getAppliedShape() {
9486         checkTreeLock();
9487         //XXX: if we allow LW components to have a shape, this must be changed
9488         return (this.compoundShape == null || isLightweight()) ? getNormalShape() : this.compoundShape;
9489     }
9490 
9491     Point getLocationOnWindow() {
9492         checkTreeLock();
9493         Point curLocation = getLocation();
9494 
9495         for (Container parent = getContainer();
9496                 parent != null && !(parent instanceof Window);
9497                 parent = parent.getContainer())
9498         {
9499             curLocation.x += parent.getX();
9500             curLocation.y += parent.getY();
9501         }
9502 
9503         return curLocation;
9504     }
9505 
9506     /**
9507      * Returns the full shape of the component located in window coordinates
9508      */
9509     final Region getNormalShape() {
9510         checkTreeLock();
9511         //XXX: we may take into account a user-specified shape for this component
9512         Point compAbsolute = getLocationOnWindow();
9513         return
9514             Region.getInstanceXYWH(
9515                     compAbsolute.x,
9516                     compAbsolute.y,
9517                     getWidth(),
9518                     getHeight()
9519             );
9520     }
9521 
9522     /**
9523      * Returns the "opaque shape" of the component.
9524      *
9525      * The opaque shape of a lightweight components is the actual shape that
9526      * needs to be cut off of the heavyweight components in order to mix this
9527      * lightweight component correctly with them.
9528      *
9529      * The method is overriden in the java.awt.Container to handle non-opaque
9530      * containers containing opaque children.
9531      *
9532      * See 6637655 for details.
9533      */
9534     Region getOpaqueShape() {
9535         checkTreeLock();
9536         if (mixingCutoutRegion != null) {
9537             return mixingCutoutRegion;
9538         } else {
9539             return getNormalShape();
9540         }
9541     }
9542 
9543     final int getSiblingIndexAbove() {
9544         checkTreeLock();
9545         Container parent = getContainer();
9546         if (parent == null) {
9547             return -1;
9548         }
9549 
9550         int nextAbove = parent.getComponentZOrder(this) - 1;
9551 
9552         return nextAbove < 0 ? -1 : nextAbove;
9553     }
9554 
9555     final ComponentPeer getHWPeerAboveMe() {
9556         checkTreeLock();
9557 
9558         Container cont = getContainer();
9559         int indexAbove = getSiblingIndexAbove();
9560 
9561         while (cont != null) {
9562             for (int i = indexAbove; i > -1; i--) {
9563                 Component comp = cont.getComponent(i);
9564                 if (comp != null && comp.isDisplayable() && !comp.isLightweight()) {
9565                     return comp.getPeer();
9566                 }
9567             }
9568 
9569             indexAbove = cont.getSiblingIndexAbove();
9570             cont = cont.getContainer();
9571         }
9572 
9573         return null;
9574     }
9575 
9576     final int getSiblingIndexBelow() {
9577         checkTreeLock();
9578         Container parent = getContainer();
9579         if (parent == null) {
9580             return -1;
9581         }
9582 
9583         int nextBelow = parent.getComponentZOrder(this) + 1;
9584 
9585         return nextBelow >= parent.getComponentCount() ? -1 : nextBelow;
9586     }
9587 
9588     final boolean isNonOpaqueForMixing() {
9589         return mixingCutoutRegion != null &&
9590             mixingCutoutRegion.isEmpty();
9591     }
9592 
9593     private Region calculateCurrentShape() {
9594         checkTreeLock();
9595         Region s = getNormalShape();
9596 
9597         if (mixingLog.isLoggable(Level.FINE)) {
9598             mixingLog.fine("this = " + this + "; normalShape=" + s);
9599         }
9600 
9601         if (getContainer() != null) {
9602             Component comp = this;
9603             Container cont = comp.getContainer();
9604 
9605             while (cont != null) {
9606                 for (int index = comp.getSiblingIndexAbove(); index != -1; --index) {
9607                     /* It is assumed that:
9608                      *
9609                      *    getComponent(getContainer().getComponentZOrder(comp)) == comp
9610                      *
9611                      * The assumption has been made according to the current
9612                      * implementation of the Container class.
9613                      */
9614                     Component c = cont.getComponent(index);
9615                     if (c.isLightweight() && c.isShowing()) {
9616                         s = s.getDifference(c.getOpaqueShape());
9617                     }
9618                 }
9619 
9620                 if (cont.isLightweight()) {
9621                     s = s.getIntersection(cont.getNormalShape());
9622                 } else {
9623                     break;
9624                 }
9625 
9626                 comp = cont;
9627                 cont = cont.getContainer();
9628             }
9629         }
9630 
9631         if (mixingLog.isLoggable(Level.FINE)) {
9632             mixingLog.fine("currentShape=" + s);
9633         }
9634 
9635         return s;
9636     }
9637 
9638     void applyCurrentShape() {
9639         checkTreeLock();
9640         if (!areBoundsValid()) {
9641             if (mixingLog.isLoggable(Level.FINE)) {
9642                 mixingLog.fine("this = " + this + "; areBoundsValid = " + areBoundsValid());
9643             }
9644             return; // Because applyCompoundShape() ignores such components anyway
9645         }
9646         if (mixingLog.isLoggable(Level.FINE)) {
9647             mixingLog.fine("this = " + this);
9648         }
9649         applyCompoundShape(calculateCurrentShape());
9650     }
9651 
9652     final void subtractAndApplyShape(Region s) {
9653         checkTreeLock();
9654 
9655         if (mixingLog.isLoggable(Level.FINE)) {
9656             mixingLog.fine("this = " + this + "; s=" + s);
9657         }
9658 
9659         applyCompoundShape(getAppliedShape().getDifference(s));
9660     }
9661 
9662     private final void applyCurrentShapeBelowMe() {
9663         checkTreeLock();
9664         Container parent = getContainer();
9665         if (parent != null && parent.isShowing()) {
9666             // First, reapply shapes of my siblings
9667             parent.recursiveApplyCurrentShape(getSiblingIndexBelow());
9668 
9669             // Second, if my container is non-opaque, reapply shapes of siblings of my container
9670             Container parent2 = parent.getContainer();
9671             while (!parent.isOpaque() && parent2 != null) {
9672                 parent2.recursiveApplyCurrentShape(parent.getSiblingIndexBelow());
9673 
9674                 parent = parent2;
9675                 parent2 = parent.getContainer();
9676             }
9677         }
9678     }
9679 
9680     final void subtractAndApplyShapeBelowMe() {
9681         checkTreeLock();
9682         Container parent = getContainer();
9683         if (parent != null && isShowing()) {
9684             Region opaqueShape = getOpaqueShape();
9685 
9686             // First, cut my siblings
9687             parent.recursiveSubtractAndApplyShape(opaqueShape, getSiblingIndexBelow());
9688 
9689             // Second, if my container is non-opaque, cut siblings of my container
9690             Container parent2 = parent.getContainer();
9691             while (!parent.isOpaque() && parent2 != null) {
9692                 parent2.recursiveSubtractAndApplyShape(opaqueShape, parent.getSiblingIndexBelow());
9693 
9694                 parent = parent2;
9695                 parent2 = parent.getContainer();
9696             }
9697         }
9698     }
9699 
9700     void mixOnShowing() {
9701         synchronized (getTreeLock()) {
9702             if (mixingLog.isLoggable(Level.FINE)) {
9703                 mixingLog.fine("this = " + this);
9704             }
9705             if (!isMixingNeeded()) {
9706                 return;
9707             }
9708             if (isLightweight()) {
9709                 subtractAndApplyShapeBelowMe();
9710             } else {
9711                 applyCurrentShape();
9712             }
9713         }
9714     }
9715 
9716     void mixOnHiding(boolean isLightweight) {
9717         // We cannot be sure that the peer exists at this point, so we need the argument
9718         //    to find out whether the hiding component is (well, actually was) a LW or a HW.
9719         synchronized (getTreeLock()) {
9720             if (mixingLog.isLoggable(Level.FINE)) {
9721                 mixingLog.fine("this = " + this + "; isLightweight = " + isLightweight);
9722             }
9723             if (!isMixingNeeded()) {
9724                 return;
9725             }
9726             if (isLightweight) {
9727                 applyCurrentShapeBelowMe();
9728             }
9729         }
9730     }
9731 
9732     void mixOnReshaping() {
9733         synchronized (getTreeLock()) {
9734             if (mixingLog.isLoggable(Level.FINE)) {
9735                 mixingLog.fine("this = " + this);
9736             }
9737             if (!isMixingNeeded()) {
9738                 return;
9739             }
9740             if (isLightweight()) {
9741                 applyCurrentShapeBelowMe();
9742             } else {
9743                 applyCurrentShape();
9744             }
9745         }
9746     }
9747 
9748     void mixOnZOrderChanging(int oldZorder, int newZorder) {
9749         synchronized (getTreeLock()) {
9750             boolean becameHigher = newZorder < oldZorder;
9751             Container parent = getContainer();
9752 
9753             if (mixingLog.isLoggable(Level.FINE)) {
9754                 mixingLog.fine("this = " + this +
9755                     "; oldZorder=" + oldZorder + "; newZorder=" + newZorder + "; parent=" + parent);
9756             }
9757             if (!isMixingNeeded()) {
9758                 return;
9759             }
9760             if (isLightweight()) {
9761                 if (becameHigher) {
9762                     if (parent != null && isShowing()) {
9763                         parent.recursiveSubtractAndApplyShape(getOpaqueShape(), getSiblingIndexBelow(), oldZorder);
9764                     }
9765                 } else {
9766                     if (parent != null) {
9767                         parent.recursiveApplyCurrentShape(oldZorder, newZorder);
9768                     }
9769                 }
9770             } else {
9771                 if (becameHigher) {
9772                     applyCurrentShape();
9773                 } else {
9774                     if (parent != null) {
9775                         Region shape = getAppliedShape();
9776 
9777                         for (int index = oldZorder; index < newZorder; index++) {
9778                             Component c = parent.getComponent(index);
9779                             if (c.isLightweight() && c.isShowing()) {
9780                                 shape = shape.getDifference(c.getOpaqueShape());
9781                             }
9782                         }
9783                         applyCompoundShape(shape);
9784                     }
9785                 }
9786             }
9787         }
9788     }
9789 
9790     void mixOnValidating() {
9791         // This method gets overriden in the Container. Obviously, a plain
9792         // non-container components don't need to handle validation.
9793     }
9794 
9795     final boolean isMixingNeeded() {
9796         if (SunToolkit.getSunAwtDisableMixing()) {
9797             if (mixingLog.isLoggable(Level.FINEST)) {
9798                 mixingLog.finest("this = " + this + "; Mixing disabled via sun.awt.disableMixing");
9799             }
9800             return false;
9801         }
9802         if (!areBoundsValid()) {
9803             if (mixingLog.isLoggable(Level.FINE)) {
9804                 mixingLog.fine("this = " + this + "; areBoundsValid = " + areBoundsValid());
9805             }
9806             return false;
9807         }
9808         Window window = getContainingWindow();
9809         if (window != null) {
9810             if (!window.hasHeavyweightDescendants() || !window.hasLightweightDescendants()) {
9811                 if (mixingLog.isLoggable(Level.FINE)) {
9812                     mixingLog.fine("containing window = " + window +
9813                             "; has h/w descendants = " + window.hasHeavyweightDescendants() +
9814                             "; has l/w descendants = " + window.hasLightweightDescendants());
9815                 }
9816                 return false;
9817             }
9818         } else {
9819             if (mixingLog.isLoggable(Level.FINE)) {
9820                 mixingLog.finest("this = " + this + "; containing window is null");
9821             }
9822             return false;
9823         }
9824         return true;
9825     }
9826 
9827     // ****************** END OF MIXING CODE ********************************
9828 
9829     private static boolean doesClassImplement(Class cls, String interfaceName) {
9830         if (cls == null) return false;
9831 
9832         for (Class c : cls.getInterfaces()) {
9833             if (c.getName().equals(interfaceName)) {
9834                 return true;
9835             }
9836         }
9837         return doesClassImplement(cls.getSuperclass(), interfaceName);
9838     }
9839 
9840     /**
9841      * Checks that the given object implements the given interface.
9842      * @param obj Object to be checked
9843      * @param interfaceName The name of the interface. Must be fully-qualified interface name.
9844      * @return true, if this object implements the given interface,
9845      *         false, otherwise, or if obj or interfaceName is null
9846      */
9847     static boolean doesImplement(Object obj, String interfaceName) {
9848         if (obj == null) return false;
9849         if (interfaceName == null) return false;
9850 
9851         return doesClassImplement(obj.getClass(), interfaceName);
9852     }
9853 
9854     // Note that the method is overriden in the Window class,
9855     // a window doesn't need to be updated in the Z-order.
9856     void updateZOrder() {
9857         peer.setZOrder(getHWPeerAboveMe());
9858     }
9859 
9860 }