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