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