Source Code Cross Referenced for Component.java in  » 6.0-JDK-Core » AWT » java » awt » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » AWT » java.awt 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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