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 = validateAlignment(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 = validateAlignment(alignmentX);
1921         isAlignmentXSet = true;
1922     }
1923 
1924     private float validateAlignment(float alignment) {
1925         return alignment > 1.0f ? 1.0f : alignment < 0.0f ? 0.0f : alignment;
1926     }
1927 
1928     /**
1929      * Sets the input verifier for this component.
1930      *
1931      * @param inputVerifier the new input verifier
1932      * @since 1.3
1933      * @see InputVerifier
1934      * @beaninfo
1935      *       bound: true
1936      * description: The component's input verifier.
1937      */
1938     public void setInputVerifier(InputVerifier inputVerifier) {
1939         InputVerifier oldInputVerifier = (InputVerifier)getClientProperty(
1940                                          JComponent_INPUT_VERIFIER);
1941         putClientProperty(JComponent_INPUT_VERIFIER, inputVerifier);
1942         firePropertyChange("inputVerifier", oldInputVerifier, inputVerifier);
1943     }
1944 
1945     /**
1946      * Returns the input verifier for this component.
1947      *
1948      * @return the <code>inputVerifier</code> property
1949      * @since 1.3
1950      * @see InputVerifier
1951      */
1952     public InputVerifier getInputVerifier() {
1953         return (InputVerifier)getClientProperty(JComponent_INPUT_VERIFIER);
1954     }
1955 
1956     /**
1957      * Returns this component's graphics context, which lets you draw
1958      * on a component. Use this method to get a <code>Graphics</code> object and
1959      * then invoke operations on that object to draw on the component.
1960      * @return this components graphics context
1961      */
1962     public Graphics getGraphics() {
1963         if (DEBUG_GRAPHICS_LOADED && shouldDebugGraphics() != 0) {
1964             DebugGraphics graphics = new DebugGraphics(super.getGraphics(),
1965                                                        this);
1966             return graphics;
1967         }
1968         return super.getGraphics();
1969     }
1970 
1971 
1972     /** Enables or disables diagnostic information about every graphics
1973       * operation performed within the component or one of its children.
1974       *
1975       * @param debugOptions  determines how the component should display
1976       *         the information;  one of the following options:
1977       * <ul>
1978       * <li>DebugGraphics.LOG_OPTION - causes a text message to be printed.
1979       * <li>DebugGraphics.FLASH_OPTION - causes the drawing to flash several
1980       * times.
1981       * <li>DebugGraphics.BUFFERED_OPTION - creates an
1982       *         <code>ExternalWindow</code> that displays the operations
1983       *         performed on the View's offscreen buffer.
1984       * <li>DebugGraphics.NONE_OPTION disables debugging.
1985       * <li>A value of 0 causes no changes to the debugging options.
1986       * </ul>
1987       * <code>debugOptions</code> is bitwise OR'd into the current value
1988       *
1989       * @beaninfo
1990       *   preferred: true
1991       *        enum: NONE_OPTION DebugGraphics.NONE_OPTION
1992       *              LOG_OPTION DebugGraphics.LOG_OPTION
1993       *              FLASH_OPTION DebugGraphics.FLASH_OPTION
1994       *              BUFFERED_OPTION DebugGraphics.BUFFERED_OPTION
1995       * description: Diagnostic options for graphics operations.
1996       */
1997     public void setDebugGraphicsOptions(int debugOptions) {
1998         DebugGraphics.setDebugOptions(this, debugOptions);
1999     }
2000 
2001     /** Returns the state of graphics debugging.
2002       *
2003       * @return a bitwise OR'd flag of zero or more of the following options:
2004       * <ul>
2005       * <li>DebugGraphics.LOG_OPTION - causes a text message to be printed.
2006       * <li>DebugGraphics.FLASH_OPTION - causes the drawing to flash several
2007       * times.
2008       * <li>DebugGraphics.BUFFERED_OPTION - creates an
2009       *         <code>ExternalWindow</code> that displays the operations
2010       *         performed on the View's offscreen buffer.
2011       * <li>DebugGraphics.NONE_OPTION disables debugging.
2012       * <li>A value of 0 causes no changes to the debugging options.
2013       * </ul>
2014       * @see #setDebugGraphicsOptions
2015       */
2016     public int getDebugGraphicsOptions() {
2017         return DebugGraphics.getDebugOptions(this);
2018     }
2019 
2020 
2021     /**
2022      * Returns true if debug information is enabled for this
2023      * <code>JComponent</code> or one of its parents.
2024      */
2025     int shouldDebugGraphics() {
2026         return DebugGraphics.shouldComponentDebug(this);
2027     }
2028 
2029     /**
2030      * This method is now obsolete, please use a combination of
2031      * <code>getActionMap()</code> and <code>getInputMap()</code> for
2032      * similar behavior. For example, to bind the <code>KeyStroke</code>
2033      * <code>aKeyStroke</code> to the <code>Action</code> <code>anAction</code>
2034      * now use:
2035      * <pre>
2036      *   component.getInputMap().put(aKeyStroke, aCommand);
2037      *   component.getActionMap().put(aCommmand, anAction);
2038      * </pre>
2039      * The above assumes you want the binding to be applicable for
2040      * <code>WHEN_FOCUSED</code>. To register bindings for other focus
2041      * states use the <code>getInputMap</code> method that takes an integer.
2042      * <p>
2043      * Register a new keyboard action.
2044      * <code>anAction</code> will be invoked if a key event matching
2045      * <code>aKeyStroke</code> occurs and <code>aCondition</code> is verified.
2046      * The <code>KeyStroke</code> object defines a
2047      * particular combination of a keyboard key and one or more modifiers
2048      * (alt, shift, ctrl, meta).
2049      * <p>
2050      * The <code>aCommand</code> will be set in the delivered event if
2051      * specified.
2052      * <p>
2053      * The <code>aCondition</code> can be one of:
2054      * <blockquote>
2055      * <DL>
2056      * <DT>WHEN_FOCUSED
2057      * <DD>The action will be invoked only when the keystroke occurs
2058      *     while the component has the focus.
2059      * <DT>WHEN_IN_FOCUSED_WINDOW
2060      * <DD>The action will be invoked when the keystroke occurs while
2061      *     the component has the focus or if the component is in the
2062      *     window that has the focus. Note that the component need not
2063      *     be an immediate descendent of the window -- it can be
2064      *     anywhere in the window's containment hierarchy. In other
2065      *     words, whenever <em>any</em> component in the window has the focus,
2066      *     the action registered with this component is invoked.
2067      * <DT>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
2068      * <DD>The action will be invoked when the keystroke occurs while the
2069      *     component has the focus or if the component is an ancestor of
2070      *     the component that has the focus.
2071      * </DL>
2072      * </blockquote>
2073      * <p>
2074      * The combination of keystrokes and conditions lets you define high
2075      * level (semantic) action events for a specified keystroke+modifier
2076      * combination (using the KeyStroke class) and direct to a parent or
2077      * child of a component that has the focus, or to the component itself.
2078      * In other words, in any hierarchical structure of components, an
2079      * arbitrary key-combination can be immediately directed to the
2080      * appropriate component in the hierarchy, and cause a specific method
2081      * to be invoked (usually by way of adapter objects).
2082      * <p>
2083      * If an action has already been registered for the receiving
2084      * container, with the same charCode and the same modifiers,
2085      * <code>anAction</code> will replace the action.
2086      *
2087      * @param anAction  the <code>Action</code> to be registered
2088      * @param aCommand  the command to be set in the delivered event
2089      * @param aKeyStroke the <code>KeyStroke</code> to bind to the action
2090      * @param aCondition the condition that needs to be met, see above
2091      * @see KeyStroke
2092      */
2093     public void registerKeyboardAction(ActionListener anAction,String aCommand,KeyStroke aKeyStroke,int aCondition) {
2094 
2095         InputMap inputMap = getInputMap(aCondition, true);
2096 
2097         if (inputMap != null) {
2098             ActionMap actionMap = getActionMap(true);
2099             ActionStandin action = new ActionStandin(anAction, aCommand);
2100             inputMap.put(aKeyStroke, action);
2101             if (actionMap != null) {
2102                 actionMap.put(action, action);
2103             }
2104         }
2105     }
2106 
2107     /**
2108      * Registers any bound <code>WHEN_IN_FOCUSED_WINDOW</code> actions with
2109      * the <code>KeyboardManager</code>. If <code>onlyIfNew</code>
2110      * is true only actions that haven't been registered are pushed
2111      * to the <code>KeyboardManager</code>;
2112      * otherwise all actions are pushed to the <code>KeyboardManager</code>.
2113      *
2114      * @param onlyIfNew  if true, only actions that haven't been registered
2115      *          are pushed to the <code>KeyboardManager</code>
2116      */
2117     private void registerWithKeyboardManager(boolean onlyIfNew) {
2118         InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW, false);
2119         KeyStroke[] strokes;
2120         @SuppressWarnings("unchecked")
2121         Hashtable<KeyStroke, KeyStroke> registered =
2122                 (Hashtable<KeyStroke, KeyStroke>)getClientProperty
2123                                 (WHEN_IN_FOCUSED_WINDOW_BINDINGS);
2124 
2125         if (inputMap != null) {
2126             // Push any new KeyStrokes to the KeyboardManager.
2127             strokes = inputMap.allKeys();
2128             if (strokes != null) {
2129                 for (int counter = strokes.length - 1; counter >= 0;
2130                      counter--) {
2131                     if (!onlyIfNew || registered == null ||
2132                         registered.get(strokes[counter]) == null) {
2133                         registerWithKeyboardManager(strokes[counter]);
2134                     }
2135                     if (registered != null) {
2136                         registered.remove(strokes[counter]);
2137                     }
2138                 }
2139             }
2140         }
2141         else {
2142             strokes = null;
2143         }
2144         // Remove any old ones.
2145         if (registered != null && registered.size() > 0) {
2146             Enumeration<KeyStroke> keys = registered.keys();
2147 
2148             while (keys.hasMoreElements()) {
2149                 KeyStroke ks = keys.nextElement();
2150                 unregisterWithKeyboardManager(ks);
2151             }
2152             registered.clear();
2153         }
2154         // Updated the registered Hashtable.
2155         if (strokes != null && strokes.length > 0) {
2156             if (registered == null) {
2157                 registered = new Hashtable<KeyStroke, KeyStroke>(strokes.length);
2158                 putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, registered);
2159             }
2160             for (int counter = strokes.length - 1; counter >= 0; counter--) {
2161                 registered.put(strokes[counter], strokes[counter]);
2162             }
2163         }
2164         else {
2165             putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, null);
2166         }
2167     }
2168 
2169     /**
2170      * Unregisters all the previously registered
2171      * <code>WHEN_IN_FOCUSED_WINDOW</code> <code>KeyStroke</code> bindings.
2172      */
2173     private void unregisterWithKeyboardManager() {
2174         @SuppressWarnings("unchecked")
2175         Hashtable<KeyStroke, KeyStroke> registered =
2176                 (Hashtable<KeyStroke, KeyStroke>)getClientProperty
2177                                 (WHEN_IN_FOCUSED_WINDOW_BINDINGS);
2178 
2179         if (registered != null && registered.size() > 0) {
2180             Enumeration<KeyStroke> keys = registered.keys();
2181 
2182             while (keys.hasMoreElements()) {
2183                 KeyStroke ks = keys.nextElement();
2184                 unregisterWithKeyboardManager(ks);
2185             }
2186         }
2187         putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, null);
2188     }
2189 
2190     /**
2191      * Invoked from <code>ComponentInputMap</code> when its bindings change.
2192      * If <code>inputMap</code> is the current <code>windowInputMap</code>
2193      * (or a parent of the window <code>InputMap</code>)
2194      * the <code>KeyboardManager</code> is notified of the new bindings.
2195      *
2196      * @param inputMap the map containing the new bindings
2197      */
2198     void componentInputMapChanged(ComponentInputMap inputMap) {
2199         InputMap km = getInputMap(WHEN_IN_FOCUSED_WINDOW, false);
2200 
2201         while (km != inputMap && km != null) {
2202             km = km.getParent();
2203         }
2204         if (km != null) {
2205             registerWithKeyboardManager(false);
2206         }
2207     }
2208 
2209     private void registerWithKeyboardManager(KeyStroke aKeyStroke) {
2210         KeyboardManager.getCurrentManager().registerKeyStroke(aKeyStroke,this);
2211     }
2212 
2213     private void unregisterWithKeyboardManager(KeyStroke aKeyStroke) {
2214         KeyboardManager.getCurrentManager().unregisterKeyStroke(aKeyStroke,
2215                                                                 this);
2216     }
2217 
2218     /**
2219      * This method is now obsolete, please use a combination of
2220      * <code>getActionMap()</code> and <code>getInputMap()</code> for
2221      * similar behavior.
2222      *
2223      * @param anAction  action to be registered to given keystroke and condition
2224      * @param aKeyStroke  a {@code KeyStroke}
2225      * @param aCondition  the condition to be associated with given keystroke
2226      *                    and action
2227      * @see #getActionMap
2228      * @see #getInputMap(int)
2229      */
2230     public void registerKeyboardAction(ActionListener anAction,KeyStroke aKeyStroke,int aCondition) {
2231         registerKeyboardAction(anAction,null,aKeyStroke,aCondition);
2232     }
2233 
2234     /**
2235      * This method is now obsolete. To unregister an existing binding
2236      * you can either remove the binding from the
2237      * <code>ActionMap/InputMap</code>, or place a dummy binding the
2238      * <code>InputMap</code>. Removing the binding from the
2239      * <code>InputMap</code> allows bindings in parent <code>InputMap</code>s
2240      * to be active, whereas putting a dummy binding in the
2241      * <code>InputMap</code> effectively disables
2242      * the binding from ever happening.
2243      * <p>
2244      * Unregisters a keyboard action.
2245      * This will remove the binding from the <code>ActionMap</code>
2246      * (if it exists) as well as the <code>InputMap</code>s.
2247      *
2248      * @param aKeyStroke  the keystroke for which to unregister its
2249      *                    keyboard action
2250      */
2251     public void unregisterKeyboardAction(KeyStroke aKeyStroke) {
2252         ActionMap am = getActionMap(false);
2253         for (int counter = 0; counter < 3; counter++) {
2254             InputMap km = getInputMap(counter, false);
2255             if (km != null) {
2256                 Object actionID = km.get(aKeyStroke);
2257 
2258                 if (am != null && actionID != null) {
2259                     am.remove(actionID);
2260                 }
2261                 km.remove(aKeyStroke);
2262             }
2263         }
2264     }
2265 
2266     /**
2267      * Returns the <code>KeyStrokes</code> that will initiate
2268      * registered actions.
2269      *
2270      * @return an array of <code>KeyStroke</code> objects
2271      * @see #registerKeyboardAction
2272      */
2273     public KeyStroke[] getRegisteredKeyStrokes() {
2274         int[] counts = new int[3];
2275         KeyStroke[][] strokes = new KeyStroke[3][];
2276 
2277         for (int counter = 0; counter < 3; counter++) {
2278             InputMap km = getInputMap(counter, false);
2279             strokes[counter] = (km != null) ? km.allKeys() : null;
2280             counts[counter] = (strokes[counter] != null) ?
2281                                strokes[counter].length : 0;
2282         }
2283         KeyStroke[] retValue = new KeyStroke[counts[0] + counts[1] +
2284                                             counts[2]];
2285         for (int counter = 0, last = 0; counter < 3; counter++) {
2286             if (counts[counter] > 0) {
2287                 System.arraycopy(strokes[counter], 0, retValue, last,
2288                                  counts[counter]);
2289                 last += counts[counter];
2290             }
2291         }
2292         return retValue;
2293     }
2294 
2295     /**
2296      * Returns the condition that determines whether a registered action
2297      * occurs in response to the specified keystroke.
2298      * <p>
2299      * For Java 2 platform v1.3, a <code>KeyStroke</code> can be associated
2300      * with more than one condition.
2301      * For example, 'a' could be bound for the two
2302      * conditions <code>WHEN_FOCUSED</code> and
2303      * <code>WHEN_IN_FOCUSED_WINDOW</code> condition.
2304      *
2305      * @param aKeyStroke  the keystroke for which to request an
2306      *                    action-keystroke condition
2307      * @return the action-keystroke condition
2308      */
2309     public int getConditionForKeyStroke(KeyStroke aKeyStroke) {
2310         for (int counter = 0; counter < 3; counter++) {
2311             InputMap inputMap = getInputMap(counter, false);
2312             if (inputMap != null && inputMap.get(aKeyStroke) != null) {
2313                 return counter;
2314             }
2315         }
2316         return UNDEFINED_CONDITION;
2317     }
2318 
2319     /**
2320      * Returns the object that will perform the action registered for a
2321      * given keystroke.
2322      *
2323      * @param aKeyStroke  the keystroke for which to return a listener
2324      * @return the <code>ActionListener</code>
2325      *          object invoked when the keystroke occurs
2326      */
2327     public ActionListener getActionForKeyStroke(KeyStroke aKeyStroke) {
2328         ActionMap am = getActionMap(false);
2329 
2330         if (am == null) {
2331             return null;
2332         }
2333         for (int counter = 0; counter < 3; counter++) {
2334             InputMap inputMap = getInputMap(counter, false);
2335             if (inputMap != null) {
2336                 Object actionBinding = inputMap.get(aKeyStroke);
2337 
2338                 if (actionBinding != null) {
2339                     Action action = am.get(actionBinding);
2340                     if (action instanceof ActionStandin) {
2341                         return ((ActionStandin)action).actionListener;
2342                     }
2343                     return action;
2344                 }
2345             }
2346         }
2347         return null;
2348     }
2349 
2350     /**
2351      * Unregisters all the bindings in the first tier <code>InputMaps</code>
2352      * and <code>ActionMap</code>. This has the effect of removing any
2353      * local bindings, and allowing the bindings defined in parent
2354      * <code>InputMap/ActionMaps</code>
2355      * (the UI is usually defined in the second tier) to persist.
2356      */
2357     public void resetKeyboardActions() {
2358         // Keys
2359         for (int counter = 0; counter < 3; counter++) {
2360             InputMap inputMap = getInputMap(counter, false);
2361 
2362             if (inputMap != null) {
2363                 inputMap.clear();
2364             }
2365         }
2366 
2367         // Actions
2368         ActionMap am = getActionMap(false);
2369 
2370         if (am != null) {
2371             am.clear();
2372         }
2373     }
2374 
2375     /**
2376      * Sets the <code>InputMap</code> to use under the condition
2377      * <code>condition</code> to
2378      * <code>map</code>. A <code>null</code> value implies you
2379      * do not want any bindings to be used, even from the UI. This will
2380      * not reinstall the UI <code>InputMap</code> (if there was one).
2381      * <code>condition</code> has one of the following values:
2382      * <ul>
2383      * <li><code>WHEN_IN_FOCUSED_WINDOW</code>
2384      * <li><code>WHEN_FOCUSED</code>
2385      * <li><code>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT</code>
2386      * </ul>
2387      * If <code>condition</code> is <code>WHEN_IN_FOCUSED_WINDOW</code>
2388      * and <code>map</code> is not a <code>ComponentInputMap</code>, an
2389      * <code>IllegalArgumentException</code> will be thrown.
2390      * Similarly, if <code>condition</code> is not one of the values
2391      * listed, an <code>IllegalArgumentException</code> will be thrown.
2392      *
2393      * @param condition one of the values listed above
2394      * @param map  the <code>InputMap</code> to use for the given condition
2395      * @exception IllegalArgumentException if <code>condition</code> is
2396      *          <code>WHEN_IN_FOCUSED_WINDOW</code> and <code>map</code>
2397      *          is not an instance of <code>ComponentInputMap</code>; or
2398      *          if <code>condition</code> is not one of the legal values
2399      *          specified above
2400      * @since 1.3
2401      */
2402     public final void setInputMap(int condition, InputMap map) {
2403         switch (condition) {
2404         case WHEN_IN_FOCUSED_WINDOW:
2405             if (map != null && !(map instanceof ComponentInputMap)) {
2406                 throw new IllegalArgumentException("WHEN_IN_FOCUSED_WINDOW InputMaps must be of type ComponentInputMap");
2407             }
2408             windowInputMap = (ComponentInputMap)map;
2409             setFlag(WIF_INPUTMAP_CREATED, true);
2410             registerWithKeyboardManager(false);
2411             break;
2412         case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
2413             ancestorInputMap = map;
2414             setFlag(ANCESTOR_INPUTMAP_CREATED, true);
2415             break;
2416         case WHEN_FOCUSED:
2417             focusInputMap = map;
2418             setFlag(FOCUS_INPUTMAP_CREATED, true);
2419             break;
2420         default:
2421             throw new IllegalArgumentException("condition must be one of JComponent.WHEN_IN_FOCUSED_WINDOW, JComponent.WHEN_FOCUSED or JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT");
2422         }
2423     }
2424 
2425     /**
2426      * Returns the <code>InputMap</code> that is used during
2427      * <code>condition</code>.
2428      *
2429      * @param condition one of WHEN_IN_FOCUSED_WINDOW, WHEN_FOCUSED,
2430      *        WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
2431      * @return the <code>InputMap</code> for the specified
2432      *          <code>condition</code>
2433      * @since 1.3
2434      */
2435     public final InputMap getInputMap(int condition) {
2436         return getInputMap(condition, true);
2437     }
2438 
2439     /**
2440      * Returns the <code>InputMap</code> that is used when the
2441      * component has focus.
2442      * This is convenience method for <code>getInputMap(WHEN_FOCUSED)</code>.
2443      *
2444      * @return the <code>InputMap</code> used when the component has focus
2445      * @since 1.3
2446      */
2447     public final InputMap getInputMap() {
2448         return getInputMap(WHEN_FOCUSED, true);
2449     }
2450 
2451     /**
2452      * Sets the <code>ActionMap</code> to <code>am</code>. This does not set
2453      * the parent of the <code>am</code> to be the <code>ActionMap</code>
2454      * from the UI (if there was one), it is up to the caller to have done this.
2455      *
2456      * @param am  the new <code>ActionMap</code>
2457      * @since 1.3
2458      */
2459     public final void setActionMap(ActionMap am) {
2460         actionMap = am;
2461         setFlag(ACTIONMAP_CREATED, true);
2462     }
2463 
2464     /**
2465      * Returns the <code>ActionMap</code> used to determine what
2466      * <code>Action</code> to fire for particular <code>KeyStroke</code>
2467      * binding. The returned <code>ActionMap</code>, unless otherwise
2468      * set, will have the <code>ActionMap</code> from the UI set as the parent.
2469      *
2470      * @return the <code>ActionMap</code> containing the key/action bindings
2471      * @since 1.3
2472      */
2473     public final ActionMap getActionMap() {
2474         return getActionMap(true);
2475     }
2476 
2477     /**
2478      * Returns the <code>InputMap</code> to use for condition
2479      * <code>condition</code>.  If the <code>InputMap</code> hasn't
2480      * been created, and <code>create</code> is
2481      * true, it will be created.
2482      *
2483      * @param condition one of the following values:
2484      * <ul>
2485      * <li>JComponent.FOCUS_INPUTMAP_CREATED
2486      * <li>JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
2487      * <li>JComponent.WHEN_IN_FOCUSED_WINDOW
2488      * </ul>
2489      * @param create if true, create the <code>InputMap</code> if it
2490      *          is not already created
2491      * @return the <code>InputMap</code> for the given <code>condition</code>;
2492      *          if <code>create</code> is false and the <code>InputMap</code>
2493      *          hasn't been created, returns <code>null</code>
2494      * @exception IllegalArgumentException if <code>condition</code>
2495      *          is not one of the legal values listed above
2496      */
2497     final InputMap getInputMap(int condition, boolean create) {
2498         switch (condition) {
2499         case WHEN_FOCUSED:
2500             if (getFlag(FOCUS_INPUTMAP_CREATED)) {
2501                 return focusInputMap;
2502             }
2503             // Hasn't been created yet.
2504             if (create) {
2505                 InputMap km = new InputMap();
2506                 setInputMap(condition, km);
2507                 return km;
2508             }
2509             break;
2510         case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
2511             if (getFlag(ANCESTOR_INPUTMAP_CREATED)) {
2512                 return ancestorInputMap;
2513             }
2514             // Hasn't been created yet.
2515             if (create) {
2516                 InputMap km = new InputMap();
2517                 setInputMap(condition, km);
2518                 return km;
2519             }
2520             break;
2521         case WHEN_IN_FOCUSED_WINDOW:
2522             if (getFlag(WIF_INPUTMAP_CREATED)) {
2523                 return windowInputMap;
2524             }
2525             // Hasn't been created yet.
2526             if (create) {
2527                 ComponentInputMap km = new ComponentInputMap(this);
2528                 setInputMap(condition, km);
2529                 return km;
2530             }
2531             break;
2532         default:
2533             throw new IllegalArgumentException("condition must be one of JComponent.WHEN_IN_FOCUSED_WINDOW, JComponent.WHEN_FOCUSED or JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT");
2534         }
2535         return null;
2536     }
2537 
2538     /**
2539      * Finds and returns the appropriate <code>ActionMap</code>.
2540      *
2541      * @param create if true, create the <code>ActionMap</code> if it
2542      *          is not already created
2543      * @return the <code>ActionMap</code> for this component; if the
2544      *          <code>create</code> flag is false and there is no
2545      *          current <code>ActionMap</code>, returns <code>null</code>
2546      */
2547     final ActionMap getActionMap(boolean create) {
2548         if (getFlag(ACTIONMAP_CREATED)) {
2549             return actionMap;
2550         }
2551         // Hasn't been created.
2552         if (create) {
2553             ActionMap am = new ActionMap();
2554             setActionMap(am);
2555             return am;
2556         }
2557         return null;
2558     }
2559 
2560     /**
2561      * Returns the baseline.  The baseline is measured from the top of
2562      * the component.  This method is primarily meant for
2563      * <code>LayoutManager</code>s to align components along their
2564      * baseline.  A return value less than 0 indicates this component
2565      * does not have a reasonable baseline and that
2566      * <code>LayoutManager</code>s should not align this component on
2567      * its baseline.
2568      * <p>
2569      * This method calls into the <code>ComponentUI</code> method of the
2570      * same name.  If this component does not have a <code>ComponentUI</code>
2571      * -1 will be returned.  If a value &gt;= 0 is
2572      * returned, then the component has a valid baseline for any
2573      * size &gt;= the minimum size and <code>getBaselineResizeBehavior</code>
2574      * can be used to determine how the baseline changes with size.
2575      *
2576      * @throws IllegalArgumentException {@inheritDoc}
2577      * @see #getBaselineResizeBehavior
2578      * @see java.awt.FontMetrics
2579      * @since 1.6
2580      */
2581     public int getBaseline(int width, int height) {
2582         // check size.
2583         super.getBaseline(width, height);
2584         if (ui != null) {
2585             return ui.getBaseline(this, width, height);
2586         }
2587         return -1;
2588     }
2589 
2590     /**
2591      * Returns an enum indicating how the baseline of the component
2592      * changes as the size changes.  This method is primarily meant for
2593      * layout managers and GUI builders.
2594      * <p>
2595      * This method calls into the <code>ComponentUI</code> method of
2596      * the same name.  If this component does not have a
2597      * <code>ComponentUI</code>
2598      * <code>BaselineResizeBehavior.OTHER</code> will be
2599      * returned.  Subclasses should
2600      * never return <code>null</code>; if the baseline can not be
2601      * calculated return <code>BaselineResizeBehavior.OTHER</code>.  Callers
2602      * should first ask for the baseline using
2603      * <code>getBaseline</code> and if a value &gt;= 0 is returned use
2604      * this method.  It is acceptable for this method to return a
2605      * value other than <code>BaselineResizeBehavior.OTHER</code> even if
2606      * <code>getBaseline</code> returns a value less than 0.
2607      *
2608      * @see #getBaseline(int, int)
2609      * @since 1.6
2610      */
2611     public BaselineResizeBehavior getBaselineResizeBehavior() {
2612         if (ui != null) {
2613             return ui.getBaselineResizeBehavior(this);
2614         }
2615         return BaselineResizeBehavior.OTHER;
2616     }
2617 
2618     /**
2619      * In release 1.4, the focus subsystem was rearchitected.
2620      * For more information, see
2621      * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
2622      * How to Use the Focus Subsystem</a>,
2623      * a section in <em>The Java Tutorial</em>.
2624      * <p>
2625      * Requests focus on this <code>JComponent</code>'s
2626      * <code>FocusTraversalPolicy</code>'s default <code>Component</code>.
2627      * If this <code>JComponent</code> is a focus cycle root, then its
2628      * <code>FocusTraversalPolicy</code> is used. Otherwise, the
2629      * <code>FocusTraversalPolicy</code> of this <code>JComponent</code>'s
2630      * focus-cycle-root ancestor is used.
2631      *
2632      * @return true if this component can request to get the input focus,
2633      *              false if it can not
2634      * @see java.awt.FocusTraversalPolicy#getDefaultComponent
2635      * @deprecated As of 1.4, replaced by
2636      * <code>FocusTraversalPolicy.getDefaultComponent(Container).requestFocus()</code>
2637      */
2638     @Deprecated
2639     public boolean requestDefaultFocus() {
2640         Container nearestRoot =
2641             (isFocusCycleRoot()) ? this : getFocusCycleRootAncestor();
2642         if (nearestRoot == null) {
2643             return false;
2644         }
2645         Component comp = nearestRoot.getFocusTraversalPolicy().
2646             getDefaultComponent(nearestRoot);
2647         if (comp != null) {
2648             comp.requestFocus();
2649             return true;
2650         } else {
2651             return false;
2652         }
2653     }
2654 
2655     /**
2656      * Makes the component visible or invisible.
2657      * Overrides <code>Component.setVisible</code>.
2658      *
2659      * @param aFlag  true to make the component visible; false to
2660      *          make it invisible
2661      *
2662      * @beaninfo
2663      *    attribute: visualUpdate true
2664      */
2665     public void setVisible(boolean aFlag) {
2666         if (aFlag != isVisible()) {
2667             super.setVisible(aFlag);
2668             if (aFlag) {
2669                 Container parent = getParent();
2670                 if (parent != null) {
2671                     Rectangle r = getBounds();
2672                     parent.repaint(r.x, r.y, r.width, r.height);
2673                 }
2674                 revalidate();
2675             }
2676         }
2677     }
2678 
2679     /**
2680      * Sets whether or not this component is enabled.
2681      * A component that is enabled may respond to user input,
2682      * while a component that is not enabled cannot respond to
2683      * user input.  Some components may alter their visual
2684      * representation when they are disabled in order to
2685      * provide feedback to the user that they cannot take input.
2686      * <p>Note: Disabling a component does not disable its children.
2687      *
2688      * <p>Note: Disabling a lightweight component does not prevent it from
2689      * receiving MouseEvents.
2690      *
2691      * @param enabled true if this component should be enabled, false otherwise
2692      * @see java.awt.Component#isEnabled
2693      * @see java.awt.Component#isLightweight
2694      *
2695      * @beaninfo
2696      *    preferred: true
2697      *        bound: true
2698      *    attribute: visualUpdate true
2699      *  description: The enabled state of the component.
2700      */
2701     public void setEnabled(boolean enabled) {
2702         boolean oldEnabled = isEnabled();
2703         super.setEnabled(enabled);
2704         firePropertyChange("enabled", oldEnabled, enabled);
2705         if (enabled != oldEnabled) {
2706             repaint();
2707         }
2708     }
2709 
2710     /**
2711      * Sets the foreground color of this component.  It is up to the
2712      * look and feel to honor this property, some may choose to ignore
2713      * it.
2714      *
2715      * @param fg  the desired foreground <code>Color</code>
2716      * @see java.awt.Component#getForeground
2717      *
2718      * @beaninfo
2719      *    preferred: true
2720      *        bound: true
2721      *    attribute: visualUpdate true
2722      *  description: The foreground color of the component.
2723      */
2724     public void setForeground(Color fg) {
2725         Color oldFg = getForeground();
2726         super.setForeground(fg);
2727         if ((oldFg != null) ? !oldFg.equals(fg) : ((fg != null) && !fg.equals(oldFg))) {
2728             // foreground already bound in AWT1.2
2729             repaint();
2730         }
2731     }
2732 
2733     /**
2734      * Sets the background color of this component.  The background
2735      * color is used only if the component is opaque, and only
2736      * by subclasses of <code>JComponent</code> or
2737      * <code>ComponentUI</code> implementations.  Direct subclasses of
2738      * <code>JComponent</code> must override
2739      * <code>paintComponent</code> to honor this property.
2740      * <p>
2741      * It is up to the look and feel to honor this property, some may
2742      * choose to ignore it.
2743      *
2744      * @param bg the desired background <code>Color</code>
2745      * @see java.awt.Component#getBackground
2746      * @see #setOpaque
2747      *
2748      * @beaninfo
2749      *    preferred: true
2750      *        bound: true
2751      *    attribute: visualUpdate true
2752      *  description: The background color of the component.
2753      */
2754     public void setBackground(Color bg) {
2755         Color oldBg = getBackground();
2756         super.setBackground(bg);
2757         if ((oldBg != null) ? !oldBg.equals(bg) : ((bg != null) && !bg.equals(oldBg))) {
2758             // background already bound in AWT1.2
2759             repaint();
2760         }
2761     }
2762 
2763     /**
2764      * Sets the font for this component.
2765      *
2766      * @param font the desired <code>Font</code> for this component
2767      * @see java.awt.Component#getFont
2768      *
2769      * @beaninfo
2770      *    preferred: true
2771      *        bound: true
2772      *    attribute: visualUpdate true
2773      *  description: The font for the component.
2774      */
2775     public void setFont(Font font) {
2776         Font oldFont = getFont();
2777         super.setFont(font);
2778         // font already bound in AWT1.2
2779         if (font != oldFont) {
2780             revalidate();
2781             repaint();
2782         }
2783     }
2784 
2785     /**
2786      * Returns the default locale used to initialize each JComponent's
2787      * locale property upon creation.
2788      *
2789      * The default locale has "AppContext" scope so that applets (and
2790      * potentially multiple lightweight applications running in a single VM)
2791      * can have their own setting. An applet can safely alter its default
2792      * locale because it will have no affect on other applets (or the browser).
2793      *
2794      * @return the default <code>Locale</code>.
2795      * @see #setDefaultLocale
2796      * @see java.awt.Component#getLocale
2797      * @see #setLocale
2798      * @since 1.4
2799      */
2800     static public Locale getDefaultLocale() {
2801         Locale l = (Locale) SwingUtilities.appContextGet(defaultLocale);
2802         if( l == null ) {
2803             //REMIND(bcb) choosing the default value is more complicated
2804             //than this.
2805             l = Locale.getDefault();
2806             JComponent.setDefaultLocale( l );
2807         }
2808         return l;
2809     }
2810 
2811 
2812     /**
2813      * Sets the default locale used to initialize each JComponent's locale
2814      * property upon creation.  The initial value is the VM's default locale.
2815      *
2816      * The default locale has "AppContext" scope so that applets (and
2817      * potentially multiple lightweight applications running in a single VM)
2818      * can have their own setting. An applet can safely alter its default
2819      * locale because it will have no affect on other applets (or the browser).
2820      *
2821      * @param l the desired default <code>Locale</code> for new components.
2822      * @see #getDefaultLocale
2823      * @see java.awt.Component#getLocale
2824      * @see #setLocale
2825      * @since 1.4
2826      */
2827     static public void setDefaultLocale( Locale l ) {
2828         SwingUtilities.appContextPut(defaultLocale, l);
2829     }
2830 
2831 
2832     /**
2833      * Processes any key events that the component itself
2834      * recognizes.  This is called after the focus
2835      * manager and any interested listeners have been
2836      * given a chance to steal away the event.  This
2837      * method is called only if the event has not
2838      * yet been consumed.  This method is called prior
2839      * to the keyboard UI logic.
2840      * <p>
2841      * This method is implemented to do nothing.  Subclasses would
2842      * normally override this method if they process some
2843      * key events themselves.  If the event is processed,
2844      * it should be consumed.
2845      *
2846      * @param e the event to be processed
2847      */
2848     protected void processComponentKeyEvent(KeyEvent e) {
2849     }
2850 
2851     /** Overrides <code>processKeyEvent</code> to process events. **/
2852     protected void processKeyEvent(KeyEvent e) {
2853       boolean result;
2854       boolean shouldProcessKey;
2855 
2856       // This gives the key event listeners a crack at the event
2857       super.processKeyEvent(e);
2858 
2859       // give the component itself a crack at the event
2860       if (! e.isConsumed()) {
2861           processComponentKeyEvent(e);
2862       }
2863 
2864       shouldProcessKey = KeyboardState.shouldProcess(e);
2865 
2866       if(e.isConsumed()) {
2867         return;
2868       }
2869 
2870       if (shouldProcessKey && processKeyBindings(e, e.getID() ==
2871                                                  KeyEvent.KEY_PRESSED)) {
2872           e.consume();
2873       }
2874     }
2875 
2876     /**
2877      * Invoked to process the key bindings for <code>ks</code> as the result
2878      * of the <code>KeyEvent</code> <code>e</code>. This obtains
2879      * the appropriate <code>InputMap</code>,
2880      * gets the binding, gets the action from the <code>ActionMap</code>,
2881      * and then (if the action is found and the component
2882      * is enabled) invokes <code>notifyAction</code> to notify the action.
2883      *
2884      * @param ks  the <code>KeyStroke</code> queried
2885      * @param e the <code>KeyEvent</code>
2886      * @param condition one of the following values:
2887      * <ul>
2888      * <li>JComponent.WHEN_FOCUSED
2889      * <li>JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
2890      * <li>JComponent.WHEN_IN_FOCUSED_WINDOW
2891      * </ul>
2892      * @param pressed true if the key is pressed
2893      * @return true if there was a binding to an action, and the action
2894      *         was enabled
2895      *
2896      * @since 1.3
2897      */
2898     protected boolean processKeyBinding(KeyStroke ks, KeyEvent e,
2899                                         int condition, boolean pressed) {
2900         InputMap map = getInputMap(condition, false);
2901         ActionMap am = getActionMap(false);
2902 
2903         if(map != null && am != null && isEnabled()) {
2904             Object binding = map.get(ks);
2905             Action action = (binding == null) ? null : am.get(binding);
2906             if (action != null) {
2907                 return SwingUtilities.notifyAction(action, ks, e, this,
2908                                                    e.getModifiers());
2909             }
2910         }
2911         return false;
2912     }
2913 
2914     /**
2915      * This is invoked as the result of a <code>KeyEvent</code>
2916      * that was not consumed by the <code>FocusManager</code>,
2917      * <code>KeyListeners</code>, or the component. It will first try
2918      * <code>WHEN_FOCUSED</code> bindings,
2919      * then <code>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT</code> bindings,
2920      * and finally <code>WHEN_IN_FOCUSED_WINDOW</code> bindings.
2921      *
2922      * @param e the unconsumed <code>KeyEvent</code>
2923      * @param pressed true if the key is pressed
2924      * @return true if there is a key binding for <code>e</code>
2925      */
2926     boolean processKeyBindings(KeyEvent e, boolean pressed) {
2927       if (!SwingUtilities.isValidKeyEventForKeyBindings(e)) {
2928           return false;
2929       }
2930       // Get the KeyStroke
2931       // There may be two keystrokes associated with a low-level key event;
2932       // in this case a keystroke made of an extended key code has a priority.
2933       KeyStroke ks;
2934       KeyStroke ksE = null;
2935 
2936       if (e.getID() == KeyEvent.KEY_TYPED) {
2937           ks = KeyStroke.getKeyStroke(e.getKeyChar());
2938       }
2939       else {
2940           ks = KeyStroke.getKeyStroke(e.getKeyCode(),e.getModifiers(),
2941                                     (pressed ? false:true));
2942           if (e.getKeyCode() != e.getExtendedKeyCode()) {
2943               ksE = KeyStroke.getKeyStroke(e.getExtendedKeyCode(),e.getModifiers(),
2944                                     (pressed ? false:true));
2945           }
2946       }
2947 
2948       // Do we have a key binding for e?
2949       // If we have a binding by an extended code, use it.
2950       // If not, check for regular code binding.
2951       if(ksE != null && processKeyBinding(ksE, e, WHEN_FOCUSED, pressed)) {
2952           return true;
2953       }
2954       if(processKeyBinding(ks, e, WHEN_FOCUSED, pressed))
2955           return true;
2956 
2957       /* We have no key binding. Let's try the path from our parent to the
2958        * window excluded. We store the path components so we can avoid
2959        * asking the same component twice.
2960        */
2961       Container parent = this;
2962       while (parent != null && !(parent instanceof Window) &&
2963              !(parent instanceof Applet)) {
2964           if(parent instanceof JComponent) {
2965               if(ksE != null && ((JComponent)parent).processKeyBinding(ksE, e,
2966                                WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed))
2967                   return true;
2968               if(((JComponent)parent).processKeyBinding(ks, e,
2969                                WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed))
2970                   return true;
2971           }
2972           // This is done so that the children of a JInternalFrame are
2973           // given precedence for WHEN_IN_FOCUSED_WINDOW bindings before
2974           // other components WHEN_IN_FOCUSED_WINDOW bindings. This also gives
2975           // more precedence to the WHEN_IN_FOCUSED_WINDOW bindings of the
2976           // JInternalFrame's children vs the
2977           // WHEN_ANCESTOR_OF_FOCUSED_COMPONENT bindings of the parents.
2978           // maybe generalize from JInternalFrame (like isFocusCycleRoot).
2979           if ((parent instanceof JInternalFrame) &&
2980               JComponent.processKeyBindingsForAllComponents(e,parent,pressed)){
2981               return true;
2982           }
2983           parent = parent.getParent();
2984       }
2985 
2986       /* No components between the focused component and the window is
2987        * actually interested by the key event. Let's try the other
2988        * JComponent in this window.
2989        */
2990       if(parent != null) {
2991         return JComponent.processKeyBindingsForAllComponents(e,parent,pressed);
2992       }
2993       return false;
2994     }
2995 
2996     static boolean processKeyBindingsForAllComponents(KeyEvent e,
2997                                       Container container, boolean pressed) {
2998         while (true) {
2999             if (KeyboardManager.getCurrentManager().fireKeyboardAction(
3000                                 e, pressed, container)) {
3001                 return true;
3002             }
3003             if (container instanceof Popup.HeavyWeightWindow) {
3004                 container = ((Window)container).getOwner();
3005             }
3006             else {
3007                 return false;
3008             }
3009         }
3010     }
3011 
3012     /**
3013      * Registers the text to display in a tool tip.
3014      * The text displays when the cursor lingers over the component.
3015      * <p>
3016      * See <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/tooltip.html">How to Use Tool Tips</a>
3017      * in <em>The Java Tutorial</em>
3018      * for further documentation.
3019      *
3020      * @param text  the string to display; if the text is <code>null</code>,
3021      *              the tool tip is turned off for this component
3022      * @see #TOOL_TIP_TEXT_KEY
3023      * @beaninfo
3024      *   preferred: true
3025      * description: The text to display in a tool tip.
3026      */
3027     public void setToolTipText(String text) {
3028         String oldText = getToolTipText();
3029         putClientProperty(TOOL_TIP_TEXT_KEY, text);
3030         ToolTipManager toolTipManager = ToolTipManager.sharedInstance();
3031         if (text != null) {
3032             if (oldText == null) {
3033                 toolTipManager.registerComponent(this);
3034             }
3035         } else {
3036             toolTipManager.unregisterComponent(this);
3037         }
3038     }
3039 
3040     /**
3041      * Returns the tooltip string that has been set with
3042      * <code>setToolTipText</code>.
3043      *
3044      * @return the text of the tool tip
3045      * @see #TOOL_TIP_TEXT_KEY
3046      */
3047     public String getToolTipText() {
3048         return (String)getClientProperty(TOOL_TIP_TEXT_KEY);
3049     }
3050 
3051 
3052     /**
3053      * Returns the string to be used as the tooltip for <i>event</i>.
3054      * By default this returns any string set using
3055      * <code>setToolTipText</code>.  If a component provides
3056      * more extensive API to support differing tooltips at different locations,
3057      * this method should be overridden.
3058      *
3059      * @param event the {@code MouseEvent} that initiated the
3060      *              {@code ToolTip} display
3061      * @return a string containing the  tooltip
3062      */
3063     public String getToolTipText(MouseEvent event) {
3064         return getToolTipText();
3065     }
3066 
3067     /**
3068      * Returns the tooltip location in this component's coordinate system.
3069      * If <code>null</code> is returned, Swing will choose a location.
3070      * The default implementation returns <code>null</code>.
3071      *
3072      * @param event  the <code>MouseEvent</code> that caused the
3073      *          <code>ToolTipManager</code> to show the tooltip
3074      * @return always returns <code>null</code>
3075      */
3076     public Point getToolTipLocation(MouseEvent event) {
3077         return null;
3078     }
3079 
3080     /**
3081      * Returns the preferred location to display the popup menu in this
3082      * component's coordinate system. It is up to the look and feel to
3083      * honor this property, some may choose to ignore it.
3084      * If {@code null}, the look and feel will choose a suitable location.
3085      *
3086      * @param event the {@code MouseEvent} that triggered the popup to be
3087      *        shown, or {@code null} if the popup is not being shown as the
3088      *        result of a mouse event
3089      * @return location to display the {@code JPopupMenu}, or {@code null}
3090      * @since 1.5
3091      */
3092     public Point getPopupLocation(MouseEvent event) {
3093         return null;
3094     }
3095 
3096 
3097     /**
3098      * Returns the instance of <code>JToolTip</code> that should be used
3099      * to display the tooltip.
3100      * Components typically would not override this method,
3101      * but it can be used to
3102      * cause different tooltips to be displayed differently.
3103      *
3104      * @return the <code>JToolTip</code> used to display this toolTip
3105      */
3106     public JToolTip createToolTip() {
3107         JToolTip tip = new JToolTip();
3108         tip.setComponent(this);
3109         return tip;
3110     }
3111 
3112     /**
3113      * Forwards the <code>scrollRectToVisible()</code> message to the
3114      * <code>JComponent</code>'s parent. Components that can service
3115      * the request, such as <code>JViewport</code>,
3116      * override this method and perform the scrolling.
3117      *
3118      * @param aRect the visible <code>Rectangle</code>
3119      * @see JViewport
3120      */
3121     public void scrollRectToVisible(Rectangle aRect) {
3122         Container parent;
3123         int dx = getX(), dy = getY();
3124 
3125         for (parent = getParent();
3126                  !(parent == null) &&
3127                  !(parent instanceof JComponent) &&
3128                  !(parent instanceof CellRendererPane);
3129              parent = parent.getParent()) {
3130              Rectangle bounds = parent.getBounds();
3131 
3132              dx += bounds.x;
3133              dy += bounds.y;
3134         }
3135 
3136         if (!(parent == null) && !(parent instanceof CellRendererPane)) {
3137             aRect.x += dx;
3138             aRect.y += dy;
3139 
3140             ((JComponent)parent).scrollRectToVisible(aRect);
3141             aRect.x -= dx;
3142             aRect.y -= dy;
3143         }
3144     }
3145 
3146     /**
3147      * Sets the <code>autoscrolls</code> property.
3148      * If <code>true</code> mouse dragged events will be
3149      * synthetically generated when the mouse is dragged
3150      * outside of the component's bounds and mouse motion
3151      * has paused (while the button continues to be held
3152      * down). The synthetic events make it appear that the
3153      * drag gesture has resumed in the direction established when
3154      * the component's boundary was crossed.  Components that
3155      * support autoscrolling must handle <code>mouseDragged</code>
3156      * events by calling <code>scrollRectToVisible</code> with a
3157      * rectangle that contains the mouse event's location.  All of
3158      * the Swing components that support item selection and are
3159      * typically displayed in a <code>JScrollPane</code>
3160      * (<code>JTable</code>, <code>JList</code>, <code>JTree</code>,
3161      * <code>JTextArea</code>, and <code>JEditorPane</code>)
3162      * already handle mouse dragged events in this way.  To enable
3163      * autoscrolling in any other component, add a mouse motion
3164      * listener that calls <code>scrollRectToVisible</code>.
3165      * For example, given a <code>JPanel</code>, <code>myPanel</code>:
3166      * <pre>
3167      * MouseMotionListener doScrollRectToVisible = new MouseMotionAdapter() {
3168      *     public void mouseDragged(MouseEvent e) {
3169      *        Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1);
3170      *        ((JPanel)e.getSource()).scrollRectToVisible(r);
3171      *    }
3172      * };
3173      * myPanel.addMouseMotionListener(doScrollRectToVisible);
3174      * </pre>
3175      * The default value of the <code>autoScrolls</code>
3176      * property is <code>false</code>.
3177      *
3178      * @param autoscrolls if true, synthetic mouse dragged events
3179      *   are generated when the mouse is dragged outside of a component's
3180      *   bounds and the mouse button continues to be held down; otherwise
3181      *   false
3182      * @see #getAutoscrolls
3183      * @see JViewport
3184      * @see JScrollPane
3185      *
3186      * @beaninfo
3187      *      expert: true
3188      * description: Determines if this component automatically scrolls its contents when dragged.
3189      */
3190     public void setAutoscrolls(boolean autoscrolls) {
3191         setFlag(AUTOSCROLLS_SET, true);
3192         if (this.autoscrolls != autoscrolls) {
3193             this.autoscrolls = autoscrolls;
3194             if (autoscrolls) {
3195                 enableEvents(AWTEvent.MOUSE_EVENT_MASK);
3196                 enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
3197             }
3198             else {
3199                 Autoscroller.stop(this);
3200             }
3201         }
3202     }
3203 
3204     /**
3205      * Gets the <code>autoscrolls</code> property.
3206      *
3207      * @return the value of the <code>autoscrolls</code> property
3208      * @see JViewport
3209      * @see #setAutoscrolls
3210      */
3211     public boolean getAutoscrolls() {
3212         return autoscrolls;
3213     }
3214 
3215     /**
3216      * Sets the {@code TransferHandler}, which provides support for transfer
3217      * of data into and out of this component via cut/copy/paste and drag
3218      * and drop. This may be {@code null} if the component does not support
3219      * data transfer operations.
3220      * <p>
3221      * If the new {@code TransferHandler} is not {@code null}, this method
3222      * also installs a <b>new</b> {@code DropTarget} on the component to
3223      * activate drop handling through the {@code TransferHandler} and activate
3224      * any built-in support (such as calculating and displaying potential drop
3225      * locations). If you do not wish for this component to respond in any way
3226      * to drops, you can disable drop support entirely either by removing the
3227      * drop target ({@code setDropTarget(null)}) or by de-activating it
3228      * ({@code getDropTaget().setActive(false)}).
3229      * <p>
3230      * If the new {@code TransferHandler} is {@code null}, this method removes
3231      * the drop target.
3232      * <p>
3233      * Under two circumstances, this method does not modify the drop target:
3234      * First, if the existing drop target on this component was explicitly
3235      * set by the developer to a {@code non-null} value. Second, if the
3236      * system property {@code suppressSwingDropSupport} is {@code true}. The
3237      * default value for the system property is {@code false}.
3238      * <p>
3239      * Please see
3240      * <a href="http://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
3241      * How to Use Drag and Drop and Data Transfer</a>,
3242      * a section in <em>The Java Tutorial</em>, for more information.
3243      *
3244      * @param newHandler the new {@code TransferHandler}
3245      *
3246      * @see TransferHandler
3247      * @see #getTransferHandler
3248      * @since 1.4
3249      * @beaninfo
3250      *        bound: true
3251      *       hidden: true
3252      *  description: Mechanism for transfer of data to and from the component
3253      */
3254     public void setTransferHandler(TransferHandler newHandler) {
3255         TransferHandler oldHandler = (TransferHandler)getClientProperty(
3256                                       JComponent_TRANSFER_HANDLER);
3257         putClientProperty(JComponent_TRANSFER_HANDLER, newHandler);
3258 
3259         SwingUtilities.installSwingDropTargetAsNecessary(this, newHandler);
3260         firePropertyChange("transferHandler", oldHandler, newHandler);
3261     }
3262 
3263     /**
3264      * Gets the <code>transferHandler</code> property.
3265      *
3266      * @return  the value of the <code>transferHandler</code> property
3267      *
3268      * @see TransferHandler
3269      * @see #setTransferHandler
3270      * @since 1.4
3271      */
3272     public TransferHandler getTransferHandler() {
3273         return (TransferHandler)getClientProperty(JComponent_TRANSFER_HANDLER);
3274     }
3275 
3276     /**
3277      * Calculates a custom drop location for this type of component,
3278      * representing where a drop at the given point should insert data.
3279      * <code>null</code> is returned if this component doesn't calculate
3280      * custom drop locations. In this case, <code>TransferHandler</code>
3281      * will provide a default <code>DropLocation</code> containing just
3282      * the point.
3283      *
3284      * @param p the point to calculate a drop location for
3285      * @return the drop location, or <code>null</code>
3286      */
3287     TransferHandler.DropLocation dropLocationForPoint(Point p) {
3288         return null;
3289     }
3290 
3291     /**
3292      * Called to set or clear the drop location during a DnD operation.
3293      * In some cases, the component may need to use its internal selection
3294      * temporarily to indicate the drop location. To help facilitate this,
3295      * this method returns and accepts as a parameter a state object.
3296      * This state object can be used to store, and later restore, the selection
3297      * state. Whatever this method returns will be passed back to it in
3298      * future calls, as the state parameter. If it wants the DnD system to
3299      * continue storing the same state, it must pass it back every time.
3300      * Here's how this is used:
3301      * <p>
3302      * Let's say that on the first call to this method the component decides
3303      * to save some state (because it is about to use the selection to show
3304      * a drop index). It can return a state object to the caller encapsulating
3305      * any saved selection state. On a second call, let's say the drop location
3306      * is being changed to something else. The component doesn't need to
3307      * restore anything yet, so it simply passes back the same state object
3308      * to have the DnD system continue storing it. Finally, let's say this
3309      * method is messaged with <code>null</code>. This means DnD
3310      * is finished with this component for now, meaning it should restore
3311      * state. At this point, it can use the state parameter to restore
3312      * said state, and of course return <code>null</code> since there's
3313      * no longer anything to store.
3314      *
3315      * @param location the drop location (as calculated by
3316      *        <code>dropLocationForPoint</code>) or <code>null</code>
3317      *        if there's no longer a valid drop location
3318      * @param state the state object saved earlier for this component,
3319      *        or <code>null</code>
3320      * @param forDrop whether or not the method is being called because an
3321      *        actual drop occurred
3322      * @return any saved state for this component, or <code>null</code> if none
3323      */
3324     Object setDropLocation(TransferHandler.DropLocation location,
3325                            Object state,
3326                            boolean forDrop) {
3327 
3328         return null;
3329     }
3330 
3331     /**
3332      * Called to indicate to this component that DnD is done.
3333      * Needed by <code>JTree</code>.
3334      */
3335     void dndDone() {
3336     }
3337 
3338     /**
3339      * Processes mouse events occurring on this component by
3340      * dispatching them to any registered
3341      * <code>MouseListener</code> objects, refer to
3342      * {@link java.awt.Component#processMouseEvent(MouseEvent)}
3343      * for a complete description of this method.
3344      *
3345      * @param       e the mouse event
3346      * @see         java.awt.Component#processMouseEvent
3347      * @since       1.5
3348      */
3349     protected void processMouseEvent(MouseEvent e) {
3350         if (autoscrolls && e.getID() == MouseEvent.MOUSE_RELEASED) {
3351             Autoscroller.stop(this);
3352         }
3353         super.processMouseEvent(e);
3354     }
3355 
3356     /**
3357      * Processes mouse motion events, such as MouseEvent.MOUSE_DRAGGED.
3358      *
3359      * @param e the <code>MouseEvent</code>
3360      * @see MouseEvent
3361      */
3362     protected void processMouseMotionEvent(MouseEvent e) {
3363         boolean dispatch = true;
3364         if (autoscrolls && e.getID() == MouseEvent.MOUSE_DRAGGED) {
3365             // We don't want to do the drags when the mouse moves if we're
3366             // autoscrolling.  It makes it feel spastic.
3367             dispatch = !Autoscroller.isRunning(this);
3368             Autoscroller.processMouseDragged(e);
3369         }
3370         if (dispatch) {
3371             super.processMouseMotionEvent(e);
3372         }
3373     }
3374 
3375     // Inner classes can't get at this method from a super class
3376     void superProcessMouseMotionEvent(MouseEvent e) {
3377         super.processMouseMotionEvent(e);
3378     }
3379 
3380     /**
3381      * This is invoked by the <code>RepaintManager</code> if
3382      * <code>createImage</code> is called on the component.
3383      *
3384      * @param newValue true if the double buffer image was created from this component
3385      */
3386     void setCreatedDoubleBuffer(boolean newValue) {
3387         setFlag(CREATED_DOUBLE_BUFFER, newValue);
3388     }
3389 
3390     /**
3391      * Returns true if the <code>RepaintManager</code>
3392      * created the double buffer image from the component.
3393      *
3394      * @return true if this component had a double buffer image, false otherwise
3395      */
3396     boolean getCreatedDoubleBuffer() {
3397         return getFlag(CREATED_DOUBLE_BUFFER);
3398     }
3399 
3400     /**
3401      * <code>ActionStandin</code> is used as a standin for
3402      * <code>ActionListeners</code> that are
3403      * added via <code>registerKeyboardAction</code>.
3404      */
3405     final class ActionStandin implements Action {
3406         private final ActionListener actionListener;
3407         private final String command;
3408         // This will be non-null if actionListener is an Action.
3409         private final Action action;
3410 
3411         ActionStandin(ActionListener actionListener, String command) {
3412             this.actionListener = actionListener;
3413             if (actionListener instanceof Action) {
3414                 this.action = (Action)actionListener;
3415             }
3416             else {
3417                 this.action = null;
3418             }
3419             this.command = command;
3420         }
3421 
3422         public Object getValue(String key) {
3423             if (key != null) {
3424                 if (key.equals(Action.ACTION_COMMAND_KEY)) {
3425                     return command;
3426                 }
3427                 if (action != null) {
3428                     return action.getValue(key);
3429                 }
3430                 if (key.equals(NAME)) {
3431                     return "ActionStandin";
3432                 }
3433             }
3434             return null;
3435         }
3436 
3437         public boolean isEnabled() {
3438             if (actionListener == null) {
3439                 // This keeps the old semantics where
3440                 // registerKeyboardAction(null) would essentialy remove
3441                 // the binding. We don't remove the binding from the
3442                 // InputMap as that would still allow parent InputMaps
3443                 // bindings to be accessed.
3444                 return false;
3445             }
3446             if (action == null) {
3447                 return true;
3448             }
3449             return action.isEnabled();
3450         }
3451 
3452         public void actionPerformed(ActionEvent ae) {
3453             if (actionListener != null) {
3454                 actionListener.actionPerformed(ae);
3455             }
3456         }
3457 
3458         // We don't allow any values to be added.
3459         public void putValue(String key, Object value) {}
3460 
3461         // Does nothing, our enabledness is determiend from our asociated
3462         // action.
3463         public void setEnabled(boolean b) { }
3464 
3465         public void addPropertyChangeListener
3466                     (PropertyChangeListener listener) {}
3467         public void removePropertyChangeListener
3468                           (PropertyChangeListener listener) {}
3469     }
3470 
3471 
3472     // This class is used by the KeyboardState class to provide a single
3473     // instance that can be stored in the AppContext.
3474     static final class IntVector {
3475         int array[] = null;
3476         int count = 0;
3477         int capacity = 0;
3478 
3479         int size() {
3480             return count;
3481         }
3482 
3483         int elementAt(int index) {
3484             return array[index];
3485         }
3486 
3487         void addElement(int value) {
3488             if (count == capacity) {
3489                 capacity = (capacity + 2) * 2;
3490                 int[] newarray = new int[capacity];
3491                 if (count > 0) {
3492                     System.arraycopy(array, 0, newarray, 0, count);
3493                 }
3494                 array = newarray;
3495             }
3496             array[count++] = value;
3497         }
3498 
3499         void setElementAt(int value, int index) {
3500             array[index] = value;
3501         }
3502     }
3503 
3504     @SuppressWarnings("serial")
3505     static class KeyboardState implements Serializable {
3506         private static final Object keyCodesKey =
3507             JComponent.KeyboardState.class;
3508 
3509         // Get the array of key codes from the AppContext.
3510         static IntVector getKeyCodeArray() {
3511             IntVector iv =
3512                 (IntVector)SwingUtilities.appContextGet(keyCodesKey);
3513             if (iv == null) {
3514                 iv = new IntVector();
3515                 SwingUtilities.appContextPut(keyCodesKey, iv);
3516             }
3517             return iv;
3518         }
3519 
3520         static void registerKeyPressed(int keyCode) {
3521             IntVector kca = getKeyCodeArray();
3522             int count = kca.size();
3523             int i;
3524             for(i=0;i<count;i++) {
3525                 if(kca.elementAt(i) == -1){
3526                     kca.setElementAt(keyCode, i);
3527                     return;
3528                 }
3529             }
3530             kca.addElement(keyCode);
3531         }
3532 
3533         static void registerKeyReleased(int keyCode) {
3534             IntVector kca = getKeyCodeArray();
3535             int count = kca.size();
3536             int i;
3537             for(i=0;i<count;i++) {
3538                 if(kca.elementAt(i) == keyCode) {
3539                     kca.setElementAt(-1, i);
3540                     return;
3541                 }
3542             }
3543         }
3544 
3545         static boolean keyIsPressed(int keyCode) {
3546             IntVector kca = getKeyCodeArray();
3547             int count = kca.size();
3548             int i;
3549             for(i=0;i<count;i++) {
3550                 if(kca.elementAt(i) == keyCode) {
3551                     return true;
3552                 }
3553             }
3554             return false;
3555         }
3556 
3557         /**
3558          * Updates internal state of the KeyboardState and returns true
3559          * if the event should be processed further.
3560          */
3561         static boolean shouldProcess(KeyEvent e) {
3562             switch (e.getID()) {
3563             case KeyEvent.KEY_PRESSED:
3564                 if (!keyIsPressed(e.getKeyCode())) {
3565                     registerKeyPressed(e.getKeyCode());
3566                 }
3567                 return true;
3568             case KeyEvent.KEY_RELEASED:
3569                 // We are forced to process VK_PRINTSCREEN separately because
3570                 // the Windows doesn't generate the key pressed event for
3571                 // printscreen and it block the processing of key release
3572                 // event for printscreen.
3573                 if (keyIsPressed(e.getKeyCode()) || e.getKeyCode()==KeyEvent.VK_PRINTSCREEN) {
3574                     registerKeyReleased(e.getKeyCode());
3575                     return true;
3576                 }
3577                 return false;
3578             case KeyEvent.KEY_TYPED:
3579                 return true;
3580             default:
3581                 // Not a known KeyEvent type, bail.
3582                 return false;
3583             }
3584       }
3585     }
3586 
3587     static final sun.awt.RequestFocusController focusController =
3588         new sun.awt.RequestFocusController() {
3589             public boolean acceptRequestFocus(Component from, Component to,
3590                                               boolean temporary, boolean focusedWindowChangeAllowed,
3591                                               sun.awt.CausedFocusEvent.Cause cause)
3592             {
3593                 if ((to == null) || !(to instanceof JComponent)) {
3594                     return true;
3595                 }
3596 
3597                 if ((from == null) || !(from instanceof JComponent)) {
3598                     return true;
3599                 }
3600 
3601                 JComponent target = (JComponent) to;
3602                 if (!target.getVerifyInputWhenFocusTarget()) {
3603                     return true;
3604                 }
3605 
3606                 JComponent jFocusOwner = (JComponent)from;
3607                 InputVerifier iv = jFocusOwner.getInputVerifier();
3608 
3609                 if (iv == null) {
3610                     return true;
3611                 } else {
3612                     Object currentSource = SwingUtilities.appContextGet(
3613                             INPUT_VERIFIER_SOURCE_KEY);
3614                     if (currentSource == jFocusOwner) {
3615                         // We're currently calling into the InputVerifier
3616                         // for this component, so allow the focus change.
3617                         return true;
3618                     }
3619                     SwingUtilities.appContextPut(INPUT_VERIFIER_SOURCE_KEY,
3620                                                  jFocusOwner);
3621                     try {
3622                         return iv.shouldYieldFocus(jFocusOwner);
3623                     } finally {
3624                         if (currentSource != null) {
3625                             // We're already in the InputVerifier for
3626                             // currentSource. By resetting the currentSource
3627                             // we ensure that if the InputVerifier for
3628                             // currentSource does a requestFocus, we don't
3629                             // try and run the InputVerifier again.
3630                             SwingUtilities.appContextPut(
3631                                 INPUT_VERIFIER_SOURCE_KEY, currentSource);
3632                         } else {
3633                             SwingUtilities.appContextRemove(
3634                                 INPUT_VERIFIER_SOURCE_KEY);
3635                         }
3636                     }
3637                 }
3638             }
3639         };
3640 
3641     /*
3642      * --- Accessibility Support ---
3643      */
3644 
3645     /**
3646      * @deprecated As of JDK version 1.1,
3647      * replaced by <code>java.awt.Component.setEnabled(boolean)</code>.
3648      */
3649     @Deprecated
3650     public void enable() {
3651         if (isEnabled() != true) {
3652             super.enable();
3653             if (accessibleContext != null) {
3654                 accessibleContext.firePropertyChange(
3655                     AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
3656                     null, AccessibleState.ENABLED);
3657             }
3658         }
3659     }
3660 
3661     /**
3662      * @deprecated As of JDK version 1.1,
3663      * replaced by <code>java.awt.Component.setEnabled(boolean)</code>.
3664      */
3665     @Deprecated
3666     public void disable() {
3667         if (isEnabled() != false) {
3668             super.disable();
3669             if (accessibleContext != null) {
3670                 accessibleContext.firePropertyChange(
3671                     AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
3672                     AccessibleState.ENABLED, null);
3673             }
3674         }
3675     }
3676 
3677     /**
3678      * Inner class of JComponent used to provide default support for
3679      * accessibility.  This class is not meant to be used directly by
3680      * application developers, but is instead meant only to be
3681      * subclassed by component developers.
3682      * <p>
3683      * <strong>Warning:</strong>
3684      * Serialized objects of this class will not be compatible with
3685      * future Swing releases. The current serialization support is
3686      * appropriate for short term storage or RMI between applications running
3687      * the same version of Swing.  As of 1.4, support for long term storage
3688      * of all JavaBeans&trade;
3689      * has been added to the <code>java.beans</code> package.
3690      * Please see {@link java.beans.XMLEncoder}.
3691      */
3692     @SuppressWarnings("serial") // Same-version serialization only
3693     public abstract class AccessibleJComponent extends AccessibleAWTContainer
3694        implements AccessibleExtendedComponent
3695     {
3696         /**
3697          * Though the class is abstract, this should be called by
3698          * all sub-classes.
3699          */
3700         protected AccessibleJComponent() {
3701             super();
3702         }
3703 
3704         /**
3705          * Number of PropertyChangeListener objects registered. It's used
3706          * to add/remove ContainerListener and FocusListener to track
3707          * target JComponent's state
3708          */
3709         private volatile transient int propertyListenersCount = 0;
3710 
3711         /**
3712          * This field duplicates the function of the accessibleAWTFocusHandler field
3713          * in java.awt.Component.AccessibleAWTComponent, so it has been deprecated.
3714          */
3715         @Deprecated
3716         protected FocusListener accessibleFocusHandler = null;
3717 
3718         /**
3719          * Fire PropertyChange listener, if one is registered,
3720          * when children added/removed.
3721          */
3722         protected class AccessibleContainerHandler
3723             implements ContainerListener {
3724             public void componentAdded(ContainerEvent e) {
3725                 Component c = e.getChild();
3726                 if (c != null && c instanceof Accessible) {
3727                     AccessibleJComponent.this.firePropertyChange(
3728                         AccessibleContext.ACCESSIBLE_CHILD_PROPERTY,
3729                         null, c.getAccessibleContext());
3730                 }
3731             }
3732             public void componentRemoved(ContainerEvent e) {
3733                 Component c = e.getChild();
3734                 if (c != null && c instanceof Accessible) {
3735                     AccessibleJComponent.this.firePropertyChange(
3736                         AccessibleContext.ACCESSIBLE_CHILD_PROPERTY,
3737                         c.getAccessibleContext(), null);
3738                 }
3739             }
3740         }
3741 
3742         /**
3743          * Fire PropertyChange listener, if one is registered,
3744          * when focus events happen
3745          * @since 1.3
3746          */
3747         protected class AccessibleFocusHandler implements FocusListener {
3748            public void focusGained(FocusEvent event) {
3749                if (accessibleContext != null) {
3750                     accessibleContext.firePropertyChange(
3751                         AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
3752                         null, AccessibleState.FOCUSED);
3753                 }
3754             }
3755             public void focusLost(FocusEvent event) {
3756                 if (accessibleContext != null) {
3757                     accessibleContext.firePropertyChange(
3758                         AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
3759                         AccessibleState.FOCUSED, null);
3760                 }
3761             }
3762         } // inner class AccessibleFocusHandler
3763 
3764 
3765         /**
3766          * Adds a PropertyChangeListener to the listener list.
3767          *
3768          * @param listener  the PropertyChangeListener to be added
3769          */
3770         public void addPropertyChangeListener(PropertyChangeListener listener) {
3771             if (accessibleContainerHandler == null) {
3772                 accessibleContainerHandler = new AccessibleContainerHandler();
3773             }
3774             if (propertyListenersCount++ == 0) {
3775                 JComponent.this.addContainerListener(accessibleContainerHandler);
3776             }
3777             super.addPropertyChangeListener(listener);
3778         }
3779 
3780         /**
3781          * Removes a PropertyChangeListener from the listener list.
3782          * This removes a PropertyChangeListener that was registered
3783          * for all properties.
3784          *
3785          * @param listener  the PropertyChangeListener to be removed
3786          */
3787         public void removePropertyChangeListener(PropertyChangeListener listener) {
3788             if (--propertyListenersCount == 0) {
3789                 JComponent.this.removeContainerListener(accessibleContainerHandler);
3790             }
3791             super.removePropertyChangeListener(listener);
3792         }
3793 
3794 
3795 
3796         /**
3797          * Recursively search through the border hierarchy (if it exists)
3798          * for a TitledBorder with a non-null title.  This does a depth
3799          * first search on first the inside borders then the outside borders.
3800          * The assumption is that titles make really pretty inside borders
3801          * but not very pretty outside borders in compound border situations.
3802          * It's rather arbitrary, but hopefully decent UI programmers will
3803          * not create multiple titled borders for the same component.
3804          *
3805          * @param b  the {@code Border} for which to retrieve its title
3806          * @return the border's title as a {@code String}, null if it has
3807          *         no title
3808          */
3809         protected String getBorderTitle(Border b) {
3810             String s;
3811             if (b instanceof TitledBorder) {
3812                 return ((TitledBorder) b).getTitle();
3813             } else if (b instanceof CompoundBorder) {
3814                 s = getBorderTitle(((CompoundBorder) b).getInsideBorder());
3815                 if (s == null) {
3816                     s = getBorderTitle(((CompoundBorder) b).getOutsideBorder());
3817                 }
3818                 return s;
3819             } else {
3820                 return null;
3821             }
3822         }
3823 
3824         // AccessibleContext methods
3825         //
3826         /**
3827          * Gets the accessible name of this object.  This should almost never
3828          * return java.awt.Component.getName(), as that generally isn't
3829          * a localized name, and doesn't have meaning for the user.  If the
3830          * object is fundamentally a text object (such as a menu item), the
3831          * accessible name should be the text of the object (for example,
3832          * "save").
3833          * If the object has a tooltip, the tooltip text may also be an
3834          * appropriate String to return.
3835          *
3836          * @return the localized name of the object -- can be null if this
3837          *         object does not have a name
3838          * @see AccessibleContext#setAccessibleName
3839          */
3840         public String getAccessibleName() {
3841             String name = accessibleName;
3842 
3843             // fallback to the client name property
3844             //
3845             if (name == null) {
3846                 name = (String)getClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY);
3847             }
3848 
3849             // fallback to the titled border if it exists
3850             //
3851             if (name == null) {
3852                 name = getBorderTitle(getBorder());
3853             }
3854 
3855             // fallback to the label labeling us if it exists
3856             //
3857             if (name == null) {
3858                 Object o = getClientProperty(JLabel.LABELED_BY_PROPERTY);
3859                 if (o instanceof Accessible) {
3860                     AccessibleContext ac = ((Accessible) o).getAccessibleContext();
3861                     if (ac != null) {
3862                         name = ac.getAccessibleName();
3863                     }
3864                 }
3865             }
3866             return name;
3867         }
3868 
3869         /**
3870          * Gets the accessible description of this object.  This should be
3871          * a concise, localized description of what this object is - what
3872          * is its meaning to the user.  If the object has a tooltip, the
3873          * tooltip text may be an appropriate string to return, assuming
3874          * it contains a concise description of the object (instead of just
3875          * the name of the object - for example a "Save" icon on a toolbar that
3876          * had "save" as the tooltip text shouldn't return the tooltip
3877          * text as the description, but something like "Saves the current
3878          * text document" instead).
3879          *
3880          * @return the localized description of the object -- can be null if
3881          * this object does not have a description
3882          * @see AccessibleContext#setAccessibleDescription
3883          */
3884         public String getAccessibleDescription() {
3885             String description = accessibleDescription;
3886 
3887             // fallback to the client description property
3888             //
3889             if (description == null) {
3890                 description = (String)getClientProperty(AccessibleContext.ACCESSIBLE_DESCRIPTION_PROPERTY);
3891             }
3892 
3893             // fallback to the tool tip text if it exists
3894             //
3895             if (description == null) {
3896                 try {
3897                     description = getToolTipText();
3898                 } catch (Exception e) {
3899                     // Just in case the subclass overrode the
3900                     // getToolTipText method and actually
3901                     // requires a MouseEvent.
3902                     // [[[FIXME:  WDW - we probably should require this
3903                     // method to take a MouseEvent and just pass it on
3904                     // to getToolTipText.  The swing-feedback traffic
3905                     // leads me to believe getToolTipText might change,
3906                     // though, so I was hesitant to make this change at
3907                     // this time.]]]
3908                 }
3909             }
3910 
3911             // fallback to the label labeling us if it exists
3912             //
3913             if (description == null) {
3914                 Object o = getClientProperty(JLabel.LABELED_BY_PROPERTY);
3915                 if (o instanceof Accessible) {
3916                     AccessibleContext ac = ((Accessible) o).getAccessibleContext();
3917                     if (ac != null) {
3918                         description = ac.getAccessibleDescription();
3919                     }
3920                 }
3921             }
3922 
3923             return description;
3924         }
3925 
3926         /**
3927          * Gets the role of this object.
3928          *
3929          * @return an instance of AccessibleRole describing the role of the
3930          * object
3931          * @see AccessibleRole
3932          */
3933         public AccessibleRole getAccessibleRole() {
3934             return AccessibleRole.SWING_COMPONENT;
3935         }
3936 
3937         /**
3938          * Gets the state of this object.
3939          *
3940          * @return an instance of AccessibleStateSet containing the current
3941          * state set of the object
3942          * @see AccessibleState
3943          */
3944         public AccessibleStateSet getAccessibleStateSet() {
3945             AccessibleStateSet states = super.getAccessibleStateSet();
3946             if (JComponent.this.isOpaque()) {
3947                 states.add(AccessibleState.OPAQUE);
3948             }
3949             return states;
3950         }
3951 
3952         /**
3953          * Returns the number of accessible children in the object.  If all
3954          * of the children of this object implement Accessible, than this
3955          * method should return the number of children of this object.
3956          *
3957          * @return the number of accessible children in the object.
3958          */
3959         public int getAccessibleChildrenCount() {
3960             return super.getAccessibleChildrenCount();
3961         }
3962 
3963         /**
3964          * Returns the nth Accessible child of the object.
3965          *
3966          * @param i zero-based index of child
3967          * @return the nth Accessible child of the object
3968          */
3969         public Accessible getAccessibleChild(int i) {
3970             return super.getAccessibleChild(i);
3971         }
3972 
3973         // ----- AccessibleExtendedComponent
3974 
3975         /**
3976          * Returns the AccessibleExtendedComponent
3977          *
3978          * @return the AccessibleExtendedComponent
3979          */
3980         AccessibleExtendedComponent getAccessibleExtendedComponent() {
3981             return this;
3982         }
3983 
3984         /**
3985          * Returns the tool tip text
3986          *
3987          * @return the tool tip text, if supported, of the object;
3988          * otherwise, null
3989          * @since 1.4
3990          */
3991         public String getToolTipText() {
3992             return JComponent.this.getToolTipText();
3993         }
3994 
3995         /**
3996          * Returns the titled border text
3997          *
3998          * @return the titled border text, if supported, of the object;
3999          * otherwise, null
4000          * @since 1.4
4001          */
4002         public String getTitledBorderText() {
4003             Border border = JComponent.this.getBorder();
4004             if (border instanceof TitledBorder) {
4005                 return ((TitledBorder)border).getTitle();
4006             } else {
4007                 return null;
4008             }
4009         }
4010 
4011         /**
4012          * Returns key bindings associated with this object
4013          *
4014          * @return the key bindings, if supported, of the object;
4015          * otherwise, null
4016          * @see AccessibleKeyBinding
4017          * @since 1.4
4018          */
4019         public AccessibleKeyBinding getAccessibleKeyBinding(){
4020             // Try to get the linked label's mnemonic if it exists
4021             Object o = getClientProperty(JLabel.LABELED_BY_PROPERTY);
4022             if (o instanceof Accessible){
4023                 AccessibleContext ac = ((Accessible) o).getAccessibleContext();
4024                 if (ac != null){
4025                     AccessibleComponent comp = ac.getAccessibleComponent();
4026                     if (! (comp instanceof AccessibleExtendedComponent))
4027                         return null;
4028                     return ((AccessibleExtendedComponent)comp).getAccessibleKeyBinding();
4029                 }
4030             }
4031             return null;
4032         }
4033     } // inner class AccessibleJComponent
4034 
4035 
4036     /**
4037      * Returns an <code>ArrayTable</code> used for
4038      * key/value "client properties" for this component. If the
4039      * <code>clientProperties</code> table doesn't exist, an empty one
4040      * will be created.
4041      *
4042      * @return an ArrayTable
4043      * @see #putClientProperty
4044      * @see #getClientProperty
4045      */
4046     private ArrayTable getClientProperties() {
4047         if (clientProperties == null) {
4048             clientProperties = new ArrayTable();
4049         }
4050         return clientProperties;
4051     }
4052 
4053 
4054     /**
4055      * Returns the value of the property with the specified key.  Only
4056      * properties added with <code>putClientProperty</code> will return
4057      * a non-<code>null</code> value.
4058      *
4059      * @param key the being queried
4060      * @return the value of this property or <code>null</code>
4061      * @see #putClientProperty
4062      */
4063     public final Object getClientProperty(Object key) {
4064         if (key == SwingUtilities2.AA_TEXT_PROPERTY_KEY) {
4065             return aaTextInfo;
4066         } else if (key == SwingUtilities2.COMPONENT_UI_PROPERTY_KEY) {
4067             return ui;
4068         }
4069          if(clientProperties == null) {
4070             return null;
4071         } else {
4072             synchronized(clientProperties) {
4073                 return clientProperties.get(key);
4074             }
4075         }
4076     }
4077 
4078     /**
4079      * Adds an arbitrary key/value "client property" to this component.
4080      * <p>
4081      * The <code>get/putClientProperty</code> methods provide access to
4082      * a small per-instance hashtable. Callers can use get/putClientProperty
4083      * to annotate components that were created by another module.
4084      * For example, a
4085      * layout manager might store per child constraints this way. For example:
4086      * <pre>
4087      * componentA.putClientProperty("to the left of", componentB);
4088      * </pre>
4089      * If value is <code>null</code> this method will remove the property.
4090      * Changes to client properties are reported with
4091      * <code>PropertyChange</code> events.
4092      * The name of the property (for the sake of PropertyChange
4093      * events) is <code>key.toString()</code>.
4094      * <p>
4095      * The <code>clientProperty</code> dictionary is not intended to
4096      * support large
4097      * scale extensions to JComponent nor should be it considered an
4098      * alternative to subclassing when designing a new component.
4099      *
4100      * @param key the new client property key
4101      * @param value the new client property value; if <code>null</code>
4102      *          this method will remove the property
4103      * @see #getClientProperty
4104      * @see #addPropertyChangeListener
4105      */
4106     public final void putClientProperty(Object key, Object value) {
4107         if (key == SwingUtilities2.AA_TEXT_PROPERTY_KEY) {
4108             aaTextInfo = value;
4109             return;
4110         }
4111         if (value == null && clientProperties == null) {
4112             // Both the value and ArrayTable are null, implying we don't
4113             // have to do anything.
4114             return;
4115         }
4116         ArrayTable clientProperties = getClientProperties();
4117         Object oldValue;
4118         synchronized(clientProperties) {
4119             oldValue = clientProperties.get(key);
4120             if (value != null) {
4121                 clientProperties.put(key, value);
4122             } else if (oldValue != null) {
4123                 clientProperties.remove(key);
4124             } else {
4125                 // old == new == null
4126                 return;
4127             }
4128         }
4129         clientPropertyChanged(key, oldValue, value);
4130         firePropertyChange(key.toString(), oldValue, value);
4131     }
4132 
4133     // Invoked from putClientProperty.  This is provided for subclasses
4134     // in Swing.
4135     void clientPropertyChanged(Object key, Object oldValue,
4136                                Object newValue) {
4137     }
4138 
4139 
4140     /*
4141      * Sets the property with the specified name to the specified value if
4142      * the property has not already been set by the client program.
4143      * This method is used primarily to set UI defaults for properties
4144      * with primitive types, where the values cannot be marked with
4145      * UIResource.
4146      * @see LookAndFeel#installProperty
4147      * @param propertyName String containing the name of the property
4148      * @param value Object containing the property value
4149      */
4150     void setUIProperty(String propertyName, Object value) {
4151         if (propertyName == "opaque") {
4152             if (!getFlag(OPAQUE_SET)) {
4153                 setOpaque(((Boolean)value).booleanValue());
4154                 setFlag(OPAQUE_SET, false);
4155             }
4156         } else if (propertyName == "autoscrolls") {
4157             if (!getFlag(AUTOSCROLLS_SET)) {
4158                 setAutoscrolls(((Boolean)value).booleanValue());
4159                 setFlag(AUTOSCROLLS_SET, false);
4160             }
4161         } else if (propertyName == "focusTraversalKeysForward") {
4162             @SuppressWarnings("unchecked")
4163             Set<AWTKeyStroke> strokeSet = (Set<AWTKeyStroke>) value;
4164             if (!getFlag(FOCUS_TRAVERSAL_KEYS_FORWARD_SET)) {
4165                 super.setFocusTraversalKeys(KeyboardFocusManager.
4166                                             FORWARD_TRAVERSAL_KEYS,
4167                                             strokeSet);
4168             }
4169         } else if (propertyName == "focusTraversalKeysBackward") {
4170             @SuppressWarnings("unchecked")
4171             Set<AWTKeyStroke> strokeSet = (Set<AWTKeyStroke>) value;
4172             if (!getFlag(FOCUS_TRAVERSAL_KEYS_BACKWARD_SET)) {
4173                 super.setFocusTraversalKeys(KeyboardFocusManager.
4174                                             BACKWARD_TRAVERSAL_KEYS,
4175                                             strokeSet);
4176             }
4177         } else {
4178             throw new IllegalArgumentException("property \""+
4179                                                propertyName+ "\" cannot be set using this method");
4180         }
4181     }
4182 
4183 
4184     /**
4185      * Sets the focus traversal keys for a given traversal operation for this
4186      * Component.
4187      * Refer to
4188      * {@link java.awt.Component#setFocusTraversalKeys}
4189      * for a complete description of this method.
4190      * <p>
4191      * This method may throw a {@code ClassCastException} if any {@code Object}
4192      * in {@code keystrokes} is not an {@code AWTKeyStroke}.
4193      *
4194      * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
4195      *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
4196      *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
4197      * @param keystrokes the Set of AWTKeyStroke for the specified operation
4198      * @see java.awt.KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
4199      * @see java.awt.KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
4200      * @see java.awt.KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
4201      * @throws IllegalArgumentException if id is not one of
4202      *         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
4203      *         KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
4204      *         KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or if keystrokes
4205      *         contains null, or if any keystroke represents a KEY_TYPED event,
4206      *         or if any keystroke already maps to another focus traversal
4207      *         operation for this Component
4208      * @since 1.5
4209      * @beaninfo
4210      *       bound: true
4211      */
4212     public void
4213         setFocusTraversalKeys(int id, Set<? extends AWTKeyStroke> keystrokes)
4214     {
4215         if (id == KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS) {
4216             setFlag(FOCUS_TRAVERSAL_KEYS_FORWARD_SET,true);
4217         } else if (id == KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS) {
4218             setFlag(FOCUS_TRAVERSAL_KEYS_BACKWARD_SET,true);
4219         }
4220         super.setFocusTraversalKeys(id,keystrokes);
4221     }
4222 
4223     /* --- Transitional java.awt.Component Support ---
4224      * The methods and fields in this section will migrate to
4225      * java.awt.Component in the next JDK release.
4226      */
4227 
4228     /**
4229      * Returns true if this component is lightweight, that is, if it doesn't
4230      * have a native window system peer.
4231      *
4232      * @param c  the {@code Component} to be checked
4233      * @return true if this component is lightweight
4234      */
4235     @SuppressWarnings("deprecation")
4236     public static boolean isLightweightComponent(Component c) {
4237         return c.getPeer() instanceof LightweightPeer;
4238     }
4239 
4240 
4241     /**
4242      * @deprecated As of JDK 5,
4243      * replaced by <code>Component.setBounds(int, int, int, int)</code>.
4244      * <p>
4245      * Moves and resizes this component.
4246      *
4247      * @param x  the new horizontal location
4248      * @param y  the new vertical location
4249      * @param w  the new width
4250      * @param h  the new height
4251      * @see java.awt.Component#setBounds
4252      */
4253     @Deprecated
4254     public void reshape(int x, int y, int w, int h) {
4255         super.reshape(x, y, w, h);
4256     }
4257 
4258 
4259     /**
4260      * Stores the bounds of this component into "return value"
4261      * <code>rv</code> and returns <code>rv</code>.
4262      * If <code>rv</code> is <code>null</code> a new <code>Rectangle</code>
4263      * is allocated.  This version of <code>getBounds</code> is useful
4264      * if the caller wants to avoid allocating a new <code>Rectangle</code>
4265      * object on the heap.
4266      *
4267      * @param rv the return value, modified to the component's bounds
4268      * @return <code>rv</code>; if <code>rv</code> is <code>null</code>
4269      *          return a newly created <code>Rectangle</code> with this
4270      *          component's bounds
4271      */
4272     public Rectangle getBounds(Rectangle rv) {
4273         if (rv == null) {
4274             return new Rectangle(getX(), getY(), getWidth(), getHeight());
4275         }
4276         else {
4277             rv.setBounds(getX(), getY(), getWidth(), getHeight());
4278             return rv;
4279         }
4280     }
4281 
4282 
4283     /**
4284      * Stores the width/height of this component into "return value"
4285      * <code>rv</code> and returns <code>rv</code>.
4286      * If <code>rv</code> is <code>null</code> a new <code>Dimension</code>
4287      * object is allocated.  This version of <code>getSize</code>
4288      * is useful if the caller wants to avoid allocating a new
4289      * <code>Dimension</code> object on the heap.
4290      *
4291      * @param rv the return value, modified to the component's size
4292      * @return <code>rv</code>
4293      */
4294     public Dimension getSize(Dimension rv) {
4295         if (rv == null) {
4296             return new Dimension(getWidth(), getHeight());
4297         }
4298         else {
4299             rv.setSize(getWidth(), getHeight());
4300             return rv;
4301         }
4302     }
4303 
4304 
4305     /**
4306      * Stores the x,y origin of this component into "return value"
4307      * <code>rv</code> and returns <code>rv</code>.
4308      * If <code>rv</code> is <code>null</code> a new <code>Point</code>
4309      * is allocated.  This version of <code>getLocation</code> is useful
4310      * if the caller wants to avoid allocating a new <code>Point</code>
4311      * object on the heap.
4312      *
4313      * @param rv the return value, modified to the component's location
4314      * @return <code>rv</code>
4315      */
4316     public Point getLocation(Point rv) {
4317         if (rv == null) {
4318             return new Point(getX(), getY());
4319         }
4320         else {
4321             rv.setLocation(getX(), getY());
4322             return rv;
4323         }
4324     }
4325 
4326 
4327     /**
4328      * Returns the current x coordinate of the component's origin.
4329      * This method is preferable to writing
4330      * <code>component.getBounds().x</code>, or
4331      * <code>component.getLocation().x</code> because it doesn't cause any
4332      * heap allocations.
4333      *
4334      * @return the current x coordinate of the component's origin
4335      */
4336     public int getX() { return super.getX(); }
4337 
4338 
4339     /**
4340      * Returns the current y coordinate of the component's origin.
4341      * This method is preferable to writing
4342      * <code>component.getBounds().y</code>, or
4343      * <code>component.getLocation().y</code> because it doesn't cause any
4344      * heap allocations.
4345      *
4346      * @return the current y coordinate of the component's origin
4347      */
4348     public int getY() { return super.getY(); }
4349 
4350 
4351     /**
4352      * Returns the current width of this component.
4353      * This method is preferable to writing
4354      * <code>component.getBounds().width</code>, or
4355      * <code>component.getSize().width</code> because it doesn't cause any
4356      * heap allocations.
4357      *
4358      * @return the current width of this component
4359      */
4360     public int getWidth() { return super.getWidth(); }
4361 
4362 
4363     /**
4364      * Returns the current height of this component.
4365      * This method is preferable to writing
4366      * <code>component.getBounds().height</code>, or
4367      * <code>component.getSize().height</code> because it doesn't cause any
4368      * heap allocations.
4369      *
4370      * @return the current height of this component
4371      */
4372     public int getHeight() { return super.getHeight(); }
4373 
4374     /**
4375      * Returns true if this component is completely opaque.
4376      * <p>
4377      * An opaque component paints every pixel within its
4378      * rectangular bounds. A non-opaque component paints only a subset of
4379      * its pixels or none at all, allowing the pixels underneath it to
4380      * "show through".  Therefore, a component that does not fully paint
4381      * its pixels provides a degree of transparency.
4382      * <p>
4383      * Subclasses that guarantee to always completely paint their contents
4384      * should override this method and return true.
4385      *
4386      * @return true if this component is completely opaque
4387      * @see #setOpaque
4388      */
4389     public boolean isOpaque() {
4390         return getFlag(IS_OPAQUE);
4391     }
4392 
4393     /**
4394      * If true the component paints every pixel within its bounds.
4395      * Otherwise, the component may not paint some or all of its
4396      * pixels, allowing the underlying pixels to show through.
4397      * <p>
4398      * The default value of this property is false for <code>JComponent</code>.
4399      * However, the default value for this property on most standard
4400      * <code>JComponent</code> subclasses (such as <code>JButton</code> and
4401      * <code>JTree</code>) is look-and-feel dependent.
4402      *
4403      * @param isOpaque  true if this component should be opaque
4404      * @see #isOpaque
4405      * @beaninfo
4406      *        bound: true
4407      *       expert: true
4408      *  description: The component's opacity
4409      */
4410     public void setOpaque(boolean isOpaque) {
4411         boolean oldValue = getFlag(IS_OPAQUE);
4412         setFlag(IS_OPAQUE, isOpaque);
4413         setFlag(OPAQUE_SET, true);
4414         firePropertyChange("opaque", oldValue, isOpaque);
4415     }
4416 
4417 
4418     /**
4419      * If the specified rectangle is completely obscured by any of this
4420      * component's opaque children then returns true.  Only direct children
4421      * are considered, more distant descendants are ignored.  A
4422      * <code>JComponent</code> is opaque if
4423      * <code>JComponent.isOpaque()</code> returns true, other lightweight
4424      * components are always considered transparent, and heavyweight components
4425      * are always considered opaque.
4426      *
4427      * @param x  x value of specified rectangle
4428      * @param y  y value of specified rectangle
4429      * @param width  width of specified rectangle
4430      * @param height height of specified rectangle
4431      * @return true if the specified rectangle is obscured by an opaque child
4432      */
4433     boolean rectangleIsObscured(int x,int y,int width,int height)
4434     {
4435         int numChildren = getComponentCount();
4436 
4437         for(int i = 0; i < numChildren; i++) {
4438             Component child = getComponent(i);
4439             int cx, cy, cw, ch;
4440 
4441             cx = child.getX();
4442             cy = child.getY();
4443             cw = child.getWidth();
4444             ch = child.getHeight();
4445 
4446             if (x >= cx && (x + width) <= (cx + cw) &&
4447                 y >= cy && (y + height) <= (cy + ch) && child.isVisible()) {
4448 
4449                 if(child instanceof JComponent) {
4450 //                  System.out.println("A) checking opaque: " + ((JComponent)child).isOpaque() + "  " + child);
4451 //                  System.out.print("B) ");
4452 //                  Thread.dumpStack();
4453                     return child.isOpaque();
4454                 } else {
4455                     /** Sometimes a heavy weight can have a bound larger than its peer size
4456                      *  so we should always draw under heavy weights
4457                      */
4458                     return false;
4459                 }
4460             }
4461         }
4462 
4463         return false;
4464     }
4465 
4466 
4467     /**
4468      * Returns the <code>Component</code>'s "visible rect rectangle" -  the
4469      * intersection of the visible rectangles for the component <code>c</code>
4470      * and all of its ancestors.  The return value is stored in
4471      * <code>visibleRect</code>.
4472      *
4473      * @param c  the component
4474      * @param visibleRect  a <code>Rectangle</code> computed as the
4475      *          intersection of all visible rectangles for the component
4476      *          <code>c</code> and all of its ancestors -- this is the
4477      *          return value for this method
4478      * @see #getVisibleRect
4479      */
4480     static final void computeVisibleRect(Component c, Rectangle visibleRect) {
4481         Container p = c.getParent();
4482         Rectangle bounds = c.getBounds();
4483 
4484         if (p == null || p instanceof Window || p instanceof Applet) {
4485             visibleRect.setBounds(0, 0, bounds.width, bounds.height);
4486         } else {
4487             computeVisibleRect(p, visibleRect);
4488             visibleRect.x -= bounds.x;
4489             visibleRect.y -= bounds.y;
4490             SwingUtilities.computeIntersection(0,0,bounds.width,bounds.height,visibleRect);
4491         }
4492     }
4493 
4494 
4495     /**
4496      * Returns the <code>Component</code>'s "visible rect rectangle" -  the
4497      * intersection of the visible rectangles for this component
4498      * and all of its ancestors.  The return value is stored in
4499      * <code>visibleRect</code>.
4500      *
4501      * @param visibleRect a <code>Rectangle</code> computed as the
4502      *          intersection of all visible rectangles for this
4503      *          component and all of its ancestors -- this is the return
4504      *          value for this method
4505      * @see #getVisibleRect
4506      */
4507     public void computeVisibleRect(Rectangle visibleRect) {
4508         computeVisibleRect(this, visibleRect);
4509     }
4510 
4511 
4512     /**
4513      * Returns the <code>Component</code>'s "visible rectangle" -  the
4514      * intersection of this component's visible rectangle,
4515      * <code>new Rectangle(0, 0, getWidth(), getHeight())</code>,
4516      * and all of its ancestors' visible rectangles.
4517      *
4518      * @return the visible rectangle
4519      */
4520     public Rectangle getVisibleRect() {
4521         Rectangle visibleRect = new Rectangle();
4522 
4523         computeVisibleRect(visibleRect);
4524         return visibleRect;
4525     }
4526 
4527     /**
4528      * Support for reporting bound property changes for boolean properties.
4529      * This method can be called when a bound property has changed and it will
4530      * send the appropriate PropertyChangeEvent to any registered
4531      * PropertyChangeListeners.
4532      *
4533      * @param propertyName the property whose value has changed
4534      * @param oldValue the property's previous value
4535      * @param newValue the property's new value
4536      */
4537     public void firePropertyChange(String propertyName,
4538                                    boolean oldValue, boolean newValue) {
4539         super.firePropertyChange(propertyName, oldValue, newValue);
4540     }
4541 
4542 
4543     /**
4544      * Support for reporting bound property changes for integer properties.
4545      * This method can be called when a bound property has changed and it will
4546      * send the appropriate PropertyChangeEvent to any registered
4547      * PropertyChangeListeners.
4548      *
4549      * @param propertyName the property whose value has changed
4550      * @param oldValue the property's previous value
4551      * @param newValue the property's new value
4552      */
4553     public void firePropertyChange(String propertyName,
4554                                       int oldValue, int newValue) {
4555         super.firePropertyChange(propertyName, oldValue, newValue);
4556     }
4557 
4558     // XXX This method is implemented as a workaround to a JLS issue with ambiguous
4559     // methods. This should be removed once 4758654 is resolved.
4560     public void firePropertyChange(String propertyName, char oldValue, char newValue) {
4561         super.firePropertyChange(propertyName, oldValue, newValue);
4562     }
4563 
4564     /**
4565      * Supports reporting constrained property changes.
4566      * This method can be called when a constrained property has changed
4567      * and it will send the appropriate <code>PropertyChangeEvent</code>
4568      * to any registered <code>VetoableChangeListeners</code>.
4569      *
4570      * @param propertyName  the name of the property that was listened on
4571      * @param oldValue  the old value of the property
4572      * @param newValue  the new value of the property
4573      * @exception java.beans.PropertyVetoException when the attempt to set the
4574      *          property is vetoed by the component
4575      */
4576     protected void fireVetoableChange(String propertyName, Object oldValue, Object newValue)
4577         throws java.beans.PropertyVetoException
4578     {
4579         if (vetoableChangeSupport == null) {
4580             return;
4581         }
4582         vetoableChangeSupport.fireVetoableChange(propertyName, oldValue, newValue);
4583     }
4584 
4585 
4586     /**
4587      * Adds a <code>VetoableChangeListener</code> to the listener list.
4588      * The listener is registered for all properties.
4589      *
4590      * @param listener  the <code>VetoableChangeListener</code> to be added
4591      */
4592     public synchronized void addVetoableChangeListener(VetoableChangeListener listener) {
4593         if (vetoableChangeSupport == null) {
4594             vetoableChangeSupport = new java.beans.VetoableChangeSupport(this);
4595         }
4596         vetoableChangeSupport.addVetoableChangeListener(listener);
4597     }
4598 
4599 
4600     /**
4601      * Removes a <code>VetoableChangeListener</code> from the listener list.
4602      * This removes a <code>VetoableChangeListener</code> that was registered
4603      * for all properties.
4604      *
4605      * @param listener  the <code>VetoableChangeListener</code> to be removed
4606      */
4607     public synchronized void removeVetoableChangeListener(VetoableChangeListener listener) {
4608         if (vetoableChangeSupport == null) {
4609             return;
4610         }
4611         vetoableChangeSupport.removeVetoableChangeListener(listener);
4612     }
4613 
4614 
4615     /**
4616      * Returns an array of all the vetoable change listeners
4617      * registered on this component.
4618      *
4619      * @return all of the component's <code>VetoableChangeListener</code>s
4620      *         or an empty
4621      *         array if no vetoable change listeners are currently registered
4622      *
4623      * @see #addVetoableChangeListener
4624      * @see #removeVetoableChangeListener
4625      *
4626      * @since 1.4
4627      */
4628     public synchronized VetoableChangeListener[] getVetoableChangeListeners() {
4629         if (vetoableChangeSupport == null) {
4630             return new VetoableChangeListener[0];
4631         }
4632         return vetoableChangeSupport.getVetoableChangeListeners();
4633     }
4634 
4635 
4636     /**
4637      * Returns the top-level ancestor of this component (either the
4638      * containing <code>Window</code> or <code>Applet</code>),
4639      * or <code>null</code> if this component has not
4640      * been added to any container.
4641      *
4642      * @return the top-level <code>Container</code> that this component is in,
4643      *          or <code>null</code> if not in any container
4644      */
4645     public Container getTopLevelAncestor() {
4646         for(Container p = this; p != null; p = p.getParent()) {
4647             if(p instanceof Window || p instanceof Applet) {
4648                 return p;
4649             }
4650         }
4651         return null;
4652     }
4653 
4654     private AncestorNotifier getAncestorNotifier() {
4655         return (AncestorNotifier)
4656             getClientProperty(JComponent_ANCESTOR_NOTIFIER);
4657     }
4658 
4659     /**
4660      * Registers <code>listener</code> so that it will receive
4661      * <code>AncestorEvents</code> when it or any of its ancestors
4662      * move or are made visible or invisible.
4663      * Events are also sent when the component or its ancestors are added
4664      * or removed from the containment hierarchy.
4665      *
4666      * @param listener  the <code>AncestorListener</code> to register
4667      * @see AncestorEvent
4668      */
4669     public void addAncestorListener(AncestorListener listener) {
4670         AncestorNotifier ancestorNotifier = getAncestorNotifier();
4671         if (ancestorNotifier == null) {
4672             ancestorNotifier = new AncestorNotifier(this);
4673             putClientProperty(JComponent_ANCESTOR_NOTIFIER,
4674                               ancestorNotifier);
4675         }
4676         ancestorNotifier.addAncestorListener(listener);
4677     }
4678 
4679     /**
4680      * Unregisters <code>listener</code> so that it will no longer receive
4681      * <code>AncestorEvents</code>.
4682      *
4683      * @param listener  the <code>AncestorListener</code> to be removed
4684      * @see #addAncestorListener
4685      */
4686     public void removeAncestorListener(AncestorListener listener) {
4687         AncestorNotifier ancestorNotifier = getAncestorNotifier();
4688         if (ancestorNotifier == null) {
4689             return;
4690         }
4691         ancestorNotifier.removeAncestorListener(listener);
4692         if (ancestorNotifier.listenerList.getListenerList().length == 0) {
4693             ancestorNotifier.removeAllListeners();
4694             putClientProperty(JComponent_ANCESTOR_NOTIFIER, null);
4695         }
4696     }
4697 
4698     /**
4699      * Returns an array of all the ancestor listeners
4700      * registered on this component.
4701      *
4702      * @return all of the component's <code>AncestorListener</code>s
4703      *         or an empty
4704      *         array if no ancestor listeners are currently registered
4705      *
4706      * @see #addAncestorListener
4707      * @see #removeAncestorListener
4708      *
4709      * @since 1.4
4710      */
4711     public AncestorListener[] getAncestorListeners() {
4712         AncestorNotifier ancestorNotifier = getAncestorNotifier();
4713         if (ancestorNotifier == null) {
4714             return new AncestorListener[0];
4715         }
4716         return ancestorNotifier.getAncestorListeners();
4717     }
4718 
4719     /**
4720      * Returns an array of all the objects currently registered
4721      * as <code><em>Foo</em>Listener</code>s
4722      * upon this <code>JComponent</code>.
4723      * <code><em>Foo</em>Listener</code>s are registered using the
4724      * <code>add<em>Foo</em>Listener</code> method.
4725      *
4726      * <p>
4727      *
4728      * You can specify the <code>listenerType</code> argument
4729      * with a class literal,
4730      * such as
4731      * <code><em>Foo</em>Listener.class</code>.
4732      * For example, you can query a
4733      * <code>JComponent</code> <code>c</code>
4734      * for its mouse listeners with the following code:
4735      * <pre>MouseListener[] mls = (MouseListener[])(c.getListeners(MouseListener.class));</pre>
4736      * If no such listeners exist, this method returns an empty array.
4737      *
4738      * @param listenerType the type of listeners requested; this parameter
4739      *          should specify an interface that descends from
4740      *          <code>java.util.EventListener</code>
4741      * @return an array of all objects registered as
4742      *          <code><em>Foo</em>Listener</code>s on this component,
4743      *          or an empty array if no such
4744      *          listeners have been added
4745      * @exception ClassCastException if <code>listenerType</code>
4746      *          doesn't specify a class or interface that implements
4747      *          <code>java.util.EventListener</code>
4748      *
4749      * @since 1.3
4750      *
4751      * @see #getVetoableChangeListeners
4752      * @see #getAncestorListeners
4753      */
4754     @SuppressWarnings("unchecked") // Casts to (T[])
4755     public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
4756         T[] result;
4757         if (listenerType == AncestorListener.class) {
4758             // AncestorListeners are handled by the AncestorNotifier
4759             result = (T[])getAncestorListeners();
4760         }
4761         else if (listenerType == VetoableChangeListener.class) {
4762             // VetoableChangeListeners are handled by VetoableChangeSupport
4763             result = (T[])getVetoableChangeListeners();
4764         }
4765         else if (listenerType == PropertyChangeListener.class) {
4766             // PropertyChangeListeners are handled by PropertyChangeSupport
4767             result = (T[])getPropertyChangeListeners();
4768         }
4769         else {
4770             result = listenerList.getListeners(listenerType);
4771         }
4772 
4773         if (result.length == 0) {
4774             return super.getListeners(listenerType);
4775         }
4776         return result;
4777     }
4778 
4779     /**
4780      * Notifies this component that it now has a parent component.
4781      * When this method is invoked, the chain of parent components is
4782      * set up with <code>KeyboardAction</code> event listeners.
4783      * This method is called by the toolkit internally and should
4784      * not be called directly by programs.
4785      *
4786      * @see #registerKeyboardAction
4787      */
4788     public void addNotify() {
4789         super.addNotify();
4790         firePropertyChange("ancestor", null, getParent());
4791 
4792         registerWithKeyboardManager(false);
4793         registerNextFocusableComponent();
4794     }
4795 
4796 
4797     /**
4798      * Notifies this component that it no longer has a parent component.
4799      * When this method is invoked, any <code>KeyboardAction</code>s
4800      * set up in the the chain of parent components are removed.
4801      * This method is called by the toolkit internally and should
4802      * not be called directly by programs.
4803      *
4804      * @see #registerKeyboardAction
4805      */
4806     public void removeNotify() {
4807         super.removeNotify();
4808         // This isn't strictly correct.  The event shouldn't be
4809         // fired until *after* the parent is set to null.  But
4810         // we only get notified before that happens
4811         firePropertyChange("ancestor", getParent(), null);
4812 
4813         unregisterWithKeyboardManager();
4814         deregisterNextFocusableComponent();
4815 
4816         if (getCreatedDoubleBuffer()) {
4817             RepaintManager.currentManager(this).resetDoubleBuffer();
4818             setCreatedDoubleBuffer(false);
4819         }
4820         if (autoscrolls) {
4821             Autoscroller.stop(this);
4822         }
4823     }
4824 
4825 
4826     /**
4827      * Adds the specified region to the dirty region list if the component
4828      * is showing.  The component will be repainted after all of the
4829      * currently pending events have been dispatched.
4830      *
4831      * @param tm  this parameter is not used
4832      * @param x  the x value of the dirty region
4833      * @param y  the y value of the dirty region
4834      * @param width  the width of the dirty region
4835      * @param height  the height of the dirty region
4836      * @see #isPaintingOrigin()
4837      * @see java.awt.Component#isShowing
4838      * @see RepaintManager#addDirtyRegion
4839      */
4840     public void repaint(long tm, int x, int y, int width, int height) {
4841         RepaintManager.currentManager(SunToolkit.targetToAppContext(this))
4842                       .addDirtyRegion(this, x, y, width, height);
4843     }
4844 
4845 
4846     /**
4847      * Adds the specified region to the dirty region list if the component
4848      * is showing.  The component will be repainted after all of the
4849      * currently pending events have been dispatched.
4850      *
4851      * @param  r a <code>Rectangle</code> containing the dirty region
4852      * @see #isPaintingOrigin()
4853      * @see java.awt.Component#isShowing
4854      * @see RepaintManager#addDirtyRegion
4855      */
4856     public void repaint(Rectangle r) {
4857         repaint(0,r.x,r.y,r.width,r.height);
4858     }
4859 
4860 
4861     /**
4862      * Supports deferred automatic layout.
4863      * <p>
4864      * Calls <code>invalidate</code> and then adds this component's
4865      * <code>validateRoot</code> to a list of components that need to be
4866      * validated.  Validation will occur after all currently pending
4867      * events have been dispatched.  In other words after this method
4868      * is called,  the first validateRoot (if any) found when walking
4869      * up the containment hierarchy of this component will be validated.
4870      * By default, <code>JRootPane</code>, <code>JScrollPane</code>,
4871      * and <code>JTextField</code> return true
4872      * from <code>isValidateRoot</code>.
4873      * <p>
4874      * This method will automatically be called on this component
4875      * when a property value changes such that size, location, or
4876      * internal layout of this component has been affected.  This automatic
4877      * updating differs from the AWT because programs generally no
4878      * longer need to invoke <code>validate</code> to get the contents of the
4879      * GUI to update.
4880      *
4881      * @see java.awt.Component#invalidate
4882      * @see java.awt.Container#validate
4883      * @see #isValidateRoot
4884      * @see RepaintManager#addInvalidComponent
4885      */
4886     public void revalidate() {
4887         if (getParent() == null) {
4888             // Note: We don't bother invalidating here as once added
4889             // to a valid parent invalidate will be invoked (addImpl
4890             // invokes addNotify which will invoke invalidate on the
4891             // new Component). Also, if we do add a check to isValid
4892             // here it can potentially be called before the constructor
4893             // which was causing some people grief.
4894             return;
4895         }
4896         if (SunToolkit.isDispatchThreadForAppContext(this)) {
4897             invalidate();
4898             RepaintManager.currentManager(this).addInvalidComponent(this);
4899         }
4900         else {
4901             // To avoid a flood of Runnables when constructing GUIs off
4902             // the EDT, a flag is maintained as to whether or not
4903             // a Runnable has been scheduled.
4904             synchronized(this) {
4905                 if (getFlag(REVALIDATE_RUNNABLE_SCHEDULED)) {
4906                     return;
4907                 }
4908                 setFlag(REVALIDATE_RUNNABLE_SCHEDULED, true);
4909             }
4910             SunToolkit.executeOnEventHandlerThread(this, () -> {
4911                 synchronized(JComponent.this) {
4912                     setFlag(REVALIDATE_RUNNABLE_SCHEDULED, false);
4913                 }
4914                 revalidate();
4915             });
4916         }
4917     }
4918 
4919     /**
4920      * If this method returns true, <code>revalidate</code> calls by
4921      * descendants of this component will cause the entire tree
4922      * beginning with this root to be validated.
4923      * Returns false by default.  <code>JScrollPane</code> overrides
4924      * this method and returns true.
4925      *
4926      * @return always returns false
4927      * @see #revalidate
4928      * @see java.awt.Component#invalidate
4929      * @see java.awt.Container#validate
4930      * @see java.awt.Container#isValidateRoot
4931      */
4932     @Override
4933     public boolean isValidateRoot() {
4934         return false;
4935     }
4936 
4937 
4938     /**
4939      * Returns true if this component tiles its children -- that is, if
4940      * it can guarantee that the children will not overlap.  The
4941      * repainting system is substantially more efficient in this
4942      * common case.  <code>JComponent</code> subclasses that can't make this
4943      * guarantee, such as <code>JLayeredPane</code>,
4944      * should override this method to return false.
4945      *
4946      * @return always returns true
4947      */
4948     public boolean isOptimizedDrawingEnabled() {
4949         return true;
4950     }
4951 
4952     /**
4953      * Returns {@code true} if a paint triggered on a child component should cause
4954      * painting to originate from this Component, or one of its ancestors.
4955      * <p>
4956      * Calling {@link #repaint} or {@link #paintImmediately(int, int, int, int)}
4957      * on a Swing component will result in calling
4958      * the {@link JComponent#paintImmediately(int, int, int, int)} method of
4959      * the first ancestor which {@code isPaintingOrigin()} returns {@code true}, if there are any.
4960      * <p>
4961      * {@code JComponent} subclasses that need to be painted when any of their
4962      * children are repainted should override this method to return {@code true}.
4963      *
4964      * @return always returns {@code false}
4965      *
4966      * @see #paintImmediately(int, int, int, int)
4967      */
4968     protected boolean isPaintingOrigin() {
4969         return false;
4970     }
4971 
4972     /**
4973      * Paints the specified region in this component and all of its
4974      * descendants that overlap the region, immediately.
4975      * <p>
4976      * It's rarely necessary to call this method.  In most cases it's
4977      * more efficient to call repaint, which defers the actual painting
4978      * and can collapse redundant requests into a single paint call.
4979      * This method is useful if one needs to update the display while
4980      * the current event is being dispatched.
4981      * <p>
4982      * This method is to be overridden when the dirty region needs to be changed
4983      * for components that are painting origins.
4984      *
4985      * @param x  the x value of the region to be painted
4986      * @param y  the y value of the region to be painted
4987      * @param w  the width of the region to be painted
4988      * @param h  the height of the region to be painted
4989      * @see #repaint
4990      * @see #isPaintingOrigin()
4991      */
4992     public void paintImmediately(int x,int y,int w, int h) {
4993         Component c = this;
4994         Component parent;
4995 
4996         if(!isShowing()) {
4997             return;
4998         }
4999 
5000         JComponent paintingOigin = SwingUtilities.getPaintingOrigin(this);
5001         if (paintingOigin != null) {
5002             Rectangle rectangle = SwingUtilities.convertRectangle(
5003                     c, new Rectangle(x, y, w, h), paintingOigin);
5004             paintingOigin.paintImmediately(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
5005             return;
5006         }
5007 
5008         while(!c.isOpaque()) {
5009             parent = c.getParent();
5010             if(parent != null) {
5011                 x += c.getX();
5012                 y += c.getY();
5013                 c = parent;
5014             } else {
5015                 break;
5016             }
5017 
5018             if(!(c instanceof JComponent)) {
5019                 break;
5020             }
5021         }
5022         if(c instanceof JComponent) {
5023             ((JComponent)c)._paintImmediately(x,y,w,h);
5024         } else {
5025             c.repaint(x,y,w,h);
5026         }
5027     }
5028 
5029     /**
5030      * Paints the specified region now.
5031      *
5032      * @param r a <code>Rectangle</code> containing the region to be painted
5033      */
5034     public void paintImmediately(Rectangle r) {
5035         paintImmediately(r.x,r.y,r.width,r.height);
5036     }
5037 
5038     /**
5039      * Returns whether this component should be guaranteed to be on top.
5040      * For example, it would make no sense for <code>Menu</code>s to pop up
5041      * under another component, so they would always return true.
5042      * Most components will want to return false, hence that is the default.
5043      *
5044      * @return always returns false
5045      */
5046     // package private
5047     boolean alwaysOnTop() {
5048         return false;
5049     }
5050 
5051     void setPaintingChild(Component paintingChild) {
5052         this.paintingChild = paintingChild;
5053     }
5054 
5055     void _paintImmediately(int x, int y, int w, int h) {
5056         Graphics g;
5057         Container c;
5058         Rectangle b;
5059 
5060         int tmpX, tmpY, tmpWidth, tmpHeight;
5061         int offsetX=0,offsetY=0;
5062 
5063         boolean hasBuffer = false;
5064 
5065         JComponent bufferedComponent = null;
5066         JComponent paintingComponent = this;
5067 
5068         RepaintManager repaintManager = RepaintManager.currentManager(this);
5069         // parent Container's up to Window or Applet. First container is
5070         // the direct parent. Note that in testing it was faster to
5071         // alloc a new Vector vs keeping a stack of them around, and gc
5072         // seemed to have a minimal effect on this.
5073         java.util.List<Component> path = new java.util.ArrayList<Component>(7);
5074         int pIndex = -1;
5075         int pCount = 0;
5076 
5077         tmpX = tmpY = tmpWidth = tmpHeight = 0;
5078 
5079         Rectangle paintImmediatelyClip = fetchRectangle();
5080         paintImmediatelyClip.x = x;
5081         paintImmediatelyClip.y = y;
5082         paintImmediatelyClip.width = w;
5083         paintImmediatelyClip.height = h;
5084 
5085 
5086         // System.out.println("1) ************* in _paintImmediately for " + this);
5087 
5088         boolean ontop = alwaysOnTop() && isOpaque();
5089         if (ontop) {
5090             SwingUtilities.computeIntersection(0, 0, getWidth(), getHeight(),
5091                                                paintImmediatelyClip);
5092             if (paintImmediatelyClip.width == 0) {
5093                 recycleRectangle(paintImmediatelyClip);
5094                 return;
5095             }
5096         }
5097         Component child;
5098         for (c = this, child = null;
5099              c != null && !(c instanceof Window) && !(c instanceof Applet);
5100              child = c, c = c.getParent()) {
5101                 JComponent jc = (c instanceof JComponent) ? (JComponent)c :
5102                                 null;
5103                 path.add(c);
5104                 if(!ontop && jc != null && !jc.isOptimizedDrawingEnabled()) {
5105                     boolean resetPC;
5106 
5107                     // Children of c may overlap, three possible cases for the
5108                     // painting region:
5109                     // . Completely obscured by an opaque sibling, in which
5110                     //   case there is no need to paint.
5111                     // . Partially obscured by a sibling: need to start
5112                     //   painting from c.
5113                     // . Otherwise we aren't obscured and thus don't need to
5114                     //   start painting from parent.
5115                     if (c != this) {
5116                         if (jc.isPaintingOrigin()) {
5117                             resetPC = true;
5118                         }
5119                         else {
5120                             Component[] children = c.getComponents();
5121                             int i = 0;
5122                             for (; i<children.length; i++) {
5123                                 if (children[i] == child) break;
5124                             }
5125                             switch (jc.getObscuredState(i,
5126                                             paintImmediatelyClip.x,
5127                                             paintImmediatelyClip.y,
5128                                             paintImmediatelyClip.width,
5129                                             paintImmediatelyClip.height)) {
5130                             case NOT_OBSCURED:
5131                                 resetPC = false;
5132                                 break;
5133                             case COMPLETELY_OBSCURED:
5134                                 recycleRectangle(paintImmediatelyClip);
5135                                 return;
5136                             default:
5137                                 resetPC = true;
5138                                 break;
5139                             }
5140                         }
5141                     }
5142                     else {
5143                         resetPC = false;
5144                     }
5145 
5146                     if (resetPC) {
5147                         // Get rid of any buffer since we draw from here and
5148                         // we might draw something larger
5149                         paintingComponent = jc;
5150                         pIndex = pCount;
5151                         offsetX = offsetY = 0;
5152                         hasBuffer = false;
5153                     }
5154                 }
5155                 pCount++;
5156 
5157                 // look to see if the parent (and therefor this component)
5158                 // is double buffered
5159                 if(repaintManager.isDoubleBufferingEnabled() && jc != null &&
5160                                   jc.isDoubleBuffered()) {
5161                     hasBuffer = true;
5162                     bufferedComponent = jc;
5163                 }
5164 
5165                 // if we aren't on top, include the parent's clip
5166                 if (!ontop) {
5167                     int bx = c.getX();
5168                     int by = c.getY();
5169                     tmpWidth = c.getWidth();
5170                     tmpHeight = c.getHeight();
5171                     SwingUtilities.computeIntersection(tmpX,tmpY,tmpWidth,tmpHeight,paintImmediatelyClip);
5172                     paintImmediatelyClip.x += bx;
5173                     paintImmediatelyClip.y += by;
5174                     offsetX += bx;
5175                     offsetY += by;
5176                 }
5177         }
5178 
5179         // If the clip width or height is negative, don't bother painting
5180         if(c == null || c.getPeer() == null ||
5181                         paintImmediatelyClip.width <= 0 ||
5182                         paintImmediatelyClip.height <= 0) {
5183             recycleRectangle(paintImmediatelyClip);
5184             return;
5185         }
5186 
5187         paintingComponent.setFlag(IS_REPAINTING, true);
5188 
5189         paintImmediatelyClip.x -= offsetX;
5190         paintImmediatelyClip.y -= offsetY;
5191 
5192         // Notify the Components that are going to be painted of the
5193         // child component to paint to.
5194         if(paintingComponent != this) {
5195             Component comp;
5196             int i = pIndex;
5197             for(; i > 0 ; i--) {
5198                 comp = path.get(i);
5199                 if(comp instanceof JComponent) {
5200                     ((JComponent)comp).setPaintingChild(path.get(i-1));
5201                 }
5202             }
5203         }
5204         try {
5205             if ((g = safelyGetGraphics(paintingComponent, c)) != null) {
5206                 try {
5207                     if (hasBuffer) {
5208                         RepaintManager rm = RepaintManager.currentManager(
5209                                 bufferedComponent);
5210                         rm.beginPaint();
5211                         try {
5212                             rm.paint(paintingComponent, bufferedComponent, g,
5213                                     paintImmediatelyClip.x,
5214                                     paintImmediatelyClip.y,
5215                                     paintImmediatelyClip.width,
5216                                     paintImmediatelyClip.height);
5217                         } finally {
5218                             rm.endPaint();
5219                         }
5220                     } else {
5221                         g.setClip(paintImmediatelyClip.x, paintImmediatelyClip.y,
5222                                 paintImmediatelyClip.width, paintImmediatelyClip.height);
5223                         paintingComponent.paint(g);
5224                     }
5225                 } finally {
5226                     g.dispose();
5227                 }
5228             }
5229         }
5230         finally {
5231             // Reset the painting child for the parent components.
5232             if(paintingComponent != this) {
5233                 Component comp;
5234                 int i = pIndex;
5235                 for(; i > 0 ; i--) {
5236                     comp = path.get(i);
5237                     if(comp instanceof JComponent) {
5238                         ((JComponent)comp).setPaintingChild(null);
5239                     }
5240                 }
5241             }
5242             paintingComponent.setFlag(IS_REPAINTING, false);
5243         }
5244         recycleRectangle(paintImmediatelyClip);
5245     }
5246 
5247     /**
5248      * Paints to the specified graphics.  This does not set the clip and it
5249      * does not adjust the Graphics in anyway, callers must do that first.
5250      * This method is package-private for RepaintManager.PaintManager and
5251      * its subclasses to call, it is NOT intended for general use outside
5252      * of that.
5253      */
5254     void paintToOffscreen(Graphics g, int x, int y, int w, int h, int maxX,
5255                           int maxY) {
5256         try {
5257             setFlag(ANCESTOR_USING_BUFFER, true);
5258             if ((y + h) < maxY || (x + w) < maxX) {
5259                 setFlag(IS_PAINTING_TILE, true);
5260             }
5261             if (getFlag(IS_REPAINTING)) {
5262                 // Called from paintImmediately (RepaintManager) to fill
5263                 // repaint request
5264                 paint(g);
5265             } else {
5266                 // Called from paint() (AWT) to repair damage
5267                 if(!rectangleIsObscured(x, y, w, h)) {
5268                     paintComponent(g);
5269                     paintBorder(g);
5270                 }
5271                 paintChildren(g);
5272             }
5273         } finally {
5274             setFlag(ANCESTOR_USING_BUFFER, false);
5275             setFlag(IS_PAINTING_TILE, false);
5276         }
5277     }
5278 
5279     /**
5280      * Returns whether or not the region of the specified component is
5281      * obscured by a sibling.
5282      *
5283      * @return NOT_OBSCURED if non of the siblings above the Component obscure
5284      *         it, COMPLETELY_OBSCURED if one of the siblings completely
5285      *         obscures the Component or PARTIALLY_OBSCURED if the Component is
5286      *         only partially obscured.
5287      */
5288     private int getObscuredState(int compIndex, int x, int y, int width,
5289                                  int height) {
5290         int retValue = NOT_OBSCURED;
5291         Rectangle tmpRect = fetchRectangle();
5292 
5293         for (int i = compIndex - 1 ; i >= 0 ; i--) {
5294             Component sibling = getComponent(i);
5295             if (!sibling.isVisible()) {
5296                 continue;
5297             }
5298             Rectangle siblingRect;
5299             boolean opaque;
5300             if (sibling instanceof JComponent) {
5301                 opaque = sibling.isOpaque();
5302                 if (!opaque) {
5303                     if (retValue == PARTIALLY_OBSCURED) {
5304                         continue;
5305                     }
5306                 }
5307             }
5308             else {
5309                 opaque = true;
5310             }
5311             siblingRect = sibling.getBounds(tmpRect);
5312             if (opaque && x >= siblingRect.x && (x + width) <=
5313                      (siblingRect.x + siblingRect.width) &&
5314                      y >= siblingRect.y && (y + height) <=
5315                      (siblingRect.y + siblingRect.height)) {
5316                 recycleRectangle(tmpRect);
5317                 return COMPLETELY_OBSCURED;
5318             }
5319             else if (retValue == NOT_OBSCURED &&
5320                      !((x + width <= siblingRect.x) ||
5321                        (y + height <= siblingRect.y) ||
5322                        (x >= siblingRect.x + siblingRect.width) ||
5323                        (y >= siblingRect.y + siblingRect.height))) {
5324                 retValue = PARTIALLY_OBSCURED;
5325             }
5326         }
5327         recycleRectangle(tmpRect);
5328         return retValue;
5329     }
5330 
5331     /**
5332      * Returns true, which implies that before checking if a child should
5333      * be painted it is first check that the child is not obscured by another
5334      * sibling. This is only checked if <code>isOptimizedDrawingEnabled</code>
5335      * returns false.
5336      *
5337      * @return always returns true
5338      */
5339     boolean checkIfChildObscuredBySibling() {
5340         return true;
5341     }
5342 
5343 
5344     private void setFlag(int aFlag, boolean aValue) {
5345         if(aValue) {
5346             flags |= (1 << aFlag);
5347         } else {
5348             flags &= ~(1 << aFlag);
5349         }
5350     }
5351     private boolean getFlag(int aFlag) {
5352         int mask = (1 << aFlag);
5353         return ((flags & mask) == mask);
5354     }
5355     // These functions must be static so that they can be called from
5356     // subclasses inside the package, but whose inheritance hierarhcy includes
5357     // classes outside of the package below JComponent (e.g., JTextArea).
5358     static void setWriteObjCounter(JComponent comp, byte count) {
5359         comp.flags = (comp.flags & ~(0xFF << WRITE_OBJ_COUNTER_FIRST)) |
5360                      (count << WRITE_OBJ_COUNTER_FIRST);
5361     }
5362     static byte getWriteObjCounter(JComponent comp) {
5363         return (byte)((comp.flags >> WRITE_OBJ_COUNTER_FIRST) & 0xFF);
5364     }
5365 
5366     /** Buffering **/
5367 
5368     /**
5369      *  Sets whether this component should use a buffer to paint.
5370      *  If set to true, all the drawing from this component will be done
5371      *  in an offscreen painting buffer. The offscreen painting buffer will
5372      *  the be copied onto the screen.
5373      *  If a <code>Component</code> is buffered and one of its ancestor
5374      *  is also buffered, the ancestor buffer will be used.
5375      *
5376      *  @param aFlag if true, set this component to be double buffered
5377      */
5378     public void setDoubleBuffered(boolean aFlag) {
5379         setFlag(IS_DOUBLE_BUFFERED,aFlag);
5380     }
5381 
5382     /**
5383      * Returns whether this component should use a buffer to paint.
5384      *
5385      * @return true if this component is double buffered, otherwise false
5386      */
5387     public boolean isDoubleBuffered() {
5388         return getFlag(IS_DOUBLE_BUFFERED);
5389     }
5390 
5391     /**
5392      * Returns the <code>JRootPane</code> ancestor for this component.
5393      *
5394      * @return the <code>JRootPane</code> that contains this component,
5395      *          or <code>null</code> if no <code>JRootPane</code> is found
5396      */
5397     public JRootPane getRootPane() {
5398         return SwingUtilities.getRootPane(this);
5399     }
5400 
5401 
5402     /** Serialization **/
5403 
5404     /**
5405      * This is called from Component by way of reflection. Do NOT change
5406      * the name unless you change the code in Component as well.
5407      */
5408     void compWriteObjectNotify() {
5409         byte count = JComponent.getWriteObjCounter(this);
5410         JComponent.setWriteObjCounter(this, (byte)(count + 1));
5411         if (count != 0) {
5412             return;
5413         }
5414 
5415         uninstallUIAndProperties();
5416 
5417         /* JTableHeader is in a separate package, which prevents it from
5418          * being able to override this package-private method the way the
5419          * other components can.  We don't want to make this method protected
5420          * because it would introduce public-api for a less-than-desirable
5421          * serialization scheme, so we compromise with this 'instanceof' hack
5422          * for now.
5423          */
5424         if (getToolTipText() != null ||
5425             this instanceof javax.swing.table.JTableHeader) {
5426             ToolTipManager.sharedInstance().unregisterComponent(JComponent.this);
5427         }
5428     }
5429 
5430     /**
5431      * This object is the <code>ObjectInputStream</code> callback
5432      * that's called after a complete graph of objects (including at least
5433      * one <code>JComponent</code>) has been read.
5434      *  It sets the UI property of each Swing component
5435      * that was read to the current default with <code>updateUI</code>.
5436      * <p>
5437      * As each  component is read in we keep track of the current set of
5438      * root components here, in the roots vector.  Note that there's only one
5439      * <code>ReadObjectCallback</code> per <code>ObjectInputStream</code>,
5440      * they're stored in the static <code>readObjectCallbacks</code>
5441      * hashtable.
5442      *
5443      * @see java.io.ObjectInputStream#registerValidation
5444      * @see SwingUtilities#updateComponentTreeUI
5445      */
5446     private class ReadObjectCallback implements ObjectInputValidation
5447     {
5448         private final Vector<JComponent> roots = new Vector<JComponent>(1);
5449         private final ObjectInputStream inputStream;
5450 
5451         ReadObjectCallback(ObjectInputStream s) throws Exception {
5452             inputStream = s;
5453             s.registerValidation(this, 0);
5454         }
5455 
5456         /**
5457          * This is the method that's called after the entire graph
5458          * of objects has been read in.  It initializes
5459          * the UI property of all of the copmonents with
5460          * <code>SwingUtilities.updateComponentTreeUI</code>.
5461          */
5462         public void validateObject() throws InvalidObjectException {
5463             try {
5464                 for (JComponent root : roots) {
5465                     SwingUtilities.updateComponentTreeUI(root);
5466                 }
5467             }
5468             finally {
5469                 readObjectCallbacks.remove(inputStream);
5470             }
5471         }
5472 
5473         /**
5474          * If <code>c</code> isn't a descendant of a component we've already
5475          * seen, then add it to the roots <code>Vector</code>.
5476          *
5477          * @param c the <code>JComponent</code> to add
5478          */
5479         private void registerComponent(JComponent c)
5480         {
5481             /* If the Component c is a descendant of one of the
5482              * existing roots (or it IS an existing root), we're done.
5483              */
5484             for (JComponent root : roots) {
5485                 for(Component p = c; p != null; p = p.getParent()) {
5486                     if (p == root) {
5487                         return;
5488                     }
5489                 }
5490             }
5491 
5492             /* Otherwise: if Component c is an ancestor of any of the
5493              * existing roots then remove them and add c (the "new root")
5494              * to the roots vector.
5495              */
5496             for(int i = 0; i < roots.size(); i++) {
5497                 JComponent root = roots.elementAt(i);
5498                 for(Component p = root.getParent(); p != null; p = p.getParent()) {
5499                     if (p == c) {
5500                         roots.removeElementAt(i--); // !!
5501                         break;
5502                     }
5503                 }
5504             }
5505 
5506             roots.addElement(c);
5507         }
5508     }
5509 
5510 
5511     /**
5512      * We use the <code>ObjectInputStream</code> "registerValidation"
5513      * callback to update the UI for the entire tree of components
5514      * after they've all been read in.
5515      *
5516      * @param s  the <code>ObjectInputStream</code> from which to read
5517      */
5518     private void readObject(ObjectInputStream s)
5519         throws IOException, ClassNotFoundException
5520     {
5521         ObjectInputStream.GetField f = s.readFields();
5522 
5523         isAlignmentXSet = f.get("isAlignmentXSet", false);
5524         alignmentX = validateAlignment(f.get("alignmentX", 0f));
5525         isAlignmentYSet = f.get("isAlignmentYSet", false);
5526         alignmentY = validateAlignment(f.get("alignmentY", 0f));
5527         listenerList = (EventListenerList) f.get("listenerList", null);
5528         vetoableChangeSupport = (VetoableChangeSupport) f.get("vetoableChangeSupport", null);
5529         autoscrolls = f.get("autoscrolls", false);
5530         border = (Border) f.get("border", null);
5531         flags = f.get("flags", 0);
5532         inputVerifier = (InputVerifier) f.get("inputVerifier", null);
5533         verifyInputWhenFocusTarget = f.get("verifyInputWhenFocusTarget", false);
5534         popupMenu = (JPopupMenu) f.get("popupMenu", null);
5535         focusInputMap = (InputMap) f.get("focusInputMap", null);
5536         ancestorInputMap = (InputMap) f.get("ancestorInputMap", null);
5537         windowInputMap = (ComponentInputMap) f.get("windowInputMap", null);
5538         actionMap = (ActionMap) f.get("actionMap", null);
5539 
5540         /* If there's no ReadObjectCallback for this stream yet, that is, if
5541          * this is the first call to JComponent.readObject() for this
5542          * graph of objects, then create a callback and stash it
5543          * in the readObjectCallbacks table.  Note that the ReadObjectCallback
5544          * constructor takes care of calling s.registerValidation().
5545          */
5546         ReadObjectCallback cb = readObjectCallbacks.get(s);
5547         if (cb == null) {
5548             try {
5549                 readObjectCallbacks.put(s, cb = new ReadObjectCallback(s));
5550             }
5551             catch (Exception e) {
5552                 throw new IOException(e.toString());
5553             }
5554         }
5555         cb.registerComponent(this);
5556 
5557         // Read back the client properties.
5558         int cpCount = s.readInt();
5559         if (cpCount > 0) {
5560             clientProperties = new ArrayTable();
5561             for (int counter = 0; counter < cpCount; counter++) {
5562                 clientProperties.put(s.readObject(),
5563                                      s.readObject());
5564             }
5565         }
5566         if (getToolTipText() != null) {
5567             ToolTipManager.sharedInstance().registerComponent(this);
5568         }
5569         setWriteObjCounter(this, (byte)0);
5570     }
5571 
5572 
5573     /**
5574      * Before writing a <code>JComponent</code> to an
5575      * <code>ObjectOutputStream</code> we temporarily uninstall its UI.
5576      * This is tricky to do because we want to uninstall
5577      * the UI before any of the <code>JComponent</code>'s children
5578      * (or its <code>LayoutManager</code> etc.) are written,
5579      * and we don't want to restore the UI until the most derived
5580      * <code>JComponent</code> subclass has been been stored.
5581      *
5582      * @param s the <code>ObjectOutputStream</code> in which to write
5583      */
5584     private void writeObject(ObjectOutputStream s) throws IOException {
5585         s.defaultWriteObject();
5586         if (getUIClassID().equals(uiClassID)) {
5587             byte count = JComponent.getWriteObjCounter(this);
5588             JComponent.setWriteObjCounter(this, --count);
5589             if (count == 0 && ui != null) {
5590                 ui.installUI(this);
5591             }
5592         }
5593         ArrayTable.writeArrayTable(s, clientProperties);
5594     }
5595 
5596 
5597     /**
5598      * Returns a string representation of this <code>JComponent</code>.
5599      * This method
5600      * is intended to be used only for debugging purposes, and the
5601      * content and format of the returned string may vary between
5602      * implementations. The returned string may be empty but may not
5603      * be <code>null</code>.
5604      *
5605      * @return  a string representation of this <code>JComponent</code>
5606      */
5607     protected String paramString() {
5608         String preferredSizeString = (isPreferredSizeSet() ?
5609                                       getPreferredSize().toString() : "");
5610         String minimumSizeString = (isMinimumSizeSet() ?
5611                                     getMinimumSize().toString() : "");
5612         String maximumSizeString = (isMaximumSizeSet() ?
5613                                     getMaximumSize().toString() : "");
5614         String borderString = (border == null ? ""
5615                                : (border == this ? "this" : border.toString()));
5616 
5617         return super.paramString() +
5618         ",alignmentX=" + alignmentX +
5619         ",alignmentY=" + alignmentY +
5620         ",border=" + borderString +
5621         ",flags=" + flags +             // should beef this up a bit
5622         ",maximumSize=" + maximumSizeString +
5623         ",minimumSize=" + minimumSizeString +
5624         ",preferredSize=" + preferredSizeString;
5625     }
5626 
5627     /**
5628      * {@inheritDoc}
5629      */
5630     @Override
5631     @Deprecated
5632     public void hide() {
5633         boolean showing = isShowing();
5634         super.hide();
5635         if (showing) {
5636             Container parent = getParent();
5637             if (parent != null) {
5638                 Rectangle r = getBounds();
5639                 parent.repaint(r.x, r.y, r.width, r.height);
5640             }
5641             revalidate();
5642         }
5643     }
5644 
5645 }