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