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

Save This Page
Home » openjdk-7 » java » awt » [javadoc | source]