Source Code Cross Referenced for JComponent.java in  » 6.0-JDK-Core » swing » javax » swing » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » swing » javax.swing 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025        package javax.swing;
0026
0027        import java.util.HashSet;
0028        import java.util.Hashtable;
0029        import java.util.Dictionary;
0030        import java.util.Enumeration;
0031        import java.util.Locale;
0032        import java.util.Vector;
0033        import java.util.EventListener;
0034        import java.util.Set;
0035        import java.util.Map;
0036        import java.util.HashMap;
0037
0038        import java.awt.*;
0039        import java.awt.event.*;
0040        import java.awt.image.VolatileImage;
0041        import java.awt.Graphics2D;
0042        import java.awt.peer.LightweightPeer;
0043        import java.awt.dnd.DropTarget;
0044        import java.awt.font.FontRenderContext;
0045        import java.beans.*;
0046
0047        import java.applet.Applet;
0048
0049        import java.io.Serializable;
0050        import java.io.ObjectOutputStream;
0051        import java.io.ObjectInputStream;
0052        import java.io.IOException;
0053        import java.io.ObjectInputValidation;
0054        import java.io.InvalidObjectException;
0055
0056        import javax.swing.border.*;
0057        import javax.swing.event.*;
0058        import javax.swing.plaf.*;
0059        import static javax.swing.ClientPropertyKey.*;
0060        import javax.accessibility.*;
0061
0062        import sun.swing.SwingUtilities2;
0063        import sun.swing.UIClientPropertyKey;
0064
0065        /**
0066         * The base class for all Swing components except top-level containers.
0067         * To use a component that inherits from <code>JComponent</code>,
0068         * you must place the component in a containment hierarchy
0069         * whose root is a top-level Swing container.
0070         * Top-level Swing containers --
0071         * such as <code>JFrame</code>, <code>JDialog</code>, 
0072         * and <code>JApplet</code> --
0073         * are specialized components
0074         * that provide a place for other Swing components to paint themselves.
0075         * For an explanation of containment hierarchies, see
0076         * <a
0077         href="http://java.sun.com/docs/books/tutorial/uiswing/overview/hierarchy.html">Swing Components and the Containment Hierarchy</a>,
0078         * a section in <em>The Java Tutorial</em>.
0079         *
0080         * <p>
0081         * The <code>JComponent</code> class provides:
0082         * <ul>
0083         * <li>The base class for both standard and custom components
0084         *     that use the Swing architecture.
0085         * <li>A "pluggable look and feel" (L&F) that can be specified by the
0086         *     programmer or (optionally) selected by the user at runtime.
0087         *     The look and feel for each component is provided by a 
0088         *     <em>UI delegate</em> -- an object that descends from
0089         *     {@link javax.swing.plaf.ComponentUI}.
0090         *     See <a
0091         * href="http://java.sun.com/docs/books/tutorial/uiswing/misc/plaf.html">How
0092         *     to Set the Look and Feel</a>
0093         *     in <em>The Java Tutorial</em>
0094         *     for more information.
0095         * <li>Comprehensive keystroke handling.
0096         *     See the document <a
0097         * href="http://java.sun.com/products/jfc/tsc/special_report/kestrel/keybindings.html">Keyboard
0098         *     Bindings in Swing</a>,
0099         *     an article in <em>The Swing Connection</em>,
0100         *     for more information.
0101         * <li>Support for tool tips --
0102         *     short descriptions that pop up when the cursor lingers
0103         *     over a component.
0104         *     See <a
0105         * href="http://java.sun.com/docs/books/tutorial/uiswing/components/tooltip.html">How
0106         *     to Use Tool Tips</a>
0107         *     in <em>The Java Tutorial</em>
0108         *     for more information.
0109         * <li>Support for accessibility.
0110         *     <code>JComponent</code> contains all of the methods in the
0111         *     <code>Accessible</code> interface,
0112         *     but it doesn't actually implement the interface.  That is the
0113         *     responsibility of the individual classes
0114         *     that extend <code>JComponent</code>.
0115         * <li>Support for component-specific properties.
0116         *     With the {@link #putClientProperty}
0117         *     and {@link #getClientProperty} methods,
0118         *     you can associate name-object pairs
0119         *     with any object that descends from <code>JComponent</code>.
0120         * <li>An infrastructure for painting
0121         *     that includes double buffering and support for borders.
0122         *     For more information see <a
0123         * href="http://java.sun.com/docs/books/tutorial/uiswing/overview/draw.html">Painting</a> and
0124         * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/border.html">How
0125         *     to Use Borders</a>,
0126         *     both of which are sections in <em>The Java Tutorial</em>.
0127         * </ul>
0128         * For more information on these subjects, see the
0129         * <a href="package-summary.html#package_description">Swing package description</a> 
0130         * and <em>The Java Tutorial</em> section
0131         * <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/jcomponent.html">The JComponent Class</a>.
0132         * <p>
0133         * <code>JComponent</code> and its subclasses document default values
0134         * for certain properties.  For example, <code>JTable</code> documents the
0135         * default row height as 16.  Each <code>JComponent</code> subclass
0136         * that has a <code>ComponentUI</code> will create the
0137         * <code>ComponentUI</code> as part of its constructor.  In order
0138         * to provide a particular look and feel each
0139         * <code>ComponentUI</code> may set properties back on the
0140         * <code>JComponent</code> that created it.  For example, a custom
0141         * look and feel may require <code>JTable</code>s to have a row
0142         * height of 24. The documented defaults are the value of a property
0143         * BEFORE the <code>ComponentUI</code> has been installed.  If you
0144         * need a specific value for a particular property you should
0145         * explicitly set it.
0146         * <p>
0147         * In release 1.4, the focus subsystem was rearchitected.
0148         * For more information, see
0149         * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
0150         * How to Use the Focus Subsystem</a>,
0151         * a section in <em>The Java Tutorial</em>.
0152         * <p>
0153         * <strong>Warning:</strong> Swing is not thread safe. For more
0154         * information see <a
0155         * href="package-summary.html#threading">Swing's Threading
0156         * Policy</a>.
0157         * <p>
0158         * <strong>Warning:</strong>
0159         * Serialized objects of this class will not be compatible with
0160         * future Swing releases. The current serialization support is
0161         * appropriate for short term storage or RMI between applications running
0162         * the same version of Swing.  As of 1.4, support for long term storage
0163         * of all JavaBeans<sup><font size="-2">TM</font></sup>
0164         * has been added to the <code>java.beans</code> package.
0165         * Please see {@link java.beans.XMLEncoder}.
0166         *
0167         * @see KeyStroke
0168         * @see Action
0169         * @see #setBorder
0170         * @see #registerKeyboardAction
0171         * @see JOptionPane
0172         * @see #setDebugGraphicsOptions
0173         * @see #setToolTipText
0174         * @see #setAutoscrolls
0175         *
0176         * @version 2.291, 05/05/07
0177         * @author Hans Muller
0178         * @author Arnaud Weber
0179         */
0180        public abstract class JComponent extends Container implements 
0181                Serializable, TransferHandler.HasGetTransferHandler {
0182            /**
0183             * @see #getUIClassID
0184             * @see #writeObject
0185             */
0186            private static final String uiClassID = "ComponentUI";
0187
0188            /**
0189             * @see #readObject
0190             */
0191            private static final Hashtable readObjectCallbacks = new Hashtable(
0192                    1);
0193
0194            /**
0195             * Keys to use for forward focus traversal when the JComponent is
0196             * managing focus.
0197             */
0198            private static Set<KeyStroke> managingFocusForwardTraversalKeys;
0199
0200            /**
0201             * Keys to use for backward focus traversal when the JComponent is
0202             * managing focus.
0203             */
0204            private static Set<KeyStroke> managingFocusBackwardTraversalKeys;
0205
0206            // Following are the possible return values from getObscuredState.
0207            private static final int NOT_OBSCURED = 0;
0208            private static final int PARTIALLY_OBSCURED = 1;
0209            private static final int COMPLETELY_OBSCURED = 2;
0210
0211            /**
0212             * Set to true when DebugGraphics has been loaded.
0213             */
0214            static boolean DEBUG_GRAPHICS_LOADED;
0215
0216            /**
0217             * Key used to look up a value from the AppContext to determine the 
0218             * JComponent the InputVerifier is running for. That is, if
0219             * AppContext.get(INPUT_VERIFIER_SOURCE_KEY) returns non-null, it
0220             * indicates the EDT is calling into the InputVerifier from the
0221             * returned component.
0222             */
0223            private static final Object INPUT_VERIFIER_SOURCE_KEY = new StringBuilder(
0224                    "InputVerifierSourceKey");
0225
0226            /* The following fields support set methods for the corresponding
0227             * java.awt.Component properties.
0228             */
0229            private boolean isAlignmentXSet;
0230            private float alignmentX;
0231            private boolean isAlignmentYSet;
0232            private float alignmentY;
0233
0234            /**
0235             * Backing store for JComponent properties and listeners
0236             */
0237
0238            /** The look and feel delegate for this component. */
0239            protected transient ComponentUI ui;
0240            /** A list of event listeners for this component. */
0241            protected EventListenerList listenerList = new EventListenerList();
0242
0243            private transient ArrayTable clientProperties;
0244            private VetoableChangeSupport vetoableChangeSupport;
0245            /**
0246             * Whether or not autoscroll has been enabled.
0247             */
0248            private boolean autoscrolls;
0249            private Border border;
0250            private int flags;
0251
0252            /* Input verifier for this component */
0253            private InputVerifier inputVerifier = null;
0254
0255            private boolean verifyInputWhenFocusTarget = true;
0256
0257            /** 
0258             * Set in <code>_paintImmediately</code>.
0259             * Will indicate the child that initiated the painting operation.
0260             * If <code>paintingChild</code> is opaque, no need to paint
0261             * any child components after <code>paintingChild</code>.
0262             * Test used in <code>paintChildren</code>. 
0263             */
0264            transient Component paintingChild;
0265
0266            /**
0267             * Constant used for <code>registerKeyboardAction</code> that
0268             * means that the command should be invoked when
0269             * the component has the focus.
0270             */
0271            public static final int WHEN_FOCUSED = 0;
0272
0273            /**
0274             * Constant used for <code>registerKeyboardAction</code> that
0275             * means that the command should be invoked when the receiving
0276             * component is an ancestor of the focused component or is
0277             * itself the focused component.
0278             */
0279            public static final int WHEN_ANCESTOR_OF_FOCUSED_COMPONENT = 1;
0280
0281            /**
0282             * Constant used for <code>registerKeyboardAction</code> that
0283             * means that the command should be invoked when
0284             * the receiving component is in the window that has the focus
0285             * or is itself the focused component.
0286             */
0287            public static final int WHEN_IN_FOCUSED_WINDOW = 2;
0288
0289            /**
0290             * Constant used by some of the APIs to mean that no condition is defined.
0291             */
0292            public static final int UNDEFINED_CONDITION = -1;
0293
0294            /**
0295             * The key used by <code>JComponent</code> to access keyboard bindings.
0296             */
0297            private static final String KEYBOARD_BINDINGS_KEY = "_KeyboardBindings";
0298
0299            /**
0300             * An array of <code>KeyStroke</code>s used for
0301             * <code>WHEN_IN_FOCUSED_WINDOW</code> are stashed
0302             * in the client properties under this string.
0303             */
0304            private static final String WHEN_IN_FOCUSED_WINDOW_BINDINGS = "_WhenInFocusedWindow";
0305
0306            /**
0307             * The comment to display when the cursor is over the component,
0308             * also known as a "value tip", "flyover help", or "flyover label".
0309             */
0310            public static final String TOOL_TIP_TEXT_KEY = "ToolTipText";
0311
0312            private static final String NEXT_FOCUS = "nextFocus";
0313
0314            /**
0315             * <code>JPopupMenu</code> assigned to this component
0316             * and all of its childrens
0317             */
0318            private JPopupMenu popupMenu;
0319
0320            /** Private flags **/
0321            private static final int IS_DOUBLE_BUFFERED = 0;
0322            private static final int ANCESTOR_USING_BUFFER = 1;
0323            private static final int IS_PAINTING_TILE = 2;
0324            private static final int IS_OPAQUE = 3;
0325            private static final int KEY_EVENTS_ENABLED = 4;
0326            private static final int FOCUS_INPUTMAP_CREATED = 5;
0327            private static final int ANCESTOR_INPUTMAP_CREATED = 6;
0328            private static final int WIF_INPUTMAP_CREATED = 7;
0329            private static final int ACTIONMAP_CREATED = 8;
0330            private static final int CREATED_DOUBLE_BUFFER = 9;
0331            // bit 10 is free
0332            private static final int IS_PRINTING = 11;
0333            private static final int IS_PRINTING_ALL = 12;
0334            private static final int IS_REPAINTING = 13;
0335            /** Bits 14-21 are used to handle nested writeObject calls. **/
0336            private static final int WRITE_OBJ_COUNTER_FIRST = 14;
0337            private static final int RESERVED_1 = 15;
0338            private static final int RESERVED_2 = 16;
0339            private static final int RESERVED_3 = 17;
0340            private static final int RESERVED_4 = 18;
0341            private static final int RESERVED_5 = 19;
0342            private static final int RESERVED_6 = 20;
0343            private static final int WRITE_OBJ_COUNTER_LAST = 21;
0344
0345            private static final int REQUEST_FOCUS_DISABLED = 22;
0346            private static final int INHERITS_POPUP_MENU = 23;
0347            private static final int OPAQUE_SET = 24;
0348            private static final int AUTOSCROLLS_SET = 25;
0349            private static final int FOCUS_TRAVERSAL_KEYS_FORWARD_SET = 26;
0350            private static final int FOCUS_TRAVERSAL_KEYS_BACKWARD_SET = 27;
0351            private static final int REVALIDATE_RUNNABLE_SCHEDULED = 28;
0352
0353            /**
0354             * Temporary rectangles.
0355             */
0356            private static java.util.List tempRectangles = new java.util.ArrayList(
0357                    11);
0358
0359            /** Used for <code>WHEN_FOCUSED</code> bindings. */
0360            private InputMap focusInputMap;
0361            /** Used for <code>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT</code> bindings. */
0362            private InputMap ancestorInputMap;
0363            /** Used for <code>WHEN_IN_FOCUSED_KEY</code> bindings. */
0364            private ComponentInputMap windowInputMap;
0365
0366            /** ActionMap. */
0367            private ActionMap actionMap;
0368
0369            /** Key used to store the default locale in an AppContext **/
0370            private static final String defaultLocale = "JComponent.defaultLocale";
0371
0372            private static Component componentObtainingGraphicsFrom;
0373            private static Object componentObtainingGraphicsFromLock = new StringBuilder(
0374                    "componentObtainingGraphicsFrom");
0375
0376            /**
0377             * AA text hints.
0378             */
0379            transient private Object aaTextInfo;
0380
0381            static Graphics safelyGetGraphics(Component c) {
0382                return safelyGetGraphics(c, SwingUtilities.getRoot(c));
0383            }
0384
0385            static Graphics safelyGetGraphics(Component c, Component root) {
0386                synchronized (componentObtainingGraphicsFromLock) {
0387                    componentObtainingGraphicsFrom = root;
0388                    Graphics g = c.getGraphics();
0389                    componentObtainingGraphicsFrom = null;
0390                    return g;
0391                }
0392            }
0393
0394            static void getGraphicsInvoked(Component root) {
0395                if (!JComponent.isComponentObtainingGraphicsFrom(root)) {
0396                    JRootPane rootPane = ((RootPaneContainer) root)
0397                            .getRootPane();
0398                    if (rootPane != null) {
0399                        rootPane.disableTrueDoubleBuffering();
0400                    }
0401                }
0402            }
0403
0404            /**
0405             * Returns true if {@code c} is the component the graphics is being
0406             * requested of. This is intended for use when getGraphics is invoked.
0407             */
0408            private static boolean isComponentObtainingGraphicsFrom(Component c) {
0409                synchronized (componentObtainingGraphicsFromLock) {
0410                    return (componentObtainingGraphicsFrom == c);
0411                }
0412            }
0413
0414            /**
0415             * Returns the Set of <code>KeyStroke</code>s to use if the component
0416             * is managing focus for forward focus traversal.
0417             */
0418            static Set<KeyStroke> getManagingFocusForwardTraversalKeys() {
0419                synchronized (JComponent.class) {
0420                    if (managingFocusForwardTraversalKeys == null) {
0421                        managingFocusForwardTraversalKeys = new HashSet<KeyStroke>(
0422                                1);
0423                        managingFocusForwardTraversalKeys.add(KeyStroke
0424                                .getKeyStroke(KeyEvent.VK_TAB,
0425                                        InputEvent.CTRL_MASK));
0426                    }
0427                }
0428                return managingFocusForwardTraversalKeys;
0429            }
0430
0431            /**
0432             * Returns the Set of <code>KeyStroke</code>s to use if the component
0433             * is managing focus for backward focus traversal.
0434             */
0435            static Set<KeyStroke> getManagingFocusBackwardTraversalKeys() {
0436                synchronized (JComponent.class) {
0437                    if (managingFocusBackwardTraversalKeys == null) {
0438                        managingFocusBackwardTraversalKeys = new HashSet<KeyStroke>(
0439                                1);
0440                        managingFocusBackwardTraversalKeys.add(KeyStroke
0441                                .getKeyStroke(KeyEvent.VK_TAB,
0442                                        InputEvent.SHIFT_MASK
0443                                                | InputEvent.CTRL_MASK));
0444                    }
0445                }
0446                return managingFocusBackwardTraversalKeys;
0447            }
0448
0449            private static Rectangle fetchRectangle() {
0450                synchronized (tempRectangles) {
0451                    Rectangle rect;
0452                    int size = tempRectangles.size();
0453                    if (size > 0) {
0454                        rect = (Rectangle) tempRectangles.remove(size - 1);
0455                    } else {
0456                        rect = new Rectangle(0, 0, 0, 0);
0457                    }
0458                    return rect;
0459                }
0460            }
0461
0462            private static void recycleRectangle(Rectangle rect) {
0463                synchronized (tempRectangles) {
0464                    tempRectangles.add(rect);
0465                }
0466            }
0467
0468            /**
0469             * Sets whether or not <code>getComponentPopupMenu</code> should delegate
0470             * to the parent if this component does not have a <code>JPopupMenu</code>
0471             * assigned to it.
0472             * <p>
0473             * The default value for this is false, but some <code>JComponent</code>
0474             * subclasses that are implemented as a number of <code>JComponent</code>s
0475             * may set this to true.
0476             * <p>
0477             * This is a bound property.
0478             *
0479             * @param value whether or not the JPopupMenu is inherited
0480             * @see #setComponentPopupMenu
0481             * @beaninfo
0482             *        bound: true
0483             *  description: Whether or not the JPopupMenu is inherited
0484             * @since 1.5
0485             */
0486            public void setInheritsPopupMenu(boolean value) {
0487                boolean oldValue = getFlag(INHERITS_POPUP_MENU);
0488                setFlag(INHERITS_POPUP_MENU, value);
0489                firePropertyChange("inheritsPopupMenu", oldValue, value);
0490            }
0491
0492            /**
0493             * Returns true if the JPopupMenu should be inherited from the parent.
0494             *
0495             * @see #setComponentPopupMenu
0496             * @since 1.5
0497             */
0498            public boolean getInheritsPopupMenu() {
0499                return getFlag(INHERITS_POPUP_MENU);
0500            }
0501
0502            /**
0503             * Sets the <code>JPopupMenu</code> for this <code>JComponent</code>.
0504             * The UI is responsible for registering bindings and adding the necessary
0505             * listeners such that the <code>JPopupMenu</code> will be shown at
0506             * the appropriate time. When the <code>JPopupMenu</code> is shown
0507             * depends upon the look and feel: some may show it on a mouse event,
0508             * some may enable a key binding.
0509             * <p>
0510             * If <code>popup</code> is null, and <code>getInheritsPopupMenu</code>
0511             * returns true, then <code>getComponentPopupMenu</code> will be delegated
0512             * to the parent. This provides for a way to make all child components
0513             * inherit the popupmenu of the parent.
0514             * <p>
0515             * This is a bound property.
0516             *
0517             * @param popup - the popup that will be assigned to this component
0518             *                may be null
0519             * @see #getComponentPopupMenu
0520             * @beaninfo
0521             *        bound: true
0522             *    preferred: true
0523             *  description: Popup to show
0524             * @since 1.5
0525             */
0526            public void setComponentPopupMenu(JPopupMenu popup) {
0527                if (popup != null) {
0528                    enableEvents(AWTEvent.MOUSE_EVENT_MASK);
0529                }
0530                JPopupMenu oldPopup = this .popupMenu;
0531                this .popupMenu = popup;
0532                firePropertyChange("componentPopupMenu", oldPopup, popup);
0533            }
0534
0535            /**
0536             * Returns <code>JPopupMenu</code> that assigned for this component.
0537             * If this component does not have a <code>JPopupMenu</code> assigned
0538             * to it and <code>getInheritsPopupMenu</code> is true, this
0539             * will return <code>getParent().getComponentPopupMenu()</code> (assuming
0540             * the parent is valid.)
0541             *
0542             * @return <code>JPopupMenu</code> assigned for this component
0543             *         or <code>null</code> if no popup assigned
0544             * @see #setComponentPopupMenu
0545             * @since 1.5
0546             */
0547            public JPopupMenu getComponentPopupMenu() {
0548
0549                if (!getInheritsPopupMenu()) {
0550                    return popupMenu;
0551                }
0552
0553                if (popupMenu == null) {
0554                    // Search parents for its popup
0555                    Container parent = getParent();
0556                    while (parent != null) {
0557                        if (parent instanceof  JComponent) {
0558                            return ((JComponent) parent)
0559                                    .getComponentPopupMenu();
0560                        }
0561                        if (parent instanceof  Window
0562                                || parent instanceof  Applet) {
0563                            // Reached toplevel, break and return null
0564                            break;
0565                        }
0566                        parent = parent.getParent();
0567                    }
0568                    return null;
0569                }
0570
0571                return popupMenu;
0572            }
0573
0574            /**
0575             * Default <code>JComponent</code> constructor.  This constructor does
0576             * very little initialization beyond calling the <code>Container</code> 
0577             * constructor.  For example, the initial layout manager is 
0578             * <code>null</code>. It does, however, set the component's locale 
0579             * property to the value returned by 
0580             * <code>JComponent.getDefaultLocale</code>.
0581             *
0582             * @see #getDefaultLocale
0583             */
0584            public JComponent() {
0585                super ();
0586                // We enable key events on all JComponents so that accessibility
0587                // bindings will work everywhere. This is a partial fix to BugID
0588                // 4282211.
0589                enableEvents(AWTEvent.KEY_EVENT_MASK);
0590                if (isManagingFocus()) {
0591                    LookAndFeel.installProperty(this ,
0592                            "focusTraversalKeysForward",
0593                            getManagingFocusForwardTraversalKeys());
0594                    LookAndFeel.installProperty(this ,
0595                            "focusTraversalKeysBackward",
0596                            getManagingFocusBackwardTraversalKeys());
0597                }
0598
0599                super .setLocale(JComponent.getDefaultLocale());
0600            }
0601
0602            /**
0603             * Resets the UI property to a value from the current look and feel.
0604             * <code>JComponent</code> subclasses must override this method
0605             * like this:
0606             * <pre>
0607             *   public void updateUI() {
0608             *      setUI((SliderUI)UIManager.getUI(this);
0609             *   }
0610             *  </pre>
0611             *
0612             * @see #setUI
0613             * @see UIManager#getLookAndFeel
0614             * @see UIManager#getUI
0615             */
0616            public void updateUI() {
0617            }
0618
0619            /**
0620             * Sets the look and feel delegate for this component.
0621             * <code>JComponent</code> subclasses generally override this method
0622             * to narrow the argument type. For example, in <code>JSlider</code>:
0623             * <pre>
0624             * public void setUI(SliderUI newUI) {
0625             *     super.setUI(newUI);
0626             * }
0627             *  </pre>
0628             * <p>
0629             * Additionally <code>JComponent</code> subclasses must provide a
0630             * <code>getUI</code> method that returns the correct type.  For example:
0631             * <pre>
0632             * public SliderUI getUI() {
0633             *     return (SliderUI)ui;
0634             * }
0635             * </pre>
0636             *
0637             * @param newUI the new UI delegate
0638             * @see #updateUI
0639             * @see UIManager#getLookAndFeel
0640             * @see UIManager#getUI
0641             * @beaninfo
0642             *        bound: true
0643             *       hidden: true
0644             *    attribute: visualUpdate true
0645             *  description: The component's look and feel delegate.
0646             */
0647            protected void setUI(ComponentUI newUI) {
0648                /* We do not check that the UI instance is different
0649                 * before allowing the switch in order to enable the
0650                 * same UI instance *with different default settings*
0651                 * to be installed.
0652                 */
0653
0654                uninstallUIAndProperties();
0655
0656                // aaText shouldn't persist between look and feels, reset it.
0657                aaTextInfo = UIManager.getDefaults().get(
0658                        SwingUtilities2.AA_TEXT_PROPERTY_KEY);
0659                ComponentUI oldUI = ui;
0660                ui = newUI;
0661                if (ui != null) {
0662                    ui.installUI(this );
0663                }
0664
0665                firePropertyChange("UI", oldUI, newUI);
0666                revalidate();
0667                repaint();
0668            }
0669
0670            /**
0671             * Uninstalls the UI, if any, and any client properties designated
0672             * as being specific to the installed UI - instances of
0673             * {@code UIClientPropertyKey}.
0674             */
0675            private void uninstallUIAndProperties() {
0676                if (ui != null) {
0677                    ui.uninstallUI(this );
0678                    //clean UIClientPropertyKeys from client properties
0679                    if (clientProperties != null) {
0680                        synchronized (clientProperties) {
0681                            Object[] clientPropertyKeys = clientProperties
0682                                    .getKeys(null);
0683                            if (clientPropertyKeys != null) {
0684                                for (Object key : clientPropertyKeys) {
0685                                    if (key instanceof  UIClientPropertyKey) {
0686                                        putClientProperty(key, null);
0687                                    }
0688                                }
0689                            }
0690                        }
0691                    }
0692                }
0693            }
0694
0695            /**
0696             * Returns the <code>UIDefaults</code> key used to
0697             * look up the name of the <code>swing.plaf.ComponentUI</code>
0698             * class that defines the look and feel
0699             * for this component.  Most applications will never need to
0700             * call this method.  Subclasses of <code>JComponent</code> that support
0701             * pluggable look and feel should override this method to
0702             * return a <code>UIDefaults</code> key that maps to the
0703             * <code>ComponentUI</code> subclass that defines their look and feel.
0704             *
0705             * @return the <code>UIDefaults</code> key for a
0706             *		<code>ComponentUI</code> subclass
0707             * @see UIDefaults#getUI
0708             * @beaninfo
0709             *      expert: true
0710             * description: UIClassID
0711             */
0712            public String getUIClassID() {
0713                return uiClassID;
0714            }
0715
0716            /**
0717             * Returns the graphics object used to paint this component.
0718             * If <code>DebugGraphics</code> is turned on we create a new
0719             * <code>DebugGraphics</code> object if necessary.
0720             * Otherwise we just configure the
0721             * specified graphics object's foreground and font.
0722             *
0723             * @param g the original <code>Graphics</code> object
0724             * @return a <code>Graphics</code> object configured for this component
0725             */
0726            protected Graphics getComponentGraphics(Graphics g) {
0727                Graphics componentGraphics = g;
0728                if (ui != null && DEBUG_GRAPHICS_LOADED) {
0729                    if ((DebugGraphics.debugComponentCount() != 0)
0730                            && (shouldDebugGraphics() != 0)
0731                            && !(g instanceof  DebugGraphics)) {
0732                        componentGraphics = new DebugGraphics(g, this );
0733                    }
0734                }
0735                componentGraphics.setColor(getForeground());
0736                componentGraphics.setFont(getFont());
0737
0738                return componentGraphics;
0739            }
0740
0741            /**
0742             * Calls the UI delegate's paint method, if the UI delegate
0743             * is non-<code>null</code>.  We pass the delegate a copy of the
0744             * <code>Graphics</code> object to protect the rest of the
0745             * paint code from irrevocable changes
0746             * (for example, <code>Graphics.translate</code>).
0747             * <p>
0748             * If you override this in a subclass you should not make permanent
0749             * changes to the passed in <code>Graphics</code>. For example, you
0750             * should not alter the clip <code>Rectangle</code> or modify the
0751             * transform. If you need to do these operations you may find it
0752             * easier to create a new <code>Graphics</code> from the passed in
0753             * <code>Graphics</code> and manipulate it. Further, if you do not
0754             * invoker super's implementation you must honor the opaque property,
0755             * that is
0756             * if this component is opaque, you must completely fill in the background
0757             * in a non-opaque color. If you do not honor the opaque property you
0758             * will likely see visual artifacts.
0759             * <p>
0760             * The passed in <code>Graphics</code> object might
0761             * have a transform other than the identify transform
0762             * installed on it.  In this case, you might get
0763             * unexpected results if you cumulatively apply
0764             * another transform.
0765             *
0766             * @param g the <code>Graphics</code> object to protect
0767             * @see #paint
0768             * @see ComponentUI
0769             */
0770            protected void paintComponent(Graphics g) {
0771                if (ui != null) {
0772                    Graphics scratchGraphics = (g == null) ? null : g.create();
0773                    try {
0774                        ui.update(scratchGraphics, this );
0775                    } finally {
0776                        scratchGraphics.dispose();
0777                    }
0778                }
0779            }
0780
0781            /**
0782             * Paints this component's children.
0783             * If <code>shouldUseBuffer</code> is true,
0784             * no component ancestor has a buffer and
0785             * the component children can use a buffer if they have one.
0786             * Otherwise, one ancestor has a buffer currently in use and children
0787             * should not use a buffer to paint.
0788             * @param g  the <code>Graphics</code> context in which to paint
0789             * @see #paint
0790             * @see java.awt.Container#paint
0791             */
0792            protected void paintChildren(Graphics g) {
0793                boolean isJComponent;
0794                Graphics sg = g;
0795
0796                synchronized (getTreeLock()) {
0797                    int i = getComponentCount() - 1;
0798                    if (i < 0) {
0799                        return;
0800                    }
0801                    // If we are only to paint to a specific child, determine
0802                    // its index.
0803                    if (paintingChild != null
0804                            && (paintingChild instanceof  JComponent)
0805                            && ((JComponent) paintingChild).isOpaque()) {
0806                        for (; i >= 0; i--) {
0807                            if (getComponent(i) == paintingChild) {
0808                                break;
0809                            }
0810                        }
0811                    }
0812                    Rectangle tmpRect = fetchRectangle();
0813                    boolean checkSiblings = (!isOptimizedDrawingEnabled() && checkIfChildObscuredBySibling());
0814                    Rectangle clipBounds = null;
0815                    if (checkSiblings) {
0816                        clipBounds = sg.getClipBounds();
0817                        if (clipBounds == null) {
0818                            clipBounds = new Rectangle(0, 0, getWidth(),
0819                                    getHeight());
0820                        }
0821                    }
0822                    boolean printing = getFlag(IS_PRINTING);
0823                    for (; i >= 0; i--) {
0824                        Component comp = getComponent(i);
0825                        isJComponent = (comp instanceof  JComponent);
0826                        if (comp != null
0827                                && (isJComponent || isLightweightComponent(comp))
0828                                && (comp.isVisible() == true)) {
0829                            Rectangle cr;
0830
0831                            cr = comp.getBounds(tmpRect);
0832
0833                            boolean hitClip = g.hitClip(cr.x, cr.y, cr.width,
0834                                    cr.height);
0835
0836                            if (hitClip) {
0837                                if (checkSiblings && i > 0) {
0838                                    int x = cr.x;
0839                                    int y = cr.y;
0840                                    int width = cr.width;
0841                                    int height = cr.height;
0842                                    SwingUtilities.computeIntersection(
0843                                            clipBounds.x, clipBounds.y,
0844                                            clipBounds.width,
0845                                            clipBounds.height, cr);
0846
0847                                    if (getObscuredState(i, cr.x, cr.y,
0848                                            cr.width, cr.height) == COMPLETELY_OBSCURED) {
0849                                        continue;
0850                                    }
0851                                    cr.x = x;
0852                                    cr.y = y;
0853                                    cr.width = width;
0854                                    cr.height = height;
0855                                }
0856                                Graphics cg = sg.create(cr.x, cr.y, cr.width,
0857                                        cr.height);
0858                                cg.setColor(comp.getForeground());
0859                                cg.setFont(comp.getFont());
0860                                boolean shouldSetFlagBack = false;
0861                                try {
0862                                    if (isJComponent) {
0863                                        if (getFlag(ANCESTOR_USING_BUFFER)) {
0864                                            ((JComponent) comp)
0865                                                    .setFlag(
0866                                                            ANCESTOR_USING_BUFFER,
0867                                                            true);
0868                                            shouldSetFlagBack = true;
0869                                        }
0870                                        if (getFlag(IS_PAINTING_TILE)) {
0871                                            ((JComponent) comp).setFlag(
0872                                                    IS_PAINTING_TILE, true);
0873                                            shouldSetFlagBack = true;
0874                                        }
0875                                        if (!printing) {
0876                                            ((JComponent) comp).paint(cg);
0877                                        } else {
0878                                            if (!getFlag(IS_PRINTING_ALL)) {
0879                                                comp.print(cg);
0880                                            } else {
0881                                                comp.printAll(cg);
0882                                            }
0883                                        }
0884                                    } else {
0885                                        if (!printing) {
0886                                            comp.paint(cg);
0887                                        } else {
0888                                            if (!getFlag(IS_PRINTING_ALL)) {
0889                                                comp.print(cg);
0890                                            } else {
0891                                                comp.printAll(cg);
0892                                            }
0893                                        }
0894                                    }
0895                                } finally {
0896                                    cg.dispose();
0897                                    if (shouldSetFlagBack) {
0898                                        ((JComponent) comp).setFlag(
0899                                                ANCESTOR_USING_BUFFER, false);
0900                                        ((JComponent) comp).setFlag(
0901                                                IS_PAINTING_TILE, false);
0902                                    }
0903                                }
0904                            }
0905                        }
0906
0907                    }
0908                    recycleRectangle(tmpRect);
0909                }
0910            }
0911
0912            /**
0913             * Paints the component's border.
0914             * <p>
0915             * If you override this in a subclass you should not make permanent
0916             * changes to the passed in <code>Graphics</code>. For example, you
0917             * should not alter the clip <code>Rectangle</code> or modify the
0918             * transform. If you need to do these operations you may find it
0919             * easier to create a new <code>Graphics</code> from the passed in
0920             * <code>Graphics</code> and manipulate it.
0921             *
0922             * @param g  the <code>Graphics</code> context in which to paint
0923             *
0924             * @see #paint
0925             * @see #setBorder
0926             */
0927            protected void paintBorder(Graphics g) {
0928                Border border = getBorder();
0929                if (border != null) {
0930                    border.paintBorder(this , g, 0, 0, getWidth(), getHeight());
0931                }
0932            }
0933
0934            /**
0935             * Calls <code>paint</code>.  Doesn't clear the background but see
0936             * <code>ComponentUI.update</code>, which is called by 
0937             * <code>paintComponent</code>.
0938             *
0939             * @param g the <code>Graphics</code> context in which to paint
0940             * @see #paint
0941             * @see #paintComponent
0942             * @see javax.swing.plaf.ComponentUI
0943             */
0944            public void update(Graphics g) {
0945                paint(g);
0946            }
0947
0948            /**
0949             * Invoked by Swing to draw components.
0950             * Applications should not invoke <code>paint</code> directly,
0951             * but should instead use the <code>repaint</code> method to
0952             * schedule the component for redrawing.
0953             * <p>
0954             * This method actually delegates the work of painting to three
0955             * protected methods: <code>paintComponent</code>,
0956             * <code>paintBorder</code>,
0957             * and <code>paintChildren</code>.  They're called in the order
0958             * listed to ensure that children appear on top of component itself.
0959             * Generally speaking, the component and its children should not
0960             * paint in the insets area allocated to the border. Subclasses can
0961             * just override this method, as always.  A subclass that just
0962             * wants to specialize the UI (look and feel) delegate's
0963             * <code>paint</code> method should just override
0964             * <code>paintComponent</code>.
0965             *
0966             * @param g  the <code>Graphics</code> context in which to paint
0967             * @see #paintComponent
0968             * @see #paintBorder
0969             * @see #paintChildren
0970             * @see #getComponentGraphics
0971             * @see #repaint
0972             */
0973            public void paint(Graphics g) {
0974                boolean shouldClearPaintFlags = false;
0975
0976                if ((getWidth() <= 0) || (getHeight() <= 0)) {
0977                    return;
0978                }
0979
0980                Graphics componentGraphics = getComponentGraphics(g);
0981                Graphics co = componentGraphics.create();
0982                try {
0983                    RepaintManager repaintManager = RepaintManager
0984                            .currentManager(this );
0985                    Rectangle clipRect = co.getClipBounds();
0986                    int clipX;
0987                    int clipY;
0988                    int clipW;
0989                    int clipH;
0990                    if (clipRect == null) {
0991                        clipX = clipY = 0;
0992                        clipW = getWidth();
0993                        clipH = getHeight();
0994                    } else {
0995                        clipX = clipRect.x;
0996                        clipY = clipRect.y;
0997                        clipW = clipRect.width;
0998                        clipH = clipRect.height;
0999                    }
1000
1001                    if (clipW > getWidth()) {
1002                        clipW = getWidth();
1003                    }
1004                    if (clipH > getHeight()) {
1005                        clipH = getHeight();
1006                    }
1007
1008                    if (getParent() != null
1009                            && !(getParent() instanceof  JComponent)) {
1010                        adjustPaintFlags();
1011                        shouldClearPaintFlags = true;
1012                    }
1013
1014                    int bw, bh;
1015                    boolean printing = getFlag(IS_PRINTING);
1016                    if (!printing && repaintManager.isDoubleBufferingEnabled()
1017                            && !getFlag(ANCESTOR_USING_BUFFER)
1018                            && isDoubleBuffered()) {
1019                        repaintManager.beginPaint();
1020                        try {
1021                            repaintManager.paint(this , this , co, clipX, clipY,
1022                                    clipW, clipH);
1023                        } finally {
1024                            repaintManager.endPaint();
1025                        }
1026                    } else {
1027                        // Will ocassionaly happen in 1.2, especially when printing.
1028                        if (clipRect == null) {
1029                            co.setClip(clipX, clipY, clipW, clipH);
1030                        }
1031
1032                        if (!rectangleIsObscured(clipX, clipY, clipW, clipH)) {
1033                            if (!printing) {
1034                                paintComponent(co);
1035                                paintBorder(co);
1036                            } else {
1037                                printComponent(co);
1038                                printBorder(co);
1039                            }
1040                        }
1041                        if (!printing) {
1042                            paintChildren(co);
1043                        } else {
1044                            printChildren(co);
1045                        }
1046                    }
1047                } finally {
1048                    co.dispose();
1049                    if (shouldClearPaintFlags) {
1050                        setFlag(ANCESTOR_USING_BUFFER, false);
1051                        setFlag(IS_PAINTING_TILE, false);
1052                        setFlag(IS_PRINTING, false);
1053                        setFlag(IS_PRINTING_ALL, false);
1054                    }
1055                }
1056            }
1057
1058            // paint forcing use of the double buffer.  This is used for historical
1059            // reasons: JViewport, when scrolling, previously directly invoked paint 
1060            // while turning off double buffering at the RepaintManager level, this
1061            // codes simulates that.
1062            void paintForceDoubleBuffered(Graphics g) {
1063                RepaintManager rm = RepaintManager.currentManager(this );
1064                Rectangle clip = g.getClipBounds();
1065                rm.beginPaint();
1066                setFlag(IS_REPAINTING, true);
1067                try {
1068                    rm.paint(this , this , g, clip.x, clip.y, clip.width,
1069                            clip.height);
1070                } finally {
1071                    rm.endPaint();
1072                    setFlag(IS_REPAINTING, false);
1073                }
1074            }
1075
1076            /**
1077             * Returns true if this component, or any of its ancestors, are in
1078             * the processing of painting.
1079             */
1080            boolean isPainting() {
1081                Container component = this ;
1082                while (component != null) {
1083                    if (component instanceof  JComponent
1084                            && ((JComponent) component)
1085                                    .getFlag(ANCESTOR_USING_BUFFER)) {
1086                        return true;
1087                    }
1088                    component = component.getParent();
1089                }
1090                return false;
1091            }
1092
1093            private void adjustPaintFlags() {
1094                JComponent jparent = null;
1095                Container parent;
1096                for (parent = getParent(); parent != null; parent = parent
1097                        .getParent()) {
1098                    if (parent instanceof  JComponent) {
1099                        jparent = (JComponent) parent;
1100                        if (jparent.getFlag(ANCESTOR_USING_BUFFER))
1101                            setFlag(ANCESTOR_USING_BUFFER, true);
1102                        if (jparent.getFlag(IS_PAINTING_TILE))
1103                            setFlag(IS_PAINTING_TILE, true);
1104                        if (jparent.getFlag(IS_PRINTING))
1105                            setFlag(IS_PRINTING, true);
1106                        if (jparent.getFlag(IS_PRINTING_ALL))
1107                            setFlag(IS_PRINTING_ALL, true);
1108                        break;
1109                    }
1110                }
1111            }
1112
1113            /**
1114             * Invoke this method to print the component. This method invokes
1115             * <code>print</code> on the component.
1116             *
1117             * @param g the <code>Graphics</code> context in which to paint
1118             * @see #print
1119             * @see #printComponent
1120             * @see #printBorder
1121             * @see #printChildren
1122             */
1123            public void printAll(Graphics g) {
1124                setFlag(IS_PRINTING_ALL, true);
1125                try {
1126                    print(g);
1127                } finally {
1128                    setFlag(IS_PRINTING_ALL, false);
1129                }
1130            }
1131
1132            /**
1133             * Invoke this method to print the component to the specified
1134             * <code>Graphics</code>. This method will result in invocations
1135             * of <code>printComponent</code>, <code>printBorder</code> and
1136             * <code>printChildren</code>. It is recommended that you override
1137             * one of the previously mentioned methods rather than this one if
1138             * your intention is to customize the way printing looks. However,
1139             * it can be useful to override this method should you want to prepare
1140             * state before invoking the superclass behavior. As an example,
1141             * if you wanted to change the component's background color before
1142             * printing, you could do the following:
1143             * <pre>
1144             *     public void print(Graphics g) {
1145             *         Color orig = getBackground();
1146             *         setBackground(Color.WHITE);
1147             *
1148             *         // wrap in try/finally so that we always restore the state
1149             *         try {
1150             *             super.print(g);
1151             *         } finally {
1152             *             setBackground(orig);
1153             *         }
1154             *     }
1155             * </pre>
1156             * <p>
1157             * Alternatively, or for components that delegate painting to other objects,
1158             * you can query during painting whether or not the component is in the
1159             * midst of a print operation. The <code>isPaintingForPrint</code> method provides
1160             * this ability and its return value will be changed by this method: to
1161             * <code>true</code> immediately before rendering and to <code>false</code>
1162             * immediately after. With each change a property change event is fired on
1163             * this component with the name <code>"paintingForPrint"</code>.
1164             * <p>
1165             * This method sets the component's state such that the double buffer
1166             * will not be used: painting will be done directly on the passed in
1167             * <code>Graphics</code>.
1168             *
1169             * @param g the <code>Graphics</code> context in which to paint
1170             * @see #printComponent
1171             * @see #printBorder
1172             * @see #printChildren
1173             * @see #isPaintingForPrint
1174             */
1175            public void print(Graphics g) {
1176                setFlag(IS_PRINTING, true);
1177                firePropertyChange("paintingForPrint", false, true);
1178                try {
1179                    paint(g);
1180                } finally {
1181                    setFlag(IS_PRINTING, false);
1182                    firePropertyChange("paintingForPrint", true, false);
1183                }
1184            }
1185
1186            /**
1187             * This is invoked during a printing operation. This is implemented to
1188             * invoke <code>paintComponent</code> on the component. Override this
1189             * if you wish to add special painting behavior when printing.
1190             *
1191             * @param g the <code>Graphics</code> context in which to paint
1192             * @see #print
1193             * @since 1.3
1194             */
1195            protected void printComponent(Graphics g) {
1196                paintComponent(g);
1197            }
1198
1199            /**
1200             * Prints this component's children. This is implemented to invoke
1201             * <code>paintChildren</code> on the component. Override this if you
1202             * wish to print the children differently than painting.
1203             *
1204             * @param g the <code>Graphics</code> context in which to paint
1205             * @see #print
1206             * @since 1.3
1207             */
1208            protected void printChildren(Graphics g) {
1209                paintChildren(g);
1210            }
1211
1212            /**
1213             * Prints the component's border. This is implemented to invoke
1214             * <code>paintBorder</code> on the component. Override this if you
1215             * wish to print the border differently that it is painted.
1216             *
1217             * @param g the <code>Graphics</code> context in which to paint
1218             * @see #print
1219             * @since 1.3
1220             */
1221            protected void printBorder(Graphics g) {
1222                paintBorder(g);
1223            }
1224
1225            /**
1226             *  Returns true if the component is currently painting a tile.
1227             *  If this method returns true, paint will be called again for another
1228             *  tile. This method returns false if you are not painting a tile or
1229             *  if the last tile is painted.
1230             *  Use this method to keep some state you might need between tiles.
1231             *
1232             *  @return  true if the component is currently painting a tile,
1233             *		false otherwise
1234             */
1235            public boolean isPaintingTile() {
1236                return getFlag(IS_PAINTING_TILE);
1237            }
1238
1239            /**
1240             * Returns <code>true</code> if the current painting operation on this
1241             * component is part of a <code>print</code> operation. This method is
1242             * useful when you want to customize what you print versus what you show
1243             * on the screen.
1244             * <p>
1245             * You can detect changes in the value of this property by listening for
1246             * property change events on this component with name
1247             * <code>"paintingForPrint"</code>.
1248             * <p>
1249             * Note: This method provides complimentary functionality to that provided
1250             * by other high level Swing printing APIs. However, it deals strictly with
1251             * painting and should not be confused as providing information on higher
1252             * level print processes. For example, a {@link javax.swing.JTable#print()}
1253             * operation doesn't necessarily result in a continuous rendering of the
1254             * full component, and the return value of this method can change multiple
1255             * times during that operation. It is even possible for the component to be
1256             * painted to the screen while the printing process is ongoing. In such a
1257             * case, the return value of this method is <code>true</code> when, and only
1258             * when, the table is being painted as part of the printing process.
1259             *
1260             * @return true if the current painting operation on this component
1261             *         is part of a print operation
1262             * @see #print
1263             * @since 1.6
1264             */
1265            public final boolean isPaintingForPrint() {
1266                return getFlag(IS_PRINTING);
1267            }
1268
1269            /**
1270             * In release 1.4, the focus subsystem was rearchitected.
1271             * For more information, see
1272             * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1273             * How to Use the Focus Subsystem</a>,
1274             * a section in <em>The Java Tutorial</em>.
1275             * <p>
1276             * Changes this <code>JComponent</code>'s focus traversal keys to
1277             * CTRL+TAB and CTRL+SHIFT+TAB. Also prevents
1278             * <code>SortingFocusTraversalPolicy</code> from considering descendants
1279             * of this JComponent when computing a focus traversal cycle.
1280             *
1281             * @see java.awt.Component#setFocusTraversalKeys
1282             * @see SortingFocusTraversalPolicy
1283             * @deprecated As of 1.4, replaced by
1284             *   <code>Component.setFocusTraversalKeys(int, Set)</code> and
1285             *   <code>Container.setFocusCycleRoot(boolean)</code>.
1286             */
1287            @Deprecated
1288            public boolean isManagingFocus() {
1289                return false;
1290            }
1291
1292            private void registerNextFocusableComponent() {
1293                registerNextFocusableComponent(getNextFocusableComponent());
1294            }
1295
1296            private void registerNextFocusableComponent(
1297                    Component nextFocusableComponent) {
1298                if (nextFocusableComponent == null) {
1299                    return;
1300                }
1301
1302                Container nearestRoot = (isFocusCycleRoot()) ? this 
1303                        : getFocusCycleRootAncestor();
1304                FocusTraversalPolicy policy = nearestRoot
1305                        .getFocusTraversalPolicy();
1306                if (!(policy instanceof  LegacyGlueFocusTraversalPolicy)) {
1307                    policy = new LegacyGlueFocusTraversalPolicy(policy);
1308                    nearestRoot.setFocusTraversalPolicy(policy);
1309                }
1310                ((LegacyGlueFocusTraversalPolicy) policy)
1311                        .setNextFocusableComponent(this , nextFocusableComponent);
1312            }
1313
1314            private void deregisterNextFocusableComponent() {
1315                Component nextFocusableComponent = getNextFocusableComponent();
1316                if (nextFocusableComponent == null) {
1317                    return;
1318                }
1319
1320                Container nearestRoot = (isFocusCycleRoot()) ? this 
1321                        : getFocusCycleRootAncestor();
1322                if (nearestRoot == null) {
1323                    return;
1324                }
1325                FocusTraversalPolicy policy = nearestRoot
1326                        .getFocusTraversalPolicy();
1327                if (policy instanceof  LegacyGlueFocusTraversalPolicy) {
1328                    ((LegacyGlueFocusTraversalPolicy) policy)
1329                            .unsetNextFocusableComponent(this ,
1330                                    nextFocusableComponent);
1331                }
1332            }
1333
1334            /**
1335             * In release 1.4, the focus subsystem was rearchitected.
1336             * For more information, see
1337             * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1338             * How to Use the Focus Subsystem</a>,
1339             * a section in <em>The Java Tutorial</em>.
1340             * <p>
1341             * Overrides the default <code>FocusTraversalPolicy</code> for this
1342             * <code>JComponent</code>'s focus traversal cycle by unconditionally
1343             * setting the specified <code>Component</code> as the next
1344             * <code>Component</code> in the cycle, and this <code>JComponent</code>
1345             * as the specified <code>Component</code>'s previous
1346             * <code>Component</code> in the cycle.
1347             *
1348             * @param aComponent the <code>Component</code> that should follow this
1349             *        <code>JComponent</code> in the focus traversal cycle
1350             *
1351             * @see #getNextFocusableComponent
1352             * @see java.awt.FocusTraversalPolicy
1353             * @deprecated As of 1.4, replaced by <code>FocusTraversalPolicy</code>
1354             */
1355            @Deprecated
1356            public void setNextFocusableComponent(Component aComponent) {
1357                boolean displayable = isDisplayable();
1358                if (displayable) {
1359                    deregisterNextFocusableComponent();
1360                }
1361                putClientProperty(NEXT_FOCUS, aComponent);
1362                if (displayable) {
1363                    registerNextFocusableComponent(aComponent);
1364                }
1365            }
1366
1367            /**
1368             * In release 1.4, the focus subsystem was rearchitected.
1369             * For more information, see
1370             * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1371             * How to Use the Focus Subsystem</a>,
1372             * a section in <em>The Java Tutorial</em>.
1373             * <p>
1374             * Returns the <code>Component</code> set by a prior call to
1375             * <code>setNextFocusableComponent(Component)</code> on this
1376             * <code>JComponent</code>.
1377             *
1378             * @return the <code>Component</code> that will follow this
1379             *        <code>JComponent</code> in the focus traversal cycle, or
1380             *        <code>null</code> if none has been explicitly specified
1381             *
1382             * @see #setNextFocusableComponent
1383             * @deprecated As of 1.4, replaced by <code>FocusTraversalPolicy</code>.
1384             */
1385            @Deprecated
1386            public Component getNextFocusableComponent() {
1387                return (Component) getClientProperty(NEXT_FOCUS);
1388            }
1389
1390            /**
1391             * Provides a hint as to whether or not this <code>JComponent</code>
1392             * should get focus. This is only a hint, and it is up to consumers that
1393             * are requesting focus to honor this property. This is typically honored
1394             * for mouse operations, but not keyboard operations. For example, look
1395             * and feels could verify this property is true before requesting focus
1396             * during a mouse operation. This would often times be used if you did
1397             * not want a mouse press on a <code>JComponent</code> to steal focus,
1398             * but did want the <code>JComponent</code> to be traversable via the
1399             * keyboard. If you do not want this <code>JComponent</code> focusable at
1400             * all, use the <code>setFocusable</code> method instead.
1401             * <p>
1402             * Please see
1403             * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1404             * How to Use the Focus Subsystem</a>,
1405             * a section in <em>The Java Tutorial</em>,
1406             * for more information.
1407             * 
1408             * @param requestFocusEnabled indicates whether you want this
1409             *        <code>JComponent</code> to be focusable or not
1410             * @see <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
1411             * @see java.awt.Component#setFocusable
1412             */
1413            public void setRequestFocusEnabled(boolean requestFocusEnabled) {
1414                setFlag(REQUEST_FOCUS_DISABLED, !requestFocusEnabled);
1415            }
1416
1417            /**
1418             * Returns <code>true</code> if this <code>JComponent</code> should
1419             * get focus; otherwise returns <code>false</code>.
1420             * <p>
1421             * Please see
1422             * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1423             * How to Use the Focus Subsystem</a>,
1424             * a section in <em>The Java Tutorial</em>,
1425             * for more information.
1426             * 
1427             * @return <code>true</code> if this component should get focus,
1428             *     otherwise returns <code>false</code>
1429             * @see #setRequestFocusEnabled
1430             * @see <a href="../../java/awt/doc-files/FocusSpec.html">Focus
1431             *      Specification</a>
1432             * @see java.awt.Component#isFocusable
1433             */
1434            public boolean isRequestFocusEnabled() {
1435                return !getFlag(REQUEST_FOCUS_DISABLED);
1436            }
1437
1438            /**
1439             * Requests that this <code>Component</code> gets the input focus.
1440             * Refer to {@link java.awt.Component#requestFocus()
1441             * Component.requestFocus()} for a complete description of
1442             * this method.
1443             * <p>
1444             * Note that the use of this method is discouraged because
1445             * its behavior is platform dependent. Instead we recommend the
1446             * use of {@link #requestFocusInWindow() requestFocusInWindow()}.
1447             * If you would like more information on focus, see
1448             * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1449             * How to Use the Focus Subsystem</a>,
1450             * a section in <em>The Java Tutorial</em>.
1451             *
1452             * @see java.awt.Component#requestFocusInWindow()
1453             * @see java.awt.Component#requestFocusInWindow(boolean)
1454             * @since 1.4
1455             */
1456            public void requestFocus() {
1457                super .requestFocus();
1458            }
1459
1460            /**
1461             * Requests that this <code>Component</code> gets the input focus.
1462             * Refer to {@link java.awt.Component#requestFocus(boolean)
1463             * Component.requestFocus(boolean)} for a complete description of
1464             * this method.
1465             * <p>
1466             * Note that the use of this method is discouraged because
1467             * its behavior is platform dependent. Instead we recommend the
1468             * use of {@link #requestFocusInWindow(boolean)
1469             * requestFocusInWindow(boolean)}.
1470             * If you would like more information on focus, see
1471             * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1472             * How to Use the Focus Subsystem</a>,
1473             * a section in <em>The Java Tutorial</em>.
1474             *
1475             * @param temporary boolean indicating if the focus change is temporary
1476             * @return <code>false</code> if the focus change request is guaranteed to
1477             *         fail; <code>true</code> if it is likely to succeed
1478             * @see java.awt.Component#requestFocusInWindow()
1479             * @see java.awt.Component#requestFocusInWindow(boolean)
1480             * @since 1.4     
1481             */
1482            public boolean requestFocus(boolean temporary) {
1483                return super .requestFocus(temporary);
1484            }
1485
1486            /**
1487             * Requests that this <code>Component</code> gets the input focus.
1488             * Refer to {@link java.awt.Component#requestFocusInWindow()
1489             * Component.requestFocusInWindow()} for a complete description of
1490             * this method.
1491             * <p>
1492             * If you would like more information on focus, see
1493             * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1494             * How to Use the Focus Subsystem</a>,
1495             * a section in <em>The Java Tutorial</em>.
1496             *
1497             * @return <code>false</code> if the focus change request is guaranteed to
1498             *         fail; <code>true</code> if it is likely to succeed
1499             * @see java.awt.Component#requestFocusInWindow()
1500             * @see java.awt.Component#requestFocusInWindow(boolean)
1501             * @since 1.4
1502             */
1503            public boolean requestFocusInWindow() {
1504                return super .requestFocusInWindow();
1505            }
1506
1507            /**
1508             * Requests that this <code>Component</code> gets the input focus.
1509             * Refer to {@link java.awt.Component#requestFocusInWindow(boolean)
1510             * Component.requestFocusInWindow(boolean)} for a complete description of
1511             * this method.
1512             * <p>
1513             * If you would like more information on focus, see
1514             * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1515             * How to Use the Focus Subsystem</a>,
1516             * a section in <em>The Java Tutorial</em>.
1517             *
1518             * @param temporary boolean indicating if the focus change is temporary
1519             * @return <code>false</code> if the focus change request is guaranteed to
1520             *         fail; <code>true</code> if it is likely to succeed
1521             * @see java.awt.Component#requestFocusInWindow()
1522             * @see java.awt.Component#requestFocusInWindow(boolean)
1523             * @since 1.4
1524             */
1525            protected boolean requestFocusInWindow(boolean temporary) {
1526                return super .requestFocusInWindow(temporary);
1527            }
1528
1529            /**
1530             * Requests that this Component get the input focus, and that this
1531             * Component's top-level ancestor become the focused Window. This component
1532             * must be displayable, visible, and focusable for the request to be
1533             * granted.
1534             * <p>
1535             * This method is intended for use by focus implementations. Client code
1536             * should not use this method; instead, it should use
1537             * <code>requestFocusInWindow()</code>.
1538             *
1539             * @see #requestFocusInWindow()
1540             */
1541            public void grabFocus() {
1542                requestFocus();
1543            }
1544
1545            /** 
1546             * Sets the value to indicate whether input verifier for the
1547             * current focus owner will be called before this component requests
1548             * focus. The default is true. Set to false on components such as a
1549             * Cancel button or a scrollbar, which should activate even if the
1550             * input in the current focus owner is not "passed" by the input
1551             * verifier for that component.
1552             *
1553             * @param verifyInputWhenFocusTarget value for the
1554             *        <code>verifyInputWhenFocusTarget</code> property
1555             * @see InputVerifier
1556             * @see #setInputVerifier
1557             * @see #getInputVerifier
1558             * @see #getVerifyInputWhenFocusTarget
1559             *
1560             * @since 1.3
1561             * @beaninfo
1562             *       bound: true
1563             * description: Whether the Component verifies input before accepting
1564             *              focus.
1565             */
1566            public void setVerifyInputWhenFocusTarget(
1567                    boolean verifyInputWhenFocusTarget) {
1568                boolean oldVerifyInputWhenFocusTarget = this .verifyInputWhenFocusTarget;
1569                this .verifyInputWhenFocusTarget = verifyInputWhenFocusTarget;
1570                firePropertyChange("verifyInputWhenFocusTarget",
1571                        oldVerifyInputWhenFocusTarget,
1572                        verifyInputWhenFocusTarget);
1573            }
1574
1575            /** 
1576             * Returns the value that indicates whether the input verifier for the 
1577             * current focus owner will be called before this component requests
1578             * focus.
1579             *          
1580             * @return value of the <code>verifyInputWhenFocusTarget</code> property
1581             *   
1582             * @see InputVerifier
1583             * @see #setInputVerifier
1584             * @see #getInputVerifier
1585             * @see #setVerifyInputWhenFocusTarget
1586             *
1587             * @since 1.3
1588             */
1589            public boolean getVerifyInputWhenFocusTarget() {
1590                return verifyInputWhenFocusTarget;
1591            }
1592
1593            /**
1594             * Gets the <code>FontMetrics</code> for the specified <code>Font</code>.
1595             *
1596             * @param font the font for which font metrics is to be
1597             *          obtained
1598             * @return the font metrics for <code>font</code>
1599             * @throws NullPointerException if <code>font</code> is null
1600             * @since 1.5
1601             */
1602            public FontMetrics getFontMetrics(Font font) {
1603                return SwingUtilities2.getFontMetrics(this , font);
1604            }
1605
1606            /**
1607             * Sets the preferred size of this component.
1608             * If <code>preferredSize</code> is <code>null</code>, the UI will
1609             * be asked for the preferred size.
1610             * @beaninfo
1611             *   preferred: true
1612             *       bound: true
1613             * description: The preferred size of the component.
1614             */
1615            public void setPreferredSize(Dimension preferredSize) {
1616                super .setPreferredSize(preferredSize);
1617            }
1618
1619            /**
1620             * If the <code>preferredSize</code> has been set to a
1621             * non-<code>null</code> value just returns it.
1622             * If the UI delegate's <code>getPreferredSize</code>
1623             * method returns a non <code>null</code> value then return that;
1624             * otherwise defer to the component's layout manager.
1625             *
1626             * @return the value of the <code>preferredSize</code> property
1627             * @see #setPreferredSize
1628             * @see ComponentUI
1629             */
1630            public Dimension getPreferredSize() {
1631                if (isPreferredSizeSet()) {
1632                    return super .getPreferredSize();
1633                }
1634                Dimension size = null;
1635                if (ui != null) {
1636                    size = ui.getPreferredSize(this );
1637                }
1638                return (size != null) ? size : super .getPreferredSize();
1639            }
1640
1641            /**
1642             * Sets the maximum size of this component to a constant
1643             * value.  Subsequent calls to <code>getMaximumSize</code> will always
1644             * return this value; the component's UI will not be asked
1645             * to compute it.  Setting the maximum size to <code>null</code>
1646             * restores the default behavior.
1647             *
1648             * @param maximumSize a <code>Dimension</code> containing the 
1649             *		desired maximum allowable size
1650             * @see #getMaximumSize
1651             * @beaninfo
1652             *       bound: true
1653             * description: The maximum size of the component.
1654             */
1655            public void setMaximumSize(Dimension maximumSize) {
1656                super .setMaximumSize(maximumSize);
1657            }
1658
1659            /**
1660             * If the maximum size has been set to a non-<code>null</code> value
1661             * just returns it.  If the UI delegate's <code>getMaximumSize</code>
1662             * method returns a non-<code>null</code> value then return that;
1663             * otherwise defer to the component's layout manager.
1664             *
1665             * @return the value of the <code>maximumSize</code> property
1666             * @see #setMaximumSize
1667             * @see ComponentUI
1668             */
1669            public Dimension getMaximumSize() {
1670                if (isMaximumSizeSet()) {
1671                    return super .getMaximumSize();
1672                }
1673                Dimension size = null;
1674                if (ui != null) {
1675                    size = ui.getMaximumSize(this );
1676                }
1677                return (size != null) ? size : super .getMaximumSize();
1678            }
1679
1680            /**
1681             * Sets the minimum size of this component to a constant
1682             * value.  Subsequent calls to <code>getMinimumSize</code> will always
1683             * return this value; the component's UI will not be asked
1684             * to compute it.  Setting the minimum size to <code>null</code>
1685             * restores the default behavior.
1686             *
1687             * @param minimumSize the new minimum size of this component
1688             * @see #getMinimumSize
1689             * @beaninfo
1690             *       bound: true
1691             * description: The minimum size of the component.
1692             */
1693            public void setMinimumSize(Dimension minimumSize) {
1694                super .setMinimumSize(minimumSize);
1695            }
1696
1697            /**
1698             * If the minimum size has been set to a non-<code>null</code> value
1699             * just returns it.  If the UI delegate's <code>getMinimumSize</code>
1700             * method returns a non-<code>null</code> value then return that; otherwise
1701             * defer to the component's layout manager.
1702             *
1703             * @return the value of the <code>minimumSize</code> property
1704             * @see #setMinimumSize
1705             * @see ComponentUI
1706             */
1707            public Dimension getMinimumSize() {
1708                if (isMinimumSizeSet()) {
1709                    return super .getMinimumSize();
1710                }
1711                Dimension size = null;
1712                if (ui != null) {
1713                    size = ui.getMinimumSize(this );
1714                }
1715                return (size != null) ? size : super .getMinimumSize();
1716            }
1717
1718            /**
1719             * Gives the UI delegate an opportunity to define the precise
1720             * shape of this component for the sake of mouse processing.
1721             *
1722             * @return true if this component logically contains x,y
1723             * @see java.awt.Component#contains(int, int)
1724             * @see ComponentUI
1725             */
1726            public boolean contains(int x, int y) {
1727                return (ui != null) ? ui.contains(this , x, y) : super .contains(
1728                        x, y);
1729            }
1730
1731            /**
1732             * Sets the border of this component.  The <code>Border</code> object is
1733             * responsible for defining the insets for the component
1734             * (overriding any insets set directly on the component) and
1735             * for optionally rendering any border decorations within the
1736             * bounds of those insets.  Borders should be used (rather
1737             * than insets) for creating both decorative and non-decorative
1738             * (such as margins and padding) regions for a swing component.
1739             * Compound borders can be used to nest multiple borders within a
1740             * single component.
1741             * <p>
1742             * Although technically you can set the border on any object
1743             * that inherits from <code>JComponent</code>, the look and
1744             * feel implementation of many standard Swing components
1745             * doesn't work well with user-set borders.  In general, 
1746             * when you want to set a border on a standard Swing
1747             * component other than <code>JPanel</code> or <code>JLabel</code>,
1748             * we recommend that you put the component in a <code>JPanel</code>
1749             * and set the border on the <code>JPanel</code>.
1750             * <p>
1751             * This is a bound property.
1752             *
1753             * @param border the border to be rendered for this component
1754             * @see Border
1755             * @see CompoundBorder
1756             * @beaninfo
1757             *        bound: true
1758             *    preferred: true
1759             *    attribute: visualUpdate true
1760             *  description: The component's border.
1761             */
1762            public void setBorder(Border border) {
1763                Border oldBorder = this .border;
1764
1765                this .border = border;
1766                firePropertyChange("border", oldBorder, border);
1767                if (border != oldBorder) {
1768                    if (border == null
1769                            || oldBorder == null
1770                            || !(border.getBorderInsets(this ).equals(oldBorder
1771                                    .getBorderInsets(this )))) {
1772                        revalidate();
1773                    }
1774                    repaint();
1775                }
1776            }
1777
1778            /**
1779             * Returns the border of this component or <code>null</code> if no 
1780             * border is currently set.
1781             *
1782             * @return the border object for this component
1783             * @see #setBorder
1784             */
1785            public Border getBorder() {
1786                return border;
1787            }
1788
1789            /**
1790             * If a border has been set on this component, returns the
1791             * border's insets; otherwise calls <code>super.getInsets</code>.
1792             *
1793             * @return the value of the insets property
1794             * @see #setBorder
1795             */
1796            public Insets getInsets() {
1797                if (border != null) {
1798                    return border.getBorderInsets(this );
1799                }
1800                return super .getInsets();
1801            }
1802
1803            /**
1804             * Returns an <code>Insets</code> object containing this component's inset
1805             * values.  The passed-in <code>Insets</code> object will be reused
1806             * if possible.
1807             * Calling methods cannot assume that the same object will be returned,
1808             * however.  All existing values within this object are overwritten.
1809             * If <code>insets</code> is null, this will allocate a new one.
1810             *
1811             * @param insets the <code>Insets</code> object, which can be reused
1812             * @return the <code>Insets</code> object
1813             * @see #getInsets
1814             * @beaninfo
1815             *   expert: true
1816             */
1817            public Insets getInsets(Insets insets) {
1818                if (insets == null) {
1819                    insets = new Insets(0, 0, 0, 0);
1820                }
1821                if (border != null) {
1822                    if (border instanceof  AbstractBorder) {
1823                        return ((AbstractBorder) border).getBorderInsets(this ,
1824                                insets);
1825                    } else {
1826                        // Can't reuse border insets because the Border interface
1827                        // can't be enhanced.
1828                        return border.getBorderInsets(this );
1829                    }
1830                } else {
1831                    // super.getInsets() always returns an Insets object with
1832                    // all of its value zeroed.  No need for a new object here.
1833                    insets.left = insets.top = insets.right = insets.bottom = 0;
1834                    return insets;
1835                }
1836            }
1837
1838            /**
1839             * Overrides <code>Container.getAlignmentY</code> to return
1840             * the horizontal alignment.
1841             *
1842             * @return the value of the <code>alignmentY</code> property
1843             * @see #setAlignmentY
1844             * @see java.awt.Component#getAlignmentY
1845             */
1846            public float getAlignmentY() {
1847                if (isAlignmentYSet) {
1848                    return alignmentY;
1849                }
1850                return super .getAlignmentY();
1851            }
1852
1853            /**
1854             * Sets the the horizontal alignment.
1855             *
1856             * @param alignmentY  the new horizontal alignment
1857             * @see #getAlignmentY
1858             * @beaninfo
1859             *   description: The preferred vertical alignment of the component.
1860             */
1861            public void setAlignmentY(float alignmentY) {
1862                this .alignmentY = alignmentY > 1.0f ? 1.0f
1863                        : alignmentY < 0.0f ? 0.0f : alignmentY;
1864                isAlignmentYSet = true;
1865            }
1866
1867            /**
1868             * Overrides <code>Container.getAlignmentX</code> to return
1869             * the vertical alignment.
1870             *
1871             * @return the value of the <code>alignmentX</code> property
1872             * @see #setAlignmentX
1873             * @see java.awt.Component#getAlignmentX
1874             */
1875            public float getAlignmentX() {
1876                if (isAlignmentXSet) {
1877                    return alignmentX;
1878                }
1879                return super .getAlignmentX();
1880            }
1881
1882            /**
1883             * Sets the the vertical alignment.
1884             *
1885             * @param alignmentX  the new vertical alignment
1886             * @see #getAlignmentX
1887             * @beaninfo
1888             *   description: The preferred horizontal alignment of the component.
1889             */
1890            public void setAlignmentX(float alignmentX) {
1891                this .alignmentX = alignmentX > 1.0f ? 1.0f
1892                        : alignmentX < 0.0f ? 0.0f : alignmentX;
1893                isAlignmentXSet = true;
1894            }
1895
1896            /**
1897             * Sets the input verifier for this component.
1898             *
1899             * @param inputVerifier the new input verifier
1900             * @since 1.3
1901             * @see InputVerifier
1902             * @beaninfo
1903             *       bound: true
1904             * description: The component's input verifier.
1905             */
1906            public void setInputVerifier(InputVerifier inputVerifier) {
1907                InputVerifier oldInputVerifier = (InputVerifier) getClientProperty(JComponent_INPUT_VERIFIER);
1908                putClientProperty(JComponent_INPUT_VERIFIER, inputVerifier);
1909                firePropertyChange("inputVerifier", oldInputVerifier,
1910                        inputVerifier);
1911            }
1912
1913            /**
1914             * Returns the input verifier for this component.
1915             *
1916             * @return the <code>inputVerifier</code> property
1917             * @since 1.3
1918             * @see InputVerifier
1919             */
1920            public InputVerifier getInputVerifier() {
1921                return (InputVerifier) getClientProperty(JComponent_INPUT_VERIFIER);
1922            }
1923
1924            /**
1925             * Returns this component's graphics context, which lets you draw
1926             * on a component. Use this method to get a <code>Graphics</code> object and
1927             * then invoke operations on that object to draw on the component.
1928             * @return this components graphics context
1929             */
1930            public Graphics getGraphics() {
1931                if (DEBUG_GRAPHICS_LOADED && shouldDebugGraphics() != 0) {
1932                    DebugGraphics graphics = new DebugGraphics(super 
1933                            .getGraphics(), this );
1934                    return graphics;
1935                }
1936                return super .getGraphics();
1937            }
1938
1939            /** Enables or disables diagnostic information about every graphics
1940             * operation performed within the component or one of its children.
1941             *
1942             * @param debugOptions  determines how the component should display
1943             *		the information;  one of the following options:
1944             * <ul>
1945             * <li>DebugGraphics.LOG_OPTION - causes a text message to be printed.
1946             * <li>DebugGraphics.FLASH_OPTION - causes the drawing to flash several
1947             * times.
1948             * <li>DebugGraphics.BUFFERED_OPTION - creates an
1949             *		<code>ExternalWindow</code> that displays the operations
1950             * 	performed on the View's offscreen buffer.
1951             * <li>DebugGraphics.NONE_OPTION disables debugging.
1952             * <li>A value of 0 causes no changes to the debugging options.
1953             * </ul>
1954             * <code>debugOptions</code> is bitwise OR'd into the current value
1955             *
1956             * @beaninfo
1957             *   preferred: true
1958             *        enum: NONE_OPTION DebugGraphics.NONE_OPTION
1959             *              LOG_OPTION DebugGraphics.LOG_OPTION
1960             *              FLASH_OPTION DebugGraphics.FLASH_OPTION
1961             *              BUFFERED_OPTION DebugGraphics.BUFFERED_OPTION
1962             * description: Diagnostic options for graphics operations.
1963             */
1964            public void setDebugGraphicsOptions(int debugOptions) {
1965                DebugGraphics.setDebugOptions(this , debugOptions);
1966            }
1967
1968            /** Returns the state of graphics debugging.
1969             *
1970             * @return a bitwise OR'd flag of zero or more of the following options:
1971             * <ul>
1972             * <li>DebugGraphics.LOG_OPTION - causes a text message to be printed.
1973             * <li>DebugGraphics.FLASH_OPTION - causes the drawing to flash several
1974             * times.
1975             * <li>DebugGraphics.BUFFERED_OPTION - creates an
1976             *		<code>ExternalWindow</code> that displays the operations
1977             * 	performed on the View's offscreen buffer.
1978             * <li>DebugGraphics.NONE_OPTION disables debugging.
1979             * <li>A value of 0 causes no changes to the debugging options.
1980             * </ul>
1981             * @see #setDebugGraphicsOptions
1982             */
1983            public int getDebugGraphicsOptions() {
1984                return DebugGraphics.getDebugOptions(this );
1985            }
1986
1987            /**
1988             * Returns true if debug information is enabled for this
1989             * <code>JComponent</code> or one of its parents.
1990             */
1991            int shouldDebugGraphics() {
1992                return DebugGraphics.shouldComponentDebug(this );
1993            }
1994
1995            /**
1996             * This method is now obsolete, please use a combination of
1997             * <code>getActionMap()</code> and <code>getInputMap()</code> for
1998             * similiar behavior. For example, to bind the <code>KeyStroke</code>
1999             * <code>aKeyStroke</code> to the <code>Action</code> <code>anAction</code>
2000             * now use:
2001             * <pre>
2002             *   component.getInputMap().put(aKeyStroke, aCommand);
2003             *   component.getActionMap().put(aCommmand, anAction);
2004             * </pre>
2005             * The above assumes you want the binding to be applicable for
2006             * <code>WHEN_FOCUSED</code>. To register bindings for other focus
2007             * states use the <code>getInputMap</code> method that takes an integer.
2008             * <p>
2009             * Register a new keyboard action.
2010             * <code>anAction</code> will be invoked if a key event matching
2011             * <code>aKeyStroke</code> occurs and <code>aCondition</code> is verified.
2012             * The <code>KeyStroke</code> object defines a
2013             * particular combination of a keyboard key and one or more modifiers
2014             * (alt, shift, ctrl, meta).
2015             * <p>
2016             * The <code>aCommand</code> will be set in the delivered event if
2017             * specified.
2018             * <p>
2019             * The <code>aCondition</code> can be one of:
2020             * <blockquote>
2021             * <DL>
2022             * <DT>WHEN_FOCUSED
2023             * <DD>The action will be invoked only when the keystroke occurs
2024             *     while the component has the focus.
2025             * <DT>WHEN_IN_FOCUSED_WINDOW
2026             * <DD>The action will be invoked when the keystroke occurs while
2027             *     the component has the focus or if the component is in the
2028             *     window that has the focus. Note that the component need not
2029             *     be an immediate descendent of the window -- it can be
2030             *     anywhere in the window's containment hierarchy. In other
2031             *     words, whenever <em>any</em> component in the window has the focus,
2032             *     the action registered with this component is invoked.
2033             * <DT>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
2034             * <DD>The action will be invoked when the keystroke occurs while the
2035             *     component has the focus or if the component is an ancestor of
2036             *     the component that has the focus.
2037             * </DL>
2038             * </blockquote>
2039             * <p>
2040             * The combination of keystrokes and conditions lets you define high
2041             * level (semantic) action events for a specified keystroke+modifier
2042             * combination (using the KeyStroke class) and direct to a parent or
2043             * child of a component that has the focus, or to the component itself.
2044             * In other words, in any hierarchical structure of components, an
2045             * arbitrary key-combination can be immediately directed to the
2046             * appropriate component in the hierarchy, and cause a specific method
2047             * to be invoked (usually by way of adapter objects).
2048             * <p>
2049             * If an action has already been registered for the receiving
2050             * container, with the same charCode and the same modifiers,
2051             * <code>anAction</code> will replace the action.
2052             *
2053             * @param anAction  the <code>Action</code> to be registered
2054             * @param aCommand  the command to be set in the delivered event
2055             * @param aKeyStroke the <code>KeyStroke</code> to bind to the action
2056             * @param aCondition the condition that needs to be met, see above
2057             * @see KeyStroke
2058             */
2059            public void registerKeyboardAction(ActionListener anAction,
2060                    String aCommand, KeyStroke aKeyStroke, int aCondition) {
2061
2062                InputMap inputMap = getInputMap(aCondition, true);
2063
2064                if (inputMap != null) {
2065                    ActionMap actionMap = getActionMap(true);
2066                    ActionStandin action = new ActionStandin(anAction, aCommand);
2067                    inputMap.put(aKeyStroke, action);
2068                    if (actionMap != null) {
2069                        actionMap.put(action, action);
2070                    }
2071                }
2072            }
2073
2074            /**
2075             * Registers any bound <code>WHEN_IN_FOCUSED_WINDOW</code> actions with
2076             * the <code>KeyboardManager</code>. If <code>onlyIfNew</code>
2077             * is true only actions that haven't been registered are pushed
2078             * to the <code>KeyboardManager</code>;
2079             * otherwise all actions are pushed to the <code>KeyboardManager</code>.
2080             *
2081             * @param onlyIfNew  if true, only actions that haven't been registered
2082             *		are pushed to the <code>KeyboardManager</code>
2083             */
2084            private void registerWithKeyboardManager(boolean onlyIfNew) {
2085                InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW, false);
2086                KeyStroke[] strokes;
2087                Hashtable registered = (Hashtable) getClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS);
2088
2089                if (inputMap != null) {
2090                    // Push any new KeyStrokes to the KeyboardManager.
2091                    strokes = inputMap.allKeys();
2092                    if (strokes != null) {
2093                        for (int counter = strokes.length - 1; counter >= 0; counter--) {
2094                            if (!onlyIfNew || registered == null
2095                                    || registered.get(strokes[counter]) == null) {
2096                                registerWithKeyboardManager(strokes[counter]);
2097                            }
2098                            if (registered != null) {
2099                                registered.remove(strokes[counter]);
2100                            }
2101                        }
2102                    }
2103                } else {
2104                    strokes = null;
2105                }
2106                // Remove any old ones.
2107                if (registered != null && registered.size() > 0) {
2108                    Enumeration keys = registered.keys();
2109
2110                    while (keys.hasMoreElements()) {
2111                        KeyStroke ks = (KeyStroke) keys.nextElement();
2112                        unregisterWithKeyboardManager(ks);
2113                    }
2114                    registered.clear();
2115                }
2116                // Updated the registered Hashtable.
2117                if (strokes != null && strokes.length > 0) {
2118                    if (registered == null) {
2119                        registered = new Hashtable(strokes.length);
2120                        putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS,
2121                                registered);
2122                    }
2123                    for (int counter = strokes.length - 1; counter >= 0; counter--) {
2124                        registered.put(strokes[counter], strokes[counter]);
2125                    }
2126                } else {
2127                    putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, null);
2128                }
2129            }
2130
2131            /**
2132             * Unregisters all the previously registered
2133             * <code>WHEN_IN_FOCUSED_WINDOW</code> <code>KeyStroke</code> bindings.
2134             */
2135            private void unregisterWithKeyboardManager() {
2136                Hashtable registered = (Hashtable) getClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS);
2137
2138                if (registered != null && registered.size() > 0) {
2139                    Enumeration keys = registered.keys();
2140
2141                    while (keys.hasMoreElements()) {
2142                        KeyStroke ks = (KeyStroke) keys.nextElement();
2143                        unregisterWithKeyboardManager(ks);
2144                    }
2145                }
2146                putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, null);
2147            }
2148
2149            /**
2150             * Invoked from <code>ComponentInputMap</code> when its bindings change.
2151             * If <code>inputMap</code> is the current <code>windowInputMap</code>
2152             * (or a parent of the window <code>InputMap</code>)
2153             * the <code>KeyboardManager</code> is notified of the new bindings.
2154             *
2155             * @param inputMap the map containing the new bindings
2156             */
2157            void componentInputMapChanged(ComponentInputMap inputMap) {
2158                InputMap km = getInputMap(WHEN_IN_FOCUSED_WINDOW, false);
2159
2160                while (km != inputMap && km != null) {
2161                    km = (ComponentInputMap) km.getParent();
2162                }
2163                if (km != null) {
2164                    registerWithKeyboardManager(false);
2165                }
2166            }
2167
2168            private void registerWithKeyboardManager(KeyStroke aKeyStroke) {
2169                KeyboardManager.getCurrentManager().registerKeyStroke(
2170                        aKeyStroke, this );
2171            }
2172
2173            private void unregisterWithKeyboardManager(KeyStroke aKeyStroke) {
2174                KeyboardManager.getCurrentManager().unregisterKeyStroke(
2175                        aKeyStroke, this );
2176            }
2177
2178            /**
2179             * This method is now obsolete, please use a combination of
2180             * <code>getActionMap()</code> and <code>getInputMap()</code> for
2181             * similiar behavior.
2182             */
2183            public void registerKeyboardAction(ActionListener anAction,
2184                    KeyStroke aKeyStroke, int aCondition) {
2185                registerKeyboardAction(anAction, null, aKeyStroke, aCondition);
2186            }
2187
2188            /**
2189             * This method is now obsolete. To unregister an existing binding
2190             * you can either remove the binding from the
2191             * <code>ActionMap/InputMap</code>, or place a dummy binding the
2192             * <code>InputMap</code>. Removing the binding from the
2193             * <code>InputMap</code> allows bindings in parent <code>InputMap</code>s
2194             * to be active, whereas putting a dummy binding in the
2195             * <code>InputMap</code> effectively disables
2196             * the binding from ever happening.
2197             * <p>
2198             * Unregisters a keyboard action.
2199             * This will remove the binding from the <code>ActionMap</code>
2200             * (if it exists) as well as the <code>InputMap</code>s.
2201             */
2202            public void unregisterKeyboardAction(KeyStroke aKeyStroke) {
2203                ActionMap am = getActionMap(false);
2204                for (int counter = 0; counter < 3; counter++) {
2205                    InputMap km = getInputMap(counter, false);
2206                    if (km != null) {
2207                        Object actionID = km.get(aKeyStroke);
2208
2209                        if (am != null && actionID != null) {
2210                            am.remove(actionID);
2211                        }
2212                        km.remove(aKeyStroke);
2213                    }
2214                }
2215            }
2216
2217            /**
2218             * Returns the <code>KeyStrokes</code> that will initiate
2219             * registered actions.
2220             *
2221             * @return an array of <code>KeyStroke</code> objects
2222             * @see #registerKeyboardAction
2223             */
2224            public KeyStroke[] getRegisteredKeyStrokes() {
2225                int[] counts = new int[3];
2226                KeyStroke[][] strokes = new KeyStroke[3][];
2227
2228                for (int counter = 0; counter < 3; counter++) {
2229                    InputMap km = getInputMap(counter, false);
2230                    strokes[counter] = (km != null) ? km.allKeys() : null;
2231                    counts[counter] = (strokes[counter] != null) ? strokes[counter].length
2232                            : 0;
2233                }
2234                KeyStroke[] retValue = new KeyStroke[counts[0] + counts[1]
2235                        + counts[2]];
2236                for (int counter = 0, last = 0; counter < 3; counter++) {
2237                    if (counts[counter] > 0) {
2238                        System.arraycopy(strokes[counter], 0, retValue, last,
2239                                counts[counter]);
2240                        last += counts[counter];
2241                    }
2242                }
2243                return retValue;
2244            }
2245
2246            /**
2247             * Returns the condition that determines whether a registered action
2248             * occurs in response to the specified keystroke.
2249             * <p>
2250             * For Java 2 platform v1.3, a <code>KeyStroke</code> can be associated
2251             * with more than one condition.
2252             * For example, 'a' could be bound for the two
2253             * conditions <code>WHEN_FOCUSED</code> and
2254             * <code>WHEN_IN_FOCUSED_WINDOW</code> condition.
2255             *
2256             * @return the action-keystroke condition
2257             */
2258            public int getConditionForKeyStroke(KeyStroke aKeyStroke) {
2259                for (int counter = 0; counter < 3; counter++) {
2260                    InputMap inputMap = getInputMap(counter, false);
2261                    if (inputMap != null && inputMap.get(aKeyStroke) != null) {
2262                        return counter;
2263                    }
2264                }
2265                return UNDEFINED_CONDITION;
2266            }
2267
2268            /**
2269             * Returns the object that will perform the action registered for a
2270             * given keystroke.
2271             *
2272             * @return the <code>ActionListener</code>
2273             *		object invoked when the keystroke occurs
2274             */
2275            public ActionListener getActionForKeyStroke(KeyStroke aKeyStroke) {
2276                ActionMap am = getActionMap(false);
2277
2278                if (am == null) {
2279                    return null;
2280                }
2281                for (int counter = 0; counter < 3; counter++) {
2282                    InputMap inputMap = getInputMap(counter, false);
2283                    if (inputMap != null) {
2284                        Object actionBinding = inputMap.get(aKeyStroke);
2285
2286                        if (actionBinding != null) {
2287                            Action action = am.get(actionBinding);
2288                            if (action instanceof  ActionStandin) {
2289                                return ((ActionStandin) action).actionListener;
2290                            }
2291                            return action;
2292                        }
2293                    }
2294                }
2295                return null;
2296            }
2297
2298            /**
2299             * Unregisters all the bindings in the first tier <code>InputMaps</code>
2300             * and <code>ActionMap</code>. This has the effect of removing any
2301             * local bindings, and allowing the bindings defined in parent
2302             * <code>InputMap/ActionMaps</code>
2303             * (the UI is usually defined in the second tier) to persist.
2304             */
2305            public void resetKeyboardActions() {
2306                // Keys
2307                for (int counter = 0; counter < 3; counter++) {
2308                    InputMap inputMap = getInputMap(counter, false);
2309
2310                    if (inputMap != null) {
2311                        inputMap.clear();
2312                    }
2313                }
2314
2315                // Actions
2316                ActionMap am = getActionMap(false);
2317
2318                if (am != null) {
2319                    am.clear();
2320                }
2321            }
2322
2323            /**
2324             * Sets the <code>InputMap</code> to use under the condition
2325             * <code>condition</code> to
2326             * <code>map</code>. A <code>null</code> value implies you
2327             * do not want any bindings to be used, even from the UI. This will
2328             * not reinstall the UI <code>InputMap</code> (if there was one).
2329             * <code>condition</code> has one of the following values:
2330             * <ul>
2331             * <li><code>WHEN_IN_FOCUSED_WINDOW</code>
2332             * <li><code>WHEN_FOCUSED</code>
2333             * <li><code>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT</code>
2334             * </ul>
2335             * If <code>condition</code> is <code>WHEN_IN_FOCUSED_WINDOW</code> 
2336             * and <code>map</code> is not a <code>ComponentInputMap</code>, an
2337             * <code>IllegalArgumentException</code> will be thrown.
2338             * Similarly, if <code>condition</code> is not one of the values 
2339             * listed, an <code>IllegalArgumentException</code> will be thrown.
2340             *
2341             * @param condition one of the values listed above
2342             * @param map  the <code>InputMap</code> to use for the given condition
2343             * @exception IllegalArgumentException if <code>condition</code> is
2344             *		<code>WHEN_IN_FOCUSED_WINDOW</code> and <code>map</code>
2345             *		is not an instance of <code>ComponentInputMap</code>; or
2346             *		if <code>condition</code> is not one of the legal values
2347             *		specified above
2348             * @since 1.3
2349             */
2350            public final void setInputMap(int condition, InputMap map) {
2351                switch (condition) {
2352                case WHEN_IN_FOCUSED_WINDOW:
2353                    if (map != null && !(map instanceof  ComponentInputMap)) {
2354                        throw new IllegalArgumentException(
2355                                "WHEN_IN_FOCUSED_WINDOW InputMaps must be of type ComponentInputMap");
2356                    }
2357                    windowInputMap = (ComponentInputMap) map;
2358                    setFlag(WIF_INPUTMAP_CREATED, true);
2359                    registerWithKeyboardManager(false);
2360                    break;
2361                case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
2362                    ancestorInputMap = map;
2363                    setFlag(ANCESTOR_INPUTMAP_CREATED, true);
2364                    break;
2365                case WHEN_FOCUSED:
2366                    focusInputMap = map;
2367                    setFlag(FOCUS_INPUTMAP_CREATED, true);
2368                    break;
2369                default:
2370                    throw new IllegalArgumentException(
2371                            "condition must be one of JComponent.WHEN_IN_FOCUSED_WINDOW, JComponent.WHEN_FOCUSED or JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT");
2372                }
2373            }
2374
2375            /**
2376             * Returns the <code>InputMap</code> that is used during
2377             * <code>condition</code>.
2378             *
2379             * @param condition one of WHEN_IN_FOCUSED_WINDOW, WHEN_FOCUSED,
2380             *        WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
2381             * @return the <code>InputMap</code> for the specified
2382             *		<code>condition</code>
2383             * @since 1.3
2384             */
2385            public final InputMap getInputMap(int condition) {
2386                return getInputMap(condition, true);
2387            }
2388
2389            /**
2390             * Returns the <code>InputMap</code> that is used when the
2391             * component has focus.
2392             * This is convenience method for <code>getInputMap(WHEN_FOCUSED)</code>.
2393             *
2394             * @return the <code>InputMap</code> used when the component has focus
2395             * @since 1.3
2396             */
2397            public final InputMap getInputMap() {
2398                return getInputMap(WHEN_FOCUSED, true);
2399            }
2400
2401            /**
2402             * Sets the <code>ActionMap</code> to <code>am</code>. This does not set
2403             * the parent of the <code>am</code> to be the <code>ActionMap</code>
2404             * from the UI (if there was one), it is up to the caller to have done this.
2405             * 
2406             * @param am  the new <code>ActionMap</code>
2407             * @since 1.3
2408             */
2409            public final void setActionMap(ActionMap am) {
2410                actionMap = am;
2411                setFlag(ACTIONMAP_CREATED, true);
2412            }
2413
2414            /**
2415             * Returns the <code>ActionMap</code> used to determine what
2416             * <code>Action</code> to fire for particular <code>KeyStroke</code>
2417             * binding. The returned <code>ActionMap</code>, unless otherwise
2418             * set, will have the <code>ActionMap</code> from the UI set as the parent.
2419             *
2420             * @return the <code>ActionMap</code> containing the key/action bindings
2421             * @since 1.3
2422             */
2423            public final ActionMap getActionMap() {
2424                return getActionMap(true);
2425            }
2426
2427            /**
2428             * Returns the <code>InputMap</code> to use for condition
2429             * <code>condition</code>.  If the <code>InputMap</code> hasn't
2430             * been created, and <code>create</code> is
2431             * true, it will be created.
2432             *
2433             * @param condition one of the following values:
2434             * <ul>
2435             * <li>JComponent.FOCUS_INPUTMAP_CREATED
2436             * <li>JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
2437             * <li>JComponent.WHEN_IN_FOCUSED_WINDOW
2438             * </ul>
2439             * @param create if true, create the <code>InputMap</code> if it
2440             *		is not already created
2441             * @return the <code>InputMap</code> for the given <code>condition</code>;
2442             *		if <code>create</code> is false and the <code>InputMap</code>
2443             *		hasn't been created, returns <code>null</code>
2444             * @exception IllegalArgumentException if <code>condition</code> 
2445             *		is not one of the legal values listed above
2446             */
2447            final InputMap getInputMap(int condition, boolean create) {
2448                switch (condition) {
2449                case WHEN_FOCUSED:
2450                    if (getFlag(FOCUS_INPUTMAP_CREATED)) {
2451                        return focusInputMap;
2452                    }
2453                    // Hasn't been created yet.
2454                    if (create) {
2455                        InputMap km = new InputMap();
2456                        setInputMap(condition, km);
2457                        return km;
2458                    }
2459                    break;
2460                case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
2461                    if (getFlag(ANCESTOR_INPUTMAP_CREATED)) {
2462                        return ancestorInputMap;
2463                    }
2464                    // Hasn't been created yet.
2465                    if (create) {
2466                        InputMap km = new InputMap();
2467                        setInputMap(condition, km);
2468                        return km;
2469                    }
2470                    break;
2471                case WHEN_IN_FOCUSED_WINDOW:
2472                    if (getFlag(WIF_INPUTMAP_CREATED)) {
2473                        return windowInputMap;
2474                    }
2475                    // Hasn't been created yet.
2476                    if (create) {
2477                        ComponentInputMap km = new ComponentInputMap(this );
2478                        setInputMap(condition, km);
2479                        return km;
2480                    }
2481                    break;
2482                default:
2483                    throw new IllegalArgumentException(
2484                            "condition must be one of JComponent.WHEN_IN_FOCUSED_WINDOW, JComponent.WHEN_FOCUSED or JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT");
2485                }
2486                return null;
2487            }
2488
2489            /**
2490             * Finds and returns the appropriate <code>ActionMap</code>.
2491             * 
2492             * @param create if true, create the <code>ActionMap</code> if it
2493             *		is not already created
2494             * @return the <code>ActionMap</code> for this component; if the
2495             *		<code>create</code> flag is false and there is no
2496             *		current <code>ActionMap</code>, returns <code>null</code>
2497             */
2498            final ActionMap getActionMap(boolean create) {
2499                if (getFlag(ACTIONMAP_CREATED)) {
2500                    return actionMap;
2501                }
2502                // Hasn't been created.
2503                if (create) {
2504                    ActionMap am = new ActionMap();
2505                    setActionMap(am);
2506                    return am;
2507                }
2508                return null;
2509            }
2510
2511            /**
2512             * Returns the baseline.  The baseline is measured from the top of
2513             * the component.  This method is primarily meant for
2514             * <code>LayoutManager</code>s to align components along their
2515             * baseline.  A return value less than 0 indicates this component
2516             * does not have a reasonable baseline and that
2517             * <code>LayoutManager</code>s should not align this component on
2518             * its baseline.
2519             * <p>
2520             * This method calls into the <code>ComponentUI</code> method of the
2521             * same name.  If this component does not have a <code>ComponentUI</code>
2522             * -1 will be returned.  If a value &gt;= 0 is
2523             * returned, then the component has a valid baseline for any
2524             * size &gt;= the minimum size and <code>getBaselineResizeBehavior</code>
2525             * can be used to determine how the baseline changes with size.
2526             *
2527             * @throws IllegalArgumentException {@inheritDoc}
2528             * @see #getBaselineResizeBehavior
2529             * @see java.awt.FontMetrics
2530             * @since 1.6
2531             */
2532            public int getBaseline(int width, int height) {
2533                // check size.
2534                super .getBaseline(width, height);
2535                if (ui != null) {
2536                    return ui.getBaseline(this , width, height);
2537                }
2538                return -1;
2539            }
2540
2541            /**
2542             * Returns an enum indicating how the baseline of the component
2543             * changes as the size changes.  This method is primarily meant for
2544             * layout managers and GUI builders.
2545             * <p>
2546             * This method calls into the <code>ComponentUI</code> method of
2547             * the same name.  If this component does not have a
2548             * <code>ComponentUI</code>
2549             * <code>BaselineResizeBehavior.OTHER</code> will be
2550             * returned.  Subclasses should
2551             * never return <code>null</code>; if the baseline can not be
2552             * calculated return <code>BaselineResizeBehavior.OTHER</code>.  Callers
2553             * should first ask for the baseline using
2554             * <code>getBaseline</code> and if a value &gt;= 0 is returned use
2555             * this method.  It is acceptable for this method to return a
2556             * value other than <code>BaselineResizeBehavior.OTHER</code> even if
2557             * <code>getBaseline</code> returns a value less than 0.
2558             *
2559             * @see #getBaseline(int, int)
2560             * @since 1.6
2561             */
2562            public BaselineResizeBehavior getBaselineResizeBehavior() {
2563                if (ui != null) {
2564                    return ui.getBaselineResizeBehavior(this );
2565                }
2566                return BaselineResizeBehavior.OTHER;
2567            }
2568
2569            /**
2570             * In release 1.4, the focus subsystem was rearchitected.
2571             * For more information, see
2572             * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
2573             * How to Use the Focus Subsystem</a>,
2574             * a section in <em>The Java Tutorial</em>.
2575             * <p>
2576             * Requests focus on this <code>JComponent</code>'s
2577             * <code>FocusTraversalPolicy</code>'s default <code>Component</code>. 
2578             * If this <code>JComponent</code> is a focus cycle root, then its
2579             * <code>FocusTraversalPolicy</code> is used. Otherwise, the
2580             * <code>FocusTraversalPolicy</code> of this <code>JComponent</code>'s
2581             * focus-cycle-root ancestor is used.
2582             *
2583             * @see java.awt.FocusTraversalPolicy#getDefaultComponent
2584             * @deprecated As of 1.4, replaced by
2585             * <code>FocusTraversalPolicy.getDefaultComponent(Container).requestFocus()</code>
2586             */
2587            @Deprecated
2588            public boolean requestDefaultFocus() {
2589                Container nearestRoot = (isFocusCycleRoot()) ? this 
2590                        : getFocusCycleRootAncestor();
2591                if (nearestRoot == null) {
2592                    return false;
2593                }
2594                Component comp = nearestRoot.getFocusTraversalPolicy()
2595                        .getDefaultComponent(nearestRoot);
2596                if (comp != null) {
2597                    comp.requestFocus();
2598                    return true;
2599                } else {
2600                    return false;
2601                }
2602            }
2603
2604            /**
2605             * Makes the component visible or invisible.
2606             * Overrides <code>Component.setVisible</code>.
2607             * 
2608             * @param aFlag  true to make the component visible; false to
2609             *		make it invisible
2610             *
2611             * @beaninfo
2612             *    attribute: visualUpdate true
2613             */
2614            public void setVisible(boolean aFlag) {
2615                if (aFlag != isVisible()) {
2616                    super .setVisible(aFlag);
2617                    Container parent = getParent();
2618                    if (parent != null) {
2619                        Rectangle r = getBounds();
2620                        parent.repaint(r.x, r.y, r.width, r.height);
2621                    }
2622                    // Some (all should) LayoutManagers do not consider components
2623                    // that are not visible. As such we need to revalidate when the
2624                    // visible bit changes.
2625                    revalidate();
2626                }
2627            }
2628
2629            /**
2630             * Sets whether or not this component is enabled.
2631             * A component that is enabled may respond to user input,
2632             * while a component that is not enabled cannot respond to 
2633             * user input.  Some components may alter their visual
2634             * representation when they are disabled in order to 
2635             * provide feedback to the user that they cannot take input.
2636             * <p>Note: Disabling a component does not disable its children.
2637             *
2638             * <p>Note: Disabling a lightweight component does not prevent it from
2639             * receiving MouseEvents.
2640             *
2641             * @param enabled true if this component should be enabled, false otherwise
2642             * @see java.awt.Component#isEnabled
2643             * @see java.awt.Component#isLightweight
2644             *
2645             * @beaninfo
2646             *    preferred: true
2647             *        bound: true
2648             *    attribute: visualUpdate true
2649             *  description: The enabled state of the component.
2650             */
2651            public void setEnabled(boolean enabled) {
2652                boolean oldEnabled = isEnabled();
2653                super .setEnabled(enabled);
2654                firePropertyChange("enabled", oldEnabled, enabled);
2655                if (enabled != oldEnabled) {
2656                    repaint();
2657                }
2658            }
2659
2660            /**
2661             * Sets the foreground color of this component.  It is up to the
2662             * look and feel to honor this property, some may choose to ignore
2663             * it.
2664             *
2665             * @param fg  the desired foreground <code>Color</code> 
2666             * @see java.awt.Component#getForeground
2667             *
2668             * @beaninfo
2669             *    preferred: true
2670             *        bound: true
2671             *    attribute: visualUpdate true
2672             *  description: The foreground color of the component.
2673             */
2674            public void setForeground(Color fg) {
2675                Color oldFg = getForeground();
2676                super .setForeground(fg);
2677                if ((oldFg != null) ? !oldFg.equals(fg) : ((fg != null) && !fg
2678                        .equals(oldFg))) {
2679                    // foreground already bound in AWT1.2
2680                    repaint();
2681                }
2682            }
2683
2684            /**
2685             * Sets the background color of this component.  The background
2686             * color is used only if the component is opaque, and only
2687             * by subclasses of <code>JComponent</code> or
2688             * <code>ComponentUI</code> implementations.  Direct subclasses of
2689             * <code>JComponent</code> must override
2690             * <code>paintComponent</code> to honor this property.
2691             * <p>
2692             * It is up to the look and feel to honor this property, some may
2693             * choose to ignore it.
2694             *
2695             * @param bg the desired background <code>Color</code>
2696             * @see java.awt.Component#getBackground
2697             * @see #setOpaque
2698             *
2699             * @beaninfo
2700             *    preferred: true
2701             *        bound: true
2702             *    attribute: visualUpdate true
2703             *  description: The background color of the component.
2704             */
2705            public void setBackground(Color bg) {
2706                Color oldBg = getBackground();
2707                super .setBackground(bg);
2708                if ((oldBg != null) ? !oldBg.equals(bg) : ((bg != null) && !bg
2709                        .equals(oldBg))) {
2710                    // background already bound in AWT1.2
2711                    repaint();
2712                }
2713            }
2714
2715            /**
2716             * Sets the font for this component.
2717             *
2718             * @param font the desired <code>Font</code> for this component
2719             * @see java.awt.Component#getFont
2720             *
2721             * @beaninfo
2722             *    preferred: true
2723             *        bound: true
2724             *    attribute: visualUpdate true
2725             *  description: The font for the component.
2726             */
2727            public void setFont(Font font) {
2728                Font oldFont = getFont();
2729                super .setFont(font);
2730                // font already bound in AWT1.2
2731                if (font != oldFont) {
2732                    revalidate();
2733                    repaint();
2734                }
2735            }
2736
2737            /**
2738             * Returns the default locale used to initialize each JComponent's 
2739             * locale property upon creation.
2740             *
2741             * The default locale has "AppContext" scope so that applets (and 
2742             * potentially multiple lightweight applications running in a single VM) 
2743             * can have their own setting. An applet can safely alter its default
2744             * locale because it will have no affect on other applets (or the browser).
2745             *
2746             * @return the default <code>Locale</code>.
2747             * @see #setDefaultLocale
2748             * @see java.awt.Component#getLocale
2749             * @see #setLocale
2750             * @since 1.4
2751             */
2752            static public Locale getDefaultLocale() {
2753                Locale l = (Locale) SwingUtilities.appContextGet(defaultLocale);
2754                if (l == null) {
2755                    //REMIND(bcb) choosing the default value is more complicated
2756                    //than this.
2757                    l = Locale.getDefault();
2758                    JComponent.setDefaultLocale(l);
2759                }
2760                return l;
2761            }
2762
2763            /**
2764             * Sets the default locale used to initialize each JComponent's locale
2765             * property upon creation.  The initial value is the VM's default locale.
2766             *
2767             * The default locale has "AppContext" scope so that applets (and 
2768             * potentially multiple lightweight applications running in a single VM) 
2769             * can have their own setting. An applet can safely alter its default
2770             * locale because it will have no affect on other applets (or the browser).
2771             *
2772             * @param l the desired default <code>Locale</code> for new components.
2773             * @see #getDefaultLocale
2774             * @see java.awt.Component#getLocale
2775             * @see #setLocale
2776             * @since 1.4
2777             */
2778            static public void setDefaultLocale(Locale l) {
2779                SwingUtilities.appContextPut(defaultLocale, l);
2780            }
2781
2782            /**
2783             * Processes any key events that the component itself
2784             * recognizes.  This is called after the focus
2785             * manager and any interested listeners have been
2786             * given a chance to steal away the event.  This
2787             * method is called only if the event has not
2788             * yet been consumed.  This method is called prior
2789             * to the keyboard UI logic.
2790             * <p>
2791             * This method is implemented to do nothing.  Subclasses would
2792             * normally override this method if they process some
2793             * key events themselves.  If the event is processed,
2794             * it should be consumed.
2795             */
2796            protected void processComponentKeyEvent(KeyEvent e) {
2797            }
2798
2799            /** Overrides <code>processKeyEvent</code> to process events. **/
2800            protected void processKeyEvent(KeyEvent e) {
2801                boolean result;
2802                boolean shouldProcessKey;
2803
2804                // This gives the key event listeners a crack at the event
2805                super .processKeyEvent(e);
2806
2807                // give the component itself a crack at the event
2808                if (!e.isConsumed()) {
2809                    processComponentKeyEvent(e);
2810                }
2811
2812                shouldProcessKey = KeyboardState.shouldProcess(e);
2813
2814                if (e.isConsumed()) {
2815                    return;
2816                }
2817
2818                if (shouldProcessKey
2819                        && processKeyBindings(e,
2820                                e.getID() == KeyEvent.KEY_PRESSED)) {
2821                    e.consume();
2822                }
2823            }
2824
2825            /**
2826             * Invoked to process the key bindings for <code>ks</code> as the result
2827             * of the <code>KeyEvent</code> <code>e</code>. This obtains
2828             * the appropriate <code>InputMap</code>,
2829             * gets the binding, gets the action from the <code>ActionMap</code>,
2830             * and then (if the action is found and the component
2831             * is enabled) invokes <code>notifyAction</code> to notify the action.
2832             *
2833             * @param ks  the <code>KeyStroke</code> queried
2834             * @param e the <code>KeyEvent</code>
2835             * @param condition one of the following values:
2836             * <ul>
2837             * <li>JComponent.WHEN_FOCUSED
2838             * <li>JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
2839             * <li>JComponent.WHEN_IN_FOCUSED_WINDOW
2840             * </ul>
2841             * @param pressed true if the key is pressed
2842             * @return true if there was a binding to an action, and the action
2843             *         was enabled
2844             *
2845             * @since 1.3
2846             */
2847            protected boolean processKeyBinding(KeyStroke ks, KeyEvent e,
2848                    int condition, boolean pressed) {
2849                InputMap map = getInputMap(condition, false);
2850                ActionMap am = getActionMap(false);
2851
2852                if (map != null && am != null && isEnabled()) {
2853                    Object binding = map.get(ks);
2854                    Action action = (binding == null) ? null : am.get(binding);
2855                    if (action != null) {
2856                        return SwingUtilities.notifyAction(action, ks, e, this ,
2857                                e.getModifiers());
2858                    }
2859                }
2860                return false;
2861            }
2862
2863            /**
2864             * This is invoked as the result of a <code>KeyEvent</code>
2865             * that was not consumed by the <code>FocusManager</code>,
2866             * <code>KeyListeners</code>, or the component. It will first try
2867             * <code>WHEN_FOCUSED</code> bindings,
2868             * then <code>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT</code> bindings,
2869             * and finally <code>WHEN_IN_FOCUSED_WINDOW</code> bindings.
2870             *
2871             * @param e the unconsumed <code>KeyEvent</code>
2872             * @param pressed true if the key is pressed
2873             * @return true if there is a key binding for <code>e</code>
2874             */
2875            boolean processKeyBindings(KeyEvent e, boolean pressed) {
2876                if (!SwingUtilities.isValidKeyEventForKeyBindings(e)) {
2877                    return false;
2878                }
2879                // Get the KeyStroke
2880                KeyStroke ks;
2881
2882                if (e.getID() == KeyEvent.KEY_TYPED) {
2883                    ks = KeyStroke.getKeyStroke(e.getKeyChar());
2884                } else {
2885                    ks = KeyStroke.getKeyStroke(e.getKeyCode(), e
2886                            .getModifiers(), (pressed ? false : true));
2887                }
2888
2889                /* Do we have a key binding for e? */
2890                if (processKeyBinding(ks, e, WHEN_FOCUSED, pressed))
2891                    return true;
2892
2893                /* We have no key binding. Let's try the path from our parent to the
2894                 * window excluded. We store the path components so we can avoid
2895                 * asking the same component twice.
2896                 */
2897                Container parent = this ;
2898                while (parent != null && !(parent instanceof  Window)
2899                        && !(parent instanceof  Applet)) {
2900                    if (parent instanceof  JComponent) {
2901                        if (((JComponent) parent).processKeyBinding(ks, e,
2902                                WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed))
2903                            return true;
2904                    }
2905                    // This is done so that the children of a JInternalFrame are
2906                    // given precedence for WHEN_IN_FOCUSED_WINDOW bindings before
2907                    // other components WHEN_IN_FOCUSED_WINDOW bindings. This also gives
2908                    // more precedence to the WHEN_IN_FOCUSED_WINDOW bindings of the
2909                    // JInternalFrame's children vs the
2910                    // WHEN_ANCESTOR_OF_FOCUSED_COMPONENT bindings of the parents.
2911                    // maybe generalize from JInternalFrame (like isFocusCycleRoot).
2912                    if ((parent instanceof  JInternalFrame)
2913                            && JComponent.processKeyBindingsForAllComponents(e,
2914                                    parent, pressed)) {
2915                        return true;
2916                    }
2917                    parent = parent.getParent();
2918                }
2919
2920                /* No components between the focused component and the window is
2921                 * actually interested by the key event. Let's try the other
2922                 * JComponent in this window.
2923                 */
2924                if (parent != null) {
2925                    return JComponent.processKeyBindingsForAllComponents(e,
2926                            parent, pressed);
2927                }
2928                return false;
2929            }
2930
2931            static boolean processKeyBindingsForAllComponents(KeyEvent e,
2932                    Container container, boolean pressed) {
2933                while (true) {
2934                    if (KeyboardManager.getCurrentManager().fireKeyboardAction(
2935                            e, pressed, container)) {
2936                        return true;
2937                    }
2938                    if (container instanceof  Popup.HeavyWeightWindow) {
2939                        container = ((Window) container).getOwner();
2940                    } else {
2941                        return false;
2942                    }
2943                }
2944            }
2945
2946            /**
2947             * Registers the text to display in a tool tip.
2948             * The text displays when the cursor lingers over the component.
2949             * <p>
2950             * See <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/tooltip.html">How to Use Tool Tips</a>
2951             * in <em>The Java Tutorial</em>
2952             * for further documentation.
2953             *
2954             * @param text  the string to display; if the text is <code>null</code>,
2955             *              the tool tip is turned off for this component
2956             * @see #TOOL_TIP_TEXT_KEY
2957             * @beaninfo
2958             *   preferred: true
2959             * description: The text to display in a tool tip.
2960             */
2961            public void setToolTipText(String text) {
2962                String oldText = getToolTipText();
2963                putClientProperty(TOOL_TIP_TEXT_KEY, text);
2964                ToolTipManager toolTipManager = ToolTipManager.sharedInstance();
2965                if (text != null) {
2966                    if (oldText == null) {
2967                        toolTipManager.registerComponent(this );
2968                    }
2969                } else {
2970                    toolTipManager.unregisterComponent(this );
2971                }
2972            }
2973
2974            /**
2975             * Returns the tooltip string that has been set with
2976             * <code>setToolTipText</code>.
2977             *
2978             * @return the text of the tool tip
2979             * @see #TOOL_TIP_TEXT_KEY
2980             */
2981            public String getToolTipText() {
2982                return (String) getClientProperty(TOOL_TIP_TEXT_KEY);
2983            }
2984
2985            /**
2986             * Returns the string to be used as the tooltip for <i>event</i>.
2987             * By default this returns any string set using
2988             * <code>setToolTipText</code>.  If a component provides
2989             * more extensive API to support differing tooltips at different locations,
2990             * this method should be overridden.
2991             */
2992            public String getToolTipText(MouseEvent event) {
2993                return getToolTipText();
2994            }
2995
2996            /**
2997             * Returns the tooltip location in this component's coordinate system.
2998             * If <code>null</code> is returned, Swing will choose a location.
2999             * The default implementation returns <code>null</code>.
3000             *
3001             * @param event  the <code>MouseEvent</code> that caused the
3002             *		<code>ToolTipManager</code> to show the tooltip
3003             * @return always returns <code>null</code>
3004             */
3005            public Point getToolTipLocation(MouseEvent event) {
3006                return null;
3007            }
3008
3009            /**
3010             * Returns the preferred location to display the popup menu in this
3011             * component's coordinate system. It is up to the look and feel to
3012             * honor this property, some may choose to ignore it.
3013             * If {@code null}, the look and feel will choose a suitable location.
3014             *
3015             * @param event the {@code MouseEvent} that triggered the popup to be
3016             *        shown, or {@code null} if the popup is not being shown as the
3017             *        result of a mouse event
3018             * @return location to display the {@code JPopupMenu}, or {@code null}
3019             * @since 1.5
3020             */
3021            public Point getPopupLocation(MouseEvent event) {
3022                return null;
3023            }
3024
3025            /**
3026             * Returns the instance of <code>JToolTip</code> that should be used
3027             * to display the tooltip.
3028             * Components typically would not override this method,
3029             * but it can be used to
3030             * cause different tooltips to be displayed differently.
3031             *
3032             * @return the <code>JToolTip</code> used to display this toolTip
3033             */
3034            public JToolTip createToolTip() {
3035                JToolTip tip = new JToolTip();
3036                tip.setComponent(this );
3037                return tip;
3038            }
3039
3040            /**
3041             * Forwards the <code>scrollRectToVisible()</code> message to the
3042             * <code>JComponent</code>'s parent. Components that can service
3043             * the request, such as <code>JViewport</code>,
3044             * override this method and perform the scrolling.
3045             *
3046             * @param aRect the visible <code>Rectangle</code>
3047             * @see JViewport
3048             */
3049            public void scrollRectToVisible(Rectangle aRect) {
3050                Container parent;
3051                int dx = getX(), dy = getY();
3052
3053                for (parent = getParent(); !(parent == null)
3054                        && !(parent instanceof  JComponent)
3055                        && !(parent instanceof  CellRendererPane); parent = parent
3056                        .getParent()) {
3057                    Rectangle bounds = parent.getBounds();
3058
3059                    dx += bounds.x;
3060                    dy += bounds.y;
3061                }
3062
3063                if (!(parent == null) && !(parent instanceof  CellRendererPane)) {
3064                    aRect.x += dx;
3065                    aRect.y += dy;
3066
3067                    ((JComponent) parent).scrollRectToVisible(aRect);
3068                    aRect.x -= dx;
3069                    aRect.y -= dy;
3070                }
3071            }
3072
3073            /**
3074             * Sets the <code>autoscrolls</code> property.
3075             * If <code>true</code> mouse dragged events will be
3076             * synthetically generated when the mouse is dragged
3077             * outside of the component's bounds and mouse motion
3078             * has paused (while the button continues to be held
3079             * down). The synthetic events make it appear that the
3080             * drag gesture has resumed in the direction established when
3081             * the component's boundary was crossed.  Components that
3082             * support autoscrolling must handle <code>mouseDragged</code>
3083             * events by calling <code>scrollRectToVisible</code> with a
3084             * rectangle that contains the mouse event's location.  All of
3085             * the Swing components that support item selection and are
3086             * typically displayed in a <code>JScrollPane</code>
3087             * (<code>JTable</code>, <code>JList</code>, <code>JTree</code>,
3088             * <code>JTextArea</code>, and <code>JEditorPane</code>)
3089             * already handle mouse dragged events in this way.  To enable
3090             * autoscrolling in any other component, add a mouse motion
3091             * listener that calls <code>scrollRectToVisible</code>.
3092             * For example, given a <code>JPanel</code>, <code>myPanel</code>:
3093             * <pre>
3094             * MouseMotionListener doScrollRectToVisible = new MouseMotionAdapter() {
3095             *     public void mouseDragged(MouseEvent e) {
3096             *        Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1);
3097             *        ((JPanel)e.getSource()).scrollRectToVisible(r);
3098             *    }
3099             * };
3100             * myPanel.addMouseMotionListener(doScrollRectToVisible);
3101             * </pre>
3102             * The default value of the <code>autoScrolls</code>
3103             * property is <code>false</code>.
3104             *
3105             * @param autoscrolls if true, synthetic mouse dragged events
3106             *   are generated when the mouse is dragged outside of a component's
3107             *   bounds and the mouse button continues to be held down; otherwise
3108             *   false
3109             * @see #getAutoscrolls
3110             * @see JViewport
3111             * @see JScrollPane
3112             *
3113             * @beaninfo
3114             *      expert: true
3115             * description: Determines if this component automatically scrolls its contents when dragged.
3116             */
3117            public void setAutoscrolls(boolean autoscrolls) {
3118                setFlag(AUTOSCROLLS_SET, true);
3119                if (this .autoscrolls != autoscrolls) {
3120                    this .autoscrolls = autoscrolls;
3121                    if (autoscrolls) {
3122                        enableEvents(AWTEvent.MOUSE_EVENT_MASK);
3123                        enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
3124                    } else {
3125                        Autoscroller.stop(this );
3126                    }
3127                }
3128            }
3129
3130            /**
3131             * Gets the <code>autoscrolls</code> property.
3132             *
3133             * @return the value of the <code>autoscrolls</code> property
3134             * @see JViewport
3135             * @see #setAutoscrolls
3136             */
3137            public boolean getAutoscrolls() {
3138                return autoscrolls;
3139            }
3140
3141            /**
3142             * Sets the {@code TransferHandler}, which provides support for transfer
3143             * of data into and out of this component via cut/copy/paste and drag
3144             * and drop. This may be {@code null} if the component does not support
3145             * data transfer operations.
3146             * <p>
3147             * If the new {@code TransferHandler} is not {@code null}, this method
3148             * also installs a <b>new</b> {@code DropTarget} on the component to
3149             * activate drop handling through the {@code TransferHandler} and activate
3150             * any built-in support (such as calculating and displaying potential drop
3151             * locations). If you do not wish for this component to respond in any way
3152             * to drops, you can disable drop support entirely either by removing the
3153             * drop target ({@code setDropTarget(null)}) or by de-activating it
3154             * ({@code getDropTaget().setActive(false)}).
3155             * <p>
3156             * If the new {@code TransferHandler} is {@code null}, this method removes
3157             * the drop target.
3158             * <p>
3159             * Under two circumstances, this method does not modify the drop target:
3160             * First, if the existing drop target on this component was explicitly
3161             * set by the developer to a {@code non-null} value. Second, if the
3162             * system property {@code suppressSwingDropSupport} is {@code true}. The
3163             * default value for the system property is {@code false}.
3164             * <p>
3165             * Please see
3166             * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/dnd.html">
3167             * How to Use Drag and Drop and Data Transfer</a>,
3168             * a section in <em>The Java Tutorial</em>, for more information.
3169             * 
3170             * @param newHandler the new {@code TransferHandler}
3171             *
3172             * @see TransferHandler
3173             * @see #getTransferHandler
3174             * @since 1.4
3175             * @beaninfo
3176             *        bound: true
3177             *       hidden: true
3178             *  description: Mechanism for transfer of data to and from the component
3179             */
3180            public void setTransferHandler(TransferHandler newHandler) {
3181                TransferHandler oldHandler = (TransferHandler) getClientProperty(JComponent_TRANSFER_HANDLER);
3182                putClientProperty(JComponent_TRANSFER_HANDLER, newHandler);
3183
3184                SwingUtilities.installSwingDropTargetAsNecessary(this ,
3185                        newHandler);
3186                firePropertyChange("transferHandler", oldHandler, newHandler);
3187            }
3188
3189            /**
3190             * Gets the <code>transferHandler</code> property.
3191             *
3192             * @return  the value of the <code>transferHandler</code> property
3193             *
3194             * @see TransferHandler
3195             * @see #setTransferHandler
3196             * @since 1.4
3197             */
3198            public TransferHandler getTransferHandler() {
3199                return (TransferHandler) getClientProperty(JComponent_TRANSFER_HANDLER);
3200            }
3201
3202            /**
3203             * Calculates a custom drop location for this type of component,
3204             * representing where a drop at the given point should insert data.
3205             * <code>null</code> is returned if this component doesn't calculate
3206             * custom drop locations. In this case, <code>TransferHandler</code>
3207             * will provide a default <code>DropLocation</code> containing just
3208             * the point.
3209             *
3210             * @param p the point to calculate a drop location for
3211             * @return the drop location, or <code>null</code>
3212             */
3213            TransferHandler.DropLocation dropLocationForPoint(Point p) {
3214                return null;
3215            }
3216
3217            /**
3218             * Called to set or clear the drop location during a DnD operation.
3219             * In some cases, the component may need to use its internal selection
3220             * temporarily to indicate the drop location. To help facilitate this,
3221             * this method returns and accepts as a parameter a state object.
3222             * This state object can be used to store, and later restore, the selection
3223             * state. Whatever this method returns will be passed back to it in
3224             * future calls, as the state parameter. If it wants the DnD system to
3225             * continue storing the same state, it must pass it back every time.
3226             * Here's how this is used:
3227             * <p>
3228             * Let's say that on the first call to this method the component decides
3229             * to save some state (because it is about to use the selection to show
3230             * a drop index). It can return a state object to the caller encapsulating
3231             * any saved selection state. On a second call, let's say the drop location
3232             * is being changed to something else. The component doesn't need to
3233             * restore anything yet, so it simply passes back the same state object
3234             * to have the DnD system continue storing it. Finally, let's say this
3235             * method is messaged with <code>null</code>. This means DnD
3236             * is finished with this component for now, meaning it should restore
3237             * state. At this point, it can use the state parameter to restore
3238             * said state, and of course return <code>null</code> since there's
3239             * no longer anything to store.
3240             *
3241             * @param location the drop location (as calculated by
3242             *        <code>dropLocationForPoint</code>) or <code>null</code>
3243             *        if there's no longer a valid drop location
3244             * @param state the state object saved earlier for this component,
3245             *        or <code>null</code>
3246             * @param forDrop whether or not the method is being called because an
3247             *        actual drop occurred
3248             * @return any saved state for this component, or <code>null</code> if none
3249             */
3250            Object setDropLocation(TransferHandler.DropLocation location,
3251                    Object state, boolean forDrop) {
3252
3253                return null;
3254            }
3255
3256            /**
3257             * Called to indicate to this component that DnD is done.
3258             * Needed by <code>JTree</code>.
3259             */
3260            void dndDone() {
3261            }
3262
3263            /**
3264             * Processes mouse events occurring on this component by
3265             * dispatching them to any registered
3266             * <code>MouseListener</code> objects, refer to
3267             * {@link java.awt.Component#processMouseEvent(MouseEvent)}
3268             * for a complete description of this method.
3269             *
3270             * @param       e the mouse event
3271             * @see         java.awt.Component#processMouseEvent
3272             * @since       1.5
3273             */
3274            protected void processMouseEvent(MouseEvent e) {
3275                if (autoscrolls && e.getID() == MouseEvent.MOUSE_RELEASED) {
3276                    Autoscroller.stop(this );
3277                }
3278                super .processMouseEvent(e);
3279            }
3280
3281            /**
3282             * Processes mouse motion events, such as MouseEvent.MOUSE_DRAGGED.
3283             *
3284             * @param e the <code>MouseEvent</code>
3285             * @see MouseEvent
3286             */
3287            protected void processMouseMotionEvent(MouseEvent e) {
3288                boolean dispatch = true;
3289                if (autoscrolls && e.getID() == MouseEvent.MOUSE_DRAGGED) {
3290                    // We don't want to do the drags when the mouse moves if we're
3291                    // autoscrolling.  It makes it feel spastic.
3292                    dispatch = !Autoscroller.isRunning(this );
3293                    Autoscroller.processMouseDragged(e);
3294                }
3295                if (dispatch) {
3296                    super .processMouseMotionEvent(e);
3297                }
3298            }
3299
3300            // Inner classes can't get at this method from a super class
3301            void super ProcessMouseMotionEvent(MouseEvent e) {
3302                super .processMouseMotionEvent(e);
3303            }
3304
3305            /**
3306             * This is invoked by the <code>RepaintManager</code> if
3307             * <code>createImage</code> is called on the component.
3308             *
3309             * @param newValue true if the double buffer image was created from this component
3310             */
3311            void setCreatedDoubleBuffer(boolean newValue) {
3312                setFlag(CREATED_DOUBLE_BUFFER, newValue);
3313            }
3314
3315            /**
3316             * Returns true if the <code>RepaintManager</code>
3317             * created the double buffer image from the component.
3318             *
3319             * @return true if this component had a double buffer image, false otherwise
3320             */
3321            boolean getCreatedDoubleBuffer() {
3322                return getFlag(CREATED_DOUBLE_BUFFER);
3323            }
3324
3325            /**
3326             * <code>ActionStandin</code> is used as a standin for
3327             * <code>ActionListeners</code> that are
3328             * added via <code>registerKeyboardAction</code>.
3329             */
3330            final class ActionStandin implements  Action {
3331                private final ActionListener actionListener;
3332                private final String command;
3333                // This will be non-null if actionListener is an Action.
3334                private final Action action;
3335
3336                ActionStandin(ActionListener actionListener, String command) {
3337                    this .actionListener = actionListener;
3338                    if (actionListener instanceof  Action) {
3339                        this .action = (Action) actionListener;
3340                    } else {
3341                        this .action = null;
3342                    }
3343                    this .command = command;
3344                }
3345
3346                public Object getValue(String key) {
3347                    if (key != null) {
3348                        if (key.equals(Action.ACTION_COMMAND_KEY)) {
3349                            return command;
3350                        }
3351                        if (action != null) {
3352                            return action.getValue(key);
3353                        }
3354                        if (key.equals(NAME)) {
3355                            return "ActionStandin";
3356                        }
3357                    }
3358                    return null;
3359                }
3360
3361                public boolean isEnabled() {
3362                    if (actionListener == null) {
3363                        // This keeps the old semantics where
3364                        // registerKeyboardAction(null) would essentialy remove
3365                        // the binding. We don't remove the binding from the
3366                        // InputMap as that would still allow parent InputMaps
3367                        // bindings to be accessed.
3368                        return false;
3369                    }
3370                    if (action == null) {
3371                        return true;
3372                    }
3373                    return action.isEnabled();
3374                }
3375
3376                public void actionPerformed(ActionEvent ae) {
3377                    if (actionListener != null) {
3378                        actionListener.actionPerformed(ae);
3379                    }
3380                }
3381
3382                // We don't allow any values to be added.
3383                public void putValue(String key, Object value) {
3384                }
3385
3386                // Does nothing, our enabledness is determiend from our asociated
3387                // action.
3388                public void setEnabled(boolean b) {
3389                }
3390
3391                public void addPropertyChangeListener(
3392                        PropertyChangeListener listener) {
3393                }
3394
3395                public void removePropertyChangeListener(
3396                        PropertyChangeListener listener) {
3397                }
3398            }
3399
3400            // This class is used by the KeyboardState class to provide a single
3401            // instance that can be stored in the AppContext.
3402            static final class IntVector {
3403                int array[] = null;
3404                int count = 0;
3405                int capacity = 0;
3406
3407                int size() {
3408                    return count;
3409                }
3410
3411                int elementAt(int index) {
3412                    return array[index];
3413                }
3414
3415                void addElement(int value) {
3416                    if (count == capacity) {
3417                        capacity = (capacity + 2) * 2;
3418                        int[] newarray = new int[capacity];
3419                        if (count > 0) {
3420                            System.arraycopy(array, 0, newarray, 0, count);
3421                        }
3422                        array = newarray;
3423                    }
3424                    array[count++] = value;
3425                }
3426
3427                void setElementAt(int value, int index) {
3428                    array[index] = value;
3429                }
3430            }
3431
3432            static class KeyboardState implements  Serializable {
3433                private static final Object keyCodesKey = JComponent.KeyboardState.class;
3434
3435                // Get the array of key codes from the AppContext.
3436                static IntVector getKeyCodeArray() {
3437                    IntVector iv = (IntVector) SwingUtilities
3438                            .appContextGet(keyCodesKey);
3439                    if (iv == null) {
3440                        iv = new IntVector();
3441                        SwingUtilities.appContextPut(keyCodesKey, iv);
3442                    }
3443                    return iv;
3444                }
3445
3446                static void registerKeyPressed(int keyCode) {
3447                    IntVector kca = getKeyCodeArray();
3448                    int count = kca.size();
3449                    int i;
3450                    for (i = 0; i < count; i++) {
3451                        if (kca.elementAt(i) == -1) {
3452                            kca.setElementAt(keyCode, i);
3453                            return;
3454                        }
3455                    }
3456                    kca.addElement(keyCode);
3457                }
3458
3459                static void registerKeyReleased(int keyCode) {
3460                    IntVector kca = getKeyCodeArray();
3461                    int count = kca.size();
3462                    int i;
3463                    for (i = 0; i < count; i++) {
3464                        if (kca.elementAt(i) == keyCode) {
3465                            kca.setElementAt(-1, i);
3466                            return;
3467                        }
3468                    }
3469                }
3470
3471                static boolean keyIsPressed(int keyCode) {
3472                    IntVector kca = getKeyCodeArray();
3473                    int count = kca.size();
3474                    int i;
3475                    for (i = 0; i < count; i++) {
3476                        if (kca.elementAt(i) == keyCode) {
3477                            return true;
3478                        }
3479                    }
3480                    return false;
3481                }
3482
3483                /**
3484                 * Updates internal state of the KeyboardState and returns true
3485                 * if the event should be processed further.
3486                 */
3487                static boolean shouldProcess(KeyEvent e) {
3488                    switch (e.getID()) {
3489                    case KeyEvent.KEY_PRESSED:
3490                        if (!keyIsPressed(e.getKeyCode())) {
3491                            registerKeyPressed(e.getKeyCode());
3492                        }
3493                        return true;
3494                    case KeyEvent.KEY_RELEASED:
3495                        // We are forced to process VK_PRINTSCREEN separately because
3496                        // the Windows doesn't generate the key pressed event for
3497                        // printscreen and it block the processing of key release
3498                        // event for printscreen.
3499                        if (keyIsPressed(e.getKeyCode())
3500                                || e.getKeyCode() == KeyEvent.VK_PRINTSCREEN) {
3501                            registerKeyReleased(e.getKeyCode());
3502                            return true;
3503                        }
3504                        return false;
3505                    case KeyEvent.KEY_TYPED:
3506                        return true;
3507                    default:
3508                        // Not a known KeyEvent type, bail.
3509                        return false;
3510                    }
3511                }
3512            }
3513
3514            static final sun.awt.RequestFocusController focusController = new sun.awt.RequestFocusController() {
3515                public boolean acceptRequestFocus(Component from, Component to,
3516                        boolean temporary, boolean focusedWindowChangeAllowed,
3517                        sun.awt.CausedFocusEvent.Cause cause) {
3518                    if ((to == null) || !(to instanceof  JComponent)) {
3519                        return true;
3520                    }
3521
3522                    if ((from == null) || !(from instanceof  JComponent)) {
3523                        return true;
3524                    }
3525
3526                    JComponent target = (JComponent) to;
3527                    if (!target.getVerifyInputWhenFocusTarget()) {
3528                        return true;
3529                    }
3530
3531                    JComponent jFocusOwner = (JComponent) from;
3532                    InputVerifier iv = jFocusOwner.getInputVerifier();
3533
3534                    if (iv == null) {
3535                        return true;
3536                    } else {
3537                        Object currentSource = SwingUtilities
3538                                .appContextGet(INPUT_VERIFIER_SOURCE_KEY);
3539                        if (currentSource == jFocusOwner) {
3540                            // We're currently calling into the InputVerifier
3541                            // for this component, so allow the focus change.
3542                            return true;
3543                        }
3544                        SwingUtilities.appContextPut(INPUT_VERIFIER_SOURCE_KEY,
3545                                jFocusOwner);
3546                        try {
3547                            return iv.shouldYieldFocus(jFocusOwner);
3548                        } finally {
3549                            if (currentSource != null) {
3550                                // We're already in the InputVerifier for
3551                                // currentSource. By resetting the currentSource
3552                                // we ensure that if the InputVerifier for
3553                                // currentSource does a requestFocus, we don't
3554                                // try and run the InputVerifier again.
3555                                SwingUtilities.appContextPut(
3556                                        INPUT_VERIFIER_SOURCE_KEY,
3557                                        currentSource);
3558                            } else {
3559                                SwingUtilities
3560                                        .appContextRemove(INPUT_VERIFIER_SOURCE_KEY);
3561                            }
3562                        }
3563                    }
3564                }
3565            };
3566
3567            /*
3568             * --- Accessibility Support ---
3569             */
3570
3571            /**
3572             * @deprecated As of JDK version 1.1,
3573             * replaced by <code>java.awt.Component.setEnabled(boolean)</code>.
3574             */
3575            @Deprecated
3576            public void enable() {
3577                if (isEnabled() != true) {
3578                    super .enable();
3579                    if (accessibleContext != null) {
3580                        accessibleContext.firePropertyChange(
3581                                AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
3582                                null, AccessibleState.ENABLED);
3583                    }
3584                }
3585            }
3586
3587            /**
3588             * @deprecated As of JDK version 1.1,
3589             * replaced by <code>java.awt.Component.setEnabled(boolean)</code>.
3590             */
3591            @Deprecated
3592            public void disable() {
3593                if (isEnabled() != false) {
3594                    super .disable();
3595                    if (accessibleContext != null) {
3596                        accessibleContext.firePropertyChange(
3597                                AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
3598                                AccessibleState.ENABLED, null);
3599                    }
3600                }
3601            }
3602
3603            /**
3604             * The <code>AccessibleContext</code> associated with this
3605             * <code>JComponent</code>.
3606             */
3607            protected AccessibleContext accessibleContext = null;
3608
3609            /**
3610             * Returns the <code>AccessibleContext</code> associated with this
3611             * <code>JComponent</code>.  The method implemented by this base
3612             * class returns null.  Classes that extend <code>JComponent</code>
3613             * should implement this method to return the 
3614             * <code>AccessibleContext</code> associated with the subclass. 
3615             *
3616             * @return the <code>AccessibleContext</code> of this
3617             *		<code>JComponent</code>
3618             */
3619            public AccessibleContext getAccessibleContext() {
3620                return accessibleContext;
3621            }
3622
3623            /**
3624             * Inner class of JComponent used to provide default support for
3625             * accessibility.  This class is not meant to be used directly by
3626             * application developers, but is instead meant only to be
3627             * subclassed by component developers.
3628             * <p>
3629             * <strong>Warning:</strong>
3630             * Serialized objects of this class will not be compatible with
3631             * future Swing releases. The current serialization support is
3632             * appropriate for short term storage or RMI between applications running
3633             * the same version of Swing.  As of 1.4, support for long term storage
3634             * of all JavaBeans<sup><font size="-2">TM</font></sup>
3635             * has been added to the <code>java.beans</code> package.
3636             * Please see {@link java.beans.XMLEncoder}.
3637             */
3638            public abstract class AccessibleJComponent extends
3639                    AccessibleAWTContainer implements 
3640                    AccessibleExtendedComponent {
3641                /**
3642                 * Though the class is abstract, this should be called by
3643                 * all sub-classes. 
3644                 */
3645                protected AccessibleJComponent() {
3646                    super ();
3647                }
3648
3649                protected ContainerListener accessibleContainerHandler = null;
3650                protected FocusListener accessibleFocusHandler = null;
3651
3652                /**
3653                 * Fire PropertyChange listener, if one is registered,
3654                 * when children added/removed.
3655                 */
3656                protected class AccessibleContainerHandler implements 
3657                        ContainerListener {
3658                    public void componentAdded(ContainerEvent e) {
3659                        Component c = e.getChild();
3660                        if (c != null && c instanceof  Accessible) {
3661                            AccessibleJComponent.this 
3662                                    .firePropertyChange(
3663                                            AccessibleContext.ACCESSIBLE_CHILD_PROPERTY,
3664                                            null, ((Accessible) c)
3665                                                    .getAccessibleContext());
3666                        }
3667                    }
3668
3669                    public void componentRemoved(ContainerEvent e) {
3670                        Component c = e.getChild();
3671                        if (c != null && c instanceof  Accessible) {
3672                            AccessibleJComponent.this 
3673                                    .firePropertyChange(
3674                                            AccessibleContext.ACCESSIBLE_CHILD_PROPERTY,
3675                                            ((Accessible) c)
3676                                                    .getAccessibleContext(),
3677                                            null);
3678                        }
3679                    }
3680                }
3681
3682                /**
3683                 * Fire PropertyChange listener, if one is registered,
3684                 * when focus events happen
3685                 * @since 1.3
3686                 */
3687                protected class AccessibleFocusHandler implements  FocusListener {
3688                    public void focusGained(FocusEvent event) {
3689                        if (accessibleContext != null) {
3690                            accessibleContext
3691                                    .firePropertyChange(
3692                                            AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
3693                                            null, AccessibleState.FOCUSED);
3694                        }
3695                    }
3696
3697                    public void focusLost(FocusEvent event) {
3698                        if (accessibleContext != null) {
3699                            accessibleContext
3700                                    .firePropertyChange(
3701                                            AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
3702                                            AccessibleState.FOCUSED, null);
3703                        }
3704                    }
3705                } // inner class AccessibleFocusHandler
3706
3707                /**
3708                 * Adds a PropertyChangeListener to the listener list.
3709                 *
3710                 * @param listener  the PropertyChangeListener to be added
3711                 */
3712                public void addPropertyChangeListener(
3713                        PropertyChangeListener listener) {
3714                    if (accessibleFocusHandler == null) {
3715                        accessibleFocusHandler = new AccessibleFocusHandler();
3716                        JComponent.this 
3717                                .addFocusListener(accessibleFocusHandler);
3718                    }
3719                    if (accessibleContainerHandler == null) {
3720                        accessibleContainerHandler = new AccessibleContainerHandler();
3721                        JComponent.this 
3722                                .addContainerListener(accessibleContainerHandler);
3723                    }
3724                    super .addPropertyChangeListener(listener);
3725                }
3726
3727                /**
3728                 * Removes a PropertyChangeListener from the listener list.
3729                 * This removes a PropertyChangeListener that was registered
3730                 * for all properties.
3731                 *
3732                 * @param listener  the PropertyChangeListener to be removed
3733                 */
3734                public void removePropertyChangeListener(
3735                        PropertyChangeListener listener) {
3736                    if (accessibleFocusHandler != null) {
3737                        JComponent.this 
3738                                .removeFocusListener(accessibleFocusHandler);
3739                        accessibleFocusHandler = null;
3740                    }
3741                    super .removePropertyChangeListener(listener);
3742                }
3743
3744                /**
3745                 * Recursively search through the border hierarchy (if it exists)
3746                 * for a TitledBorder with a non-null title.  This does a depth
3747                 * first search on first the inside borders then the outside borders.
3748                 * The assumption is that titles make really pretty inside borders
3749                 * but not very pretty outside borders in compound border situations.
3750                 * It's rather arbitrary, but hopefully decent UI programmers will
3751                 * not create multiple titled borders for the same component.
3752                 */
3753                protected String getBorderTitle(Border b) {
3754                    String s;
3755                    if (b instanceof  TitledBorder) {
3756                        return ((TitledBorder) b).getTitle();
3757                    } else if (b instanceof  CompoundBorder) {
3758                        s = getBorderTitle(((CompoundBorder) b)
3759                                .getInsideBorder());
3760                        if (s == null) {
3761                            s = getBorderTitle(((CompoundBorder) b)
3762                                    .getOutsideBorder());
3763                        }
3764                        return s;
3765                    } else {
3766                        return null;
3767                    }
3768                }
3769
3770                // AccessibleContext methods
3771                //
3772                /**
3773                 * Gets the accessible name of this object.  This should almost never
3774                 * return java.awt.Component.getName(), as that generally isn't
3775                 * a localized name, and doesn't have meaning for the user.  If the
3776                 * object is fundamentally a text object (such as a menu item), the
3777                 * accessible name should be the text of the object (for example, 
3778                 * "save").
3779                 * If the object has a tooltip, the tooltip text may also be an
3780                 * appropriate String to return.
3781                 *
3782                 * @return the localized name of the object -- can be null if this
3783                 *         object does not have a name
3784                 * @see AccessibleContext#setAccessibleName
3785                 */
3786                public String getAccessibleName() {
3787                    String name = accessibleName;
3788
3789                    // fallback to the client name property
3790                    //
3791                    if (name == null) {
3792                        name = (String) getClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY);
3793                    }
3794
3795                    // fallback to the titled border if it exists
3796                    //
3797                    if (name == null) {
3798                        name = getBorderTitle(getBorder());
3799                    }
3800
3801                    // fallback to the label labeling us if it exists
3802                    //
3803                    if (name == null) {
3804                        Object o = getClientProperty(JLabel.LABELED_BY_PROPERTY);
3805                        if (o instanceof  Accessible) {
3806                            AccessibleContext ac = ((Accessible) o)
3807                                    .getAccessibleContext();
3808                            if (ac != null) {
3809                                name = ac.getAccessibleName();
3810                            }
3811                        }
3812                    }
3813                    return name;
3814                }
3815
3816                /**
3817                 * Gets the accessible description of this object.  This should be
3818                 * a concise, localized description of what this object is - what
3819                 * is its meaning to the user.  If the object has a tooltip, the
3820                 * tooltip text may be an appropriate string to return, assuming
3821                 * it contains a concise description of the object (instead of just
3822                 * the name of the object - for example a "Save" icon on a toolbar that
3823                 * had "save" as the tooltip text shouldn't return the tooltip
3824                 * text as the description, but something like "Saves the current
3825                 * text document" instead).
3826                 *
3827                 * @return the localized description of the object -- can be null if
3828                 * this object does not have a description
3829                 * @see AccessibleContext#setAccessibleDescription
3830                 */
3831                public String getAccessibleDescription() {
3832                    String description = accessibleDescription;
3833
3834                    // fallback to the client description property
3835                    //
3836                    if (description == null) {
3837                        description = (String) getClientProperty(AccessibleContext.ACCESSIBLE_DESCRIPTION_PROPERTY);
3838                    }
3839
3840                    // fallback to the tool tip text if it exists
3841                    //
3842                    if (description == null) {
3843                        try {
3844                            description = getToolTipText();
3845                        } catch (Exception e) {
3846                            // Just in case the subclass overrode the
3847                            // getToolTipText method and actually
3848                            // requires a MouseEvent.
3849                            // [[[FIXME:  WDW - we probably should require this
3850                            // method to take a MouseEvent and just pass it on
3851                            // to getToolTipText.  The swing-feedback traffic
3852                            // leads me to believe getToolTipText might change,
3853                            // though, so I was hesitant to make this change at
3854                            // this time.]]]
3855                        }
3856                    }
3857
3858                    // fallback to the label labeling us if it exists
3859                    //
3860                    if (description == null) {
3861                        Object o = getClientProperty(JLabel.LABELED_BY_PROPERTY);
3862                        if (o instanceof  Accessible) {
3863                            AccessibleContext ac = ((Accessible) o)
3864                                    .getAccessibleContext();
3865                            if (ac != null) {
3866                                description = ac.getAccessibleDescription();
3867                            }
3868                        }
3869                    }
3870
3871                    return description;
3872                }
3873
3874                /**
3875                 * Gets the role of this object.
3876                 *
3877                 * @return an instance of AccessibleRole describing the role of the
3878                 * object
3879                 * @see AccessibleRole
3880                 */
3881                public AccessibleRole getAccessibleRole() {
3882                    return AccessibleRole.SWING_COMPONENT;
3883                }
3884
3885                /**
3886                 * Gets the state of this object.
3887                 *
3888                 * @return an instance of AccessibleStateSet containing the current
3889                 * state set of the object
3890                 * @see AccessibleState
3891                 */
3892                public AccessibleStateSet getAccessibleStateSet() {
3893                    AccessibleStateSet states = super .getAccessibleStateSet();
3894                    if (JComponent.this .isOpaque()) {
3895                        states.add(AccessibleState.OPAQUE);
3896                    }
3897                    return states;
3898                }
3899
3900                /**
3901                 * Returns the number of accessible children in the object.  If all
3902                 * of the children of this object implement Accessible, than this
3903                 * method should return the number of children of this object.
3904                 *
3905                 * @return the number of accessible children in the object.
3906                 */
3907                public int getAccessibleChildrenCount() {
3908                    return super .getAccessibleChildrenCount();
3909                }
3910
3911                /**
3912                 * Returns the nth Accessible child of the object.
3913                 *
3914                 * @param i zero-based index of child
3915                 * @return the nth Accessible child of the object
3916                 */
3917                public Accessible getAccessibleChild(int i) {
3918                    return super .getAccessibleChild(i);
3919                }
3920
3921                // ----- AccessibleExtendedComponent
3922
3923                /**
3924                 * Returns the AccessibleExtendedComponent
3925                 *
3926                 * @return the AccessibleExtendedComponent
3927                 */
3928                AccessibleExtendedComponent getAccessibleExtendedComponent() {
3929                    return this ;
3930                }
3931
3932                /**
3933                 * Returns the tool tip text
3934                 *
3935                 * @return the tool tip text, if supported, of the object; 
3936                 * otherwise, null
3937                 * @since 1.4
3938                 */
3939                public String getToolTipText() {
3940                    return JComponent.this .getToolTipText();
3941                }
3942
3943                /**
3944                 * Returns the titled border text
3945                 *
3946                 * @return the titled border text, if supported, of the object; 
3947                 * otherwise, null
3948                 * @since 1.4
3949                 */
3950                public String getTitledBorderText() {
3951                    Border border = JComponent.this .getBorder();
3952                    if (border instanceof  TitledBorder) {
3953                        return ((TitledBorder) border).getTitle();
3954                    } else {
3955                        return null;
3956                    }
3957                }
3958
3959                /**
3960                 * Returns key bindings associated with this object
3961                 *
3962                 * @return the key bindings, if supported, of the object; 
3963                 * otherwise, null
3964                 * @see AccessibleKeyBinding
3965                 * @since 1.4
3966                 */
3967                public AccessibleKeyBinding getAccessibleKeyBinding() {
3968                    return null;
3969                }
3970            } // inner class AccessibleJComponent
3971
3972            /**
3973             * Returns an <code>ArrayTable</code> used for
3974             * key/value "client properties" for this component. If the
3975             * <code>clientProperties</code> table doesn't exist, an empty one
3976             * will be created.
3977             *
3978             * @return an ArrayTable
3979             * @see #putClientProperty
3980             * @see #getClientProperty
3981             */
3982            private ArrayTable getClientProperties() {
3983                if (clientProperties == null) {
3984                    clientProperties = new ArrayTable();
3985                }
3986                return clientProperties;
3987            }
3988
3989            /**
3990             * Returns the value of the property with the specified key.  Only
3991             * properties added with <code>putClientProperty</code> will return
3992             * a non-<code>null</code> value.  
3993             * 
3994             * @param key the being queried
3995             * @return the value of this property or <code>null</code>
3996             * @see #putClientProperty
3997             */
3998            public final Object getClientProperty(Object key) {
3999                if (key == SwingUtilities2.AA_TEXT_PROPERTY_KEY) {
4000                    return aaTextInfo;
4001                } else if (key == SwingUtilities2.COMPONENT_UI_PROPERTY_KEY) {
4002                    return ui;
4003                }
4004                if (clientProperties == null) {
4005                    return null;
4006                } else {
4007                    synchronized (clientProperties) {
4008                        return clientProperties.get(key);
4009                    }
4010                }
4011            }
4012
4013            /**
4014             * Adds an arbitrary key/value "client property" to this component.
4015             * <p>
4016             * The <code>get/putClientProperty</code> methods provide access to 
4017             * a small per-instance hashtable. Callers can use get/putClientProperty
4018             * to annotate components that were created by another module.
4019             * For example, a
4020             * layout manager might store per child constraints this way. For example:
4021             * <pre>
4022             * componentA.putClientProperty("to the left of", componentB);
4023             * </pre>
4024             * If value is <code>null</code> this method will remove the property.
4025             * Changes to client properties are reported with
4026             * <code>PropertyChange</code> events.
4027             * The name of the property (for the sake of PropertyChange
4028             * events) is <code>key.toString()</code>.  
4029             * <p>
4030             * The <code>clientProperty</code> dictionary is not intended to
4031             * support large 
4032             * scale extensions to JComponent nor should be it considered an 
4033             * alternative to subclassing when designing a new component.
4034             * 
4035             * @param key the new client property key
4036             * @param value the new client property value; if <code>null</code>
4037             *		this method will remove the property
4038             * @see #getClientProperty
4039             * @see #addPropertyChangeListener
4040             */
4041            public final void putClientProperty(Object key, Object value) {
4042                if (key == SwingUtilities2.AA_TEXT_PROPERTY_KEY) {
4043                    aaTextInfo = value;
4044                    return;
4045                }
4046                if (value == null && clientProperties == null) {
4047                    // Both the value and ArrayTable are null, implying we don't
4048                    // have to do anything.
4049                    return;
4050                }
4051                ArrayTable clientProperties = getClientProperties();
4052                Object oldValue;
4053                synchronized (clientProperties) {
4054                    oldValue = clientProperties.get(key);
4055                    if (value != null) {
4056                        clientProperties.put(key, value);
4057                    } else if (oldValue != null) {
4058                        clientProperties.remove(key);
4059                    } else {
4060                        // old == new == null
4061                        return;
4062                    }
4063                }
4064                clientPropertyChanged(key, oldValue, value);
4065                firePropertyChange(key.toString(), oldValue, value);
4066            }
4067
4068            // Invoked from putClientProperty.  This is provided for subclasses
4069            // in Swing.
4070            void clientPropertyChanged(Object key, Object oldValue,
4071                    Object newValue) {
4072            }
4073
4074            /*
4075             * Sets the property with the specified name to the specified value if
4076             * the property has not already been set by the client program.
4077             * This method is used primarily to set UI defaults for properties
4078             * with primitive types, where the values cannot be marked with
4079             * UIResource.
4080             * @see LookAndFeel#installProperty
4081             * @param propertyName String containing the name of the property
4082             * @param value Object containing the property value
4083             */
4084            void setUIProperty(String propertyName, Object value) {
4085                if (propertyName == "opaque") {
4086                    if (!getFlag(OPAQUE_SET)) {
4087                        setOpaque(((Boolean) value).booleanValue());
4088                        setFlag(OPAQUE_SET, false);
4089                    }
4090                } else if (propertyName == "autoscrolls") {
4091                    if (!getFlag(AUTOSCROLLS_SET)) {
4092                        setAutoscrolls(((Boolean) value).booleanValue());
4093                        setFlag(AUTOSCROLLS_SET, false);
4094                    }
4095                } else if (propertyName == "focusTraversalKeysForward") {
4096                    if (!getFlag(FOCUS_TRAVERSAL_KEYS_FORWARD_SET)) {
4097                        super .setFocusTraversalKeys(
4098                                KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
4099                                (Set) value);
4100                    }
4101                } else if (propertyName == "focusTraversalKeysBackward") {
4102                    if (!getFlag(FOCUS_TRAVERSAL_KEYS_BACKWARD_SET)) {
4103                        super .setFocusTraversalKeys(
4104                                KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
4105                                (Set) value);
4106                    }
4107                } else {
4108                    throw new IllegalArgumentException("property \""
4109                            + propertyName
4110                            + "\" cannot be set using this method");
4111                }
4112            }
4113
4114            /**
4115             * Sets the focus traversal keys for a given traversal operation for this
4116             * Component.
4117             * Refer to 
4118             * {@link java.awt.Component#setFocusTraversalKeys}
4119             * for a complete description of this method.
4120             *
4121             * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
4122             *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
4123             *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
4124             * @param keystrokes the Set of AWTKeyStroke for the specified operation
4125             * @see java.awt.KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
4126             * @see java.awt.KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
4127             * @see java.awt.KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
4128             * @throws IllegalArgumentException if id is not one of
4129             *         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
4130             *         KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
4131             *         KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or if keystrokes
4132             *         contains null, or if any Object in keystrokes is not an
4133             *         AWTKeyStroke, or if any keystroke represents a KEY_TYPED event,
4134             *         or if any keystroke already maps to another focus traversal
4135             *         operation for this Component
4136             * @since 1.5
4137             * @beaninfo
4138             *       bound: true
4139             */
4140            public void setFocusTraversalKeys(int id,
4141                    Set<? extends AWTKeyStroke> keystrokes) {
4142                if (id == KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS) {
4143                    setFlag(FOCUS_TRAVERSAL_KEYS_FORWARD_SET, true);
4144                } else if (id == KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS) {
4145                    setFlag(FOCUS_TRAVERSAL_KEYS_BACKWARD_SET, true);
4146                }
4147                super .setFocusTraversalKeys(id, keystrokes);
4148            }
4149
4150            /* --- Transitional java.awt.Component Support ---
4151             * The methods and fields in this section will migrate to
4152             * java.awt.Component in the next JDK release.
4153             */
4154
4155            /**
4156             * Returns true if this component is lightweight, that is, if it doesn't
4157             * have a native window system peer.
4158             *
4159             * @return true if this component is lightweight
4160             */
4161            public static boolean isLightweightComponent(Component c) {
4162                return c.getPeer() instanceof  LightweightPeer;
4163            }
4164
4165            /**
4166             * @deprecated As of JDK 5,
4167             * replaced by <code>Component.setBounds(int, int, int, int)</code>.
4168             * <p>
4169             * Moves and resizes this component.
4170             *
4171             * @param x  the new horizontal location
4172             * @param y  the new vertical location
4173             * @param w  the new width
4174             * @param h  the new height
4175             * @see java.awt.Component#setBounds
4176             */
4177            @Deprecated
4178            public void reshape(int x, int y, int w, int h) {
4179                super .reshape(x, y, w, h);
4180            }
4181
4182            /**
4183             * Stores the bounds of this component into "return value"
4184             * <code>rv</code> and returns <code>rv</code>.
4185             * If <code>rv</code> is <code>null</code> a new <code>Rectangle</code>
4186             * is allocated.  This version of <code>getBounds</code> is useful
4187             * if the caller wants to avoid allocating a new <code>Rectangle</code>
4188             * object on the heap.
4189             *
4190             * @param rv the return value, modified to the component's bounds
4191             * @return <code>rv</code>; if <code>rv</code> is <code>null</code>
4192             *		return a newly created <code>Rectangle</code> with this
4193             *		component's bounds
4194             */
4195            public Rectangle getBounds(Rectangle rv) {
4196                if (rv == null) {
4197                    return new Rectangle(getX(), getY(), getWidth(),
4198                            getHeight());
4199                } else {
4200                    rv.setBounds(getX(), getY(), getWidth(), getHeight());
4201                    return rv;
4202                }
4203            }
4204
4205            /**
4206             * Stores the width/height of this component into "return value"
4207             * <code>rv</code> and returns <code>rv</code>.
4208             * If <code>rv</code> is <code>null</code> a new <code>Dimension</code>
4209             * object is allocated.  This version of <code>getSize</code>
4210             * is useful if the caller wants to avoid allocating a new
4211             * <code>Dimension</code> object on the heap.
4212             *
4213             * @param rv the return value, modified to the component's size
4214             * @return <code>rv</code>
4215             */
4216            public Dimension getSize(Dimension rv) {
4217                if (rv == null) {
4218                    return new Dimension(getWidth(), getHeight());
4219                } else {
4220                    rv.setSize(getWidth(), getHeight());
4221                    return rv;
4222                }
4223            }
4224
4225            /**
4226             * Stores the x,y origin of this component into "return value"
4227             * <code>rv</code> and returns <code>rv</code>.
4228             * If <code>rv</code> is <code>null</code> a new <code>Point</code>
4229             * is allocated.  This version of <code>getLocation</code> is useful
4230             * if the caller wants to avoid allocating a new <code>Point</code>
4231             * object on the heap.
4232             *
4233             * @param rv the return value, modified to the component's location
4234             * @return <code>rv</code>
4235             */
4236            public Point getLocation(Point rv) {
4237                if (rv == null) {
4238                    return new Point(getX(), getY());
4239                } else {
4240                    rv.setLocation(getX(), getY());
4241                    return rv;
4242                }
4243            }
4244
4245            /**
4246             * Returns the current x coordinate of the component's origin.
4247             * This method is preferable to writing
4248             * <code>component.getBounds().x</code>, or
4249             * <code>component.getLocation().x</code> because it doesn't cause any
4250             * heap allocations.
4251             *
4252             * @return the current x coordinate of the component's origin
4253             */
4254            public int getX() {
4255                return super .getX();
4256            }
4257
4258            /**
4259             * Returns the current y coordinate of the component's origin.
4260             * This method is preferable to writing
4261             * <code>component.getBounds().y</code>, or
4262             * <code>component.getLocation().y</code> because it doesn't cause any
4263             * heap allocations.
4264             *
4265             * @return the current y coordinate of the component's origin
4266             */
4267            public int getY() {
4268                return super .getY();
4269            }
4270
4271            /**
4272             * Returns the current width of this component.
4273             * This method is preferable to writing
4274             * <code>component.getBounds().width</code>, or
4275             * <code>component.getSize().width</code> because it doesn't cause any
4276             * heap allocations.
4277             *
4278             * @return the current width of this component
4279             */
4280            public int getWidth() {
4281                return super .getWidth();
4282            }
4283
4284            /**
4285             * Returns the current height of this component.
4286             * This method is preferable to writing
4287             * <code>component.getBounds().height</code>, or
4288             * <code>component.getSize().height</code> because it doesn't cause any
4289             * heap allocations.
4290             *
4291             * @return the current height of this component
4292             */
4293            public int getHeight() {
4294                return super .getHeight();
4295            }
4296
4297            /**
4298             * Returns true if this component is completely opaque.
4299             * <p>
4300             * An opaque component paints every pixel within its
4301             * rectangular bounds. A non-opaque component paints only a subset of
4302             * its pixels or none at all, allowing the pixels underneath it to
4303             * "show through".  Therefore, a component that does not fully paint
4304             * its pixels provides a degree of transparency.
4305             * <p>
4306             * Subclasses that guarantee to always completely paint their contents
4307             * should override this method and return true.
4308             *
4309             * @return true if this component is completely opaque
4310             * @see #setOpaque
4311             */
4312            public boolean isOpaque() {
4313                return getFlag(IS_OPAQUE);
4314            }
4315
4316            /**
4317             * If true the component paints every pixel within its bounds. 
4318             * Otherwise, the component may not paint some or all of its
4319             * pixels, allowing the underlying pixels to show through.
4320             * <p>
4321             * The default value of this property is false for <code>JComponent</code>.
4322             * However, the default value for this property on most standard
4323             * <code>JComponent</code> subclasses (such as <code>JButton</code> and
4324             * <code>JTree</code>) is look-and-feel dependent.
4325             *
4326             * @param isOpaque  true if this component should be opaque
4327             * @see #isOpaque
4328             * @beaninfo
4329             *        bound: true
4330             *       expert: true
4331             *  description: The component's opacity
4332             */
4333            public void setOpaque(boolean isOpaque) {
4334                boolean oldValue = getFlag(IS_OPAQUE);
4335                setFlag(IS_OPAQUE, isOpaque);
4336                setFlag(OPAQUE_SET, true);
4337                firePropertyChange("opaque", oldValue, isOpaque);
4338            }
4339
4340            /**
4341             * If the specified rectangle is completely obscured by any of this
4342             * component's opaque children then returns true.  Only direct children
4343             * are considered, more distant descendants are ignored.  A
4344             * <code>JComponent</code> is opaque if
4345             * <code>JComponent.isOpaque()</code> returns true, other lightweight
4346             * components are always considered transparent, and heavyweight components
4347             * are always considered opaque.
4348             *
4349             * @param x  x value of specified rectangle
4350             * @param y  y value of specified rectangle
4351             * @param width  width of specified rectangle
4352             * @param height height of specified rectangle
4353             * @return true if the specified rectangle is obscured by an opaque child
4354             */
4355            boolean rectangleIsObscured(int x, int y, int width, int height) {
4356                int numChildren = getComponentCount();
4357
4358                for (int i = 0; i < numChildren; i++) {
4359                    Component child = getComponent(i);
4360                    int cx, cy, cw, ch;
4361
4362                    cx = child.getX();
4363                    cy = child.getY();
4364                    cw = child.getWidth();
4365                    ch = child.getHeight();
4366
4367                    if (x >= cx && (x + width) <= (cx + cw) && y >= cy
4368                            && (y + height) <= (cy + ch) && child.isVisible()) {
4369
4370                        if (child instanceof  JComponent) {
4371                            //		    System.out.println("A) checking opaque: " + ((JComponent)child).isOpaque() + "  " + child);
4372                            //		    System.out.print("B) ");
4373                            //		    Thread.dumpStack();
4374                            return ((JComponent) child).isOpaque();
4375                        } else {
4376                            /** Sometimes a heavy weight can have a bound larger than its peer size
4377                             *  so we should always draw under heavy weights
4378                             */
4379                            return false;
4380                        }
4381                    }
4382                }
4383
4384                return false;
4385            }
4386
4387            /**
4388             * Returns the <code>Component</code>'s "visible rect rectangle" -  the
4389             * intersection of the visible rectangles for the component <code>c</code>
4390             * and all of its ancestors.  The return value is stored in
4391             * <code>visibleRect</code>.
4392             *
4393             * @param c  the component
4394             * @param visibleRect  a <code>Rectangle</code> computed as the
4395             *		intersection of all visible rectangles for the component
4396             *		<code>c</code> and all of its ancestors -- this is the
4397             *		return value for this method
4398             * @see #getVisibleRect
4399             */
4400            static final void computeVisibleRect(Component c,
4401                    Rectangle visibleRect) {
4402                Container p = c.getParent();
4403                Rectangle bounds = c.getBounds();
4404
4405                if (p == null || p instanceof  Window || p instanceof  Applet) {
4406                    visibleRect.setBounds(0, 0, bounds.width, bounds.height);
4407                } else {
4408                    computeVisibleRect(p, visibleRect);
4409                    visibleRect.x -= bounds.x;
4410                    visibleRect.y -= bounds.y;
4411                    SwingUtilities.computeIntersection(0, 0, bounds.width,
4412                            bounds.height, visibleRect);
4413                }
4414            }
4415
4416            /**
4417             * Returns the <code>Component</code>'s "visible rect rectangle" -  the
4418             * intersection of the visible rectangles for this component
4419             * and all of its ancestors.  The return value is stored in
4420             * <code>visibleRect</code>.
4421             *
4422             * @param visibleRect a <code>Rectangle</code> computed as the 
4423             *		intersection of all visible rectangles for this
4424             *		component and all of its ancestors -- this is the return
4425             *		value for this method
4426             * @see #getVisibleRect
4427             */
4428            public void computeVisibleRect(Rectangle visibleRect) {
4429                computeVisibleRect(this , visibleRect);
4430            }
4431
4432            /**
4433             * Returns the <code>Component</code>'s "visible rectangle" -  the
4434             * intersection of this component's visible rectangle,
4435             * <code>new Rectangle(0, 0, getWidth(), getHeight())</code>,
4436             * and all of its ancestors' visible rectangles.
4437             *
4438             * @return the visible rectangle
4439             */
4440            public Rectangle getVisibleRect() {
4441                Rectangle visibleRect = new Rectangle();
4442
4443                computeVisibleRect(visibleRect);
4444                return visibleRect;
4445            }
4446
4447            /**
4448             * Support for reporting bound property changes for boolean properties. 
4449             * This method can be called when a bound property has changed and it will
4450             * send the appropriate PropertyChangeEvent to any registered
4451             * PropertyChangeListeners.
4452             *
4453             * @param propertyName the property whose value has changed
4454             * @param oldValue the property's previous value
4455             * @param newValue the property's new value
4456             */
4457            public void firePropertyChange(String propertyName,
4458                    boolean oldValue, boolean newValue) {
4459                super .firePropertyChange(propertyName, oldValue, newValue);
4460            }
4461
4462            /**
4463             * Support for reporting bound property changes for integer properties. 
4464             * This method can be called when a bound property has changed and it will
4465             * send the appropriate PropertyChangeEvent to any registered
4466             * PropertyChangeListeners.
4467             *
4468             * @param propertyName the property whose value has changed
4469             * @param oldValue the property's previous value
4470             * @param newValue the property's new value
4471             */
4472            public void firePropertyChange(String propertyName, int oldValue,
4473                    int newValue) {
4474                super .firePropertyChange(propertyName, oldValue, newValue);
4475            }
4476
4477            // XXX This method is implemented as a workaround to a JLS issue with ambiguous 
4478            // methods. This should be removed once 4758654 is resolved.
4479            public void firePropertyChange(String propertyName, char oldValue,
4480                    char newValue) {
4481                super .firePropertyChange(propertyName, oldValue, newValue);
4482            }
4483
4484            /**
4485             * Supports reporting constrained property changes.
4486             * This method can be called when a constrained property has changed
4487             * and it will send the appropriate <code>PropertyChangeEvent</code>
4488             * to any registered <code>VetoableChangeListeners</code>.
4489             *
4490             * @param propertyName  the name of the property that was listened on
4491             * @param oldValue  the old value of the property
4492             * @param newValue  the new value of the property
4493             * @exception PropertyVetoException when the attempt to set the
4494             *		property is vetoed by the component
4495             */
4496            protected void fireVetoableChange(String propertyName,
4497                    Object oldValue, Object newValue)
4498                    throws java.beans.PropertyVetoException {
4499                if (vetoableChangeSupport == null) {
4500                    return;
4501                }
4502                vetoableChangeSupport.fireVetoableChange(propertyName,
4503                        oldValue, newValue);
4504            }
4505
4506            /**
4507             * Adds a <code>VetoableChangeListener</code> to the listener list.
4508             * The listener is registered for all properties.
4509             *
4510             * @param listener  the <code>VetoableChangeListener</code> to be added
4511             */
4512            public synchronized void addVetoableChangeListener(
4513                    VetoableChangeListener listener) {
4514                if (vetoableChangeSupport == null) {
4515                    vetoableChangeSupport = new java.beans.VetoableChangeSupport(
4516                            this );
4517                }
4518                vetoableChangeSupport.addVetoableChangeListener(listener);
4519            }
4520
4521            /**
4522             * Removes a <code>VetoableChangeListener</code> from the listener list.
4523             * This removes a <code>VetoableChangeListener</code> that was registered
4524             * for all properties.
4525             *
4526             * @param listener  the <code>VetoableChangeListener</code> to be removed
4527             */
4528            public synchronized void removeVetoableChangeListener(
4529                    VetoableChangeListener listener) {
4530                if (vetoableChangeSupport == null) {
4531                    return;
4532                }
4533                vetoableChangeSupport.removeVetoableChangeListener(listener);
4534            }
4535
4536            /**
4537             * Returns an array of all the vetoable change listeners 
4538             * registered on this component.
4539             *
4540             * @return all of the component's <code>VetoableChangeListener</code>s
4541             *         or an empty
4542             *         array if no vetoable change listeners are currently registered
4543             *
4544             * @see #addVetoableChangeListener
4545             * @see #removeVetoableChangeListener
4546             *
4547             * @since 1.4
4548             */
4549            public synchronized VetoableChangeListener[] getVetoableChangeListeners() {
4550                if (vetoableChangeSupport == null) {
4551                    return new VetoableChangeListener[0];
4552                }
4553                return vetoableChangeSupport.getVetoableChangeListeners();
4554            }
4555
4556            /**
4557             * Returns the top-level ancestor of this component (either the
4558             * containing <code>Window</code> or <code>Applet</code>),
4559             * or <code>null</code> if this component has not
4560             * been added to any container.
4561             *
4562             * @return the top-level <code>Container</code> that this component is in,
4563             *		or <code>null</code> if not in any container
4564             */
4565            public Container getTopLevelAncestor() {
4566                for (Container p = this ; p != null; p = p.getParent()) {
4567                    if (p instanceof  Window || p instanceof  Applet) {
4568                        return p;
4569                    }
4570                }
4571                return null;
4572            }
4573
4574            private AncestorNotifier getAncestorNotifier() {
4575                return (AncestorNotifier) getClientProperty(JComponent_ANCESTOR_NOTIFIER);
4576            }
4577
4578            /**
4579             * Registers <code>listener</code> so that it will receive
4580             * <code>AncestorEvents</code> when it or any of its ancestors
4581             * move or are made visible or invisible.
4582             * Events are also sent when the component or its ancestors are added
4583             * or removed from the containment hierarchy.
4584             *
4585             * @param listener  the <code>AncestorListener</code> to register
4586             * @see AncestorEvent
4587             */
4588            public void addAncestorListener(AncestorListener listener) {
4589                AncestorNotifier ancestorNotifier = getAncestorNotifier();
4590                if (ancestorNotifier == null) {
4591                    ancestorNotifier = new AncestorNotifier(this );
4592                    putClientProperty(JComponent_ANCESTOR_NOTIFIER,
4593                            ancestorNotifier);
4594                }
4595                ancestorNotifier.addAncestorListener(listener);
4596            }
4597
4598            /**
4599             * Unregisters <code>listener</code> so that it will no longer receive
4600             * <code>AncestorEvents</code>.
4601             *
4602             * @param listener  the <code>AncestorListener</code> to be removed
4603             * @see #addAncestorListener
4604             */
4605            public void removeAncestorListener(AncestorListener listener) {
4606                AncestorNotifier ancestorNotifier = getAncestorNotifier();
4607                if (ancestorNotifier == null) {
4608                    return;
4609                }
4610                ancestorNotifier.removeAncestorListener(listener);
4611                if (ancestorNotifier.listenerList.getListenerList().length == 0) {
4612                    ancestorNotifier.removeAllListeners();
4613                    putClientProperty(JComponent_ANCESTOR_NOTIFIER, null);
4614                }
4615            }
4616
4617            /**
4618             * Returns an array of all the ancestor listeners 
4619             * registered on this component.
4620             * 
4621             * @return all of the component's <code>AncestorListener</code>s 
4622             *         or an empty
4623             *         array if no ancestor listeners are currently registered
4624             *
4625             * @see #addAncestorListener
4626             * @see #removeAncestorListener
4627             *
4628             * @since 1.4
4629             */
4630            public AncestorListener[] getAncestorListeners() {
4631                AncestorNotifier ancestorNotifier = getAncestorNotifier();
4632                if (ancestorNotifier == null) {
4633                    return new AncestorListener[0];
4634                }
4635                return ancestorNotifier.getAncestorListeners();
4636            }
4637
4638            /**
4639             * Returns an array of all the objects currently registered
4640             * as <code><em>Foo</em>Listener</code>s
4641             * upon this <code>JComponent</code>.
4642             * <code><em>Foo</em>Listener</code>s are registered using the 
4643             * <code>add<em>Foo</em>Listener</code> method.
4644             *
4645             * <p>
4646             * 
4647             * You can specify the <code>listenerType</code> argument
4648             * with a class literal, 
4649             * such as 
4650             * <code><em>Foo</em>Listener.class</code>.
4651             * For example, you can query a  
4652             * <code>JComponent</code> <code>c</code>
4653             * for its mouse listeners with the following code:
4654             * <pre>MouseListener[] mls = (MouseListener[])(c.getListeners(MouseListener.class));</pre>
4655             * If no such listeners exist, this method returns an empty array.
4656             * 
4657             * @param listenerType the type of listeners requested; this parameter
4658             *		should specify an interface that descends from
4659             *          <code>java.util.EventListener</code>
4660             * @return an array of all objects registered as 
4661             *		<code><em>Foo</em>Listener</code>s on this component,
4662             *          or an empty array if no such
4663             *		listeners have been added
4664             * @exception ClassCastException if <code>listenerType</code> 
4665             *          doesn't specify a class or interface that implements
4666             *		<code>java.util.EventListener</code>
4667             *
4668             * @since 1.3
4669             * 
4670             * @see #getVetoableChangeListeners
4671             * @see #getAncestorListeners
4672             */
4673            public <T extends EventListener> T[] getListeners(
4674                    Class<T> listenerType) {
4675                T[] result;
4676                if (listenerType == AncestorListener.class) {
4677                    // AncestorListeners are handled by the AncestorNotifier
4678                    result = (T[]) getAncestorListeners();
4679                } else if (listenerType == VetoableChangeListener.class) {
4680                    // VetoableChangeListeners are handled by VetoableChangeSupport
4681                    result = (T[]) getVetoableChangeListeners();
4682                } else if (listenerType == PropertyChangeListener.class) {
4683                    // PropertyChangeListeners are handled by PropertyChangeSupport
4684                    result = (T[]) getPropertyChangeListeners();
4685                } else {
4686                    result = (T[]) listenerList.getListeners(listenerType);
4687                }
4688
4689                if (result.length == 0) {
4690                    return super .getListeners(listenerType);
4691                }
4692                return result;
4693            }
4694
4695            /**
4696             * Notifies this component that it now has a parent component.
4697             * When this method is invoked, the chain of parent components is
4698             * set up with <code>KeyboardAction</code> event listeners.
4699             *
4700             * @see #registerKeyboardAction
4701             */
4702            public void addNotify() {
4703                super .addNotify();
4704                firePropertyChange("ancestor", null, getParent());
4705
4706                registerWithKeyboardManager(false);
4707                registerNextFocusableComponent();
4708            }
4709
4710            /**
4711             * Notifies this component that it no longer has a parent component.
4712             * When this method is invoked, any <code>KeyboardAction</code>s
4713             * set up in the the chain of parent components are removed.
4714             *
4715             * @see #registerKeyboardAction
4716             */
4717            public void removeNotify() {
4718                super .removeNotify();
4719                // This isn't strictly correct.  The event shouldn't be
4720                // fired until *after* the parent is set to null.  But
4721                // we only get notified before that happens
4722                firePropertyChange("ancestor", getParent(), null);
4723
4724                unregisterWithKeyboardManager();
4725                deregisterNextFocusableComponent();
4726
4727                if (getCreatedDoubleBuffer()) {
4728                    RepaintManager.currentManager(this ).resetDoubleBuffer();
4729                    setCreatedDoubleBuffer(false);
4730                }
4731                if (autoscrolls) {
4732                    Autoscroller.stop(this );
4733                }
4734            }
4735
4736            /**
4737             * Adds the specified region to the dirty region list if the component
4738             * is showing.  The component will be repainted after all of the
4739             * currently pending events have been dispatched.
4740             *
4741             * @param tm  this parameter is not used
4742             * @param x  the x value of the dirty region
4743             * @param y  the y value of the dirty region
4744             * @param width  the width of the dirty region
4745             * @param height  the height of the dirty region
4746             * @see java.awt.Component#isShowing
4747             * @see RepaintManager#addDirtyRegion
4748             */
4749            public void repaint(long tm, int x, int y, int width, int height) {
4750                RepaintManager.currentManager(this ).addDirtyRegion(this , x, y,
4751                        width, height);
4752            }
4753
4754            /**
4755             * Adds the specified region to the dirty region list if the component
4756             * is showing.  The component will be repainted after all of the
4757             * currently pending events have been dispatched.
4758             *
4759             * @param  r a <code>Rectangle</code> containing the dirty region
4760             * @see java.awt.Component#isShowing
4761             * @see RepaintManager#addDirtyRegion
4762             */
4763            public void repaint(Rectangle r) {
4764                repaint(0, r.x, r.y, r.width, r.height);
4765            }
4766
4767            /**
4768             * Supports deferred automatic layout.  
4769             * <p> 
4770             * Calls <code>invalidate</code> and then adds this component's
4771             * <code>validateRoot</code> to a list of components that need to be
4772             * validated.  Validation will occur after all currently pending
4773             * events have been dispatched.  In other words after this method
4774             * is called,  the first validateRoot (if any) found when walking
4775             * up the containment hierarchy of this component will be validated.
4776             * By default, <code>JRootPane</code>, <code>JScrollPane</code>,
4777             * and <code>JTextField</code> return true 
4778             * from <code>isValidateRoot</code>.
4779             * <p>
4780             * This method will automatically be called on this component 
4781             * when a property value changes such that size, location, or 
4782             * internal layout of this component has been affected.  This automatic
4783             * updating differs from the AWT because programs generally no
4784             * longer need to invoke <code>validate</code> to get the contents of the
4785             * GUI to update. 
4786             * <p>
4787             *
4788             * @see java.awt.Component#invalidate
4789             * @see java.awt.Container#validate
4790             * @see #isValidateRoot
4791             * @see RepaintManager#addInvalidComponent
4792             */
4793            public void revalidate() {
4794                if (getParent() == null) {
4795                    // Note: We don't bother invalidating here as once added
4796                    // to a valid parent invalidate will be invoked (addImpl
4797                    // invokes addNotify which will invoke invalidate on the
4798                    // new Component). Also, if we do add a check to isValid
4799                    // here it can potentially be called before the constructor
4800                    // which was causing some people grief.
4801                    return;
4802                }
4803                if (SwingUtilities.isEventDispatchThread()) {
4804                    invalidate();
4805                    RepaintManager.currentManager(this ).addInvalidComponent(
4806                            this );
4807                } else {
4808                    // To avoid a flood of Runnables when constructing GUIs off
4809                    // the EDT, a flag is maintained as to whether or not
4810                    // a Runnable has been scheduled.
4811                    synchronized (this ) {
4812                        if (getFlag(REVALIDATE_RUNNABLE_SCHEDULED)) {
4813                            return;
4814                        }
4815                        setFlag(REVALIDATE_RUNNABLE_SCHEDULED, true);
4816                    }
4817                    Runnable callRevalidate = new Runnable() {
4818                        public void run() {
4819                            synchronized (JComponent.this ) {
4820                                setFlag(REVALIDATE_RUNNABLE_SCHEDULED, false);
4821                            }
4822                            revalidate();
4823                        }
4824                    };
4825                    SwingUtilities.invokeLater(callRevalidate);
4826                }
4827            }
4828
4829            /**
4830             * If this method returns true, <code>revalidate</code> calls by
4831             * descendants of this component will cause the entire tree
4832             * beginning with this root to be validated.
4833             * Returns false by default.  <code>JScrollPane</code> overrides
4834             * this method and returns true.
4835             *
4836             * @return always returns false
4837             * @see #revalidate
4838             * @see java.awt.Component#invalidate
4839             * @see java.awt.Container#validate
4840             */
4841            public boolean isValidateRoot() {
4842                return false;
4843            }
4844
4845            /**
4846             * Returns true if this component tiles its children -- that is, if
4847             * it can guarantee that the children will not overlap.  The
4848             * repainting system is substantially more efficient in this
4849             * common case.  <code>JComponent</code> subclasses that can't make this
4850             * guarantee, such as <code>JLayeredPane</code>,
4851             * should override this method to return false.
4852             *
4853             * @return always returns true 
4854             */
4855            public boolean isOptimizedDrawingEnabled() {
4856                return true;
4857            }
4858
4859            /**
4860             * Returns true if a paint triggered on a child component should cause
4861             * painting to originate from this Component, or one of its ancestors.
4862             *
4863             * @return true if painting should originate from this Component or
4864             *         one of its ancestors.
4865             */
4866            boolean isPaintingOrigin() {
4867                return false;
4868            }
4869
4870            /**
4871             * Paints the specified region in this component and all of its
4872             * descendants that overlap the region, immediately.
4873             * <p>
4874             * It's rarely necessary to call this method.  In most cases it's
4875             * more efficient to call repaint, which defers the actual painting
4876             * and can collapse redundant requests into a single paint call.
4877             * This method is useful if one needs to update the display while
4878             * the current event is being dispatched.
4879             *
4880             * @param x  the x value of the region to be painted
4881             * @param y  the y value of the region to be painted
4882             * @param w  the width of the region to be painted
4883             * @param h  the height of the region to be painted
4884             * @see #repaint
4885             */
4886            public void paintImmediately(int x, int y, int w, int h) {
4887                Component c = this ;
4888                Component parent;
4889
4890                if (!isShowing()) {
4891                    return;
4892                }
4893                while (!((JComponent) c).isOpaque()) {
4894                    parent = c.getParent();
4895                    if (parent != null) {
4896                        x += c.getX();
4897                        y += c.getY();
4898                        c = parent;
4899                    } else {
4900                        break;
4901                    }
4902
4903                    if (!(c instanceof  JComponent)) {
4904                        break;
4905                    }
4906                }
4907                if (c instanceof  JComponent) {
4908                    ((JComponent) c)._paintImmediately(x, y, w, h);
4909                } else {
4910                    c.repaint(x, y, w, h);
4911                }
4912            }
4913
4914            /**
4915             * Paints the specified region now.
4916             *
4917             * @param r a <code>Rectangle</code> containing the region to be painted
4918             */
4919            public void paintImmediately(Rectangle r) {
4920                paintImmediately(r.x, r.y, r.width, r.height);
4921            }
4922
4923            /**
4924             * Returns whether this component should be guaranteed to be on top.
4925             * For example, it would make no sense for <code>Menu</code>s to pop up 
4926             * under another component, so they would always return true.
4927             * Most components will want to return false, hence that is the default.
4928             * 
4929             * @return always returns false
4930             */
4931            // package private
4932            boolean alwaysOnTop() {
4933                return false;
4934            }
4935
4936            void setPaintingChild(Component paintingChild) {
4937                this .paintingChild = paintingChild;
4938            }
4939
4940            void _paintImmediately(int x, int y, int w, int h) {
4941                Graphics g;
4942                Container c;
4943                Rectangle b;
4944
4945                int tmpX, tmpY, tmpWidth, tmpHeight;
4946                int offsetX = 0, offsetY = 0;
4947
4948                boolean hasBuffer = false;
4949
4950                JComponent bufferedComponent = null;
4951                JComponent paintingComponent = this ;
4952
4953                RepaintManager repaintManager = RepaintManager
4954                        .currentManager(this );
4955                // parent Container's up to Window or Applet. First container is
4956                // the direct parent. Note that in testing it was faster to 
4957                // alloc a new Vector vs keeping a stack of them around, and gc
4958                // seemed to have a minimal effect on this.
4959                java.util.List<Component> path = new java.util.ArrayList<Component>(
4960                        7);
4961                int pIndex = -1;
4962                int pCount = 0;
4963
4964                tmpX = tmpY = tmpWidth = tmpHeight = 0;
4965
4966                Rectangle paintImmediatelyClip = fetchRectangle();
4967                paintImmediatelyClip.x = x;
4968                paintImmediatelyClip.y = y;
4969                paintImmediatelyClip.width = w;
4970                paintImmediatelyClip.height = h;
4971
4972                // System.out.println("1) ************* in _paintImmediately for " + this);
4973
4974                boolean ontop = alwaysOnTop() && isOpaque();
4975                if (ontop) {
4976                    SwingUtilities.computeIntersection(0, 0, getWidth(),
4977                            getHeight(), paintImmediatelyClip);
4978                    if (paintImmediatelyClip.width == 0) {
4979                        recycleRectangle(paintImmediatelyClip);
4980                        return;
4981                    }
4982                }
4983                Component child;
4984                for (c = this , child = null; c != null
4985                        && !(c instanceof  Window) && !(c instanceof  Applet); child = c, c = c
4986                        .getParent()) {
4987                    JComponent jc = (c instanceof  JComponent) ? (JComponent) c
4988                            : null;
4989                    path.add(c);
4990                    if (!ontop && jc != null && !jc.isOptimizedDrawingEnabled()) {
4991                        boolean resetPC;
4992
4993                        // Children of c may overlap, three possible cases for the
4994                        // painting region:
4995                        // . Completely obscured by an opaque sibling, in which
4996                        //   case there is no need to paint.
4997                        // . Partially obscured by a sibling: need to start
4998                        //   painting from c.
4999                        // . Otherwise we aren't obscured and thus don't need to
5000                        //   start painting from parent.
5001                        if (c != this ) {
5002                            if (jc.isPaintingOrigin()) {
5003                                resetPC = true;
5004                            } else {
5005                                Component[] children = c.getComponents();
5006                                int i = 0;
5007                                for (; i < children.length; i++) {
5008                                    if (children[i] == child)
5009                                        break;
5010                                }
5011                                switch (jc.getObscuredState(i,
5012                                        paintImmediatelyClip.x,
5013                                        paintImmediatelyClip.y,
5014                                        paintImmediatelyClip.width,
5015                                        paintImmediatelyClip.height)) {
5016                                case NOT_OBSCURED:
5017                                    resetPC = false;
5018                                    break;
5019                                case COMPLETELY_OBSCURED:
5020                                    recycleRectangle(paintImmediatelyClip);
5021                                    return;
5022                                default:
5023                                    resetPC = true;
5024                                    break;
5025                                }
5026                            }
5027                        } else {
5028                            resetPC = false;
5029                        }
5030
5031                        if (resetPC) {
5032                            // Get rid of any buffer since we draw from here and
5033                            // we might draw something larger
5034                            paintingComponent = jc;
5035                            pIndex = pCount;
5036                            offsetX = offsetY = 0;
5037                            hasBuffer = false;
5038                        }
5039                    }
5040                    pCount++;
5041
5042                    // look to see if the parent (and therefor this component)
5043                    // is double buffered
5044                    if (repaintManager.isDoubleBufferingEnabled() && jc != null
5045                            && jc.isDoubleBuffered()) {
5046                        hasBuffer = true;
5047                        bufferedComponent = jc;
5048                    }
5049
5050                    // if we aren't on top, include the parent's clip 
5051                    if (!ontop) {
5052                        int bx = c.getX();
5053                        int by = c.getY();
5054                        tmpWidth = c.getWidth();
5055                        tmpHeight = c.getHeight();
5056                        SwingUtilities.computeIntersection(tmpX, tmpY,
5057                                tmpWidth, tmpHeight, paintImmediatelyClip);
5058                        paintImmediatelyClip.x += bx;
5059                        paintImmediatelyClip.y += by;
5060                        offsetX += bx;
5061                        offsetY += by;
5062                    }
5063                }
5064
5065                // If the clip width or height is negative, don't bother painting
5066                if (c == null || c.getPeer() == null
5067                        || paintImmediatelyClip.width <= 0
5068                        || paintImmediatelyClip.height <= 0) {
5069                    recycleRectangle(paintImmediatelyClip);
5070                    return;
5071                }
5072
5073                paintingComponent.setFlag(IS_REPAINTING, true);
5074
5075                paintImmediatelyClip.x -= offsetX;
5076                paintImmediatelyClip.y -= offsetY;
5077
5078                // Notify the Components that are going to be painted of the
5079                // child component to paint to.
5080                if (paintingComponent != this ) {
5081                    Component comp;
5082                    int i = pIndex;
5083                    for (; i > 0; i--) {
5084                        comp = path.get(i);
5085                        if (comp instanceof  JComponent) {
5086                            ((JComponent) comp).setPaintingChild(path
5087                                    .get(i - 1));
5088                        }
5089                    }
5090                }
5091
5092                try {
5093                    g = safelyGetGraphics(paintingComponent, c);
5094                    try {
5095                        if (hasBuffer) {
5096                            RepaintManager rm = RepaintManager
5097                                    .currentManager(bufferedComponent);
5098                            rm.beginPaint();
5099                            try {
5100                                rm.paint(paintingComponent, bufferedComponent,
5101                                        g, paintImmediatelyClip.x,
5102                                        paintImmediatelyClip.y,
5103                                        paintImmediatelyClip.width,
5104                                        paintImmediatelyClip.height);
5105                            } finally {
5106                                rm.endPaint();
5107                            }
5108                        } else {
5109                            g.setClip(paintImmediatelyClip.x,
5110                                    paintImmediatelyClip.y,
5111                                    paintImmediatelyClip.width,
5112                                    paintImmediatelyClip.height);
5113                            paintingComponent.paint(g);
5114                        }
5115                    } finally {
5116                        g.dispose();
5117                    }
5118                } finally {
5119                    // Reset the painting child for the parent components.
5120                    if (paintingComponent != this ) {
5121                        Component comp;
5122                        int i = pIndex;
5123                        for (; i > 0; i--) {
5124                            comp = path.get(i);
5125                            if (comp instanceof  JComponent) {
5126                                ((JComponent) comp).setPaintingChild(null);
5127                            }
5128                        }
5129                    }
5130                    paintingComponent.setFlag(IS_REPAINTING, false);
5131                }
5132                recycleRectangle(paintImmediatelyClip);
5133            }
5134
5135            /**
5136             * Paints to the specified graphics.  This does not set the clip and it
5137             * does not adjust the Graphics in anyway, callers must do that first.
5138             * This method is package-private for RepaintManager.PaintManager and
5139             * its subclasses to call, it is NOT intended for general use outside
5140             * of that.
5141             */
5142            void paintToOffscreen(Graphics g, int x, int y, int w, int h,
5143                    int maxX, int maxY) {
5144                try {
5145                    setFlag(ANCESTOR_USING_BUFFER, true);
5146                    if ((y + h) < maxY || (x + w) < maxX) {
5147                        setFlag(IS_PAINTING_TILE, true);
5148                    }
5149                    if (getFlag(IS_REPAINTING)) {
5150                        // Called from paintImmediately (RepaintManager) to fill 
5151                        // repaint request
5152                        paint(g);
5153                    } else {
5154                        // Called from paint() (AWT) to repair damage
5155                        if (!rectangleIsObscured(x, y, w, h)) {
5156                            paintComponent(g);
5157                            paintBorder(g);
5158                        }
5159                        paintChildren(g);
5160                    }
5161                } finally {
5162                    setFlag(ANCESTOR_USING_BUFFER, false);
5163                    setFlag(IS_PAINTING_TILE, false);
5164                }
5165            }
5166
5167            /**
5168             * Returns whether or not the region of the specified component is
5169             * obscured by a sibling.
5170             *
5171             * @return NOT_OBSCURED if non of the siblings above the Component obscure
5172             *         it, COMPLETELY_OBSCURED if one of the siblings completely
5173             *         obscures the Component or PARTIALLY_OBSCURED if the Comonent is
5174             *         only partially obscured.
5175             */
5176            private int getObscuredState(int compIndex, int x, int y,
5177                    int width, int height) {
5178                int retValue = NOT_OBSCURED;
5179                Rectangle tmpRect = fetchRectangle();
5180
5181                for (int i = compIndex - 1; i >= 0; i--) {
5182                    Component sibling = getComponent(i);
5183                    if (!sibling.isVisible()) {
5184                        continue;
5185                    }
5186                    Rectangle siblingRect;
5187                    boolean opaque;
5188                    if (sibling instanceof  JComponent) {
5189                        opaque = ((JComponent) sibling).isOpaque();
5190                        if (!opaque) {
5191                            if (retValue == PARTIALLY_OBSCURED) {
5192                                continue;
5193                            }
5194                        }
5195                    } else {
5196                        opaque = true;
5197                    }
5198                    siblingRect = sibling.getBounds(tmpRect);
5199                    if (opaque
5200                            && x >= siblingRect.x
5201                            && (x + width) <= (siblingRect.x + siblingRect.width)
5202                            && y >= siblingRect.y
5203                            && (y + height) <= (siblingRect.y + siblingRect.height)) {
5204                        recycleRectangle(tmpRect);
5205                        return COMPLETELY_OBSCURED;
5206                    } else if (retValue == NOT_OBSCURED
5207                            && !((x + width <= siblingRect.x)
5208                                    || (y + height <= siblingRect.y)
5209                                    || (x >= siblingRect.x + siblingRect.width) || (y >= siblingRect.y
5210                                    + siblingRect.height))) {
5211                        retValue = PARTIALLY_OBSCURED;
5212                    }
5213                }
5214                recycleRectangle(tmpRect);
5215                return retValue;
5216            }
5217
5218            /**
5219             * Returns true, which implies that before checking if a child should
5220             * be painted it is first check that the child is not obscured by another 
5221             * sibling. This is only checked if <code>isOptimizedDrawingEnabled</code>
5222             * returns false.
5223             *
5224             * @return always returns true
5225             */
5226            boolean checkIfChildObscuredBySibling() {
5227                return true;
5228            }
5229
5230            private void setFlag(int aFlag, boolean aValue) {
5231                if (aValue) {
5232                    flags |= (1 << aFlag);
5233                } else {
5234                    flags &= ~(1 << aFlag);
5235                }
5236            }
5237
5238            private boolean getFlag(int aFlag) {
5239                int mask = (1 << aFlag);
5240                return ((flags & mask) == mask);
5241            }
5242
5243            // These functions must be static so that they can be called from
5244            // subclasses inside the package, but whose inheritance hierarhcy includes
5245            // classes outside of the package below JComponent (e.g., JTextArea).
5246            static void setWriteObjCounter(JComponent comp, byte count) {
5247                comp.flags = (comp.flags & ~(0xFF << WRITE_OBJ_COUNTER_FIRST))
5248                        | (count << WRITE_OBJ_COUNTER_FIRST);
5249            }
5250
5251            static byte getWriteObjCounter(JComponent comp) {
5252                return (byte) ((comp.flags >> WRITE_OBJ_COUNTER_FIRST) & 0xFF);
5253            }
5254
5255            /** Buffering **/
5256
5257            /**
5258             *  Sets whether this component should use a buffer to paint.
5259             *  If set to true, all the drawing from this component will be done
5260             *  in an offscreen painting buffer. The offscreen painting buffer will
5261             *  the be copied onto the screen.
5262             *  If a <code>Component</code> is buffered and one of its ancestor
5263             *  is also buffered, the ancestor buffer will be used.
5264             *
5265             *  @param aFlag if true, set this component to be double buffered
5266             */
5267            public void setDoubleBuffered(boolean aFlag) {
5268                setFlag(IS_DOUBLE_BUFFERED, aFlag);
5269            }
5270
5271            /**
5272             * Returns whether this component should use a buffer to paint.
5273             *
5274             * @return true if this component is double buffered, otherwise false
5275             */
5276            public boolean isDoubleBuffered() {
5277                return getFlag(IS_DOUBLE_BUFFERED);
5278            }
5279
5280            /**
5281             * Returns the <code>JRootPane</code> ancestor for this component.
5282             *
5283             * @return the <code>JRootPane</code> that contains this component,
5284             *		or <code>null</code> if no <code>JRootPane</code> is found
5285             */
5286            public JRootPane getRootPane() {
5287                return SwingUtilities.getRootPane(this );
5288            }
5289
5290            /** Serialization **/
5291
5292            /**
5293             * This is called from Component by way of reflection. Do NOT change
5294             * the name unless you change the code in Component as well.
5295             */
5296            void compWriteObjectNotify() {
5297                byte count = JComponent.getWriteObjCounter(this );
5298                JComponent.setWriteObjCounter(this , (byte) (count + 1));
5299                if (count != 0) {
5300                    return;
5301                }
5302
5303                uninstallUIAndProperties();
5304
5305                /* JTableHeader is in a separate package, which prevents it from
5306                 * being able to override this package-private method the way the
5307                 * other components can.  We don't want to make this method protected
5308                 * because it would introduce public-api for a less-than-desirable
5309                 * serialization scheme, so we compromise with this 'instanceof' hack
5310                 * for now.
5311                 */
5312                if (getToolTipText() != null
5313                        || this  instanceof  javax.swing.table.JTableHeader) {
5314                    ToolTipManager.sharedInstance().unregisterComponent(
5315                            JComponent.this );
5316                }
5317            }
5318
5319            /**
5320             * This object is the <code>ObjectInputStream</code> callback
5321             * that's called after a complete graph of objects (including at least
5322             * one <code>JComponent</code>) has been read.
5323             *  It sets the UI property of each Swing component 
5324             * that was read to the current default with <code>updateUI</code>.  
5325             * <p> 
5326             * As each  component is read in we keep track of the current set of 
5327             * root components here, in the roots vector.  Note that there's only one 
5328             * <code>ReadObjectCallback</code> per <code>ObjectInputStream</code>,
5329             * they're stored in the static <code>readObjectCallbacks</code>
5330             * hashtable.
5331             * 
5332             * @see java.io.ObjectInputStream#registerValidation
5333             * @see SwingUtilities#updateComponentTreeUI
5334             */
5335            private class ReadObjectCallback implements  ObjectInputValidation {
5336                private final Vector roots = new Vector(1);
5337                private final ObjectInputStream inputStream;
5338
5339                ReadObjectCallback(ObjectInputStream s) throws Exception {
5340                    inputStream = s;
5341                    s.registerValidation(this , 0);
5342                }
5343
5344                /**
5345                 * This is the method that's called after the entire graph
5346                 * of objects has been read in.  It initializes
5347                 * the UI property of all of the copmonents with
5348                 * <code>SwingUtilities.updateComponentTreeUI</code>.
5349                 */
5350                public void validateObject() throws InvalidObjectException {
5351                    try {
5352                        for (int i = 0; i < roots.size(); i++) {
5353                            JComponent root = (JComponent) (roots.elementAt(i));
5354                            SwingUtilities.updateComponentTreeUI(root);
5355                        }
5356                    } finally {
5357                        readObjectCallbacks.remove(inputStream);
5358                    }
5359                }
5360
5361                /**
5362                 * If <code>c</code> isn't a descendant of a component we've already
5363                 * seen, then add it to the roots <code>Vector</code>.
5364                 *
5365                 * @param c the <code>JComponent</code> to add
5366                 */
5367                private void registerComponent(JComponent c) {
5368                    /* If the Component c is a descendant of one of the
5369                     * existing roots (or it IS an existing root), we're done.
5370                     */
5371                    for (int i = 0; i < roots.size(); i++) {
5372                        JComponent root = (JComponent) roots.elementAt(i);
5373                        for (Component p = c; p != null; p = p.getParent()) {
5374                            if (p == root) {
5375                                return;
5376                            }
5377                        }
5378                    }
5379
5380                    /* Otherwise: if Component c is an ancestor of any of the 
5381                     * existing roots then remove them and add c (the "new root") 
5382                     * to the roots vector.
5383                     */
5384                    for (int i = 0; i < roots.size(); i++) {
5385                        JComponent root = (JComponent) roots.elementAt(i);
5386                        for (Component p = root.getParent(); p != null; p = p
5387                                .getParent()) {
5388                            if (p == c) {
5389                                roots.removeElementAt(i--); // !!
5390                                break;
5391                            }
5392                        }
5393                    }
5394
5395                    roots.addElement(c);
5396                }
5397            }
5398
5399            /**
5400             * We use the <code>ObjectInputStream</code> "registerValidation"
5401             * callback to update the UI for the entire tree of components
5402             * after they've all been read in.
5403             * 
5404             * @param s  the <code>ObjectInputStream</code> from which to read
5405             */
5406            private void readObject(ObjectInputStream s) throws IOException,
5407                    ClassNotFoundException {
5408                s.defaultReadObject();
5409
5410                /* If there's no ReadObjectCallback for this stream yet, that is, if
5411                 * this is the first call to JComponent.readObject() for this
5412                 * graph of objects, then create a callback and stash it
5413                 * in the readObjectCallbacks table.  Note that the ReadObjectCallback
5414                 * constructor takes care of calling s.registerValidation().
5415                 */
5416                ReadObjectCallback cb = (ReadObjectCallback) (readObjectCallbacks
5417                        .get(s));
5418                if (cb == null) {
5419                    try {
5420                        readObjectCallbacks.put(s, cb = new ReadObjectCallback(
5421                                s));
5422                    } catch (Exception e) {
5423                        throw new IOException(e.toString());
5424                    }
5425                }
5426                cb.registerComponent(this );
5427
5428                // Read back the client properties.
5429                int cpCount = s.readInt();
5430                if (cpCount > 0) {
5431                    clientProperties = new ArrayTable();
5432                    for (int counter = 0; counter < cpCount; counter++) {
5433                        clientProperties.put(s.readObject(), s.readObject());
5434                    }
5435                }
5436                if (getToolTipText() != null) {
5437                    ToolTipManager.sharedInstance().registerComponent(this );
5438                }
5439                setWriteObjCounter(this , (byte) 0);
5440            }
5441
5442            /**
5443             * Before writing a <code>JComponent</code> to an
5444             * <code>ObjectOutputStream</code> we temporarily uninstall its UI.
5445             * This is tricky to do because we want to uninstall
5446             * the UI before any of the <code>JComponent</code>'s children
5447             * (or its <code>LayoutManager</code> etc.) are written,
5448             * and we don't want to restore the UI until the most derived
5449             * <code>JComponent</code> subclass has been been stored.  
5450             *
5451             * @param s the <code>ObjectOutputStream</code> in which to write
5452             */
5453            private void writeObject(ObjectOutputStream s) throws IOException {
5454                s.defaultWriteObject();
5455                if (getUIClassID().equals(uiClassID)) {
5456                    byte count = JComponent.getWriteObjCounter(this );
5457                    JComponent.setWriteObjCounter(this , --count);
5458                    if (count == 0 && ui != null) {
5459                        ui.installUI(this );
5460                    }
5461                }
5462                ArrayTable.writeArrayTable(s, clientProperties);
5463            }
5464
5465            /**
5466             * Returns a string representation of this <code>JComponent</code>.
5467             * This method 
5468             * is intended to be used only for debugging purposes, and the 
5469             * content and format of the returned string may vary between      
5470             * implementations. The returned string may be empty but may not 
5471             * be <code>null</code>.
5472             * 
5473             * @return  a string representation of this <code>JComponent</code>
5474             */
5475            protected String paramString() {
5476                String preferredSizeString = (isPreferredSizeSet() ? getPreferredSize()
5477                        .toString()
5478                        : "");
5479                String minimumSizeString = (isMinimumSizeSet() ? getMinimumSize()
5480                        .toString()
5481                        : "");
5482                String maximumSizeString = (isMaximumSizeSet() ? getMaximumSize()
5483                        .toString()
5484                        : "");
5485                String borderString = (border == null ? ""
5486                        : (border == this  ? "this" : border.toString()));
5487
5488                return super .paramString() + ",alignmentX=" + alignmentX
5489                        + ",alignmentY=" + alignmentY + ",border="
5490                        + borderString + ",flags="
5491                        + flags
5492                        + // should beef this up a bit
5493                        ",maximumSize=" + maximumSizeString + ",minimumSize="
5494                        + minimumSizeString + ",preferredSize="
5495                        + preferredSizeString;
5496            }
5497
5498        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.