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