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