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