1 /*
2  * Copyright (c) 1997, 2013, 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 javax.swing;
26 
27 
28 import java.util.HashSet;
29 import java.util.Hashtable;
30 import java.util.Dictionary;
31 import java.util.Enumeration;
32 import java.util.Locale;
33 import java.util.Vector;
34 import java.util.EventListener;
35 import java.util.Set;
36 import java.util.Map;
37 import java.util.HashMap;
38 
39 import java.awt.*;
40 import java.awt.event.*;
41 import java.awt.image.VolatileImage;
42 import java.awt.Graphics2D;
43 import java.awt.peer.LightweightPeer;
44 import java.awt.dnd.DropTarget;
45 import java.awt.font.FontRenderContext;
46 import java.beans.PropertyChangeListener;
47 import java.beans.VetoableChangeListener;
48 import java.beans.VetoableChangeSupport;
49 import java.beans.Transient;
50 
51 import java.applet.Applet;
52 
53 import java.io.Serializable;
54 import java.io.ObjectOutputStream;
55 import java.io.ObjectInputStream;
56 import java.io.IOException;
57 import java.io.ObjectInputValidation;
58 import java.io.InvalidObjectException;
59 import java.util.concurrent.atomic.AtomicBoolean;
60 
61 import javax.swing.border.*;
62 import javax.swing.event.*;
63 import javax.swing.plaf.*;
64 import static javax.swing.ClientPropertyKey.*;
65 import javax.accessibility.*;
66 
67 import sun.awt.SunToolkit;
68 import sun.swing.SwingUtilities2;
69 import sun.swing.UIClientPropertyKey;
70 
71 /**
72  * The base class for all Swing components except top-level containers.
73  * To use a component that inherits from <code>JComponent</code>,
74  * you must place the component in a containment hierarchy
75  * whose root is a top-level Swing container.
76  * Top-level Swing containers --
77  * such as <code>JFrame</code>, <code>JDialog</code>,
78  * and <code>JApplet</code> --
79  * are specialized components
80  * that provide a place for other Swing components to paint themselves.
81  * For an explanation of containment hierarchies, see
82  * <a
83  href="https://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html">Swing Components and the Containment Hierarchy</a>,
84  * a section in <em>The Java Tutorial</em>.
85  *
86  * <p>
87  * The <code>JComponent</code> class provides:
88  * <ul>
89  * <li>The base class for both standard and custom components
90  *     that use the Swing architecture.
91  * <li>A "pluggable look and feel" (L&amp;F) that can be specified by the
92  *     programmer or (optionally) selected by the user at runtime.
93  *     The look and feel for each component is provided by a
94  *     <em>UI delegate</em> -- an object that descends from
95  *     {@link javax.swing.plaf.ComponentUI}.
96  *     See <a
97  * href="https://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html">How
98  *     to Set the Look and Feel</a>
99  *     in <em>The Java Tutorial</em>
100  *     for more information.
101  * <li>Comprehensive keystroke handling.
102  *     See the document <a
103  * href="https://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html">How to Use Key Bindings</a>,
104  *     an article in <em>The Java Tutorial</em>,
105  *     for more information.
106  * <li>Support for tool tips --
107  *     short descriptions that pop up when the cursor lingers
108  *     over a component.
109  *     See <a
110  * href="https://docs.oracle.com/javase/tutorial/uiswing/components/tooltip.html">How
111  *     to Use Tool Tips</a>
112  *     in <em>The Java Tutorial</em>
113  *     for more information.
114  * <li>Support for accessibility.
115  *     <code>JComponent</code> contains all of the methods in the
116  *     <code>Accessible</code> interface,
117  *     but it doesn't actually implement the interface.  That is the
118  *     responsibility of the individual classes
119  *     that extend <code>JComponent</code>.
120  * <li>Support for component-specific properties.
121  *     With the {@link #putClientProperty}
122  *     and {@link #getClientProperty} methods,
123  *     you can associate name-object pairs
124  *     with any object that descends from <code>JComponent</code>.
125  * <li>An infrastructure for painting
126  *     that includes double buffering and support for borders.
127  *     For more information see <a
128  * href="http://www.oracle.com/technetwork/java/painting-140037.html#swing">Painting</a> and
129  * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/border.htmll">How
130  *     to Use Borders</a>,
131  *     both of which are sections in <em>The Java Tutorial</em>.
132  * </ul>
133  * For more information on these subjects, see the
134  * <a href="package-summary.html#package_description">Swing package description</a>
135  * and <em>The Java Tutorial</em> section
136  * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/jcomponent.html">The JComponent Class</a>.
137  * <p>
138  * <code>JComponent</code> and its subclasses document default values
139  * for certain properties.  For example, <code>JTable</code> documents the
140  * default row height as 16.  Each <code>JComponent</code> subclass
141  * that has a <code>ComponentUI</code> will create the
142  * <code>ComponentUI</code> as part of its constructor.  In order
143  * to provide a particular look and feel each
144  * <code>ComponentUI</code> may set properties back on the
145  * <code>JComponent</code> that created it.  For example, a custom
146  * look and feel may require <code>JTable</code>s to have a row
147  * height of 24. The documented defaults are the value of a property
148  * BEFORE the <code>ComponentUI</code> has been installed.  If you
149  * need a specific value for a particular property you should
150  * explicitly set it.
151  * <p>
152  * In release 1.4, the focus subsystem was rearchitected.
153  * For more information, see
154  * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
155  * How to Use the Focus Subsystem</a>,
156  * a section in <em>The Java Tutorial</em>.
157  * <p>
158  * <strong>Warning:</strong> Swing is not thread safe. For more
159  * information see <a
160  * href="package-summary.html#threading">Swing's Threading
161  * Policy</a>.
162  * <p>
163  * <strong>Warning:</strong>
164  * Serialized objects of this class will not be compatible with
165  * future Swing releases. The current serialization support is
166  * appropriate for short term storage or RMI between applications running
167  * the same version of Swing.  As of 1.4, support for long term storage
168  * of all JavaBeans&trade;
169  * has been added to the <code>java.beans</code> package.
170  * Please see {@link java.beans.XMLEncoder}.
171  *
172  * @see KeyStroke
173  * @see Action
174  * @see #setBorder
175  * @see #registerKeyboardAction
176  * @see JOptionPane
177  * @see #setDebugGraphicsOptions
178  * @see #setToolTipText
179  * @see #setAutoscrolls
180  *
181  * @author Hans Muller
182  * @author Arnaud Weber
183  */
184 public abstract class JComponent extends Container implements Serializable,
185                                               TransferHandler.HasGetTransferHandler
186 {
187     /**
188      * @see #getUIClassID
189      * @see #writeObject
190      */
191     private static final String uiClassID = "ComponentUI";
192 
193     /**
194      * @see #readObject
195      */
196     private static final Hashtable<ObjectInputStream, ReadObjectCallback> readObjectCallbacks =
197             new Hashtable<ObjectInputStream, ReadObjectCallback>(1);
198 
199     /**
200      * Keys to use for forward focus traversal when the JComponent is
201      * managing focus.
202      */
203     private static Set<KeyStroke> managingFocusForwardTraversalKeys;
204 
205     /**
206      * Keys to use for backward focus traversal when the JComponent is
207      * managing focus.
208      */
209     private static Set<KeyStroke> managingFocusBackwardTraversalKeys;
210 
211     // Following are the possible return values from getObscuredState.
212     private static final int NOT_OBSCURED = 0;
213     private static final int PARTIALLY_OBSCURED = 1;
214     private static final int COMPLETELY_OBSCURED = 2;
215 
216     /**
217      * Set to true when DebugGraphics has been loaded.
218      */
219     static boolean DEBUG_GRAPHICS_LOADED;
220 
221     /**
222      * Key used to look up a value from the AppContext to determine the
223      * JComponent the InputVerifier is running for. That is, if
224      * AppContext.get(INPUT_VERIFIER_SOURCE_KEY) returns non-null, it
225      * indicates the EDT is calling into the InputVerifier from the
226      * returned component.
227      */
228     private static final Object INPUT_VERIFIER_SOURCE_KEY =
229             new StringBuilder("InputVerifierSourceKey");
230 
231     /* The following fields support set methods for the corresponding
232      * java.awt.Component properties.
233      */
234     private boolean isAlignmentXSet;
235     private float alignmentX;
236     private boolean isAlignmentYSet;
237     private float alignmentY;
238 
239     /**
240      * Backing store for JComponent properties and listeners
241      */
242 
243     /** The look and feel delegate for this component. */
244     protected transient ComponentUI ui;
245     /** A list of event listeners for this component. */
246     protected EventListenerList listenerList = new EventListenerList();
247 
248     private transient ArrayTable clientProperties;
249     private VetoableChangeSupport vetoableChangeSupport;
250     /**
251      * Whether or not autoscroll has been enabled.
252      */
253     private boolean autoscrolls;
254     private Border border;
255     private int flags;
256 
257     /* Input verifier for this component */
258     private InputVerifier inputVerifier = null;
259 
260     private boolean verifyInputWhenFocusTarget = true;
261 
262     /**
263      * Set in <code>_paintImmediately</code>.
264      * Will indicate the child that initiated the painting operation.
265      * If <code>paintingChild</code> is opaque, no need to paint
266      * any child components after <code>paintingChild</code>.
267      * Test used in <code>paintChildren</code>.
268      */
269     transient Component         paintingChild;
270 
271     /**
272      * Constant used for <code>registerKeyboardAction</code> that
273      * means that the command should be invoked when
274      * the component has the focus.
275      */
276     public static final int WHEN_FOCUSED = 0;
277 
278     /**
279      * Constant used for <code>registerKeyboardAction</code> that
280      * means that the command should be invoked when the receiving
281      * component is an ancestor of the focused component or is
282      * itself the focused component.
283      */
284     public static final int WHEN_ANCESTOR_OF_FOCUSED_COMPONENT = 1;
285 
286     /**
287      * Constant used for <code>registerKeyboardAction</code> that
288      * means that the command should be invoked when
289      * the receiving component is in the window that has the focus
290      * or is itself the focused component.
291      */
292     public static final int WHEN_IN_FOCUSED_WINDOW = 2;
293 
294     /**
295      * Constant used by some of the APIs to mean that no condition is defined.
296      */
297     public static final int UNDEFINED_CONDITION = -1;
298 
299     /**
300      * The key used by <code>JComponent</code> to access keyboard bindings.
301      */
302     private static final String KEYBOARD_BINDINGS_KEY = "_KeyboardBindings";
303 
304     /**
305      * An array of <code>KeyStroke</code>s used for
306      * <code>WHEN_IN_FOCUSED_WINDOW</code> are stashed
307      * in the client properties under this string.
308      */
309     private static final String WHEN_IN_FOCUSED_WINDOW_BINDINGS = "_WhenInFocusedWindow";
310 
311     /**
312      * The comment to display when the cursor is over the component,
313      * also known as a "value tip", "flyover help", or "flyover label".
314      */
315     public static final String TOOL_TIP_TEXT_KEY = "ToolTipText";
316 
317     private static final String NEXT_FOCUS = "nextFocus";
318 
319     /**
320      * <code>JPopupMenu</code> assigned to this component
321      * and all of its children
322      */
323     private JPopupMenu popupMenu;
324 
325     /** Private flags **/
326     private static final int IS_DOUBLE_BUFFERED                       =  0;
327     private static final int ANCESTOR_USING_BUFFER                    =  1;
328     private static final int IS_PAINTING_TILE                         =  2;
329     private static final int IS_OPAQUE                                =  3;
330     private static final int KEY_EVENTS_ENABLED                       =  4;
331     private static final int FOCUS_INPUTMAP_CREATED                   =  5;
332     private static final int ANCESTOR_INPUTMAP_CREATED                =  6;
333     private static final int WIF_INPUTMAP_CREATED                     =  7;
334     private static final int ACTIONMAP_CREATED                        =  8;
335     private static final int CREATED_DOUBLE_BUFFER                    =  9;
336     // bit 10 is free
337     private static final int IS_PRINTING                              = 11;
338     private static final int IS_PRINTING_ALL                          = 12;
339     private static final int IS_REPAINTING                            = 13;
340     /** Bits 14-21 are used to handle nested writeObject calls. **/
341     private static final int WRITE_OBJ_COUNTER_FIRST                  = 14;
342     private static final int RESERVED_1                               = 15;
343     private static final int RESERVED_2                               = 16;
344     private static final int RESERVED_3                               = 17;
345     private static final int RESERVED_4                               = 18;
346     private static final int RESERVED_5                               = 19;
347     private static final int RESERVED_6                               = 20;
348     private static final int WRITE_OBJ_COUNTER_LAST                   = 21;
349 
350     private static final int REQUEST_FOCUS_DISABLED                   = 22;
351     private static final int INHERITS_POPUP_MENU                      = 23;
352     private static final int OPAQUE_SET                               = 24;
353     private static final int AUTOSCROLLS_SET                          = 25;
354     private static final int FOCUS_TRAVERSAL_KEYS_FORWARD_SET         = 26;
355     private static final int FOCUS_TRAVERSAL_KEYS_BACKWARD_SET        = 27;
356 
357     private transient AtomicBoolean revalidateRunnableScheduled = new AtomicBoolean(false);
358 
359     /**
360      * Temporary rectangles.
361      */
362     private static java.util.List<Rectangle> tempRectangles = new java.util.ArrayList<Rectangle>(11);
363 
364     /** Used for <code>WHEN_FOCUSED</code> bindings. */
365     private InputMap focusInputMap;
366     /** Used for <code>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT</code> bindings. */
367     private InputMap ancestorInputMap;
368     /** Used for <code>WHEN_IN_FOCUSED_KEY</code> bindings. */
369     private ComponentInputMap windowInputMap;
370 
371     /** ActionMap. */
372     private ActionMap actionMap;
373 
374     /** Key used to store the default locale in an AppContext **/
375     private static final String defaultLocale = "JComponent.defaultLocale";
376 
377     private static Component componentObtainingGraphicsFrom;
378     private static Object componentObtainingGraphicsFromLock = new
379             StringBuilder("componentObtainingGraphicsFrom");
380 
381     /**
382      * AA text hints.
383      */
384     transient private Object aaTextInfo;
385 
safelyGetGraphics(Component c)386     static Graphics safelyGetGraphics(Component c) {
387         return safelyGetGraphics(c, SwingUtilities.getRoot(c));
388     }
389 
safelyGetGraphics(Component c, Component root)390     static Graphics safelyGetGraphics(Component c, Component root) {
391         synchronized(componentObtainingGraphicsFromLock) {
392             componentObtainingGraphicsFrom = root;
393             Graphics g = c.getGraphics();
394             componentObtainingGraphicsFrom = null;
395             return g;
396         }
397     }
398 
getGraphicsInvoked(Component root)399     static void getGraphicsInvoked(Component root) {
400         if (!JComponent.isComponentObtainingGraphicsFrom(root)) {
401             JRootPane rootPane = ((RootPaneContainer)root).getRootPane();
402             if (rootPane != null) {
403                 rootPane.disableTrueDoubleBuffering();
404             }
405         }
406     }
407 
408 
409     /**
410      * Returns true if {@code c} is the component the graphics is being
411      * requested of. This is intended for use when getGraphics is invoked.
412      */
isComponentObtainingGraphicsFrom(Component c)413     private static boolean isComponentObtainingGraphicsFrom(Component c) {
414         synchronized(componentObtainingGraphicsFromLock) {
415             return (componentObtainingGraphicsFrom == c);
416         }
417     }
418 
419     /**
420      * Returns the Set of <code>KeyStroke</code>s to use if the component
421      * is managing focus for forward focus traversal.
422      */
getManagingFocusForwardTraversalKeys()423     static Set<KeyStroke> getManagingFocusForwardTraversalKeys() {
424         synchronized(JComponent.class) {
425             if (managingFocusForwardTraversalKeys == null) {
426                 managingFocusForwardTraversalKeys = new HashSet<KeyStroke>(1);
427                 managingFocusForwardTraversalKeys.add(
428                     KeyStroke.getKeyStroke(KeyEvent.VK_TAB,
429                                            InputEvent.CTRL_MASK));
430             }
431         }
432         return managingFocusForwardTraversalKeys;
433     }
434 
435     /**
436      * Returns the Set of <code>KeyStroke</code>s to use if the component
437      * is managing focus for backward focus traversal.
438      */
getManagingFocusBackwardTraversalKeys()439     static Set<KeyStroke> getManagingFocusBackwardTraversalKeys() {
440         synchronized(JComponent.class) {
441             if (managingFocusBackwardTraversalKeys == null) {
442                 managingFocusBackwardTraversalKeys = new HashSet<KeyStroke>(1);
443                 managingFocusBackwardTraversalKeys.add(
444                     KeyStroke.getKeyStroke(KeyEvent.VK_TAB,
445                                            InputEvent.SHIFT_MASK |
446                                            InputEvent.CTRL_MASK));
447             }
448         }
449         return managingFocusBackwardTraversalKeys;
450     }
451 
fetchRectangle()452     private static Rectangle fetchRectangle() {
453         synchronized(tempRectangles) {
454             Rectangle rect;
455             int size = tempRectangles.size();
456             if (size > 0) {
457                 rect = tempRectangles.remove(size - 1);
458             }
459             else {
460                 rect = new Rectangle(0, 0, 0, 0);
461             }
462             return rect;
463         }
464     }
465 
recycleRectangle(Rectangle rect)466     private static void recycleRectangle(Rectangle rect) {
467         synchronized(tempRectangles) {
468             tempRectangles.add(rect);
469         }
470     }
471 
472     /**
473      * Sets whether or not <code>getComponentPopupMenu</code> should delegate
474      * to the parent if this component does not have a <code>JPopupMenu</code>
475      * assigned to it.
476      * <p>
477      * The default value for this is false, but some <code>JComponent</code>
478      * subclasses that are implemented as a number of <code>JComponent</code>s
479      * may set this to true.
480      * <p>
481      * This is a bound property.
482      *
483      * @param value whether or not the JPopupMenu is inherited
484      * @see #setComponentPopupMenu
485      * @beaninfo
486      *        bound: true
487      *  description: Whether or not the JPopupMenu is inherited
488      * @since 1.5
489      */
setInheritsPopupMenu(boolean value)490     public void setInheritsPopupMenu(boolean value) {
491         boolean oldValue = getFlag(INHERITS_POPUP_MENU);
492         setFlag(INHERITS_POPUP_MENU, value);
493         firePropertyChange("inheritsPopupMenu", oldValue, value);
494     }
495 
496     /**
497      * Returns true if the JPopupMenu should be inherited from the parent.
498      *
499      * @see #setComponentPopupMenu
500      * @since 1.5
501      */
getInheritsPopupMenu()502     public boolean getInheritsPopupMenu() {
503         return getFlag(INHERITS_POPUP_MENU);
504     }
505 
506     /**
507      * Sets the <code>JPopupMenu</code> for this <code>JComponent</code>.
508      * The UI is responsible for registering bindings and adding the necessary
509      * listeners such that the <code>JPopupMenu</code> will be shown at
510      * the appropriate time. When the <code>JPopupMenu</code> is shown
511      * depends upon the look and feel: some may show it on a mouse event,
512      * some may enable a key binding.
513      * <p>
514      * If <code>popup</code> is null, and <code>getInheritsPopupMenu</code>
515      * returns true, then <code>getComponentPopupMenu</code> will be delegated
516      * to the parent. This provides for a way to make all child components
517      * inherit the popupmenu of the parent.
518      * <p>
519      * This is a bound property.
520      *
521      * @param popup - the popup that will be assigned to this component
522      *                may be null
523      * @see #getComponentPopupMenu
524      * @beaninfo
525      *        bound: true
526      *    preferred: true
527      *  description: Popup to show
528      * @since 1.5
529      */
setComponentPopupMenu(JPopupMenu popup)530     public void setComponentPopupMenu(JPopupMenu popup) {
531         if(popup != null) {
532             enableEvents(AWTEvent.MOUSE_EVENT_MASK);
533         }
534         JPopupMenu oldPopup = this.popupMenu;
535         this.popupMenu = popup;
536         firePropertyChange("componentPopupMenu", oldPopup, popup);
537     }
538 
539     /**
540      * Returns <code>JPopupMenu</code> that assigned for this component.
541      * If this component does not have a <code>JPopupMenu</code> assigned
542      * to it and <code>getInheritsPopupMenu</code> is true, this
543      * will return <code>getParent().getComponentPopupMenu()</code> (assuming
544      * the parent is valid.)
545      *
546      * @return <code>JPopupMenu</code> assigned for this component
547      *         or <code>null</code> if no popup assigned
548      * @see #setComponentPopupMenu
549      * @since 1.5
550      */
getComponentPopupMenu()551     public JPopupMenu getComponentPopupMenu() {
552 
553         if(!getInheritsPopupMenu()) {
554             return popupMenu;
555         }
556 
557         if(popupMenu == null) {
558             // Search parents for its popup
559             Container parent = getParent();
560             while (parent != null) {
561                 if(parent instanceof JComponent) {
562                     return ((JComponent)parent).getComponentPopupMenu();
563                 }
564                 if(parent instanceof Window ||
565                    parent instanceof Applet) {
566                     // Reached toplevel, break and return null
567                     break;
568                 }
569                 parent = parent.getParent();
570             }
571             return null;
572         }
573 
574         return popupMenu;
575     }
576 
577     /**
578      * Default <code>JComponent</code> constructor.  This constructor does
579      * very little initialization beyond calling the <code>Container</code>
580      * constructor.  For example, the initial layout manager is
581      * <code>null</code>. It does, however, set the component's locale
582      * property to the value returned by
583      * <code>JComponent.getDefaultLocale</code>.
584      *
585      * @see #getDefaultLocale
586      */
JComponent()587     public JComponent() {
588         super();
589         // We enable key events on all JComponents so that accessibility
590         // bindings will work everywhere. This is a partial fix to BugID
591         // 4282211.
592         enableEvents(AWTEvent.KEY_EVENT_MASK);
593         if (isManagingFocus()) {
594             LookAndFeel.installProperty(this,
595                                         "focusTraversalKeysForward",
596                                   getManagingFocusForwardTraversalKeys());
597             LookAndFeel.installProperty(this,
598                                         "focusTraversalKeysBackward",
599                                   getManagingFocusBackwardTraversalKeys());
600         }
601 
602         super.setLocale( JComponent.getDefaultLocale() );
603     }
604 
605 
606     /**
607      * Resets the UI property to a value from the current look and feel.
608      * <code>JComponent</code> subclasses must override this method
609      * like this:
610      * <pre>
611      *   public void updateUI() {
612      *      setUI((SliderUI)UIManager.getUI(this);
613      *   }
614      *  </pre>
615      *
616      * @see #setUI
617      * @see UIManager#getLookAndFeel
618      * @see UIManager#getUI
619      */
updateUI()620     public void updateUI() {}
621 
622 
623     /**
624      * Sets the look and feel delegate for this component.
625      * <code>JComponent</code> subclasses generally override this method
626      * to narrow the argument type. For example, in <code>JSlider</code>:
627      * <pre>
628      * public void setUI(SliderUI newUI) {
629      *     super.setUI(newUI);
630      * }
631      *  </pre>
632      * <p>
633      * Additionally <code>JComponent</code> subclasses must provide a
634      * <code>getUI</code> method that returns the correct type.  For example:
635      * <pre>
636      * public SliderUI getUI() {
637      *     return (SliderUI)ui;
638      * }
639      * </pre>
640      *
641      * @param newUI the new UI delegate
642      * @see #updateUI
643      * @see UIManager#getLookAndFeel
644      * @see UIManager#getUI
645      * @beaninfo
646      *        bound: true
647      *       hidden: true
648      *    attribute: visualUpdate true
649      *  description: The component's look and feel delegate.
650      */
setUI(ComponentUI newUI)651     protected void setUI(ComponentUI newUI) {
652         /* We do not check that the UI instance is different
653          * before allowing the switch in order to enable the
654          * same UI instance *with different default settings*
655          * to be installed.
656          */
657 
658         uninstallUIAndProperties();
659 
660         // aaText shouldn't persist between look and feels, reset it.
661         aaTextInfo =
662             UIManager.getDefaults().get(SwingUtilities2.AA_TEXT_PROPERTY_KEY);
663         ComponentUI oldUI = ui;
664         ui = newUI;
665         if (ui != null) {
666             ui.installUI(this);
667         }
668 
669         firePropertyChange("UI", oldUI, newUI);
670         revalidate();
671         repaint();
672     }
673 
674     /**
675      * Uninstalls the UI, if any, and any client properties designated
676      * as being specific to the installed UI - instances of
677      * {@code UIClientPropertyKey}.
678      */
uninstallUIAndProperties()679     private void uninstallUIAndProperties() {
680         if (ui != null) {
681             ui.uninstallUI(this);
682             //clean UIClientPropertyKeys from client properties
683             if (clientProperties != null) {
684                 synchronized(clientProperties) {
685                     Object[] clientPropertyKeys =
686                         clientProperties.getKeys(null);
687                     if (clientPropertyKeys != null) {
688                         for (Object key : clientPropertyKeys) {
689                             if (key instanceof UIClientPropertyKey) {
690                                 putClientProperty(key, null);
691                             }
692                         }
693                     }
694                 }
695             }
696         }
697     }
698 
699     /**
700      * Returns the <code>UIDefaults</code> key used to
701      * look up the name of the <code>swing.plaf.ComponentUI</code>
702      * class that defines the look and feel
703      * for this component.  Most applications will never need to
704      * call this method.  Subclasses of <code>JComponent</code> that support
705      * pluggable look and feel should override this method to
706      * return a <code>UIDefaults</code> key that maps to the
707      * <code>ComponentUI</code> subclass that defines their look and feel.
708      *
709      * @return the <code>UIDefaults</code> key for a
710      *          <code>ComponentUI</code> subclass
711      * @see UIDefaults#getUI
712      * @beaninfo
713      *      expert: true
714      * description: UIClassID
715      */
getUIClassID()716     public String getUIClassID() {
717         return uiClassID;
718     }
719 
720 
721     /**
722      * Returns the graphics object used to paint this component.
723      * If <code>DebugGraphics</code> is turned on we create a new
724      * <code>DebugGraphics</code> object if necessary.
725      * Otherwise we just configure the
726      * specified graphics object's foreground and font.
727      *
728      * @param g the original <code>Graphics</code> object
729      * @return a <code>Graphics</code> object configured for this component
730      */
getComponentGraphics(Graphics g)731     protected Graphics getComponentGraphics(Graphics g) {
732         Graphics componentGraphics = g;
733         if (ui != null && DEBUG_GRAPHICS_LOADED) {
734             if ((DebugGraphics.debugComponentCount() != 0) &&
735                     (shouldDebugGraphics() != 0) &&
736                     !(g instanceof DebugGraphics)) {
737                 componentGraphics = new DebugGraphics(g,this);
738             }
739         }
740         componentGraphics.setColor(getForeground());
741         componentGraphics.setFont(getFont());
742 
743         return componentGraphics;
744     }
745 
746 
747     /**
748      * Calls the UI delegate's paint method, if the UI delegate
749      * is non-<code>null</code>.  We pass the delegate a copy of the
750      * <code>Graphics</code> object to protect the rest of the
751      * paint code from irrevocable changes
752      * (for example, <code>Graphics.translate</code>).
753      * <p>
754      * If you override this in a subclass you should not make permanent
755      * changes to the passed in <code>Graphics</code>. For example, you
756      * should not alter the clip <code>Rectangle</code> or modify the
757      * transform. If you need to do these operations you may find it
758      * easier to create a new <code>Graphics</code> from the passed in
759      * <code>Graphics</code> and manipulate it. Further, if you do not
760      * invoker super's implementation you must honor the opaque property,
761      * that is
762      * if this component is opaque, you must completely fill in the background
763      * in a non-opaque color. If you do not honor the opaque property you
764      * will likely see visual artifacts.
765      * <p>
766      * The passed in <code>Graphics</code> object might
767      * have a transform other than the identify transform
768      * installed on it.  In this case, you might get
769      * unexpected results if you cumulatively apply
770      * another transform.
771      *
772      * @param g the <code>Graphics</code> object to protect
773      * @see #paint
774      * @see ComponentUI
775      */
paintComponent(Graphics g)776     protected void paintComponent(Graphics g) {
777         if (ui != null) {
778             Graphics scratchGraphics = (g == null) ? null : g.create();
779             try {
780                 ui.update(scratchGraphics, this);
781             }
782             finally {
783                 scratchGraphics.dispose();
784             }
785         }
786     }
787 
788     /**
789      * Paints this component's children.
790      * If <code>shouldUseBuffer</code> is true,
791      * no component ancestor has a buffer and
792      * the component children can use a buffer if they have one.
793      * Otherwise, one ancestor has a buffer currently in use and children
794      * should not use a buffer to paint.
795      * @param g  the <code>Graphics</code> context in which to paint
796      * @see #paint
797      * @see java.awt.Container#paint
798      */
paintChildren(Graphics g)799     protected void paintChildren(Graphics g) {
800         Graphics sg = g;
801 
802         synchronized(getTreeLock()) {
803             int i = getComponentCount() - 1;
804             if (i < 0) {
805                 return;
806             }
807             // If we are only to paint to a specific child, determine
808             // its index.
809             if (paintingChild != null &&
810                 (paintingChild instanceof JComponent) &&
811                 paintingChild.isOpaque()) {
812                 for (; i >= 0; i--) {
813                     if (getComponent(i) == paintingChild){
814                         break;
815                     }
816                 }
817             }
818             Rectangle tmpRect = fetchRectangle();
819             boolean checkSiblings = (!isOptimizedDrawingEnabled() &&
820                                      checkIfChildObscuredBySibling());
821             Rectangle clipBounds = null;
822             if (checkSiblings) {
823                 clipBounds = sg.getClipBounds();
824                 if (clipBounds == null) {
825                     clipBounds = new Rectangle(0, 0, getWidth(),
826                                                getHeight());
827                 }
828             }
829             boolean printing = getFlag(IS_PRINTING);
830             final Window window = SwingUtilities.getWindowAncestor(this);
831             final boolean isWindowOpaque = window == null || window.isOpaque();
832             for (; i >= 0 ; i--) {
833                 Component comp = getComponent(i);
834                 if (comp == null) {
835                     continue;
836                 }
837 
838                 final boolean isJComponent = comp instanceof JComponent;
839 
840                 // Enable painting of heavyweights in non-opaque windows.
841                 // See 6884960
842                 if ((!isWindowOpaque || isJComponent ||
843                             isLightweightComponent(comp)) && comp.isVisible())
844                 {
845                     Rectangle cr;
846 
847                     cr = comp.getBounds(tmpRect);
848 
849                     boolean hitClip = g.hitClip(cr.x, cr.y, cr.width,
850                                                 cr.height);
851 
852                     if (hitClip) {
853                         if (checkSiblings && i > 0) {
854                             int x = cr.x;
855                             int y = cr.y;
856                             int width = cr.width;
857                             int height = cr.height;
858                             SwingUtilities.computeIntersection
859                                 (clipBounds.x, clipBounds.y,
860                                  clipBounds.width, clipBounds.height, cr);
861 
862                             if(getObscuredState(i, cr.x, cr.y, cr.width,
863                                           cr.height) == COMPLETELY_OBSCURED) {
864                                 continue;
865                             }
866                             cr.x = x;
867                             cr.y = y;
868                             cr.width = width;
869                             cr.height = height;
870                         }
871                         Graphics cg = sg.create(cr.x, cr.y, cr.width,
872                                                 cr.height);
873                         cg.setColor(comp.getForeground());
874                         cg.setFont(comp.getFont());
875                         boolean shouldSetFlagBack = false;
876                         try {
877                             if(isJComponent) {
878                                 if(getFlag(ANCESTOR_USING_BUFFER)) {
879                                     ((JComponent)comp).setFlag(
880                                                  ANCESTOR_USING_BUFFER,true);
881                                     shouldSetFlagBack = true;
882                                 }
883                                 if(getFlag(IS_PAINTING_TILE)) {
884                                     ((JComponent)comp).setFlag(
885                                                  IS_PAINTING_TILE,true);
886                                     shouldSetFlagBack = true;
887                                 }
888                                 if(!printing) {
889                                     comp.paint(cg);
890                                 }
891                                 else {
892                                     if (!getFlag(IS_PRINTING_ALL)) {
893                                         comp.print(cg);
894                                     }
895                                     else {
896                                         comp.printAll(cg);
897                                     }
898                                 }
899                             } else {
900                                 // The component is either lightweight, or
901                                 // heavyweight in a non-opaque window
902                                 if (!printing) {
903                                     comp.paint(cg);
904                                 }
905                                 else {
906                                     if (!getFlag(IS_PRINTING_ALL)) {
907                                         comp.print(cg);
908                                     }
909                                     else {
910                                         comp.printAll(cg);
911                                     }
912                                 }
913                             }
914                         } finally {
915                             cg.dispose();
916                             if(shouldSetFlagBack) {
917                                 ((JComponent)comp).setFlag(
918                                              ANCESTOR_USING_BUFFER,false);
919                                 ((JComponent)comp).setFlag(
920                                              IS_PAINTING_TILE,false);
921                             }
922                         }
923                     }
924                 }
925 
926             }
927             recycleRectangle(tmpRect);
928         }
929     }
930 
931     /**
932      * Paints the component's border.
933      * <p>
934      * If you override this in a subclass you should not make permanent
935      * changes to the passed in <code>Graphics</code>. For example, you
936      * should not alter the clip <code>Rectangle</code> or modify the
937      * transform. If you need to do these operations you may find it
938      * easier to create a new <code>Graphics</code> from the passed in
939      * <code>Graphics</code> and manipulate it.
940      *
941      * @param g  the <code>Graphics</code> context in which to paint
942      *
943      * @see #paint
944      * @see #setBorder
945      */
paintBorder(Graphics g)946     protected void paintBorder(Graphics g) {
947         Border border = getBorder();
948         if (border != null) {
949             border.paintBorder(this, g, 0, 0, getWidth(), getHeight());
950         }
951     }
952 
953 
954     /**
955      * Calls <code>paint</code>.  Doesn't clear the background but see
956      * <code>ComponentUI.update</code>, which is called by
957      * <code>paintComponent</code>.
958      *
959      * @param g the <code>Graphics</code> context in which to paint
960      * @see #paint
961      * @see #paintComponent
962      * @see javax.swing.plaf.ComponentUI
963      */
update(Graphics g)964     public void update(Graphics g) {
965         paint(g);
966     }
967 
968 
969     /**
970      * Invoked by Swing to draw components.
971      * Applications should not invoke <code>paint</code> directly,
972      * but should instead use the <code>repaint</code> method to
973      * schedule the component for redrawing.
974      * <p>
975      * This method actually delegates the work of painting to three
976      * protected methods: <code>paintComponent</code>,
977      * <code>paintBorder</code>,
978      * and <code>paintChildren</code>.  They're called in the order
979      * listed to ensure that children appear on top of component itself.
980      * Generally speaking, the component and its children should not
981      * paint in the insets area allocated to the border. Subclasses can
982      * just override this method, as always.  A subclass that just
983      * wants to specialize the UI (look and feel) delegate's
984      * <code>paint</code> method should just override
985      * <code>paintComponent</code>.
986      *
987      * @param g  the <code>Graphics</code> context in which to paint
988      * @see #paintComponent
989      * @see #paintBorder
990      * @see #paintChildren
991      * @see #getComponentGraphics
992      * @see #repaint
993      */
paint(Graphics g)994     public void paint(Graphics g) {
995         boolean shouldClearPaintFlags = false;
996 
997         if ((getWidth() <= 0) || (getHeight() <= 0)) {
998             return;
999         }
1000 
1001         Graphics componentGraphics = getComponentGraphics(g);
1002         Graphics co = componentGraphics.create();
1003         try {
1004             RepaintManager repaintManager = RepaintManager.currentManager(this);
1005             Rectangle clipRect = co.getClipBounds();
1006             int clipX;
1007             int clipY;
1008             int clipW;
1009             int clipH;
1010             if (clipRect == null) {
1011                 clipX = clipY = 0;
1012                 clipW = getWidth();
1013                 clipH = getHeight();
1014             }
1015             else {
1016                 clipX = clipRect.x;
1017                 clipY = clipRect.y;
1018                 clipW = clipRect.width;
1019                 clipH = clipRect.height;
1020             }
1021 
1022             if(clipW > getWidth()) {
1023                 clipW = getWidth();
1024             }
1025             if(clipH > getHeight()) {
1026                 clipH = getHeight();
1027             }
1028 
1029             if(getParent() != null && !(getParent() instanceof JComponent)) {
1030                 adjustPaintFlags();
1031                 shouldClearPaintFlags = true;
1032             }
1033 
1034             int bw,bh;
1035             boolean printing = getFlag(IS_PRINTING);
1036             if (!printing && repaintManager.isDoubleBufferingEnabled() &&
1037                 !getFlag(ANCESTOR_USING_BUFFER) && isDoubleBuffered() &&
1038                 (getFlag(IS_REPAINTING) || repaintManager.isPainting()))
1039             {
1040                 repaintManager.beginPaint();
1041                 try {
1042                     repaintManager.paint(this, this, co, clipX, clipY, clipW,
1043                                          clipH);
1044                 } finally {
1045                     repaintManager.endPaint();
1046                 }
1047             }
1048             else {
1049                 // Will ocassionaly happen in 1.2, especially when printing.
1050                 if (clipRect == null) {
1051                     co.setClip(clipX, clipY, clipW, clipH);
1052                 }
1053 
1054                 if (!rectangleIsObscured(clipX,clipY,clipW,clipH)) {
1055                     if (!printing) {
1056                         paintComponent(co);
1057                         paintBorder(co);
1058                     }
1059                     else {
1060                         printComponent(co);
1061                         printBorder(co);
1062                     }
1063                 }
1064                 if (!printing) {
1065                     paintChildren(co);
1066                 }
1067                 else {
1068                     printChildren(co);
1069                 }
1070             }
1071         } finally {
1072             co.dispose();
1073             if(shouldClearPaintFlags) {
1074                 setFlag(ANCESTOR_USING_BUFFER,false);
1075                 setFlag(IS_PAINTING_TILE,false);
1076                 setFlag(IS_PRINTING,false);
1077                 setFlag(IS_PRINTING_ALL,false);
1078             }
1079         }
1080     }
1081 
1082     // paint forcing use of the double buffer.  This is used for historical
1083     // reasons: JViewport, when scrolling, previously directly invoked paint
1084     // while turning off double buffering at the RepaintManager level, this
1085     // codes simulates that.
paintForceDoubleBuffered(Graphics g)1086     void paintForceDoubleBuffered(Graphics g) {
1087         RepaintManager rm = RepaintManager.currentManager(this);
1088         Rectangle clip = g.getClipBounds();
1089         rm.beginPaint();
1090         setFlag(IS_REPAINTING, true);
1091         try {
1092             rm.paint(this, this, g, clip.x, clip.y, clip.width, clip.height);
1093         } finally {
1094             rm.endPaint();
1095             setFlag(IS_REPAINTING, false);
1096         }
1097     }
1098 
1099     /**
1100      * Returns true if this component, or any of its ancestors, are in
1101      * the processing of painting.
1102      */
isPainting()1103     boolean isPainting() {
1104         Container component = this;
1105         while (component != null) {
1106             if (component instanceof JComponent &&
1107                    ((JComponent)component).getFlag(ANCESTOR_USING_BUFFER)) {
1108                 return true;
1109             }
1110             component = component.getParent();
1111         }
1112         return false;
1113     }
1114 
adjustPaintFlags()1115     private void adjustPaintFlags() {
1116         JComponent jparent;
1117         Container parent;
1118         for(parent = getParent() ; parent != null ; parent =
1119             parent.getParent()) {
1120             if(parent instanceof JComponent) {
1121                 jparent = (JComponent) parent;
1122                 if(jparent.getFlag(ANCESTOR_USING_BUFFER))
1123                   setFlag(ANCESTOR_USING_BUFFER, true);
1124                 if(jparent.getFlag(IS_PAINTING_TILE))
1125                   setFlag(IS_PAINTING_TILE, true);
1126                 if(jparent.getFlag(IS_PRINTING))
1127                   setFlag(IS_PRINTING, true);
1128                 if(jparent.getFlag(IS_PRINTING_ALL))
1129                   setFlag(IS_PRINTING_ALL, true);
1130                 break;
1131             }
1132         }
1133     }
1134 
1135     /**
1136      * Invoke this method to print the component. This method invokes
1137      * <code>print</code> on the component.
1138      *
1139      * @param g the <code>Graphics</code> context in which to paint
1140      * @see #print
1141      * @see #printComponent
1142      * @see #printBorder
1143      * @see #printChildren
1144      */
printAll(Graphics g)1145     public void printAll(Graphics g) {
1146         setFlag(IS_PRINTING_ALL, true);
1147         try {
1148             print(g);
1149         }
1150         finally {
1151             setFlag(IS_PRINTING_ALL, false);
1152         }
1153     }
1154 
1155     /**
1156      * Invoke this method to print the component to the specified
1157      * <code>Graphics</code>. This method will result in invocations
1158      * of <code>printComponent</code>, <code>printBorder</code> and
1159      * <code>printChildren</code>. It is recommended that you override
1160      * one of the previously mentioned methods rather than this one if
1161      * your intention is to customize the way printing looks. However,
1162      * it can be useful to override this method should you want to prepare
1163      * state before invoking the superclass behavior. As an example,
1164      * if you wanted to change the component's background color before
1165      * printing, you could do the following:
1166      * <pre>
1167      *     public void print(Graphics g) {
1168      *         Color orig = getBackground();
1169      *         setBackground(Color.WHITE);
1170      *
1171      *         // wrap in try/finally so that we always restore the state
1172      *         try {
1173      *             super.print(g);
1174      *         } finally {
1175      *             setBackground(orig);
1176      *         }
1177      *     }
1178      * </pre>
1179      * <p>
1180      * Alternatively, or for components that delegate painting to other objects,
1181      * you can query during painting whether or not the component is in the
1182      * midst of a print operation. The <code>isPaintingForPrint</code> method provides
1183      * this ability and its return value will be changed by this method: to
1184      * <code>true</code> immediately before rendering and to <code>false</code>
1185      * immediately after. With each change a property change event is fired on
1186      * this component with the name <code>"paintingForPrint"</code>.
1187      * <p>
1188      * This method sets the component's state such that the double buffer
1189      * will not be used: painting will be done directly on the passed in
1190      * <code>Graphics</code>.
1191      *
1192      * @param g the <code>Graphics</code> context in which to paint
1193      * @see #printComponent
1194      * @see #printBorder
1195      * @see #printChildren
1196      * @see #isPaintingForPrint
1197      */
print(Graphics g)1198     public void print(Graphics g) {
1199         setFlag(IS_PRINTING, true);
1200         firePropertyChange("paintingForPrint", false, true);
1201         try {
1202             paint(g);
1203         }
1204         finally {
1205             setFlag(IS_PRINTING, false);
1206             firePropertyChange("paintingForPrint", true, false);
1207         }
1208     }
1209 
1210     /**
1211      * This is invoked during a printing operation. This is implemented to
1212      * invoke <code>paintComponent</code> on the component. Override this
1213      * if you wish to add special painting behavior when printing.
1214      *
1215      * @param g the <code>Graphics</code> context in which to paint
1216      * @see #print
1217      * @since 1.3
1218      */
printComponent(Graphics g)1219     protected void printComponent(Graphics g) {
1220         paintComponent(g);
1221     }
1222 
1223     /**
1224      * Prints this component's children. This is implemented to invoke
1225      * <code>paintChildren</code> on the component. Override this if you
1226      * wish to print the children differently than painting.
1227      *
1228      * @param g the <code>Graphics</code> context in which to paint
1229      * @see #print
1230      * @since 1.3
1231      */
printChildren(Graphics g)1232     protected void printChildren(Graphics g) {
1233         paintChildren(g);
1234     }
1235 
1236     /**
1237      * Prints the component's border. This is implemented to invoke
1238      * <code>paintBorder</code> on the component. Override this if you
1239      * wish to print the border differently that it is painted.
1240      *
1241      * @param g the <code>Graphics</code> context in which to paint
1242      * @see #print
1243      * @since 1.3
1244      */
printBorder(Graphics g)1245     protected void printBorder(Graphics g) {
1246         paintBorder(g);
1247     }
1248 
1249     /**
1250      *  Returns true if the component is currently painting a tile.
1251      *  If this method returns true, paint will be called again for another
1252      *  tile. This method returns false if you are not painting a tile or
1253      *  if the last tile is painted.
1254      *  Use this method to keep some state you might need between tiles.
1255      *
1256      *  @return  true if the component is currently painting a tile,
1257      *          false otherwise
1258      */
isPaintingTile()1259     public boolean isPaintingTile() {
1260         return getFlag(IS_PAINTING_TILE);
1261     }
1262 
1263     /**
1264      * Returns <code>true</code> if the current painting operation on this
1265      * component is part of a <code>print</code> operation. This method is
1266      * useful when you want to customize what you print versus what you show
1267      * on the screen.
1268      * <p>
1269      * You can detect changes in the value of this property by listening for
1270      * property change events on this component with name
1271      * <code>"paintingForPrint"</code>.
1272      * <p>
1273      * Note: This method provides complimentary functionality to that provided
1274      * by other high level Swing printing APIs. However, it deals strictly with
1275      * painting and should not be confused as providing information on higher
1276      * level print processes. For example, a {@link javax.swing.JTable#print()}
1277      * operation doesn't necessarily result in a continuous rendering of the
1278      * full component, and the return value of this method can change multiple
1279      * times during that operation. It is even possible for the component to be
1280      * painted to the screen while the printing process is ongoing. In such a
1281      * case, the return value of this method is <code>true</code> when, and only
1282      * when, the table is being painted as part of the printing process.
1283      *
1284      * @return true if the current painting operation on this component
1285      *         is part of a print operation
1286      * @see #print
1287      * @since 1.6
1288      */
isPaintingForPrint()1289     public final boolean isPaintingForPrint() {
1290         return getFlag(IS_PRINTING);
1291     }
1292 
1293     /**
1294      * In release 1.4, the focus subsystem was rearchitected.
1295      * For more information, see
1296      * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
1297      * How to Use the Focus Subsystem</a>,
1298      * a section in <em>The Java Tutorial</em>.
1299      * <p>
1300      * Changes this <code>JComponent</code>'s focus traversal keys to
1301      * CTRL+TAB and CTRL+SHIFT+TAB. Also prevents
1302      * <code>SortingFocusTraversalPolicy</code> from considering descendants
1303      * of this JComponent when computing a focus traversal cycle.
1304      *
1305      * @see java.awt.Component#setFocusTraversalKeys
1306      * @see SortingFocusTraversalPolicy
1307      * @deprecated As of 1.4, replaced by
1308      *   <code>Component.setFocusTraversalKeys(int, Set)</code> and
1309      *   <code>Container.setFocusCycleRoot(boolean)</code>.
1310      */
1311     @Deprecated
isManagingFocus()1312     public boolean isManagingFocus() {
1313         return false;
1314     }
1315 
registerNextFocusableComponent()1316     private void registerNextFocusableComponent() {
1317         registerNextFocusableComponent(getNextFocusableComponent());
1318     }
1319 
registerNextFocusableComponent(Component nextFocusableComponent)1320     private void registerNextFocusableComponent(Component
1321                                                 nextFocusableComponent) {
1322         if (nextFocusableComponent == null) {
1323             return;
1324         }
1325 
1326         Container nearestRoot =
1327             (isFocusCycleRoot()) ? this : getFocusCycleRootAncestor();
1328         FocusTraversalPolicy policy = nearestRoot.getFocusTraversalPolicy();
1329         if (!(policy instanceof LegacyGlueFocusTraversalPolicy)) {
1330             policy = new LegacyGlueFocusTraversalPolicy(policy);
1331             nearestRoot.setFocusTraversalPolicy(policy);
1332         }
1333         ((LegacyGlueFocusTraversalPolicy)policy).
1334             setNextFocusableComponent(this, nextFocusableComponent);
1335     }
1336 
deregisterNextFocusableComponent()1337     private void deregisterNextFocusableComponent() {
1338         Component nextFocusableComponent = getNextFocusableComponent();
1339         if (nextFocusableComponent == null) {
1340             return;
1341         }
1342 
1343         Container nearestRoot =
1344             (isFocusCycleRoot()) ? this : getFocusCycleRootAncestor();
1345         if (nearestRoot == null) {
1346             return;
1347         }
1348         FocusTraversalPolicy policy = nearestRoot.getFocusTraversalPolicy();
1349         if (policy instanceof LegacyGlueFocusTraversalPolicy) {
1350             ((LegacyGlueFocusTraversalPolicy)policy).
1351                 unsetNextFocusableComponent(this, nextFocusableComponent);
1352         }
1353     }
1354 
1355     /**
1356      * In release 1.4, the focus subsystem was rearchitected.
1357      * For more information, see
1358      * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
1359      * How to Use the Focus Subsystem</a>,
1360      * a section in <em>The Java Tutorial</em>.
1361      * <p>
1362      * Overrides the default <code>FocusTraversalPolicy</code> for this
1363      * <code>JComponent</code>'s focus traversal cycle by unconditionally
1364      * setting the specified <code>Component</code> as the next
1365      * <code>Component</code> in the cycle, and this <code>JComponent</code>
1366      * as the specified <code>Component</code>'s previous
1367      * <code>Component</code> in the cycle.
1368      *
1369      * @param aComponent the <code>Component</code> that should follow this
1370      *        <code>JComponent</code> in the focus traversal cycle
1371      *
1372      * @see #getNextFocusableComponent
1373      * @see java.awt.FocusTraversalPolicy
1374      * @deprecated As of 1.4, replaced by <code>FocusTraversalPolicy</code>
1375      */
1376     @Deprecated
setNextFocusableComponent(Component aComponent)1377     public void setNextFocusableComponent(Component aComponent) {
1378         boolean displayable = isDisplayable();
1379         if (displayable) {
1380             deregisterNextFocusableComponent();
1381         }
1382         putClientProperty(NEXT_FOCUS, aComponent);
1383         if (displayable) {
1384             registerNextFocusableComponent(aComponent);
1385         }
1386     }
1387 
1388     /**
1389      * In release 1.4, the focus subsystem was rearchitected.
1390      * For more information, see
1391      * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
1392      * How to Use the Focus Subsystem</a>,
1393      * a section in <em>The Java Tutorial</em>.
1394      * <p>
1395      * Returns the <code>Component</code> set by a prior call to
1396      * <code>setNextFocusableComponent(Component)</code> on this
1397      * <code>JComponent</code>.
1398      *
1399      * @return the <code>Component</code> that will follow this
1400      *        <code>JComponent</code> in the focus traversal cycle, or
1401      *        <code>null</code> if none has been explicitly specified
1402      *
1403      * @see #setNextFocusableComponent
1404      * @deprecated As of 1.4, replaced by <code>FocusTraversalPolicy</code>.
1405      */
1406     @Deprecated
getNextFocusableComponent()1407     public Component getNextFocusableComponent() {
1408         return (Component)getClientProperty(NEXT_FOCUS);
1409     }
1410 
1411     /**
1412      * Provides a hint as to whether or not this <code>JComponent</code>
1413      * should get focus. This is only a hint, and it is up to consumers that
1414      * are requesting focus to honor this property. This is typically honored
1415      * for mouse operations, but not keyboard operations. For example, look
1416      * and feels could verify this property is true before requesting focus
1417      * during a mouse operation. This would often times be used if you did
1418      * not want a mouse press on a <code>JComponent</code> to steal focus,
1419      * but did want the <code>JComponent</code> to be traversable via the
1420      * keyboard. If you do not want this <code>JComponent</code> focusable at
1421      * all, use the <code>setFocusable</code> method instead.
1422      * <p>
1423      * Please see
1424      * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
1425      * How to Use the Focus Subsystem</a>,
1426      * a section in <em>The Java Tutorial</em>,
1427      * for more information.
1428      *
1429      * @param requestFocusEnabled indicates whether you want this
1430      *        <code>JComponent</code> to be focusable or not
1431      * @see <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
1432      * @see java.awt.Component#setFocusable
1433      */
setRequestFocusEnabled(boolean requestFocusEnabled)1434     public void setRequestFocusEnabled(boolean requestFocusEnabled) {
1435         setFlag(REQUEST_FOCUS_DISABLED, !requestFocusEnabled);
1436     }
1437 
1438     /**
1439      * Returns <code>true</code> if this <code>JComponent</code> should
1440      * get focus; otherwise returns <code>false</code>.
1441      * <p>
1442      * Please see
1443      * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
1444      * How to Use the Focus Subsystem</a>,
1445      * a section in <em>The Java Tutorial</em>,
1446      * for more information.
1447      *
1448      * @return <code>true</code> if this component should get focus,
1449      *     otherwise returns <code>false</code>
1450      * @see #setRequestFocusEnabled
1451      * @see <a href="../../java/awt/doc-files/FocusSpec.html">Focus
1452      *      Specification</a>
1453      * @see java.awt.Component#isFocusable
1454      */
isRequestFocusEnabled()1455     public boolean isRequestFocusEnabled() {
1456         return !getFlag(REQUEST_FOCUS_DISABLED);
1457     }
1458 
1459     /**
1460      * Requests that this <code>Component</code> gets the input focus.
1461      * Refer to {@link java.awt.Component#requestFocus()
1462      * Component.requestFocus()} for a complete description of
1463      * this method.
1464      * <p>
1465      * Note that the use of this method is discouraged because
1466      * its behavior is platform dependent. Instead we recommend the
1467      * use of {@link #requestFocusInWindow() requestFocusInWindow()}.
1468      * If you would like more information on focus, see
1469      * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
1470      * How to Use the Focus Subsystem</a>,
1471      * a section in <em>The Java Tutorial</em>.
1472      *
1473      * @see java.awt.Component#requestFocusInWindow()
1474      * @see java.awt.Component#requestFocusInWindow(boolean)
1475      * @since 1.4
1476      */
requestFocus()1477     public void requestFocus() {
1478         super.requestFocus();
1479     }
1480 
1481     /**
1482      * Requests that this <code>Component</code> gets the input focus.
1483      * Refer to {@link java.awt.Component#requestFocus(boolean)
1484      * Component.requestFocus(boolean)} for a complete description of
1485      * this method.
1486      * <p>
1487      * Note that the use of this method is discouraged because
1488      * its behavior is platform dependent. Instead we recommend the
1489      * use of {@link #requestFocusInWindow(boolean)
1490      * requestFocusInWindow(boolean)}.
1491      * If you would like more information on focus, see
1492      * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
1493      * How to Use the Focus Subsystem</a>,
1494      * a section in <em>The Java Tutorial</em>.
1495      *
1496      * @param temporary boolean indicating if the focus change is temporary
1497      * @return <code>false</code> if the focus change request is guaranteed to
1498      *         fail; <code>true</code> if it is likely to succeed
1499      * @see java.awt.Component#requestFocusInWindow()
1500      * @see java.awt.Component#requestFocusInWindow(boolean)
1501      * @since 1.4
1502      */
requestFocus(boolean temporary)1503     public boolean requestFocus(boolean temporary) {
1504         return super.requestFocus(temporary);
1505     }
1506 
1507     /**
1508      * Requests that this <code>Component</code> gets the input focus.
1509      * Refer to {@link java.awt.Component#requestFocusInWindow()
1510      * Component.requestFocusInWindow()} for a complete description of
1511      * this method.
1512      * <p>
1513      * If you would like more information on focus, see
1514      * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
1515      * How to Use the Focus Subsystem</a>,
1516      * a section in <em>The Java Tutorial</em>.
1517      *
1518      * @return <code>false</code> if the focus change request is guaranteed to
1519      *         fail; <code>true</code> if it is likely to succeed
1520      * @see java.awt.Component#requestFocusInWindow()
1521      * @see java.awt.Component#requestFocusInWindow(boolean)
1522      * @since 1.4
1523      */
requestFocusInWindow()1524     public boolean requestFocusInWindow() {
1525         return super.requestFocusInWindow();
1526     }
1527 
1528     /**
1529      * Requests that this <code>Component</code> gets the input focus.
1530      * Refer to {@link java.awt.Component#requestFocusInWindow(boolean)
1531      * Component.requestFocusInWindow(boolean)} for a complete description of
1532      * this method.
1533      * <p>
1534      * If you would like more information on focus, see
1535      * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
1536      * How to Use the Focus Subsystem</a>,
1537      * a section in <em>The Java Tutorial</em>.
1538      *
1539      * @param temporary boolean indicating if the focus change is temporary
1540      * @return <code>false</code> if the focus change request is guaranteed to
1541      *         fail; <code>true</code> if it is likely to succeed
1542      * @see java.awt.Component#requestFocusInWindow()
1543      * @see java.awt.Component#requestFocusInWindow(boolean)
1544      * @since 1.4
1545      */
requestFocusInWindow(boolean temporary)1546     protected boolean requestFocusInWindow(boolean temporary) {
1547         return super.requestFocusInWindow(temporary);
1548     }
1549 
1550     /**
1551      * Requests that this Component get the input focus, and that this
1552      * Component's top-level ancestor become the focused Window. This component
1553      * must be displayable, visible, and focusable for the request to be
1554      * granted.
1555      * <p>
1556      * This method is intended for use by focus implementations. Client code
1557      * should not use this method; instead, it should use
1558      * <code>requestFocusInWindow()</code>.
1559      *
1560      * @see #requestFocusInWindow()
1561      */
grabFocus()1562     public void grabFocus() {
1563         requestFocus();
1564     }
1565 
1566     /**
1567      * Sets the value to indicate whether input verifier for the
1568      * current focus owner will be called before this component requests
1569      * focus. The default is true. Set to false on components such as a
1570      * Cancel button or a scrollbar, which should activate even if the
1571      * input in the current focus owner is not "passed" by the input
1572      * verifier for that component.
1573      *
1574      * @param verifyInputWhenFocusTarget value for the
1575      *        <code>verifyInputWhenFocusTarget</code> property
1576      * @see InputVerifier
1577      * @see #setInputVerifier
1578      * @see #getInputVerifier
1579      * @see #getVerifyInputWhenFocusTarget
1580      *
1581      * @since 1.3
1582      * @beaninfo
1583      *       bound: true
1584      * description: Whether the Component verifies input before accepting
1585      *              focus.
1586      */
setVerifyInputWhenFocusTarget(boolean verifyInputWhenFocusTarget)1587     public void setVerifyInputWhenFocusTarget(boolean
1588                                               verifyInputWhenFocusTarget) {
1589         boolean oldVerifyInputWhenFocusTarget =
1590             this.verifyInputWhenFocusTarget;
1591         this.verifyInputWhenFocusTarget = verifyInputWhenFocusTarget;
1592         firePropertyChange("verifyInputWhenFocusTarget",
1593                            oldVerifyInputWhenFocusTarget,
1594                            verifyInputWhenFocusTarget);
1595     }
1596 
1597     /**
1598      * Returns the value that indicates whether the input verifier for the
1599      * current focus owner will be called before this component requests
1600      * focus.
1601      *
1602      * @return value of the <code>verifyInputWhenFocusTarget</code> property
1603      *
1604      * @see InputVerifier
1605      * @see #setInputVerifier
1606      * @see #getInputVerifier
1607      * @see #setVerifyInputWhenFocusTarget
1608      *
1609      * @since 1.3
1610      */
getVerifyInputWhenFocusTarget()1611     public boolean getVerifyInputWhenFocusTarget() {
1612         return verifyInputWhenFocusTarget;
1613     }
1614 
1615 
1616     /**
1617      * Gets the <code>FontMetrics</code> for the specified <code>Font</code>.
1618      *
1619      * @param font the font for which font metrics is to be
1620      *          obtained
1621      * @return the font metrics for <code>font</code>
1622      * @throws NullPointerException if <code>font</code> is null
1623      * @since 1.5
1624      */
getFontMetrics(Font font)1625     public FontMetrics getFontMetrics(Font font) {
1626         return SwingUtilities2.getFontMetrics(this, font);
1627     }
1628 
1629 
1630     /**
1631      * Sets the preferred size of this component.
1632      * If <code>preferredSize</code> is <code>null</code>, the UI will
1633      * be asked for the preferred size.
1634      * @beaninfo
1635      *   preferred: true
1636      *       bound: true
1637      * description: The preferred size of the component.
1638      */
setPreferredSize(Dimension preferredSize)1639     public void setPreferredSize(Dimension preferredSize) {
1640         super.setPreferredSize(preferredSize);
1641     }
1642 
1643 
1644     /**
1645      * If the <code>preferredSize</code> has been set to a
1646      * non-<code>null</code> value just returns it.
1647      * If the UI delegate's <code>getPreferredSize</code>
1648      * method returns a non <code>null</code> value then return that;
1649      * otherwise defer to the component's layout manager.
1650      *
1651      * @return the value of the <code>preferredSize</code> property
1652      * @see #setPreferredSize
1653      * @see ComponentUI
1654      */
1655     @Transient
getPreferredSize()1656     public Dimension getPreferredSize() {
1657         if (isPreferredSizeSet()) {
1658             return super.getPreferredSize();
1659         }
1660         Dimension size = null;
1661         if (ui != null) {
1662             size = ui.getPreferredSize(this);
1663         }
1664         return (size != null) ? size : super.getPreferredSize();
1665     }
1666 
1667 
1668     /**
1669      * Sets the maximum size of this component to a constant
1670      * value.  Subsequent calls to <code>getMaximumSize</code> will always
1671      * return this value; the component's UI will not be asked
1672      * to compute it.  Setting the maximum size to <code>null</code>
1673      * restores the default behavior.
1674      *
1675      * @param maximumSize a <code>Dimension</code> containing the
1676      *          desired maximum allowable size
1677      * @see #getMaximumSize
1678      * @beaninfo
1679      *       bound: true
1680      * description: The maximum size of the component.
1681      */
setMaximumSize(Dimension maximumSize)1682     public void setMaximumSize(Dimension maximumSize) {
1683         super.setMaximumSize(maximumSize);
1684     }
1685 
1686 
1687     /**
1688      * If the maximum size has been set to a non-<code>null</code> value
1689      * just returns it.  If the UI delegate's <code>getMaximumSize</code>
1690      * method returns a non-<code>null</code> value then return that;
1691      * otherwise defer to the component's layout manager.
1692      *
1693      * @return the value of the <code>maximumSize</code> property
1694      * @see #setMaximumSize
1695      * @see ComponentUI
1696      */
1697     @Transient
getMaximumSize()1698     public Dimension getMaximumSize() {
1699         if (isMaximumSizeSet()) {
1700             return super.getMaximumSize();
1701         }
1702         Dimension size = null;
1703         if (ui != null) {
1704             size = ui.getMaximumSize(this);
1705         }
1706         return (size != null) ? size : super.getMaximumSize();
1707     }
1708 
1709 
1710     /**
1711      * Sets the minimum size of this component to a constant
1712      * value.  Subsequent calls to <code>getMinimumSize</code> will always
1713      * return this value; the component's UI will not be asked
1714      * to compute it.  Setting the minimum size to <code>null</code>
1715      * restores the default behavior.
1716      *
1717      * @param minimumSize the new minimum size of this component
1718      * @see #getMinimumSize
1719      * @beaninfo
1720      *       bound: true
1721      * description: The minimum size of the component.
1722      */
setMinimumSize(Dimension minimumSize)1723     public void setMinimumSize(Dimension minimumSize) {
1724         super.setMinimumSize(minimumSize);
1725     }
1726 
1727     /**
1728      * If the minimum size has been set to a non-<code>null</code> value
1729      * just returns it.  If the UI delegate's <code>getMinimumSize</code>
1730      * method returns a non-<code>null</code> value then return that; otherwise
1731      * defer to the component's layout manager.
1732      *
1733      * @return the value of the <code>minimumSize</code> property
1734      * @see #setMinimumSize
1735      * @see ComponentUI
1736      */
1737     @Transient
getMinimumSize()1738     public Dimension getMinimumSize() {
1739         if (isMinimumSizeSet()) {
1740             return super.getMinimumSize();
1741         }
1742         Dimension size = null;
1743         if (ui != null) {
1744             size = ui.getMinimumSize(this);
1745         }
1746         return (size != null) ? size : super.getMinimumSize();
1747     }
1748 
1749     /**
1750      * Gives the UI delegate an opportunity to define the precise
1751      * shape of this component for the sake of mouse processing.
1752      *
1753      * @return true if this component logically contains x,y
1754      * @see java.awt.Component#contains(int, int)
1755      * @see ComponentUI
1756      */
contains(int x, int y)1757     public boolean contains(int x, int y) {
1758         return (ui != null) ? ui.contains(this, x, y) : super.contains(x, y);
1759     }
1760 
1761     /**
1762      * Sets the border of this component.  The <code>Border</code> object is
1763      * responsible for defining the insets for the component
1764      * (overriding any insets set directly on the component) and
1765      * for optionally rendering any border decorations within the
1766      * bounds of those insets.  Borders should be used (rather
1767      * than insets) for creating both decorative and non-decorative
1768      * (such as margins and padding) regions for a swing component.
1769      * Compound borders can be used to nest multiple borders within a
1770      * single component.
1771      * <p>
1772      * Although technically you can set the border on any object
1773      * that inherits from <code>JComponent</code>, the look and
1774      * feel implementation of many standard Swing components
1775      * doesn't work well with user-set borders.  In general,
1776      * when you want to set a border on a standard Swing
1777      * component other than <code>JPanel</code> or <code>JLabel</code>,
1778      * we recommend that you put the component in a <code>JPanel</code>
1779      * and set the border on the <code>JPanel</code>.
1780      * <p>
1781      * This is a bound property.
1782      *
1783      * @param border the border to be rendered for this component
1784      * @see Border
1785      * @see CompoundBorder
1786      * @beaninfo
1787      *        bound: true
1788      *    preferred: true
1789      *    attribute: visualUpdate true
1790      *  description: The component's border.
1791      */
setBorder(Border border)1792     public void setBorder(Border border) {
1793         Border         oldBorder = this.border;
1794 
1795         this.border = border;
1796         firePropertyChange("border", oldBorder, border);
1797         if (border != oldBorder) {
1798             if (border == null || oldBorder == null ||
1799                 !(border.getBorderInsets(this).equals(oldBorder.getBorderInsets(this)))) {
1800                 revalidate();
1801             }
1802             repaint();
1803         }
1804     }
1805 
1806     /**
1807      * Returns the border of this component or <code>null</code> if no
1808      * border is currently set.
1809      *
1810      * @return the border object for this component
1811      * @see #setBorder
1812      */
getBorder()1813     public Border getBorder() {
1814         return border;
1815     }
1816 
1817     /**
1818      * If a border has been set on this component, returns the
1819      * border's insets; otherwise calls <code>super.getInsets</code>.
1820      *
1821      * @return the value of the insets property
1822      * @see #setBorder
1823      */
getInsets()1824     public Insets getInsets() {
1825         if (border != null) {
1826             return border.getBorderInsets(this);
1827         }
1828         return super.getInsets();
1829     }
1830 
1831     /**
1832      * Returns an <code>Insets</code> object containing this component's inset
1833      * values.  The passed-in <code>Insets</code> object will be reused
1834      * if possible.
1835      * Calling methods cannot assume that the same object will be returned,
1836      * however.  All existing values within this object are overwritten.
1837      * If <code>insets</code> is null, this will allocate a new one.
1838      *
1839      * @param insets the <code>Insets</code> object, which can be reused
1840      * @return the <code>Insets</code> object
1841      * @see #getInsets
1842      * @beaninfo
1843      *   expert: true
1844      */
getInsets(Insets insets)1845     public Insets getInsets(Insets insets) {
1846         if (insets == null) {
1847             insets = new Insets(0, 0, 0, 0);
1848         }
1849         if (border != null) {
1850             if (border instanceof AbstractBorder) {
1851                 return ((AbstractBorder)border).getBorderInsets(this, insets);
1852             } else {
1853                 // Can't reuse border insets because the Border interface
1854                 // can't be enhanced.
1855                 return border.getBorderInsets(this);
1856             }
1857         } else {
1858             // super.getInsets() always returns an Insets object with
1859             // all of its value zeroed.  No need for a new object here.
1860             insets.left = insets.top = insets.right = insets.bottom = 0;
1861             return insets;
1862         }
1863     }
1864 
1865     /**
1866      * Overrides <code>Container.getAlignmentY</code> to return
1867      * the horizontal alignment.
1868      *
1869      * @return the value of the <code>alignmentY</code> property
1870      * @see #setAlignmentY
1871      * @see java.awt.Component#getAlignmentY
1872      */
getAlignmentY()1873     public float getAlignmentY() {
1874         if (isAlignmentYSet) {
1875             return alignmentY;
1876         }
1877         return super.getAlignmentY();
1878     }
1879 
1880     /**
1881      * Sets the the horizontal alignment.
1882      *
1883      * @param alignmentY  the new horizontal alignment
1884      * @see #getAlignmentY
1885      * @beaninfo
1886      *   description: The preferred vertical alignment of the component.
1887      */
setAlignmentY(float alignmentY)1888     public void setAlignmentY(float alignmentY) {
1889         this.alignmentY = alignmentY > 1.0f ? 1.0f : alignmentY < 0.0f ? 0.0f : alignmentY;
1890         isAlignmentYSet = true;
1891     }
1892 
1893 
1894     /**
1895      * Overrides <code>Container.getAlignmentX</code> to return
1896      * the vertical alignment.
1897      *
1898      * @return the value of the <code>alignmentX</code> property
1899      * @see #setAlignmentX
1900      * @see java.awt.Component#getAlignmentX
1901      */
1902     public float getAlignmentX() {
1903         if (isAlignmentXSet) {
1904             return alignmentX;
1905         }
1906         return super.getAlignmentX();
1907     }
1908 
1909     /**
1910      * Sets the the vertical alignment.
1911      *
1912      * @param alignmentX  the new vertical alignment
1913      * @see #getAlignmentX
1914      * @beaninfo
1915      *   description: The preferred horizontal alignment of the component.
1916      */
1917     public void setAlignmentX(float alignmentX) {
1918         this.alignmentX = alignmentX > 1.0f ? 1.0f : alignmentX < 0.0f ? 0.0f : alignmentX;
1919         isAlignmentXSet = true;
1920     }
1921 
1922     /**
1923      * Sets the input verifier for this component.
1924      *
1925      * @param inputVerifier the new input verifier
1926      * @since 1.3
1927      * @see InputVerifier
1928      * @beaninfo
1929      *       bound: true
1930      * description: The component's input verifier.
1931      */
1932     public void setInputVerifier(InputVerifier inputVerifier) {
1933         InputVerifier oldInputVerifier = (InputVerifier)getClientProperty(
1934                                          JComponent_INPUT_VERIFIER);
1935         putClientProperty(JComponent_INPUT_VERIFIER, inputVerifier);
1936         firePropertyChange("inputVerifier", oldInputVerifier, inputVerifier);
1937     }
1938 
1939     /**
1940      * Returns the input verifier for this component.
1941      *
1942      * @return the <code>inputVerifier</code> property
1943      * @since 1.3
1944      * @see InputVerifier
1945      */
1946     public InputVerifier getInputVerifier() {
1947         return (InputVerifier)getClientProperty(JComponent_INPUT_VERIFIER);
1948     }
1949 
1950     /**
1951      * Returns this component's graphics context, which lets you draw
1952      * on a component. Use this method to get a <code>Graphics</code> object and
1953      * then invoke operations on that object to draw on the component.
1954      * @return this components graphics context
1955      */
1956     public Graphics getGraphics() {
1957         if (DEBUG_GRAPHICS_LOADED && shouldDebugGraphics() != 0) {
1958             DebugGraphics graphics = new DebugGraphics(super.getGraphics(),
1959                                                        this);
1960             return graphics;
1961         }
1962         return super.getGraphics();
1963     }
1964 
1965 
1966     /** Enables or disables diagnostic information about every graphics
1967       * operation performed within the component or one of its children.
1968       *
1969       * @param debugOptions  determines how the component should display
1970       *         the information;  one of the following options:
1971       * <ul>
1972       * <li>DebugGraphics.LOG_OPTION - causes a text message to be printed.
1973       * <li>DebugGraphics.FLASH_OPTION - causes the drawing to flash several
1974       * times.
1975       * <li>DebugGraphics.BUFFERED_OPTION - creates an
1976       *         <code>ExternalWindow</code> that displays the operations
1977       *         performed on the View's offscreen buffer.
1978       * <li>DebugGraphics.NONE_OPTION disables debugging.
1979       * <li>A value of 0 causes no changes to the debugging options.
1980       * </ul>
1981       * <code>debugOptions</code> is bitwise OR'd into the current value
1982       *
1983       * @beaninfo
1984       *   preferred: true
1985       *        enum: NONE_OPTION DebugGraphics.NONE_OPTION
1986       *              LOG_OPTION DebugGraphics.LOG_OPTION
1987       *              FLASH_OPTION DebugGraphics.FLASH_OPTION
1988       *              BUFFERED_OPTION DebugGraphics.BUFFERED_OPTION
1989       * description: Diagnostic options for graphics operations.
1990       */
1991     public void setDebugGraphicsOptions(int debugOptions) {
1992         DebugGraphics.setDebugOptions(this, debugOptions);
1993     }
1994 
1995     /** Returns the state of graphics debugging.
1996       *
1997       * @return a bitwise OR'd flag of zero or more of the following options:
1998       * <ul>
1999       * <li>DebugGraphics.LOG_OPTION - causes a text message to be printed.
2000       * <li>DebugGraphics.FLASH_OPTION - causes the drawing to flash several
2001       * times.
2002       * <li>DebugGraphics.BUFFERED_OPTION - creates an
2003       *         <code>ExternalWindow</code> that displays the operations
2004       *         performed on the View's offscreen buffer.
2005       * <li>DebugGraphics.NONE_OPTION disables debugging.
2006       * <li>A value of 0 causes no changes to the debugging options.
2007       * </ul>
2008       * @see #setDebugGraphicsOptions
2009       */
2010     public int getDebugGraphicsOptions() {
2011         return DebugGraphics.getDebugOptions(this);
2012     }
2013 
2014 
2015     /**
2016      * Returns true if debug information is enabled for this
2017      * <code>JComponent</code> or one of its parents.
2018      */
2019     int shouldDebugGraphics() {
2020         return DebugGraphics.shouldComponentDebug(this);
2021     }
2022 
2023     /**
2024      * This method is now obsolete, please use a combination of
2025      * <code>getActionMap()</code> and <code>getInputMap()</code> for
2026      * similar behavior. For example, to bind the <code>KeyStroke</code>
2027      * <code>aKeyStroke</code> to the <code>Action</code> <code>anAction</code>
2028      * now use:
2029      * <pre>
2030      *   component.getInputMap().put(aKeyStroke, aCommand);
2031      *   component.getActionMap().put(aCommmand, anAction);
2032      * </pre>
2033      * The above assumes you want the binding to be applicable for
2034      * <code>WHEN_FOCUSED</code>. To register bindings for other focus
2035      * states use the <code>getInputMap</code> method that takes an integer.
2036      * <p>
2037      * Register a new keyboard action.
2038      * <code>anAction</code> will be invoked if a key event matching
2039      * <code>aKeyStroke</code> occurs and <code>aCondition</code> is verified.
2040      * The <code>KeyStroke</code> object defines a
2041      * particular combination of a keyboard key and one or more modifiers
2042      * (alt, shift, ctrl, meta).
2043      * <p>
2044      * The <code>aCommand</code> will be set in the delivered event if
2045      * specified.
2046      * <p>
2047      * The <code>aCondition</code> can be one of:
2048      * <blockquote>
2049      * <DL>
2050      * <DT>WHEN_FOCUSED
2051      * <DD>The action will be invoked only when the keystroke occurs
2052      *     while the component has the focus.
2053      * <DT>WHEN_IN_FOCUSED_WINDOW
2054      * <DD>The action will be invoked when the keystroke occurs while
2055      *     the component has the focus or if the component is in the
2056      *     window that has the focus. Note that the component need not
2057      *     be an immediate descendent of the window -- it can be
2058      *     anywhere in the window's containment hierarchy. In other
2059      *     words, whenever <em>any</em> component in the window has the focus,
2060      *     the action registered with this component is invoked.
2061      * <DT>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
2062      * <DD>The action will be invoked when the keystroke occurs while the
2063      *     component has the focus or if the component is an ancestor of
2064      *     the component that has the focus.
2065      * </DL>
2066      * </blockquote>
2067      * <p>
2068      * The combination of keystrokes and conditions lets you define high
2069      * level (semantic) action events for a specified keystroke+modifier
2070      * combination (using the KeyStroke class) and direct to a parent or
2071      * child of a component that has the focus, or to the component itself.
2072      * In other words, in any hierarchical structure of components, an
2073      * arbitrary key-combination can be immediately directed to the
2074      * appropriate component in the hierarchy, and cause a specific method
2075      * to be invoked (usually by way of adapter objects).
2076      * <p>
2077      * If an action has already been registered for the receiving
2078      * container, with the same charCode and the same modifiers,
2079      * <code>anAction</code> will replace the action.
2080      *
2081      * @param anAction  the <code>Action</code> to be registered
2082      * @param aCommand  the command to be set in the delivered event
2083      * @param aKeyStroke the <code>KeyStroke</code> to bind to the action
2084      * @param aCondition the condition that needs to be met, see above
2085      * @see KeyStroke
2086      */
2087     public void registerKeyboardAction(ActionListener anAction,String aCommand,KeyStroke aKeyStroke,int aCondition) {
2088 
2089         InputMap inputMap = getInputMap(aCondition, true);
2090 
2091         if (inputMap != null) {
2092             ActionMap actionMap = getActionMap(true);
2093             ActionStandin action = new ActionStandin(anAction, aCommand);
2094             inputMap.put(aKeyStroke, action);
2095             if (actionMap != null) {
2096                 actionMap.put(action, action);
2097             }
2098         }
2099     }
2100 
2101     /**
2102      * Registers any bound <code>WHEN_IN_FOCUSED_WINDOW</code> actions with
2103      * the <code>KeyboardManager</code>. If <code>onlyIfNew</code>
2104      * is true only actions that haven't been registered are pushed
2105      * to the <code>KeyboardManager</code>;
2106      * otherwise all actions are pushed to the <code>KeyboardManager</code>.
2107      *
2108      * @param onlyIfNew  if true, only actions that haven't been registered
2109      *          are pushed to the <code>KeyboardManager</code>
2110      */
2111     private void registerWithKeyboardManager(boolean onlyIfNew) {
2112         InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW, false);
2113         KeyStroke[] strokes;
2114         Hashtable<KeyStroke, KeyStroke> registered =
2115                 (Hashtable<KeyStroke, KeyStroke>)getClientProperty
2116                                 (WHEN_IN_FOCUSED_WINDOW_BINDINGS);
2117 
2118         if (inputMap != null) {
2119             // Push any new KeyStrokes to the KeyboardManager.
2120             strokes = inputMap.allKeys();
2121             if (strokes != null) {
2122                 for (int counter = strokes.length - 1; counter >= 0;
2123                      counter--) {
2124                     if (!onlyIfNew || registered == null ||
2125                         registered.get(strokes[counter]) == null) {
2126                         registerWithKeyboardManager(strokes[counter]);
2127                     }
2128                     if (registered != null) {
2129                         registered.remove(strokes[counter]);
2130                     }
2131                 }
2132             }
2133         }
2134         else {
2135             strokes = null;
2136         }
2137         // Remove any old ones.
2138         if (registered != null && registered.size() > 0) {
2139             Enumeration<KeyStroke> keys = registered.keys();
2140 
2141             while (keys.hasMoreElements()) {
2142                 KeyStroke ks = keys.nextElement();
2143                 unregisterWithKeyboardManager(ks);
2144             }
registered.clear()2145             registered.clear();
2146         }
2147         // Updated the registered Hashtable.
2148         if (strokes != null && strokes.length > 0) {
2149             if (registered == null) {
2150                 registered = new Hashtable<KeyStroke, KeyStroke>(strokes.length);
putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, registered)2151                 putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, registered);
2152             }
2153             for (int counter = strokes.length - 1; counter >= 0; counter--) {
registered.put(strokes[counter], strokes[counter])2154                 registered.put(strokes[counter], strokes[counter]);
2155             }
2156         }
2157         else {
putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, null)2158             putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, null);
2159         }
2160     }
2161 
2162     /**
2163      * Unregisters all the previously registered
2164      * <code>WHEN_IN_FOCUSED_WINDOW</code> <code>KeyStroke</code> bindings.
2165      */
2166     private void unregisterWithKeyboardManager() {
2167         Hashtable<KeyStroke, KeyStroke> registered =
2168                 (Hashtable<KeyStroke, KeyStroke>)getClientProperty
2169                                 (WHEN_IN_FOCUSED_WINDOW_BINDINGS);
2170 
2171         if (registered != null && registered.size() > 0) {
2172             Enumeration<KeyStroke> keys = registered.keys();
2173 
2174             while (keys.hasMoreElements()) {
2175                 KeyStroke ks = keys.nextElement();
2176                 unregisterWithKeyboardManager(ks);
2177             }
2178         }
2179         putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, null);
2180     }
2181 
2182     /**
2183      * Invoked from <code>ComponentInputMap</code> when its bindings change.
2184      * If <code>inputMap</code> is the current <code>windowInputMap</code>
2185      * (or a parent of the window <code>InputMap</code>)
2186      * the <code>KeyboardManager</code> is notified of the new bindings.
2187      *
2188      * @param inputMap the map containing the new bindings
2189      */
2190     void componentInputMapChanged(ComponentInputMap inputMap) {
2191         InputMap km = getInputMap(WHEN_IN_FOCUSED_WINDOW, false);
2192 
2193         while (km != inputMap && km != null) {
2194             km = km.getParent();
2195         }
2196         if (km != null) {
2197             registerWithKeyboardManager(false);
2198         }
2199     }
2200 
2201     private void registerWithKeyboardManager(KeyStroke aKeyStroke) {
2202         KeyboardManager.getCurrentManager().registerKeyStroke(aKeyStroke,this);
2203     }
2204 
2205     private void unregisterWithKeyboardManager(KeyStroke aKeyStroke) {
2206         KeyboardManager.getCurrentManager().unregisterKeyStroke(aKeyStroke,
2207                                                                 this);
2208     }
2209 
2210     /**
2211      * This method is now obsolete, please use a combination of
2212      * <code>getActionMap()</code> and <code>getInputMap()</code> for
2213      * similar behavior.
2214      */
2215     public void registerKeyboardAction(ActionListener anAction,KeyStroke aKeyStroke,int aCondition) {
2216         registerKeyboardAction(anAction,null,aKeyStroke,aCondition);
2217     }
2218 
2219     /**
2220      * This method is now obsolete. To unregister an existing binding
2221      * you can either remove the binding from the
2222      * <code>ActionMap/InputMap</code>, or place a dummy binding the
2223      * <code>InputMap</code>. Removing the binding from the
2224      * <code>InputMap</code> allows bindings in parent <code>InputMap</code>s
2225      * to be active, whereas putting a dummy binding in the
2226      * <code>InputMap</code> effectively disables
2227      * the binding from ever happening.
2228      * <p>
2229      * Unregisters a keyboard action.
2230      * This will remove the binding from the <code>ActionMap</code>
2231      * (if it exists) as well as the <code>InputMap</code>s.
2232      */
2233     public void unregisterKeyboardAction(KeyStroke aKeyStroke) {
2234         ActionMap am = getActionMap(false);
2235         for (int counter = 0; counter < 3; counter++) {
2236             InputMap km = getInputMap(counter, false);
2237             if (km != null) {
2238                 Object actionID = km.get(aKeyStroke);
2239 
2240                 if (am != null && actionID != null) {
2241                     am.remove(actionID);
2242                 }
2243                 km.remove(aKeyStroke);
2244             }
2245         }
2246     }
2247 
2248     /**
2249      * Returns the <code>KeyStrokes</code> that will initiate
2250      * registered actions.
2251      *
2252      * @return an array of <code>KeyStroke</code> objects
2253      * @see #registerKeyboardAction
2254      */
2255     public KeyStroke[] getRegisteredKeyStrokes() {
2256         int[] counts = new int[3];
2257         KeyStroke[][] strokes = new KeyStroke[3][];
2258 
2259         for (int counter = 0; counter < 3; counter++) {
2260             InputMap km = getInputMap(counter, false);
2261             strokes[counter] = (km != null) ? km.allKeys() : null;
2262             counts[counter] = (strokes[counter] != null) ?
2263                                strokes[counter].length : 0;
2264         }
2265         KeyStroke[] retValue = new KeyStroke[counts[0] + counts[1] +
2266                                             counts[2]];
2267         for (int counter = 0, last = 0; counter < 3; counter++) {
2268             if (counts[counter] > 0) {
2269                 System.arraycopy(strokes[counter], 0, retValue, last,
2270                                  counts[counter]);
2271                 last += counts[counter];
2272             }
2273         }
2274         return retValue;
2275     }
2276 
2277     /**
2278      * Returns the condition that determines whether a registered action
2279      * occurs in response to the specified keystroke.
2280      * <p>
2281      * For Java 2 platform v1.3, a <code>KeyStroke</code> can be associated
2282      * with more than one condition.
2283      * For example, 'a' could be bound for the two
2284      * conditions <code>WHEN_FOCUSED</code> and
2285      * <code>WHEN_IN_FOCUSED_WINDOW</code> condition.
2286      *
2287      * @return the action-keystroke condition
2288      */
2289     public int getConditionForKeyStroke(KeyStroke aKeyStroke) {
2290         for (int counter = 0; counter < 3; counter++) {
2291             InputMap inputMap = getInputMap(counter, false);
2292             if (inputMap != null && inputMap.get(aKeyStroke) != null) {
2293                 return counter;
2294             }
2295         }
2296         return UNDEFINED_CONDITION;
2297     }
2298 
2299     /**
2300      * Returns the object that will perform the action registered for a
2301      * given keystroke.
2302      *
2303      * @return the <code>ActionListener</code>
2304      *          object invoked when the keystroke occurs
2305      */
2306     public ActionListener getActionForKeyStroke(KeyStroke aKeyStroke) {
2307         ActionMap am = getActionMap(false);
2308 
2309         if (am == null) {
2310             return null;
2311         }
2312         for (int counter = 0; counter < 3; counter++) {
2313             InputMap inputMap = getInputMap(counter, false);
2314             if (inputMap != null) {
2315                 Object actionBinding = inputMap.get(aKeyStroke);
2316 
2317                 if (actionBinding != null) {
2318                     Action action = am.get(actionBinding);
2319                     if (action instanceof ActionStandin) {
2320                         return ((ActionStandin)action).actionListener;
2321                     }
2322                     return action;
2323                 }
2324             }
2325         }
2326         return null;
2327     }
2328 
2329     /**
2330      * Unregisters all the bindings in the first tier <code>InputMaps</code>
2331      * and <code>ActionMap</code>. This has the effect of removing any
2332      * local bindings, and allowing the bindings defined in parent
2333      * <code>InputMap/ActionMaps</code>
2334      * (the UI is usually defined in the second tier) to persist.
2335      */
2336     public void resetKeyboardActions() {
2337         // Keys
2338         for (int counter = 0; counter < 3; counter++) {
2339             InputMap inputMap = getInputMap(counter, false);
2340 
2341             if (inputMap != null) {
2342                 inputMap.clear();
2343             }
2344         }
2345 
2346         // Actions
2347         ActionMap am = getActionMap(false);
2348 
2349         if (am != null) {
2350             am.clear();
2351         }
2352     }
2353 
2354     /**
2355      * Sets the <code>InputMap</code> to use under the condition
2356      * <code>condition</code> to
2357      * <code>map</code>. A <code>null</code> value implies you
2358      * do not want any bindings to be used, even from the UI. This will
2359      * not reinstall the UI <code>InputMap</code> (if there was one).
2360      * <code>condition</code> has one of the following values:
2361      * <ul>
2362      * <li><code>WHEN_IN_FOCUSED_WINDOW</code>
2363      * <li><code>WHEN_FOCUSED</code>
2364      * <li><code>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT</code>
2365      * </ul>
2366      * If <code>condition</code> is <code>WHEN_IN_FOCUSED_WINDOW</code>
2367      * and <code>map</code> is not a <code>ComponentInputMap</code>, an
2368      * <code>IllegalArgumentException</code> will be thrown.
2369      * Similarly, if <code>condition</code> is not one of the values
2370      * listed, an <code>IllegalArgumentException</code> will be thrown.
2371      *
2372      * @param condition one of the values listed above
2373      * @param map  the <code>InputMap</code> to use for the given condition
2374      * @exception IllegalArgumentException if <code>condition</code> is
2375      *          <code>WHEN_IN_FOCUSED_WINDOW</code> and <code>map</code>
2376      *          is not an instance of <code>ComponentInputMap</code>; or
2377      *          if <code>condition</code> is not one of the legal values
2378      *          specified above
2379      * @since 1.3
2380      */
2381     public final void setInputMap(int condition, InputMap map) {
2382         switch (condition) {
2383         case WHEN_IN_FOCUSED_WINDOW:
2384             if (map != null && !(map instanceof ComponentInputMap)) {
2385                 throw new IllegalArgumentException("WHEN_IN_FOCUSED_WINDOW InputMaps must be of type ComponentInputMap");
2386             }
2387             windowInputMap = (ComponentInputMap)map;
2388             setFlag(WIF_INPUTMAP_CREATED, true);
2389             registerWithKeyboardManager(false);
2390             break;
2391         case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
2392             ancestorInputMap = map;
2393             setFlag(ANCESTOR_INPUTMAP_CREATED, true);
2394             break;
2395         case WHEN_FOCUSED:
2396             focusInputMap = map;
2397             setFlag(FOCUS_INPUTMAP_CREATED, true);
2398             break;
2399         default:
2400             throw new IllegalArgumentException("condition must be one of JComponent.WHEN_IN_FOCUSED_WINDOW, JComponent.WHEN_FOCUSED or JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT");
2401         }
2402     }
2403 
2404     /**
2405      * Returns the <code>InputMap</code> that is used during
2406      * <code>condition</code>.
2407      *
2408      * @param condition one of WHEN_IN_FOCUSED_WINDOW, WHEN_FOCUSED,
2409      *        WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
2410      * @return the <code>InputMap</code> for the specified
2411      *          <code>condition</code>
2412      * @since 1.3
2413      */
2414     public final InputMap getInputMap(int condition) {
2415         return getInputMap(condition, true);
2416     }
2417 
2418     /**
2419      * Returns the <code>InputMap</code> that is used when the
2420      * component has focus.
2421      * This is convenience method for <code>getInputMap(WHEN_FOCUSED)</code>.
2422      *
2423      * @return the <code>InputMap</code> used when the component has focus
2424      * @since 1.3
2425      */
2426     public final InputMap getInputMap() {
2427         return getInputMap(WHEN_FOCUSED, true);
2428     }
2429 
2430     /**
2431      * Sets the <code>ActionMap</code> to <code>am</code>. This does not set
2432      * the parent of the <code>am</code> to be the <code>ActionMap</code>
2433      * from the UI (if there was one), it is up to the caller to have done this.
2434      *
2435      * @param am  the new <code>ActionMap</code>
2436      * @since 1.3
2437      */
2438     public final void setActionMap(ActionMap am) {
2439         actionMap = am;
2440         setFlag(ACTIONMAP_CREATED, true);
2441     }
2442 
2443     /**
2444      * Returns the <code>ActionMap</code> used to determine what
2445      * <code>Action</code> to fire for particular <code>KeyStroke</code>
2446      * binding. The returned <code>ActionMap</code>, unless otherwise
2447      * set, will have the <code>ActionMap</code> from the UI set as the parent.
2448      *
2449      * @return the <code>ActionMap</code> containing the key/action bindings
2450      * @since 1.3
2451      */
2452     public final ActionMap getActionMap() {
2453         return getActionMap(true);
2454     }
2455 
2456     /**
2457      * Returns the <code>InputMap</code> to use for condition
2458      * <code>condition</code>.  If the <code>InputMap</code> hasn't
2459      * been created, and <code>create</code> is
2460      * true, it will be created.
2461      *
2462      * @param condition one of the following values:
2463      * <ul>
2464      * <li>JComponent.FOCUS_INPUTMAP_CREATED
2465      * <li>JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
2466      * <li>JComponent.WHEN_IN_FOCUSED_WINDOW
2467      * </ul>
2468      * @param create if true, create the <code>InputMap</code> if it
2469      *          is not already created
2470      * @return the <code>InputMap</code> for the given <code>condition</code>;
2471      *          if <code>create</code> is false and the <code>InputMap</code>
2472      *          hasn't been created, returns <code>null</code>
2473      * @exception IllegalArgumentException if <code>condition</code>
2474      *          is not one of the legal values listed above
2475      */
2476     final InputMap getInputMap(int condition, boolean create) {
2477         switch (condition) {
2478         case WHEN_FOCUSED:
2479             if (getFlag(FOCUS_INPUTMAP_CREATED)) {
2480                 return focusInputMap;
2481             }
2482             // Hasn't been created yet.
2483             if (create) {
2484                 InputMap km = new InputMap();
2485                 setInputMap(condition, km);
2486                 return km;
2487             }
2488             break;
2489         case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
2490             if (getFlag(ANCESTOR_INPUTMAP_CREATED)) {
2491                 return ancestorInputMap;
2492             }
2493             // Hasn't been created yet.
2494             if (create) {
2495                 InputMap km = new InputMap();
2496                 setInputMap(condition, km);
2497                 return km;
2498             }
2499             break;
2500         case WHEN_IN_FOCUSED_WINDOW:
2501             if (getFlag(WIF_INPUTMAP_CREATED)) {
2502                 return windowInputMap;
2503             }
2504             // Hasn't been created yet.
2505             if (create) {
2506                 ComponentInputMap km = new ComponentInputMap(this);
2507                 setInputMap(condition, km);
2508                 return km;
2509             }
2510             break;
2511         default:
2512             throw new IllegalArgumentException("condition must be one of JComponent.WHEN_IN_FOCUSED_WINDOW, JComponent.WHEN_FOCUSED or JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT");
2513         }
2514         return null;
2515     }
2516 
2517     /**
2518      * Finds and returns the appropriate <code>ActionMap</code>.
2519      *
2520      * @param create if true, create the <code>ActionMap</code> if it
2521      *          is not already created
2522      * @return the <code>ActionMap</code> for this component; if the
2523      *          <code>create</code> flag is false and there is no
2524      *          current <code>ActionMap</code>, returns <code>null</code>
2525      */
2526     final ActionMap getActionMap(boolean create) {
2527         if (getFlag(ACTIONMAP_CREATED)) {
2528             return actionMap;
2529         }
2530         // Hasn't been created.
2531         if (create) {
2532             ActionMap am = new ActionMap();
2533             setActionMap(am);
2534             return am;
2535         }
2536         return null;
2537     }
2538 
2539     /**
2540      * Returns the baseline.  The baseline is measured from the top of
2541      * the component.  This method is primarily meant for
2542      * <code>LayoutManager</code>s to align components along their
2543      * baseline.  A return value less than 0 indicates this component
2544      * does not have a reasonable baseline and that
2545      * <code>LayoutManager</code>s should not align this component on
2546      * its baseline.
2547      * <p>
2548      * This method calls into the <code>ComponentUI</code> method of the
2549      * same name.  If this component does not have a <code>ComponentUI</code>
2550      * -1 will be returned.  If a value &gt;= 0 is
2551      * returned, then the component has a valid baseline for any
2552      * size &gt;= the minimum size and <code>getBaselineResizeBehavior</code>
2553      * can be used to determine how the baseline changes with size.
2554      *
2555      * @throws IllegalArgumentException {@inheritDoc}
2556      * @see #getBaselineResizeBehavior
2557      * @see java.awt.FontMetrics
2558      * @since 1.6
2559      */
2560     public int getBaseline(int width, int height) {
2561         // check size.
2562         super.getBaseline(width, height);
2563         if (ui != null) {
2564             return ui.getBaseline(this, width, height);
2565         }
2566         return -1;
2567     }
2568 
2569     /**
2570      * Returns an enum indicating how the baseline of the component
2571      * changes as the size changes.  This method is primarily meant for
2572      * layout managers and GUI builders.
2573      * <p>
2574      * This method calls into the <code>ComponentUI</code> method of
2575      * the same name.  If this component does not have a
2576      * <code>ComponentUI</code>
2577      * <code>BaselineResizeBehavior.OTHER</code> will be
2578      * returned.  Subclasses should
2579      * never return <code>null</code>; if the baseline can not be
2580      * calculated return <code>BaselineResizeBehavior.OTHER</code>.  Callers
2581      * should first ask for the baseline using
2582      * <code>getBaseline</code> and if a value &gt;= 0 is returned use
2583      * this method.  It is acceptable for this method to return a
2584      * value other than <code>BaselineResizeBehavior.OTHER</code> even if
2585      * <code>getBaseline</code> returns a value less than 0.
2586      *
2587      * @see #getBaseline(int, int)
2588      * @since 1.6
2589      */
2590     public BaselineResizeBehavior getBaselineResizeBehavior() {
2591         if (ui != null) {
2592             return ui.getBaselineResizeBehavior(this);
2593         }
2594         return BaselineResizeBehavior.OTHER;
2595     }
2596 
2597     /**
2598      * In release 1.4, the focus subsystem was rearchitected.
2599      * For more information, see
2600      * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
2601      * How to Use the Focus Subsystem</a>,
2602      * a section in <em>The Java Tutorial</em>.
2603      * <p>
2604      * Requests focus on this <code>JComponent</code>'s
2605      * <code>FocusTraversalPolicy</code>'s default <code>Component</code>.
2606      * If this <code>JComponent</code> is a focus cycle root, then its
2607      * <code>FocusTraversalPolicy</code> is used. Otherwise, the
2608      * <code>FocusTraversalPolicy</code> of this <code>JComponent</code>'s
2609      * focus-cycle-root ancestor is used.
2610      *
2611      * @see java.awt.FocusTraversalPolicy#getDefaultComponent
2612      * @deprecated As of 1.4, replaced by
2613      * <code>FocusTraversalPolicy.getDefaultComponent(Container).requestFocus()</code>
2614      */
2615     @Deprecated
2616     public boolean requestDefaultFocus() {
2617         Container nearestRoot =
2618             (isFocusCycleRoot()) ? this : getFocusCycleRootAncestor();
2619         if (nearestRoot == null) {
2620             return false;
2621         }
2622         Component comp = nearestRoot.getFocusTraversalPolicy().
2623             getDefaultComponent(nearestRoot);
2624         if (comp != null) {
2625             comp.requestFocus();
2626             return true;
2627         } else {
2628             return false;
2629         }
2630     }
2631 
2632     /**
2633      * Makes the component visible or invisible.
2634      * Overrides <code>Component.setVisible</code>.
2635      *
2636      * @param aFlag  true to make the component visible; false to
2637      *          make it invisible
2638      *
2639      * @beaninfo
2640      *    attribute: visualUpdate true
2641      */
2642     public void setVisible(boolean aFlag) {
2643         if (aFlag != isVisible()) {
2644             super.setVisible(aFlag);
2645             if (aFlag) {
2646                 Container parent = getParent();
2647                 if (parent != null) {
2648                     Rectangle r = getBounds();
2649                     parent.repaint(r.x, r.y, r.width, r.height);
2650                 }
2651                 revalidate();
2652             }
2653         }
2654     }
2655 
2656     /**
2657      * Sets whether or not this component is enabled.
2658      * A component that is enabled may respond to user input,
2659      * while a component that is not enabled cannot respond to
2660      * user input.  Some components may alter their visual
2661      * representation when they are disabled in order to
2662      * provide feedback to the user that they cannot take input.
2663      * <p>Note: Disabling a component does not disable its children.
2664      *
2665      * <p>Note: Disabling a lightweight component does not prevent it from
2666      * receiving MouseEvents.
2667      *
2668      * @param enabled true if this component should be enabled, false otherwise
2669      * @see java.awt.Component#isEnabled
2670      * @see java.awt.Component#isLightweight
2671      *
2672      * @beaninfo
2673      *    preferred: true
2674      *        bound: true
2675      *    attribute: visualUpdate true
2676      *  description: The enabled state of the component.
2677      */
2678     public void setEnabled(boolean enabled) {
2679         boolean oldEnabled = isEnabled();
2680         super.setEnabled(enabled);
2681         firePropertyChange("enabled", oldEnabled, enabled);
2682         if (enabled != oldEnabled) {
2683             repaint();
2684         }
2685     }
2686 
2687     /**
2688      * Sets the foreground color of this component.  It is up to the
2689      * look and feel to honor this property, some may choose to ignore
2690      * it.
2691      *
2692      * @param fg  the desired foreground <code>Color</code>
2693      * @see java.awt.Component#getForeground
2694      *
2695      * @beaninfo
2696      *    preferred: true
2697      *        bound: true
2698      *    attribute: visualUpdate true
2699      *  description: The foreground color of the component.
2700      */
2701     public void setForeground(Color fg) {
2702         Color oldFg = getForeground();
2703         super.setForeground(fg);
2704         if ((oldFg != null) ? !oldFg.equals(fg) : ((fg != null) && !fg.equals(oldFg))) {
2705             // foreground already bound in AWT1.2
2706             repaint();
2707         }
2708     }
2709 
2710     /**
2711      * Sets the background color of this component.  The background
2712      * color is used only if the component is opaque, and only
2713      * by subclasses of <code>JComponent</code> or
2714      * <code>ComponentUI</code> implementations.  Direct subclasses of
2715      * <code>JComponent</code> must override
2716      * <code>paintComponent</code> to honor this property.
2717      * <p>
2718      * It is up to the look and feel to honor this property, some may
2719      * choose to ignore it.
2720      *
2721      * @param bg the desired background <code>Color</code>
2722      * @see java.awt.Component#getBackground
2723      * @see #setOpaque
2724      *
2725      * @beaninfo
2726      *    preferred: true
2727      *        bound: true
2728      *    attribute: visualUpdate true
2729      *  description: The background color of the component.
2730      */
2731     public void setBackground(Color bg) {
2732         Color oldBg = getBackground();
2733         super.setBackground(bg);
2734         if ((oldBg != null) ? !oldBg.equals(bg) : ((bg != null) && !bg.equals(oldBg))) {
2735             // background already bound in AWT1.2
2736             repaint();
2737         }
2738     }
2739 
2740     /**
2741      * Sets the font for this component.
2742      *
2743      * @param font the desired <code>Font</code> for this component
2744      * @see java.awt.Component#getFont
2745      *
2746      * @beaninfo
2747      *    preferred: true
2748      *        bound: true
2749      *    attribute: visualUpdate true
2750      *  description: The font for the component.
2751      */
2752     public void setFont(Font font) {
2753         Font oldFont = getFont();
2754         super.setFont(font);
2755         // font already bound in AWT1.2
2756         if (font != oldFont) {
2757             revalidate();
2758             repaint();
2759         }
2760     }
2761 
2762     /**
2763      * Returns the default locale used to initialize each JComponent's
2764      * locale property upon creation.
2765      *
2766      * The default locale has "AppContext" scope so that applets (and
2767      * potentially multiple lightweight applications running in a single VM)
2768      * can have their own setting. An applet can safely alter its default
2769      * locale because it will have no affect on other applets (or the browser).
2770      *
2771      * @return the default <code>Locale</code>.
2772      * @see #setDefaultLocale
2773      * @see java.awt.Component#getLocale
2774      * @see #setLocale
2775      * @since 1.4
2776      */
2777     static public Locale getDefaultLocale() {
2778         Locale l = (Locale) SwingUtilities.appContextGet(defaultLocale);
2779         if( l == null ) {
2780             //REMIND(bcb) choosing the default value is more complicated
2781             //than this.
2782             l = Locale.getDefault();
2783             JComponent.setDefaultLocale( l );
2784         }
2785         return l;
2786     }
2787 
2788 
2789     /**
2790      * Sets the default locale used to initialize each JComponent's locale
2791      * property upon creation.  The initial value is the VM's default locale.
2792      *
2793      * The default locale has "AppContext" scope so that applets (and
2794      * potentially multiple lightweight applications running in a single VM)
2795      * can have their own setting. An applet can safely alter its default
2796      * locale because it will have no affect on other applets (or the browser).
2797      *
2798      * @param l the desired default <code>Locale</code> for new components.
2799      * @see #getDefaultLocale
2800      * @see java.awt.Component#getLocale
2801      * @see #setLocale
2802      * @since 1.4
2803      */
2804     static public void setDefaultLocale( Locale l ) {
2805         SwingUtilities.appContextPut(defaultLocale, l);
2806     }
2807 
2808 
2809     /**
2810      * Processes any key events that the component itself
2811      * recognizes.  This is called after the focus
2812      * manager and any interested listeners have been
2813      * given a chance to steal away the event.  This
2814      * method is called only if the event has not
2815      * yet been consumed.  This method is called prior
2816      * to the keyboard UI logic.
2817      * <p>
2818      * This method is implemented to do nothing.  Subclasses would
2819      * normally override this method if they process some
2820      * key events themselves.  If the event is processed,
2821      * it should be consumed.
2822      */
2823     protected void processComponentKeyEvent(KeyEvent e) {
2824     }
2825 
2826     /** Overrides <code>processKeyEvent</code> to process events. **/
2827     protected void processKeyEvent(KeyEvent e) {
2828       boolean result;
2829       boolean shouldProcessKey;
2830 
2831       // This gives the key event listeners a crack at the event
2832       super.processKeyEvent(e);
2833 
2834       // give the component itself a crack at the event
2835       if (! e.isConsumed()) {
2836           processComponentKeyEvent(e);
2837       }
2838 
2839       shouldProcessKey = KeyboardState.shouldProcess(e);
2840 
2841       if(e.isConsumed()) {
2842         return;
2843       }
2844 
2845       if (shouldProcessKey && processKeyBindings(e, e.getID() ==
2846                                                  KeyEvent.KEY_PRESSED)) {
2847           e.consume();
2848       }
2849     }
2850 
2851     /**
2852      * Invoked to process the key bindings for <code>ks</code> as the result
2853      * of the <code>KeyEvent</code> <code>e</code>. This obtains
2854      * the appropriate <code>InputMap</code>,
2855      * gets the binding, gets the action from the <code>ActionMap</code>,
2856      * and then (if the action is found and the component
2857      * is enabled) invokes <code>notifyAction</code> to notify the action.
2858      *
2859      * @param ks  the <code>KeyStroke</code> queried
2860      * @param e the <code>KeyEvent</code>
2861      * @param condition one of the following values:
2862      * <ul>
2863      * <li>JComponent.WHEN_FOCUSED
2864      * <li>JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
2865      * <li>JComponent.WHEN_IN_FOCUSED_WINDOW
2866      * </ul>
2867      * @param pressed true if the key is pressed
2868      * @return true if there was a binding to an action, and the action
2869      *         was enabled
2870      *
2871      * @since 1.3
2872      */
2873     protected boolean processKeyBinding(KeyStroke ks, KeyEvent e,
2874                                         int condition, boolean pressed) {
2875         InputMap map = getInputMap(condition, false);
2876         ActionMap am = getActionMap(false);
2877 
2878         if(map != null && am != null && isEnabled()) {
2879             Object binding = map.get(ks);
2880             Action action = (binding == null) ? null : am.get(binding);
2881             if (action != null) {
2882                 return SwingUtilities.notifyAction(action, ks, e, this,
2883                                                    e.getModifiers());
2884             }
2885         }
2886         return false;
2887     }
2888 
2889     /**
2890      * This is invoked as the result of a <code>KeyEvent</code>
2891      * that was not consumed by the <code>FocusManager</code>,
2892      * <code>KeyListeners</code>, or the component. It will first try
2893      * <code>WHEN_FOCUSED</code> bindings,
2894      * then <code>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT</code> bindings,
2895      * and finally <code>WHEN_IN_FOCUSED_WINDOW</code> bindings.
2896      *
2897      * @param e the unconsumed <code>KeyEvent</code>
2898      * @param pressed true if the key is pressed
2899      * @return true if there is a key binding for <code>e</code>
2900      */
2901     boolean processKeyBindings(KeyEvent e, boolean pressed) {
2902       if (!SwingUtilities.isValidKeyEventForKeyBindings(e)) {
2903           return false;
2904       }
2905       // Get the KeyStroke
2906       // There may be two keystrokes associated with a low-level key event;
2907       // in this case a keystroke made of an extended key code has a priority.
2908       KeyStroke ks;
2909       KeyStroke ksE = null;
2910 
2911       if (e.getID() == KeyEvent.KEY_TYPED) {
2912           ks = KeyStroke.getKeyStroke(e.getKeyChar());
2913       }
2914       else {
2915           ks = KeyStroke.getKeyStroke(e.getKeyCode(),e.getModifiers(),
2916                                     (pressed ? false:true));
2917           if (e.getKeyCode() != e.getExtendedKeyCode()) {
2918               ksE = KeyStroke.getKeyStroke(e.getExtendedKeyCode(),e.getModifiers(),
2919                                     (pressed ? false:true));
2920           }
2921       }
2922 
2923       // Do we have a key binding for e?
2924       // If we have a binding by an extended code, use it.
2925       // If not, check for regular code binding.
2926       if(ksE != null && processKeyBinding(ksE, e, WHEN_FOCUSED, pressed)) {
2927           return true;
2928       }
2929       if(processKeyBinding(ks, e, WHEN_FOCUSED, pressed))
2930           return true;
2931 
2932       /* We have no key binding. Let's try the path from our parent to the
2933        * window excluded. We store the path components so we can avoid
2934        * asking the same component twice.
2935        */
2936       Container parent = this;
2937       while (parent != null && !(parent instanceof Window) &&
2938              !(parent instanceof Applet)) {
2939           if(parent instanceof JComponent) {
2940               if(ksE != null && ((JComponent)parent).processKeyBinding(ksE, e,
2941                                WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed))
2942                   return true;
2943               if(((JComponent)parent).processKeyBinding(ks, e,
2944                                WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed))
2945                   return true;
2946           }
2947           // This is done so that the children of a JInternalFrame are
2948           // given precedence for WHEN_IN_FOCUSED_WINDOW bindings before
2949           // other components WHEN_IN_FOCUSED_WINDOW bindings. This also gives
2950           // more precedence to the WHEN_IN_FOCUSED_WINDOW bindings of the
2951           // JInternalFrame's children vs the
2952           // WHEN_ANCESTOR_OF_FOCUSED_COMPONENT bindings of the parents.
2953           // maybe generalize from JInternalFrame (like isFocusCycleRoot).
2954           if ((parent instanceof JInternalFrame) &&
2955               JComponent.processKeyBindingsForAllComponents(e,parent,pressed)){
2956               return true;
2957           }
2958           parent = parent.getParent();
2959       }
2960 
2961       /* No components between the focused component and the window is
2962        * actually interested by the key event. Let's try the other
2963        * JComponent in this window.
2964        */
2965       if(parent != null) {
2966         return JComponent.processKeyBindingsForAllComponents(e,parent,pressed);
2967       }
2968       return false;
2969     }
2970 
2971     static boolean processKeyBindingsForAllComponents(KeyEvent e,
2972                                       Container container, boolean pressed) {
2973         while (true) {
2974             if (KeyboardManager.getCurrentManager().fireKeyboardAction(
2975                                 e, pressed, container)) {
2976                 return true;
2977             }
2978             if (container instanceof Popup.HeavyWeightWindow) {
2979                 container = ((Window)container).getOwner();
2980             }
2981             else {
2982                 return false;
2983             }
2984         }
2985     }
2986 
2987     /**
2988      * Registers the text to display in a tool tip.
2989      * The text displays when the cursor lingers over the component.
2990      * <p>
2991      * See <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/tooltip.html">How to Use Tool Tips</a>
2992      * in <em>The Java Tutorial</em>
2993      * for further documentation.
2994      *
2995      * @param text  the string to display; if the text is <code>null</code>,
2996      *              the tool tip is turned off for this component
2997      * @see #TOOL_TIP_TEXT_KEY
2998      * @beaninfo
2999      *   preferred: true
3000      * description: The text to display in a tool tip.
3001      */
3002     public void setToolTipText(String text) {
3003         String oldText = getToolTipText();
3004         putClientProperty(TOOL_TIP_TEXT_KEY, text);
3005         ToolTipManager toolTipManager = ToolTipManager.sharedInstance();
3006         if (text != null) {
3007             if (oldText == null) {
3008                 toolTipManager.registerComponent(this);
3009             }
3010         } else {
3011             toolTipManager.unregisterComponent(this);
3012         }
3013     }
3014 
3015     /**
3016      * Returns the tooltip string that has been set with
3017      * <code>setToolTipText</code>.
3018      *
3019      * @return the text of the tool tip
3020      * @see #TOOL_TIP_TEXT_KEY
3021      */
3022     public String getToolTipText() {
3023         return (String)getClientProperty(TOOL_TIP_TEXT_KEY);
3024     }
3025 
3026 
3027     /**
3028      * Returns the string to be used as the tooltip for <i>event</i>.
3029      * By default this returns any string set using
3030      * <code>setToolTipText</code>.  If a component provides
3031      * more extensive API to support differing tooltips at different locations,
3032      * this method should be overridden.
3033      */
3034     public String getToolTipText(MouseEvent event) {
3035         return getToolTipText();
3036     }
3037 
3038     /**
3039      * Returns the tooltip location in this component's coordinate system.
3040      * If <code>null</code> is returned, Swing will choose a location.
3041      * The default implementation returns <code>null</code>.
3042      *
3043      * @param event  the <code>MouseEvent</code> that caused the
3044      *          <code>ToolTipManager</code> to show the tooltip
3045      * @return always returns <code>null</code>
3046      */
3047     public Point getToolTipLocation(MouseEvent event) {
3048         return null;
3049     }
3050 
3051     /**
3052      * Returns the preferred location to display the popup menu in this
3053      * component's coordinate system. It is up to the look and feel to
3054      * honor this property, some may choose to ignore it.
3055      * If {@code null}, the look and feel will choose a suitable location.
3056      *
3057      * @param event the {@code MouseEvent} that triggered the popup to be
3058      *        shown, or {@code null} if the popup is not being shown as the
3059      *        result of a mouse event
3060      * @return location to display the {@code JPopupMenu}, or {@code null}
3061      * @since 1.5
3062      */
3063     public Point getPopupLocation(MouseEvent event) {
3064         return null;
3065     }
3066 
3067 
3068     /**
3069      * Returns the instance of <code>JToolTip</code> that should be used
3070      * to display the tooltip.
3071      * Components typically would not override this method,
3072      * but it can be used to
3073      * cause different tooltips to be displayed differently.
3074      *
3075      * @return the <code>JToolTip</code> used to display this toolTip
3076      */
3077     public JToolTip createToolTip() {
3078         JToolTip tip = new JToolTip();
3079         tip.setComponent(this);
3080         return tip;
3081     }
3082 
3083     /**
3084      * Forwards the <code>scrollRectToVisible()</code> message to the
3085      * <code>JComponent</code>'s parent. Components that can service
3086      * the request, such as <code>JViewport</code>,
3087      * override this method and perform the scrolling.
3088      *
3089      * @param aRect the visible <code>Rectangle</code>
3090      * @see JViewport
3091      */
3092     public void scrollRectToVisible(Rectangle aRect) {
3093         Container parent;
3094         int dx = getX(), dy = getY();
3095 
3096         for (parent = getParent();
3097                  !(parent == null) &&
3098                  !(parent instanceof JComponent) &&
3099                  !(parent instanceof CellRendererPane);
3100              parent = parent.getParent()) {
3101              Rectangle bounds = parent.getBounds();
3102 
3103              dx += bounds.x;
3104              dy += bounds.y;
3105         }
3106 
3107         if (!(parent == null) && !(parent instanceof CellRendererPane)) {
3108             aRect.x += dx;
3109             aRect.y += dy;
3110 
3111             ((JComponent)parent).scrollRectToVisible(aRect);
3112             aRect.x -= dx;
3113             aRect.y -= dy;
3114         }
3115     }
3116 
3117     /**
3118      * Sets the <code>autoscrolls</code> property.
3119      * If <code>true</code> mouse dragged events will be
3120      * synthetically generated when the mouse is dragged
3121      * outside of the component's bounds and mouse motion
3122      * has paused (while the button continues to be held
3123      * down). The synthetic events make it appear that the
3124      * drag gesture has resumed in the direction established when
3125      * the component's boundary was crossed.  Components that
3126      * support autoscrolling must handle <code>mouseDragged</code>
3127      * events by calling <code>scrollRectToVisible</code> with a
3128      * rectangle that contains the mouse event's location.  All of
3129      * the Swing components that support item selection and are
3130      * typically displayed in a <code>JScrollPane</code>
3131      * (<code>JTable</code>, <code>JList</code>, <code>JTree</code>,
3132      * <code>JTextArea</code>, and <code>JEditorPane</code>)
3133      * already handle mouse dragged events in this way.  To enable
3134      * autoscrolling in any other component, add a mouse motion
3135      * listener that calls <code>scrollRectToVisible</code>.
3136      * For example, given a <code>JPanel</code>, <code>myPanel</code>:
3137      * <pre>
3138      * MouseMotionListener doScrollRectToVisible = new MouseMotionAdapter() {
3139      *     public void mouseDragged(MouseEvent e) {
3140      *        Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1);
3141      *        ((JPanel)e.getSource()).scrollRectToVisible(r);
3142      *    }
3143      * };
3144      * myPanel.addMouseMotionListener(doScrollRectToVisible);
3145      * </pre>
3146      * The default value of the <code>autoScrolls</code>
3147      * property is <code>false</code>.
3148      *
3149      * @param autoscrolls if true, synthetic mouse dragged events
3150      *   are generated when the mouse is dragged outside of a component's
3151      *   bounds and the mouse button continues to be held down; otherwise
3152      *   false
3153      * @see #getAutoscrolls
3154      * @see JViewport
3155      * @see JScrollPane
3156      *
3157      * @beaninfo
3158      *      expert: true
3159      * description: Determines if this component automatically scrolls its contents when dragged.
3160      */
3161     public void setAutoscrolls(boolean autoscrolls) {
3162         setFlag(AUTOSCROLLS_SET, true);
3163         if (this.autoscrolls != autoscrolls) {
3164             this.autoscrolls = autoscrolls;
3165             if (autoscrolls) {
3166                 enableEvents(AWTEvent.MOUSE_EVENT_MASK);
3167                 enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
3168             }
3169             else {
3170                 Autoscroller.stop(this);
3171             }
3172         }
3173     }
3174 
3175     /**
3176      * Gets the <code>autoscrolls</code> property.
3177      *
3178      * @return the value of the <code>autoscrolls</code> property
3179      * @see JViewport
3180      * @see #setAutoscrolls
3181      */
3182     public boolean getAutoscrolls() {
3183         return autoscrolls;
3184     }
3185 
3186     /**
3187      * Sets the {@code TransferHandler}, which provides support for transfer
3188      * of data into and out of this component via cut/copy/paste and drag
3189      * and drop. This may be {@code null} if the component does not support
3190      * data transfer operations.
3191      * <p>
3192      * If the new {@code TransferHandler} is not {@code null}, this method
3193      * also installs a <b>new</b> {@code DropTarget} on the component to
3194      * activate drop handling through the {@code TransferHandler} and activate
3195      * any built-in support (such as calculating and displaying potential drop
3196      * locations). If you do not wish for this component to respond in any way
3197      * to drops, you can disable drop support entirely either by removing the
3198      * drop target ({@code setDropTarget(null)}) or by de-activating it
3199      * ({@code getDropTaget().setActive(false)}).
3200      * <p>
3201      * If the new {@code TransferHandler} is {@code null}, this method removes
3202      * the drop target.
3203      * <p>
3204      * Under two circumstances, this method does not modify the drop target:
3205      * First, if the existing drop target on this component was explicitly
3206      * set by the developer to a {@code non-null} value. Second, if the
3207      * system property {@code suppressSwingDropSupport} is {@code true}. The
3208      * default value for the system property is {@code false}.
3209      * <p>
3210      * Please see
3211      * <a href="https://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
3212      * How to Use Drag and Drop and Data Transfer</a>,
3213      * a section in <em>The Java Tutorial</em>, for more information.
3214      *
3215      * @param newHandler the new {@code TransferHandler}
3216      *
3217      * @see TransferHandler
3218      * @see #getTransferHandler
3219      * @since 1.4
3220      * @beaninfo
3221      *        bound: true
3222      *       hidden: true
3223      *  description: Mechanism for transfer of data to and from the component
3224      */
3225     public void setTransferHandler(TransferHandler newHandler) {
3226         TransferHandler oldHandler = (TransferHandler)getClientProperty(
3227                                       JComponent_TRANSFER_HANDLER);
3228         putClientProperty(JComponent_TRANSFER_HANDLER, newHandler);
3229 
3230         SwingUtilities.installSwingDropTargetAsNecessary(this, newHandler);
3231         firePropertyChange("transferHandler", oldHandler, newHandler);
3232     }
3233 
3234     /**
3235      * Gets the <code>transferHandler</code> property.
3236      *
3237      * @return  the value of the <code>transferHandler</code> property
3238      *
3239      * @see TransferHandler
3240      * @see #setTransferHandler
3241      * @since 1.4
3242      */
3243     public TransferHandler getTransferHandler() {
3244         return (TransferHandler)getClientProperty(JComponent_TRANSFER_HANDLER);
3245     }
3246 
3247     /**
3248      * Calculates a custom drop location for this type of component,
3249      * representing where a drop at the given point should insert data.
3250      * <code>null</code> is returned if this component doesn't calculate
3251      * custom drop locations. In this case, <code>TransferHandler</code>
3252      * will provide a default <code>DropLocation</code> containing just
3253      * the point.
3254      *
3255      * @param p the point to calculate a drop location for
3256      * @return the drop location, or <code>null</code>
3257      */
3258     TransferHandler.DropLocation dropLocationForPoint(Point p) {
3259         return null;
3260     }
3261 
3262     /**
3263      * Called to set or clear the drop location during a DnD operation.
3264      * In some cases, the component may need to use its internal selection
3265      * temporarily to indicate the drop location. To help facilitate this,
3266      * this method returns and accepts as a parameter a state object.
3267      * This state object can be used to store, and later restore, the selection
3268      * state. Whatever this method returns will be passed back to it in
3269      * future calls, as the state parameter. If it wants the DnD system to
3270      * continue storing the same state, it must pass it back every time.
3271      * Here's how this is used:
3272      * <p>
3273      * Let's say that on the first call to this method the component decides
3274      * to save some state (because it is about to use the selection to show
3275      * a drop index). It can return a state object to the caller encapsulating
3276      * any saved selection state. On a second call, let's say the drop location
3277      * is being changed to something else. The component doesn't need to
3278      * restore anything yet, so it simply passes back the same state object
3279      * to have the DnD system continue storing it. Finally, let's say this
3280      * method is messaged with <code>null</code>. This means DnD
3281      * is finished with this component for now, meaning it should restore
3282      * state. At this point, it can use the state parameter to restore
3283      * said state, and of course return <code>null</code> since there's
3284      * no longer anything to store.
3285      *
3286      * @param location the drop location (as calculated by
3287      *        <code>dropLocationForPoint</code>) or <code>null</code>
3288      *        if there's no longer a valid drop location
3289      * @param state the state object saved earlier for this component,
3290      *        or <code>null</code>
3291      * @param forDrop whether or not the method is being called because an
3292      *        actual drop occurred
3293      * @return any saved state for this component, or <code>null</code> if none
3294      */
3295     Object setDropLocation(TransferHandler.DropLocation location,
3296                            Object state,
3297                            boolean forDrop) {
3298 
3299         return null;
3300     }
3301 
3302     /**
3303      * Called to indicate to this component that DnD is done.
3304      * Needed by <code>JTree</code>.
3305      */
3306     void dndDone() {
3307     }
3308 
3309     /**
3310      * Processes mouse events occurring on this component by
3311      * dispatching them to any registered
3312      * <code>MouseListener</code> objects, refer to
3313      * {@link java.awt.Component#processMouseEvent(MouseEvent)}
3314      * for a complete description of this method.
3315      *
3316      * @param       e the mouse event
3317      * @see         java.awt.Component#processMouseEvent
3318      * @since       1.5
3319      */
3320     protected void processMouseEvent(MouseEvent e) {
3321         if (autoscrolls && e.getID() == MouseEvent.MOUSE_RELEASED) {
3322             Autoscroller.stop(this);
3323         }
3324         super.processMouseEvent(e);
3325     }
3326 
3327     /**
3328      * Processes mouse motion events, such as MouseEvent.MOUSE_DRAGGED.
3329      *
3330      * @param e the <code>MouseEvent</code>
3331      * @see MouseEvent
3332      */
3333     protected void processMouseMotionEvent(MouseEvent e) {
3334         boolean dispatch = true;
3335         if (autoscrolls && e.getID() == MouseEvent.MOUSE_DRAGGED) {
3336             // We don't want to do the drags when the mouse moves if we're
3337             // autoscrolling.  It makes it feel spastic.
3338             dispatch = !Autoscroller.isRunning(this);
3339             Autoscroller.processMouseDragged(e);
3340         }
3341         if (dispatch) {
3342             super.processMouseMotionEvent(e);
3343         }
3344     }
3345 
3346     // Inner classes can't get at this method from a super class
3347     void superProcessMouseMotionEvent(MouseEvent e) {
3348         super.processMouseMotionEvent(e);
3349     }
3350 
3351     /**
3352      * This is invoked by the <code>RepaintManager</code> if
3353      * <code>createImage</code> is called on the component.
3354      *
3355      * @param newValue true if the double buffer image was created from this component
3356      */
3357     void setCreatedDoubleBuffer(boolean newValue) {
3358         setFlag(CREATED_DOUBLE_BUFFER, newValue);
3359     }
3360 
3361     /**
3362      * Returns true if the <code>RepaintManager</code>
3363      * created the double buffer image from the component.
3364      *
3365      * @return true if this component had a double buffer image, false otherwise
3366      */
3367     boolean getCreatedDoubleBuffer() {
3368         return getFlag(CREATED_DOUBLE_BUFFER);
3369     }
3370 
3371     /**
3372      * <code>ActionStandin</code> is used as a standin for
3373      * <code>ActionListeners</code> that are
3374      * added via <code>registerKeyboardAction</code>.
3375      */
3376     final class ActionStandin implements Action {
3377         private final ActionListener actionListener;
3378         private final String command;
3379         // This will be non-null if actionListener is an Action.
3380         private final Action action;
3381 
3382         ActionStandin(ActionListener actionListener, String command) {
3383             this.actionListener = actionListener;
3384             if (actionListener instanceof Action) {
3385                 this.action = (Action)actionListener;
3386             }
3387             else {
3388                 this.action = null;
3389             }
3390             this.command = command;
3391         }
3392 
3393         public Object getValue(String key) {
3394             if (key != null) {
3395                 if (key.equals(Action.ACTION_COMMAND_KEY)) {
3396                     return command;
3397                 }
3398                 if (action != null) {
3399                     return action.getValue(key);
3400                 }
3401                 if (key.equals(NAME)) {
3402                     return "ActionStandin";
3403                 }
3404             }
3405             return null;
3406         }
3407 
3408         public boolean isEnabled() {
3409             if (actionListener == null) {
3410                 // This keeps the old semantics where
3411                 // registerKeyboardAction(null) would essentialy remove
3412                 // the binding. We don't remove the binding from the
3413                 // InputMap as that would still allow parent InputMaps
3414                 // bindings to be accessed.
3415                 return false;
3416             }
3417             if (action == null) {
3418                 return true;
3419             }
3420             return action.isEnabled();
3421         }
3422 
3423         public void actionPerformed(ActionEvent ae) {
3424             if (actionListener != null) {
3425                 actionListener.actionPerformed(ae);
3426             }
3427         }
3428 
3429         // We don't allow any values to be added.
3430         public void putValue(String key, Object value) {}
3431 
3432         // Does nothing, our enabledness is determiend from our asociated
3433         // action.
3434         public void setEnabled(boolean b) { }
3435 
3436         public void addPropertyChangeListener
3437                     (PropertyChangeListener listener) {}
3438         public void removePropertyChangeListener
3439                           (PropertyChangeListener listener) {}
3440     }
3441 
3442 
3443     // This class is used by the KeyboardState class to provide a single
3444     // instance that can be stored in the AppContext.
3445     static final class IntVector {
3446         int array[] = null;
3447         int count = 0;
3448         int capacity = 0;
3449 
3450         int size() {
3451             return count;
3452         }
3453 
3454         int elementAt(int index) {
3455             return array[index];
3456         }
3457 
3458         void addElement(int value) {
3459             if (count == capacity) {
3460                 capacity = (capacity + 2) * 2;
3461                 int[] newarray = new int[capacity];
3462                 if (count > 0) {
3463                     System.arraycopy(array, 0, newarray, 0, count);
3464                 }
3465                 array = newarray;
3466             }
3467             array[count++] = value;
3468         }
3469 
3470         void setElementAt(int value, int index) {
3471             array[index] = value;
3472         }
3473     }
3474 
3475     @SuppressWarnings("serial")
3476     static class KeyboardState implements Serializable {
3477         private static final Object keyCodesKey =
3478             JComponent.KeyboardState.class;
3479 
3480         // Get the array of key codes from the AppContext.
3481         static IntVector getKeyCodeArray() {
3482             IntVector iv =
3483                 (IntVector)SwingUtilities.appContextGet(keyCodesKey);
3484             if (iv == null) {
3485                 iv = new IntVector();
3486                 SwingUtilities.appContextPut(keyCodesKey, iv);
3487             }
3488             return iv;
3489         }
3490 
3491         static void registerKeyPressed(int keyCode) {
3492             IntVector kca = getKeyCodeArray();
3493             int count = kca.size();
3494             int i;
3495             for(i=0;i<count;i++) {
3496                 if(kca.elementAt(i) == -1){
3497                     kca.setElementAt(keyCode, i);
3498                     return;
3499                 }
3500             }
3501             kca.addElement(keyCode);
3502         }
3503 
3504         static void registerKeyReleased(int keyCode) {
3505             IntVector kca = getKeyCodeArray();
3506             int count = kca.size();
3507             int i;
3508             for(i=0;i<count;i++) {
3509                 if(kca.elementAt(i) == keyCode) {
3510                     kca.setElementAt(-1, i);
3511                     return;
3512                 }
3513             }
3514         }
3515 
3516         static boolean keyIsPressed(int keyCode) {
3517             IntVector kca = getKeyCodeArray();
3518             int count = kca.size();
3519             int i;
3520             for(i=0;i<count;i++) {
3521                 if(kca.elementAt(i) == keyCode) {
3522                     return true;
3523                 }
3524             }
3525             return false;
3526         }
3527 
3528         /**
3529          * Updates internal state of the KeyboardState and returns true
3530          * if the event should be processed further.
3531          */
3532         static boolean shouldProcess(KeyEvent e) {
3533             switch (e.getID()) {
3534             case KeyEvent.KEY_PRESSED:
3535                 if (!keyIsPressed(e.getKeyCode())) {
3536                     registerKeyPressed(e.getKeyCode());
3537                 }
3538                 return true;
3539             case KeyEvent.KEY_RELEASED:
3540                 // We are forced to process VK_PRINTSCREEN separately because
3541                 // the Windows doesn't generate the key pressed event for
3542                 // printscreen and it block the processing of key release
3543                 // event for printscreen.
3544                 if (keyIsPressed(e.getKeyCode()) || e.getKeyCode()==KeyEvent.VK_PRINTSCREEN) {
3545                     registerKeyReleased(e.getKeyCode());
3546                     return true;
3547                 }
3548                 return false;
3549             case KeyEvent.KEY_TYPED:
3550                 return true;
3551             default:
3552                 // Not a known KeyEvent type, bail.
3553                 return false;
3554             }
3555       }
3556     }
3557 
3558     static final sun.awt.RequestFocusController focusController =
3559         new sun.awt.RequestFocusController() {
3560             public boolean acceptRequestFocus(Component from, Component to,
3561                                               boolean temporary, boolean focusedWindowChangeAllowed,
3562                                               sun.awt.CausedFocusEvent.Cause cause)
3563             {
3564                 if ((to == null) || !(to instanceof JComponent)) {
3565                     return true;
3566                 }
3567 
3568                 if ((from == null) || !(from instanceof JComponent)) {
3569                     return true;
3570                 }
3571 
3572                 JComponent target = (JComponent) to;
3573                 if (!target.getVerifyInputWhenFocusTarget()) {
3574                     return true;
3575                 }
3576 
3577                 JComponent jFocusOwner = (JComponent)from;
3578                 InputVerifier iv = jFocusOwner.getInputVerifier();
3579 
3580                 if (iv == null) {
3581                     return true;
3582                 } else {
3583                     Object currentSource = SwingUtilities.appContextGet(
3584                             INPUT_VERIFIER_SOURCE_KEY);
3585                     if (currentSource == jFocusOwner) {
3586                         // We're currently calling into the InputVerifier
3587                         // for this component, so allow the focus change.
3588                         return true;
3589                     }
3590                     SwingUtilities.appContextPut(INPUT_VERIFIER_SOURCE_KEY,
3591                                                  jFocusOwner);
3592                     try {
3593                         return iv.shouldYieldFocus(jFocusOwner);
3594                     } finally {
3595                         if (currentSource != null) {
3596                             // We're already in the InputVerifier for
3597                             // currentSource. By resetting the currentSource
3598                             // we ensure that if the InputVerifier for
3599                             // currentSource does a requestFocus, we don't
3600                             // try and run the InputVerifier again.
3601                             SwingUtilities.appContextPut(
3602                                 INPUT_VERIFIER_SOURCE_KEY, currentSource);
3603                         } else {
3604                             SwingUtilities.appContextRemove(
3605                                 INPUT_VERIFIER_SOURCE_KEY);
3606                         }
3607                     }
3608                 }
3609             }
3610         };
3611 
3612     /*
3613      * --- Accessibility Support ---
3614      */
3615 
3616     /**
3617      * @deprecated As of JDK version 1.1,
3618      * replaced by <code>java.awt.Component.setEnabled(boolean)</code>.
3619      */
3620     @Deprecated
3621     public void enable() {
3622         if (isEnabled() != true) {
3623             super.enable();
3624             if (accessibleContext != null) {
3625                 accessibleContext.firePropertyChange(
3626                     AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
3627                     null, AccessibleState.ENABLED);
3628             }
3629         }
3630     }
3631 
3632     /**
3633      * @deprecated As of JDK version 1.1,
3634      * replaced by <code>java.awt.Component.setEnabled(boolean)</code>.
3635      */
3636     @Deprecated
3637     public void disable() {
3638         if (isEnabled() != false) {
3639             super.disable();
3640             if (accessibleContext != null) {
3641                 accessibleContext.firePropertyChange(
3642                     AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
3643                     AccessibleState.ENABLED, null);
3644             }
3645         }
3646     }
3647 
3648     /**
3649      * Inner class of JComponent used to provide default support for
3650      * accessibility.  This class is not meant to be used directly by
3651      * application developers, but is instead meant only to be
3652      * subclassed by component developers.
3653      * <p>
3654      * <strong>Warning:</strong>
3655      * Serialized objects of this class will not be compatible with
3656      * future Swing releases. The current serialization support is
3657      * appropriate for short term storage or RMI between applications running
3658      * the same version of Swing.  As of 1.4, support for long term storage
3659      * of all JavaBeans&trade;
3660      * has been added to the <code>java.beans</code> package.
3661      * Please see {@link java.beans.XMLEncoder}.
3662      */
3663     public abstract class AccessibleJComponent extends AccessibleAWTContainer
3664        implements AccessibleExtendedComponent
3665     {
3666         /**
3667          * Though the class is abstract, this should be called by
3668          * all sub-classes.
3669          */
3670         protected AccessibleJComponent() {
3671             super();
3672         }
3673 
3674         /**
3675          * Number of PropertyChangeListener objects registered. It's used
3676          * to add/remove ContainerListener and FocusListener to track
3677          * target JComponent's state
3678          */
3679         private volatile transient int propertyListenersCount = 0;
3680 
3681         /**
3682          * This field duplicates the function of the accessibleAWTFocusHandler field
3683          * in java.awt.Component.AccessibleAWTComponent, so it has been deprecated.
3684          */
3685         @Deprecated
3686         protected FocusListener accessibleFocusHandler = null;
3687 
3688         /**
3689          * Fire PropertyChange listener, if one is registered,
3690          * when children added/removed.
3691          */
3692         protected class AccessibleContainerHandler
3693             implements ContainerListener {
3694             public void componentAdded(ContainerEvent e) {
3695                 Component c = e.getChild();
3696                 if (c != null && c instanceof Accessible) {
3697                     AccessibleJComponent.this.firePropertyChange(
3698                         AccessibleContext.ACCESSIBLE_CHILD_PROPERTY,
3699                         null, c.getAccessibleContext());
3700                 }
3701             }
3702             public void componentRemoved(ContainerEvent e) {
3703                 Component c = e.getChild();
3704                 if (c != null && c instanceof Accessible) {
3705                     AccessibleJComponent.this.firePropertyChange(
3706                         AccessibleContext.ACCESSIBLE_CHILD_PROPERTY,
3707                         c.getAccessibleContext(), null);
3708                 }
3709             }
3710         }
3711 
3712         /**
3713          * Fire PropertyChange listener, if one is registered,
3714          * when focus events happen
3715          * @since 1.3
3716          */
3717         protected class AccessibleFocusHandler implements FocusListener {
3718            public void focusGained(FocusEvent event) {
3719                if (accessibleContext != null) {
3720                     accessibleContext.firePropertyChange(
3721                         AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
3722                         null, AccessibleState.FOCUSED);
3723                 }
3724             }
3725             public void focusLost(FocusEvent event) {
3726                 if (accessibleContext != null) {
3727                     accessibleContext.firePropertyChange(
3728                         AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
3729                         AccessibleState.FOCUSED, null);
3730                 }
3731             }
3732         } // inner class AccessibleFocusHandler
3733 
3734 
3735         /**
3736          * Adds a PropertyChangeListener to the listener list.
3737          *
3738          * @param listener  the PropertyChangeListener to be added
3739          */
3740         public void addPropertyChangeListener(PropertyChangeListener listener) {
3741             super.addPropertyChangeListener(listener);
3742         }
3743 
3744         /**
3745          * Removes a PropertyChangeListener from the listener list.
3746          * This removes a PropertyChangeListener that was registered
3747          * for all properties.
3748          *
3749          * @param listener  the PropertyChangeListener to be removed
3750          */
3751         public void removePropertyChangeListener(PropertyChangeListener listener) {
3752             super.removePropertyChangeListener(listener);
3753         }
3754 
3755 
3756 
3757         /**
3758          * Recursively search through the border hierarchy (if it exists)
3759          * for a TitledBorder with a non-null title.  This does a depth
3760          * first search on first the inside borders then the outside borders.
3761          * The assumption is that titles make really pretty inside borders
3762          * but not very pretty outside borders in compound border situations.
3763          * It's rather arbitrary, but hopefully decent UI programmers will
3764          * not create multiple titled borders for the same component.
3765          */
3766         protected String getBorderTitle(Border b) {
3767             String s;
3768             if (b instanceof TitledBorder) {
3769                 return ((TitledBorder) b).getTitle();
3770             } else if (b instanceof CompoundBorder) {
3771                 s = getBorderTitle(((CompoundBorder) b).getInsideBorder());
3772                 if (s == null) {
3773                     s = getBorderTitle(((CompoundBorder) b).getOutsideBorder());
3774                 }
3775                 return s;
3776             } else {
3777                 return null;
3778             }
3779         }
3780 
3781         // AccessibleContext methods
3782         //
3783         /**
3784          * Gets the accessible name of this object.  This should almost never
3785          * return java.awt.Component.getName(), as that generally isn't
3786          * a localized name, and doesn't have meaning for the user.  If the
3787          * object is fundamentally a text object (such as a menu item), the
3788          * accessible name should be the text of the object (for example,
3789          * "save").
3790          * If the object has a tooltip, the tooltip text may also be an
3791          * appropriate String to return.
3792          *
3793          * @return the localized name of the object -- can be null if this
3794          *         object does not have a name
3795          * @see AccessibleContext#setAccessibleName
3796          */
3797         public String getAccessibleName() {
3798             String name = accessibleName;
3799 
3800             // fallback to the client name property
3801             //
3802             if (name == null) {
3803                 name = (String)getClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY);
3804             }
3805 
3806             // fallback to the titled border if it exists
3807             //
3808             if (name == null) {
3809                 name = getBorderTitle(getBorder());
3810             }
3811 
3812             // fallback to the label labeling us if it exists
3813             //
3814             if (name == null) {
3815                 Object o = getClientProperty(JLabel.LABELED_BY_PROPERTY);
3816                 if (o instanceof Accessible) {
3817                     AccessibleContext ac = ((Accessible) o).getAccessibleContext();
3818                     if (ac != null) {
3819                         name = ac.getAccessibleName();
3820                     }
3821                 }
3822             }
3823             return name;
3824         }
3825 
3826         /**
3827          * Gets the accessible description of this object.  This should be
3828          * a concise, localized description of what this object is - what
3829          * is its meaning to the user.  If the object has a tooltip, the
3830          * tooltip text may be an appropriate string to return, assuming
3831          * it contains a concise description of the object (instead of just
3832          * the name of the object - for example a "Save" icon on a toolbar that
3833          * had "save" as the tooltip text shouldn't return the tooltip
3834          * text as the description, but something like "Saves the current
3835          * text document" instead).
3836          *
3837          * @return the localized description of the object -- can be null if
3838          * this object does not have a description
3839          * @see AccessibleContext#setAccessibleDescription
3840          */
3841         public String getAccessibleDescription() {
3842             String description = accessibleDescription;
3843 
3844             // fallback to the client description property
3845             //
3846             if (description == null) {
3847                 description = (String)getClientProperty(AccessibleContext.ACCESSIBLE_DESCRIPTION_PROPERTY);
3848             }
3849 
3850             // fallback to the tool tip text if it exists
3851             //
3852             if (description == null) {
3853                 try {
3854                     description = getToolTipText();
3855                 } catch (Exception e) {
3856                     // Just in case the subclass overrode the
3857                     // getToolTipText method and actually
3858                     // requires a MouseEvent.
3859                     // [[[FIXME:  WDW - we probably should require this
3860                     // method to take a MouseEvent and just pass it on
3861                     // to getToolTipText.  The swing-feedback traffic
3862                     // leads me to believe getToolTipText might change,
3863                     // though, so I was hesitant to make this change at
3864                     // this time.]]]
3865                 }
3866             }
3867 
3868             // fallback to the label labeling us if it exists
3869             //
3870             if (description == null) {
3871                 Object o = getClientProperty(JLabel.LABELED_BY_PROPERTY);
3872                 if (o instanceof Accessible) {
3873                     AccessibleContext ac = ((Accessible) o).getAccessibleContext();
3874                     if (ac != null) {
3875                         description = ac.getAccessibleDescription();
3876                     }
3877                 }
3878             }
3879 
3880             return description;
3881         }
3882 
3883         /**
3884          * Gets the role of this object.
3885          *
3886          * @return an instance of AccessibleRole describing the role of the
3887          * object
3888          * @see AccessibleRole
3889          */
3890         public AccessibleRole getAccessibleRole() {
3891             return AccessibleRole.SWING_COMPONENT;
3892         }
3893 
3894         /**
3895          * Gets the state of this object.
3896          *
3897          * @return an instance of AccessibleStateSet containing the current
3898          * state set of the object
3899          * @see AccessibleState
3900          */
3901         public AccessibleStateSet getAccessibleStateSet() {
3902             AccessibleStateSet states = super.getAccessibleStateSet();
3903             if (JComponent.this.isOpaque()) {
3904                 states.add(AccessibleState.OPAQUE);
3905             }
3906             return states;
3907         }
3908 
3909         /**
3910          * Returns the number of accessible children in the object.  If all
3911          * of the children of this object implement Accessible, than this
3912          * method should return the number of children of this object.
3913          *
3914          * @return the number of accessible children in the object.
3915          */
3916         public int getAccessibleChildrenCount() {
3917             return super.getAccessibleChildrenCount();
3918         }
3919 
3920         /**
3921          * Returns the nth Accessible child of the object.
3922          *
3923          * @param i zero-based index of child
3924          * @return the nth Accessible child of the object
3925          */
3926         public Accessible getAccessibleChild(int i) {
3927             return super.getAccessibleChild(i);
3928         }
3929 
3930         // ----- AccessibleExtendedComponent
3931 
3932         /**
3933          * Returns the AccessibleExtendedComponent
3934          *
3935          * @return the AccessibleExtendedComponent
3936          */
3937         AccessibleExtendedComponent getAccessibleExtendedComponent() {
3938             return this;
3939         }
3940 
3941         /**
3942          * Returns the tool tip text
3943          *
3944          * @return the tool tip text, if supported, of the object;
3945          * otherwise, null
3946          * @since 1.4
3947          */
3948         public String getToolTipText() {
3949             return JComponent.this.getToolTipText();
3950         }
3951 
3952         /**
3953          * Returns the titled border text
3954          *
3955          * @return the titled border text, if supported, of the object;
3956          * otherwise, null
3957          * @since 1.4
3958          */
3959         public String getTitledBorderText() {
3960             Border border = JComponent.this.getBorder();
3961             if (border instanceof TitledBorder) {
3962                 return ((TitledBorder)border).getTitle();
3963             } else {
3964                 return null;
3965             }
3966         }
3967 
3968         /**
3969          * Returns key bindings associated with this object
3970          *
3971          * @return the key bindings, if supported, of the object;
3972          * otherwise, null
3973          * @see AccessibleKeyBinding
3974          * @since 1.4
3975          */
3976         public AccessibleKeyBinding getAccessibleKeyBinding() {
3977             // Try to get the linked label's mnemonic if it exists
3978             Object o = getClientProperty(JLabel.LABELED_BY_PROPERTY);
3979             if (o instanceof Accessible){
3980                 AccessibleContext ac = ((Accessible) o).getAccessibleContext();
3981                 if (ac != null){
3982                     AccessibleComponent comp = ac.getAccessibleComponent();
3983                     if (! (comp instanceof AccessibleExtendedComponent))
3984                         return null;
3985                     return ((AccessibleExtendedComponent)comp).getAccessibleKeyBinding();
3986                 }
3987             }
3988             return null;
3989         }
3990     } // inner class AccessibleJComponent
3991 
3992 
3993     /**
3994      * Returns an <code>ArrayTable</code> used for
3995      * key/value "client properties" for this component. If the
3996      * <code>clientProperties</code> table doesn't exist, an empty one
3997      * will be created.
3998      *
3999      * @return an ArrayTable
4000      * @see #putClientProperty
4001      * @see #getClientProperty
4002      */
4003     private ArrayTable getClientProperties() {
4004         if (clientProperties == null) {
4005             clientProperties = new ArrayTable();
4006         }
4007         return clientProperties;
4008     }
4009 
4010 
4011     /**
4012      * Returns the value of the property with the specified key.  Only
4013      * properties added with <code>putClientProperty</code> will return
4014      * a non-<code>null</code> value.
4015      *
4016      * @param key the being queried
4017      * @return the value of this property or <code>null</code>
4018      * @see #putClientProperty
4019      */
4020     public final Object getClientProperty(Object key) {
4021         if (key == SwingUtilities2.AA_TEXT_PROPERTY_KEY) {
4022             return aaTextInfo;
4023         } else if (key == SwingUtilities2.COMPONENT_UI_PROPERTY_KEY) {
4024             return ui;
4025         }
4026          if(clientProperties == null) {
4027             return null;
4028         } else {
4029             synchronized(clientProperties) {
4030                 return clientProperties.get(key);
4031             }
4032         }
4033     }
4034 
4035     /**
4036      * Adds an arbitrary key/value "client property" to this component.
4037      * <p>
4038      * The <code>get/putClientProperty</code> methods provide access to
4039      * a small per-instance hashtable. Callers can use get/putClientProperty
4040      * to annotate components that were created by another module.
4041      * For example, a
4042      * layout manager might store per child constraints this way. For example:
4043      * <pre>
4044      * componentA.putClientProperty("to the left of", componentB);
4045      * </pre>
4046      * If value is <code>null</code> this method will remove the property.
4047      * Changes to client properties are reported with
4048      * <code>PropertyChange</code> events.
4049      * The name of the property (for the sake of PropertyChange
4050      * events) is <code>key.toString()</code>.
4051      * <p>
4052      * The <code>clientProperty</code> dictionary is not intended to
4053      * support large
4054      * scale extensions to JComponent nor should be it considered an
4055      * alternative to subclassing when designing a new component.
4056      *
4057      * @param key the new client property key
4058      * @param value the new client property value; if <code>null</code>
4059      *          this method will remove the property
4060      * @see #getClientProperty
4061      * @see #addPropertyChangeListener
4062      */
4063     public final void putClientProperty(Object key, Object value) {
4064         if (key == SwingUtilities2.AA_TEXT_PROPERTY_KEY) {
4065             aaTextInfo = value;
4066             return;
4067         }
4068         if (value == null && clientProperties == null) {
4069             // Both the value and ArrayTable are null, implying we don't
4070             // have to do anything.
4071             return;
4072         }
4073         ArrayTable clientProperties = getClientProperties();
4074         Object oldValue;
4075         synchronized(clientProperties) {
4076             oldValue = clientProperties.get(key);
4077             if (value != null) {
4078                 clientProperties.put(key, value);
4079             } else if (oldValue != null) {
4080                 clientProperties.remove(key);
4081             } else {
4082                 // old == new == null
4083                 return;
4084             }
4085         }
4086         clientPropertyChanged(key, oldValue, value);
4087         firePropertyChange(key.toString(), oldValue, value);
4088     }
4089 
4090     // Invoked from putClientProperty.  This is provided for subclasses
4091     // in Swing.
4092     void clientPropertyChanged(Object key, Object oldValue,
4093                                Object newValue) {
4094     }
4095 
4096 
4097     /*
4098      * Sets the property with the specified name to the specified value if
4099      * the property has not already been set by the client program.
4100      * This method is used primarily to set UI defaults for properties
4101      * with primitive types, where the values cannot be marked with
4102      * UIResource.
4103      * @see LookAndFeel#installProperty
4104      * @param propertyName String containing the name of the property
4105      * @param value Object containing the property value
4106      */
4107     void setUIProperty(String propertyName, Object value) {
4108         if (propertyName == "opaque") {
4109             if (!getFlag(OPAQUE_SET)) {
4110                 setOpaque(((Boolean)value).booleanValue());
4111                 setFlag(OPAQUE_SET, false);
4112             }
4113         } else if (propertyName == "autoscrolls") {
4114             if (!getFlag(AUTOSCROLLS_SET)) {
4115                 setAutoscrolls(((Boolean)value).booleanValue());
4116                 setFlag(AUTOSCROLLS_SET, false);
4117             }
4118         } else if (propertyName == "focusTraversalKeysForward") {
4119             if (!getFlag(FOCUS_TRAVERSAL_KEYS_FORWARD_SET)) {
4120                 super.setFocusTraversalKeys(KeyboardFocusManager.
4121                                             FORWARD_TRAVERSAL_KEYS,
4122                                             (Set<AWTKeyStroke>)value);
4123             }
4124         } else if (propertyName == "focusTraversalKeysBackward") {
4125             if (!getFlag(FOCUS_TRAVERSAL_KEYS_BACKWARD_SET)) {
4126                 super.setFocusTraversalKeys(KeyboardFocusManager.
4127                                             BACKWARD_TRAVERSAL_KEYS,
4128                                             (Set<AWTKeyStroke>)value);
4129             }
4130         } else {
4131             throw new IllegalArgumentException("property \""+
4132                                                propertyName+ "\" cannot be set using this method");
4133         }
4134     }
4135 
4136 
4137     /**
4138      * Sets the focus traversal keys for a given traversal operation for this
4139      * Component.
4140      * Refer to
4141      * {@link java.awt.Component#setFocusTraversalKeys}
4142      * for a complete description of this method.
4143      * <p>
4144      * This method may throw a {@code ClassCastException} if any {@code Object}
4145      * in {@code keystrokes} is not an {@code AWTKeyStroke}.
4146      *
4147      * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
4148      *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
4149      *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
4150      * @param keystrokes the Set of AWTKeyStroke for the specified operation
4151      * @see java.awt.KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
4152      * @see java.awt.KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
4153      * @see java.awt.KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
4154      * @throws IllegalArgumentException if id is not one of
4155      *         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
4156      *         KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
4157      *         KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or if keystrokes
4158      *         contains null, or if any keystroke represents a KEY_TYPED event,
4159      *         or if any keystroke already maps to another focus traversal
4160      *         operation for this Component
4161      * @since 1.5
4162      * @beaninfo
4163      *       bound: true
4164      */
4165     public void
4166         setFocusTraversalKeys(int id, Set<? extends AWTKeyStroke> keystrokes)
4167     {
4168         if (id == KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS) {
4169             setFlag(FOCUS_TRAVERSAL_KEYS_FORWARD_SET,true);
4170         } else if (id == KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS) {
4171             setFlag(FOCUS_TRAVERSAL_KEYS_BACKWARD_SET,true);
4172         }
4173         super.setFocusTraversalKeys(id,keystrokes);
4174     }
4175 
4176     /* --- Transitional java.awt.Component Support ---
4177      * The methods and fields in this section will migrate to
4178      * java.awt.Component in the next JDK release.
4179      */
4180 
4181     /**
4182      * Returns true if this component is lightweight, that is, if it doesn't
4183      * have a native window system peer.
4184      *
4185      * @return true if this component is lightweight
4186      */
4187     @SuppressWarnings("deprecation")
4188     public static boolean isLightweightComponent(Component c) {
4189         return c.getPeer() instanceof LightweightPeer;
4190     }
4191 
4192 
4193     /**
4194      * @deprecated As of JDK 5,
4195      * replaced by <code>Component.setBounds(int, int, int, int)</code>.
4196      * <p>
4197      * Moves and resizes this component.
4198      *
4199      * @param x  the new horizontal location
4200      * @param y  the new vertical location
4201      * @param w  the new width
4202      * @param h  the new height
4203      * @see java.awt.Component#setBounds
4204      */
4205     @Deprecated
4206     public void reshape(int x, int y, int w, int h) {
4207         super.reshape(x, y, w, h);
4208     }
4209 
4210 
4211     /**
4212      * Stores the bounds of this component into "return value"
4213      * <code>rv</code> and returns <code>rv</code>.
4214      * If <code>rv</code> is <code>null</code> a new <code>Rectangle</code>
4215      * is allocated.  This version of <code>getBounds</code> is useful
4216      * if the caller wants to avoid allocating a new <code>Rectangle</code>
4217      * object on the heap.
4218      *
4219      * @param rv the return value, modified to the component's bounds
4220      * @return <code>rv</code>; if <code>rv</code> is <code>null</code>
4221      *          return a newly created <code>Rectangle</code> with this
4222      *          component's bounds
4223      */
4224     public Rectangle getBounds(Rectangle rv) {
4225         if (rv == null) {
4226             return new Rectangle(getX(), getY(), getWidth(), getHeight());
4227         }
4228         else {
4229             rv.setBounds(getX(), getY(), getWidth(), getHeight());
4230             return rv;
4231         }
4232     }
4233 
4234 
4235     /**
4236      * Stores the width/height of this component into "return value"
4237      * <code>rv</code> and returns <code>rv</code>.
4238      * If <code>rv</code> is <code>null</code> a new <code>Dimension</code>
4239      * object is allocated.  This version of <code>getSize</code>
4240      * is useful if the caller wants to avoid allocating a new
4241      * <code>Dimension</code> object on the heap.
4242      *
4243      * @param rv the return value, modified to the component's size
4244      * @return <code>rv</code>
4245      */
4246     public Dimension getSize(Dimension rv) {
4247         if (rv == null) {
4248             return new Dimension(getWidth(), getHeight());
4249         }
4250         else {
4251             rv.setSize(getWidth(), getHeight());
4252             return rv;
4253         }
4254     }
4255 
4256 
4257     /**
4258      * Stores the x,y origin of this component into "return value"
4259      * <code>rv</code> and returns <code>rv</code>.
4260      * If <code>rv</code> is <code>null</code> a new <code>Point</code>
4261      * is allocated.  This version of <code>getLocation</code> is useful
4262      * if the caller wants to avoid allocating a new <code>Point</code>
4263      * object on the heap.
4264      *
4265      * @param rv the return value, modified to the component's location
4266      * @return <code>rv</code>
4267      */
4268     public Point getLocation(Point rv) {
4269         if (rv == null) {
4270             return new Point(getX(), getY());
4271         }
4272         else {
4273             rv.setLocation(getX(), getY());
4274             return rv;
4275         }
4276     }
4277 
4278 
4279     /**
4280      * Returns the current x coordinate of the component's origin.
4281      * This method is preferable to writing
4282      * <code>component.getBounds().x</code>, or
4283      * <code>component.getLocation().x</code> because it doesn't cause any
4284      * heap allocations.
4285      *
4286      * @return the current x coordinate of the component's origin
4287      */
4288     public int getX() { return super.getX(); }
4289 
4290 
4291     /**
4292      * Returns the current y coordinate of the component's origin.
4293      * This method is preferable to writing
4294      * <code>component.getBounds().y</code>, or
4295      * <code>component.getLocation().y</code> because it doesn't cause any
4296      * heap allocations.
4297      *
4298      * @return the current y coordinate of the component's origin
4299      */
4300     public int getY() { return super.getY(); }
4301 
4302 
4303     /**
4304      * Returns the current width of this component.
4305      * This method is preferable to writing
4306      * <code>component.getBounds().width</code>, or
4307      * <code>component.getSize().width</code> because it doesn't cause any
4308      * heap allocations.
4309      *
4310      * @return the current width of this component
4311      */
4312     public int getWidth() { return super.getWidth(); }
4313 
4314 
4315     /**
4316      * Returns the current height of this component.
4317      * This method is preferable to writing
4318      * <code>component.getBounds().height</code>, or
4319      * <code>component.getSize().height</code> because it doesn't cause any
4320      * heap allocations.
4321      *
4322      * @return the current height of this component
4323      */
4324     public int getHeight() { return super.getHeight(); }
4325 
4326     /**
4327      * Returns true if this component is completely opaque.
4328      * <p>
4329      * An opaque component paints every pixel within its
4330      * rectangular bounds. A non-opaque component paints only a subset of
4331      * its pixels or none at all, allowing the pixels underneath it to
4332      * "show through".  Therefore, a component that does not fully paint
4333      * its pixels provides a degree of transparency.
4334      * <p>
4335      * Subclasses that guarantee to always completely paint their contents
4336      * should override this method and return true.
4337      *
4338      * @return true if this component is completely opaque
4339      * @see #setOpaque
4340      */
4341     public boolean isOpaque() {
4342         return getFlag(IS_OPAQUE);
4343     }
4344 
4345     /**
4346      * If true the component paints every pixel within its bounds.
4347      * Otherwise, the component may not paint some or all of its
4348      * pixels, allowing the underlying pixels to show through.
4349      * <p>
4350      * The default value of this property is false for <code>JComponent</code>.
4351      * However, the default value for this property on most standard
4352      * <code>JComponent</code> subclasses (such as <code>JButton</code> and
4353      * <code>JTree</code>) is look-and-feel dependent.
4354      *
4355      * @param isOpaque  true if this component should be opaque
4356      * @see #isOpaque
4357      * @beaninfo
4358      *        bound: true
4359      *       expert: true
4360      *  description: The component's opacity
4361      */
4362     public void setOpaque(boolean isOpaque) {
4363         boolean oldValue = getFlag(IS_OPAQUE);
4364         setFlag(IS_OPAQUE, isOpaque);
4365         setFlag(OPAQUE_SET, true);
4366         firePropertyChange("opaque", oldValue, isOpaque);
4367     }
4368 
4369 
4370     /**
4371      * If the specified rectangle is completely obscured by any of this
4372      * component's opaque children then returns true.  Only direct children
4373      * are considered, more distant descendants are ignored.  A
4374      * <code>JComponent</code> is opaque if
4375      * <code>JComponent.isOpaque()</code> returns true, other lightweight
4376      * components are always considered transparent, and heavyweight components
4377      * are always considered opaque.
4378      *
4379      * @param x  x value of specified rectangle
4380      * @param y  y value of specified rectangle
4381      * @param width  width of specified rectangle
4382      * @param height height of specified rectangle
4383      * @return true if the specified rectangle is obscured by an opaque child
4384      */
4385     boolean rectangleIsObscured(int x,int y,int width,int height)
4386     {
4387         int numChildren = getComponentCount();
4388 
4389         for(int i = 0; i < numChildren; i++) {
4390             Component child = getComponent(i);
4391             int cx, cy, cw, ch;
4392 
4393             cx = child.getX();
4394             cy = child.getY();
4395             cw = child.getWidth();
4396             ch = child.getHeight();
4397 
4398             if (x >= cx && (x + width) <= (cx + cw) &&
4399                 y >= cy && (y + height) <= (cy + ch) && child.isVisible()) {
4400 
4401                 if(child instanceof JComponent) {
4402 //                  System.out.println("A) checking opaque: " + ((JComponent)child).isOpaque() + "  " + child);
4403 //                  System.out.print("B) ");
4404 //                  Thread.dumpStack();
4405                     return child.isOpaque();
4406                 } else {
4407                     /** Sometimes a heavy weight can have a bound larger than its peer size
4408                      *  so we should always draw under heavy weights
4409                      */
4410                     return false;
4411                 }
4412             }
4413         }
4414 
4415         return false;
4416     }
4417 
4418 
4419     /**
4420      * Returns the <code>Component</code>'s "visible rect rectangle" -  the
4421      * intersection of the visible rectangles for the component <code>c</code>
4422      * and all of its ancestors.  The return value is stored in
4423      * <code>visibleRect</code>.
4424      *
4425      * @param c  the component
4426      * @param visibleRect  a <code>Rectangle</code> computed as the
4427      *          intersection of all visible rectangles for the component
4428      *          <code>c</code> and all of its ancestors -- this is the
4429      *          return value for this method
4430      * @see #getVisibleRect
4431      */
4432     static final void computeVisibleRect(Component c, Rectangle visibleRect) {
4433         Container p = c.getParent();
4434         Rectangle bounds = c.getBounds();
4435 
4436         if (p == null || p instanceof Window || p instanceof Applet) {
4437             visibleRect.setBounds(0, 0, bounds.width, bounds.height);
4438         } else {
4439             computeVisibleRect(p, visibleRect);
4440             visibleRect.x -= bounds.x;
4441             visibleRect.y -= bounds.y;
4442             SwingUtilities.computeIntersection(0,0,bounds.width,bounds.height,visibleRect);
4443         }
4444     }
4445 
4446 
4447     /**
4448      * Returns the <code>Component</code>'s "visible rect rectangle" -  the
4449      * intersection of the visible rectangles for this component
4450      * and all of its ancestors.  The return value is stored in
4451      * <code>visibleRect</code>.
4452      *
4453      * @param visibleRect a <code>Rectangle</code> computed as the
4454      *          intersection of all visible rectangles for this
4455      *          component and all of its ancestors -- this is the return
4456      *          value for this method
4457      * @see #getVisibleRect
4458      */
4459     public void computeVisibleRect(Rectangle visibleRect) {
4460         computeVisibleRect(this, visibleRect);
4461     }
4462 
4463 
4464     /**
4465      * Returns the <code>Component</code>'s "visible rectangle" -  the
4466      * intersection of this component's visible rectangle,
4467      * <code>new Rectangle(0, 0, getWidth(), getHeight())</code>,
4468      * and all of its ancestors' visible rectangles.
4469      *
4470      * @return the visible rectangle
4471      */
4472     public Rectangle getVisibleRect() {
4473         Rectangle visibleRect = new Rectangle();
4474 
4475         computeVisibleRect(visibleRect);
4476         return visibleRect;
4477     }
4478 
4479     /**
4480      * Support for reporting bound property changes for boolean properties.
4481      * This method can be called when a bound property has changed and it will
4482      * send the appropriate PropertyChangeEvent to any registered
4483      * PropertyChangeListeners.
4484      *
4485      * @param propertyName the property whose value has changed
4486      * @param oldValue the property's previous value
4487      * @param newValue the property's new value
4488      */
4489     public void firePropertyChange(String propertyName,
4490                                    boolean oldValue, boolean newValue) {
4491         super.firePropertyChange(propertyName, oldValue, newValue);
4492     }
4493 
4494 
4495     /**
4496      * Support for reporting bound property changes for integer properties.
4497      * This method can be called when a bound property has changed and it will
4498      * send the appropriate PropertyChangeEvent to any registered
4499      * PropertyChangeListeners.
4500      *
4501      * @param propertyName the property whose value has changed
4502      * @param oldValue the property's previous value
4503      * @param newValue the property's new value
4504      */
4505     public void firePropertyChange(String propertyName,
4506                                       int oldValue, int newValue) {
4507         super.firePropertyChange(propertyName, oldValue, newValue);
4508     }
4509 
4510     // XXX This method is implemented as a workaround to a JLS issue with ambiguous
4511     // methods. This should be removed once 4758654 is resolved.
4512     public void firePropertyChange(String propertyName, char oldValue, char newValue) {
4513         super.firePropertyChange(propertyName, oldValue, newValue);
4514     }
4515 
4516     /**
4517      * Supports reporting constrained property changes.
4518      * This method can be called when a constrained property has changed
4519      * and it will send the appropriate <code>PropertyChangeEvent</code>
4520      * to any registered <code>VetoableChangeListeners</code>.
4521      *
4522      * @param propertyName  the name of the property that was listened on
4523      * @param oldValue  the old value of the property
4524      * @param newValue  the new value of the property
4525      * @exception java.beans.PropertyVetoException when the attempt to set the
4526      *          property is vetoed by the component
4527      */
4528     protected void fireVetoableChange(String propertyName, Object oldValue, Object newValue)
4529         throws java.beans.PropertyVetoException
4530     {
4531         if (vetoableChangeSupport == null) {
4532             return;
4533         }
4534         vetoableChangeSupport.fireVetoableChange(propertyName, oldValue, newValue);
4535     }
4536 
4537 
4538     /**
4539      * Adds a <code>VetoableChangeListener</code> to the listener list.
4540      * The listener is registered for all properties.
4541      *
4542      * @param listener  the <code>VetoableChangeListener</code> to be added
4543      */
4544     public synchronized void addVetoableChangeListener(VetoableChangeListener listener) {
4545         if (vetoableChangeSupport == null) {
4546             vetoableChangeSupport = new java.beans.VetoableChangeSupport(this);
4547         }
4548         vetoableChangeSupport.addVetoableChangeListener(listener);
4549     }
4550 
4551 
4552     /**
4553      * Removes a <code>VetoableChangeListener</code> from the listener list.
4554      * This removes a <code>VetoableChangeListener</code> that was registered
4555      * for all properties.
4556      *
4557      * @param listener  the <code>VetoableChangeListener</code> to be removed
4558      */
4559     public synchronized void removeVetoableChangeListener(VetoableChangeListener listener) {
4560         if (vetoableChangeSupport == null) {
4561             return;
4562         }
4563         vetoableChangeSupport.removeVetoableChangeListener(listener);
4564     }
4565 
4566 
4567     /**
4568      * Returns an array of all the vetoable change listeners
4569      * registered on this component.
4570      *
4571      * @return all of the component's <code>VetoableChangeListener</code>s
4572      *         or an empty
4573      *         array if no vetoable change listeners are currently registered
4574      *
4575      * @see #addVetoableChangeListener
4576      * @see #removeVetoableChangeListener
4577      *
4578      * @since 1.4
4579      */
4580     public synchronized VetoableChangeListener[] getVetoableChangeListeners() {
4581         if (vetoableChangeSupport == null) {
4582             return new VetoableChangeListener[0];
4583         }
4584         return vetoableChangeSupport.getVetoableChangeListeners();
4585     }
4586 
4587 
4588     /**
4589      * Returns the top-level ancestor of this component (either the
4590      * containing <code>Window</code> or <code>Applet</code>),
4591      * or <code>null</code> if this component has not
4592      * been added to any container.
4593      *
4594      * @return the top-level <code>Container</code> that this component is in,
4595      *          or <code>null</code> if not in any container
4596      */
4597     public Container getTopLevelAncestor() {
4598         for(Container p = this; p != null; p = p.getParent()) {
4599             if(p instanceof Window || p instanceof Applet) {
4600                 return p;
4601             }
4602         }
4603         return null;
4604     }
4605 
4606     private AncestorNotifier getAncestorNotifier() {
4607         return (AncestorNotifier)
4608             getClientProperty(JComponent_ANCESTOR_NOTIFIER);
4609     }
4610 
4611     /**
4612      * Registers <code>listener</code> so that it will receive
4613      * <code>AncestorEvents</code> when it or any of its ancestors
4614      * move or are made visible or invisible.
4615      * Events are also sent when the component or its ancestors are added
4616      * or removed from the containment hierarchy.
4617      *
4618      * @param listener  the <code>AncestorListener</code> to register
4619      * @see AncestorEvent
4620      */
4621     public void addAncestorListener(AncestorListener listener) {
4622         AncestorNotifier ancestorNotifier = getAncestorNotifier();
4623         if (ancestorNotifier == null) {
4624             ancestorNotifier = new AncestorNotifier(this);
4625             putClientProperty(JComponent_ANCESTOR_NOTIFIER,
4626                               ancestorNotifier);
4627         }
4628         ancestorNotifier.addAncestorListener(listener);
4629     }
4630 
4631     /**
4632      * Unregisters <code>listener</code> so that it will no longer receive
4633      * <code>AncestorEvents</code>.
4634      *
4635      * @param listener  the <code>AncestorListener</code> to be removed
4636      * @see #addAncestorListener
4637      */
4638     public void removeAncestorListener(AncestorListener listener) {
4639         AncestorNotifier ancestorNotifier = getAncestorNotifier();
4640         if (ancestorNotifier == null) {
4641             return;
4642         }
4643         ancestorNotifier.removeAncestorListener(listener);
4644         if (ancestorNotifier.listenerList.getListenerList().length == 0) {
4645             ancestorNotifier.removeAllListeners();
4646             putClientProperty(JComponent_ANCESTOR_NOTIFIER, null);
4647         }
4648     }
4649 
4650     /**
4651      * Returns an array of all the ancestor listeners
4652      * registered on this component.
4653      *
4654      * @return all of the component's <code>AncestorListener</code>s
4655      *         or an empty
4656      *         array if no ancestor listeners are currently registered
4657      *
4658      * @see #addAncestorListener
4659      * @see #removeAncestorListener
4660      *
4661      * @since 1.4
4662      */
4663     public AncestorListener[] getAncestorListeners() {
4664         AncestorNotifier ancestorNotifier = getAncestorNotifier();
4665         if (ancestorNotifier == null) {
4666             return new AncestorListener[0];
4667         }
4668         return ancestorNotifier.getAncestorListeners();
4669     }
4670 
4671     /**
4672      * Returns an array of all the objects currently registered
4673      * as <code><em>Foo</em>Listener</code>s
4674      * upon this <code>JComponent</code>.
4675      * <code><em>Foo</em>Listener</code>s are registered using the
4676      * <code>add<em>Foo</em>Listener</code> method.
4677      *
4678      * <p>
4679      *
4680      * You can specify the <code>listenerType</code> argument
4681      * with a class literal,
4682      * such as
4683      * <code><em>Foo</em>Listener.class</code>.
4684      * For example, you can query a
4685      * <code>JComponent</code> <code>c</code>
4686      * for its mouse listeners with the following code:
4687      * <pre>MouseListener[] mls = (MouseListener[])(c.getListeners(MouseListener.class));</pre>
4688      * If no such listeners exist, this method returns an empty array.
4689      *
4690      * @param listenerType the type of listeners requested; this parameter
4691      *          should specify an interface that descends from
4692      *          <code>java.util.EventListener</code>
4693      * @return an array of all objects registered as
4694      *          <code><em>Foo</em>Listener</code>s on this component,
4695      *          or an empty array if no such
4696      *          listeners have been added
4697      * @exception ClassCastException if <code>listenerType</code>
4698      *          doesn't specify a class or interface that implements
4699      *          <code>java.util.EventListener</code>
4700      *
4701      * @since 1.3
4702      *
4703      * @see #getVetoableChangeListeners
4704      * @see #getAncestorListeners
4705      */
4706     public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
4707         T[] result;
4708         if (listenerType == AncestorListener.class) {
4709             // AncestorListeners are handled by the AncestorNotifier
4710             result = (T[])getAncestorListeners();
4711         }
4712         else if (listenerType == VetoableChangeListener.class) {
4713             // VetoableChangeListeners are handled by VetoableChangeSupport
4714             result = (T[])getVetoableChangeListeners();
4715         }
4716         else if (listenerType == PropertyChangeListener.class) {
4717             // PropertyChangeListeners are handled by PropertyChangeSupport
4718             result = (T[])getPropertyChangeListeners();
4719         }
4720         else {
4721             result = listenerList.getListeners(listenerType);
4722         }
4723 
4724         if (result.length == 0) {
4725             return super.getListeners(listenerType);
4726         }
4727         return result;
4728     }
4729 
4730     /**
4731      * Notifies this component that it now has a parent component.
4732      * When this method is invoked, the chain of parent components is
4733      * set up with <code>KeyboardAction</code> event listeners.
4734      * This method is called by the toolkit internally and should
4735      * not be called directly by programs.
4736      *
4737      * @see #registerKeyboardAction
4738      */
4739     public void addNotify() {
4740         super.addNotify();
4741         firePropertyChange("ancestor", null, getParent());
4742 
4743         registerWithKeyboardManager(false);
4744         registerNextFocusableComponent();
4745     }
4746 
4747 
4748     /**
4749      * Notifies this component that it no longer has a parent component.
4750      * When this method is invoked, any <code>KeyboardAction</code>s
4751      * set up in the the chain of parent components are removed.
4752      * This method is called by the toolkit internally and should
4753      * not be called directly by programs.
4754      *
4755      * @see #registerKeyboardAction
4756      */
4757     public void removeNotify() {
4758         super.removeNotify();
4759         // This isn't strictly correct.  The event shouldn't be
4760         // fired until *after* the parent is set to null.  But
4761         // we only get notified before that happens
4762         firePropertyChange("ancestor", getParent(), null);
4763 
4764         unregisterWithKeyboardManager();
4765         deregisterNextFocusableComponent();
4766 
4767         if (getCreatedDoubleBuffer()) {
4768             RepaintManager.currentManager(this).resetDoubleBuffer();
4769             setCreatedDoubleBuffer(false);
4770         }
4771         if (autoscrolls) {
4772             Autoscroller.stop(this);
4773         }
4774     }
4775 
4776 
4777     /**
4778      * Adds the specified region to the dirty region list if the component
4779      * is showing.  The component will be repainted after all of the
4780      * currently pending events have been dispatched.
4781      *
4782      * @param tm  this parameter is not used
4783      * @param x  the x value of the dirty region
4784      * @param y  the y value of the dirty region
4785      * @param width  the width of the dirty region
4786      * @param height  the height of the dirty region
4787      * @see #isPaintingOrigin()
4788      * @see java.awt.Component#isShowing
4789      * @see RepaintManager#addDirtyRegion
4790      */
4791     public void repaint(long tm, int x, int y, int width, int height) {
4792         RepaintManager.currentManager(SunToolkit.targetToAppContext(this))
4793                       .addDirtyRegion(this, x, y, width, height);
4794     }
4795 
4796 
4797     /**
4798      * Adds the specified region to the dirty region list if the component
4799      * is showing.  The component will be repainted after all of the
4800      * currently pending events have been dispatched.
4801      *
4802      * @param  r a <code>Rectangle</code> containing the dirty region
4803      * @see #isPaintingOrigin()
4804      * @see java.awt.Component#isShowing
4805      * @see RepaintManager#addDirtyRegion
4806      */
4807     public void repaint(Rectangle r) {
4808         repaint(0,r.x,r.y,r.width,r.height);
4809     }
4810 
4811 
4812     /**
4813      * Supports deferred automatic layout.
4814      * <p>
4815      * Calls <code>invalidate</code> and then adds this component's
4816      * <code>validateRoot</code> to a list of components that need to be
4817      * validated.  Validation will occur after all currently pending
4818      * events have been dispatched.  In other words after this method
4819      * is called,  the first validateRoot (if any) found when walking
4820      * up the containment hierarchy of this component will be validated.
4821      * By default, <code>JRootPane</code>, <code>JScrollPane</code>,
4822      * and <code>JTextField</code> return true
4823      * from <code>isValidateRoot</code>.
4824      * <p>
4825      * This method will automatically be called on this component
4826      * when a property value changes such that size, location, or
4827      * internal layout of this component has been affected.  This automatic
4828      * updating differs from the AWT because programs generally no
4829      * longer need to invoke <code>validate</code> to get the contents of the
4830      * GUI to update.
4831      *
4832      * @see java.awt.Component#invalidate
4833      * @see java.awt.Container#validate
4834      * @see #isValidateRoot
4835      * @see RepaintManager#addInvalidComponent
4836      */
4837     public void revalidate() {
4838         if (getParent() == null) {
4839             // Note: We don't bother invalidating here as once added
4840             // to a valid parent invalidate will be invoked (addImpl
4841             // invokes addNotify which will invoke invalidate on the
4842             // new Component). Also, if we do add a check to isValid
4843             // here it can potentially be called before the constructor
4844             // which was causing some people grief.
4845             return;
4846         }
4847         if (SunToolkit.isDispatchThreadForAppContext(this)) {
4848             invalidate();
4849             RepaintManager.currentManager(this).addInvalidComponent(this);
4850         }
4851         else {
4852             // To avoid a flood of Runnables when constructing GUIs off
4853             // the EDT, a flag is maintained as to whether or not
4854             // a Runnable has been scheduled.
4855             if (revalidateRunnableScheduled.getAndSet(true)) {
4856                 return;
4857             }
4858             SunToolkit.executeOnEventHandlerThread(this, () -> {
4859                 revalidateRunnableScheduled.set(false);
4860                 revalidate();
4861             });
4862         }
4863     }
4864 
4865     /**
4866      * If this method returns true, <code>revalidate</code> calls by
4867      * descendants of this component will cause the entire tree
4868      * beginning with this root to be validated.
4869      * Returns false by default.  <code>JScrollPane</code> overrides
4870      * this method and returns true.
4871      *
4872      * @return always returns false
4873      * @see #revalidate
4874      * @see java.awt.Component#invalidate
4875      * @see java.awt.Container#validate
4876      * @see java.awt.Container#isValidateRoot
4877      */
4878     @Override
4879     public boolean isValidateRoot() {
4880         return false;
4881     }
4882 
4883 
4884     /**
4885      * Returns true if this component tiles its children -- that is, if
4886      * it can guarantee that the children will not overlap.  The
4887      * repainting system is substantially more efficient in this
4888      * common case.  <code>JComponent</code> subclasses that can't make this
4889      * guarantee, such as <code>JLayeredPane</code>,
4890      * should override this method to return false.
4891      *
4892      * @return always returns true
4893      */
4894     public boolean isOptimizedDrawingEnabled() {
4895         return true;
4896     }
4897 
4898     /**
4899      * Returns {@code true} if a paint triggered on a child component should cause
4900      * painting to originate from this Component, or one of its ancestors.
4901      * <p>
4902      * Calling {@link #repaint} or {@link #paintImmediately(int, int, int, int)}
4903      * on a Swing component will result in calling
4904      * the {@link JComponent#paintImmediately(int, int, int, int)} method of
4905      * the first ancestor which {@code isPaintingOrigin()} returns {@code true}, if there are any.
4906      * <p>
4907      * {@code JComponent} subclasses that need to be painted when any of their
4908      * children are repainted should override this method to return {@code true}.
4909      *
4910      * @return always returns {@code false}
4911      *
4912      * @see #paintImmediately(int, int, int, int)
4913      */
4914     protected boolean isPaintingOrigin() {
4915         return false;
4916     }
4917 
4918     /**
4919      * Paints the specified region in this component and all of its
4920      * descendants that overlap the region, immediately.
4921      * <p>
4922      * It's rarely necessary to call this method.  In most cases it's
4923      * more efficient to call repaint, which defers the actual painting
4924      * and can collapse redundant requests into a single paint call.
4925      * This method is useful if one needs to update the display while
4926      * the current event is being dispatched.
4927      * <p>
4928      * This method is to be overridden when the dirty region needs to be changed
4929      * for components that are painting origins.
4930      *
4931      * @param x  the x value of the region to be painted
4932      * @param y  the y value of the region to be painted
4933      * @param w  the width of the region to be painted
4934      * @param h  the height of the region to be painted
4935      * @see #repaint
4936      * @see #isPaintingOrigin()
4937      */
4938     public void paintImmediately(int x,int y,int w, int h) {
4939         Component c = this;
4940         Component parent;
4941 
4942         if(!isShowing()) {
4943             return;
4944         }
4945 
4946         JComponent paintingOigin = SwingUtilities.getPaintingOrigin(this);
4947         if (paintingOigin != null) {
4948             Rectangle rectangle = SwingUtilities.convertRectangle(
4949                     c, new Rectangle(x, y, w, h), paintingOigin);
4950             paintingOigin.paintImmediately(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
4951             return;
4952         }
4953 
4954         while(!c.isOpaque()) {
4955             parent = c.getParent();
4956             if(parent != null) {
4957                 x += c.getX();
4958                 y += c.getY();
4959                 c = parent;
4960             } else {
4961                 break;
4962             }
4963 
4964             if(!(c instanceof JComponent)) {
4965                 break;
4966             }
4967         }
4968         if(c instanceof JComponent) {
4969             ((JComponent)c)._paintImmediately(x,y,w,h);
4970         } else {
4971             c.repaint(x,y,w,h);
4972         }
4973     }
4974 
4975     /**
4976      * Paints the specified region now.
4977      *
4978      * @param r a <code>Rectangle</code> containing the region to be painted
4979      */
4980     public void paintImmediately(Rectangle r) {
4981         paintImmediately(r.x,r.y,r.width,r.height);
4982     }
4983 
4984     /**
4985      * Returns whether this component should be guaranteed to be on top.
4986      * For example, it would make no sense for <code>Menu</code>s to pop up
4987      * under another component, so they would always return true.
4988      * Most components will want to return false, hence that is the default.
4989      *
4990      * @return always returns false
4991      */
4992     // package private
4993     boolean alwaysOnTop() {
4994         return false;
4995     }
4996 
4997     void setPaintingChild(Component paintingChild) {
4998         this.paintingChild = paintingChild;
4999     }
5000 
5001     void _paintImmediately(int x, int y, int w, int h) {
5002         Graphics g;
5003         Container c;
5004         Rectangle b;
5005 
5006         int tmpX, tmpY, tmpWidth, tmpHeight;
5007         int offsetX=0,offsetY=0;
5008 
5009         boolean hasBuffer = false;
5010 
5011         JComponent bufferedComponent = null;
5012         JComponent paintingComponent = this;
5013 
5014         RepaintManager repaintManager = RepaintManager.currentManager(this);
5015         // parent Container's up to Window or Applet. First container is
5016         // the direct parent. Note that in testing it was faster to
5017         // alloc a new Vector vs keeping a stack of them around, and gc
5018         // seemed to have a minimal effect on this.
5019         java.util.List<Component> path = new java.util.ArrayList<Component>(7);
5020         int pIndex = -1;
5021         int pCount = 0;
5022 
5023         tmpX = tmpY = tmpWidth = tmpHeight = 0;
5024 
5025         Rectangle paintImmediatelyClip = fetchRectangle();
5026         paintImmediatelyClip.x = x;
5027         paintImmediatelyClip.y = y;
5028         paintImmediatelyClip.width = w;
5029         paintImmediatelyClip.height = h;
5030 
5031 
5032         // System.out.println("1) ************* in _paintImmediately for " + this);
5033 
5034         boolean ontop = alwaysOnTop() && isOpaque();
5035         if (ontop) {
5036             SwingUtilities.computeIntersection(0, 0, getWidth(), getHeight(),
5037                                                paintImmediatelyClip);
5038             if (paintImmediatelyClip.width == 0) {
5039                 recycleRectangle(paintImmediatelyClip);
5040                 return;
5041             }
5042         }
5043         Component child;
5044         for (c = this, child = null;
5045              c != null && !(c instanceof Window) && !(c instanceof Applet);
5046              child = c, c = c.getParent()) {
5047                 JComponent jc = (c instanceof JComponent) ? (JComponent)c :
5048                                 null;
5049                 path.add(c);
5050                 if(!ontop && jc != null && !jc.isOptimizedDrawingEnabled()) {
5051                     boolean resetPC;
5052 
5053                     // Children of c may overlap, three possible cases for the
5054                     // painting region:
5055                     // . Completely obscured by an opaque sibling, in which
5056                     //   case there is no need to paint.
5057                     // . Partially obscured by a sibling: need to start
5058                     //   painting from c.
5059                     // . Otherwise we aren't obscured and thus don't need to
5060                     //   start painting from parent.
5061                     if (c != this) {
5062                         if (jc.isPaintingOrigin()) {
5063                             resetPC = true;
5064                         }
5065                         else {
5066                             Component[] children = c.getComponents();
5067                             int i = 0;
5068                             for (; i<children.length; i++) {
5069                                 if (children[i] == child) break;
5070                             }
5071                             switch (jc.getObscuredState(i,
5072                                             paintImmediatelyClip.x,
5073                                             paintImmediatelyClip.y,
5074                                             paintImmediatelyClip.width,
5075                                             paintImmediatelyClip.height)) {
5076                             case NOT_OBSCURED:
5077                                 resetPC = false;
5078                                 break;
5079                             case COMPLETELY_OBSCURED:
5080                                 recycleRectangle(paintImmediatelyClip);
5081                                 return;
5082                             default:
5083                                 resetPC = true;
5084                                 break;
5085                             }
5086                         }
5087                     }
5088                     else {
5089                         resetPC = false;
5090                     }
5091 
5092                     if (resetPC) {
5093                         // Get rid of any buffer since we draw from here and
5094                         // we might draw something larger
5095                         paintingComponent = jc;
5096                         pIndex = pCount;
5097                         offsetX = offsetY = 0;
5098                         hasBuffer = false;
5099                     }
5100                 }
5101                 pCount++;
5102 
5103                 // look to see if the parent (and therefor this component)
5104                 // is double buffered
5105                 if(repaintManager.isDoubleBufferingEnabled() && jc != null &&
5106                                   jc.isDoubleBuffered()) {
5107                     hasBuffer = true;
5108                     bufferedComponent = jc;
5109                 }
5110 
5111                 // if we aren't on top, include the parent's clip
5112                 if (!ontop) {
5113                     int bx = c.getX();
5114                     int by = c.getY();
5115                     tmpWidth = c.getWidth();
5116                     tmpHeight = c.getHeight();
5117                     SwingUtilities.computeIntersection(tmpX,tmpY,tmpWidth,tmpHeight,paintImmediatelyClip);
5118                     paintImmediatelyClip.x += bx;
5119                     paintImmediatelyClip.y += by;
5120                     offsetX += bx;
5121                     offsetY += by;
5122                 }
5123         }
5124 
5125         // If the clip width or height is negative, don't bother painting
5126         if(c == null || c.getPeer() == null ||
5127                         paintImmediatelyClip.width <= 0 ||
5128                         paintImmediatelyClip.height <= 0) {
5129             recycleRectangle(paintImmediatelyClip);
5130             return;
5131         }
5132 
5133         paintingComponent.setFlag(IS_REPAINTING, true);
5134 
5135         paintImmediatelyClip.x -= offsetX;
5136         paintImmediatelyClip.y -= offsetY;
5137 
5138         // Notify the Components that are going to be painted of the
5139         // child component to paint to.
5140         if(paintingComponent != this) {
5141             Component comp;
5142             int i = pIndex;
5143             for(; i > 0 ; i--) {
5144                 comp = path.get(i);
5145                 if(comp instanceof JComponent) {
5146                     ((JComponent)comp).setPaintingChild(path.get(i-1));
5147                 }
5148             }
5149         }
5150         try {
5151             if ((g = safelyGetGraphics(paintingComponent, c)) != null) {
5152                 try {
5153                     if (hasBuffer) {
5154                         RepaintManager rm = RepaintManager.currentManager(
5155                                 bufferedComponent);
5156                         rm.beginPaint();
5157                         try {
5158                             rm.paint(paintingComponent, bufferedComponent, g,
5159                                     paintImmediatelyClip.x,
5160                                     paintImmediatelyClip.y,
5161                                     paintImmediatelyClip.width,
5162                                     paintImmediatelyClip.height);
5163                         } finally {
5164                             rm.endPaint();
5165                         }
5166                     } else {
5167                         g.setClip(paintImmediatelyClip.x, paintImmediatelyClip.y,
5168                                 paintImmediatelyClip.width, paintImmediatelyClip.height);
5169                         paintingComponent.paint(g);
5170                     }
5171                 } finally {
5172                     g.dispose();
5173                 }
5174             }
5175         }
5176         finally {
5177             // Reset the painting child for the parent components.
5178             if(paintingComponent != this) {
5179                 Component comp;
5180                 int i = pIndex;
5181                 for(; i > 0 ; i--) {
5182                     comp = path.get(i);
5183                     if(comp instanceof JComponent) {
5184                         ((JComponent)comp).setPaintingChild(null);
5185                     }
5186                 }
5187             }
5188             paintingComponent.setFlag(IS_REPAINTING, false);
5189         }
5190         recycleRectangle(paintImmediatelyClip);
5191     }
5192 
5193     /**
5194      * Paints to the specified graphics.  This does not set the clip and it
5195      * does not adjust the Graphics in anyway, callers must do that first.
5196      * This method is package-private for RepaintManager.PaintManager and
5197      * its subclasses to call, it is NOT intended for general use outside
5198      * of that.
5199      */
5200     void paintToOffscreen(Graphics g, int x, int y, int w, int h, int maxX,
5201                           int maxY) {
5202         try {
5203             setFlag(ANCESTOR_USING_BUFFER, true);
5204             if ((y + h) < maxY || (x + w) < maxX) {
5205                 setFlag(IS_PAINTING_TILE, true);
5206             }
5207             if (getFlag(IS_REPAINTING)) {
5208                 // Called from paintImmediately (RepaintManager) to fill
5209                 // repaint request
5210                 paint(g);
5211             } else {
5212                 // Called from paint() (AWT) to repair damage
5213                 if(!rectangleIsObscured(x, y, w, h)) {
5214                     paintComponent(g);
5215                     paintBorder(g);
5216                 }
5217                 paintChildren(g);
5218             }
5219         } finally {
5220             setFlag(ANCESTOR_USING_BUFFER, false);
5221             setFlag(IS_PAINTING_TILE, false);
5222         }
5223     }
5224 
5225     /**
5226      * Returns whether or not the region of the specified component is
5227      * obscured by a sibling.
5228      *
5229      * @return NOT_OBSCURED if non of the siblings above the Component obscure
5230      *         it, COMPLETELY_OBSCURED if one of the siblings completely
5231      *         obscures the Component or PARTIALLY_OBSCURED if the Component is
5232      *         only partially obscured.
5233      */
5234     private int getObscuredState(int compIndex, int x, int y, int width,
5235                                  int height) {
5236         int retValue = NOT_OBSCURED;
5237         Rectangle tmpRect = fetchRectangle();
5238 
5239         for (int i = compIndex - 1 ; i >= 0 ; i--) {
5240             Component sibling = getComponent(i);
5241             if (!sibling.isVisible()) {
5242                 continue;
5243             }
5244             Rectangle siblingRect;
5245             boolean opaque;
5246             if (sibling instanceof JComponent) {
5247                 opaque = sibling.isOpaque();
5248                 if (!opaque) {
5249                     if (retValue == PARTIALLY_OBSCURED) {
5250                         continue;
5251                     }
5252                 }
5253             }
5254             else {
5255                 opaque = true;
5256             }
5257             siblingRect = sibling.getBounds(tmpRect);
5258             if (opaque && x >= siblingRect.x && (x + width) <=
5259                      (siblingRect.x + siblingRect.width) &&
5260                      y >= siblingRect.y && (y + height) <=
5261                      (siblingRect.y + siblingRect.height)) {
5262                 recycleRectangle(tmpRect);
5263                 return COMPLETELY_OBSCURED;
5264             }
5265             else if (retValue == NOT_OBSCURED &&
5266                      !((x + width <= siblingRect.x) ||
5267                        (y + height <= siblingRect.y) ||
5268                        (x >= siblingRect.x + siblingRect.width) ||
5269                        (y >= siblingRect.y + siblingRect.height))) {
5270                 retValue = PARTIALLY_OBSCURED;
5271             }
5272         }
5273         recycleRectangle(tmpRect);
5274         return retValue;
5275     }
5276 
5277     /**
5278      * Returns true, which implies that before checking if a child should
5279      * be painted it is first check that the child is not obscured by another
5280      * sibling. This is only checked if <code>isOptimizedDrawingEnabled</code>
5281      * returns false.
5282      *
5283      * @return always returns true
5284      */
5285     boolean checkIfChildObscuredBySibling() {
5286         return true;
5287     }
5288 
5289 
5290     private void setFlag(int aFlag, boolean aValue) {
5291         if(aValue) {
5292             flags |= (1 << aFlag);
5293         } else {
5294             flags &= ~(1 << aFlag);
5295         }
5296     }
5297     private boolean getFlag(int aFlag) {
5298         int mask = (1 << aFlag);
5299         return ((flags & mask) == mask);
5300     }
5301     // These functions must be static so that they can be called from
5302     // subclasses inside the package, but whose inheritance hierarhcy includes
5303     // classes outside of the package below JComponent (e.g., JTextArea).
5304     static void setWriteObjCounter(JComponent comp, byte count) {
5305         comp.flags = (comp.flags & ~(0xFF << WRITE_OBJ_COUNTER_FIRST)) |
5306                      (count << WRITE_OBJ_COUNTER_FIRST);
5307     }
5308     static byte getWriteObjCounter(JComponent comp) {
5309         return (byte)((comp.flags >> WRITE_OBJ_COUNTER_FIRST) & 0xFF);
5310     }
5311 
5312     /** Buffering **/
5313 
5314     /**
5315      *  Sets whether this component should use a buffer to paint.
5316      *  If set to true, all the drawing from this component will be done
5317      *  in an offscreen painting buffer. The offscreen painting buffer will
5318      *  the be copied onto the screen.
5319      *  If a <code>Component</code> is buffered and one of its ancestor
5320      *  is also buffered, the ancestor buffer will be used.
5321      *
5322      *  @param aFlag if true, set this component to be double buffered
5323      */
5324     public void setDoubleBuffered(boolean aFlag) {
5325         setFlag(IS_DOUBLE_BUFFERED,aFlag);
5326     }
5327 
5328     /**
5329      * Returns whether this component should use a buffer to paint.
5330      *
5331      * @return true if this component is double buffered, otherwise false
5332      */
5333     public boolean isDoubleBuffered() {
5334         return getFlag(IS_DOUBLE_BUFFERED);
5335     }
5336 
5337     /**
5338      * Returns the <code>JRootPane</code> ancestor for this component.
5339      *
5340      * @return the <code>JRootPane</code> that contains this component,
5341      *          or <code>null</code> if no <code>JRootPane</code> is found
5342      */
5343     public JRootPane getRootPane() {
5344         return SwingUtilities.getRootPane(this);
5345     }
5346 
5347 
5348     /** Serialization **/
5349 
5350     /**
5351      * This is called from Component by way of reflection. Do NOT change
5352      * the name unless you change the code in Component as well.
5353      */
5354     void compWriteObjectNotify() {
5355         byte count = JComponent.getWriteObjCounter(this);
5356         JComponent.setWriteObjCounter(this, (byte)(count + 1));
5357         if (count != 0) {
5358             return;
5359         }
5360 
5361         uninstallUIAndProperties();
5362 
5363         /* JTableHeader is in a separate package, which prevents it from
5364          * being able to override this package-private method the way the
5365          * other components can.  We don't want to make this method protected
5366          * because it would introduce public-api for a less-than-desirable
5367          * serialization scheme, so we compromise with this 'instanceof' hack
5368          * for now.
5369          */
5370         if (getToolTipText() != null ||
5371             this instanceof javax.swing.table.JTableHeader) {
5372             ToolTipManager.sharedInstance().unregisterComponent(JComponent.this);
5373         }
5374     }
5375 
5376     /**
5377      * This object is the <code>ObjectInputStream</code> callback
5378      * that's called after a complete graph of objects (including at least
5379      * one <code>JComponent</code>) has been read.
5380      *  It sets the UI property of each Swing component
5381      * that was read to the current default with <code>updateUI</code>.
5382      * <p>
5383      * As each  component is read in we keep track of the current set of
5384      * root components here, in the roots vector.  Note that there's only one
5385      * <code>ReadObjectCallback</code> per <code>ObjectInputStream</code>,
5386      * they're stored in the static <code>readObjectCallbacks</code>
5387      * hashtable.
5388      *
5389      * @see java.io.ObjectInputStream#registerValidation
5390      * @see SwingUtilities#updateComponentTreeUI
5391      */
5392     private class ReadObjectCallback implements ObjectInputValidation
5393     {
5394         private final Vector<JComponent> roots = new Vector<JComponent>(1);
5395         private final ObjectInputStream inputStream;
5396 
5397         ReadObjectCallback(ObjectInputStream s) throws Exception {
5398             inputStream = s;
5399             s.registerValidation(this, 0);
5400         }
5401 
5402         /**
5403          * This is the method that's called after the entire graph
5404          * of objects has been read in.  It initializes
5405          * the UI property of all of the copmonents with
5406          * <code>SwingUtilities.updateComponentTreeUI</code>.
5407          */
5408         public void validateObject() throws InvalidObjectException {
5409             try {
5410                 for (JComponent root : roots) {
5411                     SwingUtilities.updateComponentTreeUI(root);
5412                 }
5413             }
5414             finally {
5415                 readObjectCallbacks.remove(inputStream);
5416             }
5417         }
5418 
5419         /**
5420          * If <code>c</code> isn't a descendant of a component we've already
5421          * seen, then add it to the roots <code>Vector</code>.
5422          *
5423          * @param c the <code>JComponent</code> to add
5424          */
5425         private void registerComponent(JComponent c)
5426         {
5427             /* If the Component c is a descendant of one of the
5428              * existing roots (or it IS an existing root), we're done.
5429              */
5430             for (JComponent root : roots) {
5431                 for(Component p = c; p != null; p = p.getParent()) {
5432                     if (p == root) {
5433                         return;
5434                     }
5435                 }
5436             }
5437 
5438             /* Otherwise: if Component c is an ancestor of any of the
5439              * existing roots then remove them and add c (the "new root")
5440              * to the roots vector.
5441              */
5442             for(int i = 0; i < roots.size(); i++) {
5443                 JComponent root = roots.elementAt(i);
5444                 for(Component p = root.getParent(); p != null; p = p.getParent()) {
5445                     if (p == c) {
5446                         roots.removeElementAt(i--); // !!
5447                         break;
5448                     }
5449                 }
5450             }
5451 
5452             roots.addElement(c);
5453         }
5454     }
5455 
5456 
5457     /**
5458      * We use the <code>ObjectInputStream</code> "registerValidation"
5459      * callback to update the UI for the entire tree of components
5460      * after they've all been read in.
5461      *
5462      * @param s  the <code>ObjectInputStream</code> from which to read
5463      */
5464     private void readObject(ObjectInputStream s)
5465         throws IOException, ClassNotFoundException
5466     {
5467         s.defaultReadObject();
5468 
5469         /* If there's no ReadObjectCallback for this stream yet, that is, if
5470          * this is the first call to JComponent.readObject() for this
5471          * graph of objects, then create a callback and stash it
5472          * in the readObjectCallbacks table.  Note that the ReadObjectCallback
5473          * constructor takes care of calling s.registerValidation().
5474          */
5475         ReadObjectCallback cb = readObjectCallbacks.get(s);
5476         if (cb == null) {
5477             try {
5478                 readObjectCallbacks.put(s, cb = new ReadObjectCallback(s));
5479             }
5480             catch (Exception e) {
5481                 throw new IOException(e.toString());
5482             }
5483         }
5484         cb.registerComponent(this);
5485 
5486         // Read back the client properties.
5487         int cpCount = s.readInt();
5488         if (cpCount > 0) {
5489             clientProperties = new ArrayTable();
5490             for (int counter = 0; counter < cpCount; counter++) {
5491                 clientProperties.put(s.readObject(),
5492                                      s.readObject());
5493             }
5494         }
5495         if (getToolTipText() != null) {
5496             ToolTipManager.sharedInstance().registerComponent(this);
5497         }
5498         setWriteObjCounter(this, (byte)0);
5499         revalidateRunnableScheduled = new AtomicBoolean(false);
5500     }
5501 
5502 
5503     /**
5504      * Before writing a <code>JComponent</code> to an
5505      * <code>ObjectOutputStream</code> we temporarily uninstall its UI.
5506      * This is tricky to do because we want to uninstall
5507      * the UI before any of the <code>JComponent</code>'s children
5508      * (or its <code>LayoutManager</code> etc.) are written,
5509      * and we don't want to restore the UI until the most derived
5510      * <code>JComponent</code> subclass has been been stored.
5511      *
5512      * @param s the <code>ObjectOutputStream</code> in which to write
5513      */
5514     private void writeObject(ObjectOutputStream s) throws IOException {
5515         s.defaultWriteObject();
5516         if (getUIClassID().equals(uiClassID)) {
5517             byte count = JComponent.getWriteObjCounter(this);
5518             JComponent.setWriteObjCounter(this, --count);
5519             if (count == 0 && ui != null) {
5520                 ui.installUI(this);
5521             }
5522         }
5523         ArrayTable.writeArrayTable(s, clientProperties);
5524     }
5525 
5526 
5527     /**
5528      * Returns a string representation of this <code>JComponent</code>.
5529      * This method
5530      * is intended to be used only for debugging purposes, and the
5531      * content and format of the returned string may vary between
5532      * implementations. The returned string may be empty but may not
5533      * be <code>null</code>.
5534      *
5535      * @return  a string representation of this <code>JComponent</code>
5536      */
5537     protected String paramString() {
5538         String preferredSizeString = (isPreferredSizeSet() ?
5539                                       getPreferredSize().toString() : "");
5540         String minimumSizeString = (isMinimumSizeSet() ?
5541                                     getMinimumSize().toString() : "");
5542         String maximumSizeString = (isMaximumSizeSet() ?
5543                                     getMaximumSize().toString() : "");
5544         String borderString = (border == null ? ""
5545                                : (border == this ? "this" : border.toString()));
5546 
5547         return super.paramString() +
5548         ",alignmentX=" + alignmentX +
5549         ",alignmentY=" + alignmentY +
5550         ",border=" + borderString +
5551         ",flags=" + flags +             // should beef this up a bit
5552         ",maximumSize=" + maximumSizeString +
5553         ",minimumSize=" + minimumSizeString +
5554         ",preferredSize=" + preferredSizeString;
5555     }
5556 
5557     /**
5558      * {@inheritDoc}
5559      */
5560     @Override
5561     @Deprecated
5562     public void hide() {
5563         boolean showing = isShowing();
5564         super.hide();
5565         if (showing) {
5566             Container parent = getParent();
5567             if (parent != null) {
5568                 Rectangle r = getBounds();
5569                 parent.repaint(r.x, r.y, r.width, r.height);
5570             }
5571             revalidate();
5572         }
5573     }
5574 
5575 }
5576