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