Save This Page
Home » openjdk-7 » javax » swing » [javadoc | source]
    1   /*
    2    * Copyright 1997-2008 Sun Microsystems, Inc.  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.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any 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 readObjectCallbacks = new Hashtable(1);
  196   
  197       /**
  198        * Keys to use for forward focus traversal when the JComponent is
  199        * managing focus.
  200        */
  201       private static Set<KeyStroke> managingFocusForwardTraversalKeys;
  202   
  203       /**
  204        * Keys to use for backward focus traversal when the JComponent is
  205        * managing focus.
  206        */
  207       private static Set<KeyStroke> managingFocusBackwardTraversalKeys;
  208   
  209       // Following are the possible return values from getObscuredState.
  210       private static final int NOT_OBSCURED = 0;
  211       private static final int PARTIALLY_OBSCURED = 1;
  212       private static final int COMPLETELY_OBSCURED = 2;
  213   
  214       /**
  215        * Set to true when DebugGraphics has been loaded.
  216        */
  217       static boolean DEBUG_GRAPHICS_LOADED;
  218   
  219       /**
  220        * Key used to look up a value from the AppContext to determine the
  221        * JComponent the InputVerifier is running for. That is, if
  222        * AppContext.get(INPUT_VERIFIER_SOURCE_KEY) returns non-null, it
  223        * indicates the EDT is calling into the InputVerifier from the
  224        * returned component.
  225        */
  226       private static final Object INPUT_VERIFIER_SOURCE_KEY =
  227               new StringBuilder("InputVerifierSourceKey");
  228   
  229       /* The following fields support set methods for the corresponding
  230        * java.awt.Component properties.
  231        */
  232       private boolean isAlignmentXSet;
  233       private float alignmentX;
  234       private boolean isAlignmentYSet;
  235       private float alignmentY;
  236   
  237       /**
  238        * Backing store for JComponent properties and listeners
  239        */
  240   
  241       /** The look and feel delegate for this component. */
  242       protected transient ComponentUI ui;
  243       /** A list of event listeners for this component. */
  244       protected EventListenerList listenerList = new EventListenerList();
  245   
  246       private transient ArrayTable clientProperties;
  247       private VetoableChangeSupport vetoableChangeSupport;
  248       /**
  249        * Whether or not autoscroll has been enabled.
  250        */
  251       private boolean autoscrolls;
  252       private Border border;
  253       private int flags;
  254   
  255       /* Input verifier for this component */
  256       private InputVerifier inputVerifier = null;
  257   
  258       private boolean verifyInputWhenFocusTarget = true;
  259   
  260       /**
  261        * Set in <code>_paintImmediately</code>.
  262        * Will indicate the child that initiated the painting operation.
  263        * If <code>paintingChild</code> is opaque, no need to paint
  264        * any child components after <code>paintingChild</code>.
  265        * Test used in <code>paintChildren</code>.
  266        */
  267       transient Component         paintingChild;
  268   
  269       /**
  270        * Constant used for <code>registerKeyboardAction</code> that
  271        * means that the command should be invoked when
  272        * the component has the focus.
  273        */
  274       public static final int WHEN_FOCUSED = 0;
  275   
  276       /**
  277        * Constant used for <code>registerKeyboardAction</code> that
  278        * means that the command should be invoked when the receiving
  279        * component is an ancestor of the focused component or is
  280        * itself the focused component.
  281        */
  282       public static final int WHEN_ANCESTOR_OF_FOCUSED_COMPONENT = 1;
  283   
  284       /**
  285        * Constant used for <code>registerKeyboardAction</code> that
  286        * means that the command should be invoked when
  287        * the receiving component is in the window that has the focus
  288        * or is itself the focused component.
  289        */
  290       public static final int WHEN_IN_FOCUSED_WINDOW = 2;
  291   
  292       /**
  293        * Constant used by some of the APIs to mean that no condition is defined.
  294        */
  295       public static final int UNDEFINED_CONDITION = -1;
  296   
  297       /**
  298        * The key used by <code>JComponent</code> to access keyboard bindings.
  299        */
  300       private static final String KEYBOARD_BINDINGS_KEY = "_KeyboardBindings";
  301   
  302       /**
  303        * An array of <code>KeyStroke</code>s used for
  304        * <code>WHEN_IN_FOCUSED_WINDOW</code> are stashed
  305        * in the client properties under this string.
  306        */
  307       private static final String WHEN_IN_FOCUSED_WINDOW_BINDINGS = "_WhenInFocusedWindow";
  308   
  309       /**
  310        * The comment to display when the cursor is over the component,
  311        * also known as a "value tip", "flyover help", or "flyover label".
  312        */
  313       public static final String TOOL_TIP_TEXT_KEY = "ToolTipText";
  314   
  315       private static final String NEXT_FOCUS = "nextFocus";
  316   
  317       /**
  318        * <code>JPopupMenu</code> assigned to this component
  319        * and all of its childrens
  320        */
  321       private JPopupMenu popupMenu;
  322   
  323       /** Private flags **/
  324       private static final int IS_DOUBLE_BUFFERED                       =  0;
  325       private static final int ANCESTOR_USING_BUFFER                    =  1;
  326       private static final int IS_PAINTING_TILE                         =  2;
  327       private static final int IS_OPAQUE                                =  3;
  328       private static final int KEY_EVENTS_ENABLED                       =  4;
  329       private static final int FOCUS_INPUTMAP_CREATED                   =  5;
  330       private static final int ANCESTOR_INPUTMAP_CREATED                =  6;
  331       private static final int WIF_INPUTMAP_CREATED                     =  7;
  332       private static final int ACTIONMAP_CREATED                        =  8;
  333       private static final int CREATED_DOUBLE_BUFFER                    =  9;
  334       // bit 10 is free
  335       private static final int IS_PRINTING                              = 11;
  336       private static final int IS_PRINTING_ALL                          = 12;
  337       private static final int IS_REPAINTING                            = 13;
  338       /** Bits 14-21 are used to handle nested writeObject calls. **/
  339       private static final int WRITE_OBJ_COUNTER_FIRST                  = 14;
  340       private static final int RESERVED_1                               = 15;
  341       private static final int RESERVED_2                               = 16;
  342       private static final int RESERVED_3                               = 17;
  343       private static final int RESERVED_4                               = 18;
  344       private static final int RESERVED_5                               = 19;
  345       private static final int RESERVED_6                               = 20;
  346       private static final int WRITE_OBJ_COUNTER_LAST                   = 21;
  347   
  348       private static final int REQUEST_FOCUS_DISABLED                   = 22;
  349       private static final int INHERITS_POPUP_MENU                      = 23;
  350       private static final int OPAQUE_SET                               = 24;
  351       private static final int AUTOSCROLLS_SET                          = 25;
  352       private static final int FOCUS_TRAVERSAL_KEYS_FORWARD_SET         = 26;
  353       private static final int FOCUS_TRAVERSAL_KEYS_BACKWARD_SET        = 27;
  354       private static final int REVALIDATE_RUNNABLE_SCHEDULED            = 28;
  355   
  356       /**
  357        * Temporary rectangles.
  358        */
  359       private static java.util.List tempRectangles = new java.util.ArrayList(11);
  360   
  361       /** Used for <code>WHEN_FOCUSED</code> bindings. */
  362       private InputMap focusInputMap;
  363       /** Used for <code>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT</code> bindings. */
  364       private InputMap ancestorInputMap;
  365       /** Used for <code>WHEN_IN_FOCUSED_KEY</code> bindings. */
  366       private ComponentInputMap windowInputMap;
  367   
  368       /** ActionMap. */
  369       private ActionMap actionMap;
  370   
  371       /** Key used to store the default locale in an AppContext **/
  372       private static final String defaultLocale = "JComponent.defaultLocale";
  373   
  374       private static Component componentObtainingGraphicsFrom;
  375       private static Object componentObtainingGraphicsFromLock = new
  376               StringBuilder("componentObtainingGraphicsFrom");
  377   
  378       /**
  379        * AA text hints.
  380        */
  381       transient private Object aaTextInfo;
  382   
  383       static Graphics safelyGetGraphics(Component c) {
  384           return safelyGetGraphics(c, SwingUtilities.getRoot(c));
  385       }
  386   
  387       static Graphics safelyGetGraphics(Component c, Component root) {
  388           synchronized(componentObtainingGraphicsFromLock) {
  389               componentObtainingGraphicsFrom = root;
  390               Graphics g = c.getGraphics();
  391               componentObtainingGraphicsFrom = null;
  392               return g;
  393           }
  394       }
  395   
  396       static void getGraphicsInvoked(Component root) {
  397           if (!JComponent.isComponentObtainingGraphicsFrom(root)) {
  398               JRootPane rootPane = ((RootPaneContainer)root).getRootPane();
  399               if (rootPane != null) {
  400                   rootPane.disableTrueDoubleBuffering();
  401               }
  402           }
  403       }
  404   
  405   
  406       /**
  407        * Returns true if {@code c} is the component the graphics is being
  408        * requested of. This is intended for use when getGraphics is invoked.
  409        */
  410       private static boolean isComponentObtainingGraphicsFrom(Component c) {
  411           synchronized(componentObtainingGraphicsFromLock) {
  412               return (componentObtainingGraphicsFrom == c);
  413           }
  414       }
  415   
  416       /**
  417        * Returns the Set of <code>KeyStroke</code>s to use if the component
  418        * is managing focus for forward focus traversal.
  419        */
  420       static Set<KeyStroke> getManagingFocusForwardTraversalKeys() {
  421           synchronized(JComponent.class) {
  422               if (managingFocusForwardTraversalKeys == null) {
  423                   managingFocusForwardTraversalKeys = new HashSet<KeyStroke>(1);
  424                   managingFocusForwardTraversalKeys.add(
  425                       KeyStroke.getKeyStroke(KeyEvent.VK_TAB,
  426                                              InputEvent.CTRL_MASK));
  427               }
  428           }
  429           return managingFocusForwardTraversalKeys;
  430       }
  431   
  432       /**
  433        * Returns the Set of <code>KeyStroke</code>s to use if the component
  434        * is managing focus for backward focus traversal.
  435        */
  436       static Set<KeyStroke> getManagingFocusBackwardTraversalKeys() {
  437           synchronized(JComponent.class) {
  438               if (managingFocusBackwardTraversalKeys == null) {
  439                   managingFocusBackwardTraversalKeys = new HashSet<KeyStroke>(1);
  440                   managingFocusBackwardTraversalKeys.add(
  441                       KeyStroke.getKeyStroke(KeyEvent.VK_TAB,
  442                                              InputEvent.SHIFT_MASK |
  443                                              InputEvent.CTRL_MASK));
  444               }
  445           }
  446           return managingFocusBackwardTraversalKeys;
  447       }
  448   
  449       private static Rectangle fetchRectangle() {
  450           synchronized(tempRectangles) {
  451               Rectangle rect;
  452               int size = tempRectangles.size();
  453               if (size > 0) {
  454                   rect = (Rectangle)tempRectangles.remove(size - 1);
  455               }
  456               else {
  457                   rect = new Rectangle(0, 0, 0, 0);
  458               }
  459               return rect;
  460           }
  461       }
  462   
  463       private static void recycleRectangle(Rectangle rect) {
  464           synchronized(tempRectangles) {
  465               tempRectangles.add(rect);
  466           }
  467       }
  468   
  469       /**
  470        * Sets whether or not <code>getComponentPopupMenu</code> should delegate
  471        * to the parent if this component does not have a <code>JPopupMenu</code>
  472        * assigned to it.
  473        * <p>
  474        * The default value for this is false, but some <code>JComponent</code>
  475        * subclasses that are implemented as a number of <code>JComponent</code>s
  476        * may set this to true.
  477        * <p>
  478        * This is a bound property.
  479        *
  480        * @param value whether or not the JPopupMenu is inherited
  481        * @see #setComponentPopupMenu
  482        * @beaninfo
  483        *        bound: true
  484        *  description: Whether or not the JPopupMenu is inherited
  485        * @since 1.5
  486        */
  487       public void setInheritsPopupMenu(boolean value) {
  488           boolean oldValue = getFlag(INHERITS_POPUP_MENU);
  489           setFlag(INHERITS_POPUP_MENU, value);
  490           firePropertyChange("inheritsPopupMenu", oldValue, value);
  491       }
  492   
  493       /**
  494        * Returns true if the JPopupMenu should be inherited from the parent.
  495        *
  496        * @see #setComponentPopupMenu
  497        * @since 1.5
  498        */
  499       public boolean getInheritsPopupMenu() {
  500           return getFlag(INHERITS_POPUP_MENU);
  501       }
  502   
  503       /**
  504        * Sets the <code>JPopupMenu</code> for this <code>JComponent</code>.
  505        * The UI is responsible for registering bindings and adding the necessary
  506        * listeners such that the <code>JPopupMenu</code> will be shown at
  507        * the appropriate time. When the <code>JPopupMenu</code> is shown
  508        * depends upon the look and feel: some may show it on a mouse event,
  509        * some may enable a key binding.
  510        * <p>
  511        * If <code>popup</code> is null, and <code>getInheritsPopupMenu</code>
  512        * returns true, then <code>getComponentPopupMenu</code> will be delegated
  513        * to the parent. This provides for a way to make all child components
  514        * inherit the popupmenu of the parent.
  515        * <p>
  516        * This is a bound property.
  517        *
  518        * @param popup - the popup that will be assigned to this component
  519        *                may be null
  520        * @see #getComponentPopupMenu
  521        * @beaninfo
  522        *        bound: true
  523        *    preferred: true
  524        *  description: Popup to show
  525        * @since 1.5
  526        */
  527       public void setComponentPopupMenu(JPopupMenu popup) {
  528           if(popup != null) {
  529               enableEvents(AWTEvent.MOUSE_EVENT_MASK);
  530           }
  531           JPopupMenu oldPopup = this.popupMenu;
  532           this.popupMenu = popup;
  533           firePropertyChange("componentPopupMenu", oldPopup, popup);
  534       }
  535   
  536       /**
  537        * Returns <code>JPopupMenu</code> that assigned for this component.
  538        * If this component does not have a <code>JPopupMenu</code> assigned
  539        * to it and <code>getInheritsPopupMenu</code> is true, this
  540        * will return <code>getParent().getComponentPopupMenu()</code> (assuming
  541        * the parent is valid.)
  542        *
  543        * @return <code>JPopupMenu</code> assigned for this component
  544        *         or <code>null</code> if no popup assigned
  545        * @see #setComponentPopupMenu
  546        * @since 1.5
  547        */
  548       public JPopupMenu getComponentPopupMenu() {
  549   
  550           if(!getInheritsPopupMenu()) {
  551               return popupMenu;
  552           }
  553   
  554           if(popupMenu == null) {
  555               // Search parents for its popup
  556               Container parent = getParent();
  557               while (parent != null) {
  558                   if(parent instanceof JComponent) {
  559                       return ((JComponent)parent).getComponentPopupMenu();
  560                   }
  561                   if(parent instanceof Window ||
  562                      parent instanceof Applet) {
  563                       // Reached toplevel, break and return null
  564                       break;
  565                   }
  566                   parent = parent.getParent();
  567               }
  568               return null;
  569           }
  570   
  571           return popupMenu;
  572       }
  573   
  574       /**
  575        * Default <code>JComponent</code> constructor.  This constructor does
  576        * very little initialization beyond calling the <code>Container</code>
  577        * constructor.  For example, the initial layout manager is
  578        * <code>null</code>. It does, however, set the component's locale
  579        * property to the value returned by
  580        * <code>JComponent.getDefaultLocale</code>.
  581        *
  582        * @see #getDefaultLocale
  583        */
  584       public JComponent() {
  585           super();
  586           // We enable key events on all JComponents so that accessibility
  587           // bindings will work everywhere. This is a partial fix to BugID
  588           // 4282211.
  589           enableEvents(AWTEvent.KEY_EVENT_MASK);
  590           if (isManagingFocus()) {
  591               LookAndFeel.installProperty(this,
  592                                           "focusTraversalKeysForward",
  593                                     getManagingFocusForwardTraversalKeys());
  594               LookAndFeel.installProperty(this,
  595                                           "focusTraversalKeysBackward",
  596                                     getManagingFocusBackwardTraversalKeys());
  597           }
  598   
  599           super.setLocale( JComponent.getDefaultLocale() );
  600       }
  601   
  602   
  603       /**
  604        * Resets the UI property to a value from the current look and feel.
  605        * <code>JComponent</code> subclasses must override this method
  606        * like this:
  607        * <pre>
  608        *   public void updateUI() {
  609        *      setUI((SliderUI)UIManager.getUI(this);
  610        *   }
  611        *  </pre>
  612        *
  613        * @see #setUI
  614        * @see UIManager#getLookAndFeel
  615        * @see UIManager#getUI
  616        */
  617       public void updateUI() {}
  618   
  619   
  620       /**
  621        * Sets the look and feel delegate for this component.
  622        * <code>JComponent</code> subclasses generally override this method
  623        * to narrow the argument type. For example, in <code>JSlider</code>:
  624        * <pre>
  625        * public void setUI(SliderUI newUI) {
  626        *     super.setUI(newUI);
  627        * }
  628        *  </pre>
  629        * <p>
  630        * Additionally <code>JComponent</code> subclasses must provide a
  631        * <code>getUI</code> method that returns the correct type.  For example:
  632        * <pre>
  633        * public SliderUI getUI() {
  634        *     return (SliderUI)ui;
  635        * }
  636        * </pre>
  637        *
  638        * @param newUI the new UI delegate
  639        * @see #updateUI
  640        * @see UIManager#getLookAndFeel
  641        * @see UIManager#getUI
  642        * @beaninfo
  643        *        bound: true
  644        *       hidden: true
  645        *    attribute: visualUpdate true
  646        *  description: The component's look and feel delegate.
  647        */
  648       protected void setUI(ComponentUI newUI) {
  649           /* We do not check that the UI instance is different
  650            * before allowing the switch in order to enable the
  651            * same UI instance *with different default settings*
  652            * to be installed.
  653            */
  654   
  655           uninstallUIAndProperties();
  656   
  657           // aaText shouldn't persist between look and feels, reset it.
  658           aaTextInfo =
  659               UIManager.getDefaults().get(SwingUtilities2.AA_TEXT_PROPERTY_KEY);
  660           ComponentUI oldUI = ui;
  661           ui = newUI;
  662           if (ui != null) {
  663               ui.installUI(this);
  664           }
  665   
  666           firePropertyChange("UI", oldUI, newUI);
  667           revalidate();
  668           repaint();
  669       }
  670   
  671       /**
  672        * Uninstalls the UI, if any, and any client properties designated
  673        * as being specific to the installed UI - instances of
  674        * {@code UIClientPropertyKey}.
  675        */
  676       private void uninstallUIAndProperties() {
  677           if (ui != null) {
  678               ui.uninstallUI(this);
  679               //clean UIClientPropertyKeys from client properties
  680               if (clientProperties != null) {
  681                   synchronized(clientProperties) {
  682                       Object[] clientPropertyKeys =
  683                           clientProperties.getKeys(null);
  684                       if (clientPropertyKeys != null) {
  685                           for (Object key : clientPropertyKeys) {
  686                               if (key instanceof UIClientPropertyKey) {
  687                                   putClientProperty(key, null);
  688                               }
  689                           }
  690                       }
  691                   }
  692               }
  693           }
  694       }
  695   
  696       /**
  697        * Returns the <code>UIDefaults</code> key used to
  698        * look up the name of the <code>swing.plaf.ComponentUI</code>
  699        * class that defines the look and feel
  700        * for this component.  Most applications will never need to
  701        * call this method.  Subclasses of <code>JComponent</code> that support
  702        * pluggable look and feel should override this method to
  703        * return a <code>UIDefaults</code> key that maps to the
  704        * <code>ComponentUI</code> subclass that defines their look and feel.
  705        *
  706        * @return the <code>UIDefaults</code> key for a
  707        *          <code>ComponentUI</code> subclass
  708        * @see UIDefaults#getUI
  709        * @beaninfo
  710        *      expert: true
  711        * description: UIClassID
  712        */
  713       public String getUIClassID() {
  714           return uiClassID;
  715       }
  716   
  717   
  718       /**
  719        * Returns the graphics object used to paint this component.
  720        * If <code>DebugGraphics</code> is turned on we create a new
  721        * <code>DebugGraphics</code> object if necessary.
  722        * Otherwise we just configure the
  723        * specified graphics object's foreground and font.
  724        *
  725        * @param g the original <code>Graphics</code> object
  726        * @return a <code>Graphics</code> object configured for this component
  727        */
  728       protected Graphics getComponentGraphics(Graphics g) {
  729           Graphics componentGraphics = g;
  730           if (ui != null && DEBUG_GRAPHICS_LOADED) {
  731               if ((DebugGraphics.debugComponentCount() != 0) &&
  732                       (shouldDebugGraphics() != 0) &&
  733                       !(g instanceof DebugGraphics)) {
  734                   componentGraphics = new DebugGraphics(g,this);
  735               }
  736           }
  737           componentGraphics.setColor(getForeground());
  738           componentGraphics.setFont(getFont());
  739   
  740           return componentGraphics;
  741       }
  742   
  743   
  744       /**
  745        * Calls the UI delegate's paint method, if the UI delegate
  746        * is non-<code>null</code>.  We pass the delegate a copy of the
  747        * <code>Graphics</code> object to protect the rest of the
  748        * paint code from irrevocable changes
  749        * (for example, <code>Graphics.translate</code>).
  750        * <p>
  751        * If you override this in a subclass you should not make permanent
  752        * changes to the passed in <code>Graphics</code>. For example, you
  753        * should not alter the clip <code>Rectangle</code> or modify the
  754        * transform. If you need to do these operations you may find it
  755        * easier to create a new <code>Graphics</code> from the passed in
  756        * <code>Graphics</code> and manipulate it. Further, if you do not
  757        * invoker super's implementation you must honor the opaque property,
  758        * that is
  759        * if this component is opaque, you must completely fill in the background
  760        * in a non-opaque color. If you do not honor the opaque property you
  761        * will likely see visual artifacts.
  762        * <p>
  763        * The passed in <code>Graphics</code> object might
  764        * have a transform other than the identify transform
  765        * installed on it.  In this case, you might get
  766        * unexpected results if you cumulatively apply
  767        * another transform.
  768        *
  769        * @param g the <code>Graphics</code> object to protect
  770        * @see #paint
  771        * @see ComponentUI
  772        */
  773       protected void paintComponent(Graphics g) {
  774           if (ui != null) {
  775               Graphics scratchGraphics = (g == null) ? null : g.create();
  776               try {
  777                   ui.update(scratchGraphics, this);
  778               }
  779               finally {
  780                   scratchGraphics.dispose();
  781               }
  782           }
  783       }
  784   
  785       /**
  786        * Paints this component's children.
  787        * If <code>shouldUseBuffer</code> is true,
  788        * no component ancestor has a buffer and
  789        * the component children can use a buffer if they have one.
  790        * Otherwise, one ancestor has a buffer currently in use and children
  791        * should not use a buffer to paint.
  792        * @param g  the <code>Graphics</code> context in which to paint
  793        * @see #paint
  794        * @see java.awt.Container#paint
  795        */
  796       protected void paintChildren(Graphics g) {
  797           boolean isJComponent;
  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                   ((JComponent)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               for (; i >= 0 ; i--) {
  829                   Component comp = getComponent(i);
  830                   isJComponent = (comp instanceof JComponent);
  831                   if (comp != null &&
  832                       (isJComponent || isLightweightComponent(comp)) &&
  833                       (comp.isVisible() == true)) {
  834                       Rectangle cr;
  835   
  836                       cr = comp.getBounds(tmpRect);
  837   
  838                       boolean hitClip = g.hitClip(cr.x, cr.y, cr.width,
  839                                                   cr.height);
  840   
  841                       if (hitClip) {
  842                           if (checkSiblings && i > 0) {
  843                               int x = cr.x;
  844                               int y = cr.y;
  845                               int width = cr.width;
  846                               int height = cr.height;
  847                               SwingUtilities.computeIntersection
  848                                   (clipBounds.x, clipBounds.y,
  849                                    clipBounds.width, clipBounds.height, cr);
  850   
  851                               if(getObscuredState(i, cr.x, cr.y, cr.width,
  852                                             cr.height) == COMPLETELY_OBSCURED) {
  853                                   continue;
  854                               }
  855                               cr.x = x;
  856                               cr.y = y;
  857                               cr.width = width;
  858                               cr.height = height;
  859                           }
  860                           Graphics cg = sg.create(cr.x, cr.y, cr.width,
  861                                                   cr.height);
  862                           cg.setColor(comp.getForeground());
  863                           cg.setFont(comp.getFont());
  864                           boolean shouldSetFlagBack = false;
  865                           try {
  866                               if(isJComponent) {
  867                                   if(getFlag(ANCESTOR_USING_BUFFER)) {
  868                                       ((JComponent)comp).setFlag(
  869                                                    ANCESTOR_USING_BUFFER,true);
  870                                       shouldSetFlagBack = true;
  871                                   }
  872                                   if(getFlag(IS_PAINTING_TILE)) {
  873                                       ((JComponent)comp).setFlag(
  874                                                    IS_PAINTING_TILE,true);
  875                                       shouldSetFlagBack = true;
  876                                   }
  877                                   if(!printing) {
  878                                       ((JComponent)comp).paint(cg);
  879                                   }
  880                                   else {
  881                                       if (!getFlag(IS_PRINTING_ALL)) {
  882                                           comp.print(cg);
  883                                       }
  884                                       else {
  885                                           comp.printAll(cg);
  886                                       }
  887                                   }
  888                               } else {
  889                                   if (!printing) {
  890                                       comp.paint(cg);
  891                                   }
  892                                   else {
  893                                       if (!getFlag(IS_PRINTING_ALL)) {
  894                                           comp.print(cg);
  895                                       }
  896                                       else {
  897                                           comp.printAll(cg);
  898                                       }
  899                                   }
  900                               }
  901                           } finally {
  902                               cg.dispose();
  903                               if(shouldSetFlagBack) {
  904                                   ((JComponent)comp).setFlag(
  905                                                ANCESTOR_USING_BUFFER,false);
  906                                   ((JComponent)comp).setFlag(
  907                                                IS_PAINTING_TILE,false);
  908                               }
  909                           }
  910                       }
  911                   }
  912   
  913               }
  914               recycleRectangle(tmpRect);
  915           }
  916       }
  917   
  918       /**
  919        * Paints the component's border.
  920        * <p>
  921        * If you override this in a subclass you should not make permanent
  922        * changes to the passed in <code>Graphics</code>. For example, you
  923        * should not alter the clip <code>Rectangle</code> or modify the
  924        * transform. If you need to do these operations you may find it
  925        * easier to create a new <code>Graphics</code> from the passed in
  926        * <code>Graphics</code> and manipulate it.
  927        *
  928        * @param g  the <code>Graphics</code> context in which to paint
  929        *
  930        * @see #paint
  931        * @see #setBorder
  932        */
  933       protected void paintBorder(Graphics g) {
  934           Border border = getBorder();
  935           if (border != null) {
  936               border.paintBorder(this, g, 0, 0, getWidth(), getHeight());
  937           }
  938       }
  939   
  940   
  941       /**
  942        * Calls <code>paint</code>.  Doesn't clear the background but see
  943        * <code>ComponentUI.update</code>, which is called by
  944        * <code>paintComponent</code>.
  945        *
  946        * @param g the <code>Graphics</code> context in which to paint
  947        * @see #paint
  948        * @see #paintComponent
  949        * @see javax.swing.plaf.ComponentUI
  950        */
  951       public void update(Graphics g) {
  952           paint(g);
  953       }
  954   
  955   
  956       /**
  957        * Invoked by Swing to draw components.
  958        * Applications should not invoke <code>paint</code> directly,
  959        * but should instead use the <code>repaint</code> method to
  960        * schedule the component for redrawing.
  961        * <p>
  962        * This method actually delegates the work of painting to three
  963        * protected methods: <code>paintComponent</code>,
  964        * <code>paintBorder</code>,
  965        * and <code>paintChildren</code>.  They're called in the order
  966        * listed to ensure that children appear on top of component itself.
  967        * Generally speaking, the component and its children should not
  968        * paint in the insets area allocated to the border. Subclasses can
  969        * just override this method, as always.  A subclass that just
  970        * wants to specialize the UI (look and feel) delegate's
  971        * <code>paint</code> method should just override
  972        * <code>paintComponent</code>.
  973        *
  974        * @param g  the <code>Graphics</code> context in which to paint
  975        * @see #paintComponent
  976        * @see #paintBorder
  977        * @see #paintChildren
  978        * @see #getComponentGraphics
  979        * @see #repaint
  980        */
  981       public void paint(Graphics g) {
  982           boolean shouldClearPaintFlags = false;
  983   
  984           if ((getWidth() <= 0) || (getHeight() <= 0)) {
  985               return;
  986           }
  987   
  988           Graphics componentGraphics = getComponentGraphics(g);
  989           Graphics co = componentGraphics.create();
  990           try {
  991               RepaintManager repaintManager = RepaintManager.currentManager(this);
  992               Rectangle clipRect = co.getClipBounds();
  993               int clipX;
  994               int clipY;
  995               int clipW;
  996               int clipH;
  997               if (clipRect == null) {
  998                   clipX = clipY = 0;
  999                   clipW = getWidth();
 1000                   clipH = getHeight();
 1001               }
 1002               else {
 1003                   clipX = clipRect.x;
 1004                   clipY = clipRect.y;
 1005                   clipW = clipRect.width;
 1006                   clipH = clipRect.height;
 1007               }
 1008   
 1009               if(clipW > getWidth()) {
 1010                   clipW = getWidth();
 1011               }
 1012               if(clipH > getHeight()) {
 1013                   clipH = getHeight();
 1014               }
 1015   
 1016               if(getParent() != null && !(getParent() instanceof JComponent)) {
 1017                   adjustPaintFlags();
 1018                   shouldClearPaintFlags = true;
 1019               }
 1020   
 1021               int bw,bh;
 1022               boolean printing = getFlag(IS_PRINTING);
 1023               if(!printing && repaintManager.isDoubleBufferingEnabled() &&
 1024                  !getFlag(ANCESTOR_USING_BUFFER) && isDoubleBuffered()) {
 1025                   repaintManager.beginPaint();
 1026                   try {
 1027                       repaintManager.paint(this, this, co, clipX, clipY, clipW,
 1028                                            clipH);
 1029                   } finally {
 1030                       repaintManager.endPaint();
 1031                   }
 1032               }
 1033               else {
 1034                   // Will ocassionaly happen in 1.2, especially when printing.
 1035                   if (clipRect == null) {
 1036                       co.setClip(clipX, clipY, clipW, clipH);
 1037                   }
 1038   
 1039                   if (!rectangleIsObscured(clipX,clipY,clipW,clipH)) {
 1040                       if (!printing) {
 1041                           paintComponent(co);
 1042                           paintBorder(co);
 1043                       }
 1044                       else {
 1045                           printComponent(co);
 1046                           printBorder(co);
 1047                       }
 1048                   }
 1049                   if (!printing) {
 1050                       paintChildren(co);
 1051                   }
 1052                   else {
 1053                       printChildren(co);
 1054                   }
 1055               }
 1056           } finally {
 1057               co.dispose();
 1058               if(shouldClearPaintFlags) {
 1059                   setFlag(ANCESTOR_USING_BUFFER,false);
 1060                   setFlag(IS_PAINTING_TILE,false);
 1061                   setFlag(IS_PRINTING,false);
 1062                   setFlag(IS_PRINTING_ALL,false);
 1063               }
 1064           }
 1065       }
 1066   
 1067       // paint forcing use of the double buffer.  This is used for historical
 1068       // reasons: JViewport, when scrolling, previously directly invoked paint
 1069       // while turning off double buffering at the RepaintManager level, this
 1070       // codes simulates that.
 1071       void paintForceDoubleBuffered(Graphics g) {
 1072           RepaintManager rm = RepaintManager.currentManager(this);
 1073           Rectangle clip = g.getClipBounds();
 1074           rm.beginPaint();
 1075           setFlag(IS_REPAINTING, true);
 1076           try {
 1077               rm.paint(this, this, g, clip.x, clip.y, clip.width, clip.height);
 1078           } finally {
 1079               rm.endPaint();
 1080               setFlag(IS_REPAINTING, false);
 1081           }
 1082       }
 1083   
 1084       /**
 1085        * Returns true if this component, or any of its ancestors, are in
 1086        * the processing of painting.
 1087        */
 1088       boolean isPainting() {
 1089           Container component = this;
 1090           while (component != null) {
 1091               if (component instanceof JComponent &&
 1092                      ((JComponent)component).getFlag(ANCESTOR_USING_BUFFER)) {
 1093                   return true;
 1094               }
 1095               component = component.getParent();
 1096           }
 1097           return false;
 1098       }
 1099   
 1100       private void adjustPaintFlags() {
 1101           JComponent jparent = null;
 1102           Container parent;
 1103           for(parent = getParent() ; parent != null ; parent =
 1104               parent.getParent()) {
 1105               if(parent instanceof JComponent) {
 1106                   jparent = (JComponent) parent;
 1107                   if(jparent.getFlag(ANCESTOR_USING_BUFFER))
 1108                     setFlag(ANCESTOR_USING_BUFFER, true);
 1109                   if(jparent.getFlag(IS_PAINTING_TILE))
 1110                     setFlag(IS_PAINTING_TILE, true);
 1111                   if(jparent.getFlag(IS_PRINTING))
 1112                     setFlag(IS_PRINTING, true);
 1113                   if(jparent.getFlag(IS_PRINTING_ALL))
 1114                     setFlag(IS_PRINTING_ALL, true);
 1115                   break;
 1116               }
 1117           }
 1118       }
 1119   
 1120       /**
 1121        * Invoke this method to print the component. This method invokes
 1122        * <code>print</code> on the component.
 1123        *
 1124        * @param g the <code>Graphics</code> context in which to paint
 1125        * @see #print
 1126        * @see #printComponent
 1127        * @see #printBorder
 1128        * @see #printChildren
 1129        */
 1130       public void printAll(Graphics g) {
 1131           setFlag(IS_PRINTING_ALL, true);
 1132           try {
 1133               print(g);
 1134           }
 1135           finally {
 1136               setFlag(IS_PRINTING_ALL, false);
 1137           }
 1138       }
 1139   
 1140       /**
 1141        * Invoke this method to print the component to the specified
 1142        * <code>Graphics</code>. This method will result in invocations
 1143        * of <code>printComponent</code>, <code>printBorder</code> and
 1144        * <code>printChildren</code>. It is recommended that you override
 1145        * one of the previously mentioned methods rather than this one if
 1146        * your intention is to customize the way printing looks. However,
 1147        * it can be useful to override this method should you want to prepare
 1148        * state before invoking the superclass behavior. As an example,
 1149        * if you wanted to change the component's background color before
 1150        * printing, you could do the following:
 1151        * <pre>
 1152        *     public void print(Graphics g) {
 1153        *         Color orig = getBackground();
 1154        *         setBackground(Color.WHITE);
 1155        *
 1156        *         // wrap in try/finally so that we always restore the state
 1157        *         try {
 1158        *             super.print(g);
 1159        *         } finally {
 1160        *             setBackground(orig);
 1161        *         }
 1162        *     }
 1163        * </pre>
 1164        * <p>
 1165        * Alternatively, or for components that delegate painting to other objects,
 1166        * you can query during painting whether or not the component is in the
 1167        * midst of a print operation. The <code>isPaintingForPrint</code> method provides
 1168        * this ability and its return value will be changed by this method: to
 1169        * <code>true</code> immediately before rendering and to <code>false</code>
 1170        * immediately after. With each change a property change event is fired on
 1171        * this component with the name <code>"paintingForPrint"</code>.
 1172        * <p>
 1173        * This method sets the component's state such that the double buffer
 1174        * will not be used: painting will be done directly on the passed in
 1175        * <code>Graphics</code>.
 1176        *
 1177        * @param g the <code>Graphics</code> context in which to paint
 1178        * @see #printComponent
 1179        * @see #printBorder
 1180        * @see #printChildren
 1181        * @see #isPaintingForPrint
 1182        */
 1183       public void print(Graphics g) {
 1184           setFlag(IS_PRINTING, true);
 1185           firePropertyChange("paintingForPrint", false, true);
 1186           try {
 1187               paint(g);
 1188           }
 1189           finally {
 1190               setFlag(IS_PRINTING, false);
 1191               firePropertyChange("paintingForPrint", true, false);
 1192           }
 1193       }
 1194   
 1195       /**
 1196        * This is invoked during a printing operation. This is implemented to
 1197        * invoke <code>paintComponent</code> on the component. Override this
 1198        * if you wish to add special painting behavior when printing.
 1199        *
 1200        * @param g the <code>Graphics</code> context in which to paint
 1201        * @see #print
 1202        * @since 1.3
 1203        */
 1204       protected void printComponent(Graphics g) {
 1205           paintComponent(g);
 1206       }
 1207   
 1208       /**
 1209        * Prints this component's children. This is implemented to invoke
 1210        * <code>paintChildren</code> on the component. Override this if you
 1211        * wish to print the children differently than painting.
 1212        *
 1213        * @param g the <code>Graphics</code> context in which to paint
 1214        * @see #print
 1215        * @since 1.3
 1216        */
 1217       protected void printChildren(Graphics g) {
 1218           paintChildren(g);
 1219       }
 1220   
 1221       /**
 1222        * Prints the component's border. This is implemented to invoke
 1223        * <code>paintBorder</code> on the component. Override this if you
 1224        * wish to print the border differently that it is painted.
 1225        *
 1226        * @param g the <code>Graphics</code> context in which to paint
 1227        * @see #print
 1228        * @since 1.3
 1229        */
 1230       protected void printBorder(Graphics g) {
 1231           paintBorder(g);
 1232       }
 1233   
 1234       /**
 1235        *  Returns true if the component is currently painting a tile.
 1236        *  If this method returns true, paint will be called again for another
 1237        *  tile. This method returns false if you are not painting a tile or
 1238        *  if the last tile is painted.
 1239        *  Use this method to keep some state you might need between tiles.
 1240        *
 1241        *  @return  true if the component is currently painting a tile,
 1242        *          false otherwise
 1243        */
 1244       public boolean isPaintingTile() {
 1245           return getFlag(IS_PAINTING_TILE);
 1246       }
 1247   
 1248       /**
 1249        * Returns <code>true</code> if the current painting operation on this
 1250        * component is part of a <code>print</code> operation. This method is
 1251        * useful when you want to customize what you print versus what you show
 1252        * on the screen.
 1253        * <p>
 1254        * You can detect changes in the value of this property by listening for
 1255        * property change events on this component with name
 1256        * <code>"paintingForPrint"</code>.
 1257        * <p>
 1258        * Note: This method provides complimentary functionality to that provided
 1259        * by other high level Swing printing APIs. However, it deals strictly with
 1260        * painting and should not be confused as providing information on higher
 1261        * level print processes. For example, a {@link javax.swing.JTable#print()}
 1262        * operation doesn't necessarily result in a continuous rendering of the
 1263        * full component, and the return value of this method can change multiple
 1264        * times during that operation. It is even possible for the component to be
 1265        * painted to the screen while the printing process is ongoing. In such a
 1266        * case, the return value of this method is <code>true</code> when, and only
 1267        * when, the table is being painted as part of the printing process.
 1268        *
 1269        * @return true if the current painting operation on this component
 1270        *         is part of a print operation
 1271        * @see #print
 1272        * @since 1.6
 1273        */
 1274       public final boolean isPaintingForPrint() {
 1275           return getFlag(IS_PRINTING);
 1276       }
 1277   
 1278       /**
 1279        * In release 1.4, the focus subsystem was rearchitected.
 1280        * For more information, see
 1281        * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
 1282        * How to Use the Focus Subsystem</a>,
 1283        * a section in <em>The Java Tutorial</em>.
 1284        * <p>
 1285        * Changes this <code>JComponent</code>'s focus traversal keys to
 1286        * CTRL+TAB and CTRL+SHIFT+TAB. Also prevents
 1287        * <code>SortingFocusTraversalPolicy</code> from considering descendants
 1288        * of this JComponent when computing a focus traversal cycle.
 1289        *
 1290        * @see java.awt.Component#setFocusTraversalKeys
 1291        * @see SortingFocusTraversalPolicy
 1292        * @deprecated As of 1.4, replaced by
 1293        *   <code>Component.setFocusTraversalKeys(int, Set)</code> and
 1294        *   <code>Container.setFocusCycleRoot(boolean)</code>.
 1295        */
 1296       @Deprecated
 1297       public boolean isManagingFocus() {
 1298           return false;
 1299       }
 1300   
 1301       private void registerNextFocusableComponent() {
 1302           registerNextFocusableComponent(getNextFocusableComponent());
 1303       }
 1304   
 1305       private void registerNextFocusableComponent(Component
 1306                                                   nextFocusableComponent) {
 1307           if (nextFocusableComponent == null) {
 1308               return;
 1309           }
 1310   
 1311           Container nearestRoot =
 1312               (isFocusCycleRoot()) ? this : getFocusCycleRootAncestor();
 1313           FocusTraversalPolicy policy = nearestRoot.getFocusTraversalPolicy();
 1314           if (!(policy instanceof LegacyGlueFocusTraversalPolicy)) {
 1315               policy = new LegacyGlueFocusTraversalPolicy(policy);
 1316               nearestRoot.setFocusTraversalPolicy(policy);
 1317           }
 1318           ((LegacyGlueFocusTraversalPolicy)policy).
 1319               setNextFocusableComponent(this, nextFocusableComponent);
 1320       }
 1321   
 1322       private void deregisterNextFocusableComponent() {
 1323           Component nextFocusableComponent = getNextFocusableComponent();
 1324           if (nextFocusableComponent == null) {
 1325               return;
 1326           }
 1327   
 1328           Container nearestRoot =
 1329               (isFocusCycleRoot()) ? this : getFocusCycleRootAncestor();
 1330           if (nearestRoot == null) {
 1331               return;
 1332           }
 1333           FocusTraversalPolicy policy = nearestRoot.getFocusTraversalPolicy();
 1334           if (policy instanceof LegacyGlueFocusTraversalPolicy) {
 1335               ((LegacyGlueFocusTraversalPolicy)policy).
 1336                   unsetNextFocusableComponent(this, nextFocusableComponent);
 1337           }
 1338       }
 1339   
 1340       /**
 1341        * In release 1.4, the focus subsystem was rearchitected.
 1342        * For more information, see
 1343        * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
 1344        * How to Use the Focus Subsystem</a>,
 1345        * a section in <em>The Java Tutorial</em>.
 1346        * <p>
 1347        * Overrides the default <code>FocusTraversalPolicy</code> for this
 1348        * <code>JComponent</code>'s focus traversal cycle by unconditionally
 1349        * setting the specified <code>Component</code> as the next
 1350        * <code>Component</code> in the cycle, and this <code>JComponent</code>
 1351        * as the specified <code>Component</code>'s previous
 1352        * <code>Component</code> in the cycle.
 1353        *
 1354        * @param aComponent the <code>Component</code> that should follow this
 1355        *        <code>JComponent</code> in the focus traversal cycle
 1356        *
 1357        * @see #getNextFocusableComponent
 1358        * @see java.awt.FocusTraversalPolicy
 1359        * @deprecated As of 1.4, replaced by <code>FocusTraversalPolicy</code>
 1360        */
 1361       @Deprecated
 1362       public void setNextFocusableComponent(Component aComponent) {
 1363           boolean displayable = isDisplayable();
 1364           if (displayable) {
 1365               deregisterNextFocusableComponent();
 1366           }
 1367           putClientProperty(NEXT_FOCUS, aComponent);
 1368           if (displayable) {
 1369               registerNextFocusableComponent(aComponent);
 1370           }
 1371       }
 1372   
 1373       /**
 1374        * In release 1.4, the focus subsystem was rearchitected.
 1375        * For more information, see
 1376        * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
 1377        * How to Use the Focus Subsystem</a>,
 1378        * a section in <em>The Java Tutorial</em>.
 1379        * <p>
 1380        * Returns the <code>Component</code> set by a prior call to
 1381        * <code>setNextFocusableComponent(Component)</code> on this
 1382        * <code>JComponent</code>.
 1383        *
 1384        * @return the <code>Component</code> that will follow this
 1385        *        <code>JComponent</code> in the focus traversal cycle, or
 1386        *        <code>null</code> if none has been explicitly specified
 1387        *
 1388        * @see #setNextFocusableComponent
 1389        * @deprecated As of 1.4, replaced by <code>FocusTraversalPolicy</code>.
 1390        */
 1391       @Deprecated
 1392       public Component getNextFocusableComponent() {
 1393           return (Component)getClientProperty(NEXT_FOCUS);
 1394       }
 1395   
 1396       /**
 1397        * Provides a hint as to whether or not this <code>JComponent</code>
 1398        * should get focus. This is only a hint, and it is up to consumers that
 1399        * are requesting focus to honor this property. This is typically honored
 1400        * for mouse operations, but not keyboard operations. For example, look
 1401        * and feels could verify this property is true before requesting focus
 1402        * during a mouse operation. This would often times be used if you did
 1403        * not want a mouse press on a <code>JComponent</code> to steal focus,
 1404        * but did want the <code>JComponent</code> to be traversable via the
 1405        * keyboard. If you do not want this <code>JComponent</code> focusable at
 1406        * all, use the <code>setFocusable</code> method instead.
 1407        * <p>
 1408        * Please see
 1409        * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
 1410        * How to Use the Focus Subsystem</a>,
 1411        * a section in <em>The Java Tutorial</em>,
 1412        * for more information.
 1413        *
 1414        * @param requestFocusEnabled indicates whether you want this
 1415        *        <code>JComponent</code> to be focusable or not
 1416        * @see <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
 1417        * @see java.awt.Component#setFocusable
 1418        */
 1419       public void setRequestFocusEnabled(boolean requestFocusEnabled) {
 1420           setFlag(REQUEST_FOCUS_DISABLED, !requestFocusEnabled);
 1421       }
 1422   
 1423       /**
 1424        * Returns <code>true</code> if this <code>JComponent</code> should
 1425        * get focus; otherwise returns <code>false</code>.
 1426        * <p>
 1427        * Please see
 1428        * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
 1429        * How to Use the Focus Subsystem</a>,
 1430        * a section in <em>The Java Tutorial</em>,
 1431        * for more information.
 1432        *
 1433        * @return <code>true</code> if this component should get focus,
 1434        *     otherwise returns <code>false</code>
 1435        * @see #setRequestFocusEnabled
 1436        * @see <a href="../../java/awt/doc-files/FocusSpec.html">Focus
 1437        *      Specification</a>
 1438        * @see java.awt.Component#isFocusable
 1439        */
 1440       public boolean isRequestFocusEnabled() {
 1441           return !getFlag(REQUEST_FOCUS_DISABLED);
 1442       }
 1443   
 1444       /**
 1445        * Requests that this <code>Component</code> gets the input focus.
 1446        * Refer to {@link java.awt.Component#requestFocus()
 1447        * Component.requestFocus()} for a complete description of
 1448        * this method.
 1449        * <p>
 1450        * Note that the use of this method is discouraged because
 1451        * its behavior is platform dependent. Instead we recommend the
 1452        * use of {@link #requestFocusInWindow() requestFocusInWindow()}.
 1453        * If you would like more information on focus, see
 1454        * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
 1455        * How to Use the Focus Subsystem</a>,
 1456        * a section in <em>The Java Tutorial</em>.
 1457        *
 1458        * @see java.awt.Component#requestFocusInWindow()
 1459        * @see java.awt.Component#requestFocusInWindow(boolean)
 1460        * @since 1.4
 1461        */
 1462       public void requestFocus() {
 1463           super.requestFocus();
 1464       }
 1465   
 1466       /**
 1467        * Requests that this <code>Component</code> gets the input focus.
 1468        * Refer to {@link java.awt.Component#requestFocus(boolean)
 1469        * Component.requestFocus(boolean)} for a complete description of
 1470        * this method.
 1471        * <p>
 1472        * Note that the use of this method is discouraged because
 1473        * its behavior is platform dependent. Instead we recommend the
 1474        * use of {@link #requestFocusInWindow(boolean)
 1475        * requestFocusInWindow(boolean)}.
 1476        * If you would like more information on focus, see
 1477        * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
 1478        * How to Use the Focus Subsystem</a>,
 1479        * a section in <em>The Java Tutorial</em>.
 1480        *
 1481        * @param temporary boolean indicating if the focus change is temporary
 1482        * @return <code>false</code> if the focus change request is guaranteed to
 1483        *         fail; <code>true</code> if it is likely to succeed
 1484        * @see java.awt.Component#requestFocusInWindow()
 1485        * @see java.awt.Component#requestFocusInWindow(boolean)
 1486        * @since 1.4
 1487        */
 1488       public boolean requestFocus(boolean temporary) {
 1489           return super.requestFocus(temporary);
 1490       }
 1491   
 1492       /**
 1493        * Requests that this <code>Component</code> gets the input focus.
 1494        * Refer to {@link java.awt.Component#requestFocusInWindow()
 1495        * Component.requestFocusInWindow()} for a complete description of
 1496        * this method.
 1497        * <p>
 1498        * If you would like more information on focus, see
 1499        * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
 1500        * How to Use the Focus Subsystem</a>,
 1501        * a section in <em>The Java Tutorial</em>.
 1502        *
 1503        * @return <code>false</code> if the focus change request is guaranteed to
 1504        *         fail; <code>true</code> if it is likely to succeed
 1505        * @see java.awt.Component#requestFocusInWindow()
 1506        * @see java.awt.Component#requestFocusInWindow(boolean)
 1507        * @since 1.4
 1508        */
 1509       public boolean requestFocusInWindow() {
 1510           return super.requestFocusInWindow();
 1511       }
 1512   
 1513       /**
 1514        * Requests that this <code>Component</code> gets the input focus.
 1515        * Refer to {@link java.awt.Component#requestFocusInWindow(boolean)
 1516        * Component.requestFocusInWindow(boolean)} for a complete description of
 1517        * this method.
 1518        * <p>
 1519        * If you would like more information on focus, see
 1520        * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
 1521        * How to Use the Focus Subsystem</a>,
 1522        * a section in <em>The Java Tutorial</em>.
 1523        *
 1524        * @param temporary boolean indicating if the focus change is temporary
 1525        * @return <code>false</code> if the focus change request is guaranteed to
 1526        *         fail; <code>true</code> if it is likely to succeed
 1527        * @see java.awt.Component#requestFocusInWindow()
 1528        * @see java.awt.Component#requestFocusInWindow(boolean)
 1529        * @since 1.4
 1530        */
 1531       protected boolean requestFocusInWindow(boolean temporary) {
 1532           return super.requestFocusInWindow(temporary);
 1533       }
 1534   
 1535       /**
 1536        * Requests that this Component get the input focus, and that this
 1537        * Component's top-level ancestor become the focused Window. This component
 1538        * must be displayable, visible, and focusable for the request to be
 1539        * granted.
 1540        * <p>
 1541        * This method is intended for use by focus implementations. Client code
 1542        * should not use this method; instead, it should use
 1543        * <code>requestFocusInWindow()</code>.
 1544        *
 1545        * @see #requestFocusInWindow()
 1546        */
 1547       public void grabFocus() {
 1548           requestFocus();
 1549       }
 1550   
 1551       /**
 1552        * Sets the value to indicate whether input verifier for the
 1553        * current focus owner will be called before this component requests
 1554        * focus. The default is true. Set to false on components such as a
 1555        * Cancel button or a scrollbar, which should activate even if the
 1556        * input in the current focus owner is not "passed" by the input
 1557        * verifier for that component.
 1558        *
 1559        * @param verifyInputWhenFocusTarget value for the
 1560        *        <code>verifyInputWhenFocusTarget</code> property
 1561        * @see InputVerifier
 1562        * @see #setInputVerifier
 1563        * @see #getInputVerifier
 1564        * @see #getVerifyInputWhenFocusTarget
 1565        *
 1566        * @since 1.3
 1567        * @beaninfo
 1568        *       bound: true
 1569        * description: Whether the Component verifies input before accepting
 1570        *              focus.
 1571        */
 1572       public void setVerifyInputWhenFocusTarget(boolean
 1573                                                 verifyInputWhenFocusTarget) {
 1574           boolean oldVerifyInputWhenFocusTarget =
 1575               this.verifyInputWhenFocusTarget;
 1576           this.verifyInputWhenFocusTarget = verifyInputWhenFocusTarget;
 1577           firePropertyChange("verifyInputWhenFocusTarget",
 1578                              oldVerifyInputWhenFocusTarget,
 1579                              verifyInputWhenFocusTarget);
 1580       }
 1581   
 1582       /**
 1583        * Returns the value that indicates whether the input verifier for the
 1584        * current focus owner will be called before this component requests
 1585        * focus.
 1586        *
 1587        * @return value of the <code>verifyInputWhenFocusTarget</code> property
 1588        *
 1589        * @see InputVerifier
 1590        * @see #setInputVerifier
 1591        * @see #getInputVerifier
 1592        * @see #setVerifyInputWhenFocusTarget
 1593        *
 1594        * @since 1.3
 1595        */
 1596       public boolean getVerifyInputWhenFocusTarget() {
 1597           return verifyInputWhenFocusTarget;
 1598       }
 1599   
 1600   
 1601       /**
 1602        * Gets the <code>FontMetrics</code> for the specified <code>Font</code>.
 1603        *
 1604        * @param font the font for which font metrics is to be
 1605        *          obtained
 1606        * @return the font metrics for <code>font</code>
 1607        * @throws NullPointerException if <code>font</code> is null
 1608        * @since 1.5
 1609        */
 1610       public FontMetrics getFontMetrics(Font font) {
 1611           return SwingUtilities2.getFontMetrics(this, font);
 1612       }
 1613   
 1614   
 1615       /**
 1616        * Sets the preferred size of this component.
 1617        * If <code>preferredSize</code> is <code>null</code>, the UI will
 1618        * be asked for the preferred size.
 1619        * @beaninfo
 1620        *   preferred: true
 1621        *       bound: true
 1622        * description: The preferred size of the component.
 1623        */
 1624       public void setPreferredSize(Dimension preferredSize) {
 1625           super.setPreferredSize(preferredSize);
 1626       }
 1627   
 1628   
 1629       /**
 1630        * If the <code>preferredSize</code> has been set to a
 1631        * non-<code>null</code> value just returns it.
 1632        * If the UI delegate's <code>getPreferredSize</code>
 1633        * method returns a non <code>null</code> value then return that;
 1634        * otherwise defer to the component's layout manager.
 1635        *
 1636        * @return the value of the <code>preferredSize</code> property
 1637        * @see #setPreferredSize
 1638        * @see ComponentUI
 1639        */
 1640       @Transient
 1641       public Dimension getPreferredSize() {
 1642           if (isPreferredSizeSet()) {
 1643               return super.getPreferredSize();
 1644           }
 1645           Dimension size = null;
 1646           if (ui != null) {
 1647               size = ui.getPreferredSize(this);
 1648           }
 1649           return (size != null) ? size : super.getPreferredSize();
 1650       }
 1651   
 1652   
 1653       /**
 1654        * Sets the maximum size of this component to a constant
 1655        * value.  Subsequent calls to <code>getMaximumSize</code> will always
 1656        * return this value; the component's UI will not be asked
 1657        * to compute it.  Setting the maximum size to <code>null</code>
 1658        * restores the default behavior.
 1659        *
 1660        * @param maximumSize a <code>Dimension</code> containing the
 1661        *          desired maximum allowable size
 1662        * @see #getMaximumSize
 1663        * @beaninfo
 1664        *       bound: true
 1665        * description: The maximum size of the component.
 1666        */
 1667       public void setMaximumSize(Dimension maximumSize) {
 1668           super.setMaximumSize(maximumSize);
 1669       }
 1670   
 1671   
 1672       /**
 1673        * If the maximum size has been set to a non-<code>null</code> value
 1674        * just returns it.  If the UI delegate's <code>getMaximumSize</code>
 1675        * method returns a non-<code>null</code> value then return that;
 1676        * otherwise defer to the component's layout manager.
 1677        *
 1678        * @return the value of the <code>maximumSize</code> property
 1679        * @see #setMaximumSize
 1680        * @see ComponentUI
 1681        */
 1682       @Transient
 1683       public Dimension getMaximumSize() {
 1684           if (isMaximumSizeSet()) {
 1685               return super.getMaximumSize();
 1686           }
 1687           Dimension size = null;
 1688           if (ui != null) {
 1689               size = ui.getMaximumSize(this);
 1690           }
 1691           return (size != null) ? size : super.getMaximumSize();
 1692       }
 1693   
 1694   
 1695       /**
 1696        * Sets the minimum size of this component to a constant
 1697        * value.  Subsequent calls to <code>getMinimumSize</code> will always
 1698        * return this value; the component's UI will not be asked
 1699        * to compute it.  Setting the minimum size to <code>null</code>
 1700        * restores the default behavior.
 1701        *
 1702        * @param minimumSize the new minimum size of this component
 1703        * @see #getMinimumSize
 1704        * @beaninfo
 1705        *       bound: true
 1706        * description: The minimum size of the component.
 1707        */
 1708       public void setMinimumSize(Dimension minimumSize) {
 1709           super.setMinimumSize(minimumSize);
 1710       }
 1711   
 1712       /**
 1713        * If the minimum size has been set to a non-<code>null</code> value
 1714        * just returns it.  If the UI delegate's <code>getMinimumSize</code>
 1715        * method returns a non-<code>null</code> value then return that; otherwise
 1716        * defer to the component's layout manager.
 1717        *
 1718        * @return the value of the <code>minimumSize</code> property
 1719        * @see #setMinimumSize
 1720        * @see ComponentUI
 1721        */
 1722       @Transient
 1723       public Dimension getMinimumSize() {
 1724           if (isMinimumSizeSet()) {
 1725               return super.getMinimumSize();
 1726           }
 1727           Dimension size = null;
 1728           if (ui != null) {
 1729               size = ui.getMinimumSize(this);
 1730           }
 1731           return (size != null) ? size : super.getMinimumSize();
 1732       }
 1733   
 1734       /**
 1735        * Gives the UI delegate an opportunity to define the precise
 1736        * shape of this component for the sake of mouse processing.
 1737        *
 1738        * @return true if this component logically contains x,y
 1739        * @see java.awt.Component#contains(int, int)
 1740        * @see ComponentUI
 1741        */
 1742       public boolean contains(int x, int y) {
 1743           return (ui != null) ? ui.contains(this, x, y) : super.contains(x, y);
 1744       }
 1745   
 1746       /**
 1747        * Sets the border of this component.  The <code>Border</code> object is
 1748        * responsible for defining the insets for the component
 1749        * (overriding any insets set directly on the component) and
 1750        * for optionally rendering any border decorations within the
 1751        * bounds of those insets.  Borders should be used (rather
 1752        * than insets) for creating both decorative and non-decorative
 1753        * (such as margins and padding) regions for a swing component.
 1754        * Compound borders can be used to nest multiple borders within a
 1755        * single component.
 1756        * <p>
 1757        * Although technically you can set the border on any object
 1758        * that inherits from <code>JComponent</code>, the look and
 1759        * feel implementation of many standard Swing components
 1760        * doesn't work well with user-set borders.  In general,
 1761        * when you want to set a border on a standard Swing
 1762        * component other than <code>JPanel</code> or <code>JLabel</code>,
 1763        * we recommend that you put the component in a <code>JPanel</code>
 1764        * and set the border on the <code>JPanel</code>.
 1765        * <p>
 1766        * This is a bound property.
 1767        *
 1768        * @param border the border to be rendered for this component
 1769        * @see Border
 1770        * @see CompoundBorder
 1771        * @beaninfo
 1772        *        bound: true
 1773        *    preferred: true
 1774        *    attribute: visualUpdate true
 1775        *  description: The component's border.
 1776        */
 1777       public void setBorder(Border border) {
 1778           Border         oldBorder = this.border;
 1779   
 1780           this.border = border;
 1781           firePropertyChange("border", oldBorder, border);
 1782           if (border != oldBorder) {
 1783               if (border == null || oldBorder == null ||
 1784                   !(border.getBorderInsets(this).equals(oldBorder.getBorderInsets(this)))) {
 1785                   revalidate();
 1786               }
 1787               repaint();
 1788           }
 1789       }
 1790   
 1791       /**
 1792        * Returns the border of this component or <code>null</code> if no
 1793        * border is currently set.
 1794        *
 1795        * @return the border object for this component
 1796        * @see #setBorder
 1797        */
 1798       public Border getBorder() {
 1799           return border;
 1800       }
 1801   
 1802       /**
 1803        * If a border has been set on this component, returns the
 1804        * border's insets; otherwise calls <code>super.getInsets</code>.
 1805        *
 1806        * @return the value of the insets property
 1807        * @see #setBorder
 1808        */
 1809       public Insets getInsets() {
 1810           if (border != null) {
 1811               return border.getBorderInsets(this);
 1812           }
 1813           return super.getInsets();
 1814       }
 1815   
 1816       /**
 1817        * Returns an <code>Insets</code> object containing this component's inset
 1818        * values.  The passed-in <code>Insets</code> object will be reused
 1819        * if possible.
 1820        * Calling methods cannot assume that the same object will be returned,
 1821        * however.  All existing values within this object are overwritten.
 1822        * If <code>insets</code> is null, this will allocate a new one.
 1823        *
 1824        * @param insets the <code>Insets</code> object, which can be reused
 1825        * @return the <code>Insets</code> object
 1826        * @see #getInsets
 1827        * @beaninfo
 1828        *   expert: true
 1829        */
 1830       public Insets getInsets(Insets insets) {
 1831           if (insets == null) {
 1832               insets = new Insets(0, 0, 0, 0);
 1833           }
 1834           if (border != null) {
 1835               if (border instanceof AbstractBorder) {
 1836                   return ((AbstractBorder)border).getBorderInsets(this, insets);
 1837               } else {
 1838                   // Can't reuse border insets because the Border interface
 1839                   // can't be enhanced.
 1840                   return border.getBorderInsets(this);
 1841               }
 1842           } else {
 1843               // super.getInsets() always returns an Insets object with
 1844               // all of its value zeroed.  No need for a new object here.
 1845               insets.left = insets.top = insets.right = insets.bottom = 0;
 1846               return insets;
 1847           }
 1848       }
 1849   
 1850       /**
 1851        * Overrides <code>Container.getAlignmentY</code> to return
 1852        * the horizontal alignment.
 1853        *
 1854        * @return the value of the <code>alignmentY</code> property
 1855        * @see #setAlignmentY
 1856        * @see java.awt.Component#getAlignmentY
 1857        */
 1858       public float getAlignmentY() {
 1859           if (isAlignmentYSet) {
 1860               return alignmentY;
 1861           }
 1862           return super.getAlignmentY();
 1863       }
 1864   
 1865       /**
 1866        * Sets the the horizontal alignment.
 1867        *
 1868        * @param alignmentY  the new horizontal alignment
 1869        * @see #getAlignmentY
 1870        * @beaninfo
 1871        *   description: The preferred vertical alignment of the component.
 1872        */
 1873       public void setAlignmentY(float alignmentY) {
 1874           this.alignmentY = alignmentY > 1.0f ? 1.0f : alignmentY < 0.0f ? 0.0f : alignmentY;
 1875           isAlignmentYSet = true;
 1876       }
 1877   
 1878   
 1879       /**
 1880        * Overrides <code>Container.getAlignmentX</code> to return
 1881        * the vertical alignment.
 1882        *
 1883        * @return the value of the <code>alignmentX</code> property
 1884        * @see #setAlignmentX
 1885        * @see java.awt.Component#getAlignmentX
 1886        */
 1887       public float getAlignmentX() {
 1888           if (isAlignmentXSet) {
 1889               return alignmentX;
 1890           }
 1891           return super.getAlignmentX();
 1892       }
 1893   
 1894       /**
 1895        * Sets the the vertical alignment.
 1896        *
 1897        * @param alignmentX  the new vertical alignment
 1898        * @see #getAlignmentX
 1899        * @beaninfo
 1900        *   description: The preferred horizontal alignment of the component.
 1901        */
 1902       public void setAlignmentX(float alignmentX) {
 1903           this.alignmentX = alignmentX > 1.0f ? 1.0f : alignmentX < 0.0f ? 0.0f : alignmentX;
 1904           isAlignmentXSet = true;
 1905       }
 1906   
 1907       /**
 1908        * Sets the input verifier for this component.
 1909        *
 1910        * @param inputVerifier the new input verifier
 1911        * @since 1.3
 1912        * @see InputVerifier
 1913        * @beaninfo
 1914        *       bound: true
 1915        * description: The component's input verifier.
 1916        */
 1917       public void setInputVerifier(InputVerifier inputVerifier) {
 1918           InputVerifier oldInputVerifier = (InputVerifier)getClientProperty(
 1919                                            JComponent_INPUT_VERIFIER);
 1920           putClientProperty(JComponent_INPUT_VERIFIER, inputVerifier);
 1921           firePropertyChange("inputVerifier", oldInputVerifier, inputVerifier);
 1922       }
 1923   
 1924       /**
 1925        * Returns the input verifier for this component.
 1926        *
 1927        * @return the <code>inputVerifier</code> property
 1928        * @since 1.3
 1929        * @see InputVerifier
 1930        */
 1931       public InputVerifier getInputVerifier() {
 1932           return (InputVerifier)getClientProperty(JComponent_INPUT_VERIFIER);
 1933       }
 1934   
 1935       /**
 1936        * Returns this component's graphics context, which lets you draw
 1937        * on a component. Use this method to get a <code>Graphics</code> object and
 1938        * then invoke operations on that object to draw on the component.
 1939        * @return this components graphics context
 1940        */
 1941       public Graphics getGraphics() {
 1942           if (DEBUG_GRAPHICS_LOADED && shouldDebugGraphics() != 0) {
 1943               DebugGraphics graphics = new DebugGraphics(super.getGraphics(),
 1944                                                          this);
 1945               return graphics;
 1946           }
 1947           return super.getGraphics();
 1948       }
 1949   
 1950   
 1951       /** Enables or disables diagnostic information about every graphics
 1952         * operation performed within the component or one of its children.
 1953         *
 1954         * @param debugOptions  determines how the component should display
 1955         *         the information;  one of the following options:
 1956         * <ul>
 1957         * <li>DebugGraphics.LOG_OPTION - causes a text message to be printed.
 1958         * <li>DebugGraphics.FLASH_OPTION - causes the drawing to flash several
 1959         * times.
 1960         * <li>DebugGraphics.BUFFERED_OPTION - creates an
 1961         *         <code>ExternalWindow</code> that displays the operations
 1962         *         performed on the View's offscreen buffer.
 1963         * <li>DebugGraphics.NONE_OPTION disables debugging.
 1964         * <li>A value of 0 causes no changes to the debugging options.
 1965         * </ul>
 1966         * <code>debugOptions</code> is bitwise OR'd into the current value
 1967         *
 1968         * @beaninfo
 1969         *   preferred: true
 1970         *        enum: NONE_OPTION DebugGraphics.NONE_OPTION
 1971         *              LOG_OPTION DebugGraphics.LOG_OPTION
 1972         *              FLASH_OPTION DebugGraphics.FLASH_OPTION
 1973         *              BUFFERED_OPTION DebugGraphics.BUFFERED_OPTION
 1974         * description: Diagnostic options for graphics operations.
 1975         */
 1976       public void setDebugGraphicsOptions(int debugOptions) {
 1977           DebugGraphics.setDebugOptions(this, debugOptions);
 1978       }
 1979   
 1980       /** Returns the state of graphics debugging.
 1981         *
 1982         * @return a bitwise OR'd flag of zero or more of the following options:
 1983         * <ul>
 1984         * <li>DebugGraphics.LOG_OPTION - causes a text message to be printed.
 1985         * <li>DebugGraphics.FLASH_OPTION - causes the drawing to flash several
 1986         * times.
 1987         * <li>DebugGraphics.BUFFERED_OPTION - creates an
 1988         *         <code>ExternalWindow</code> that displays the operations
 1989         *         performed on the View's offscreen buffer.
 1990         * <li>DebugGraphics.NONE_OPTION disables debugging.
 1991         * <li>A value of 0 causes no changes to the debugging options.
 1992         * </ul>
 1993         * @see #setDebugGraphicsOptions
 1994         */
 1995       public int getDebugGraphicsOptions() {
 1996           return DebugGraphics.getDebugOptions(this);
 1997       }
 1998   
 1999   
 2000       /**
 2001        * Returns true if debug information is enabled for this
 2002        * <code>JComponent</code> or one of its parents.
 2003        */
 2004       int shouldDebugGraphics() {
 2005           return DebugGraphics.shouldComponentDebug(this);
 2006       }
 2007   
 2008       /**
 2009        * This method is now obsolete, please use a combination of
 2010        * <code>getActionMap()</code> and <code>getInputMap()</code> for
 2011        * similiar behavior. For example, to bind the <code>KeyStroke</code>
 2012        * <code>aKeyStroke</code> to the <code>Action</code> <code>anAction</code>
 2013        * now use:
 2014        * <pre>
 2015        *   component.getInputMap().put(aKeyStroke, aCommand);
 2016        *   component.getActionMap().put(aCommmand, anAction);
 2017        * </pre>
 2018        * The above assumes you want the binding to be applicable for
 2019        * <code>WHEN_FOCUSED</code>. To register bindings for other focus
 2020        * states use the <code>getInputMap</code> method that takes an integer.
 2021        * <p>
 2022        * Register a new keyboard action.
 2023        * <code>anAction</code> will be invoked if a key event matching
 2024        * <code>aKeyStroke</code> occurs and <code>aCondition</code> is verified.
 2025        * The <code>KeyStroke</code> object defines a
 2026        * particular combination of a keyboard key and one or more modifiers
 2027        * (alt, shift, ctrl, meta).
 2028        * <p>
 2029        * The <code>aCommand</code> will be set in the delivered event if
 2030        * specified.
 2031        * <p>
 2032        * The <code>aCondition</code> can be one of:
 2033        * <blockquote>
 2034        * <DL>
 2035        * <DT>WHEN_FOCUSED
 2036        * <DD>The action will be invoked only when the keystroke occurs
 2037        *     while the component has the focus.
 2038        * <DT>WHEN_IN_FOCUSED_WINDOW
 2039        * <DD>The action will be invoked when the keystroke occurs while
 2040        *     the component has the focus or if the component is in the
 2041        *     window that has the focus. Note that the component need not
 2042        *     be an immediate descendent of the window -- it can be
 2043        *     anywhere in the window's containment hierarchy. In other
 2044        *     words, whenever <em>any</em> component in the window has the focus,
 2045        *     the action registered with this component is invoked.
 2046        * <DT>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
 2047        * <DD>The action will be invoked when the keystroke occurs while the
 2048        *     component has the focus or if the component is an ancestor of
 2049        *     the component that has the focus.
 2050        * </DL>
 2051        * </blockquote>
 2052        * <p>
 2053        * The combination of keystrokes and conditions lets you define high
 2054        * level (semantic) action events for a specified keystroke+modifier
 2055        * combination (using the KeyStroke class) and direct to a parent or
 2056        * child of a component that has the focus, or to the component itself.
 2057        * In other words, in any hierarchical structure of components, an
 2058        * arbitrary key-combination can be immediately directed to the
 2059        * appropriate component in the hierarchy, and cause a specific method
 2060        * to be invoked (usually by way of adapter objects).
 2061        * <p>
 2062        * If an action has already been registered for the receiving
 2063        * container, with the same charCode and the same modifiers,
 2064        * <code>anAction</code> will replace the action.
 2065        *
 2066        * @param anAction  the <code>Action</code> to be registered
 2067        * @param aCommand  the command to be set in the delivered event
 2068        * @param aKeyStroke the <code>KeyStroke</code> to bind to the action
 2069        * @param aCondition the condition that needs to be met, see above
 2070        * @see KeyStroke
 2071        */
 2072       public void registerKeyboardAction(ActionListener anAction,String aCommand,KeyStroke aKeyStroke,int aCondition) {
 2073   
 2074           InputMap inputMap = getInputMap(aCondition, true);
 2075   
 2076           if (inputMap != null) {
 2077               ActionMap actionMap = getActionMap(true);
 2078               ActionStandin action = new ActionStandin(anAction, aCommand);
 2079               inputMap.put(aKeyStroke, action);
 2080               if (actionMap != null) {
 2081                   actionMap.put(action, action);
 2082               }
 2083           }
 2084       }
 2085   
 2086       /**
 2087        * Registers any bound <code>WHEN_IN_FOCUSED_WINDOW</code> actions with
 2088        * the <code>KeyboardManager</code>. If <code>onlyIfNew</code>
 2089        * is true only actions that haven't been registered are pushed
 2090        * to the <code>KeyboardManager</code>;
 2091        * otherwise all actions are pushed to the <code>KeyboardManager</code>.
 2092        *
 2093        * @param onlyIfNew  if true, only actions that haven't been registered
 2094        *          are pushed to the <code>KeyboardManager</code>
 2095        */
 2096       private void registerWithKeyboardManager(boolean onlyIfNew) {
 2097           InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW, false);
 2098           KeyStroke[] strokes;
 2099           Hashtable registered = (Hashtable)getClientProperty
 2100                                   (WHEN_IN_FOCUSED_WINDOW_BINDINGS);
 2101   
 2102           if (inputMap != null) {
 2103               // Push any new KeyStrokes to the KeyboardManager.
 2104               strokes = inputMap.allKeys();
 2105               if (strokes != null) {
 2106                   for (int counter = strokes.length - 1; counter >= 0;
 2107                        counter--) {
 2108                       if (!onlyIfNew || registered == null ||
 2109                           registered.get(strokes[counter]) == null) {
 2110                           registerWithKeyboardManager(strokes[counter]);
 2111                       }
 2112                       if (registered != null) {
 2113                           registered.remove(strokes[counter]);
 2114                       }
 2115                   }
 2116               }
 2117           }
 2118           else {
 2119               strokes = null;
 2120           }
 2121           // Remove any old ones.
 2122           if (registered != null && registered.size() > 0) {
 2123               Enumeration keys = registered.keys();
 2124   
 2125               while (keys.hasMoreElements()) {
 2126                   KeyStroke ks = (KeyStroke)keys.nextElement();
 2127                   unregisterWithKeyboardManager(ks);
 2128               }
 2129               registered.clear();
 2130           }
 2131           // Updated the registered Hashtable.
 2132           if (strokes != null && strokes.length > 0) {
 2133               if (registered == null) {
 2134                   registered = new Hashtable(strokes.length);
 2135                   putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, registered);
 2136               }
 2137               for (int counter = strokes.length - 1; counter >= 0; counter--) {
 2138                   registered.put(strokes[counter], strokes[counter]);
 2139               }
 2140           }
 2141           else {
 2142               putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, null);
 2143           }
 2144       }
 2145   
 2146       /**
 2147        * Unregisters all the previously registered
 2148        * <code>WHEN_IN_FOCUSED_WINDOW</code> <code>KeyStroke</code> bindings.
 2149        */
 2150       private void unregisterWithKeyboardManager() {
 2151           Hashtable registered = (Hashtable)getClientProperty
 2152                                   (WHEN_IN_FOCUSED_WINDOW_BINDINGS);
 2153   
 2154           if (registered != null && registered.size() > 0) {
 2155               Enumeration keys = registered.keys();
 2156   
 2157               while (keys.hasMoreElements()) {
 2158                   KeyStroke ks = (KeyStroke)keys.nextElement();
 2159                   unregisterWithKeyboardManager(ks);
 2160               }
 2161           }
 2162           putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, null);
 2163       }
 2164   
 2165       /**
 2166        * Invoked from <code>ComponentInputMap</code> when its bindings change.
 2167        * If <code>inputMap</code> is the current <code>windowInputMap</code>
 2168        * (or a parent of the window <code>InputMap</code>)
 2169        * the <code>KeyboardManager</code> is notified of the new bindings.
 2170        *
 2171        * @param inputMap the map containing the new bindings
 2172        */
 2173       void componentInputMapChanged(ComponentInputMap inputMap) {
 2174           InputMap km = getInputMap(WHEN_IN_FOCUSED_WINDOW, false);
 2175   
 2176           while (km != inputMap && km != null) {
 2177               km = (ComponentInputMap)km.getParent();
 2178           }
 2179           if (km != null) {
 2180               registerWithKeyboardManager(false);
 2181           }
 2182       }
 2183   
 2184       private void registerWithKeyboardManager(KeyStroke aKeyStroke) {
 2185           KeyboardManager.getCurrentManager().registerKeyStroke(aKeyStroke,this);
 2186       }
 2187   
 2188       private void unregisterWithKeyboardManager(KeyStroke aKeyStroke) {
 2189           KeyboardManager.getCurrentManager().unregisterKeyStroke(aKeyStroke,
 2190                                                                   this);
 2191       }
 2192   
 2193       /**
 2194        * This method is now obsolete, please use a combination of
 2195        * <code>getActionMap()</code> and <code>getInputMap()</code> for
 2196        * similiar behavior.
 2197        */
 2198       public void registerKeyboardAction(ActionListener anAction,KeyStroke aKeyStroke,int aCondition) {
 2199           registerKeyboardAction(anAction,null,aKeyStroke,aCondition);
 2200       }
 2201   
 2202       /**
 2203        * This method is now obsolete. To unregister an existing binding
 2204        * you can either remove the binding from the
 2205        * <code>ActionMap/InputMap</code>, or place a dummy binding the
 2206        * <code>InputMap</code>. Removing the binding from the
 2207        * <code>InputMap</code> allows bindings in parent <code>InputMap</code>s
 2208        * to be active, whereas putting a dummy binding in the
 2209        * <code>InputMap</code> effectively disables
 2210        * the binding from ever happening.
 2211        * <p>
 2212        * Unregisters a keyboard action.
 2213        * This will remove the binding from the <code>ActionMap</code>
 2214        * (if it exists) as well as the <code>InputMap</code>s.
 2215        */
 2216       public void unregisterKeyboardAction(KeyStroke aKeyStroke) {
 2217           ActionMap am = getActionMap(false);
 2218           for (int counter = 0; counter < 3; counter++) {
 2219               InputMap km = getInputMap(counter, false);
 2220               if (km != null) {
 2221                   Object actionID = km.get(aKeyStroke);
 2222   
 2223                   if (am != null && actionID != null) {
 2224                       am.remove(actionID);
 2225                   }
 2226                   km.remove(aKeyStroke);
 2227               }
 2228           }
 2229       }
 2230   
 2231       /**
 2232        * Returns the <code>KeyStrokes</code> that will initiate
 2233        * registered actions.
 2234        *
 2235        * @return an array of <code>KeyStroke</code> objects
 2236        * @see #registerKeyboardAction
 2237        */
 2238       public KeyStroke[] getRegisteredKeyStrokes() {
 2239           int[] counts = new int[3];
 2240           KeyStroke[][] strokes = new KeyStroke[3][];
 2241   
 2242           for (int counter = 0; counter < 3; counter++) {
 2243               InputMap km = getInputMap(counter, false);
 2244               strokes[counter] = (km != null) ? km.allKeys() : null;
 2245               counts[counter] = (strokes[counter] != null) ?
 2246                                  strokes[counter].length : 0;
 2247           }
 2248           KeyStroke[] retValue = new KeyStroke[counts[0] + counts[1] +
 2249                                               counts[2]];
 2250           for (int counter = 0, last = 0; counter < 3; counter++) {
 2251               if (counts[counter] > 0) {
 2252                   System.arraycopy(strokes[counter], 0, retValue, last,
 2253                                    counts[counter]);
 2254                   last += counts[counter];
 2255               }
 2256           }
 2257           return retValue;
 2258       }
 2259   
 2260       /**
 2261        * Returns the condition that determines whether a registered action
 2262        * occurs in response to the specified keystroke.
 2263        * <p>
 2264        * For Java 2 platform v1.3, a <code>KeyStroke</code> can be associated
 2265        * with more than one condition.
 2266        * For example, 'a' could be bound for the two
 2267        * conditions <code>WHEN_FOCUSED</code> and
 2268        * <code>WHEN_IN_FOCUSED_WINDOW</code> condition.
 2269        *
 2270        * @return the action-keystroke condition
 2271        */
 2272       public int getConditionForKeyStroke(KeyStroke aKeyStroke) {
 2273           for (int counter = 0; counter < 3; counter++) {
 2274               InputMap inputMap = getInputMap(counter, false);
 2275               if (inputMap != null && inputMap.get(aKeyStroke) != null) {
 2276                   return counter;
 2277               }
 2278           }
 2279           return UNDEFINED_CONDITION;
 2280