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