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