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