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