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