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 void requestFocus(Component comp, FocusEvent.Cause cause) {
 855                 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         @SuppressWarnings("deprecation")
4020         protected FlipBufferStrategy(int numBuffers, BufferCapabilities caps)
4021             throws AWTException
4022         {
4023             if (!(Component.this instanceof Window) &&
4024                 !(Component.this instanceof Canvas) &&
4025                 !(Component.this instanceof Applet))
4026             {
4027                 throw new ClassCastException(
4028                         "Component must be a Canvas or Window or Applet");
4029             }
4030             this.numBuffers = numBuffers;
4031             this.caps = caps;
4032             createBuffers(numBuffers, caps);
4033         }
4034 
4035         /**
4036          * Creates one or more complex, flipping buffers with the given
4037          * capabilities.
4038          * @param numBuffers number of buffers to create; must be greater than
4039          * one
4040          * @param caps the capabilities of the buffers.
4041          * {@code BufferCapabilities.isPageFlipping} must be
4042          * {@code true}.
4043          * @exception AWTException if the capabilities supplied could not be
4044          * supported or met
4045          * @exception IllegalStateException if the component has no peer
4046          * @exception IllegalArgumentException if numBuffers is less than two,
4047          * or if {@code BufferCapabilities.isPageFlipping} is not
4048          * {@code true}.
4049          * @see java.awt.BufferCapabilities#isPageFlipping()
4050          */
4051         protected void createBuffers(int numBuffers, BufferCapabilities caps)
4052             throws AWTException
4053         {
4054             if (numBuffers < 2) {
4055                 throw new IllegalArgumentException(
4056                     "Number of buffers cannot be less than two");
4057             } else if (peer == null) {
4058                 throw new IllegalStateException(
4059                     "Component must have a valid peer");
4060             } else if (caps == null || !caps.isPageFlipping()) {
4061                 throw new IllegalArgumentException(
4062                     "Page flipping capabilities must be specified");
4063             }
4064 
4065             // save the current bounds
4066             width = getWidth();
4067             height = getHeight();
4068 
4069             if (drawBuffer != null) {
4070                 // dispose the existing backbuffers
4071                 drawBuffer = null;
4072                 drawVBuffer = null;
4073                 destroyBuffers();
4074                 // ... then recreate the backbuffers
4075             }
4076 
4077             if (caps instanceof ExtendedBufferCapabilities) {
4078                 ExtendedBufferCapabilities ebc =
4079                     (ExtendedBufferCapabilities)caps;
4080                 if (ebc.getVSync() == VSYNC_ON) {
4081                     // if this buffer strategy is not allowed to be v-synced,
4082                     // change the caps that we pass to the peer but keep on
4083                     // trying to create v-synced buffers;
4084                     // do not throw IAE here in case it is disallowed, see
4085                     // ExtendedBufferCapabilities for more info
4086                     if (!VSyncedBSManager.vsyncAllowed(this)) {
4087                         caps = ebc.derive(VSYNC_DEFAULT);
4088                     }
4089                 }
4090             }
4091 
4092             peer.createBuffers(numBuffers, caps);
4093             updateInternalBuffers();
4094         }
4095 
4096         /**
4097          * Updates internal buffers (both volatile and non-volatile)
4098          * by requesting the back-buffer from the peer.
4099          */
4100         private void updateInternalBuffers() {
4101             // get the images associated with the draw buffer
4102             drawBuffer = getBackBuffer();
4103             if (drawBuffer instanceof VolatileImage) {
4104                 drawVBuffer = (VolatileImage)drawBuffer;
4105             } else {
4106                 drawVBuffer = null;
4107             }
4108         }
4109 
4110         /**
4111          * @return direct access to the back buffer, as an image.
4112          * @exception IllegalStateException if the buffers have not yet
4113          * been created
4114          */
4115         protected Image getBackBuffer() {
4116             if (peer != null) {
4117                 return peer.getBackBuffer();
4118             } else {
4119                 throw new IllegalStateException(
4120                     "Component must have a valid peer");
4121             }
4122         }
4123 
4124         /**
4125          * Flipping moves the contents of the back buffer to the front buffer,
4126          * either by copying or by moving the video pointer.
4127          * @param flipAction an integer value describing the flipping action
4128          * for the contents of the back buffer.  This should be one of the
4129          * values of the {@code BufferCapabilities.FlipContents}
4130          * property.
4131          * @exception IllegalStateException if the buffers have not yet
4132          * been created
4133          * @see java.awt.BufferCapabilities#getFlipContents()
4134          */
4135         protected void flip(BufferCapabilities.FlipContents flipAction) {
4136             if (peer != null) {
4137                 Image backBuffer = getBackBuffer();
4138                 if (backBuffer != null) {
4139                     peer.flip(0, 0,
4140                               backBuffer.getWidth(null),
4141                               backBuffer.getHeight(null), flipAction);
4142                 }
4143             } else {
4144                 throw new IllegalStateException(
4145                     "Component must have a valid peer");
4146             }
4147         }
4148 
4149         void flipSubRegion(int x1, int y1, int x2, int y2,
4150                       BufferCapabilities.FlipContents flipAction)
4151         {
4152             if (peer != null) {
4153                 peer.flip(x1, y1, x2, y2, flipAction);
4154             } else {
4155                 throw new IllegalStateException(
4156                     "Component must have a valid peer");
4157             }
4158         }
4159 
4160         /**
4161          * Destroys the buffers created through this object
4162          */
4163         protected void destroyBuffers() {
4164             VSyncedBSManager.releaseVsync(this);
4165             if (peer != null) {
4166                 peer.destroyBuffers();
4167             } else {
4168                 throw new IllegalStateException(
4169                     "Component must have a valid peer");
4170             }
4171         }
4172 
4173         /**
4174          * @return the buffering capabilities of this strategy
4175          */
4176         public BufferCapabilities getCapabilities() {
4177             if (caps instanceof ProxyCapabilities) {
4178                 return ((ProxyCapabilities)caps).orig;
4179             } else {
4180                 return caps;
4181             }
4182         }
4183 
4184         /**
4185          * @return the graphics on the drawing buffer.  This method may not
4186          * be synchronized for performance reasons; use of this method by multiple
4187          * threads should be handled at the application level.  Disposal of the
4188          * graphics object must be handled by the application.
4189          */
4190         public Graphics getDrawGraphics() {
4191             revalidate();
4192             return drawBuffer.getGraphics();
4193         }
4194 
4195         /**
4196          * Restore the drawing buffer if it has been lost
4197          */
4198         protected void revalidate() {
4199             revalidate(true);
4200         }
4201 
4202         void revalidate(boolean checkSize) {
4203             validatedContents = false;
4204 
4205             if (checkSize && (getWidth() != width || getHeight() != height)) {
4206                 // component has been resized; recreate the backbuffers
4207                 try {
4208                     createBuffers(numBuffers, caps);
4209                 } catch (AWTException e) {
4210                     // shouldn't be possible
4211                 }
4212                 validatedContents = true;
4213             }
4214 
4215             // get the buffers from the peer every time since they
4216             // might have been replaced in response to a display change event
4217             updateInternalBuffers();
4218 
4219             // now validate the backbuffer
4220             if (drawVBuffer != null) {
4221                 GraphicsConfiguration gc =
4222                         getGraphicsConfiguration_NoClientCode();
4223                 int returnCode = drawVBuffer.validate(gc);
4224                 if (returnCode == VolatileImage.IMAGE_INCOMPATIBLE) {
4225                     try {
4226                         createBuffers(numBuffers, caps);
4227                     } catch (AWTException e) {
4228                         // shouldn't be possible
4229                     }
4230                     if (drawVBuffer != null) {
4231                         // backbuffers were recreated, so validate again
4232                         drawVBuffer.validate(gc);
4233                     }
4234                     validatedContents = true;
4235                 } else if (returnCode == VolatileImage.IMAGE_RESTORED) {
4236                     validatedContents = true;
4237                 }
4238             }
4239         }
4240 
4241         /**
4242          * @return whether the drawing buffer was lost since the last call to
4243          * {@code getDrawGraphics}
4244          */
4245         public boolean contentsLost() {
4246             if (drawVBuffer == null) {
4247                 return false;
4248             }
4249             return drawVBuffer.contentsLost();
4250         }
4251 
4252         /**
4253          * @return whether the drawing buffer was recently restored from a lost
4254          * state and reinitialized to the default background color (white)
4255          */
4256         public boolean contentsRestored() {
4257             return validatedContents;
4258         }
4259 
4260         /**
4261          * Makes the next available buffer visible by either blitting or
4262          * flipping.
4263          */
4264         public void show() {
4265             flip(caps.getFlipContents());
4266         }
4267 
4268         /**
4269          * Makes specified region of the next available buffer visible
4270          * by either blitting or flipping.
4271          */
4272         void showSubRegion(int x1, int y1, int x2, int y2) {
4273             flipSubRegion(x1, y1, x2, y2, caps.getFlipContents());
4274         }
4275 
4276         /**
4277          * {@inheritDoc}
4278          * @since 1.6
4279          */
4280         public void dispose() {
4281             if (Component.this.bufferStrategy == this) {
4282                 Component.this.bufferStrategy = null;
4283                 if (peer != null) {
4284                     destroyBuffers();
4285                 }
4286             }
4287         }
4288 
4289     } // Inner class FlipBufferStrategy
4290 
4291     /**
4292      * Inner class for blitting offscreen surfaces to a component.
4293      *
4294      * @author Michael Martak
4295      * @since 1.4
4296      */
4297     protected class BltBufferStrategy extends BufferStrategy {
4298 
4299         /**
4300          * The buffering capabilities
4301          */
4302         protected BufferCapabilities caps; // = null
4303         /**
4304          * The back buffers
4305          */
4306         protected VolatileImage[] backBuffers; // = null
4307         /**
4308          * Whether or not the drawing buffer has been recently restored from
4309          * a lost state.
4310          */
4311         protected boolean validatedContents; // = false
4312         /**
4313          * Width of the back buffers
4314          */
4315         protected int width;
4316         /**
4317          * Height of the back buffers
4318          */
4319         protected int height;
4320 
4321         /**
4322          * Insets for the hosting Component.  The size of the back buffer
4323          * is constrained by these.
4324          */
4325         private Insets insets;
4326 
4327         /**
4328          * Creates a new blt buffer strategy around a component
4329          * @param numBuffers number of buffers to create, including the
4330          * front buffer
4331          * @param caps the capabilities of the buffers
4332          */
4333         protected BltBufferStrategy(int numBuffers, BufferCapabilities caps) {
4334             this.caps = caps;
4335             createBackBuffers(numBuffers - 1);
4336         }
4337 
4338         /**
4339          * {@inheritDoc}
4340          * @since 1.6
4341          */
4342         public void dispose() {
4343             if (backBuffers != null) {
4344                 for (int counter = backBuffers.length - 1; counter >= 0;
4345                      counter--) {
4346                     if (backBuffers[counter] != null) {
4347                         backBuffers[counter].flush();
4348                         backBuffers[counter] = null;
4349                     }
4350                 }
4351             }
4352             if (Component.this.bufferStrategy == this) {
4353                 Component.this.bufferStrategy = null;
4354             }
4355         }
4356 
4357         /**
4358          * Creates the back buffers
4359          *
4360          * @param numBuffers the number of buffers to create
4361          */
4362         protected void createBackBuffers(int numBuffers) {
4363             if (numBuffers == 0) {
4364                 backBuffers = null;
4365             } else {
4366                 // save the current bounds
4367                 width = getWidth();
4368                 height = getHeight();
4369                 insets = getInsets_NoClientCode();
4370                 int iWidth = width - insets.left - insets.right;
4371                 int iHeight = height - insets.top - insets.bottom;
4372 
4373                 // It is possible for the component's width and/or height
4374                 // to be 0 here.  Force the size of the backbuffers to
4375                 // be > 0 so that creating the image won't fail.
4376                 iWidth = Math.max(1, iWidth);
4377                 iHeight = Math.max(1, iHeight);
4378                 if (backBuffers == null) {
4379                     backBuffers = new VolatileImage[numBuffers];
4380                 } else {
4381                     // flush any existing backbuffers
4382                     for (int i = 0; i < numBuffers; i++) {
4383                         if (backBuffers[i] != null) {
4384                             backBuffers[i].flush();
4385                             backBuffers[i] = null;
4386                         }
4387                     }
4388                 }
4389 
4390                 // create the backbuffers
4391                 for (int i = 0; i < numBuffers; i++) {
4392                     backBuffers[i] = createVolatileImage(iWidth, iHeight);
4393                 }
4394             }
4395         }
4396 
4397         /**
4398          * @return the buffering capabilities of this strategy
4399          */
4400         public BufferCapabilities getCapabilities() {
4401             return caps;
4402         }
4403 
4404         /**
4405          * @return the draw graphics
4406          */
4407         public Graphics getDrawGraphics() {
4408             revalidate();
4409             Image backBuffer = getBackBuffer();
4410             if (backBuffer == null) {
4411                 return getGraphics();
4412             }
4413             SunGraphics2D g = (SunGraphics2D)backBuffer.getGraphics();
4414             g.constrain(-insets.left, -insets.top,
4415                         backBuffer.getWidth(null) + insets.left,
4416                         backBuffer.getHeight(null) + insets.top);
4417             return g;
4418         }
4419 
4420         /**
4421          * @return direct access to the back buffer, as an image.
4422          * If there is no back buffer, returns null.
4423          */
4424         Image getBackBuffer() {
4425             if (backBuffers != null) {
4426                 return backBuffers[backBuffers.length - 1];
4427             } else {
4428                 return null;
4429             }
4430         }
4431 
4432         /**
4433          * Makes the next available buffer visible.
4434          */
4435         public void show() {
4436             showSubRegion(insets.left, insets.top,
4437                           width - insets.right,
4438                           height - insets.bottom);
4439         }
4440 
4441         /**
4442          * Package-private method to present a specific rectangular area
4443          * of this buffer.  This class currently shows only the entire
4444          * buffer, by calling showSubRegion() with the full dimensions of
4445          * the buffer.  Subclasses (e.g., BltSubRegionBufferStrategy
4446          * and FlipSubRegionBufferStrategy) may have region-specific show
4447          * methods that call this method with actual sub regions of the
4448          * buffer.
4449          */
4450         void showSubRegion(int x1, int y1, int x2, int y2) {
4451             if (backBuffers == null) {
4452                 return;
4453             }
4454             // Adjust location to be relative to client area.
4455             x1 -= insets.left;
4456             x2 -= insets.left;
4457             y1 -= insets.top;
4458             y2 -= insets.top;
4459             Graphics g = getGraphics_NoClientCode();
4460             if (g == null) {
4461                 // Not showing, bail
4462                 return;
4463             }
4464             try {
4465                 // First image copy is in terms of Frame's coordinates, need
4466                 // to translate to client area.
4467                 g.translate(insets.left, insets.top);
4468                 for (int i = 0; i < backBuffers.length; i++) {
4469                     g.drawImage(backBuffers[i],
4470                                 x1, y1, x2, y2,
4471                                 x1, y1, x2, y2,
4472                                 null);
4473                     g.dispose();
4474                     g = null;
4475                     g = backBuffers[i].getGraphics();
4476                 }
4477             } finally {
4478                 if (g != null) {
4479                     g.dispose();
4480                 }
4481             }
4482         }
4483 
4484         /**
4485          * Restore the drawing buffer if it has been lost
4486          */
4487         protected void revalidate() {
4488             revalidate(true);
4489         }
4490 
4491         void revalidate(boolean checkSize) {
4492             validatedContents = false;
4493 
4494             if (backBuffers == null) {
4495                 return;
4496             }
4497 
4498             if (checkSize) {
4499                 Insets insets = getInsets_NoClientCode();
4500                 if (getWidth() != width || getHeight() != height ||
4501                     !insets.equals(this.insets)) {
4502                     // component has been resized; recreate the backbuffers
4503                     createBackBuffers(backBuffers.length);
4504                     validatedContents = true;
4505                 }
4506             }
4507 
4508             // now validate the backbuffer
4509             GraphicsConfiguration gc = getGraphicsConfiguration_NoClientCode();
4510             int returnCode =
4511                 backBuffers[backBuffers.length - 1].validate(gc);
4512             if (returnCode == VolatileImage.IMAGE_INCOMPATIBLE) {
4513                 if (checkSize) {
4514                     createBackBuffers(backBuffers.length);
4515                     // backbuffers were recreated, so validate again
4516                     backBuffers[backBuffers.length - 1].validate(gc);
4517                 }
4518                 // else case means we're called from Swing on the toolkit
4519                 // thread, don't recreate buffers as that'll deadlock
4520                 // (creating VolatileImages invokes getting GraphicsConfig
4521                 // which grabs treelock).
4522                 validatedContents = true;
4523             } else if (returnCode == VolatileImage.IMAGE_RESTORED) {
4524                 validatedContents = true;
4525             }
4526         }
4527 
4528         /**
4529          * @return whether the drawing buffer was lost since the last call to
4530          * {@code getDrawGraphics}
4531          */
4532         public boolean contentsLost() {
4533             if (backBuffers == null) {
4534                 return false;
4535             } else {
4536                 return backBuffers[backBuffers.length - 1].contentsLost();
4537             }
4538         }
4539 
4540         /**
4541          * @return whether the drawing buffer was recently restored from a lost
4542          * state and reinitialized to the default background color (white)
4543          */
4544         public boolean contentsRestored() {
4545             return validatedContents;
4546         }
4547     } // Inner class BltBufferStrategy
4548 
4549     /**
4550      * Private class to perform sub-region flipping.
4551      */
4552     private class FlipSubRegionBufferStrategy extends FlipBufferStrategy
4553         implements SubRegionShowable
4554     {
4555 
4556         protected FlipSubRegionBufferStrategy(int numBuffers,
4557                                               BufferCapabilities caps)
4558             throws AWTException
4559         {
4560             super(numBuffers, caps);
4561         }
4562 
4563         public void show(int x1, int y1, int x2, int y2) {
4564             showSubRegion(x1, y1, x2, y2);
4565         }
4566 
4567         // This is invoked by Swing on the toolkit thread.
4568         public boolean showIfNotLost(int x1, int y1, int x2, int y2) {
4569             if (!contentsLost()) {
4570                 showSubRegion(x1, y1, x2, y2);
4571                 return !contentsLost();
4572             }
4573             return false;
4574         }
4575     }
4576 
4577     /**
4578      * Private class to perform sub-region blitting.  Swing will use
4579      * this subclass via the SubRegionShowable interface in order to
4580      * copy only the area changed during a repaint.
4581      * See javax.swing.BufferStrategyPaintManager.
4582      */
4583     private class BltSubRegionBufferStrategy extends BltBufferStrategy
4584         implements SubRegionShowable
4585     {
4586 
4587         protected BltSubRegionBufferStrategy(int numBuffers,
4588                                              BufferCapabilities caps)
4589         {
4590             super(numBuffers, caps);
4591         }
4592 
4593         public void show(int x1, int y1, int x2, int y2) {
4594             showSubRegion(x1, y1, x2, y2);
4595         }
4596 
4597         // This method is called by Swing on the toolkit thread.
4598         public boolean showIfNotLost(int x1, int y1, int x2, int y2) {
4599             if (!contentsLost()) {
4600                 showSubRegion(x1, y1, x2, y2);
4601                 return !contentsLost();
4602             }
4603             return false;
4604         }
4605     }
4606 
4607     /**
4608      * Inner class for flipping buffers on a component.  That component must
4609      * be a {@code Canvas} or {@code Window}.
4610      * @see Canvas
4611      * @see Window
4612      * @see java.awt.image.BufferStrategy
4613      * @author Michael Martak
4614      * @since 1.4
4615      */
4616     private class SingleBufferStrategy extends BufferStrategy {
4617 
4618         private BufferCapabilities caps;
4619 
4620         public SingleBufferStrategy(BufferCapabilities caps) {
4621             this.caps = caps;
4622         }
4623         public BufferCapabilities getCapabilities() {
4624             return caps;
4625         }
4626         public Graphics getDrawGraphics() {
4627             return getGraphics();
4628         }
4629         public boolean contentsLost() {
4630             return false;
4631         }
4632         public boolean contentsRestored() {
4633             return false;
4634         }
4635         public void show() {
4636             // Do nothing
4637         }
4638     } // Inner class SingleBufferStrategy
4639 
4640     /**
4641      * Sets whether or not paint messages received from the operating system
4642      * should be ignored.  This does not affect paint events generated in
4643      * software by the AWT, unless they are an immediate response to an
4644      * OS-level paint message.
4645      * <p>
4646      * This is useful, for example, if running under full-screen mode and
4647      * better performance is desired, or if page-flipping is used as the
4648      * buffer strategy.
4649      *
4650      * @param ignoreRepaint {@code true} if the paint messages from the OS
4651      *                      should be ignored; otherwise {@code false}
4652      *
4653      * @since 1.4
4654      * @see #getIgnoreRepaint
4655      * @see Canvas#createBufferStrategy
4656      * @see Window#createBufferStrategy
4657      * @see java.awt.image.BufferStrategy
4658      * @see GraphicsDevice#setFullScreenWindow
4659      */
4660     public void setIgnoreRepaint(boolean ignoreRepaint) {
4661         this.ignoreRepaint = ignoreRepaint;
4662     }
4663 
4664     /**
4665      * @return whether or not paint messages received from the operating system
4666      * should be ignored.
4667      *
4668      * @since 1.4
4669      * @see #setIgnoreRepaint
4670      */
4671     public boolean getIgnoreRepaint() {
4672         return ignoreRepaint;
4673     }
4674 
4675     /**
4676      * Checks whether this component "contains" the specified point,
4677      * where {@code x} and {@code y} are defined to be
4678      * relative to the coordinate system of this component.
4679      *
4680      * @param     x   the <i>x</i> coordinate of the point
4681      * @param     y   the <i>y</i> coordinate of the point
4682      * @return {@code true} if the point is within the component;
4683      *         otherwise {@code false}
4684      * @see       #getComponentAt(int, int)
4685      * @since     1.1
4686      */
4687     public boolean contains(int x, int y) {
4688         return inside(x, y);
4689     }
4690 
4691     /**
4692      * Checks whether the point is inside of this component.
4693      *
4694      * @param  x the <i>x</i> coordinate of the point
4695      * @param  y the <i>y</i> coordinate of the point
4696      * @return {@code true} if the point is within the component;
4697      *         otherwise {@code false}
4698      * @deprecated As of JDK version 1.1,
4699      * replaced by contains(int, int).
4700      */
4701     @Deprecated
4702     public boolean inside(int x, int y) {
4703         return (x >= 0) && (x < width) && (y >= 0) && (y < height);
4704     }
4705 
4706     /**
4707      * Checks whether this component "contains" the specified point,
4708      * where the point's <i>x</i> and <i>y</i> coordinates are defined
4709      * to be relative to the coordinate system of this component.
4710      *
4711      * @param     p     the point
4712      * @return {@code true} if the point is within the component;
4713      *         otherwise {@code false}
4714      * @throws    NullPointerException if {@code p} is {@code null}
4715      * @see       #getComponentAt(Point)
4716      * @since     1.1
4717      */
4718     public boolean contains(Point p) {
4719         return contains(p.x, p.y);
4720     }
4721 
4722     /**
4723      * Determines if this component or one of its immediate
4724      * subcomponents contains the (<i>x</i>,&nbsp;<i>y</i>) location,
4725      * and if so, returns the containing component. This method only
4726      * looks one level deep. If the point (<i>x</i>,&nbsp;<i>y</i>) is
4727      * inside a subcomponent that itself has subcomponents, it does not
4728      * go looking down the subcomponent tree.
4729      * <p>
4730      * The {@code locate} method of {@code Component} simply
4731      * returns the component itself if the (<i>x</i>,&nbsp;<i>y</i>)
4732      * coordinate location is inside its bounding box, and {@code null}
4733      * otherwise.
4734      * @param     x   the <i>x</i> coordinate
4735      * @param     y   the <i>y</i> coordinate
4736      * @return    the component or subcomponent that contains the
4737      *                (<i>x</i>,&nbsp;<i>y</i>) location;
4738      *                {@code null} if the location
4739      *                is outside this component
4740      * @see       #contains(int, int)
4741      * @since     1.0
4742      */
4743     public Component getComponentAt(int x, int y) {
4744         return locate(x, y);
4745     }
4746 
4747     /**
4748      * Returns the component occupying the position specified (this component,
4749      * or immediate child component, or null if neither
4750      * of the first two occupies the location).
4751      *
4752      * @param  x the <i>x</i> coordinate to search for components at
4753      * @param  y the <i>y</i> coordinate to search for components at
4754      * @return the component at the specified location or {@code null}
4755      * @deprecated As of JDK version 1.1,
4756      * replaced by getComponentAt(int, int).
4757      */
4758     @Deprecated
4759     public Component locate(int x, int y) {
4760         return contains(x, y) ? this : null;
4761     }
4762 
4763     /**
4764      * Returns the component or subcomponent that contains the
4765      * specified point.
4766      * @param  p the point
4767      * @return the component at the specified location or {@code null}
4768      * @see java.awt.Component#contains
4769      * @since 1.1
4770      */
4771     public Component getComponentAt(Point p) {
4772         return getComponentAt(p.x, p.y);
4773     }
4774 
4775     /**
4776      * @param  e the event to deliver
4777      * @deprecated As of JDK version 1.1,
4778      * replaced by {@code dispatchEvent(AWTEvent e)}.
4779      */
4780     @Deprecated
4781     public void deliverEvent(Event e) {
4782         postEvent(e);
4783     }
4784 
4785     /**
4786      * Dispatches an event to this component or one of its sub components.
4787      * Calls {@code processEvent} before returning for 1.1-style
4788      * events which have been enabled for the {@code Component}.
4789      * @param e the event
4790      */
4791     public final void dispatchEvent(AWTEvent e) {
4792         dispatchEventImpl(e);
4793     }
4794 
4795     @SuppressWarnings("deprecation")
4796     void dispatchEventImpl(AWTEvent e) {
4797         int id = e.getID();
4798 
4799         // Check that this component belongs to this app-context
4800         AppContext compContext = appContext;
4801         if (compContext != null && !compContext.equals(AppContext.getAppContext())) {
4802             if (eventLog.isLoggable(PlatformLogger.Level.FINE)) {
4803                 eventLog.fine("Event " + e + " is being dispatched on the wrong AppContext");
4804             }
4805         }
4806 
4807         if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) {
4808             eventLog.finest("{0}", e);
4809         }
4810 
4811         /*
4812          * 0. Set timestamp and modifiers of current event.
4813          */
4814         if (!(e instanceof KeyEvent)) {
4815             // Timestamp of a key event is set later in DKFM.preDispatchKeyEvent(KeyEvent).
4816             EventQueue.setCurrentEventAndMostRecentTime(e);
4817         }
4818 
4819         /*
4820          * 1. Pre-dispatchers. Do any necessary retargeting/reordering here
4821          *    before we notify AWTEventListeners.
4822          */
4823 
4824         if (e instanceof SunDropTargetEvent) {
4825             ((SunDropTargetEvent)e).dispatch();
4826             return;
4827         }
4828 
4829         if (!e.focusManagerIsDispatching) {
4830             // Invoke the private focus retargeting method which provides
4831             // lightweight Component support
4832             if (e.isPosted) {
4833                 e = KeyboardFocusManager.retargetFocusEvent(e);
4834                 e.isPosted = true;
4835             }
4836 
4837             // Now, with the event properly targeted to a lightweight
4838             // descendant if necessary, invoke the public focus retargeting
4839             // and dispatching function
4840             if (KeyboardFocusManager.getCurrentKeyboardFocusManager().
4841                 dispatchEvent(e))
4842             {
4843                 return;
4844             }
4845         }
4846         if ((e instanceof FocusEvent) && focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
4847             focusLog.finest("" + e);
4848         }
4849         // MouseWheel may need to be retargeted here so that
4850         // AWTEventListener sees the event go to the correct
4851         // Component.  If the MouseWheelEvent needs to go to an ancestor,
4852         // the event is dispatched to the ancestor, and dispatching here
4853         // stops.
4854         if (id == MouseEvent.MOUSE_WHEEL &&
4855             (!eventTypeEnabled(id)) &&
4856             (peer != null && !peer.handlesWheelScrolling()) &&
4857             (dispatchMouseWheelToAncestor((MouseWheelEvent)e)))
4858         {
4859             return;
4860         }
4861 
4862         /*
4863          * 2. Allow the Toolkit to pass this to AWTEventListeners.
4864          */
4865         Toolkit toolkit = Toolkit.getDefaultToolkit();
4866         toolkit.notifyAWTEventListeners(e);
4867 
4868 
4869         /*
4870          * 3. If no one has consumed a key event, allow the
4871          *    KeyboardFocusManager to process it.
4872          */
4873         if (!e.isConsumed()) {
4874             if (e instanceof java.awt.event.KeyEvent) {
4875                 KeyboardFocusManager.getCurrentKeyboardFocusManager().
4876                     processKeyEvent(this, (KeyEvent)e);
4877                 if (e.isConsumed()) {
4878                     return;
4879                 }
4880             }
4881         }
4882 
4883         /*
4884          * 4. Allow input methods to process the event
4885          */
4886         if (areInputMethodsEnabled()) {
4887             // We need to pass on InputMethodEvents since some host
4888             // input method adapters send them through the Java
4889             // event queue instead of directly to the component,
4890             // and the input context also handles the Java composition window
4891             if(((e instanceof InputMethodEvent) && !(this instanceof CompositionArea))
4892                ||
4893                // Otherwise, we only pass on input and focus events, because
4894                // a) input methods shouldn't know about semantic or component-level events
4895                // b) passing on the events takes time
4896                // c) isConsumed() is always true for semantic events.
4897                (e instanceof InputEvent) || (e instanceof FocusEvent)) {
4898                 InputContext inputContext = getInputContext();
4899 
4900 
4901                 if (inputContext != null) {
4902                     inputContext.dispatchEvent(e);
4903                     if (e.isConsumed()) {
4904                         if ((e instanceof FocusEvent) && focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
4905                             focusLog.finest("3579: Skipping " + e);
4906                         }
4907                         return;
4908                     }
4909                 }
4910             }
4911         } else {
4912             // When non-clients get focus, we need to explicitly disable the native
4913             // input method. The native input method is actually not disabled when
4914             // the active/passive/peered clients loose focus.
4915             if (id == FocusEvent.FOCUS_GAINED) {
4916                 InputContext inputContext = getInputContext();
4917                 if (inputContext != null && inputContext instanceof sun.awt.im.InputContext) {
4918                     ((sun.awt.im.InputContext)inputContext).disableNativeIM();
4919                 }
4920             }
4921         }
4922 
4923 
4924         /*
4925          * 5. Pre-process any special events before delivery
4926          */
4927         switch(id) {
4928             // Handling of the PAINT and UPDATE events is now done in the
4929             // peer's handleEvent() method so the background can be cleared
4930             // selectively for non-native components on Windows only.
4931             // - Fred.Ecks@Eng.sun.com, 5-8-98
4932 
4933           case KeyEvent.KEY_PRESSED:
4934           case KeyEvent.KEY_RELEASED:
4935               Container p = (Container)((this instanceof Container) ? this : parent);
4936               if (p != null) {
4937                   p.preProcessKeyEvent((KeyEvent)e);
4938                   if (e.isConsumed()) {
4939                         if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
4940                             focusLog.finest("Pre-process consumed event");
4941                         }
4942                       return;
4943                   }
4944               }
4945               break;
4946 
4947           default:
4948               break;
4949         }
4950 
4951         /*
4952          * 6. Deliver event for normal processing
4953          */
4954         if (newEventsOnly) {
4955             // Filtering needs to really be moved to happen at a lower
4956             // level in order to get maximum performance gain;  it is
4957             // here temporarily to ensure the API spec is honored.
4958             //
4959             if (eventEnabled(e)) {
4960                 processEvent(e);
4961             }
4962         } else if (id == MouseEvent.MOUSE_WHEEL) {
4963             // newEventsOnly will be false for a listenerless ScrollPane, but
4964             // MouseWheelEvents still need to be dispatched to it so scrolling
4965             // can be done.
4966             autoProcessMouseWheel((MouseWheelEvent)e);
4967         } else if (!(e instanceof MouseEvent && !postsOldMouseEvents())) {
4968             //
4969             // backward compatibility
4970             //
4971             Event olde = e.convertToOld();
4972             if (olde != null) {
4973                 int key = olde.key;
4974                 int modifiers = olde.modifiers;
4975 
4976                 postEvent(olde);
4977                 if (olde.isConsumed()) {
4978                     e.consume();
4979                 }
4980                 // if target changed key or modifier values, copy them
4981                 // back to original event
4982                 //
4983                 switch(olde.id) {
4984                   case Event.KEY_PRESS:
4985                   case Event.KEY_RELEASE:
4986                   case Event.KEY_ACTION:
4987                   case Event.KEY_ACTION_RELEASE:
4988                       if (olde.key != key) {
4989                           ((KeyEvent)e).setKeyChar(olde.getKeyEventChar());
4990                       }
4991                       if (olde.modifiers != modifiers) {
4992                           ((KeyEvent)e).setModifiers(olde.modifiers);
4993                       }
4994                       break;
4995                   default:
4996                       break;
4997                 }
4998             }
4999         }
5000 
5001         /*
5002          * 9. Allow the peer to process the event.
5003          * Except KeyEvents, they will be processed by peer after
5004          * all KeyEventPostProcessors
5005          * (see DefaultKeyboardFocusManager.dispatchKeyEvent())
5006          */
5007         if (!(e instanceof KeyEvent)) {
5008             ComponentPeer tpeer = peer;
5009             if (e instanceof FocusEvent && (tpeer == null || tpeer instanceof LightweightPeer)) {
5010                 // if focus owner is lightweight then its native container
5011                 // processes event
5012                 Component source = (Component)e.getSource();
5013                 if (source != null) {
5014                     Container target = source.getNativeContainer();
5015                     if (target != null) {
5016                         tpeer = target.peer;
5017                     }
5018                 }
5019             }
5020             if (tpeer != null) {
5021                 tpeer.handleEvent(e);
5022             }
5023         }
5024     } // dispatchEventImpl()
5025 
5026     /*
5027      * If newEventsOnly is false, method is called so that ScrollPane can
5028      * override it and handle common-case mouse wheel scrolling.  NOP
5029      * for Component.
5030      */
5031     void autoProcessMouseWheel(MouseWheelEvent e) {}
5032 
5033     /*
5034      * Dispatch given MouseWheelEvent to the first ancestor for which
5035      * MouseWheelEvents are enabled.
5036      *
5037      * Returns whether or not event was dispatched to an ancestor
5038      */
5039     @SuppressWarnings("deprecation")
5040     boolean dispatchMouseWheelToAncestor(MouseWheelEvent e) {
5041         int newX, newY;
5042         newX = e.getX() + getX(); // Coordinates take into account at least
5043         newY = e.getY() + getY(); // the cursor's position relative to this
5044                                   // Component (e.getX()), and this Component's
5045                                   // position relative to its parent.
5046         MouseWheelEvent newMWE;
5047 
5048         if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) {
5049             eventLog.finest("dispatchMouseWheelToAncestor");
5050             eventLog.finest("orig event src is of " + e.getSource().getClass());
5051         }
5052 
5053         /* parent field for Window refers to the owning Window.
5054          * MouseWheelEvents should NOT be propagated into owning Windows
5055          */
5056         synchronized (getTreeLock()) {
5057             Container anc = getParent();
5058             while (anc != null && !anc.eventEnabled(e)) {
5059                 // fix coordinates to be relative to new event source
5060                 newX += anc.getX();
5061                 newY += anc.getY();
5062 
5063                 if (!(anc instanceof Window)) {
5064                     anc = anc.getParent();
5065                 }
5066                 else {
5067                     break;
5068                 }
5069             }
5070 
5071             if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) {
5072                 eventLog.finest("new event src is " + anc.getClass());
5073             }
5074 
5075             if (anc != null && anc.eventEnabled(e)) {
5076                 // Change event to be from new source, with new x,y
5077                 // For now, just create a new event - yucky
5078 
5079                 newMWE = new MouseWheelEvent(anc, // new source
5080                                              e.getID(),
5081                                              e.getWhen(),
5082                                              e.getModifiers(),
5083                                              newX, // x relative to new source
5084                                              newY, // y relative to new source
5085                                              e.getXOnScreen(),
5086                                              e.getYOnScreen(),
5087                                              e.getClickCount(),
5088                                              e.isPopupTrigger(),
5089                                              e.getScrollType(),
5090                                              e.getScrollAmount(),
5091                                              e.getWheelRotation(),
5092                                              e.getPreciseWheelRotation());
5093                 ((AWTEvent)e).copyPrivateDataInto(newMWE);
5094                 // When dispatching a wheel event to
5095                 // ancestor, there is no need trying to find descendant
5096                 // lightweights to dispatch event to.
5097                 // If we dispatch the event to toplevel ancestor,
5098                 // this could enclose the loop: 6480024.
5099                 anc.dispatchEventToSelf(newMWE);
5100                 if (newMWE.isConsumed()) {
5101                     e.consume();
5102                 }
5103                 return true;
5104             }
5105         }
5106         return false;
5107     }
5108 
5109     boolean areInputMethodsEnabled() {
5110         // in 1.2, we assume input method support is required for all
5111         // components that handle key events, but components can turn off
5112         // input methods by calling enableInputMethods(false).
5113         return ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) &&
5114             ((eventMask & AWTEvent.KEY_EVENT_MASK) != 0 || keyListener != null);
5115     }
5116 
5117     // REMIND: remove when filtering is handled at lower level
5118     boolean eventEnabled(AWTEvent e) {
5119         return eventTypeEnabled(e.id);
5120     }
5121 
5122     boolean eventTypeEnabled(int type) {
5123         switch(type) {
5124           case ComponentEvent.COMPONENT_MOVED:
5125           case ComponentEvent.COMPONENT_RESIZED:
5126           case ComponentEvent.COMPONENT_SHOWN:
5127           case ComponentEvent.COMPONENT_HIDDEN:
5128               if ((eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 ||
5129                   componentListener != null) {
5130                   return true;
5131               }
5132               break;
5133           case FocusEvent.FOCUS_GAINED:
5134           case FocusEvent.FOCUS_LOST:
5135               if ((eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0 ||
5136                   focusListener != null) {
5137                   return true;
5138               }
5139               break;
5140           case KeyEvent.KEY_PRESSED:
5141           case KeyEvent.KEY_RELEASED:
5142           case KeyEvent.KEY_TYPED:
5143               if ((eventMask & AWTEvent.KEY_EVENT_MASK) != 0 ||
5144                   keyListener != null) {
5145                   return true;
5146               }
5147               break;
5148           case MouseEvent.MOUSE_PRESSED:
5149           case MouseEvent.MOUSE_RELEASED:
5150           case MouseEvent.MOUSE_ENTERED:
5151           case MouseEvent.MOUSE_EXITED:
5152           case MouseEvent.MOUSE_CLICKED:
5153               if ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0 ||
5154                   mouseListener != null) {
5155                   return true;
5156               }
5157               break;
5158           case MouseEvent.MOUSE_MOVED:
5159           case MouseEvent.MOUSE_DRAGGED:
5160               if ((eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0 ||
5161                   mouseMotionListener != null) {
5162                   return true;
5163               }
5164               break;
5165           case MouseEvent.MOUSE_WHEEL:
5166               if ((eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0 ||
5167                   mouseWheelListener != null) {
5168                   return true;
5169               }
5170               break;
5171           case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
5172           case InputMethodEvent.CARET_POSITION_CHANGED:
5173               if ((eventMask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0 ||
5174                   inputMethodListener != null) {
5175                   return true;
5176               }
5177               break;
5178           case HierarchyEvent.HIERARCHY_CHANGED:
5179               if ((eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 ||
5180                   hierarchyListener != null) {
5181                   return true;
5182               }
5183               break;
5184           case HierarchyEvent.ANCESTOR_MOVED:
5185           case HierarchyEvent.ANCESTOR_RESIZED:
5186               if ((eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 ||
5187                   hierarchyBoundsListener != null) {
5188                   return true;
5189               }
5190               break;
5191           case ActionEvent.ACTION_PERFORMED:
5192               if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0) {
5193                   return true;
5194               }
5195               break;
5196           case TextEvent.TEXT_VALUE_CHANGED:
5197               if ((eventMask & AWTEvent.TEXT_EVENT_MASK) != 0) {
5198                   return true;
5199               }
5200               break;
5201           case ItemEvent.ITEM_STATE_CHANGED:
5202               if ((eventMask & AWTEvent.ITEM_EVENT_MASK) != 0) {
5203                   return true;
5204               }
5205               break;
5206           case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED:
5207               if ((eventMask & AWTEvent.ADJUSTMENT_EVENT_MASK) != 0) {
5208                   return true;
5209               }
5210               break;
5211           default:
5212               break;
5213         }
5214         //
5215         // Always pass on events defined by external programs.
5216         //
5217         if (type > AWTEvent.RESERVED_ID_MAX) {
5218             return true;
5219         }
5220         return false;
5221     }
5222 
5223     /**
5224      * @deprecated As of JDK version 1.1,
5225      * replaced by dispatchEvent(AWTEvent).
5226      */
5227     @Deprecated
5228     public boolean postEvent(Event e) {
5229         ComponentPeer peer = this.peer;
5230 
5231         if (handleEvent(e)) {
5232             e.consume();
5233             return true;
5234         }
5235 
5236         Component parent = this.parent;
5237         int eventx = e.x;
5238         int eventy = e.y;
5239         if (parent != null) {
5240             e.translate(x, y);
5241             if (parent.postEvent(e)) {
5242                 e.consume();
5243                 return true;
5244             }
5245             // restore coords
5246             e.x = eventx;
5247             e.y = eventy;
5248         }
5249         return false;
5250     }
5251 
5252     // Event source interfaces
5253 
5254     /**
5255      * Adds the specified component listener to receive component events from
5256      * this component.
5257      * If listener {@code l} is {@code null},
5258      * no exception is thrown and no action is performed.
5259      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5260      * >AWT Threading Issues</a> for details on AWT's threading model.
5261      *
5262      * @param    l   the component listener
5263      * @see      java.awt.event.ComponentEvent
5264      * @see      java.awt.event.ComponentListener
5265      * @see      #removeComponentListener
5266      * @see      #getComponentListeners
5267      * @since    1.1
5268      */
5269     public synchronized void addComponentListener(ComponentListener l) {
5270         if (l == null) {
5271             return;
5272         }
5273         componentListener = AWTEventMulticaster.add(componentListener, l);
5274         newEventsOnly = true;
5275     }
5276 
5277     /**
5278      * Removes the specified component listener so that it no longer
5279      * receives component events from this component. This method performs
5280      * no function, nor does it throw an exception, if the listener
5281      * specified by the argument was not previously added to this component.
5282      * If listener {@code l} is {@code null},
5283      * no exception is thrown and no action is performed.
5284      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5285      * >AWT Threading Issues</a> for details on AWT's threading model.
5286      * @param    l   the component listener
5287      * @see      java.awt.event.ComponentEvent
5288      * @see      java.awt.event.ComponentListener
5289      * @see      #addComponentListener
5290      * @see      #getComponentListeners
5291      * @since    1.1
5292      */
5293     public synchronized void removeComponentListener(ComponentListener l) {
5294         if (l == null) {
5295             return;
5296         }
5297         componentListener = AWTEventMulticaster.remove(componentListener, l);
5298     }
5299 
5300     /**
5301      * Returns an array of all the component listeners
5302      * registered on this component.
5303      *
5304      * @return all {@code ComponentListener}s of this component
5305      *         or an empty array if no component
5306      *         listeners are currently registered
5307      *
5308      * @see #addComponentListener
5309      * @see #removeComponentListener
5310      * @since 1.4
5311      */
5312     public synchronized ComponentListener[] getComponentListeners() {
5313         return getListeners(ComponentListener.class);
5314     }
5315 
5316     /**
5317      * Adds the specified focus listener to receive focus events from
5318      * this component when this component gains input focus.
5319      * If listener {@code l} is {@code null},
5320      * no exception is thrown and no action is performed.
5321      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5322      * >AWT Threading Issues</a> for details on AWT's threading model.
5323      *
5324      * @param    l   the focus listener
5325      * @see      java.awt.event.FocusEvent
5326      * @see      java.awt.event.FocusListener
5327      * @see      #removeFocusListener
5328      * @see      #getFocusListeners
5329      * @since    1.1
5330      */
5331     public synchronized void addFocusListener(FocusListener l) {
5332         if (l == null) {
5333             return;
5334         }
5335         focusListener = AWTEventMulticaster.add(focusListener, l);
5336         newEventsOnly = true;
5337 
5338         // if this is a lightweight component, enable focus events
5339         // in the native container.
5340         if (peer instanceof LightweightPeer) {
5341             parent.proxyEnableEvents(AWTEvent.FOCUS_EVENT_MASK);
5342         }
5343     }
5344 
5345     /**
5346      * Removes the specified focus listener so that it no longer
5347      * receives focus events from this component. This method performs
5348      * no function, nor does it throw an exception, if the listener
5349      * specified by the argument was not previously added to this component.
5350      * If listener {@code l} is {@code null},
5351      * no exception is thrown and no action is performed.
5352      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5353      * >AWT Threading Issues</a> for details on AWT's threading model.
5354      *
5355      * @param    l   the focus listener
5356      * @see      java.awt.event.FocusEvent
5357      * @see      java.awt.event.FocusListener
5358      * @see      #addFocusListener
5359      * @see      #getFocusListeners
5360      * @since    1.1
5361      */
5362     public synchronized void removeFocusListener(FocusListener l) {
5363         if (l == null) {
5364             return;
5365         }
5366         focusListener = AWTEventMulticaster.remove(focusListener, l);
5367     }
5368 
5369     /**
5370      * Returns an array of all the focus listeners
5371      * registered on this component.
5372      *
5373      * @return all of this component's {@code FocusListener}s
5374      *         or an empty array if no component
5375      *         listeners are currently registered
5376      *
5377      * @see #addFocusListener
5378      * @see #removeFocusListener
5379      * @since 1.4
5380      */
5381     public synchronized FocusListener[] getFocusListeners() {
5382         return getListeners(FocusListener.class);
5383     }
5384 
5385     /**
5386      * Adds the specified hierarchy listener to receive hierarchy changed
5387      * events from this component when the hierarchy to which this container
5388      * belongs changes.
5389      * If listener {@code l} is {@code null},
5390      * no exception is thrown and no action is performed.
5391      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5392      * >AWT Threading Issues</a> for details on AWT's threading model.
5393      *
5394      * @param    l   the hierarchy listener
5395      * @see      java.awt.event.HierarchyEvent
5396      * @see      java.awt.event.HierarchyListener
5397      * @see      #removeHierarchyListener
5398      * @see      #getHierarchyListeners
5399      * @since    1.3
5400      */
5401     public void addHierarchyListener(HierarchyListener l) {
5402         if (l == null) {
5403             return;
5404         }
5405         boolean notifyAncestors;
5406         synchronized (this) {
5407             notifyAncestors =
5408                 (hierarchyListener == null &&
5409                  (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) == 0);
5410             hierarchyListener = AWTEventMulticaster.add(hierarchyListener, l);
5411             notifyAncestors = (notifyAncestors && hierarchyListener != null);
5412             newEventsOnly = true;
5413         }
5414         if (notifyAncestors) {
5415             synchronized (getTreeLock()) {
5416                 adjustListeningChildrenOnParent(AWTEvent.HIERARCHY_EVENT_MASK,
5417                                                 1);
5418             }
5419         }
5420     }
5421 
5422     /**
5423      * Removes the specified hierarchy listener so that it no longer
5424      * receives hierarchy changed events from this component. This method
5425      * performs no function, nor does it throw an exception, if the listener
5426      * specified by the argument was not previously added to this component.
5427      * If listener {@code l} is {@code null},
5428      * no exception is thrown and no action is performed.
5429      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5430      * >AWT Threading Issues</a> for details on AWT's threading model.
5431      *
5432      * @param    l   the hierarchy listener
5433      * @see      java.awt.event.HierarchyEvent
5434      * @see      java.awt.event.HierarchyListener
5435      * @see      #addHierarchyListener
5436      * @see      #getHierarchyListeners
5437      * @since    1.3
5438      */
5439     public void removeHierarchyListener(HierarchyListener l) {
5440         if (l == null) {
5441             return;
5442         }
5443         boolean notifyAncestors;
5444         synchronized (this) {
5445             notifyAncestors =
5446                 (hierarchyListener != null &&
5447                  (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) == 0);
5448             hierarchyListener =
5449                 AWTEventMulticaster.remove(hierarchyListener, l);
5450             notifyAncestors = (notifyAncestors && hierarchyListener == null);
5451         }
5452         if (notifyAncestors) {
5453             synchronized (getTreeLock()) {
5454                 adjustListeningChildrenOnParent(AWTEvent.HIERARCHY_EVENT_MASK,
5455                                                 -1);
5456             }
5457         }
5458     }
5459 
5460     /**
5461      * Returns an array of all the hierarchy listeners
5462      * registered on this component.
5463      *
5464      * @return all of this component's {@code HierarchyListener}s
5465      *         or an empty array if no hierarchy
5466      *         listeners are currently registered
5467      *
5468      * @see      #addHierarchyListener
5469      * @see      #removeHierarchyListener
5470      * @since    1.4
5471      */
5472     public synchronized HierarchyListener[] getHierarchyListeners() {
5473         return getListeners(HierarchyListener.class);
5474     }
5475 
5476     /**
5477      * Adds the specified hierarchy bounds listener to receive hierarchy
5478      * bounds events from this component when the hierarchy to which this
5479      * container belongs changes.
5480      * If listener {@code l} is {@code null},
5481      * no exception is thrown and no action is performed.
5482      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5483      * >AWT Threading Issues</a> for details on AWT's threading model.
5484      *
5485      * @param    l   the hierarchy bounds listener
5486      * @see      java.awt.event.HierarchyEvent
5487      * @see      java.awt.event.HierarchyBoundsListener
5488      * @see      #removeHierarchyBoundsListener
5489      * @see      #getHierarchyBoundsListeners
5490      * @since    1.3
5491      */
5492     public void addHierarchyBoundsListener(HierarchyBoundsListener l) {
5493         if (l == null) {
5494             return;
5495         }
5496         boolean notifyAncestors;
5497         synchronized (this) {
5498             notifyAncestors =
5499                 (hierarchyBoundsListener == null &&
5500                  (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) == 0);
5501             hierarchyBoundsListener =
5502                 AWTEventMulticaster.add(hierarchyBoundsListener, l);
5503             notifyAncestors = (notifyAncestors &&
5504                                hierarchyBoundsListener != null);
5505             newEventsOnly = true;
5506         }
5507         if (notifyAncestors) {
5508             synchronized (getTreeLock()) {
5509                 adjustListeningChildrenOnParent(
5510                                                 AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK, 1);
5511             }
5512         }
5513     }
5514 
5515     /**
5516      * Removes the specified hierarchy bounds listener so that it no longer
5517      * receives hierarchy bounds events from this component. This method
5518      * performs no function, nor does it throw an exception, if the listener
5519      * specified by the argument was not previously added to this component.
5520      * If listener {@code l} is {@code null},
5521      * no exception is thrown and no action is performed.
5522      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5523      * >AWT Threading Issues</a> for details on AWT's threading model.
5524      *
5525      * @param    l   the hierarchy bounds listener
5526      * @see      java.awt.event.HierarchyEvent
5527      * @see      java.awt.event.HierarchyBoundsListener
5528      * @see      #addHierarchyBoundsListener
5529      * @see      #getHierarchyBoundsListeners
5530      * @since    1.3
5531      */
5532     public void removeHierarchyBoundsListener(HierarchyBoundsListener l) {
5533         if (l == null) {
5534             return;
5535         }
5536         boolean notifyAncestors;
5537         synchronized (this) {
5538             notifyAncestors =
5539                 (hierarchyBoundsListener != null &&
5540                  (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) == 0);
5541             hierarchyBoundsListener =
5542                 AWTEventMulticaster.remove(hierarchyBoundsListener, l);
5543             notifyAncestors = (notifyAncestors &&
5544                                hierarchyBoundsListener == null);
5545         }
5546         if (notifyAncestors) {
5547             synchronized (getTreeLock()) {
5548                 adjustListeningChildrenOnParent(
5549                                                 AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK, -1);
5550             }
5551         }
5552     }
5553 
5554     // Should only be called while holding the tree lock
5555     int numListening(long mask) {
5556         // One mask or the other, but not neither or both.
5557         if (eventLog.isLoggable(PlatformLogger.Level.FINE)) {
5558             if ((mask != AWTEvent.HIERARCHY_EVENT_MASK) &&
5559                 (mask != AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK))
5560             {
5561                 eventLog.fine("Assertion failed");
5562             }
5563         }
5564         if ((mask == AWTEvent.HIERARCHY_EVENT_MASK &&
5565              (hierarchyListener != null ||
5566               (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0)) ||
5567             (mask == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK &&
5568              (hierarchyBoundsListener != null ||
5569               (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0))) {
5570             return 1;
5571         } else {
5572             return 0;
5573         }
5574     }
5575 
5576     // Should only be called while holding tree lock
5577     int countHierarchyMembers() {
5578         return 1;
5579     }
5580     // Should only be called while holding the tree lock
5581     int createHierarchyEvents(int id, Component changed,
5582                               Container changedParent, long changeFlags,
5583                               boolean enabledOnToolkit) {
5584         switch (id) {
5585           case HierarchyEvent.HIERARCHY_CHANGED:
5586               if (hierarchyListener != null ||
5587                   (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 ||
5588                   enabledOnToolkit) {
5589                   HierarchyEvent e = new HierarchyEvent(this, id, changed,
5590                                                         changedParent,
5591                                                         changeFlags);
5592                   dispatchEvent(e);
5593                   return 1;
5594               }
5595               break;
5596           case HierarchyEvent.ANCESTOR_MOVED:
5597           case HierarchyEvent.ANCESTOR_RESIZED:
5598               if (eventLog.isLoggable(PlatformLogger.Level.FINE)) {
5599                   if (changeFlags != 0) {
5600                       eventLog.fine("Assertion (changeFlags == 0) failed");
5601                   }
5602               }
5603               if (hierarchyBoundsListener != null ||
5604                   (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 ||
5605                   enabledOnToolkit) {
5606                   HierarchyEvent e = new HierarchyEvent(this, id, changed,
5607                                                         changedParent);
5608                   dispatchEvent(e);
5609                   return 1;
5610               }
5611               break;
5612           default:
5613               // assert false
5614               if (eventLog.isLoggable(PlatformLogger.Level.FINE)) {
5615                   eventLog.fine("This code must never be reached");
5616               }
5617               break;
5618         }
5619         return 0;
5620     }
5621 
5622     /**
5623      * Returns an array of all the hierarchy bounds listeners
5624      * registered on this component.
5625      *
5626      * @return all of this component's {@code HierarchyBoundsListener}s
5627      *         or an empty array if no hierarchy bounds
5628      *         listeners are currently registered
5629      *
5630      * @see      #addHierarchyBoundsListener
5631      * @see      #removeHierarchyBoundsListener
5632      * @since    1.4
5633      */
5634     public synchronized HierarchyBoundsListener[] getHierarchyBoundsListeners() {
5635         return getListeners(HierarchyBoundsListener.class);
5636     }
5637 
5638     /*
5639      * Should only be called while holding the tree lock.
5640      * It's added only for overriding in java.awt.Window
5641      * because parent in Window is owner.
5642      */
5643     void adjustListeningChildrenOnParent(long mask, int num) {
5644         if (parent != null) {
5645             parent.adjustListeningChildren(mask, num);
5646         }
5647     }
5648 
5649     /**
5650      * Adds the specified key listener to receive key events from
5651      * this component.
5652      * If l is null, no exception is thrown and no action is performed.
5653      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5654      * >AWT Threading Issues</a> for details on AWT's threading model.
5655      *
5656      * @param    l   the key listener.
5657      * @see      java.awt.event.KeyEvent
5658      * @see      java.awt.event.KeyListener
5659      * @see      #removeKeyListener
5660      * @see      #getKeyListeners
5661      * @since    1.1
5662      */
5663     public synchronized void addKeyListener(KeyListener l) {
5664         if (l == null) {
5665             return;
5666         }
5667         keyListener = AWTEventMulticaster.add(keyListener, l);
5668         newEventsOnly = true;
5669 
5670         // if this is a lightweight component, enable key events
5671         // in the native container.
5672         if (peer instanceof LightweightPeer) {
5673             parent.proxyEnableEvents(AWTEvent.KEY_EVENT_MASK);
5674         }
5675     }
5676 
5677     /**
5678      * Removes the specified key listener so that it no longer
5679      * receives key events from this component. This method performs
5680      * no function, nor does it throw an exception, if the listener
5681      * specified by the argument was not previously added to this component.
5682      * If listener {@code l} is {@code null},
5683      * no exception is thrown and no action is performed.
5684      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5685      * >AWT Threading Issues</a> for details on AWT's threading model.
5686      *
5687      * @param    l   the key listener
5688      * @see      java.awt.event.KeyEvent
5689      * @see      java.awt.event.KeyListener
5690      * @see      #addKeyListener
5691      * @see      #getKeyListeners
5692      * @since    1.1
5693      */
5694     public synchronized void removeKeyListener(KeyListener l) {
5695         if (l == null) {
5696             return;
5697         }
5698         keyListener = AWTEventMulticaster.remove(keyListener, l);
5699     }
5700 
5701     /**
5702      * Returns an array of all the key listeners
5703      * registered on this component.
5704      *
5705      * @return all of this component's {@code KeyListener}s
5706      *         or an empty array if no key
5707      *         listeners are currently registered
5708      *
5709      * @see      #addKeyListener
5710      * @see      #removeKeyListener
5711      * @since    1.4
5712      */
5713     public synchronized KeyListener[] getKeyListeners() {
5714         return getListeners(KeyListener.class);
5715     }
5716 
5717     /**
5718      * Adds the specified mouse listener to receive mouse events from
5719      * this component.
5720      * If listener {@code l} is {@code null},
5721      * no exception is thrown and no action is performed.
5722      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5723      * >AWT Threading Issues</a> for details on AWT's threading model.
5724      *
5725      * @param    l   the mouse listener
5726      * @see      java.awt.event.MouseEvent
5727      * @see      java.awt.event.MouseListener
5728      * @see      #removeMouseListener
5729      * @see      #getMouseListeners
5730      * @since    1.1
5731      */
5732     public synchronized void addMouseListener(MouseListener l) {
5733         if (l == null) {
5734             return;
5735         }
5736         mouseListener = AWTEventMulticaster.add(mouseListener,l);
5737         newEventsOnly = true;
5738 
5739         // if this is a lightweight component, enable mouse events
5740         // in the native container.
5741         if (peer instanceof LightweightPeer) {
5742             parent.proxyEnableEvents(AWTEvent.MOUSE_EVENT_MASK);
5743         }
5744     }
5745 
5746     /**
5747      * Removes the specified mouse listener so that it no longer
5748      * receives mouse events from this component. This method performs
5749      * no function, nor does it throw an exception, if the listener
5750      * specified by the argument was not previously added to this component.
5751      * If listener {@code l} is {@code null},
5752      * no exception is thrown and no action is performed.
5753      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5754      * >AWT Threading Issues</a> for details on AWT's threading model.
5755      *
5756      * @param    l   the mouse listener
5757      * @see      java.awt.event.MouseEvent
5758      * @see      java.awt.event.MouseListener
5759      * @see      #addMouseListener
5760      * @see      #getMouseListeners
5761      * @since    1.1
5762      */
5763     public synchronized void removeMouseListener(MouseListener l) {
5764         if (l == null) {
5765             return;
5766         }
5767         mouseListener = AWTEventMulticaster.remove(mouseListener, l);
5768     }
5769 
5770     /**
5771      * Returns an array of all the mouse listeners
5772      * registered on this component.
5773      *
5774      * @return all of this component's {@code MouseListener}s
5775      *         or an empty array if no mouse
5776      *         listeners are currently registered
5777      *
5778      * @see      #addMouseListener
5779      * @see      #removeMouseListener
5780      * @since    1.4
5781      */
5782     public synchronized MouseListener[] getMouseListeners() {
5783         return getListeners(MouseListener.class);
5784     }
5785 
5786     /**
5787      * Adds the specified mouse motion listener to receive mouse motion
5788      * events from this component.
5789      * If listener {@code l} is {@code null},
5790      * no exception is thrown and no action is performed.
5791      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5792      * >AWT Threading Issues</a> for details on AWT's threading model.
5793      *
5794      * @param    l   the mouse motion listener
5795      * @see      java.awt.event.MouseEvent
5796      * @see      java.awt.event.MouseMotionListener
5797      * @see      #removeMouseMotionListener
5798      * @see      #getMouseMotionListeners
5799      * @since    1.1
5800      */
5801     public synchronized void addMouseMotionListener(MouseMotionListener l) {
5802         if (l == null) {
5803             return;
5804         }
5805         mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener,l);
5806         newEventsOnly = true;
5807 
5808         // if this is a lightweight component, enable mouse events
5809         // in the native container.
5810         if (peer instanceof LightweightPeer) {
5811             parent.proxyEnableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
5812         }
5813     }
5814 
5815     /**
5816      * Removes the specified mouse motion listener so that it no longer
5817      * receives mouse motion events from this component. This method performs
5818      * no function, nor does it throw an exception, if the listener
5819      * specified by the argument was not previously added to this component.
5820      * If listener {@code l} is {@code null},
5821      * no exception is thrown and no action is performed.
5822      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5823      * >AWT Threading Issues</a> for details on AWT's threading model.
5824      *
5825      * @param    l   the mouse motion listener
5826      * @see      java.awt.event.MouseEvent
5827      * @see      java.awt.event.MouseMotionListener
5828      * @see      #addMouseMotionListener
5829      * @see      #getMouseMotionListeners
5830      * @since    1.1
5831      */
5832     public synchronized void removeMouseMotionListener(MouseMotionListener l) {
5833         if (l == null) {
5834             return;
5835         }
5836         mouseMotionListener = AWTEventMulticaster.remove(mouseMotionListener, l);
5837     }
5838 
5839     /**
5840      * Returns an array of all the mouse motion listeners
5841      * registered on this component.
5842      *
5843      * @return all of this component's {@code MouseMotionListener}s
5844      *         or an empty array if no mouse motion
5845      *         listeners are currently registered
5846      *
5847      * @see      #addMouseMotionListener
5848      * @see      #removeMouseMotionListener
5849      * @since    1.4
5850      */
5851     public synchronized MouseMotionListener[] getMouseMotionListeners() {
5852         return getListeners(MouseMotionListener.class);
5853     }
5854 
5855     /**
5856      * Adds the specified mouse wheel listener to receive mouse wheel events
5857      * from this component.  Containers also receive mouse wheel events from
5858      * sub-components.
5859      * <p>
5860      * For information on how mouse wheel events are dispatched, see
5861      * the class description for {@link MouseWheelEvent}.
5862      * <p>
5863      * If l is {@code null}, no exception is thrown and no
5864      * action is performed.
5865      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5866      * >AWT Threading Issues</a> for details on AWT's threading model.
5867      *
5868      * @param    l   the mouse wheel listener
5869      * @see      java.awt.event.MouseWheelEvent
5870      * @see      java.awt.event.MouseWheelListener
5871      * @see      #removeMouseWheelListener
5872      * @see      #getMouseWheelListeners
5873      * @since    1.4
5874      */
5875     public synchronized void addMouseWheelListener(MouseWheelListener l) {
5876         if (l == null) {
5877             return;
5878         }
5879         mouseWheelListener = AWTEventMulticaster.add(mouseWheelListener,l);
5880         newEventsOnly = true;
5881 
5882         // if this is a lightweight component, enable mouse events
5883         // in the native container.
5884         if (peer instanceof LightweightPeer) {
5885             parent.proxyEnableEvents(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
5886         }
5887     }
5888 
5889     /**
5890      * Removes the specified mouse wheel listener so that it no longer
5891      * receives mouse wheel events from this component. This method performs
5892      * no function, nor does it throw an exception, if the listener
5893      * specified by the argument was not previously added to this component.
5894      * If l is null, no exception is thrown and no action is performed.
5895      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5896      * >AWT Threading Issues</a> for details on AWT's threading model.
5897      *
5898      * @param    l   the mouse wheel listener.
5899      * @see      java.awt.event.MouseWheelEvent
5900      * @see      java.awt.event.MouseWheelListener
5901      * @see      #addMouseWheelListener
5902      * @see      #getMouseWheelListeners
5903      * @since    1.4
5904      */
5905     public synchronized void removeMouseWheelListener(MouseWheelListener l) {
5906         if (l == null) {
5907             return;
5908         }
5909         mouseWheelListener = AWTEventMulticaster.remove(mouseWheelListener, l);
5910     }
5911 
5912     /**
5913      * Returns an array of all the mouse wheel listeners
5914      * registered on this component.
5915      *
5916      * @return all of this component's {@code MouseWheelListener}s
5917      *         or an empty array if no mouse wheel
5918      *         listeners are currently registered
5919      *
5920      * @see      #addMouseWheelListener
5921      * @see      #removeMouseWheelListener
5922      * @since    1.4
5923      */
5924     public synchronized MouseWheelListener[] getMouseWheelListeners() {
5925         return getListeners(MouseWheelListener.class);
5926     }
5927 
5928     /**
5929      * Adds the specified input method listener to receive
5930      * input method events from this component. A component will
5931      * only receive input method events from input methods
5932      * if it also overrides {@code getInputMethodRequests} to return an
5933      * {@code InputMethodRequests} instance.
5934      * If listener {@code l} is {@code null},
5935      * no exception is thrown and no action is performed.
5936      * <p>Refer to <a href="{@docRoot}/java/awt/doc-files/AWTThreadIssues.html#ListenersThreads"
5937      * >AWT Threading Issues</a> for details on AWT's threading model.
5938      *
5939      * @param    l   the input method listener
5940      * @see      java.awt.event.InputMethodEvent
5941      * @see      java.awt.event.InputMethodListener
5942      * @see      #removeInputMethodListener
5943      * @see      #getInputMethodListeners
5944      * @see      #getInputMethodRequests
5945      * @since    1.2
5946      */
5947     public synchronized void addInputMethodListener(InputMethodListener l) {
5948         if (l == null) {
5949             return;
5950         }
5951         inputMethodListener = AWTEventMulticaster.add(inputMethodListener, l);
5952         newEventsOnly = true;
5953     }
5954 
5955     /**
5956      * Removes the specified input method listener so that it no longer
5957      * receives input method events from this component. This method performs
5958      * no function, nor does it throw an exception, if the listener
5959      * specified by the argument was not previously added to this component.
5960      * If listener {@code l} is {@code null},
5961      * no exception is thrown and no action is performed.
5962      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5963      * >AWT Threading Issues</a> for details on AWT's threading model.
5964      *
5965      * @param    l   the input method listener
5966      * @see      java.awt.event.InputMethodEvent
5967      * @see      java.awt.event.InputMethodListener
5968      * @see      #addInputMethodListener
5969      * @see      #getInputMethodListeners
5970      * @since    1.2
5971      */
5972     public synchronized void removeInputMethodListener(InputMethodListener l) {
5973         if (l == null) {
5974             return;
5975         }
5976         inputMethodListener = AWTEventMulticaster.remove(inputMethodListener, l);
5977     }
5978 
5979     /**
5980      * Returns an array of all the input method listeners
5981      * registered on this component.
5982      *
5983      * @return all of this component's {@code InputMethodListener}s
5984      *         or an empty array if no input method
5985      *         listeners are currently registered
5986      *
5987      * @see      #addInputMethodListener
5988      * @see      #removeInputMethodListener
5989      * @since    1.4
5990      */
5991     public synchronized InputMethodListener[] getInputMethodListeners() {
5992         return getListeners(InputMethodListener.class);
5993     }
5994 
5995     /**
5996      * Returns an array of all the objects currently registered
5997      * as <code><em>Foo</em>Listener</code>s
5998      * upon this {@code Component}.
5999      * <code><em>Foo</em>Listener</code>s are registered using the
6000      * <code>add<em>Foo</em>Listener</code> method.
6001      *
6002      * <p>
6003      * You can specify the {@code listenerType} argument
6004      * with a class literal, such as
6005      * <code><em>Foo</em>Listener.class</code>.
6006      * For example, you can query a
6007      * {@code Component c}
6008      * for its mouse listeners with the following code:
6009      *
6010      * <pre>MouseListener[] mls = (MouseListener[])(c.getListeners(MouseListener.class));</pre>
6011      *
6012      * If no such listeners exist, this method returns an empty array.
6013      *
6014      * @param <T> the type of the listeners
6015      * @param listenerType the type of listeners requested; this parameter
6016      *          should specify an interface that descends from
6017      *          {@code java.util.EventListener}
6018      * @return an array of all objects registered as
6019      *          <code><em>Foo</em>Listener</code>s on this component,
6020      *          or an empty array if no such listeners have been added
6021      * @exception ClassCastException if {@code listenerType}
6022      *          doesn't specify a class or interface that implements
6023      *          {@code java.util.EventListener}
6024      * @throws NullPointerException if {@code listenerType} is {@code null}
6025      * @see #getComponentListeners
6026      * @see #getFocusListeners
6027      * @see #getHierarchyListeners
6028      * @see #getHierarchyBoundsListeners
6029      * @see #getKeyListeners
6030      * @see #getMouseListeners
6031      * @see #getMouseMotionListeners
6032      * @see #getMouseWheelListeners
6033      * @see #getInputMethodListeners
6034      * @see #getPropertyChangeListeners
6035      *
6036      * @since 1.3
6037      */
6038     @SuppressWarnings("unchecked")
6039     public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
6040         EventListener l = null;
6041         if  (listenerType == ComponentListener.class) {
6042             l = componentListener;
6043         } else if (listenerType == FocusListener.class) {
6044             l = focusListener;
6045         } else if (listenerType == HierarchyListener.class) {
6046             l = hierarchyListener;
6047         } else if (listenerType == HierarchyBoundsListener.class) {
6048             l = hierarchyBoundsListener;
6049         } else if (listenerType == KeyListener.class) {
6050             l = keyListener;
6051         } else if (listenerType == MouseListener.class) {
6052             l = mouseListener;
6053         } else if (listenerType == MouseMotionListener.class) {
6054             l = mouseMotionListener;
6055         } else if (listenerType == MouseWheelListener.class) {
6056             l = mouseWheelListener;
6057         } else if (listenerType == InputMethodListener.class) {
6058             l = inputMethodListener;
6059         } else if (listenerType == PropertyChangeListener.class) {
6060             return (T[])getPropertyChangeListeners();
6061         }
6062         return AWTEventMulticaster.getListeners(l, listenerType);
6063     }
6064 
6065     /**
6066      * Gets the input method request handler which supports
6067      * requests from input methods for this component. A component
6068      * that supports on-the-spot text input must override this
6069      * method to return an {@code InputMethodRequests} instance.
6070      * At the same time, it also has to handle input method events.
6071      *
6072      * @return the input method request handler for this component,
6073      *          {@code null} by default
6074      * @see #addInputMethodListener
6075      * @since 1.2
6076      */
6077     public InputMethodRequests getInputMethodRequests() {
6078         return null;
6079     }
6080 
6081     /**
6082      * Gets the input context used by this component for handling
6083      * the communication with input methods when text is entered
6084      * in this component. By default, the input context used for
6085      * the parent component is returned. Components may
6086      * override this to return a private input context.
6087      *
6088      * @return the input context used by this component;
6089      *          {@code null} if no context can be determined
6090      * @since 1.2
6091      */
6092     public InputContext getInputContext() {
6093         Container parent = this.parent;
6094         if (parent == null) {
6095             return null;
6096         } else {
6097             return parent.getInputContext();
6098         }
6099     }
6100 
6101     /**
6102      * Enables the events defined by the specified event mask parameter
6103      * to be delivered to this component.
6104      * <p>
6105      * Event types are automatically enabled when a listener for
6106      * that event type is added to the component.
6107      * <p>
6108      * This method only needs to be invoked by subclasses of
6109      * {@code Component} which desire to have the specified event
6110      * types delivered to {@code processEvent} regardless of whether
6111      * or not a listener is registered.
6112      * @param      eventsToEnable   the event mask defining the event types
6113      * @see        #processEvent
6114      * @see        #disableEvents
6115      * @see        AWTEvent
6116      * @since      1.1
6117      */
6118     protected final void enableEvents(long eventsToEnable) {
6119         long notifyAncestors = 0;
6120         synchronized (this) {
6121             if ((eventsToEnable & AWTEvent.HIERARCHY_EVENT_MASK) != 0 &&
6122                 hierarchyListener == null &&
6123                 (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) == 0) {
6124                 notifyAncestors |= AWTEvent.HIERARCHY_EVENT_MASK;
6125             }
6126             if ((eventsToEnable & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 &&
6127                 hierarchyBoundsListener == null &&
6128                 (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) == 0) {
6129                 notifyAncestors |= AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK;
6130             }
6131             eventMask |= eventsToEnable;
6132             newEventsOnly = true;
6133         }
6134 
6135         // if this is a lightweight component, enable mouse events
6136         // in the native container.
6137         if (peer instanceof LightweightPeer) {
6138             parent.proxyEnableEvents(eventMask);
6139         }
6140         if (notifyAncestors != 0) {
6141             synchronized (getTreeLock()) {
6142                 adjustListeningChildrenOnParent(notifyAncestors, 1);
6143             }
6144         }
6145     }
6146 
6147     /**
6148      * Disables the events defined by the specified event mask parameter
6149      * from being delivered to this component.
6150      * @param      eventsToDisable   the event mask defining the event types
6151      * @see        #enableEvents
6152      * @since      1.1
6153      */
6154     protected final void disableEvents(long eventsToDisable) {
6155         long notifyAncestors = 0;
6156         synchronized (this) {
6157             if ((eventsToDisable & AWTEvent.HIERARCHY_EVENT_MASK) != 0 &&
6158                 hierarchyListener == null &&
6159                 (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0) {
6160                 notifyAncestors |= AWTEvent.HIERARCHY_EVENT_MASK;
6161             }
6162             if ((eventsToDisable & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK)!=0 &&
6163                 hierarchyBoundsListener == null &&
6164                 (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0) {
6165                 notifyAncestors |= AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK;
6166             }
6167             eventMask &= ~eventsToDisable;
6168         }
6169         if (notifyAncestors != 0) {
6170             synchronized (getTreeLock()) {
6171                 adjustListeningChildrenOnParent(notifyAncestors, -1);
6172             }
6173         }
6174     }
6175 
6176     transient sun.awt.EventQueueItem[] eventCache;
6177 
6178     /**
6179      * @see #isCoalescingEnabled
6180      * @see #checkCoalescing
6181      */
6182     private transient boolean coalescingEnabled = checkCoalescing();
6183 
6184     /**
6185      * Weak map of known coalesceEvent overriders.
6186      * Value indicates whether overriden.
6187      * Bootstrap classes are not included.
6188      */
6189     private static final Map<Class<?>, Boolean> coalesceMap =
6190         new java.util.WeakHashMap<Class<?>, Boolean>();
6191 
6192     /**
6193      * Indicates whether this class overrides coalesceEvents.
6194      * It is assumed that all classes that are loaded from the bootstrap
6195      *   do not.
6196      * The bootstrap class loader is assumed to be represented by null.
6197      * We do not check that the method really overrides
6198      *   (it might be static, private or package private).
6199      */
6200      private boolean checkCoalescing() {
6201          if (getClass().getClassLoader()==null) {
6202              return false;
6203          }
6204          final Class<? extends Component> clazz = getClass();
6205          synchronized (coalesceMap) {
6206              // Check cache.
6207              Boolean value = coalesceMap.get(clazz);
6208              if (value != null) {
6209                  return value;
6210              }
6211 
6212              // Need to check non-bootstraps.
6213              Boolean enabled = java.security.AccessController.doPrivileged(
6214                  new java.security.PrivilegedAction<Boolean>() {
6215                      public Boolean run() {
6216                          return isCoalesceEventsOverriden(clazz);
6217                      }
6218                  }
6219                  );
6220              coalesceMap.put(clazz, enabled);
6221              return enabled;
6222          }
6223      }
6224 
6225     /**
6226      * Parameter types of coalesceEvents(AWTEvent,AWTEVent).
6227      */
6228     private static final Class<?>[] coalesceEventsParams = {
6229         AWTEvent.class, AWTEvent.class
6230     };
6231 
6232     /**
6233      * Indicates whether a class or its superclasses override coalesceEvents.
6234      * Must be called with lock on coalesceMap and privileged.
6235      * @see checkCoalescing
6236      */
6237     private static boolean isCoalesceEventsOverriden(Class<?> clazz) {
6238         assert Thread.holdsLock(coalesceMap);
6239 
6240         // First check superclass - we may not need to bother ourselves.
6241         Class<?> superclass = clazz.getSuperclass();
6242         if (superclass == null) {
6243             // Only occurs on implementations that
6244             //   do not use null to represent the bootstrap class loader.
6245             return false;
6246         }
6247         if (superclass.getClassLoader() != null) {
6248             Boolean value = coalesceMap.get(superclass);
6249             if (value == null) {
6250                 // Not done already - recurse.
6251                 if (isCoalesceEventsOverriden(superclass)) {
6252                     coalesceMap.put(superclass, true);
6253                     return true;
6254                 }
6255             } else if (value) {
6256                 return true;
6257             }
6258         }
6259 
6260         try {
6261             // Throws if not overriden.
6262             clazz.getDeclaredMethod(
6263                 "coalesceEvents", coalesceEventsParams
6264                 );
6265             return true;
6266         } catch (NoSuchMethodException e) {
6267             // Not present in this class.
6268             return false;
6269         }
6270     }
6271 
6272     /**
6273      * Indicates whether coalesceEvents may do something.
6274      */
6275     final boolean isCoalescingEnabled() {
6276         return coalescingEnabled;
6277      }
6278 
6279 
6280     /**
6281      * Potentially coalesce an event being posted with an existing
6282      * event.  This method is called by {@code EventQueue.postEvent}
6283      * if an event with the same ID as the event to be posted is found in
6284      * the queue (both events must have this component as their source).
6285      * This method either returns a coalesced event which replaces
6286      * the existing event (and the new event is then discarded), or
6287      * {@code null} to indicate that no combining should be done
6288      * (add the second event to the end of the queue).  Either event
6289      * parameter may be modified and returned, as the other one is discarded
6290      * unless {@code null} is returned.
6291      * <p>
6292      * This implementation of {@code coalesceEvents} coalesces
6293      * two event types: mouse move (and drag) events,
6294      * and paint (and update) events.
6295      * For mouse move events the last event is always returned, causing
6296      * intermediate moves to be discarded.  For paint events, the new
6297      * event is coalesced into a complex {@code RepaintArea} in the peer.
6298      * The new {@code AWTEvent} is always returned.
6299      *
6300      * @param  existingEvent  the event already on the {@code EventQueue}
6301      * @param  newEvent       the event being posted to the
6302      *          {@code EventQueue}
6303      * @return a coalesced event, or {@code null} indicating that no
6304      *          coalescing was done
6305      */
6306     protected AWTEvent coalesceEvents(AWTEvent existingEvent,
6307                                       AWTEvent newEvent) {
6308         return null;
6309     }
6310 
6311     /**
6312      * Processes events occurring on this component. By default this
6313      * method calls the appropriate
6314      * <code>process&lt;event&nbsp;type&gt;Event</code>
6315      * method for the given class of event.
6316      * <p>Note that if the event parameter is {@code null}
6317      * the behavior is unspecified and may result in an
6318      * exception.
6319      *
6320      * @param     e the event
6321      * @see       #processComponentEvent
6322      * @see       #processFocusEvent
6323      * @see       #processKeyEvent
6324      * @see       #processMouseEvent
6325      * @see       #processMouseMotionEvent
6326      * @see       #processInputMethodEvent
6327      * @see       #processHierarchyEvent
6328      * @see       #processMouseWheelEvent
6329      * @since     1.1
6330      */
6331     protected void processEvent(AWTEvent e) {
6332         if (e instanceof FocusEvent) {
6333             processFocusEvent((FocusEvent)e);
6334 
6335         } else if (e instanceof MouseEvent) {
6336             switch(e.getID()) {
6337               case MouseEvent.MOUSE_PRESSED:
6338               case MouseEvent.MOUSE_RELEASED:
6339               case MouseEvent.MOUSE_CLICKED:
6340               case MouseEvent.MOUSE_ENTERED:
6341               case MouseEvent.MOUSE_EXITED:
6342                   processMouseEvent((MouseEvent)e);
6343                   break;
6344               case MouseEvent.MOUSE_MOVED:
6345               case MouseEvent.MOUSE_DRAGGED:
6346                   processMouseMotionEvent((MouseEvent)e);
6347                   break;
6348               case MouseEvent.MOUSE_WHEEL:
6349                   processMouseWheelEvent((MouseWheelEvent)e);
6350                   break;
6351             }
6352 
6353         } else if (e instanceof KeyEvent) {
6354             processKeyEvent((KeyEvent)e);
6355 
6356         } else if (e instanceof ComponentEvent) {
6357             processComponentEvent((ComponentEvent)e);
6358         } else if (e instanceof InputMethodEvent) {
6359             processInputMethodEvent((InputMethodEvent)e);
6360         } else if (e instanceof HierarchyEvent) {
6361             switch (e.getID()) {
6362               case HierarchyEvent.HIERARCHY_CHANGED:
6363                   processHierarchyEvent((HierarchyEvent)e);
6364                   break;
6365               case HierarchyEvent.ANCESTOR_MOVED:
6366               case HierarchyEvent.ANCESTOR_RESIZED:
6367                   processHierarchyBoundsEvent((HierarchyEvent)e);
6368                   break;
6369             }
6370         }
6371     }
6372 
6373     /**
6374      * Processes component events occurring on this component by
6375      * dispatching them to any registered
6376      * {@code ComponentListener} objects.
6377      * <p>
6378      * This method is not called unless component events are
6379      * enabled for this component. Component events are enabled
6380      * when one of the following occurs:
6381      * <ul>
6382      * <li>A {@code ComponentListener} object is registered
6383      * via {@code addComponentListener}.
6384      * <li>Component events are enabled via {@code enableEvents}.
6385      * </ul>
6386      * <p>Note that if the event parameter is {@code null}
6387      * the behavior is unspecified and may result in an
6388      * exception.
6389      *
6390      * @param       e the component event
6391      * @see         java.awt.event.ComponentEvent
6392      * @see         java.awt.event.ComponentListener
6393      * @see         #addComponentListener
6394      * @see         #enableEvents
6395      * @since       1.1
6396      */
6397     protected void processComponentEvent(ComponentEvent e) {
6398         ComponentListener listener = componentListener;
6399         if (listener != null) {
6400             int id = e.getID();
6401             switch(id) {
6402               case ComponentEvent.COMPONENT_RESIZED:
6403                   listener.componentResized(e);
6404                   break;
6405               case ComponentEvent.COMPONENT_MOVED:
6406                   listener.componentMoved(e);
6407                   break;
6408               case ComponentEvent.COMPONENT_SHOWN:
6409                   listener.componentShown(e);
6410                   break;
6411               case ComponentEvent.COMPONENT_HIDDEN:
6412                   listener.componentHidden(e);
6413                   break;
6414             }
6415         }
6416     }
6417 
6418     /**
6419      * Processes focus events occurring on this component by
6420      * dispatching them to any registered
6421      * {@code FocusListener} objects.
6422      * <p>
6423      * This method is not called unless focus events are
6424      * enabled for this component. Focus events are enabled
6425      * when one of the following occurs:
6426      * <ul>
6427      * <li>A {@code FocusListener} object is registered
6428      * via {@code addFocusListener}.
6429      * <li>Focus events are enabled via {@code enableEvents}.
6430      * </ul>
6431      * <p>
6432      * If focus events are enabled for a {@code Component},
6433      * the current {@code KeyboardFocusManager} determines
6434      * whether or not a focus event should be dispatched to
6435      * registered {@code FocusListener} objects.  If the
6436      * events are to be dispatched, the {@code KeyboardFocusManager}
6437      * calls the {@code Component}'s {@code dispatchEvent}
6438      * method, which results in a call to the {@code Component}'s
6439      * {@code processFocusEvent} method.
6440      * <p>
6441      * If focus events are enabled for a {@code Component}, calling
6442      * the {@code Component}'s {@code dispatchEvent} method
6443      * with a {@code FocusEvent} as the argument will result in a
6444      * call to the {@code Component}'s {@code processFocusEvent}
6445      * method regardless of the current {@code KeyboardFocusManager}.
6446      *
6447      * <p>Note that if the event parameter is {@code null}
6448      * the behavior is unspecified and may result in an
6449      * exception.
6450      *
6451      * @param       e the focus event
6452      * @see         java.awt.event.FocusEvent
6453      * @see         java.awt.event.FocusListener
6454      * @see         java.awt.KeyboardFocusManager
6455      * @see         #addFocusListener
6456      * @see         #enableEvents
6457      * @see         #dispatchEvent
6458      * @since       1.1
6459      */
6460     protected void processFocusEvent(FocusEvent e) {
6461         FocusListener listener = focusListener;
6462         if (listener != null) {
6463             int id = e.getID();
6464             switch(id) {
6465               case FocusEvent.FOCUS_GAINED:
6466                   listener.focusGained(e);
6467                   break;
6468               case FocusEvent.FOCUS_LOST:
6469                   listener.focusLost(e);
6470                   break;
6471             }
6472         }
6473     }
6474 
6475     /**
6476      * Processes key events occurring on this component by
6477      * dispatching them to any registered
6478      * {@code KeyListener} objects.
6479      * <p>
6480      * This method is not called unless key events are
6481      * enabled for this component. Key events are enabled
6482      * when one of the following occurs:
6483      * <ul>
6484      * <li>A {@code KeyListener} object is registered
6485      * via {@code addKeyListener}.
6486      * <li>Key events are enabled via {@code enableEvents}.
6487      * </ul>
6488      *
6489      * <p>
6490      * If key events are enabled for a {@code Component},
6491      * the current {@code KeyboardFocusManager} determines
6492      * whether or not a key event should be dispatched to
6493      * registered {@code KeyListener} objects.  The
6494      * {@code DefaultKeyboardFocusManager} will not dispatch
6495      * key events to a {@code Component} that is not the focus
6496      * owner or is not showing.
6497      * <p>
6498      * As of J2SE 1.4, {@code KeyEvent}s are redirected to
6499      * the focus owner. Please see the
6500      * <a href="doc-files/FocusSpec.html">Focus Specification</a>
6501      * for further information.
6502      * <p>
6503      * Calling a {@code Component}'s {@code dispatchEvent}
6504      * method with a {@code KeyEvent} as the argument will
6505      * result in a call to the {@code Component}'s
6506      * {@code processKeyEvent} method regardless of the
6507      * current {@code KeyboardFocusManager} as long as the
6508      * component is showing, focused, and enabled, and key events
6509      * are enabled on it.
6510      * <p>If the event parameter is {@code null}
6511      * the behavior is unspecified and may result in an
6512      * exception.
6513      *
6514      * @param       e the key event
6515      * @see         java.awt.event.KeyEvent
6516      * @see         java.awt.event.KeyListener
6517      * @see         java.awt.KeyboardFocusManager
6518      * @see         java.awt.DefaultKeyboardFocusManager
6519      * @see         #processEvent
6520      * @see         #dispatchEvent
6521      * @see         #addKeyListener
6522      * @see         #enableEvents
6523      * @see         #isShowing
6524      * @since       1.1
6525      */
6526     protected void processKeyEvent(KeyEvent e) {
6527         KeyListener listener = keyListener;
6528         if (listener != null) {
6529             int id = e.getID();
6530             switch(id) {
6531               case KeyEvent.KEY_TYPED:
6532                   listener.keyTyped(e);
6533                   break;
6534               case KeyEvent.KEY_PRESSED:
6535                   listener.keyPressed(e);
6536                   break;
6537               case KeyEvent.KEY_RELEASED:
6538                   listener.keyReleased(e);
6539                   break;
6540             }
6541         }
6542     }
6543 
6544     /**
6545      * Processes mouse events occurring on this component by
6546      * dispatching them to any registered
6547      * {@code MouseListener} objects.
6548      * <p>
6549      * This method is not called unless mouse events are
6550      * enabled for this component. Mouse events are enabled
6551      * when one of the following occurs:
6552      * <ul>
6553      * <li>A {@code MouseListener} object is registered
6554      * via {@code addMouseListener}.
6555      * <li>Mouse events are enabled via {@code enableEvents}.
6556      * </ul>
6557      * <p>Note that if the event parameter is {@code null}
6558      * the behavior is unspecified and may result in an
6559      * exception.
6560      *
6561      * @param       e the mouse event
6562      * @see         java.awt.event.MouseEvent
6563      * @see         java.awt.event.MouseListener
6564      * @see         #addMouseListener
6565      * @see         #enableEvents
6566      * @since       1.1
6567      */
6568     protected void processMouseEvent(MouseEvent e) {
6569         MouseListener listener = mouseListener;
6570         if (listener != null) {
6571             int id = e.getID();
6572             switch(id) {
6573               case MouseEvent.MOUSE_PRESSED:
6574                   listener.mousePressed(e);
6575                   break;
6576               case MouseEvent.MOUSE_RELEASED:
6577                   listener.mouseReleased(e);
6578                   break;
6579               case MouseEvent.MOUSE_CLICKED:
6580                   listener.mouseClicked(e);
6581                   break;
6582               case MouseEvent.MOUSE_EXITED:
6583                   listener.mouseExited(e);
6584                   break;
6585               case MouseEvent.MOUSE_ENTERED:
6586                   listener.mouseEntered(e);
6587                   break;
6588             }
6589         }
6590     }
6591 
6592     /**
6593      * Processes mouse motion events occurring on this component by
6594      * dispatching them to any registered
6595      * {@code MouseMotionListener} objects.
6596      * <p>
6597      * This method is not called unless mouse motion events are
6598      * enabled for this component. Mouse motion events are enabled
6599      * when one of the following occurs:
6600      * <ul>
6601      * <li>A {@code MouseMotionListener} object is registered
6602      * via {@code addMouseMotionListener}.
6603      * <li>Mouse motion events are enabled via {@code enableEvents}.
6604      * </ul>
6605      * <p>Note that if the event parameter is {@code null}
6606      * the behavior is unspecified and may result in an
6607      * exception.
6608      *
6609      * @param       e the mouse motion event
6610      * @see         java.awt.event.MouseEvent
6611      * @see         java.awt.event.MouseMotionListener
6612      * @see         #addMouseMotionListener
6613      * @see         #enableEvents
6614      * @since       1.1
6615      */
6616     protected void processMouseMotionEvent(MouseEvent e) {
6617         MouseMotionListener listener = mouseMotionListener;
6618         if (listener != null) {
6619             int id = e.getID();
6620             switch(id) {
6621               case MouseEvent.MOUSE_MOVED:
6622                   listener.mouseMoved(e);
6623                   break;
6624               case MouseEvent.MOUSE_DRAGGED:
6625                   listener.mouseDragged(e);
6626                   break;
6627             }
6628         }
6629     }
6630 
6631     /**
6632      * Processes mouse wheel events occurring on this component by
6633      * dispatching them to any registered
6634      * {@code MouseWheelListener} objects.
6635      * <p>
6636      * This method is not called unless mouse wheel events are
6637      * enabled for this component. Mouse wheel events are enabled
6638      * when one of the following occurs:
6639      * <ul>
6640      * <li>A {@code MouseWheelListener} object is registered
6641      * via {@code addMouseWheelListener}.
6642      * <li>Mouse wheel events are enabled via {@code enableEvents}.
6643      * </ul>
6644      * <p>
6645      * For information on how mouse wheel events are dispatched, see
6646      * the class description for {@link MouseWheelEvent}.
6647      * <p>
6648      * Note that if the event parameter is {@code null}
6649      * the behavior is unspecified and may result in an
6650      * exception.
6651      *
6652      * @param       e the mouse wheel event
6653      * @see         java.awt.event.MouseWheelEvent
6654      * @see         java.awt.event.MouseWheelListener
6655      * @see         #addMouseWheelListener
6656      * @see         #enableEvents
6657      * @since       1.4
6658      */
6659     protected void processMouseWheelEvent(MouseWheelEvent e) {
6660         MouseWheelListener listener = mouseWheelListener;
6661         if (listener != null) {
6662             int id = e.getID();
6663             switch(id) {
6664               case MouseEvent.MOUSE_WHEEL:
6665                   listener.mouseWheelMoved(e);
6666                   break;
6667             }
6668         }
6669     }
6670 
6671     boolean postsOldMouseEvents() {
6672         return false;
6673     }
6674 
6675     /**
6676      * Processes input method events occurring on this component by
6677      * dispatching them to any registered
6678      * {@code InputMethodListener} objects.
6679      * <p>
6680      * This method is not called unless input method events
6681      * are enabled for this component. Input method events are enabled
6682      * when one of the following occurs:
6683      * <ul>
6684      * <li>An {@code InputMethodListener} object is registered
6685      * via {@code addInputMethodListener}.
6686      * <li>Input method events are enabled via {@code enableEvents}.
6687      * </ul>
6688      * <p>Note that if the event parameter is {@code null}
6689      * the behavior is unspecified and may result in an
6690      * exception.
6691      *
6692      * @param       e the input method event
6693      * @see         java.awt.event.InputMethodEvent
6694      * @see         java.awt.event.InputMethodListener
6695      * @see         #addInputMethodListener
6696      * @see         #enableEvents
6697      * @since       1.2
6698      */
6699     protected void processInputMethodEvent(InputMethodEvent e) {
6700         InputMethodListener listener = inputMethodListener;
6701         if (listener != null) {
6702             int id = e.getID();
6703             switch (id) {
6704               case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
6705                   listener.inputMethodTextChanged(e);
6706                   break;
6707               case InputMethodEvent.CARET_POSITION_CHANGED:
6708                   listener.caretPositionChanged(e);
6709                   break;
6710             }
6711         }
6712     }
6713 
6714     /**
6715      * Processes hierarchy events occurring on this component by
6716      * dispatching them to any registered
6717      * {@code HierarchyListener} objects.
6718      * <p>
6719      * This method is not called unless hierarchy events
6720      * are enabled for this component. Hierarchy events are enabled
6721      * when one of the following occurs:
6722      * <ul>
6723      * <li>An {@code HierarchyListener} object is registered
6724      * via {@code addHierarchyListener}.
6725      * <li>Hierarchy events are enabled via {@code enableEvents}.
6726      * </ul>
6727      * <p>Note that if the event parameter is {@code null}
6728      * the behavior is unspecified and may result in an
6729      * exception.
6730      *
6731      * @param       e the hierarchy event
6732      * @see         java.awt.event.HierarchyEvent
6733      * @see         java.awt.event.HierarchyListener
6734      * @see         #addHierarchyListener
6735      * @see         #enableEvents
6736      * @since       1.3
6737      */
6738     protected void processHierarchyEvent(HierarchyEvent e) {
6739         HierarchyListener listener = hierarchyListener;
6740         if (listener != null) {
6741             int id = e.getID();
6742             switch (id) {
6743               case HierarchyEvent.HIERARCHY_CHANGED:
6744                   listener.hierarchyChanged(e);
6745                   break;
6746             }
6747         }
6748     }
6749 
6750     /**
6751      * Processes hierarchy bounds events occurring on this component by
6752      * dispatching them to any registered
6753      * {@code HierarchyBoundsListener} objects.
6754      * <p>
6755      * This method is not called unless hierarchy bounds events
6756      * are enabled for this component. Hierarchy bounds events are enabled
6757      * when one of the following occurs:
6758      * <ul>
6759      * <li>An {@code HierarchyBoundsListener} object is registered
6760      * via {@code addHierarchyBoundsListener}.
6761      * <li>Hierarchy bounds events are enabled via {@code enableEvents}.
6762      * </ul>
6763      * <p>Note that if the event parameter is {@code null}
6764      * the behavior is unspecified and may result in an
6765      * exception.
6766      *
6767      * @param       e the hierarchy event
6768      * @see         java.awt.event.HierarchyEvent
6769      * @see         java.awt.event.HierarchyBoundsListener
6770      * @see         #addHierarchyBoundsListener
6771      * @see         #enableEvents
6772      * @since       1.3
6773      */
6774     protected void processHierarchyBoundsEvent(HierarchyEvent e) {
6775         HierarchyBoundsListener listener = hierarchyBoundsListener;
6776         if (listener != null) {
6777             int id = e.getID();
6778             switch (id) {
6779               case HierarchyEvent.ANCESTOR_MOVED:
6780                   listener.ancestorMoved(e);
6781                   break;
6782               case HierarchyEvent.ANCESTOR_RESIZED:
6783                   listener.ancestorResized(e);
6784                   break;
6785             }
6786         }
6787     }
6788 
6789     /**
6790      * @param  evt the event to handle
6791      * @return {@code true} if the event was handled, {@code false} otherwise
6792      * @deprecated As of JDK version 1.1
6793      * replaced by processEvent(AWTEvent).
6794      */
6795     @Deprecated
6796     public boolean handleEvent(Event evt) {
6797         switch (evt.id) {
6798           case Event.MOUSE_ENTER:
6799               return mouseEnter(evt, evt.x, evt.y);
6800 
6801           case Event.MOUSE_EXIT:
6802               return mouseExit(evt, evt.x, evt.y);
6803 
6804           case Event.MOUSE_MOVE:
6805               return mouseMove(evt, evt.x, evt.y);
6806 
6807           case Event.MOUSE_DOWN:
6808               return mouseDown(evt, evt.x, evt.y);
6809 
6810           case Event.MOUSE_DRAG:
6811               return mouseDrag(evt, evt.x, evt.y);
6812 
6813           case Event.MOUSE_UP:
6814               return mouseUp(evt, evt.x, evt.y);
6815 
6816           case Event.KEY_PRESS:
6817           case Event.KEY_ACTION:
6818               return keyDown(evt, evt.key);
6819 
6820           case Event.KEY_RELEASE:
6821           case Event.KEY_ACTION_RELEASE:
6822               return keyUp(evt, evt.key);
6823 
6824           case Event.ACTION_EVENT:
6825               return action(evt, evt.arg);
6826           case Event.GOT_FOCUS:
6827               return gotFocus(evt, evt.arg);
6828           case Event.LOST_FOCUS:
6829               return lostFocus(evt, evt.arg);
6830         }
6831         return false;
6832     }
6833 
6834     /**
6835      * @param  evt the event to handle
6836      * @param  x the x coordinate
6837      * @param  y the y coordinate
6838      * @return {@code false}
6839      * @deprecated As of JDK version 1.1,
6840      * replaced by processMouseEvent(MouseEvent).
6841      */
6842     @Deprecated
6843     public boolean mouseDown(Event evt, int x, int y) {
6844         return false;
6845     }
6846 
6847     /**
6848      * @param  evt the event to handle
6849      * @param  x the x coordinate
6850      * @param  y the y coordinate
6851      * @return {@code false}
6852      * @deprecated As of JDK version 1.1,
6853      * replaced by processMouseMotionEvent(MouseEvent).
6854      */
6855     @Deprecated
6856     public boolean mouseDrag(Event evt, int x, int y) {
6857         return false;
6858     }
6859 
6860     /**
6861      * @param  evt the event to handle
6862      * @param  x the x coordinate
6863      * @param  y the y coordinate
6864      * @return {@code false}
6865      * @deprecated As of JDK version 1.1,
6866      * replaced by processMouseEvent(MouseEvent).
6867      */
6868     @Deprecated
6869     public boolean mouseUp(Event evt, int x, int y) {
6870         return false;
6871     }
6872 
6873     /**
6874      * @param  evt the event to handle
6875      * @param  x the x coordinate
6876      * @param  y the y coordinate
6877      * @return {@code false}
6878      * @deprecated As of JDK version 1.1,
6879      * replaced by processMouseMotionEvent(MouseEvent).
6880      */
6881     @Deprecated
6882     public boolean mouseMove(Event evt, int x, int y) {
6883         return false;
6884     }
6885 
6886     /**
6887      * @param  evt the event to handle
6888      * @param  x the x coordinate
6889      * @param  y the y coordinate
6890      * @return {@code false}
6891      * @deprecated As of JDK version 1.1,
6892      * replaced by processMouseEvent(MouseEvent).
6893      */
6894     @Deprecated
6895     public boolean mouseEnter(Event evt, int x, int y) {
6896         return false;
6897     }
6898 
6899     /**
6900      * @param  evt the event to handle
6901      * @param  x the x coordinate
6902      * @param  y the y coordinate
6903      * @return {@code false}
6904      * @deprecated As of JDK version 1.1,
6905      * replaced by processMouseEvent(MouseEvent).
6906      */
6907     @Deprecated
6908     public boolean mouseExit(Event evt, int x, int y) {
6909         return false;
6910     }
6911 
6912     /**
6913      * @param  evt the event to handle
6914      * @param  key the key pressed
6915      * @return {@code false}
6916      * @deprecated As of JDK version 1.1,
6917      * replaced by processKeyEvent(KeyEvent).
6918      */
6919     @Deprecated
6920     public boolean keyDown(Event evt, int key) {
6921         return false;
6922     }
6923 
6924     /**
6925      * @param  evt the event to handle
6926      * @param  key the key pressed
6927      * @return {@code false}
6928      * @deprecated As of JDK version 1.1,
6929      * replaced by processKeyEvent(KeyEvent).
6930      */
6931     @Deprecated
6932     public boolean keyUp(Event evt, int key) {
6933         return false;
6934     }
6935 
6936     /**
6937      * @param  evt the event to handle
6938      * @param  what the object acted on
6939      * @return {@code false}
6940      * @deprecated As of JDK version 1.1,
6941      * should register this component as ActionListener on component
6942      * which fires action events.
6943      */
6944     @Deprecated
6945     public boolean action(Event evt, Object what) {
6946         return false;
6947     }
6948 
6949     /**
6950      * Makes this {@code Component} displayable by connecting it to a
6951      * native screen resource.
6952      * This method is called internally by the toolkit and should
6953      * not be called directly by programs.
6954      * <p>
6955      * This method changes layout-related information, and therefore,
6956      * invalidates the component hierarchy.
6957      *
6958      * @see       #isDisplayable
6959      * @see       #removeNotify
6960      * @see #invalidate
6961      * @since 1.0
6962      */
6963     public void addNotify() {
6964         synchronized (getTreeLock()) {
6965             ComponentPeer peer = this.peer;
6966             if (peer == null || peer instanceof LightweightPeer){
6967                 if (peer == null) {
6968                     // Update both the Component's peer variable and the local
6969                     // variable we use for thread safety.
6970                     this.peer = peer = getComponentFactory().createComponent(this);
6971                 }
6972 
6973                 // This is a lightweight component which means it won't be
6974                 // able to get window-related events by itself.  If any
6975                 // have been enabled, then the nearest native container must
6976                 // be enabled.
6977                 if (parent != null) {
6978                     long mask = 0;
6979                     if ((mouseListener != null) || ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0)) {
6980                         mask |= AWTEvent.MOUSE_EVENT_MASK;
6981                     }
6982                     if ((mouseMotionListener != null) ||
6983                         ((eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0)) {
6984                         mask |= AWTEvent.MOUSE_MOTION_EVENT_MASK;
6985                     }
6986                     if ((mouseWheelListener != null ) ||
6987                         ((eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0)) {
6988                         mask |= AWTEvent.MOUSE_WHEEL_EVENT_MASK;
6989                     }
6990                     if (focusListener != null || (eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0) {
6991                         mask |= AWTEvent.FOCUS_EVENT_MASK;
6992                     }
6993                     if (keyListener != null || (eventMask & AWTEvent.KEY_EVENT_MASK) != 0) {
6994                         mask |= AWTEvent.KEY_EVENT_MASK;
6995                     }
6996                     if (mask != 0) {
6997                         parent.proxyEnableEvents(mask);
6998                     }
6999                 }
7000             } else {
7001                 // It's native. If the parent is lightweight it will need some
7002                 // help.
7003                 Container parent = getContainer();
7004                 if (parent != null && parent.isLightweight()) {
7005                     relocateComponent();
7006                     if (!parent.isRecursivelyVisibleUpToHeavyweightContainer())
7007                     {
7008                         peer.setVisible(false);
7009                     }
7010                 }
7011             }
7012             invalidate();
7013 
7014             int npopups = (popups != null? popups.size() : 0);
7015             for (int i = 0 ; i < npopups ; i++) {
7016                 PopupMenu popup = popups.elementAt(i);
7017                 popup.addNotify();
7018             }
7019 
7020             if (dropTarget != null) dropTarget.addNotify();
7021 
7022             peerFont = getFont();
7023 
7024             if (getContainer() != null && !isAddNotifyComplete) {
7025                 getContainer().increaseComponentCount(this);
7026             }
7027 
7028 
7029             // Update stacking order
7030             updateZOrder();
7031 
7032             if (!isAddNotifyComplete) {
7033                 mixOnShowing();
7034             }
7035 
7036             isAddNotifyComplete = true;
7037 
7038             if (hierarchyListener != null ||
7039                 (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 ||
7040                 Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK)) {
7041                 HierarchyEvent e =
7042                     new HierarchyEvent(this, HierarchyEvent.HIERARCHY_CHANGED,
7043                                        this, parent,
7044                                        HierarchyEvent.DISPLAYABILITY_CHANGED |
7045                                        ((isRecursivelyVisible())
7046                                         ? HierarchyEvent.SHOWING_CHANGED
7047                                         : 0));
7048                 dispatchEvent(e);
7049             }
7050         }
7051     }
7052 
7053     /**
7054      * Makes this {@code Component} undisplayable by destroying it native
7055      * screen resource.
7056      * <p>
7057      * This method is called by the toolkit internally and should
7058      * not be called directly by programs. Code overriding
7059      * this method should call {@code super.removeNotify} as
7060      * the first line of the overriding method.
7061      *
7062      * @see       #isDisplayable
7063      * @see       #addNotify
7064      * @since 1.0
7065      */
7066     public void removeNotify() {
7067         KeyboardFocusManager.clearMostRecentFocusOwner(this);
7068         if (KeyboardFocusManager.getCurrentKeyboardFocusManager().
7069             getPermanentFocusOwner() == this)
7070         {
7071             KeyboardFocusManager.getCurrentKeyboardFocusManager().
7072                 setGlobalPermanentFocusOwner(null);
7073         }
7074 
7075         synchronized (getTreeLock()) {
7076             if (isFocusOwner() && KeyboardFocusManager.isAutoFocusTransferEnabledFor(this)) {
7077                 transferFocus(true);
7078             }
7079 
7080             if (getContainer() != null && isAddNotifyComplete) {
7081                 getContainer().decreaseComponentCount(this);
7082             }
7083 
7084             int npopups = (popups != null? popups.size() : 0);
7085             for (int i = 0 ; i < npopups ; i++) {
7086                 PopupMenu popup = popups.elementAt(i);
7087                 popup.removeNotify();
7088             }
7089             // If there is any input context for this component, notify
7090             // that this component is being removed. (This has to be done
7091             // before hiding peer.)
7092             if ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) {
7093                 InputContext inputContext = getInputContext();
7094                 if (inputContext != null) {
7095                     inputContext.removeNotify(this);
7096                 }
7097             }
7098 
7099             ComponentPeer p = peer;
7100             if (p != null) {
7101                 boolean isLightweight = isLightweight();
7102 
7103                 if (bufferStrategy instanceof FlipBufferStrategy) {
7104                     ((FlipBufferStrategy)bufferStrategy).destroyBuffers();
7105                 }
7106 
7107                 if (dropTarget != null) dropTarget.removeNotify();
7108 
7109                 // Hide peer first to stop system events such as cursor moves.
7110                 if (visible) {
7111                     p.setVisible(false);
7112                 }
7113 
7114                 peer = null; // Stop peer updates.
7115                 peerFont = null;
7116 
7117                 Toolkit.getEventQueue().removeSourceEvents(this, false);
7118                 KeyboardFocusManager.getCurrentKeyboardFocusManager().
7119                     discardKeyEvents(this);
7120 
7121                 p.dispose();
7122 
7123                 mixOnHiding(isLightweight);
7124 
7125                 isAddNotifyComplete = false;
7126                 // Nullifying compoundShape means that the component has normal shape
7127                 // (or has no shape at all).
7128                 this.compoundShape = null;
7129             }
7130 
7131             if (hierarchyListener != null ||
7132                 (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 ||
7133                 Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK)) {
7134                 HierarchyEvent e =
7135                     new HierarchyEvent(this, HierarchyEvent.HIERARCHY_CHANGED,
7136                                        this, parent,
7137                                        HierarchyEvent.DISPLAYABILITY_CHANGED |
7138                                        ((isRecursivelyVisible())
7139                                         ? HierarchyEvent.SHOWING_CHANGED
7140                                         : 0));
7141                 dispatchEvent(e);
7142             }
7143         }
7144     }
7145 
7146     /**
7147      * @param  evt the event to handle
7148      * @param  what the object focused
7149      * @return  {@code false}
7150      * @deprecated As of JDK version 1.1,
7151      * replaced by processFocusEvent(FocusEvent).
7152      */
7153     @Deprecated
7154     public boolean gotFocus(Event evt, Object what) {
7155         return false;
7156     }
7157 
7158     /**
7159      * @param evt  the event to handle
7160      * @param what the object focused
7161      * @return  {@code false}
7162      * @deprecated As of JDK version 1.1,
7163      * replaced by processFocusEvent(FocusEvent).
7164      */
7165     @Deprecated
7166     public boolean lostFocus(Event evt, Object what) {
7167         return false;
7168     }
7169 
7170     /**
7171      * Returns whether this {@code Component} can become the focus
7172      * owner.
7173      *
7174      * @return {@code true} if this {@code Component} is
7175      * focusable; {@code false} otherwise
7176      * @see #setFocusable
7177      * @since 1.1
7178      * @deprecated As of 1.4, replaced by {@code isFocusable()}.
7179      */
7180     @Deprecated
7181     public boolean isFocusTraversable() {
7182         if (isFocusTraversableOverridden == FOCUS_TRAVERSABLE_UNKNOWN) {
7183             isFocusTraversableOverridden = FOCUS_TRAVERSABLE_DEFAULT;
7184         }
7185         return focusable;
7186     }
7187 
7188     /**
7189      * Returns whether this Component can be focused.
7190      *
7191      * @return {@code true} if this Component is focusable;
7192      *         {@code false} otherwise.
7193      * @see #setFocusable
7194      * @since 1.4
7195      */
7196     public boolean isFocusable() {
7197         return isFocusTraversable();
7198     }
7199 
7200     /**
7201      * Sets the focusable state of this Component to the specified value. This
7202      * value overrides the Component's default focusability.
7203      *
7204      * @param focusable indicates whether this Component is focusable
7205      * @see #isFocusable
7206      * @since 1.4
7207      */
7208     public void setFocusable(boolean focusable) {
7209         boolean oldFocusable;
7210         synchronized (this) {
7211             oldFocusable = this.focusable;
7212             this.focusable = focusable;
7213         }
7214         isFocusTraversableOverridden = FOCUS_TRAVERSABLE_SET;
7215 
7216         firePropertyChange("focusable", oldFocusable, focusable);
7217         if (oldFocusable && !focusable) {
7218             if (isFocusOwner() && KeyboardFocusManager.isAutoFocusTransferEnabled()) {
7219                 transferFocus(true);
7220             }
7221             KeyboardFocusManager.clearMostRecentFocusOwner(this);
7222         }
7223     }
7224 
7225     final boolean isFocusTraversableOverridden() {
7226         return (isFocusTraversableOverridden != FOCUS_TRAVERSABLE_DEFAULT);
7227     }
7228 
7229     /**
7230      * Sets the focus traversal keys for a given traversal operation for this
7231      * Component.
7232      * <p>
7233      * The default values for a Component's focus traversal keys are
7234      * implementation-dependent. Sun recommends that all implementations for a
7235      * particular native platform use the same default values. The
7236      * recommendations for Windows and Unix are listed below. These
7237      * recommendations are used in the Sun AWT implementations.
7238      *
7239      * <table border=1 summary="Recommended default values for a Component's focus traversal keys">
7240      * <tr>
7241      *    <th>Identifier</th>
7242      *    <th>Meaning</th>
7243      *    <th>Default</th>
7244      * </tr>
7245      * <tr>
7246      *    <td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</td>
7247      *    <td>Normal forward keyboard traversal</td>
7248      *    <td>TAB on KEY_PRESSED, CTRL-TAB on KEY_PRESSED</td>
7249      * </tr>
7250      * <tr>
7251      *    <td>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</td>
7252      *    <td>Normal reverse keyboard traversal</td>
7253      *    <td>SHIFT-TAB on KEY_PRESSED, CTRL-SHIFT-TAB on KEY_PRESSED</td>
7254      * </tr>
7255      * <tr>
7256      *    <td>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</td>
7257      *    <td>Go up one focus traversal cycle</td>
7258      *    <td>none</td>
7259      * </tr>
7260      * </table>
7261      *
7262      * To disable a traversal key, use an empty Set; Collections.EMPTY_SET is
7263      * recommended.
7264      * <p>
7265      * Using the AWTKeyStroke API, client code can specify on which of two
7266      * specific KeyEvents, KEY_PRESSED or KEY_RELEASED, the focus traversal
7267      * operation will occur. Regardless of which KeyEvent is specified,
7268      * however, all KeyEvents related to the focus traversal key, including the
7269      * associated KEY_TYPED event, will be consumed, and will not be dispatched
7270      * to any Component. It is a runtime error to specify a KEY_TYPED event as
7271      * mapping to a focus traversal operation, or to map the same event to
7272      * multiple default focus traversal operations.
7273      * <p>
7274      * If a value of null is specified for the Set, this Component inherits the
7275      * Set from its parent. If all ancestors of this Component have null
7276      * specified for the Set, then the current KeyboardFocusManager's default
7277      * Set is used.
7278      * <p>
7279      * This method may throw a {@code ClassCastException} if any {@code Object}
7280      * in {@code keystrokes} is not an {@code AWTKeyStroke}.
7281      *
7282      * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
7283      *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
7284      *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
7285      * @param keystrokes the Set of AWTKeyStroke for the specified operation
7286      * @see #getFocusTraversalKeys
7287      * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
7288      * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
7289      * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
7290      * @throws IllegalArgumentException if id is not one of
7291      *         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
7292      *         KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
7293      *         KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or if keystrokes
7294      *         contains null, or if any keystroke represents a KEY_TYPED event,
7295      *         or if any keystroke already maps to another focus traversal
7296      *         operation for this Component
7297      * @since 1.4
7298      */
7299     public void setFocusTraversalKeys(int id,
7300                                       Set<? extends AWTKeyStroke> keystrokes)
7301     {
7302         if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH - 1) {
7303             throw new IllegalArgumentException("invalid focus traversal key identifier");
7304         }
7305 
7306         setFocusTraversalKeys_NoIDCheck(id, keystrokes);
7307     }
7308 
7309     /**
7310      * Returns the Set of focus traversal keys for a given traversal operation
7311      * for this Component. (See
7312      * {@code setFocusTraversalKeys} for a full description of each key.)
7313      * <p>
7314      * If a Set of traversal keys has not been explicitly defined for this
7315      * Component, then this Component's parent's Set is returned. If no Set
7316      * has been explicitly defined for any of this Component's ancestors, then
7317      * the current KeyboardFocusManager's default Set is returned.
7318      *
7319      * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
7320      *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
7321      *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
7322      * @return the Set of AWTKeyStrokes for the specified operation. The Set
7323      *         will be unmodifiable, and may be empty. null will never be
7324      *         returned.
7325      * @see #setFocusTraversalKeys
7326      * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
7327      * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
7328      * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
7329      * @throws IllegalArgumentException if id is not one of
7330      *         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
7331      *         KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
7332      *         KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
7333      * @since 1.4
7334      */
7335     public Set<AWTKeyStroke> getFocusTraversalKeys(int id) {
7336         if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH - 1) {
7337             throw new IllegalArgumentException("invalid focus traversal key identifier");
7338         }
7339 
7340         return getFocusTraversalKeys_NoIDCheck(id);
7341     }
7342 
7343     // We define these methods so that Container does not need to repeat this
7344     // code. Container cannot call super.<method> because Container allows
7345     // DOWN_CYCLE_TRAVERSAL_KEY while Component does not. The Component method
7346     // would erroneously generate an IllegalArgumentException for
7347     // DOWN_CYCLE_TRAVERSAL_KEY.
7348     final void setFocusTraversalKeys_NoIDCheck(int id, Set<? extends AWTKeyStroke> keystrokes) {
7349         Set<AWTKeyStroke> oldKeys;
7350 
7351         synchronized (this) {
7352             if (focusTraversalKeys == null) {
7353                 initializeFocusTraversalKeys();
7354             }
7355 
7356             if (keystrokes != null) {
7357                 for (AWTKeyStroke keystroke : keystrokes ) {
7358 
7359                     if (keystroke == null) {
7360                         throw new IllegalArgumentException("cannot set null focus traversal key");
7361                     }
7362 
7363                     if (keystroke.getKeyChar() != KeyEvent.CHAR_UNDEFINED) {
7364                         throw new IllegalArgumentException("focus traversal keys cannot map to KEY_TYPED events");
7365                     }
7366 
7367                     for (int i = 0; i < focusTraversalKeys.length; i++) {
7368                         if (i == id) {
7369                             continue;
7370                         }
7371 
7372                         if (getFocusTraversalKeys_NoIDCheck(i).contains(keystroke))
7373                         {
7374                             throw new IllegalArgumentException("focus traversal keys must be unique for a Component");
7375                         }
7376                     }
7377                 }
7378             }
7379 
7380             oldKeys = focusTraversalKeys[id];
7381             focusTraversalKeys[id] = (keystrokes != null)
7382                 ? Collections.unmodifiableSet(new HashSet<AWTKeyStroke>(keystrokes))
7383                 : null;
7384         }
7385 
7386         firePropertyChange(focusTraversalKeyPropertyNames[id], oldKeys,
7387                            keystrokes);
7388     }
7389     final Set<AWTKeyStroke> getFocusTraversalKeys_NoIDCheck(int id) {
7390         // Okay to return Set directly because it is an unmodifiable view
7391         @SuppressWarnings("unchecked")
7392         Set<AWTKeyStroke> keystrokes = (focusTraversalKeys != null)
7393             ? focusTraversalKeys[id]
7394             : null;
7395 
7396         if (keystrokes != null) {
7397             return keystrokes;
7398         } else {
7399             Container parent = this.parent;
7400             if (parent != null) {
7401                 return parent.getFocusTraversalKeys(id);
7402             } else {
7403                 return KeyboardFocusManager.getCurrentKeyboardFocusManager().
7404                     getDefaultFocusTraversalKeys(id);
7405             }
7406         }
7407     }
7408 
7409     /**
7410      * Returns whether the Set of focus traversal keys for the given focus
7411      * traversal operation has been explicitly defined for this Component. If
7412      * this method returns {@code false}, this Component is inheriting the
7413      * Set from an ancestor, or from the current KeyboardFocusManager.
7414      *
7415      * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
7416      *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
7417      *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
7418      * @return {@code true} if the Set of focus traversal keys for the
7419      *         given focus traversal operation has been explicitly defined for
7420      *         this Component; {@code false} otherwise.
7421      * @throws IllegalArgumentException if id is not one of
7422      *         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
7423      *         KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
7424      *         KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
7425      * @since 1.4
7426      */
7427     public boolean areFocusTraversalKeysSet(int id) {
7428         if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH - 1) {
7429             throw new IllegalArgumentException("invalid focus traversal key identifier");
7430         }
7431 
7432         return (focusTraversalKeys != null && focusTraversalKeys[id] != null);
7433     }
7434 
7435     /**
7436      * Sets whether focus traversal keys are enabled for this Component.
7437      * Components for which focus traversal keys are disabled receive key
7438      * events for focus traversal keys. Components for which focus traversal
7439      * keys are enabled do not see these events; instead, the events are
7440      * automatically converted to traversal operations.
7441      *
7442      * @param focusTraversalKeysEnabled whether focus traversal keys are
7443      *        enabled for this Component
7444      * @see #getFocusTraversalKeysEnabled
7445      * @see #setFocusTraversalKeys
7446      * @see #getFocusTraversalKeys
7447      * @since 1.4
7448      */
7449     public void setFocusTraversalKeysEnabled(boolean
7450                                              focusTraversalKeysEnabled) {
7451         boolean oldFocusTraversalKeysEnabled;
7452         synchronized (this) {
7453             oldFocusTraversalKeysEnabled = this.focusTraversalKeysEnabled;
7454             this.focusTraversalKeysEnabled = focusTraversalKeysEnabled;
7455         }
7456         firePropertyChange("focusTraversalKeysEnabled",
7457                            oldFocusTraversalKeysEnabled,
7458                            focusTraversalKeysEnabled);
7459     }
7460 
7461     /**
7462      * Returns whether focus traversal keys are enabled for this Component.
7463      * Components for which focus traversal keys are disabled receive key
7464      * events for focus traversal keys. Components for which focus traversal
7465      * keys are enabled do not see these events; instead, the events are
7466      * automatically converted to traversal operations.
7467      *
7468      * @return whether focus traversal keys are enabled for this Component
7469      * @see #setFocusTraversalKeysEnabled
7470      * @see #setFocusTraversalKeys
7471      * @see #getFocusTraversalKeys
7472      * @since 1.4
7473      */
7474     public boolean getFocusTraversalKeysEnabled() {
7475         return focusTraversalKeysEnabled;
7476     }
7477 
7478     /**
7479      * Requests that this Component get the input focus, and that this
7480      * Component's top-level ancestor become the focused Window. This
7481      * component must be displayable, focusable, visible and all of
7482      * its ancestors (with the exception of the top-level Window) must
7483      * be visible for the request to be granted. Every effort will be
7484      * made to honor the request; however, in some cases it may be
7485      * impossible to do so. Developers must never assume that this
7486      * Component is the focus owner until this Component receives a
7487      * FOCUS_GAINED event. If this request is denied because this
7488      * Component's top-level Window cannot become the focused Window,
7489      * the request will be remembered and will be granted when the
7490      * Window is later focused by the user.
7491      * <p>
7492      * This method cannot be used to set the focus owner to no Component at
7493      * all. Use {@code KeyboardFocusManager.clearGlobalFocusOwner()}
7494      * instead.
7495      * <p>
7496      * Because the focus behavior of this method is platform-dependent,
7497      * developers are strongly encouraged to use
7498      * {@code requestFocusInWindow} when possible.
7499      *
7500      * <p>Note: Not all focus transfers result from invoking this method. As
7501      * such, a component may receive focus without this or any of the other
7502      * {@code requestFocus} methods of {@code Component} being invoked.
7503      *
7504      * @see #requestFocusInWindow
7505      * @see java.awt.event.FocusEvent
7506      * @see #addFocusListener
7507      * @see #isFocusable
7508      * @see #isDisplayable
7509      * @see KeyboardFocusManager#clearGlobalFocusOwner
7510      * @since 1.0
7511      */
7512     public void requestFocus() {
7513         requestFocusHelper(false, true);
7514     }
7515 
7516 
7517     /**
7518      * Requests by the reason of {@code cause} that this Component get the input
7519      * focus, and that this Component's top-level ancestor become the
7520      * focused Window. This component must be displayable, focusable, visible
7521      * and all of its ancestors (with the exception of the top-level Window)
7522      * must be visible for the request to be granted. Every effort will be
7523      * made to honor the request; however, in some cases it may be
7524      * impossible to do so. Developers must never assume that this
7525      * Component is the focus owner until this Component receives a
7526      * FOCUS_GAINED event.
7527      * <p>
7528      * The focus request effect may also depend on the provided
7529      * cause value. If this request is succeed the {@code FocusEvent}
7530      * generated in the result will receive the cause value specified as the
7531      * argument of method. If this request is denied because this Component's
7532      * top-level Window cannot become the focused Window, the request will be
7533      * remembered and will be granted when the Window is later focused by the
7534      * user.
7535      * <p>
7536      * This method cannot be used to set the focus owner to no Component at
7537      * all. Use {@code KeyboardFocusManager.clearGlobalFocusOwner()}
7538      * instead.
7539      * <p>
7540      * Because the focus behavior of this method is platform-dependent,
7541      * developers are strongly encouraged to use
7542      * {@code requestFocusInWindow(FocusEvent.Cause)} when possible.
7543      *
7544      * <p>Note: Not all focus transfers result from invoking this method. As
7545      * such, a component may receive focus without this or any of the other
7546      * {@code requestFocus} methods of {@code Component} being invoked.
7547      *
7548      * @param  cause the cause why the focus is requested
7549      * @see FocusEvent
7550      * @see FocusEvent.Cause
7551      * @see #requestFocusInWindow(FocusEvent.Cause)
7552      * @see java.awt.event.FocusEvent
7553      * @see #addFocusListener
7554      * @see #isFocusable
7555      * @see #isDisplayable
7556      * @see KeyboardFocusManager#clearGlobalFocusOwner
7557      * @since 9
7558      */
7559     public void requestFocus(FocusEvent.Cause cause) {
7560         requestFocusHelper(false, true, cause);
7561     }
7562 
7563     /**
7564      * Requests that this {@code Component} get the input focus,
7565      * and that this {@code Component}'s top-level ancestor
7566      * become the focused {@code Window}. This component must be
7567      * displayable, focusable, visible and all of its ancestors (with
7568      * the exception of the top-level Window) must be visible for the
7569      * request to be granted. Every effort will be made to honor the
7570      * request; however, in some cases it may be impossible to do
7571      * so. Developers must never assume that this component is the
7572      * focus owner until this component receives a FOCUS_GAINED
7573      * event. If this request is denied because this component's
7574      * top-level window cannot become the focused window, the request
7575      * will be remembered and will be granted when the window is later
7576      * focused by the user.
7577      * <p>
7578      * This method returns a boolean value. If {@code false} is returned,
7579      * the request is <b>guaranteed to fail</b>. If {@code true} is
7580      * returned, the request will succeed <b>unless</b> it is vetoed, or an
7581      * extraordinary event, such as disposal of the component's peer, occurs
7582      * before the request can be granted by the native windowing system. Again,
7583      * while a return value of {@code true} indicates that the request is
7584      * likely to succeed, developers must never assume that this component is
7585      * the focus owner until this component receives a FOCUS_GAINED event.
7586      * <p>
7587      * This method cannot be used to set the focus owner to no component at
7588      * all. Use {@code KeyboardFocusManager.clearGlobalFocusOwner}
7589      * instead.
7590      * <p>
7591      * Because the focus behavior of this method is platform-dependent,
7592      * developers are strongly encouraged to use
7593      * {@code requestFocusInWindow} when possible.
7594      * <p>
7595      * Every effort will be made to ensure that {@code FocusEvent}s
7596      * generated as a
7597      * result of this request will have the specified temporary value. However,
7598      * because specifying an arbitrary temporary state may not be implementable
7599      * on all native windowing systems, correct behavior for this method can be
7600      * guaranteed only for lightweight {@code Component}s.
7601      * This method is not intended
7602      * for general use, but exists instead as a hook for lightweight component
7603      * libraries, such as Swing.
7604      *
7605      * <p>Note: Not all focus transfers result from invoking this method. As
7606      * such, a component may receive focus without this or any of the other
7607      * {@code requestFocus} methods of {@code Component} being invoked.
7608      *
7609      * @param temporary true if the focus change is temporary,
7610      *        such as when the window loses the focus; for
7611      *        more information on temporary focus changes see the
7612      *<a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
7613      * @return {@code false} if the focus change request is guaranteed to
7614      *         fail; {@code true} if it is likely to succeed
7615      * @see java.awt.event.FocusEvent
7616      * @see #addFocusListener
7617      * @see #isFocusable
7618      * @see #isDisplayable
7619      * @see KeyboardFocusManager#clearGlobalFocusOwner
7620      * @since 1.4
7621      */
7622     protected boolean requestFocus(boolean temporary) {
7623         return requestFocusHelper(temporary, true);
7624     }
7625 
7626     /**
7627      * Requests by the reason of {@code cause} that this {@code Component} get
7628      * the input focus, and that this {@code Component}'s top-level ancestor
7629      * become the focused {@code Window}. This component must be
7630      * displayable, focusable, visible and all of its ancestors (with
7631      * the exception of the top-level Window) must be visible for the
7632      * request to be granted. Every effort will be made to honor the
7633      * request; however, in some cases it may be impossible to do
7634      * so. Developers must never assume that this component is the
7635      * focus owner until this component receives a FOCUS_GAINED
7636      * event. If this request is denied because this component's
7637      * top-level window cannot become the focused window, the request
7638      * will be remembered and will be granted when the window is later
7639      * focused by the user.
7640      * <p>
7641      * This method returns a boolean value. If {@code false} is returned,
7642      * the request is <b>guaranteed to fail</b>. If {@code true} is
7643      * returned, the request will succeed <b>unless</b> it is vetoed, or an
7644      * extraordinary event, such as disposal of the component's peer, occurs
7645      * before the request can be granted by the native windowing system. Again,
7646      * while a return value of {@code true} indicates that the request is
7647      * likely to succeed, developers must never assume that this component is
7648      * the focus owner until this component receives a FOCUS_GAINED event.
7649      * <p>
7650      * The focus request effect may also depend on the provided
7651      * cause value. If this request is succeed the {FocusEvent}
7652      * generated in the result will receive the cause value specified as the
7653      * argument of the method.
7654      * <p>
7655      * This method cannot be used to set the focus owner to no component at
7656      * all. Use {@code KeyboardFocusManager.clearGlobalFocusOwner}
7657      * instead.
7658      * <p>
7659      * Because the focus behavior of this method is platform-dependent,
7660      * developers are strongly encouraged to use
7661      * {@code requestFocusInWindow} when possible.
7662      * <p>
7663      * Every effort will be made to ensure that {@code FocusEvent}s
7664      * generated as a
7665      * result of this request will have the specified temporary value. However,
7666      * because specifying an arbitrary temporary state may not be implementable
7667      * on all native windowing systems, correct behavior for this method can be
7668      * guaranteed only for lightweight {@code Component}s.
7669      * This method is not intended
7670      * for general use, but exists instead as a hook for lightweight component
7671      * libraries, such as Swing.
7672      * <p>
7673      * Note: Not all focus transfers result from invoking this method. As
7674      * such, a component may receive focus without this or any of the other
7675      * {@code requestFocus} methods of {@code Component} being invoked.
7676      *
7677      * @param temporary true if the focus change is temporary,
7678      *        such as when the window loses the focus; for
7679      *        more information on temporary focus changes see the
7680      *<a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
7681      *
7682      * @param  cause the cause why the focus is requested
7683      * @return {@code false} if the focus change request is guaranteed to
7684      *         fail; {@code true} if it is likely to succeed
7685      * @see FocusEvent
7686      * @see FocusEvent.Cause
7687      * @see #addFocusListener
7688      * @see #isFocusable
7689      * @see #isDisplayable
7690      * @see KeyboardFocusManager#clearGlobalFocusOwner
7691      * @since 9
7692      */
7693     protected boolean requestFocus(boolean temporary, FocusEvent.Cause cause) {
7694         return requestFocusHelper(temporary, true, cause);
7695     }
7696 
7697     /**
7698      * Requests that this Component get the input focus, if this
7699      * Component's top-level ancestor is already the focused
7700      * Window. This component must be displayable, focusable, visible
7701      * and all of its ancestors (with the exception of the top-level
7702      * Window) must be visible for the request to be granted. Every
7703      * effort will be made to honor the request; however, in some
7704      * cases it may be impossible to do so. Developers must never
7705      * assume that this Component is the focus owner until this
7706      * Component receives a FOCUS_GAINED event.
7707      * <p>
7708      * This method returns a boolean value. If {@code false} is returned,
7709      * the request is <b>guaranteed to fail</b>. If {@code true} is
7710      * returned, the request will succeed <b>unless</b> it is vetoed, or an
7711      * extraordinary event, such as disposal of the Component's peer, occurs
7712      * before the request can be granted by the native windowing system. Again,
7713      * while a return value of {@code true} indicates that the request is
7714      * likely to succeed, developers must never assume that this Component is
7715      * the focus owner until this Component receives a FOCUS_GAINED event.
7716      * <p>
7717      * This method cannot be used to set the focus owner to no Component at
7718      * all. Use {@code KeyboardFocusManager.clearGlobalFocusOwner()}
7719      * instead.
7720      * <p>
7721      * The focus behavior of this method can be implemented uniformly across
7722      * platforms, and thus developers are strongly encouraged to use this
7723      * method over {@code requestFocus} when possible. Code which relies
7724      * on {@code requestFocus} may exhibit different focus behavior on
7725      * different platforms.
7726      *
7727      * <p>Note: Not all focus transfers result from invoking this method. As
7728      * such, a component may receive focus without this or any of the other
7729      * {@code requestFocus} methods of {@code Component} being invoked.
7730      *
7731      * @return {@code false} if the focus change request is guaranteed to
7732      *         fail; {@code true} if it is likely to succeed
7733      * @see #requestFocus
7734      * @see java.awt.event.FocusEvent
7735      * @see #addFocusListener
7736      * @see #isFocusable
7737      * @see #isDisplayable
7738      * @see KeyboardFocusManager#clearGlobalFocusOwner
7739      * @since 1.4
7740      */
7741     public boolean requestFocusInWindow() {
7742         return requestFocusHelper(false, false);
7743     }
7744 
7745     /**
7746      * Requests by the reason of {@code cause} that this Component get the input
7747      * focus, if this Component's top-level ancestor is already the focused
7748      * Window. This component must be displayable, focusable, visible
7749      * and all of its ancestors (with the exception of the top-level
7750      * Window) must be visible for the request to be granted. Every
7751      * effort will be made to honor the request; however, in some
7752      * cases it may be impossible to do so. Developers must never
7753      * assume that this Component is the focus owner until this
7754      * Component receives a FOCUS_GAINED event.
7755      * <p>
7756      * This method returns a boolean value. If {@code false} is returned,
7757      * the request is <b>guaranteed to fail</b>. If {@code true} is
7758      * returned, the request will succeed <b>unless</b> it is vetoed, or an
7759      * extraordinary event, such as disposal of the Component's peer, occurs
7760      * before the request can be granted by the native windowing system. Again,
7761      * while a return value of {@code true} indicates that the request is
7762      * likely to succeed, developers must never assume that this Component is
7763      * the focus owner until this Component receives a FOCUS_GAINED event.
7764      * <p>
7765      * The focus request effect may also depend on the provided
7766      * cause value. If this request is succeed the {@code FocusEvent}
7767      * generated in the result will receive the cause value specified as the
7768      * argument of the method.
7769      * <p>
7770      * This method cannot be used to set the focus owner to no Component at
7771      * all. Use {@code KeyboardFocusManager.clearGlobalFocusOwner()}
7772      * instead.
7773      * <p>
7774      * The focus behavior of this method can be implemented uniformly across
7775      * platforms, and thus developers are strongly encouraged to use this
7776      * method over {@code requestFocus(FocusEvent.Cause)} when possible.
7777      * Code which relies on {@code requestFocus(FocusEvent.Cause)} may exhibit
7778      * different focus behavior on different platforms.
7779      *
7780      * <p>Note: Not all focus transfers result from invoking this method. As
7781      * such, a component may receive focus without this or any of the other
7782      * {@code requestFocus} methods of {@code Component} being invoked.
7783      *
7784      * @param  cause the cause why the focus is requested
7785      * @return {@code false} if the focus change request is guaranteed to
7786      *         fail; {@code true} if it is likely to succeed
7787      * @see #requestFocus(FocusEvent.Cause)
7788      * @see FocusEvent
7789      * @see FocusEvent.Cause
7790      * @see java.awt.event.FocusEvent
7791      * @see #addFocusListener
7792      * @see #isFocusable
7793      * @see #isDisplayable
7794      * @see KeyboardFocusManager#clearGlobalFocusOwner
7795      * @since 9
7796      */
7797     public boolean requestFocusInWindow(FocusEvent.Cause cause) {
7798         return requestFocusHelper(false, false, cause);
7799     }
7800 
7801     /**
7802      * Requests that this {@code Component} get the input focus,
7803      * if this {@code Component}'s top-level ancestor is already
7804      * the focused {@code Window}.  This component must be
7805      * displayable, focusable, visible and all of its ancestors (with
7806      * the exception of the top-level Window) must be visible for the
7807      * request to be granted. Every effort will be made to honor the
7808      * request; however, in some cases it may be impossible to do
7809      * so. Developers must never assume that this component is the
7810      * focus owner until this component receives a FOCUS_GAINED event.
7811      * <p>
7812      * This method returns a boolean value. If {@code false} is returned,
7813      * the request is <b>guaranteed to fail</b>. If {@code true} is
7814      * returned, the request will succeed <b>unless</b> it is vetoed, or an
7815      * extraordinary event, such as disposal of the component's peer, occurs
7816      * before the request can be granted by the native windowing system. Again,
7817      * while a return value of {@code true} indicates that the request is
7818      * likely to succeed, developers must never assume that this component is
7819      * the focus owner until this component receives a FOCUS_GAINED event.
7820      * <p>
7821      * This method cannot be used to set the focus owner to no component at
7822      * all. Use {@code KeyboardFocusManager.clearGlobalFocusOwner}
7823      * instead.
7824      * <p>
7825      * The focus behavior of this method can be implemented uniformly across
7826      * platforms, and thus developers are strongly encouraged to use this
7827      * method over {@code requestFocus} when possible. Code which relies
7828      * on {@code requestFocus} may exhibit different focus behavior on
7829      * different platforms.
7830      * <p>
7831      * Every effort will be made to ensure that {@code FocusEvent}s
7832      * generated as a
7833      * result of this request will have the specified temporary value. However,
7834      * because specifying an arbitrary temporary state may not be implementable
7835      * on all native windowing systems, correct behavior for this method can be
7836      * guaranteed only for lightweight components. This method is not intended
7837      * for general use, but exists instead as a hook for lightweight component
7838      * libraries, such as Swing.
7839      *
7840      * <p>Note: Not all focus transfers result from invoking this method. As
7841      * such, a component may receive focus without this or any of the other
7842      * {@code requestFocus} methods of {@code Component} being invoked.
7843      *
7844      * @param temporary true if the focus change is temporary,
7845      *        such as when the window loses the focus; for
7846      *        more information on temporary focus changes see the
7847      *<a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
7848      * @return {@code false} if the focus change request is guaranteed to
7849      *         fail; {@code true} if it is likely to succeed
7850      * @see #requestFocus
7851      * @see java.awt.event.FocusEvent
7852      * @see #addFocusListener
7853      * @see #isFocusable
7854      * @see #isDisplayable
7855      * @see KeyboardFocusManager#clearGlobalFocusOwner
7856      * @since 1.4
7857      */
7858     protected boolean requestFocusInWindow(boolean temporary) {
7859         return requestFocusHelper(temporary, false);
7860     }
7861 
7862     boolean requestFocusInWindow(boolean temporary, FocusEvent.Cause cause) {
7863         return requestFocusHelper(temporary, false, cause);
7864     }
7865 
7866     final boolean requestFocusHelper(boolean temporary,
7867                                      boolean focusedWindowChangeAllowed) {
7868         return requestFocusHelper(temporary, focusedWindowChangeAllowed, FocusEvent.Cause.UNKNOWN);
7869     }
7870 
7871     final boolean requestFocusHelper(boolean temporary,
7872                                      boolean focusedWindowChangeAllowed,
7873                                      FocusEvent.Cause cause)
7874     {
7875         // 1) Check if the event being dispatched is a system-generated mouse event.
7876         AWTEvent currentEvent = EventQueue.getCurrentEvent();
7877         if (currentEvent instanceof MouseEvent &&
7878             SunToolkit.isSystemGenerated(currentEvent))
7879         {
7880             // 2) Sanity check: if the mouse event component source belongs to the same containing window.
7881             Component source = ((MouseEvent)currentEvent).getComponent();
7882             if (source == null || source.getContainingWindow() == getContainingWindow()) {
7883                 focusLog.finest("requesting focus by mouse event \"in window\"");
7884 
7885                 // If both the conditions are fulfilled the focus request should be strictly
7886                 // bounded by the toplevel window. It's assumed that the mouse event activates
7887                 // the window (if it wasn't active) and this makes it possible for a focus
7888                 // request with a strong in-window requirement to change focus in the bounds
7889                 // of the toplevel. If, by any means, due to asynchronous nature of the event
7890                 // dispatching mechanism, the window happens to be natively inactive by the time
7891                 // this focus request is eventually handled, it should not re-activate the
7892                 // toplevel. Otherwise the result may not meet user expectations. See 6981400.
7893                 focusedWindowChangeAllowed = false;
7894             }
7895         }
7896         if (!isRequestFocusAccepted(temporary, focusedWindowChangeAllowed, cause)) {
7897             if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7898                 focusLog.finest("requestFocus is not accepted");
7899             }
7900             return false;
7901         }
7902         // Update most-recent map
7903         KeyboardFocusManager.setMostRecentFocusOwner(this);
7904 
7905         Component window = this;
7906         while ( (window != null) && !(window instanceof Window)) {
7907             if (!window.isVisible()) {
7908                 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7909                     focusLog.finest("component is recursively invisible");
7910                 }
7911                 return false;
7912             }
7913             window = window.parent;
7914         }
7915 
7916         ComponentPeer peer = this.peer;
7917         Component heavyweight = (peer instanceof LightweightPeer)
7918             ? getNativeContainer() : this;
7919         if (heavyweight == null || !heavyweight.isVisible()) {
7920             if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7921                 focusLog.finest("Component is not a part of visible hierarchy");
7922             }
7923             return false;
7924         }
7925         peer = heavyweight.peer;
7926         if (peer == null) {
7927             if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7928                 focusLog.finest("Peer is null");
7929             }
7930             return false;
7931         }
7932 
7933         // Focus this Component
7934         long time = 0;
7935         if (EventQueue.isDispatchThread()) {
7936             time = Toolkit.getEventQueue().getMostRecentKeyEventTime();
7937         } else {
7938             // A focus request made from outside EDT should not be associated with any event
7939             // and so its time stamp is simply set to the current time.
7940             time = System.currentTimeMillis();
7941         }
7942 
7943         boolean success = peer.requestFocus
7944             (this, temporary, focusedWindowChangeAllowed, time, cause);
7945         if (!success) {
7946             KeyboardFocusManager.getCurrentKeyboardFocusManager
7947                 (appContext).dequeueKeyEvents(time, this);
7948             if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7949                 focusLog.finest("Peer request failed");
7950             }
7951         } else {
7952             if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7953                 focusLog.finest("Pass for " + this);
7954             }
7955         }
7956         return success;
7957     }
7958 
7959     private boolean isRequestFocusAccepted(boolean temporary,
7960                                            boolean focusedWindowChangeAllowed,
7961                                            FocusEvent.Cause cause)
7962     {
7963         if (!isFocusable() || !isVisible()) {
7964             if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7965                 focusLog.finest("Not focusable or not visible");
7966             }
7967             return false;
7968         }
7969 
7970         ComponentPeer peer = this.peer;
7971         if (peer == null) {
7972             if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7973                 focusLog.finest("peer is null");
7974             }
7975             return false;
7976         }
7977 
7978         Window window = getContainingWindow();
7979         if (window == null || !window.isFocusableWindow()) {
7980             if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7981                 focusLog.finest("Component doesn't have toplevel");
7982             }
7983             return false;
7984         }
7985 
7986         // We have passed all regular checks for focus request,
7987         // now let's call RequestFocusController and see what it says.
7988         Component focusOwner = KeyboardFocusManager.getMostRecentFocusOwner(window);
7989         if (focusOwner == null) {
7990             // sometimes most recent focus owner may be null, but focus owner is not
7991             // e.g. we reset most recent focus owner if user removes focus owner
7992             focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
7993             if (focusOwner != null && focusOwner.getContainingWindow() != window) {
7994                 focusOwner = null;
7995             }
7996         }
7997 
7998         if (focusOwner == this || focusOwner == null) {
7999             // Controller is supposed to verify focus transfers and for this it
8000             // should know both from and to components.  And it shouldn't verify
8001             // transfers from when these components are equal.
8002             if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
8003                 focusLog.finest("focus owner is null or this");
8004             }
8005             return true;
8006         }
8007 
8008         if (FocusEvent.Cause.ACTIVATION == cause) {
8009             // we shouldn't call RequestFocusController in case we are
8010             // in activation.  We do request focus on component which
8011             // has got temporary focus lost and then on component which is
8012             // most recent focus owner.  But most recent focus owner can be
8013             // changed by requestFocusXXX() call only, so this transfer has
8014             // been already approved.
8015             if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
8016                 focusLog.finest("cause is activation");
8017             }
8018             return true;
8019         }
8020 
8021         boolean ret = Component.requestFocusController.acceptRequestFocus(focusOwner,
8022                                                                           this,
8023                                                                           temporary,
8024                                                                           focusedWindowChangeAllowed,
8025                                                                           cause);
8026         if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
8027             focusLog.finest("RequestFocusController returns {0}", ret);
8028         }
8029 
8030         return ret;
8031     }
8032 
8033     private static RequestFocusController requestFocusController = new DummyRequestFocusController();
8034 
8035     // Swing access this method through reflection to implement InputVerifier's functionality.
8036     // Perhaps, we should make this method public (later ;)
8037     private static class DummyRequestFocusController implements RequestFocusController {
8038         public boolean acceptRequestFocus(Component from, Component to,
8039                                           boolean temporary, boolean focusedWindowChangeAllowed,
8040                                           FocusEvent.Cause cause)
8041         {
8042             return true;
8043         }
8044     };
8045 
8046     static synchronized void setRequestFocusController(RequestFocusController requestController)
8047     {
8048         if (requestController == null) {
8049             requestFocusController = new DummyRequestFocusController();
8050         } else {
8051             requestFocusController = requestController;
8052         }
8053     }
8054 
8055     /**
8056      * Returns the Container which is the focus cycle root of this Component's
8057      * focus traversal cycle. Each focus traversal cycle has only a single
8058      * focus cycle root and each Component which is not a Container belongs to
8059      * only a single focus traversal cycle. Containers which are focus cycle
8060      * roots belong to two cycles: one rooted at the Container itself, and one
8061      * rooted at the Container's nearest focus-cycle-root ancestor. For such
8062      * Containers, this method will return the Container's nearest focus-cycle-
8063      * root ancestor.
8064      *
8065      * @return this Component's nearest focus-cycle-root ancestor
8066      * @see Container#isFocusCycleRoot()
8067      * @since 1.4
8068      */
8069     public Container getFocusCycleRootAncestor() {
8070         Container rootAncestor = this.parent;
8071         while (rootAncestor != null && !rootAncestor.isFocusCycleRoot()) {
8072             rootAncestor = rootAncestor.parent;
8073         }
8074         return rootAncestor;
8075     }
8076 
8077     /**
8078      * Returns whether the specified Container is the focus cycle root of this
8079      * Component's focus traversal cycle. Each focus traversal cycle has only
8080      * a single focus cycle root and each Component which is not a Container
8081      * belongs to only a single focus traversal cycle.
8082      *
8083      * @param container the Container to be tested
8084      * @return {@code true} if the specified Container is a focus-cycle-
8085      *         root of this Component; {@code false} otherwise
8086      * @see Container#isFocusCycleRoot()
8087      * @since 1.4
8088      */
8089     public boolean isFocusCycleRoot(Container container) {
8090         Container rootAncestor = getFocusCycleRootAncestor();
8091         return (rootAncestor == container);
8092     }
8093 
8094     Container getTraversalRoot() {
8095         return getFocusCycleRootAncestor();
8096     }
8097 
8098     /**
8099      * Transfers the focus to the next component, as though this Component were
8100      * the focus owner.
8101      * @see       #requestFocus()
8102      * @since     1.1
8103      */
8104     public void transferFocus() {
8105         nextFocus();
8106     }
8107 
8108     /**
8109      * @deprecated As of JDK version 1.1,
8110      * replaced by transferFocus().
8111      */
8112     @Deprecated
8113     public void nextFocus() {
8114         transferFocus(false);
8115     }
8116 
8117     boolean transferFocus(boolean clearOnFailure) {
8118         if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
8119             focusLog.finer("clearOnFailure = " + clearOnFailure);
8120         }
8121         Component toFocus = getNextFocusCandidate();
8122         boolean res = false;
8123         if (toFocus != null && !toFocus.isFocusOwner() && toFocus != this) {
8124             res = toFocus.requestFocusInWindow(FocusEvent.Cause.TRAVERSAL_FORWARD);
8125         }
8126         if (clearOnFailure && !res) {
8127             if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
8128                 focusLog.finer("clear global focus owner");
8129             }
8130             KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwnerPriv();
8131         }
8132         if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
8133             focusLog.finer("returning result: " + res);
8134         }
8135         return res;
8136     }
8137 
8138     @SuppressWarnings("deprecation")
8139     final Component getNextFocusCandidate() {
8140         Container rootAncestor = getTraversalRoot();
8141         Component comp = this;
8142         while (rootAncestor != null &&
8143                !(rootAncestor.isShowing() && rootAncestor.canBeFocusOwner()))
8144         {
8145             comp = rootAncestor;
8146             rootAncestor = comp.getFocusCycleRootAncestor();
8147         }
8148         if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
8149             focusLog.finer("comp = " + comp + ", root = " + rootAncestor);
8150         }
8151         Component candidate = null;
8152         if (rootAncestor != null) {
8153             FocusTraversalPolicy policy = rootAncestor.getFocusTraversalPolicy();
8154             Component toFocus = policy.getComponentAfter(rootAncestor, comp);
8155             if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
8156                 focusLog.finer("component after is " + toFocus);
8157             }
8158             if (toFocus == null) {
8159                 toFocus = policy.getDefaultComponent(rootAncestor);
8160                 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
8161                     focusLog.finer("default component is " + toFocus);
8162                 }
8163             }
8164             if (toFocus == null) {
8165                 Applet applet = EmbeddedFrame.getAppletIfAncestorOf(this);
8166                 if (applet != null) {
8167                     toFocus = applet;
8168                 }
8169             }
8170             candidate = toFocus;
8171         }
8172         if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
8173             focusLog.finer("Focus transfer candidate: " + candidate);
8174         }
8175         return candidate;
8176     }
8177 
8178     /**
8179      * Transfers the focus to the previous component, as though this Component
8180      * were the focus owner.
8181      * @see       #requestFocus()
8182      * @since     1.4
8183      */
8184     public void transferFocusBackward() {
8185         transferFocusBackward(false);
8186     }
8187 
8188     boolean transferFocusBackward(boolean clearOnFailure) {
8189         Container rootAncestor = getTraversalRoot();
8190         Component comp = this;
8191         while (rootAncestor != null &&
8192                !(rootAncestor.isShowing() && rootAncestor.canBeFocusOwner()))
8193         {
8194             comp = rootAncestor;
8195             rootAncestor = comp.getFocusCycleRootAncestor();
8196         }
8197         boolean res = false;
8198         if (rootAncestor != null) {
8199             FocusTraversalPolicy policy = rootAncestor.getFocusTraversalPolicy();
8200             Component toFocus = policy.getComponentBefore(rootAncestor, comp);
8201             if (toFocus == null) {
8202                 toFocus = policy.getDefaultComponent(rootAncestor);
8203             }
8204             if (toFocus != null) {
8205                 res = toFocus.requestFocusInWindow(FocusEvent.Cause.TRAVERSAL_BACKWARD);
8206             }
8207         }
8208         if (clearOnFailure && !res) {
8209             if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
8210                 focusLog.finer("clear global focus owner");
8211             }
8212             KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwnerPriv();
8213         }
8214         if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {
8215             focusLog.finer("returning result: " + res);
8216         }
8217         return res;
8218     }
8219 
8220     /**
8221      * Transfers the focus up one focus traversal cycle. Typically, the focus
8222      * owner is set to this Component's focus cycle root, and the current focus
8223      * cycle root is set to the new focus owner's focus cycle root. If,
8224      * however, this Component's focus cycle root is a Window, then the focus
8225      * owner is set to the focus cycle root's default Component to focus, and
8226      * the current focus cycle root is unchanged.
8227      *
8228      * @see       #requestFocus()
8229      * @see       Container#isFocusCycleRoot()
8230      * @see       Container#setFocusCycleRoot(boolean)
8231      * @since     1.4
8232      */
8233     public void transferFocusUpCycle() {
8234         Container rootAncestor;
8235         for (rootAncestor = getFocusCycleRootAncestor();
8236              rootAncestor != null && !(rootAncestor.isShowing() &&
8237                                        rootAncestor.isFocusable() &&
8238                                        rootAncestor.isEnabled());
8239              rootAncestor = rootAncestor.getFocusCycleRootAncestor()) {
8240         }
8241 
8242         if (rootAncestor != null) {
8243             Container rootAncestorRootAncestor =
8244                 rootAncestor.getFocusCycleRootAncestor();
8245             Container fcr = (rootAncestorRootAncestor != null) ?
8246                 rootAncestorRootAncestor : rootAncestor;
8247 
8248             KeyboardFocusManager.getCurrentKeyboardFocusManager().
8249                 setGlobalCurrentFocusCycleRootPriv(fcr);
8250             rootAncestor.requestFocus(FocusEvent.Cause.TRAVERSAL_UP);
8251         } else {
8252             Window window = getContainingWindow();
8253 
8254             if (window != null) {
8255                 Component toFocus = window.getFocusTraversalPolicy().
8256                     getDefaultComponent(window);
8257                 if (toFocus != null) {
8258                     KeyboardFocusManager.getCurrentKeyboardFocusManager().
8259                         setGlobalCurrentFocusCycleRootPriv(window);
8260                     toFocus.requestFocus(FocusEvent.Cause.TRAVERSAL_UP);
8261                 }
8262             }
8263         }
8264     }
8265 
8266     /**
8267      * Returns {@code true} if this {@code Component} is the
8268      * focus owner.  This method is obsolete, and has been replaced by
8269      * {@code isFocusOwner()}.
8270      *
8271      * @return {@code true} if this {@code Component} is the
8272      *         focus owner; {@code false} otherwise
8273      * @since 1.2
8274      */
8275     public boolean hasFocus() {
8276         return (KeyboardFocusManager.getCurrentKeyboardFocusManager().
8277                 getFocusOwner() == this);
8278     }
8279 
8280     /**
8281      * Returns {@code true} if this {@code Component} is the
8282      *    focus owner.
8283      *
8284      * @return {@code true} if this {@code Component} is the
8285      *     focus owner; {@code false} otherwise
8286      * @since 1.4
8287      */
8288     public boolean isFocusOwner() {
8289         return hasFocus();
8290     }
8291 
8292     /*
8293      * Used to disallow auto-focus-transfer on disposal of the focus owner
8294      * in the process of disposing its parent container.
8295      */
8296     private boolean autoFocusTransferOnDisposal = true;
8297 
8298     void setAutoFocusTransferOnDisposal(boolean value) {
8299         autoFocusTransferOnDisposal = value;
8300     }
8301 
8302     boolean isAutoFocusTransferOnDisposal() {
8303         return autoFocusTransferOnDisposal;
8304     }
8305 
8306     /**
8307      * Adds the specified popup menu to the component.
8308      * @param     popup the popup menu to be added to the component.
8309      * @see       #remove(MenuComponent)
8310      * @exception NullPointerException if {@code popup} is {@code null}
8311      * @since     1.1
8312      */
8313     public void add(PopupMenu popup) {
8314         synchronized (getTreeLock()) {
8315             if (popup.parent != null) {
8316                 popup.parent.remove(popup);
8317             }
8318             if (popups == null) {
8319                 popups = new Vector<PopupMenu>();
8320             }
8321             popups.addElement(popup);
8322             popup.parent = this;
8323 
8324             if (peer != null) {
8325                 if (popup.peer == null) {
8326                     popup.addNotify();
8327                 }
8328             }
8329         }
8330     }
8331 
8332     /**
8333      * Removes the specified popup menu from the component.
8334      * @param     popup the popup menu to be removed
8335      * @see       #add(PopupMenu)
8336      * @since     1.1
8337      */
8338     @SuppressWarnings("unchecked")
8339     public void remove(MenuComponent popup) {
8340         synchronized (getTreeLock()) {
8341             if (popups == null) {
8342                 return;
8343             }
8344             int index = popups.indexOf(popup);
8345             if (index >= 0) {
8346                 PopupMenu pmenu = (PopupMenu)popup;
8347                 if (pmenu.peer != null) {
8348                     pmenu.removeNotify();
8349                 }
8350                 pmenu.parent = null;
8351                 popups.removeElementAt(index);
8352                 if (popups.size() == 0) {
8353                     popups = null;
8354                 }
8355             }
8356         }
8357     }
8358 
8359     /**
8360      * Returns a string representing the state of this component. This
8361      * method is intended to be used only for debugging purposes, and the
8362      * content and format of the returned string may vary between
8363      * implementations. The returned string may be empty but may not be
8364      * {@code null}.
8365      *
8366      * @return  a string representation of this component's state
8367      * @since     1.0
8368      */
8369     protected String paramString() {
8370         final String thisName = Objects.toString(getName(), "");
8371         final String invalid = isValid() ? "" : ",invalid";
8372         final String hidden = visible ? "" : ",hidden";
8373         final String disabled = enabled ? "" : ",disabled";
8374         return thisName + ',' + x + ',' + y + ',' + width + 'x' + height
8375                 + invalid + hidden + disabled;
8376     }
8377 
8378     /**
8379      * Returns a string representation of this component and its values.
8380      * @return    a string representation of this component
8381      * @since     1.0
8382      */
8383     public String toString() {
8384         return getClass().getName() + '[' + paramString() + ']';
8385     }
8386 
8387     /**
8388      * Prints a listing of this component to the standard system output
8389      * stream {@code System.out}.
8390      * @see       java.lang.System#out
8391      * @since     1.0
8392      */
8393     public void list() {
8394         list(System.out, 0);
8395     }
8396 
8397     /**
8398      * Prints a listing of this component to the specified output
8399      * stream.
8400      * @param    out   a print stream
8401      * @throws   NullPointerException if {@code out} is {@code null}
8402      * @since    1.0
8403      */
8404     public void list(PrintStream out) {
8405         list(out, 0);
8406     }
8407 
8408     /**
8409      * Prints out a list, starting at the specified indentation, to the
8410      * specified print stream.
8411      * @param     out      a print stream
8412      * @param     indent   number of spaces to indent
8413      * @see       java.io.PrintStream#println(java.lang.Object)
8414      * @throws    NullPointerException if {@code out} is {@code null}
8415      * @since     1.0
8416      */
8417     public void list(PrintStream out, int indent) {
8418         for (int i = 0 ; i < indent ; i++) {
8419             out.print(" ");
8420         }
8421         out.println(this);
8422     }
8423 
8424     /**
8425      * Prints a listing to the specified print writer.
8426      * @param  out  the print writer to print to
8427      * @throws NullPointerException if {@code out} is {@code null}
8428      * @since 1.1
8429      */
8430     public void list(PrintWriter out) {
8431         list(out, 0);
8432     }
8433 
8434     /**
8435      * Prints out a list, starting at the specified indentation, to
8436      * the specified print writer.
8437      * @param out the print writer to print to
8438      * @param indent the number of spaces to indent
8439      * @throws NullPointerException if {@code out} is {@code null}
8440      * @see       java.io.PrintStream#println(java.lang.Object)
8441      * @since 1.1
8442      */
8443     public void list(PrintWriter out, int indent) {
8444         for (int i = 0 ; i < indent ; i++) {
8445             out.print(" ");
8446         }
8447         out.println(this);
8448     }
8449 
8450     /*
8451      * Fetches the native container somewhere higher up in the component
8452      * tree that contains this component.
8453      */
8454     final Container getNativeContainer() {
8455         Container p = getContainer();
8456         while (p != null && p.peer instanceof LightweightPeer) {
8457             p = p.getContainer();
8458         }
8459         return p;
8460     }
8461 
8462     /**
8463      * Adds a PropertyChangeListener to the listener list. The listener is
8464      * registered for all bound properties of this class, including the
8465      * following:
8466      * <ul>
8467      *    <li>this Component's font ("font")</li>
8468      *    <li>this Component's background color ("background")</li>
8469      *    <li>this Component's foreground color ("foreground")</li>
8470      *    <li>this Component's focusability ("focusable")</li>
8471      *    <li>this Component's focus traversal keys enabled state
8472      *        ("focusTraversalKeysEnabled")</li>
8473      *    <li>this Component's Set of FORWARD_TRAVERSAL_KEYS
8474      *        ("forwardFocusTraversalKeys")</li>
8475      *    <li>this Component's Set of BACKWARD_TRAVERSAL_KEYS
8476      *        ("backwardFocusTraversalKeys")</li>
8477      *    <li>this Component's Set of UP_CYCLE_TRAVERSAL_KEYS
8478      *        ("upCycleFocusTraversalKeys")</li>
8479      *    <li>this Component's preferred size ("preferredSize")</li>
8480      *    <li>this Component's minimum size ("minimumSize")</li>
8481      *    <li>this Component's maximum size ("maximumSize")</li>
8482      *    <li>this Component's name ("name")</li>
8483      * </ul>
8484      * Note that if this {@code Component} is inheriting a bound property, then no
8485      * event will be fired in response to a change in the inherited property.
8486      * <p>
8487      * If {@code listener} is {@code null},
8488      * no exception is thrown and no action is performed.
8489      *
8490      * @param    listener  the property change listener to be added
8491      *
8492      * @see #removePropertyChangeListener
8493      * @see #getPropertyChangeListeners
8494      * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
8495      */
8496     public void addPropertyChangeListener(
8497                                                        PropertyChangeListener listener) {
8498         synchronized (getObjectLock()) {
8499             if (listener == null) {
8500                 return;
8501             }
8502             if (changeSupport == null) {
8503                 changeSupport = new PropertyChangeSupport(this);
8504             }
8505             changeSupport.addPropertyChangeListener(listener);
8506         }
8507     }
8508 
8509     /**
8510      * Removes a PropertyChangeListener from the listener list. This method
8511      * should be used to remove PropertyChangeListeners that were registered
8512      * for all bound properties of this class.
8513      * <p>
8514      * If listener is null, no exception is thrown and no action is performed.
8515      *
8516      * @param listener the PropertyChangeListener to be removed
8517      *
8518      * @see #addPropertyChangeListener
8519      * @see #getPropertyChangeListeners
8520      * @see #removePropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
8521      */
8522     public void removePropertyChangeListener(
8523                                                           PropertyChangeListener listener) {
8524         synchronized (getObjectLock()) {
8525             if (listener == null || changeSupport == null) {
8526                 return;
8527             }
8528             changeSupport.removePropertyChangeListener(listener);
8529         }
8530     }
8531 
8532     /**
8533      * Returns an array of all the property change listeners
8534      * registered on this component.
8535      *
8536      * @return all of this component's {@code PropertyChangeListener}s
8537      *         or an empty array if no property change
8538      *         listeners are currently registered
8539      *
8540      * @see      #addPropertyChangeListener
8541      * @see      #removePropertyChangeListener
8542      * @see      #getPropertyChangeListeners(java.lang.String)
8543      * @see      java.beans.PropertyChangeSupport#getPropertyChangeListeners
8544      * @since    1.4
8545      */
8546     public PropertyChangeListener[] getPropertyChangeListeners() {
8547         synchronized (getObjectLock()) {
8548             if (changeSupport == null) {
8549                 return new PropertyChangeListener[0];
8550             }
8551             return changeSupport.getPropertyChangeListeners();
8552         }
8553     }
8554 
8555     /**
8556      * Adds a PropertyChangeListener to the listener list for a specific
8557      * property. The specified property may be user-defined, or one of the
8558      * following:
8559      * <ul>
8560      *    <li>this Component's font ("font")</li>
8561      *    <li>this Component's background color ("background")</li>
8562      *    <li>this Component's foreground color ("foreground")</li>
8563      *    <li>this Component's focusability ("focusable")</li>
8564      *    <li>this Component's focus traversal keys enabled state
8565      *        ("focusTraversalKeysEnabled")</li>
8566      *    <li>this Component's Set of FORWARD_TRAVERSAL_KEYS
8567      *        ("forwardFocusTraversalKeys")</li>
8568      *    <li>this Component's Set of BACKWARD_TRAVERSAL_KEYS
8569      *        ("backwardFocusTraversalKeys")</li>
8570      *    <li>this Component's Set of UP_CYCLE_TRAVERSAL_KEYS
8571      *        ("upCycleFocusTraversalKeys")</li>
8572      * </ul>
8573      * Note that if this {@code Component} is inheriting a bound property, then no
8574      * event will be fired in response to a change in the inherited property.
8575      * <p>
8576      * If {@code propertyName} or {@code listener} is {@code null},
8577      * no exception is thrown and no action is taken.
8578      *
8579      * @param propertyName one of the property names listed above
8580      * @param listener the property change listener to be added
8581      *
8582      * @see #removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
8583      * @see #getPropertyChangeListeners(java.lang.String)
8584      * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
8585      */
8586     public void addPropertyChangeListener(
8587                                                        String propertyName,
8588                                                        PropertyChangeListener listener) {
8589         synchronized (getObjectLock()) {
8590             if (listener == null) {
8591                 return;
8592             }
8593             if (changeSupport == null) {
8594                 changeSupport = new PropertyChangeSupport(this);
8595             }
8596             changeSupport.addPropertyChangeListener(propertyName, listener);
8597         }
8598     }
8599 
8600     /**
8601      * Removes a {@code PropertyChangeListener} from the listener
8602      * list for a specific property. This method should be used to remove
8603      * {@code PropertyChangeListener}s
8604      * that were registered for a specific bound property.
8605      * <p>
8606      * If {@code propertyName} or {@code listener} is {@code null},
8607      * no exception is thrown and no action is taken.
8608      *
8609      * @param propertyName a valid property name
8610      * @param listener the PropertyChangeListener to be removed
8611      *
8612      * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
8613      * @see #getPropertyChangeListeners(java.lang.String)
8614      * @see #removePropertyChangeListener(java.beans.PropertyChangeListener)
8615      */
8616     public void removePropertyChangeListener(
8617                                                           String propertyName,
8618                                                           PropertyChangeListener listener) {
8619         synchronized (getObjectLock()) {
8620             if (listener == null || changeSupport == null) {
8621                 return;
8622             }
8623             changeSupport.removePropertyChangeListener(propertyName, listener);
8624         }
8625     }
8626 
8627     /**
8628      * Returns an array of all the listeners which have been associated
8629      * with the named property.
8630      *
8631      * @param  propertyName the property name
8632      * @return all of the {@code PropertyChangeListener}s associated with
8633      *         the named property; if no such listeners have been added or
8634      *         if {@code propertyName} is {@code null}, an empty
8635      *         array is returned
8636      *
8637      * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
8638      * @see #removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
8639      * @see #getPropertyChangeListeners
8640      * @since 1.4
8641      */
8642     public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
8643         synchronized (getObjectLock()) {
8644             if (changeSupport == null) {
8645                 return new PropertyChangeListener[0];
8646             }
8647             return changeSupport.getPropertyChangeListeners(propertyName);
8648         }
8649     }
8650 
8651     /**
8652      * Support for reporting bound property changes for Object properties.
8653      * This method can be called when a bound property has changed and it will
8654      * send the appropriate PropertyChangeEvent to any registered
8655      * PropertyChangeListeners.
8656      *
8657      * @param propertyName the property whose value has changed
8658      * @param oldValue the property's previous value
8659      * @param newValue the property's new value
8660      */
8661     protected void firePropertyChange(String propertyName,
8662                                       Object oldValue, Object newValue) {
8663         PropertyChangeSupport changeSupport;
8664         synchronized (getObjectLock()) {
8665             changeSupport = this.changeSupport;
8666         }
8667         if (changeSupport == null ||
8668             (oldValue != null && newValue != null && oldValue.equals(newValue))) {
8669             return;
8670         }
8671         changeSupport.firePropertyChange(propertyName, oldValue, newValue);
8672     }
8673 
8674     /**
8675      * Support for reporting bound property changes for boolean properties.
8676      * This method can be called when a bound property has changed and it will
8677      * send the appropriate PropertyChangeEvent to any registered
8678      * PropertyChangeListeners.
8679      *
8680      * @param propertyName the property whose value has changed
8681      * @param oldValue the property's previous value
8682      * @param newValue the property's new value
8683      * @since 1.4
8684      */
8685     protected void firePropertyChange(String propertyName,
8686                                       boolean oldValue, boolean newValue) {
8687         PropertyChangeSupport changeSupport = this.changeSupport;
8688         if (changeSupport == null || oldValue == newValue) {
8689             return;
8690         }
8691         changeSupport.firePropertyChange(propertyName, oldValue, newValue);
8692     }
8693 
8694     /**
8695      * Support for reporting bound property changes for integer properties.
8696      * This method can be called when a bound property has changed and it will
8697      * send the appropriate PropertyChangeEvent to any registered
8698      * PropertyChangeListeners.
8699      *
8700      * @param propertyName the property whose value has changed
8701      * @param oldValue the property's previous value
8702      * @param newValue the property's new value
8703      * @since 1.4
8704      */
8705     protected void firePropertyChange(String propertyName,
8706                                       int oldValue, int newValue) {
8707         PropertyChangeSupport changeSupport = this.changeSupport;
8708         if (changeSupport == null || oldValue == newValue) {
8709             return;
8710         }
8711         changeSupport.firePropertyChange(propertyName, oldValue, newValue);
8712     }
8713 
8714     /**
8715      * Reports a bound property change.
8716      *
8717      * @param propertyName the programmatic name of the property
8718      *          that was changed
8719      * @param oldValue the old value of the property (as a byte)
8720      * @param newValue the new value of the property (as a byte)
8721      * @see #firePropertyChange(java.lang.String, java.lang.Object,
8722      *          java.lang.Object)
8723      * @since 1.5
8724      */
8725     public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {
8726         if (changeSupport == null || oldValue == newValue) {
8727             return;
8728         }
8729         firePropertyChange(propertyName, Byte.valueOf(oldValue), Byte.valueOf(newValue));
8730     }
8731 
8732     /**
8733      * Reports a bound property change.
8734      *
8735      * @param propertyName the programmatic name of the property
8736      *          that was changed
8737      * @param oldValue the old value of the property (as a char)
8738      * @param newValue the new value of the property (as a char)
8739      * @see #firePropertyChange(java.lang.String, java.lang.Object,
8740      *          java.lang.Object)
8741      * @since 1.5
8742      */
8743     public void firePropertyChange(String propertyName, char oldValue, char newValue) {
8744         if (changeSupport == null || oldValue == newValue) {
8745             return;
8746         }
8747         firePropertyChange(propertyName, Character.valueOf(oldValue), Character.valueOf(newValue));
8748     }
8749 
8750     /**
8751      * Reports a bound property change.
8752      *
8753      * @param propertyName the programmatic name of the property
8754      *          that was changed
8755      * @param oldValue the old value of the property (as a short)
8756      * @param newValue the new value of the property (as a short)
8757      * @see #firePropertyChange(java.lang.String, java.lang.Object,
8758      *          java.lang.Object)
8759      * @since 1.5
8760      */
8761     public void firePropertyChange(String propertyName, short oldValue, short newValue) {
8762         if (changeSupport == null || oldValue == newValue) {
8763             return;
8764         }
8765         firePropertyChange(propertyName, Short.valueOf(oldValue), Short.valueOf(newValue));
8766     }
8767 
8768 
8769     /**
8770      * Reports a bound property change.
8771      *
8772      * @param propertyName the programmatic name of the property
8773      *          that was changed
8774      * @param oldValue the old value of the property (as a long)
8775      * @param newValue the new value of the property (as a long)
8776      * @see #firePropertyChange(java.lang.String, java.lang.Object,
8777      *          java.lang.Object)
8778      * @since 1.5
8779      */
8780     public void firePropertyChange(String propertyName, long oldValue, long newValue) {
8781         if (changeSupport == null || oldValue == newValue) {
8782             return;
8783         }
8784         firePropertyChange(propertyName, Long.valueOf(oldValue), Long.valueOf(newValue));
8785     }
8786 
8787     /**
8788      * Reports a bound property change.
8789      *
8790      * @param propertyName the programmatic name of the property
8791      *          that was changed
8792      * @param oldValue the old value of the property (as a float)
8793      * @param newValue the new value of the property (as a float)
8794      * @see #firePropertyChange(java.lang.String, java.lang.Object,
8795      *          java.lang.Object)
8796      * @since 1.5
8797      */
8798     public void firePropertyChange(String propertyName, float oldValue, float newValue) {
8799         if (changeSupport == null || oldValue == newValue) {
8800             return;
8801         }
8802         firePropertyChange(propertyName, Float.valueOf(oldValue), Float.valueOf(newValue));
8803     }
8804 
8805     /**
8806      * Reports a bound property change.
8807      *
8808      * @param propertyName the programmatic name of the property
8809      *          that was changed
8810      * @param oldValue the old value of the property (as a double)
8811      * @param newValue the new value of the property (as a double)
8812      * @see #firePropertyChange(java.lang.String, java.lang.Object,
8813      *          java.lang.Object)
8814      * @since 1.5
8815      */
8816     public void firePropertyChange(String propertyName, double oldValue, double newValue) {
8817         if (changeSupport == null || oldValue == newValue) {
8818             return;
8819         }
8820         firePropertyChange(propertyName, Double.valueOf(oldValue), Double.valueOf(newValue));
8821     }
8822 
8823 
8824     // Serialization support.
8825 
8826     /**
8827      * Component Serialized Data Version.
8828      *
8829      * @serial
8830      */
8831     private int componentSerializedDataVersion = 4;
8832 
8833     /**
8834      * This hack is for Swing serialization. It will invoke
8835      * the Swing package private method {@code compWriteObjectNotify}.
8836      */
8837     private void doSwingSerialization() {
8838         if (!(this instanceof JComponent)) {
8839             return;
8840         }
8841         @SuppressWarnings("deprecation")
8842         Package swingPackage = Package.getPackage("javax.swing");
8843         // For Swing serialization to correctly work Swing needs to
8844         // be notified before Component does it's serialization.  This
8845         // hack accommodates this.
8846         //
8847         // Swing classes MUST be loaded by the bootstrap class loader,
8848         // otherwise we don't consider them.
8849         for (Class<?> klass = Component.this.getClass(); klass != null;
8850                    klass = klass.getSuperclass()) {
8851             if (klass.getPackage() == swingPackage &&
8852                       klass.getClassLoader() == null) {
8853 
8854                 SwingAccessor.getJComponentAccessor()
8855                         .compWriteObjectNotify((JComponent) this);
8856                 return;
8857             }
8858         }
8859     }
8860 
8861     /**
8862      * Writes default serializable fields to stream.  Writes
8863      * a variety of serializable listeners as optional data.
8864      * The non-serializable listeners are detected and
8865      * no attempt is made to serialize them.
8866      *
8867      * @param s the {@code ObjectOutputStream} to write
8868      * @serialData {@code null} terminated sequence of
8869      *   0 or more pairs; the pair consists of a {@code String}
8870      *   and an {@code Object}; the {@code String} indicates
8871      *   the type of object and is one of the following (as of 1.4):
8872      *   {@code componentListenerK} indicating an
8873      *     {@code ComponentListener} object;
8874      *   {@code focusListenerK} indicating an
8875      *     {@code FocusListener} object;
8876      *   {@code keyListenerK} indicating an
8877      *     {@code KeyListener} object;
8878      *   {@code mouseListenerK} indicating an
8879      *     {@code MouseListener} object;
8880      *   {@code mouseMotionListenerK} indicating an
8881      *     {@code MouseMotionListener} object;
8882      *   {@code inputMethodListenerK} indicating an
8883      *     {@code InputMethodListener} object;
8884      *   {@code hierarchyListenerK} indicating an
8885      *     {@code HierarchyListener} object;
8886      *   {@code hierarchyBoundsListenerK} indicating an
8887      *     {@code HierarchyBoundsListener} object;
8888      *   {@code mouseWheelListenerK} indicating an
8889      *     {@code MouseWheelListener} object
8890      * @serialData an optional {@code ComponentOrientation}
8891      *    (after {@code inputMethodListener}, as of 1.2)
8892      *
8893      * @see AWTEventMulticaster#save(java.io.ObjectOutputStream, java.lang.String, java.util.EventListener)
8894      * @see #componentListenerK
8895      * @see #focusListenerK
8896      * @see #keyListenerK
8897      * @see #mouseListenerK
8898      * @see #mouseMotionListenerK
8899      * @see #inputMethodListenerK
8900      * @see #hierarchyListenerK
8901      * @see #hierarchyBoundsListenerK
8902      * @see #mouseWheelListenerK
8903      * @see #readObject(ObjectInputStream)
8904      */
8905     private void writeObject(ObjectOutputStream s)
8906       throws IOException
8907     {
8908         doSwingSerialization();
8909 
8910         s.defaultWriteObject();
8911 
8912         AWTEventMulticaster.save(s, componentListenerK, componentListener);
8913         AWTEventMulticaster.save(s, focusListenerK, focusListener);
8914         AWTEventMulticaster.save(s, keyListenerK, keyListener);
8915         AWTEventMulticaster.save(s, mouseListenerK, mouseListener);
8916         AWTEventMulticaster.save(s, mouseMotionListenerK, mouseMotionListener);
8917         AWTEventMulticaster.save(s, inputMethodListenerK, inputMethodListener);
8918 
8919         s.writeObject(null);
8920         s.writeObject(componentOrientation);
8921 
8922         AWTEventMulticaster.save(s, hierarchyListenerK, hierarchyListener);
8923         AWTEventMulticaster.save(s, hierarchyBoundsListenerK,
8924                                  hierarchyBoundsListener);
8925         s.writeObject(null);
8926 
8927         AWTEventMulticaster.save(s, mouseWheelListenerK, mouseWheelListener);
8928         s.writeObject(null);
8929 
8930     }
8931 
8932     /**
8933      * Reads the {@code ObjectInputStream} and if it isn't
8934      * {@code null} adds a listener to receive a variety
8935      * of events fired by the component.
8936      * Unrecognized keys or values will be ignored.
8937      *
8938      * @param s the {@code ObjectInputStream} to read
8939      * @see #writeObject(ObjectOutputStream)
8940      */
8941     private void readObject(ObjectInputStream s)
8942       throws ClassNotFoundException, IOException
8943     {
8944         objectLock = new Object();
8945 
8946         acc = AccessController.getContext();
8947 
8948         s.defaultReadObject();
8949 
8950         appContext = AppContext.getAppContext();
8951         coalescingEnabled = checkCoalescing();
8952         if (componentSerializedDataVersion < 4) {
8953             // These fields are non-transient and rely on default
8954             // serialization. However, the default values are insufficient,
8955             // so we need to set them explicitly for object data streams prior
8956             // to 1.4.
8957             focusable = true;
8958             isFocusTraversableOverridden = FOCUS_TRAVERSABLE_UNKNOWN;
8959             initializeFocusTraversalKeys();
8960             focusTraversalKeysEnabled = true;
8961         }
8962 
8963         Object keyOrNull;
8964         while(null != (keyOrNull = s.readObject())) {
8965             String key = ((String)keyOrNull).intern();
8966 
8967             if (componentListenerK == key)
8968                 addComponentListener((ComponentListener)(s.readObject()));
8969 
8970             else if (focusListenerK == key)
8971                 addFocusListener((FocusListener)(s.readObject()));
8972 
8973             else if (keyListenerK == key)
8974                 addKeyListener((KeyListener)(s.readObject()));
8975 
8976             else if (mouseListenerK == key)
8977                 addMouseListener((MouseListener)(s.readObject()));
8978 
8979             else if (mouseMotionListenerK == key)
8980                 addMouseMotionListener((MouseMotionListener)(s.readObject()));
8981 
8982             else if (inputMethodListenerK == key)
8983                 addInputMethodListener((InputMethodListener)(s.readObject()));
8984 
8985             else // skip value for unrecognized key
8986                 s.readObject();
8987 
8988         }
8989 
8990         // Read the component's orientation if it's present
8991         Object orient = null;
8992 
8993         try {
8994             orient = s.readObject();
8995         } catch (java.io.OptionalDataException e) {
8996             // JDK 1.1 instances will not have this optional data.
8997             // e.eof will be true to indicate that there is no more
8998             // data available for this object.
8999             // If e.eof is not true, throw the exception as it
9000             // might have been caused by reasons unrelated to
9001             // componentOrientation.
9002 
9003             if (!e.eof)  {
9004                 throw (e);
9005             }
9006         }
9007 
9008         if (orient != null) {
9009             componentOrientation = (ComponentOrientation)orient;
9010         } else {
9011             componentOrientation = ComponentOrientation.UNKNOWN;
9012         }
9013 
9014         try {
9015             while(null != (keyOrNull = s.readObject())) {
9016                 String key = ((String)keyOrNull).intern();
9017 
9018                 if (hierarchyListenerK == key) {
9019                     addHierarchyListener((HierarchyListener)(s.readObject()));
9020                 }
9021                 else if (hierarchyBoundsListenerK == key) {
9022                     addHierarchyBoundsListener((HierarchyBoundsListener)
9023                                                (s.readObject()));
9024                 }
9025                 else {
9026                     // skip value for unrecognized key
9027                     s.readObject();
9028                 }
9029             }
9030         } catch (java.io.OptionalDataException e) {
9031             // JDK 1.1/1.2 instances will not have this optional data.
9032             // e.eof will be true to indicate that there is no more
9033             // data available for this object.
9034             // If e.eof is not true, throw the exception as it
9035             // might have been caused by reasons unrelated to
9036             // hierarchy and hierarchyBounds listeners.
9037 
9038             if (!e.eof)  {
9039                 throw (e);
9040             }
9041         }
9042 
9043         try {
9044             while (null != (keyOrNull = s.readObject())) {
9045                 String key = ((String)keyOrNull).intern();
9046 
9047                 if (mouseWheelListenerK == key) {
9048                     addMouseWheelListener((MouseWheelListener)(s.readObject()));
9049                 }
9050                 else {
9051                     // skip value for unrecognized key
9052                     s.readObject();
9053                 }
9054             }
9055         } catch (java.io.OptionalDataException e) {
9056             // pre-1.3 instances will not have this optional data.
9057             // e.eof will be true to indicate that there is no more
9058             // data available for this object.
9059             // If e.eof is not true, throw the exception as it
9060             // might have been caused by reasons unrelated to
9061             // mouse wheel listeners
9062 
9063             if (!e.eof)  {
9064                 throw (e);
9065             }
9066         }
9067 
9068         if (popups != null) {
9069             int npopups = popups.size();
9070             for (int i = 0 ; i < npopups ; i++) {
9071                 PopupMenu popup = popups.elementAt(i);
9072                 popup.parent = this;
9073             }
9074         }
9075     }
9076 
9077     /**
9078      * Sets the language-sensitive orientation that is to be used to order
9079      * the elements or text within this component.  Language-sensitive
9080      * {@code LayoutManager} and {@code Component}
9081      * subclasses will use this property to
9082      * determine how to lay out and draw components.
9083      * <p>
9084      * At construction time, a component's orientation is set to
9085      * {@code ComponentOrientation.UNKNOWN},
9086      * indicating that it has not been specified
9087      * explicitly.  The UNKNOWN orientation behaves the same as
9088      * {@code ComponentOrientation.LEFT_TO_RIGHT}.
9089      * <p>
9090      * To set the orientation of a single component, use this method.
9091      * To set the orientation of an entire component
9092      * hierarchy, use
9093      * {@link #applyComponentOrientation applyComponentOrientation}.
9094      * <p>
9095      * This method changes layout-related information, and therefore,
9096      * invalidates the component hierarchy.
9097      *
9098      * @param  o the orientation to be set
9099      *
9100      * @see ComponentOrientation
9101      * @see #invalidate
9102      *
9103      * @author Laura Werner, IBM
9104      */
9105     public void setComponentOrientation(ComponentOrientation o) {
9106         ComponentOrientation oldValue = componentOrientation;
9107         componentOrientation = o;
9108 
9109         // This is a bound property, so report the change to
9110         // any registered listeners.  (Cheap if there are none.)
9111         firePropertyChange("componentOrientation", oldValue, o);
9112 
9113         // This could change the preferred size of the Component.
9114         invalidateIfValid();
9115     }
9116 
9117     /**
9118      * Retrieves the language-sensitive orientation that is to be used to order
9119      * the elements or text within this component.  {@code LayoutManager}
9120      * and {@code Component}
9121      * subclasses that wish to respect orientation should call this method to
9122      * get the component's orientation before performing layout or drawing.
9123      *
9124      * @return the orientation to order the elements or text
9125      * @see ComponentOrientation
9126      *
9127      * @author Laura Werner, IBM
9128      */
9129     public ComponentOrientation getComponentOrientation() {
9130         return componentOrientation;
9131     }
9132 
9133     /**
9134      * Sets the {@code ComponentOrientation} property of this component
9135      * and all components contained within it.
9136      * <p>
9137      * This method changes layout-related information, and therefore,
9138      * invalidates the component hierarchy.
9139      *
9140      *
9141      * @param orientation the new component orientation of this component and
9142      *        the components contained within it.
9143      * @exception NullPointerException if {@code orientation} is null.
9144      * @see #setComponentOrientation
9145      * @see #getComponentOrientation
9146      * @see #invalidate
9147      * @since 1.4
9148      */
9149     public void applyComponentOrientation(ComponentOrientation orientation) {
9150         if (orientation == null) {
9151             throw new NullPointerException();
9152         }
9153         setComponentOrientation(orientation);
9154     }
9155 
9156     final boolean canBeFocusOwner() {
9157         // It is enabled, visible, focusable.
9158         if (isEnabled() && isDisplayable() && isVisible() && isFocusable()) {
9159             return true;
9160         }
9161         return false;
9162     }
9163 
9164     /**
9165      * Checks that this component meets the prerequisites to be focus owner:
9166      * - it is enabled, visible, focusable
9167      * - it's parents are all enabled and showing
9168      * - top-level window is focusable
9169      * - if focus cycle root has DefaultFocusTraversalPolicy then it also checks that this policy accepts
9170      * this component as focus owner
9171      * @since 1.5
9172      */
9173     final boolean canBeFocusOwnerRecursively() {
9174         // - it is enabled, visible, focusable
9175         if (!canBeFocusOwner()) {
9176             return false;
9177         }
9178 
9179         // - it's parents are all enabled and showing
9180         synchronized(getTreeLock()) {
9181             if (parent != null) {
9182                 return parent.canContainFocusOwner(this);
9183             }
9184         }
9185         return true;
9186     }
9187 
9188     /**
9189      * Fix the location of the HW component in a LW container hierarchy.
9190      */
9191     final void relocateComponent() {
9192         synchronized (getTreeLock()) {
9193             if (peer == null) {
9194                 return;
9195             }
9196             int nativeX = x;
9197             int nativeY = y;
9198             for (Component cont = getContainer();
9199                     cont != null && cont.isLightweight();
9200                     cont = cont.getContainer())
9201             {
9202                 nativeX += cont.x;
9203                 nativeY += cont.y;
9204             }
9205             peer.setBounds(nativeX, nativeY, width, height,
9206                     ComponentPeer.SET_LOCATION);
9207         }
9208     }
9209 
9210     /**
9211      * Returns the {@code Window} ancestor of the component.
9212      * @return Window ancestor of the component or component by itself if it is Window;
9213      *         null, if component is not a part of window hierarchy
9214      */
9215     Window getContainingWindow() {
9216         return SunToolkit.getContainingWindow(this);
9217     }
9218 
9219     /**
9220      * Initialize JNI field and method IDs
9221      */
9222     private static native void initIDs();
9223 
9224     /*
9225      * --- Accessibility Support ---
9226      *
9227      *  Component will contain all of the methods in interface Accessible,
9228      *  though it won't actually implement the interface - that will be up
9229      *  to the individual objects which extend Component.
9230      */
9231 
9232     /**
9233      * The {@code AccessibleContext} associated with this {@code Component}.
9234      */
9235     protected AccessibleContext accessibleContext = null;
9236 
9237     /**
9238      * Gets the {@code AccessibleContext} associated
9239      * with this {@code Component}.
9240      * The method implemented by this base
9241      * class returns null.  Classes that extend {@code Component}
9242      * should implement this method to return the
9243      * {@code AccessibleContext} associated with the subclass.
9244      *
9245      *
9246      * @return the {@code AccessibleContext} of this
9247      *    {@code Component}
9248      * @since 1.3
9249      */
9250     public AccessibleContext getAccessibleContext() {
9251         return accessibleContext;
9252     }
9253 
9254     /**
9255      * Inner class of Component used to provide default support for
9256      * accessibility.  This class is not meant to be used directly by
9257      * application developers, but is instead meant only to be
9258      * subclassed by component developers.
9259      * <p>
9260      * The class used to obtain the accessible role for this object.
9261      * @since 1.3
9262      */
9263     protected abstract class AccessibleAWTComponent extends AccessibleContext
9264         implements Serializable, AccessibleComponent {
9265 
9266         private static final long serialVersionUID = 642321655757800191L;
9267 
9268         /**
9269          * Though the class is abstract, this should be called by
9270          * all sub-classes.
9271          */
9272         protected AccessibleAWTComponent() {
9273         }
9274 
9275         /**
9276          * Number of PropertyChangeListener objects registered. It's used
9277          * to add/remove ComponentListener and FocusListener to track
9278          * target Component's state.
9279          */
9280         private transient volatile int propertyListenersCount = 0;
9281 
9282         /**
9283          * A component listener to track show/hide/resize events
9284          * and convert them to PropertyChange events.
9285          */
9286         protected ComponentListener accessibleAWTComponentHandler = null;
9287 
9288         /**
9289          * A listener to track focus events
9290          * and convert them to PropertyChange events.
9291          */
9292         protected FocusListener accessibleAWTFocusHandler = null;
9293 
9294         /**
9295          * Fire PropertyChange listener, if one is registered,
9296          * when shown/hidden..
9297          * @since 1.3
9298          */
9299         protected class AccessibleAWTComponentHandler implements ComponentListener {
9300             public void componentHidden(ComponentEvent e)  {
9301                 if (accessibleContext != null) {
9302                     accessibleContext.firePropertyChange(
9303                                                          AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
9304                                                          AccessibleState.VISIBLE, null);
9305                 }
9306             }
9307 
9308             public void componentShown(ComponentEvent e)  {
9309                 if (accessibleContext != null) {
9310                     accessibleContext.firePropertyChange(
9311                                                          AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
9312                                                          null, AccessibleState.VISIBLE);
9313                 }
9314             }
9315 
9316             public void componentMoved(ComponentEvent e)  {
9317             }
9318 
9319             public void componentResized(ComponentEvent e)  {
9320             }
9321         } // inner class AccessibleAWTComponentHandler
9322 
9323 
9324         /**
9325          * Fire PropertyChange listener, if one is registered,
9326          * when focus events happen
9327          * @since 1.3
9328          */
9329         protected class AccessibleAWTFocusHandler implements FocusListener {
9330             public void focusGained(FocusEvent event) {
9331                 if (accessibleContext != null) {
9332                     accessibleContext.firePropertyChange(
9333                                                          AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
9334                                                          null, AccessibleState.FOCUSED);
9335                 }
9336             }
9337             public void focusLost(FocusEvent event) {
9338                 if (accessibleContext != null) {
9339                     accessibleContext.firePropertyChange(
9340                                                          AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
9341                                                          AccessibleState.FOCUSED, null);
9342                 }
9343             }
9344         }  // inner class AccessibleAWTFocusHandler
9345 
9346 
9347         /**
9348          * Adds a {@code PropertyChangeListener} to the listener list.
9349          *
9350          * @param listener  the property change listener to be added
9351          */
9352         public void addPropertyChangeListener(PropertyChangeListener listener) {
9353             if (accessibleAWTComponentHandler == null) {
9354                 accessibleAWTComponentHandler = new AccessibleAWTComponentHandler();
9355             }
9356             if (accessibleAWTFocusHandler == null) {
9357                 accessibleAWTFocusHandler = new AccessibleAWTFocusHandler();
9358             }
9359             if (propertyListenersCount++ == 0) {
9360                 Component.this.addComponentListener(accessibleAWTComponentHandler);
9361                 Component.this.addFocusListener(accessibleAWTFocusHandler);
9362             }
9363             super.addPropertyChangeListener(listener);
9364         }
9365 
9366         /**
9367          * Remove a PropertyChangeListener from the listener list.
9368          * This removes a PropertyChangeListener that was registered
9369          * for all properties.
9370          *
9371          * @param listener  The PropertyChangeListener to be removed
9372          */
9373         public void removePropertyChangeListener(PropertyChangeListener listener) {
9374             if (--propertyListenersCount == 0) {
9375                 Component.this.removeComponentListener(accessibleAWTComponentHandler);
9376                 Component.this.removeFocusListener(accessibleAWTFocusHandler);
9377             }
9378             super.removePropertyChangeListener(listener);
9379         }
9380 
9381         // AccessibleContext methods
9382         //
9383         /**
9384          * Gets the accessible name of this object.  This should almost never
9385          * return {@code java.awt.Component.getName()},
9386          * as that generally isn't a localized name,
9387          * and doesn't have meaning for the user.  If the
9388          * object is fundamentally a text object (e.g. a menu item), the
9389          * accessible name should be the text of the object (e.g. "save").
9390          * If the object has a tooltip, the tooltip text may also be an
9391          * appropriate String to return.
9392          *
9393          * @return the localized name of the object -- can be
9394          *         {@code null} if this
9395          *         object does not have a name
9396          * @see javax.accessibility.AccessibleContext#setAccessibleName
9397          */
9398         public String getAccessibleName() {
9399             return accessibleName;
9400         }
9401 
9402         /**
9403          * Gets the accessible description of this object.  This should be
9404          * a concise, localized description of what this object is - what
9405          * is its meaning to the user.  If the object has a tooltip, the
9406          * tooltip text may be an appropriate string to return, assuming
9407          * it contains a concise description of the object (instead of just
9408          * the name of the object - e.g. a "Save" icon on a toolbar that
9409          * had "save" as the tooltip text shouldn't return the tooltip
9410          * text as the description, but something like "Saves the current
9411          * text document" instead).
9412          *
9413          * @return the localized description of the object -- can be
9414          *        {@code null} if this object does not have a description
9415          * @see javax.accessibility.AccessibleContext#setAccessibleDescription
9416          */
9417         public String getAccessibleDescription() {
9418             return accessibleDescription;
9419         }
9420 
9421         /**
9422          * Gets the role of this object.
9423          *
9424          * @return an instance of {@code AccessibleRole}
9425          *      describing the role of the object
9426          * @see javax.accessibility.AccessibleRole
9427          */
9428         public AccessibleRole getAccessibleRole() {
9429             return AccessibleRole.AWT_COMPONENT;
9430         }
9431 
9432         /**
9433          * Gets the state of this object.
9434          *
9435          * @return an instance of {@code AccessibleStateSet}
9436          *       containing the current state set of the object
9437          * @see javax.accessibility.AccessibleState
9438          */
9439         public AccessibleStateSet getAccessibleStateSet() {
9440             return Component.this.getAccessibleStateSet();
9441         }
9442 
9443         /**
9444          * Gets the {@code Accessible} parent of this object.
9445          * If the parent of this object implements {@code Accessible},
9446          * this method should simply return {@code getParent}.
9447          *
9448          * @return the {@code Accessible} parent of this
9449          *      object -- can be {@code null} if this
9450          *      object does not have an {@code Accessible} parent
9451          */
9452         public Accessible getAccessibleParent() {
9453             if (accessibleParent != null) {
9454                 return accessibleParent;
9455             } else {
9456                 Container parent = getParent();
9457                 if (parent instanceof Accessible) {
9458                     return (Accessible) parent;
9459                 }
9460             }
9461             return null;
9462         }
9463 
9464         /**
9465          * Gets the index of this object in its accessible parent.
9466          *
9467          * @return the index of this object in its parent; or -1 if this
9468          *    object does not have an accessible parent
9469          * @see #getAccessibleParent
9470          */
9471         public int getAccessibleIndexInParent() {
9472             return Component.this.getAccessibleIndexInParent();
9473         }
9474 
9475         /**
9476          * Returns the number of accessible children in the object.  If all
9477          * of the children of this object implement {@code Accessible},
9478          * then this method should return the number of children of this object.
9479          *
9480          * @return the number of accessible children in the object
9481          */
9482         public int getAccessibleChildrenCount() {
9483             return 0; // Components don't have children
9484         }
9485 
9486         /**
9487          * Returns the nth {@code Accessible} child of the object.
9488          *
9489          * @param i zero-based index of child
9490          * @return the nth {@code Accessible} child of the object
9491          */
9492         public Accessible getAccessibleChild(int i) {
9493             return null; // Components don't have children
9494         }
9495 
9496         /**
9497          * Returns the locale of this object.
9498          *
9499          * @return the locale of this object
9500          */
9501         public Locale getLocale() {
9502             return Component.this.getLocale();
9503         }
9504 
9505         /**
9506          * Gets the {@code AccessibleComponent} associated
9507          * with this object if one exists.
9508          * Otherwise return {@code null}.
9509          *
9510          * @return the component
9511          */
9512         public AccessibleComponent getAccessibleComponent() {
9513             return this;
9514         }
9515 
9516 
9517         // AccessibleComponent methods
9518         //
9519         /**
9520          * Gets the background color of this object.
9521          *
9522          * @return the background color, if supported, of the object;
9523          *      otherwise, {@code null}
9524          */
9525         public Color getBackground() {
9526             return Component.this.getBackground();
9527         }
9528 
9529         /**
9530          * Sets the background color of this object.
9531          * (For transparency, see {@code isOpaque}.)
9532          *
9533          * @param c the new {@code Color} for the background
9534          * @see Component#isOpaque
9535          */
9536         public void setBackground(Color c) {
9537             Component.this.setBackground(c);
9538         }
9539 
9540         /**
9541          * Gets the foreground color of this object.
9542          *
9543          * @return the foreground color, if supported, of the object;
9544          *     otherwise, {@code null}
9545          */
9546         public Color getForeground() {
9547             return Component.this.getForeground();
9548         }
9549 
9550         /**
9551          * Sets the foreground color of this object.
9552          *
9553          * @param c the new {@code Color} for the foreground
9554          */
9555         public void setForeground(Color c) {
9556             Component.this.setForeground(c);
9557         }
9558 
9559         /**
9560          * Gets the {@code Cursor} of this object.
9561          *
9562          * @return the {@code Cursor}, if supported,
9563          *     of the object; otherwise, {@code null}
9564          */
9565         public Cursor getCursor() {
9566             return Component.this.getCursor();
9567         }
9568 
9569         /**
9570          * Sets the {@code Cursor} of this object.
9571          * <p>
9572          * The method may have no visual effect if the Java platform
9573          * implementation and/or the native system do not support
9574          * changing the mouse cursor shape.
9575          * @param cursor the new {@code Cursor} for the object
9576          */
9577         public void setCursor(Cursor cursor) {
9578             Component.this.setCursor(cursor);
9579         }
9580 
9581         /**
9582          * Gets the {@code Font} of this object.
9583          *
9584          * @return the {@code Font}, if supported,
9585          *    for the object; otherwise, {@code null}
9586          */
9587         public Font getFont() {
9588             return Component.this.getFont();
9589         }
9590 
9591         /**
9592          * Sets the {@code Font} of this object.
9593          *
9594          * @param f the new {@code Font} for the object
9595          */
9596         public void setFont(Font f) {
9597             Component.this.setFont(f);
9598         }
9599 
9600         /**
9601          * Gets the {@code FontMetrics} of this object.
9602          *
9603          * @param f the {@code Font}
9604          * @return the {@code FontMetrics}, if supported,
9605          *     the object; otherwise, {@code null}
9606          * @see #getFont
9607          */
9608         public FontMetrics getFontMetrics(Font f) {
9609             if (f == null) {
9610                 return null;
9611             } else {
9612                 return Component.this.getFontMetrics(f);
9613             }
9614         }
9615 
9616         /**
9617          * Determines if the object is enabled.
9618          *
9619          * @return true if object is enabled; otherwise, false
9620          */
9621         public boolean isEnabled() {
9622             return Component.this.isEnabled();
9623         }
9624 
9625         /**
9626          * Sets the enabled state of the object.
9627          *
9628          * @param b if true, enables this object; otherwise, disables it
9629          */
9630         public void setEnabled(boolean b) {
9631             boolean old = Component.this.isEnabled();
9632             Component.this.setEnabled(b);
9633             if (b != old) {
9634                 if (accessibleContext != null) {
9635                     if (b) {
9636                         accessibleContext.firePropertyChange(
9637                                                              AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
9638                                                              null, AccessibleState.ENABLED);
9639                     } else {
9640                         accessibleContext.firePropertyChange(
9641                                                              AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
9642                                                              AccessibleState.ENABLED, null);
9643                     }
9644                 }
9645             }
9646         }
9647 
9648         /**
9649          * Determines if the object is visible.  Note: this means that the
9650          * object intends to be visible; however, it may not in fact be
9651          * showing on the screen because one of the objects that this object
9652          * is contained by is not visible.  To determine if an object is
9653          * showing on the screen, use {@code isShowing}.
9654          *
9655          * @return true if object is visible; otherwise, false
9656          */
9657         public boolean isVisible() {
9658             return Component.this.isVisible();
9659         }
9660 
9661         /**
9662          * Sets the visible state of the object.
9663          *
9664          * @param b if true, shows this object; otherwise, hides it
9665          */
9666         public void setVisible(boolean b) {
9667             boolean old = Component.this.isVisible();
9668             Component.this.setVisible(b);
9669             if (b != old) {
9670                 if (accessibleContext != null) {
9671                     if (b) {
9672                         accessibleContext.firePropertyChange(
9673                                                              AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
9674                                                              null, AccessibleState.VISIBLE);
9675                     } else {
9676                         accessibleContext.firePropertyChange(
9677                                                              AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
9678                                                              AccessibleState.VISIBLE, null);
9679                     }
9680                 }
9681             }
9682         }
9683 
9684         /**
9685          * Determines if the object is showing.  This is determined by checking
9686          * the visibility of the object and ancestors of the object.  Note:
9687          * this will return true even if the object is obscured by another
9688          * (for example, it happens to be underneath a menu that was pulled
9689          * down).
9690          *
9691          * @return true if object is showing; otherwise, false
9692          */
9693         public boolean isShowing() {
9694             return Component.this.isShowing();
9695         }
9696 
9697         /**
9698          * Checks whether the specified point is within this object's bounds,
9699          * where the point's x and y coordinates are defined to be relative to
9700          * the coordinate system of the object.
9701          *
9702          * @param p the {@code Point} relative to the
9703          *     coordinate system of the object
9704          * @return true if object contains {@code Point}; otherwise false
9705          */
9706         public boolean contains(Point p) {
9707             return Component.this.contains(p);
9708         }
9709 
9710         /**
9711          * Returns the location of the object on the screen.
9712          *
9713          * @return location of object on screen -- can be
9714          *    {@code null} if this object is not on the screen
9715          */
9716         public Point getLocationOnScreen() {
9717             synchronized (Component.this.getTreeLock()) {
9718                 if (Component.this.isShowing()) {
9719                     return Component.this.getLocationOnScreen();
9720                 } else {
9721                     return null;
9722                 }
9723             }
9724         }
9725 
9726         /**
9727          * Gets the location of the object relative to the parent in the form
9728          * of a point specifying the object's top-left corner in the screen's
9729          * coordinate space.
9730          *
9731          * @return an instance of Point representing the top-left corner of
9732          * the object's bounds in the coordinate space of the screen;
9733          * {@code null} if this object or its parent are not on the screen
9734          */
9735         public Point getLocation() {
9736             return Component.this.getLocation();
9737         }
9738 
9739         /**
9740          * Sets the location of the object relative to the parent.
9741          * @param p  the coordinates of the object
9742          */
9743         public void setLocation(Point p) {
9744             Component.this.setLocation(p);
9745         }
9746 
9747         /**
9748          * Gets the bounds of this object in the form of a Rectangle object.
9749          * The bounds specify this object's width, height, and location
9750          * relative to its parent.
9751          *
9752          * @return a rectangle indicating this component's bounds;
9753          *   {@code null} if this object is not on the screen
9754          */
9755         public Rectangle getBounds() {
9756             return Component.this.getBounds();
9757         }
9758 
9759         /**
9760          * Sets the bounds of this object in the form of a
9761          * {@code Rectangle} object.
9762          * The bounds specify this object's width, height, and location
9763          * relative to its parent.
9764          *
9765          * @param r a rectangle indicating this component's bounds
9766          */
9767         public void setBounds(Rectangle r) {
9768             Component.this.setBounds(r);
9769         }
9770 
9771         /**
9772          * Returns the size of this object in the form of a
9773          * {@code Dimension} object. The height field of the
9774          * {@code Dimension} object contains this object's
9775          * height, and the width field of the {@code Dimension}
9776          * object contains this object's width.
9777          *
9778          * @return a {@code Dimension} object that indicates
9779          *     the size of this component; {@code null} if
9780          *     this object is not on the screen
9781          */
9782         public Dimension getSize() {
9783             return Component.this.getSize();
9784         }
9785 
9786         /**
9787          * Resizes this object so that it has width and height.
9788          *
9789          * @param d the dimension specifying the new size of the object
9790          */
9791         public void setSize(Dimension d) {
9792             Component.this.setSize(d);
9793         }
9794 
9795         /**
9796          * Returns the {@code Accessible} child,
9797          * if one exists, contained at the local
9798          * coordinate {@code Point}.  Otherwise returns
9799          * {@code null}.
9800          *
9801          * @param p the point defining the top-left corner of
9802          *      the {@code Accessible}, given in the
9803          *      coordinate space of the object's parent
9804          * @return the {@code Accessible}, if it exists,
9805          *      at the specified location; else {@code null}
9806          */
9807         public Accessible getAccessibleAt(Point p) {
9808             return null; // Components don't have children
9809         }
9810 
9811         /**
9812          * Returns whether this object can accept focus or not.
9813          *
9814          * @return true if object can accept focus; otherwise false
9815          */
9816         public boolean isFocusTraversable() {
9817             return Component.this.isFocusTraversable();
9818         }
9819 
9820         /**
9821          * Requests focus for this object.
9822          */
9823         public void requestFocus() {
9824             Component.this.requestFocus();
9825         }
9826 
9827         /**
9828          * Adds the specified focus listener to receive focus events from this
9829          * component.
9830          *
9831          * @param l the focus listener
9832          */
9833         public void addFocusListener(FocusListener l) {
9834             Component.this.addFocusListener(l);
9835         }
9836 
9837         /**
9838          * Removes the specified focus listener so it no longer receives focus
9839          * events from this component.
9840          *
9841          * @param l the focus listener
9842          */
9843         public void removeFocusListener(FocusListener l) {
9844             Component.this.removeFocusListener(l);
9845         }
9846 
9847     } // inner class AccessibleAWTComponent
9848 
9849 
9850     /**
9851      * Gets the index of this object in its accessible parent.
9852      * If this object does not have an accessible parent, returns
9853      * -1.
9854      *
9855      * @return the index of this object in its accessible parent
9856      */
9857     int getAccessibleIndexInParent() {
9858         synchronized (getTreeLock()) {
9859 
9860             AccessibleContext accContext = getAccessibleContext();
9861             if (accContext == null) {
9862                 return -1;
9863             }
9864 
9865             Accessible parent = accContext.getAccessibleParent();
9866             if (parent == null) {
9867                 return -1;
9868             }
9869 
9870             accContext = parent.getAccessibleContext();
9871             for (int i = 0; i < accContext.getAccessibleChildrenCount(); i++) {
9872                 if (this.equals(accContext.getAccessibleChild(i))) {
9873                     return i;
9874                 }
9875             }
9876 
9877             return -1;
9878         }
9879     }
9880 
9881     /**
9882      * Gets the current state set of this object.
9883      *
9884      * @return an instance of {@code AccessibleStateSet}
9885      *    containing the current state set of the object
9886      * @see AccessibleState
9887      */
9888     AccessibleStateSet getAccessibleStateSet() {
9889         synchronized (getTreeLock()) {
9890             AccessibleStateSet states = new AccessibleStateSet();
9891             if (this.isEnabled()) {
9892                 states.add(AccessibleState.ENABLED);
9893             }
9894             if (this.isFocusTraversable()) {
9895                 states.add(AccessibleState.FOCUSABLE);
9896             }
9897             if (this.isVisible()) {
9898                 states.add(AccessibleState.VISIBLE);
9899             }
9900             if (this.isShowing()) {
9901                 states.add(AccessibleState.SHOWING);
9902             }
9903             if (this.isFocusOwner()) {
9904                 states.add(AccessibleState.FOCUSED);
9905             }
9906             if (this instanceof Accessible) {
9907                 AccessibleContext ac = ((Accessible) this).getAccessibleContext();
9908                 if (ac != null) {
9909                     Accessible ap = ac.getAccessibleParent();
9910                     if (ap != null) {
9911                         AccessibleContext pac = ap.getAccessibleContext();
9912                         if (pac != null) {
9913                             AccessibleSelection as = pac.getAccessibleSelection();
9914                             if (as != null) {
9915                                 states.add(AccessibleState.SELECTABLE);
9916                                 int i = ac.getAccessibleIndexInParent();
9917                                 if (i >= 0) {
9918                                     if (as.isAccessibleChildSelected(i)) {
9919                                         states.add(AccessibleState.SELECTED);
9920                                     }
9921                                 }
9922                             }
9923                         }
9924                     }
9925                 }
9926             }
9927             if (Component.isInstanceOf(this, "javax.swing.JComponent")) {
9928                 if (((javax.swing.JComponent) this).isOpaque()) {
9929                     states.add(AccessibleState.OPAQUE);
9930                 }
9931             }
9932             return states;
9933         }
9934     }
9935 
9936     /**
9937      * Checks that the given object is instance of the given class.
9938      * @param obj Object to be checked
9939      * @param className The name of the class. Must be fully-qualified class name.
9940      * @return true, if this object is instanceof given class,
9941      *         false, otherwise, or if obj or className is null
9942      */
9943     static boolean isInstanceOf(Object obj, String className) {
9944         if (obj == null) return false;
9945         if (className == null) return false;
9946 
9947         Class<?> cls = obj.getClass();
9948         while (cls != null) {
9949             if (cls.getName().equals(className)) {
9950                 return true;
9951             }
9952             cls = cls.getSuperclass();
9953         }
9954         return false;
9955     }
9956 
9957 
9958     // ************************** MIXING CODE *******************************
9959 
9960     /**
9961      * Check whether we can trust the current bounds of the component.
9962      * The return value of false indicates that the container of the
9963      * component is invalid, and therefore needs to be laid out, which would
9964      * probably mean changing the bounds of its children.
9965      * Null-layout of the container or absence of the container mean
9966      * the bounds of the component are final and can be trusted.
9967      */
9968     final boolean areBoundsValid() {
9969         Container cont = getContainer();
9970         return cont == null || cont.isValid() || cont.getLayout() == null;
9971     }
9972 
9973     /**
9974      * Applies the shape to the component
9975      * @param shape Shape to be applied to the component
9976      */
9977     void applyCompoundShape(Region shape) {
9978         checkTreeLock();
9979 
9980         if (!areBoundsValid()) {
9981             if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
9982                 mixingLog.fine("this = " + this + "; areBoundsValid = " + areBoundsValid());
9983             }
9984             return;
9985         }
9986 
9987         if (!isLightweight()) {
9988             ComponentPeer peer = this.peer;
9989             if (peer != null) {
9990                 // The Region class has some optimizations. That's why
9991                 // we should manually check whether it's empty and
9992                 // substitute the object ourselves. Otherwise we end up
9993                 // with some incorrect Region object with loX being
9994                 // greater than the hiX for instance.
9995                 if (shape.isEmpty()) {
9996                     shape = Region.EMPTY_REGION;
9997                 }
9998 
9999 
10000                 // Note: the shape is not really copied/cloned. We create
10001                 // the Region object ourselves, so there's no any possibility
10002                 // to modify the object outside of the mixing code.
10003                 // Nullifying compoundShape means that the component has normal shape
10004                 // (or has no shape at all).
10005                 if (shape.equals(getNormalShape())) {
10006                     if (this.compoundShape == null) {
10007                         return;
10008                     }
10009                     this.compoundShape = null;
10010                     peer.applyShape(null);
10011                 } else {
10012                     if (shape.equals(getAppliedShape())) {
10013                         return;
10014                     }
10015                     this.compoundShape = shape;
10016                     Point compAbsolute = getLocationOnWindow();
10017                     if (mixingLog.isLoggable(PlatformLogger.Level.FINER)) {
10018                         mixingLog.fine("this = " + this +
10019                                 "; compAbsolute=" + compAbsolute + "; shape=" + shape);
10020                     }
10021                     peer.applyShape(shape.getTranslatedRegion(-compAbsolute.x, -compAbsolute.y));
10022                 }
10023             }
10024         }
10025     }
10026 
10027     /**
10028      * Returns the shape previously set with applyCompoundShape().
10029      * If the component is LW or no shape was applied yet,
10030      * the method returns the normal shape.
10031      */
10032     private Region getAppliedShape() {
10033         checkTreeLock();
10034         //XXX: if we allow LW components to have a shape, this must be changed
10035         return (this.compoundShape == null || isLightweight()) ? getNormalShape() : this.compoundShape;
10036     }
10037 
10038     Point getLocationOnWindow() {
10039         checkTreeLock();
10040         Point curLocation = getLocation();
10041 
10042         for (Container parent = getContainer();
10043                 parent != null && !(parent instanceof Window);
10044                 parent = parent.getContainer())
10045         {
10046             curLocation.x += parent.getX();
10047             curLocation.y += parent.getY();
10048         }
10049 
10050         return curLocation;
10051     }
10052 
10053     /**
10054      * Returns the full shape of the component located in window coordinates
10055      */
10056     final Region getNormalShape() {
10057         checkTreeLock();
10058         //XXX: we may take into account a user-specified shape for this component
10059         Point compAbsolute = getLocationOnWindow();
10060         return
10061             Region.getInstanceXYWH(
10062                     compAbsolute.x,
10063                     compAbsolute.y,
10064                     getWidth(),
10065                     getHeight()
10066             );
10067     }
10068 
10069     /**
10070      * Returns the "opaque shape" of the component.
10071      *
10072      * The opaque shape of a lightweight components is the actual shape that
10073      * needs to be cut off of the heavyweight components in order to mix this
10074      * lightweight component correctly with them.
10075      *
10076      * The method is overriden in the java.awt.Container to handle non-opaque
10077      * containers containing opaque children.
10078      *
10079      * See 6637655 for details.
10080      */
10081     Region getOpaqueShape() {
10082         checkTreeLock();
10083         if (mixingCutoutRegion != null) {
10084             return mixingCutoutRegion;
10085         } else {
10086             return getNormalShape();
10087         }
10088     }
10089 
10090     final int getSiblingIndexAbove() {
10091         checkTreeLock();
10092         Container parent = getContainer();
10093         if (parent == null) {
10094             return -1;
10095         }
10096 
10097         int nextAbove = parent.getComponentZOrder(this) - 1;
10098 
10099         return nextAbove < 0 ? -1 : nextAbove;
10100     }
10101 
10102     final ComponentPeer getHWPeerAboveMe() {
10103         checkTreeLock();
10104 
10105         Container cont = getContainer();
10106         int indexAbove = getSiblingIndexAbove();
10107 
10108         while (cont != null) {
10109             for (int i = indexAbove; i > -1; i--) {
10110                 Component comp = cont.getComponent(i);
10111                 if (comp != null && comp.isDisplayable() && !comp.isLightweight()) {
10112                     return comp.peer;
10113                 }
10114             }
10115             // traversing the hierarchy up to the closest HW container;
10116             // further traversing may return a component that is not actually
10117             // a native sibling of this component and this kind of z-order
10118             // request may not be allowed by the underlying system (6852051).
10119             if (!cont.isLightweight()) {
10120                 break;
10121             }
10122 
10123             indexAbove = cont.getSiblingIndexAbove();
10124             cont = cont.getContainer();
10125         }
10126 
10127         return null;
10128     }
10129 
10130     final int getSiblingIndexBelow() {
10131         checkTreeLock();
10132         Container parent = getContainer();
10133         if (parent == null) {
10134             return -1;
10135         }
10136 
10137         int nextBelow = parent.getComponentZOrder(this) + 1;
10138 
10139         return nextBelow >= parent.getComponentCount() ? -1 : nextBelow;
10140     }
10141 
10142     final boolean isNonOpaqueForMixing() {
10143         return mixingCutoutRegion != null &&
10144             mixingCutoutRegion.isEmpty();
10145     }
10146 
10147     private Region calculateCurrentShape() {
10148         checkTreeLock();
10149         Region s = getNormalShape();
10150 
10151         if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
10152             mixingLog.fine("this = " + this + "; normalShape=" + s);
10153         }
10154 
10155         if (getContainer() != null) {
10156             Component comp = this;
10157             Container cont = comp.getContainer();
10158 
10159             while (cont != null) {
10160                 for (int index = comp.getSiblingIndexAbove(); index != -1; --index) {
10161                     /* It is assumed that:
10162                      *
10163                      *    getComponent(getContainer().getComponentZOrder(comp)) == comp
10164                      *
10165                      * The assumption has been made according to the current
10166                      * implementation of the Container class.
10167                      */
10168                     Component c = cont.getComponent(index);
10169                     if (c.isLightweight() && c.isShowing()) {
10170                         s = s.getDifference(c.getOpaqueShape());
10171                     }
10172                 }
10173 
10174                 if (cont.isLightweight()) {
10175                     s = s.getIntersection(cont.getNormalShape());
10176                 } else {
10177                     break;
10178                 }
10179 
10180                 comp = cont;
10181                 cont = cont.getContainer();
10182             }
10183         }
10184 
10185         if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
10186             mixingLog.fine("currentShape=" + s);
10187         }
10188 
10189         return s;
10190     }
10191 
10192     void applyCurrentShape() {
10193         checkTreeLock();
10194         if (!areBoundsValid()) {
10195             if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
10196                 mixingLog.fine("this = " + this + "; areBoundsValid = " + areBoundsValid());
10197             }
10198             return; // Because applyCompoundShape() ignores such components anyway
10199         }
10200         if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
10201             mixingLog.fine("this = " + this);
10202         }
10203         applyCompoundShape(calculateCurrentShape());
10204     }
10205 
10206     final void subtractAndApplyShape(Region s) {
10207         checkTreeLock();
10208 
10209         if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
10210             mixingLog.fine("this = " + this + "; s=" + s);
10211         }
10212 
10213         applyCompoundShape(getAppliedShape().getDifference(s));
10214     }
10215 
10216     private final void applyCurrentShapeBelowMe() {
10217         checkTreeLock();
10218         Container parent = getContainer();
10219         if (parent != null && parent.isShowing()) {
10220             // First, reapply shapes of my siblings
10221             parent.recursiveApplyCurrentShape(getSiblingIndexBelow());
10222 
10223             // Second, if my container is non-opaque, reapply shapes of siblings of my container
10224             Container parent2 = parent.getContainer();
10225             while (!parent.isOpaque() && parent2 != null) {
10226                 parent2.recursiveApplyCurrentShape(parent.getSiblingIndexBelow());
10227 
10228                 parent = parent2;
10229                 parent2 = parent.getContainer();
10230             }
10231         }
10232     }
10233 
10234     final void subtractAndApplyShapeBelowMe() {
10235         checkTreeLock();
10236         Container parent = getContainer();
10237         if (parent != null && isShowing()) {
10238             Region opaqueShape = getOpaqueShape();
10239 
10240             // First, cut my siblings
10241             parent.recursiveSubtractAndApplyShape(opaqueShape, getSiblingIndexBelow());
10242 
10243             // Second, if my container is non-opaque, cut siblings of my container
10244             Container parent2 = parent.getContainer();
10245             while (!parent.isOpaque() && parent2 != null) {
10246                 parent2.recursiveSubtractAndApplyShape(opaqueShape, parent.getSiblingIndexBelow());
10247 
10248                 parent = parent2;
10249                 parent2 = parent.getContainer();
10250             }
10251         }
10252     }
10253 
10254     void mixOnShowing() {
10255         synchronized (getTreeLock()) {
10256             if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
10257                 mixingLog.fine("this = " + this);
10258             }
10259             if (!isMixingNeeded()) {
10260                 return;
10261             }
10262             if (isLightweight()) {
10263                 subtractAndApplyShapeBelowMe();
10264             } else {
10265                 applyCurrentShape();
10266             }
10267         }
10268     }
10269 
10270     void mixOnHiding(boolean isLightweight) {
10271         // We cannot be sure that the peer exists at this point, so we need the argument
10272         //    to find out whether the hiding component is (well, actually was) a LW or a HW.
10273         synchronized (getTreeLock()) {
10274             if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
10275                 mixingLog.fine("this = " + this + "; isLightweight = " + isLightweight);
10276             }
10277             if (!isMixingNeeded()) {
10278                 return;
10279             }
10280             if (isLightweight) {
10281                 applyCurrentShapeBelowMe();
10282             }
10283         }
10284     }
10285 
10286     void mixOnReshaping() {
10287         synchronized (getTreeLock()) {
10288             if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
10289                 mixingLog.fine("this = " + this);
10290             }
10291             if (!isMixingNeeded()) {
10292                 return;
10293             }
10294             if (isLightweight()) {
10295                 applyCurrentShapeBelowMe();
10296             } else {
10297                 applyCurrentShape();
10298             }
10299         }
10300     }
10301 
10302     void mixOnZOrderChanging(int oldZorder, int newZorder) {
10303         synchronized (getTreeLock()) {
10304             boolean becameHigher = newZorder < oldZorder;
10305             Container parent = getContainer();
10306 
10307             if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
10308                 mixingLog.fine("this = " + this +
10309                     "; oldZorder=" + oldZorder + "; newZorder=" + newZorder + "; parent=" + parent);
10310             }
10311             if (!isMixingNeeded()) {
10312                 return;
10313             }
10314             if (isLightweight()) {
10315                 if (becameHigher) {
10316                     if (parent != null && isShowing()) {
10317                         parent.recursiveSubtractAndApplyShape(getOpaqueShape(), getSiblingIndexBelow(), oldZorder);
10318                     }
10319                 } else {
10320                     if (parent != null) {
10321                         parent.recursiveApplyCurrentShape(oldZorder, newZorder);
10322                     }
10323                 }
10324             } else {
10325                 if (becameHigher) {
10326                     applyCurrentShape();
10327                 } else {
10328                     if (parent != null) {
10329                         Region shape = getAppliedShape();
10330 
10331                         for (int index = oldZorder; index < newZorder; index++) {
10332                             Component c = parent.getComponent(index);
10333                             if (c.isLightweight() && c.isShowing()) {
10334                                 shape = shape.getDifference(c.getOpaqueShape());
10335                             }
10336                         }
10337                         applyCompoundShape(shape);
10338                     }
10339                 }
10340             }
10341         }
10342     }
10343 
10344     void mixOnValidating() {
10345         // This method gets overriden in the Container. Obviously, a plain
10346         // non-container components don't need to handle validation.
10347     }
10348 
10349     final boolean isMixingNeeded() {
10350         if (SunToolkit.getSunAwtDisableMixing()) {
10351             if (mixingLog.isLoggable(PlatformLogger.Level.FINEST)) {
10352                 mixingLog.finest("this = " + this + "; Mixing disabled via sun.awt.disableMixing");
10353             }
10354             return false;
10355         }
10356         if (!areBoundsValid()) {
10357             if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
10358                 mixingLog.fine("this = " + this + "; areBoundsValid = " + areBoundsValid());
10359             }
10360             return false;
10361         }
10362         Window window = getContainingWindow();
10363         if (window != null) {
10364             if (!window.hasHeavyweightDescendants() || !window.hasLightweightDescendants() || window.isDisposing()) {
10365                 if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
10366                     mixingLog.fine("containing window = " + window +
10367                             "; has h/w descendants = " + window.hasHeavyweightDescendants() +
10368                             "; has l/w descendants = " + window.hasLightweightDescendants() +
10369                             "; disposing = " + window.isDisposing());
10370                 }
10371                 return false;
10372             }
10373         } else {
10374             if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
10375                 mixingLog.fine("this = " + this + "; containing window is null");
10376             }
10377             return false;
10378         }
10379         return true;
10380     }
10381 
10382     /**
10383      * Sets a 'mixing-cutout' shape for this lightweight component.
10384      *
10385      * This method is used exclusively for the purposes of the
10386      * Heavyweight/Lightweight Components Mixing feature and will
10387      * have no effect if applied to a heavyweight component.
10388      *
10389      * By default a lightweight component is treated as an opaque rectangle for
10390      * the purposes of the Heavyweight/Lightweight Components Mixing feature.
10391      * This method enables developers to set an arbitrary shape to be cut out
10392      * from heavyweight components positioned underneath the lightweight
10393      * component in the z-order.
10394      * <p>
10395      * The {@code shape} argument may have the following values:
10396      * <ul>
10397      * <li>{@code null} - reverts the default cutout shape (the rectangle equal
10398      * to the component's {@code getBounds()})
10399      * <li><i>empty-shape</i> - does not cut out anything from heavyweight
10400      * components. This makes this lightweight component effectively
10401      * transparent. Note that descendants of the lightweight component still
10402      * affect the shapes of heavyweight components.  An example of an
10403      * <i>empty-shape</i> is {@code new Rectangle()}.
10404      * <li><i>non-empty-shape</i> - the given shape will be cut out from
10405      * heavyweight components.
10406      * </ul>
10407      * <p>
10408      * The most common example when the 'mixing-cutout' shape is needed is a
10409      * glass pane component. The {@link JRootPane#setGlassPane()} method
10410      * automatically sets the <i>empty-shape</i> as the 'mixing-cutout' shape
10411      * for the given glass pane component.  If a developer needs some other
10412      * 'mixing-cutout' shape for the glass pane (which is rare), this must be
10413      * changed manually after installing the glass pane to the root pane.
10414      *
10415      * @param shape the new 'mixing-cutout' shape
10416      * @since 9
10417      */
10418     public void setMixingCutoutShape(Shape shape) {
10419         Region region = shape == null ? null : Region.getInstance(shape, null);
10420 
10421         synchronized (getTreeLock()) {
10422             boolean needShowing = false;
10423             boolean needHiding = false;
10424 
10425             if (!isNonOpaqueForMixing()) {
10426                 needHiding = true;
10427             }
10428 
10429             mixingCutoutRegion = region;
10430 
10431             if (!isNonOpaqueForMixing()) {
10432                 needShowing = true;
10433             }
10434 
10435             if (isMixingNeeded()) {
10436                 if (needHiding) {
10437                     mixOnHiding(isLightweight());
10438                 }
10439                 if (needShowing) {
10440                     mixOnShowing();
10441                 }
10442             }
10443         }
10444     }
10445 
10446     // ****************** END OF MIXING CODE ********************************
10447 
10448     // Note that the method is overriden in the Window class,
10449     // a window doesn't need to be updated in the Z-order.
10450     void updateZOrder() {
10451         peer.setZOrder(getHWPeerAboveMe());
10452     }
10453 
10454 }