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