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