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