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