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