Home » openjdk-7 » javax » swing » [javadoc | source]

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

Home » openjdk-7 » javax » swing » [javadoc | source]