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