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