Source for javax.swing.JComponent

   1: /* JComponent.java -- Every component in swing inherits from this class.
   2:    Copyright (C) 2002, 2004, 2005, 2006,  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package javax.swing;
  40: 
  41: import java.applet.Applet;
  42: import java.awt.AWTEvent;
  43: import java.awt.Color;
  44: import java.awt.Component;
  45: import java.awt.Container;
  46: import java.awt.Dimension;
  47: import java.awt.EventQueue;
  48: import java.awt.FocusTraversalPolicy;
  49: import java.awt.Font;
  50: import java.awt.Graphics;
  51: import java.awt.Graphics2D;
  52: import java.awt.Image;
  53: import java.awt.Insets;
  54: import java.awt.Point;
  55: import java.awt.Rectangle;
  56: import java.awt.Shape;
  57: import java.awt.Window;
  58: import java.awt.dnd.DropTarget;
  59: import java.awt.event.ActionEvent;
  60: import java.awt.event.ActionListener;
  61: import java.awt.event.ContainerEvent;
  62: import java.awt.event.ContainerListener;
  63: import java.awt.event.FocusEvent;
  64: import java.awt.event.FocusListener;
  65: import java.awt.event.KeyEvent;
  66: import java.awt.event.MouseEvent;
  67: import java.awt.peer.LightweightPeer;
  68: import java.beans.PropertyChangeEvent;
  69: import java.beans.PropertyChangeListener;
  70: import java.beans.PropertyVetoException;
  71: import java.beans.VetoableChangeListener;
  72: import java.io.Serializable;
  73: import java.util.ArrayList;
  74: import java.util.EventListener;
  75: import java.util.Hashtable;
  76: import java.util.Locale;
  77: import java.util.Set;
  78: 
  79: import javax.accessibility.Accessible;
  80: import javax.accessibility.AccessibleContext;
  81: import javax.accessibility.AccessibleExtendedComponent;
  82: import javax.accessibility.AccessibleKeyBinding;
  83: import javax.accessibility.AccessibleRole;
  84: import javax.accessibility.AccessibleState;
  85: import javax.accessibility.AccessibleStateSet;
  86: import javax.swing.border.Border;
  87: import javax.swing.border.CompoundBorder;
  88: import javax.swing.border.TitledBorder;
  89: import javax.swing.event.AncestorEvent;
  90: import javax.swing.event.AncestorListener;
  91: import javax.swing.event.EventListenerList;
  92: import javax.swing.plaf.ComponentUI;
  93: 
  94: /**
  95:  * The base class of all Swing components.
  96:  * It contains generic methods to manage events, properties and sizes. Actual
  97:  * drawing of the component is channeled to a look-and-feel class that is
  98:  * implemented elsewhere.
  99:  *
 100:  * @author Ronald Veldema (rveldema&064;cs.vu.nl)
 101:  * @author Graydon Hoare (graydon&064;redhat.com)
 102:  */
 103: public abstract class JComponent extends Container implements Serializable
 104: {
 105:   private static final long serialVersionUID = -7908749299918704233L;
 106: 
 107:   /** 
 108:    * The accessible context of this <code>JComponent</code>.
 109:    */
 110:   protected AccessibleContext accessibleContext;
 111: 
 112:   /**
 113:    * Basic accessibility support for <code>JComponent</code> derived
 114:    * widgets.
 115:    */
 116:   public abstract class AccessibleJComponent 
 117:     extends AccessibleAWTContainer
 118:     implements AccessibleExtendedComponent
 119:   {
 120:     /**
 121:      * Receives notification if the focus on the JComponent changes and
 122:      * fires appropriate PropertyChangeEvents to listeners registered with
 123:      * the AccessibleJComponent.
 124:      */
 125:     protected class AccessibleFocusHandler 
 126:       implements FocusListener
 127:     {
 128:       /**
 129:        * Creates a new AccessibleFocusHandler.
 130:        */
 131:       protected AccessibleFocusHandler()
 132:       {
 133:         // Nothing to do here.
 134:       }
 135: 
 136:       /**
 137:        * Receives notification when the JComponent gained focus and fires
 138:        * a PropertyChangeEvent to listeners registered on the
 139:        * AccessibleJComponent with a property name of
 140:        * {@link AccessibleContext#ACCESSIBLE_STATE_PROPERTY} and a new value
 141:        * of {@link AccessibleState#FOCUSED}.
 142:        */
 143:       public void focusGained(FocusEvent event)
 144:       {
 145:         AccessibleJComponent.this.firePropertyChange
 146:           (AccessibleContext.ACCESSIBLE_STATE_PROPERTY, null,
 147:            AccessibleState.FOCUSED);
 148:       }
 149: 
 150:       /**
 151:        * Receives notification when the JComponent lost focus and fires
 152:        * a PropertyChangeEvent to listeners registered on the
 153:        * AccessibleJComponent with a property name of
 154:        * {@link AccessibleContext#ACCESSIBLE_STATE_PROPERTY} and an old value
 155:        * of {@link AccessibleState#FOCUSED}.
 156:        */
 157:       public void focusLost(FocusEvent valevent)
 158:       {
 159:         AccessibleJComponent.this.firePropertyChange
 160:           (AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
 161:            AccessibleState.FOCUSED, null);
 162:       }
 163:     }
 164: 
 165:     /**
 166:      * Receives notification if there are child components are added or removed
 167:      * from the JComponent and fires appropriate PropertyChangeEvents to
 168:      * interested listeners on the AccessibleJComponent.
 169:      */
 170:     protected class AccessibleContainerHandler 
 171:       implements ContainerListener
 172:     {
 173:       /**
 174:        * Creates a new AccessibleContainerHandler.
 175:        */
 176:       protected AccessibleContainerHandler()
 177:       {
 178:         // Nothing to do here.
 179:       }
 180: 
 181:       /**
 182:        * Receives notification when a child component is added to the
 183:        * JComponent and fires a PropertyChangeEvent on listeners registered
 184:        * with the AccessibleJComponent with a property name of
 185:        * {@link AccessibleContext#ACCESSIBLE_CHILD_PROPERTY}.
 186:        *
 187:        * @param event the container event
 188:        */
 189:       public void componentAdded(ContainerEvent event)
 190:       {
 191:         Component c = event.getChild();
 192:         if (c != null && c instanceof Accessible)
 193:           {
 194:             AccessibleContext childCtx = c.getAccessibleContext();
 195:             AccessibleJComponent.this.firePropertyChange
 196:               (AccessibleContext.ACCESSIBLE_CHILD_PROPERTY, null, childCtx);
 197:           }
 198:       }
 199: 
 200:       /**
 201:        * Receives notification when a child component is removed from the
 202:        * JComponent and fires a PropertyChangeEvent on listeners registered
 203:        * with the AccessibleJComponent with a property name of
 204:        * {@link AccessibleContext#ACCESSIBLE_CHILD_PROPERTY}.
 205:        *
 206:        * @param event the container event
 207:        */
 208:       public void componentRemoved(ContainerEvent event)
 209:       {
 210:         Component c = event.getChild();
 211:         if (c != null && c instanceof Accessible)
 212:           {
 213:             AccessibleContext childCtx = c.getAccessibleContext();
 214:             AccessibleJComponent.this.firePropertyChange
 215:               (AccessibleContext.ACCESSIBLE_CHILD_PROPERTY, childCtx, null);
 216:           }
 217:       }
 218:     }
 219: 
 220:     private static final long serialVersionUID = -7047089700479897799L;
 221: 
 222:     /**
 223:      * Receives notification when a child component is added to the
 224:      * JComponent and fires a PropertyChangeEvent on listeners registered
 225:      * with the AccessibleJComponent.
 226:      *
 227:      * @specnote AccessibleAWTContainer has a protected field with the same
 228:      *           name. Looks like a bug or nasty misdesign to me.
 229:      */
 230:     protected ContainerListener accessibleContainerHandler;
 231: 
 232:     /**
 233:      * Receives notification if the focus on the JComponent changes and
 234:      * fires appropriate PropertyChangeEvents to listeners registered with
 235:      * the AccessibleJComponent.
 236:      *
 237:      * @specnote AccessibleAWTComponent has a protected field
 238:      *           accessibleAWTFocusHandler. Looks like a bug or nasty misdesign
 239:      *           to me.
 240:      */
 241:     protected FocusListener accessibleFocusHandler;
 242: 
 243:     /**
 244:      * Creates a new AccessibleJComponent.
 245:      */
 246:     protected AccessibleJComponent()
 247:     {
 248:       // Nothing to do here.
 249:     }
 250: 
 251:     /**
 252:      * Adds a property change listener to the list of registered listeners.
 253:      *
 254:      * This sets up the {@link #accessibleContainerHandler} and
 255:      * {@link #accessibleFocusHandler} fields and calls
 256:      * <code>super.addPropertyChangeListener(listener)</code>.
 257:      *
 258:      * @param listener the listener to add
 259:      */
 260:     public void addPropertyChangeListener(PropertyChangeListener listener)
 261:     {
 262:       // Tests seem to indicate that this method also sets up the other two
 263:       // handlers.
 264:       if (accessibleContainerHandler == null)
 265:         {
 266:           accessibleContainerHandler = new AccessibleContainerHandler();
 267:           addContainerListener(accessibleContainerHandler);
 268:         }
 269:       if (accessibleFocusHandler == null)
 270:         {
 271:           accessibleFocusHandler = new AccessibleFocusHandler();
 272:           addFocusListener(accessibleFocusHandler);
 273:         }
 274:       super.addPropertyChangeListener(listener);
 275:     }
 276: 
 277:     /**
 278:      * Removes a property change listener from the list of registered listeners.
 279:      *
 280:      * This uninstalls the {@link #accessibleContainerHandler} and
 281:      * {@link #accessibleFocusHandler} fields and calls
 282:      * <code>super.removePropertyChangeListener(listener)</code>.
 283:      *
 284:      * @param listener the listener to remove
 285:      */
 286:     public void removePropertyChangeListener(PropertyChangeListener listener)
 287:     {
 288:       // Tests seem to indicate that this method also resets the other two
 289:       // handlers.
 290:       if (accessibleContainerHandler != null)
 291:         {
 292:           removeContainerListener(accessibleContainerHandler);
 293:           accessibleContainerHandler = null;
 294:         }
 295:       if (accessibleFocusHandler != null)
 296:         {
 297:           removeFocusListener(accessibleFocusHandler);
 298:           accessibleFocusHandler = null;
 299:         }
 300:       super.removePropertyChangeListener(listener);
 301:     }
 302: 
 303:     /**
 304:      * Returns the number of accessible children of this object.
 305:      *
 306:      * @return  the number of accessible children of this object
 307:      */
 308:     public int getAccessibleChildrenCount()
 309:     {
 310:       // TODO: The functionality should be performed in the superclass.
 311:       // Find out why this is overridden. However, it is very well possible
 312:       // that this is left over from times when there was no such superclass
 313:       // method.
 314:       return super.getAccessibleChildrenCount();
 315:     }
 316: 
 317:     /**
 318:      * Returns the accessible child component at index <code>i</code>.
 319:      *
 320:      * @param i the index of the accessible child to return
 321:      *
 322:      * @return the accessible child component at index <code>i</code>
 323:      */
 324:     public Accessible getAccessibleChild(int i)
 325:     {
 326:       // TODO: The functionality should be performed in the superclass.
 327:       // Find out why this is overridden. However, it is very well possible
 328:       // that this is left over from times when there was no such superclass
 329:       // method.
 330:       return super.getAccessibleChild(i);
 331:     }
 332: 
 333:     /**
 334:      * Returns the accessible state set of this component.
 335:      *
 336:      * @return the accessible state set of this component
 337:      */
 338:     public AccessibleStateSet getAccessibleStateSet()
 339:     {
 340:       // Note: While the java.awt.Component has an 'opaque' property, it
 341:       // seems that it is not added to the accessible state set there, even
 342:       // if this property is true. However, it is handled for JComponent, so
 343:       // we add it here.
 344:       AccessibleStateSet state = super.getAccessibleStateSet();
 345:       if (isOpaque())
 346:         state.add(AccessibleState.OPAQUE);
 347:       return state;
 348:     }
 349: 
 350:     /**
 351:      * Returns the localized name for this object. Generally this should
 352:      * almost never return {@link Component#getName()} since that is not
 353:      * a localized name. If the object is some kind of text component (like
 354:      * a menu item), then the value of the object may be returned. Also, if
 355:      * the object has a tooltip, the value of the tooltip may also be
 356:      * appropriate.
 357:      *
 358:      * @return the localized name for this object or <code>null</code> if this
 359:      *         object has no name
 360:      */
 361:     public String getAccessibleName()
 362:     {
 363:       String name = super.getAccessibleName();
 364: 
 365:       // There are two fallbacks provided by the JComponent in the case the
 366:       // superclass returns null:
 367:       // - If the component is inside a titled border, then it inherits the
 368:       //   name from the border title.
 369:       // - If the component is not inside a titled border but has a label
 370:       //   (via JLabel.setLabelFor()), then it gets the name from the label's
 371:       //   accessible context.
 372: 
 373:       if (name == null)
 374:         {
 375:           name = getTitledBorderText();
 376:         }
 377: 
 378:       if (name == null)
 379:         {
 380:           Object l = getClientProperty(JLabel.LABEL_PROPERTY);
 381:           if (l instanceof Accessible)
 382:             {
 383:               AccessibleContext labelCtx =
 384:                 ((Accessible) l).getAccessibleContext();
 385:               name = labelCtx.getAccessibleName();
 386:             }
 387:         }
 388: 
 389:       return name;
 390:     }
 391: 
 392:     /**
 393:      * Returns the localized description of this object.
 394:      *
 395:      * @return the localized description of this object or <code>null</code>
 396:      *         if this object has no description
 397:      */
 398:     public String getAccessibleDescription()
 399:     {
 400:       // There are two fallbacks provided by the JComponent in the case the
 401:       // superclass returns null:
 402:       // - If the component has a tooltip, then inherit the description from
 403:       //   the tooltip.
 404:       // - If the component is not inside a titled border but has a label
 405:       //   (via JLabel.setLabelFor()), then it gets the name from the label's
 406:       //   accessible context.
 407:       String descr = super.getAccessibleDescription();
 408: 
 409:       if (descr == null)
 410:         {
 411:           descr = getToolTipText();
 412:         }
 413: 
 414:       if (descr == null)
 415:         {
 416:           Object l = getClientProperty(JLabel.LABEL_PROPERTY);
 417:           if (l instanceof Accessible)
 418:             {
 419:               AccessibleContext labelCtx =
 420:                 ((Accessible) l).getAccessibleContext();
 421:               descr = labelCtx.getAccessibleName();
 422:             }
 423:         }
 424: 
 425:       return descr;
 426:     }
 427: 
 428:     /**
 429:      * Returns the accessible role of this component.
 430:      *
 431:      * @return the accessible role of this component
 432:      *
 433:      * @see AccessibleRole
 434:      */
 435:     public AccessibleRole getAccessibleRole()
 436:     {
 437:       return AccessibleRole.SWING_COMPONENT;
 438:     }
 439: 
 440:     /**
 441:      * Recursivly searches a border hierarchy (starting at <code>border) for
 442:      * a titled border and returns the title if one is found, <code>null</code>
 443:      * otherwise.
 444:      *
 445:      * @param border the border to start search from
 446:      *
 447:      * @return the border title of a possibly found titled border
 448:      */
 449:     protected String getBorderTitle(Border border)
 450:     {
 451:       String title = null;
 452:       if (border instanceof CompoundBorder)
 453:         {
 454:           CompoundBorder compound = (CompoundBorder) border;
 455:           Border inner = compound.getInsideBorder();
 456:           title = getBorderTitle(inner);
 457:           if (title == null)
 458:             {
 459:               Border outer = compound.getOutsideBorder();
 460:               title = getBorderTitle(outer);
 461:             }
 462:         }
 463:       else if (border instanceof TitledBorder)
 464:         {
 465:           TitledBorder titled = (TitledBorder) border;
 466:           title = titled.getTitle(); 
 467:         }
 468:       return title;
 469:     }
 470: 
 471:     /**
 472:      * Returns the tooltip text for this accessible component.
 473:      *
 474:      * @return the tooltip text for this accessible component
 475:      */
 476:     public String getToolTipText()
 477:     {
 478:       return JComponent.this.getToolTipText();
 479:     }
 480: 
 481:     /**
 482:      * Returns the title of the border of this accessible component if
 483:      * this component has a titled border, otherwise returns <code>null</code>.
 484:      *
 485:      * @return the title of the border of this accessible component if
 486:      *         this component has a titled border, otherwise returns
 487:      *         <code>null</code>
 488:      */
 489:     public String getTitledBorderText()
 490:     {
 491:       return getBorderTitle(getBorder()); 
 492:     }
 493: 
 494:     /**
 495:      * Returns the keybindings associated with this accessible component or
 496:      * <code>null</code> if the component does not support key bindings.
 497:      *
 498:      * @return the keybindings associated with this accessible component
 499:      */
 500:     public AccessibleKeyBinding getAccessibleKeyBinding()
 501:     {
 502:       // The reference implementation seems to always return null here,
 503:       // independent of the key bindings of the JComponent. So do we.
 504:       return null;
 505:     }
 506:   }
 507: 
 508:   /** 
 509:    * An explicit value for the component's preferred size; if not set by a
 510:    * user, this is calculated on the fly by delegating to the {@link
 511:    * ComponentUI#getPreferredSize} method on the {@link #ui} property. 
 512:    */
 513:   Dimension preferredSize;
 514: 
 515:   /** 
 516:    * An explicit value for the component's minimum size; if not set by a
 517:    * user, this is calculated on the fly by delegating to the {@link
 518:    * ComponentUI#getMinimumSize} method on the {@link #ui} property. 
 519:    */
 520:   Dimension minimumSize;
 521: 
 522:   /** 
 523:    * An explicit value for the component's maximum size; if not set by a
 524:    * user, this is calculated on the fly by delegating to the {@link
 525:    * ComponentUI#getMaximumSize} method on the {@link #ui} property.
 526:    */
 527:   Dimension maximumSize;
 528: 
 529:   /**
 530:    * A value between 0.0 and 1.0 indicating the preferred horizontal
 531:    * alignment of the component, relative to its siblings. The values
 532:    * {@link #LEFT_ALIGNMENT}, {@link #CENTER_ALIGNMENT}, and {@link
 533:    * #RIGHT_ALIGNMENT} can also be used, as synonyms for <code>0.0</code>,
 534:    * <code>0.5</code>, and <code>1.0</code>, respectively. Not all layout
 535:    * managers use this property.
 536:    *
 537:    * @see #getAlignmentX
 538:    * @see #setAlignmentX
 539:    * @see javax.swing.OverlayLayout
 540:    * @see javax.swing.BoxLayout
 541:    */
 542:   float alignmentX = -1.0F;
 543: 
 544:   /**
 545:    * A value between 0.0 and 1.0 indicating the preferred vertical
 546:    * alignment of the component, relative to its siblings. The values
 547:    * {@link #TOP_ALIGNMENT}, {@link #CENTER_ALIGNMENT}, and {@link
 548:    * #BOTTOM_ALIGNMENT} can also be used, as synonyms for <code>0.0</code>,
 549:    * <code>0.5</code>, and <code>1.0</code>, respectively. Not all layout
 550:    * managers use this property.
 551:    *
 552:    * @see #getAlignmentY
 553:    * @see #setAlignmentY
 554:    * @see javax.swing.OverlayLayout
 555:    * @see javax.swing.BoxLayout
 556:    */
 557:   float alignmentY = -1.0F;
 558: 
 559:   /** 
 560:    * The border painted around this component.
 561:    * 
 562:    * @see #paintBorder
 563:    */
 564:   Border border;
 565: 
 566:   /** 
 567:    * The text to show in the tooltip associated with this component.
 568:    * 
 569:    * @see #setToolTipText
 570:    * @see #getToolTipText()
 571:    */
 572:    String toolTipText;
 573: 
 574:   /** 
 575:    * <p>Whether to double buffer this component when painting. This flag
 576:    * should generally be <code>true</code>, to ensure good painting
 577:    * performance.</p>
 578:    *
 579:    * <p>All children of a double buffered component are painted into the
 580:    * double buffer automatically, so only the top widget in a window needs
 581:    * to be double buffered.</p>
 582:    *
 583:    * @see #setDoubleBuffered
 584:    * @see #isDoubleBuffered
 585:    * @see #paint
 586:    */
 587:   boolean doubleBuffered = true;
 588: 
 589:   /**
 590:    * A set of flags indicating which debugging graphics facilities should
 591:    * be enabled on this component. The values should be a combination of
 592:    * {@link DebugGraphics#NONE_OPTION}, {@link DebugGraphics#LOG_OPTION},
 593:    * {@link DebugGraphics#FLASH_OPTION}, or {@link
 594:    * DebugGraphics#BUFFERED_OPTION}.
 595:    *
 596:    * @see #setDebugGraphicsOptions
 597:    * @see #getDebugGraphicsOptions
 598:    * @see DebugGraphics
 599:    * @see #getComponentGraphics
 600:    */
 601:   int debugGraphicsOptions;
 602: 
 603:   /** 
 604:    * <p>This property controls two independent behaviors simultaneously.</p>
 605:    *
 606:    * <p>First, it controls whether to fill the background of this widget
 607:    * when painting its body. This affects calls to {@link
 608:    * JComponent#paintComponent}, which in turn calls {@link
 609:    * ComponentUI#update} on the component's {@link #ui} property. If the
 610:    * component is opaque during this call, the background will be filled
 611:    * before calling {@link ComponentUI#paint}. This happens merely as a
 612:    * convenience; you may fill the component's background yourself too,
 613:    * but there is no need to do so if you will be filling with the same
 614:    * color.</p>
 615:    *
 616:    * <p>Second, it the opaque property informs swing's repaint system
 617:    * whether it will be necessary to paint the components "underneath" this
 618:    * component, in Z-order. If the component is opaque, it is considered to
 619:    * completely occlude components "underneath" it, so they will not be
 620:    * repainted along with the opaque component.</p>
 621:    *
 622:    * <p>The default value for this property is <code>false</code>, but most
 623:    * components will want to set it to <code>true</code> when installing UI
 624:    * defaults in {@link ComponentUI#installUI}.</p>
 625:    *
 626:    * @see #setOpaque
 627:    * @see #isOpaque
 628:    * @see #paintComponent
 629:    */
 630:   boolean opaque = false;
 631: 
 632:   /** 
 633:    * The user interface delegate for this component. Event delivery and
 634:    * repainting of the component are usually delegated to this object. 
 635:    *
 636:    * @see #setUI
 637:    * @see #getUIClassID
 638:    * @see #updateUI
 639:    */
 640:   protected ComponentUI ui;
 641: 
 642:   /**
 643:    * A hint to the focus system that this component should or should not
 644:    * get focus. If this is <code>false</code>, swing will not try to
 645:    * request focus on this component; if <code>true</code>, swing might
 646:    * try to request focus, but the request might fail. Thus it is only 
 647:    * a hint guiding swing's behavior.
 648:    *
 649:    * @see #requestFocus()
 650:    * @see #isRequestFocusEnabled
 651:    * @see #setRequestFocusEnabled
 652:    */
 653:   boolean requestFocusEnabled;
 654: 
 655:   /**
 656:    * Flag indicating behavior of this component when the mouse is dragged
 657:    * outside the component and the mouse <em>stops moving</em>. If
 658:    * <code>true</code>, synthetic mouse events will be delivered on regular
 659:    * timed intervals, continuing off in the direction the mouse exited the
 660:    * component, until the mouse is released or re-enters the component.
 661:    *
 662:    * @see #setAutoscrolls
 663:    * @see #getAutoscrolls
 664:    */
 665:   boolean autoscrolls = false;
 666: 
 667:   /**
 668:    * Indicates whether the current paint call is already double buffered or
 669:    * not. 
 670:    */
 671:   static boolean isPaintingDoubleBuffered = false;
 672: 
 673:   /**
 674:    * Listeners for events other than {@link PropertyChangeEvent} are
 675:    * handled by this listener list. PropertyChangeEvents are handled in
 676:    * {@link #changeSupport}.
 677:    */
 678:   protected EventListenerList listenerList = new EventListenerList();
 679: 
 680:   /** 
 681:    * Storage for "client properties", which are key/value pairs associated
 682:    * with this component by a "client", such as a user application or a
 683:    * layout manager. This is lazily constructed when the component gets its
 684:    * first client property.
 685:    */
 686:   private Hashtable clientProperties;
 687:   
 688:   private InputMap inputMap_whenFocused;
 689:   private InputMap inputMap_whenAncestorOfFocused;
 690:   private ComponentInputMap inputMap_whenInFocusedWindow;
 691:   private ActionMap actionMap;
 692:   /** @since 1.3 */
 693:   private boolean verifyInputWhenFocusTarget;
 694:   private InputVerifier inputVerifier;
 695: 
 696:   private TransferHandler transferHandler;
 697: 
 698:   /**
 699:    * Indicates if this component is currently painting a tile or not.
 700:    */
 701:   private boolean paintingTile;
 702: 
 703:   /**
 704:    * A temporary buffer used for fast dragging of components.
 705:    */
 706:   private Image dragBuffer;
 707: 
 708:   /**
 709:    * Indicates if the dragBuffer is already initialized.
 710:    */
 711:   private boolean dragBufferInitialized;
 712: 
 713:   /**
 714:    * A cached Rectangle object to be reused. Be careful when you use that,
 715:    * so that it doesn't get modified in another context within the same
 716:    * method call chain.
 717:    */
 718:   private static transient Rectangle rectCache;
 719: 
 720:   /**
 721:    * The default locale of the component.
 722:    * 
 723:    * @see #getDefaultLocale
 724:    * @see #setDefaultLocale
 725:    */
 726:   private static Locale defaultLocale;
 727:   
 728:   public static final String TOOL_TIP_TEXT_KEY = "ToolTipText";
 729: 
 730:   /**
 731:    * Constant used to indicate that no condition has been assigned to a
 732:    * particular action.
 733:    *
 734:    * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
 735:    */
 736:   public static final int UNDEFINED_CONDITION = -1;
 737: 
 738:   /**
 739:    * Constant used to indicate that an action should be performed only when 
 740:    * the component has focus.
 741:    *
 742:    * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
 743:    */
 744:   public static final int WHEN_FOCUSED = 0;
 745: 
 746:   /**
 747:    * Constant used to indicate that an action should be performed only when 
 748:    * the component is an ancestor of the component which has focus.
 749:    *
 750:    * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
 751:    */
 752:   public static final int WHEN_ANCESTOR_OF_FOCUSED_COMPONENT = 1;
 753: 
 754:   /**
 755:    * Constant used to indicate that an action should be performed only when 
 756:    * the component is in the window which has focus.
 757:    *
 758:    * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
 759:    */
 760:   public static final int WHEN_IN_FOCUSED_WINDOW = 2;
 761: 
 762:   /**
 763:    * Indicates if this component is completely dirty or not. This is used
 764:    * by the RepaintManager's
 765:    * {@link RepaintManager#isCompletelyDirty(JComponent)} method.
 766:    */
 767:   boolean isCompletelyDirty = false;
 768: 
 769:   /**
 770:    * Indicates if the opaque property has been set by a client program or by
 771:    * the UI.
 772:    *
 773:    * @see #setUIProperty(String, Object)
 774:    * @see LookAndFeel#installProperty(JComponent, String, Object)
 775:    */
 776:   private boolean clientOpaqueSet = false;
 777: 
 778:   /**
 779:    * Indicates if the autoscrolls property has been set by a client program or
 780:    * by the UI.
 781:    *
 782:    * @see #setUIProperty(String, Object)
 783:    * @see LookAndFeel#installProperty(JComponent, String, Object)
 784:    */
 785:   private boolean clientAutoscrollsSet = false;
 786: 
 787:   /**
 788:    * Creates a new <code>JComponent</code> instance.
 789:    */
 790:   public JComponent()
 791:   {
 792:     super();
 793:     setDropTarget(new DropTarget());
 794:     defaultLocale = Locale.getDefault();
 795:     debugGraphicsOptions = DebugGraphics.NONE_OPTION;
 796:     setRequestFocusEnabled(true);
 797:   }
 798: 
 799:   /**
 800:    * Helper to lazily construct and return the client properties table.
 801:    * 
 802:    * @return The current client properties table
 803:    *
 804:    * @see #clientProperties
 805:    * @see #getClientProperty
 806:    * @see #putClientProperty
 807:    */
 808:   private Hashtable getClientProperties()
 809:   {
 810:     if (clientProperties == null)
 811:       clientProperties = new Hashtable();
 812:     return clientProperties;
 813:   }
 814: 
 815:   /**
 816:    * Get a client property associated with this component and a particular
 817:    * key.
 818:    *
 819:    * @param key The key with which to look up the client property
 820:    *
 821:    * @return A client property associated with this object and key
 822:    *
 823:    * @see #clientProperties
 824:    * @see #getClientProperties
 825:    * @see #putClientProperty
 826:    */
 827:   public final Object getClientProperty(Object key)
 828:   {
 829:     return getClientProperties().get(key);
 830:   }
 831: 
 832:   /**
 833:    * Add a client property <code>value</code> to this component, associated
 834:    * with <code>key</code>. If there is an existing client property
 835:    * associated with <code>key</code>, it will be replaced.  A
 836:    * {@link PropertyChangeEvent} is sent to registered listeners (with the
 837:    * name of the property being <code>key.toString()</code>).
 838:    *
 839:    * @param key The key of the client property association to add
 840:    * @param value The value of the client property association to add
 841:    *
 842:    * @see #clientProperties
 843:    * @see #getClientProperties
 844:    * @see #getClientProperty
 845:    */
 846:   public final void putClientProperty(Object key, Object value)
 847:   {
 848:     Hashtable t = getClientProperties();
 849:     Object old = t.get(key);
 850:     if (value != null)
 851:       t.put(key, value);
 852:     else
 853:       t.remove(key);
 854:     firePropertyChange(key.toString(), old, value);
 855:   }
 856: 
 857:   /**
 858:    * Unregister an <code>AncestorListener</code>.
 859:    *
 860:    * @param listener The listener to unregister
 861:    * 
 862:    * @see #addAncestorListener
 863:    */
 864:   public void removeAncestorListener(AncestorListener listener)
 865:   {
 866:     listenerList.remove(AncestorListener.class, listener);
 867:   }
 868: 
 869:   /**
 870:    * Unregister a <code>VetoableChangeChangeListener</code>.
 871:    *
 872:    * @param listener The listener to unregister
 873:    *
 874:    * @see #addVetoableChangeListener
 875:    */
 876:   public void removeVetoableChangeListener(VetoableChangeListener listener)
 877:   {
 878:     listenerList.remove(VetoableChangeListener.class, listener);
 879:   }
 880: 
 881:   /**
 882:    * Register an <code>AncestorListener</code>.
 883:    *
 884:    * @param listener The listener to register
 885:    *
 886:    * @see #removeVetoableChangeListener
 887:    */
 888:   public void addAncestorListener(AncestorListener listener)
 889:   {
 890:     listenerList.add(AncestorListener.class, listener);
 891:   }
 892: 
 893:   /**
 894:    * Register a <code>PropertyChangeListener</code> for a specific, named
 895:    * property. To listen to all property changes, regardless of name, use
 896:    * {@link #addPropertyChangeListener(PropertyChangeListener)} instead.
 897:    *
 898:    * @param propertyName The property name to listen to
 899:    * @param listener The listener to register
 900:    *
 901:    * @see #removePropertyChangeListener(String, PropertyChangeListener)
 902:    * @see #changeSupport
 903:    */
 904:   public void addPropertyChangeListener(String propertyName,
 905:                                         PropertyChangeListener listener)
 906:   {
 907:     listenerList.add(PropertyChangeListener.class, listener);
 908:   }
 909: 
 910:   /**
 911:    * Register a <code>VetoableChangeListener</code>.
 912:    *
 913:    * @param listener The listener to register
 914:    *
 915:    * @see #removeVetoableChangeListener
 916:    * @see #listenerList
 917:    */
 918:   public void addVetoableChangeListener(VetoableChangeListener listener)
 919:   {
 920:     listenerList.add(VetoableChangeListener.class, listener);
 921:   }
 922: 
 923:   /**
 924:    * Returns all registered {@link EventListener}s of the given 
 925:    * <code>listenerType</code>.
 926:    *
 927:    * @param listenerType the class of listeners to filter (<code>null</code> 
 928:    *                     not permitted).
 929:    *                     
 930:    * @return An array of registered listeners.
 931:    * 
 932:    * @throws ClassCastException if <code>listenerType</code> does not implement
 933:    *                            the {@link EventListener} interface.
 934:    * @throws NullPointerException if <code>listenerType</code> is 
 935:    *                              <code>null</code>.
 936:    *                            
 937:    * @see #getAncestorListeners()
 938:    * @see #listenerList
 939:    * 
 940:    * @since 1.3
 941:    */
 942:   public EventListener[] getListeners(Class listenerType)
 943:   {
 944:     if (listenerType == PropertyChangeListener.class)
 945:       return getPropertyChangeListeners();
 946:     else
 947:       return listenerList.getListeners(listenerType);
 948:   }
 949: 
 950:   /**
 951:    * Return all registered <code>AncestorListener</code> objects.
 952:    *
 953:    * @return The set of <code>AncestorListener</code> objects in {@link
 954:    * #listenerList}
 955:    */
 956:   public AncestorListener[] getAncestorListeners()
 957:   {
 958:     return (AncestorListener[]) getListeners(AncestorListener.class);
 959:   }
 960: 
 961:   /**
 962:    * Return all registered <code>VetoableChangeListener</code> objects.
 963:    *
 964:    * @return The set of <code>VetoableChangeListener</code> objects in {@link
 965:    * #listenerList}
 966:    */
 967:   public VetoableChangeListener[] getVetoableChangeListeners()
 968:   {
 969:     return (VetoableChangeListener[]) getListeners(VetoableChangeListener.class);
 970:   }
 971: 
 972:   /**
 973:    * A variant of {@link #firePropertyChange(String,Object,Object)} 
 974:    * for properties with <code>boolean</code> values.
 975:    *
 976:    * @specnote It seems that in JDK1.5 all property related methods have been 
 977:    *           moved to java.awt.Component, except this and 2 others. We call
 978:    *           super here. I guess this will also be removed in one of the next
 979:    *           releases.
 980:    */
 981:   public void firePropertyChange(String propertyName, boolean oldValue,
 982:                                  boolean newValue)
 983:   {
 984:     super.firePropertyChange(propertyName, oldValue, newValue);
 985:   }
 986: 
 987:   /**
 988:    * A variant of {@link #firePropertyChange(String,Object,Object)} 
 989:    * for properties with <code>char</code> values.
 990:    *
 991:    * @specnote It seems that in JDK1.5 all property related methods have been 
 992:    *           moved to java.awt.Component, except this and 2 others. We call
 993:    *           super here. I guess this will also be removed in one of the next
 994:    *           releases.
 995:    */
 996:   public void firePropertyChange(String propertyName, char oldValue,
 997:                                  char newValue)
 998:   {
 999:     super.firePropertyChange(propertyName, oldValue, newValue);
1000:   }
1001: 
1002:   /**
1003:    * A variant of {@link #firePropertyChange(String,Object,Object)} 
1004:    * for properties with <code>int</code> values.
1005:    *
1006:    * @specnote It seems that in JDK1.5 all property related methods have been 
1007:    *           moved to java.awt.Component, except this and 2 others. We call
1008:    *           super here. I guess this will also be removed in one of the next
1009:    *           releases.
1010:    */
1011:   public void firePropertyChange(String propertyName, int oldValue,
1012:                                  int newValue)
1013:   {
1014:     super.firePropertyChange(propertyName, oldValue, newValue);
1015:   }
1016: 
1017:   /**
1018:    * Call {@link VetoableChangeListener#vetoableChange} on all listeners
1019:    * registered to listen to a given property. Any method which changes
1020:    * the specified property of this component should call this method.
1021:    *
1022:    * @param propertyName The property which changed
1023:    * @param oldValue The old value of the property
1024:    * @param newValue The new value of the property
1025:    *
1026:    * @throws PropertyVetoException if the change was vetoed by a listener
1027:    *
1028:    * @see #addVetoableChangeListener
1029:    * @see #removeVetoableChangeListener
1030:    */
1031:   protected void fireVetoableChange(String propertyName, Object oldValue,
1032:                                     Object newValue)
1033:     throws PropertyVetoException
1034:   {
1035:     VetoableChangeListener[] listeners = getVetoableChangeListeners();
1036: 
1037:     PropertyChangeEvent evt = 
1038:       new PropertyChangeEvent(this, propertyName, oldValue, newValue);
1039: 
1040:     for (int i = 0; i < listeners.length; i++)
1041:       listeners[i].vetoableChange(evt);
1042:   }
1043: 
1044:   /**
1045:    * Get the value of the accessibleContext property for this component.
1046:    *
1047:    * @return the current value of the property
1048:    */
1049:   public AccessibleContext getAccessibleContext()
1050:   {
1051:     return null;
1052:   }
1053: 
1054:   /**
1055:    * Get the value of the {@link #alignmentX} property.
1056:    *
1057:    * @return The current value of the property.
1058:    *
1059:    * @see #setAlignmentX
1060:    * @see #alignmentY
1061:    */
1062:   public float getAlignmentX()
1063:   {
1064:     float ret = alignmentX;
1065:     if (alignmentX < 0)
1066:       // alignment has not been set explicitly.
1067:       ret = super.getAlignmentX();
1068: 
1069:     return ret;
1070:   }
1071: 
1072:   /**
1073:    * Get the value of the {@link #alignmentY} property.
1074:    *
1075:    * @return The current value of the property.
1076:    *
1077:    * @see #setAlignmentY
1078:    * @see #alignmentX
1079:    */
1080:   public float getAlignmentY()
1081:   {
1082:     float ret = alignmentY;
1083:     if (alignmentY < 0)
1084:       // alignment has not been set explicitly.
1085:       ret = super.getAlignmentY();
1086: 
1087:     return ret;
1088:   }
1089: 
1090:   /**
1091:    * Get the current value of the {@link #autoscrolls} property.
1092:    *
1093:    * @return The current value of the property
1094:    */
1095:   public boolean getAutoscrolls()
1096:   {
1097:     return autoscrolls;
1098:   }
1099: 
1100:   /**
1101:    * Set the value of the {@link #border} property.
1102:    *   
1103:    * @param newBorder The new value of the property
1104:    *
1105:    * @see #getBorder
1106:    */
1107:   public void setBorder(Border newBorder)
1108:   {
1109:     Border oldBorder = getBorder();
1110:     if (oldBorder == newBorder)
1111:       return;
1112: 
1113:     border = newBorder;
1114:     firePropertyChange("border", oldBorder, newBorder);
1115:     repaint();
1116:   }
1117: 
1118:   /**
1119:    * Get the value of the {@link #border} property.
1120:    *
1121:    * @return The property's current value
1122:    *
1123:    * @see #setBorder
1124:    */
1125:   public Border getBorder()
1126:   {
1127:     return border;
1128:   }
1129: 
1130:   /**
1131:    * Get the component's current bounding box. If a rectangle is provided,
1132:    * use this as the return value (adjusting its fields in place);
1133:    * otherwise (of <code>null</code> is provided) return a new {@link
1134:    * Rectangle}.
1135:    *
1136:    * @param rv Optional return value to use
1137:    *
1138:    * @return A rectangle bounding the component
1139:    */
1140:   public Rectangle getBounds(Rectangle rv)
1141:   {
1142:     if (rv == null)
1143:       return new Rectangle(getX(), getY(), getWidth(), getHeight());
1144:     else
1145:       {
1146:         rv.setBounds(getX(), getY(), getWidth(), getHeight());
1147:         return rv;
1148:       }
1149:   }
1150: 
1151:   /**
1152:    * Prepares a graphics context for painting this object. If {@link
1153:    * #debugGraphicsOptions} is not equal to {@link
1154:    * DebugGraphics#NONE_OPTION}, produce a new {@link DebugGraphics} object
1155:    * wrapping the parameter. Otherwise configure the parameter with this
1156:    * component's foreground color and font.
1157:    *
1158:    * @param g The graphics context to wrap or configure
1159:    *
1160:    * @return A graphics context to paint this object with
1161:    *
1162:    * @see #debugGraphicsOptions
1163:    * @see #paint
1164:    */
1165:   protected Graphics getComponentGraphics(Graphics g)
1166:   {
1167:     Graphics g2 = g;
1168:     int options = getDebugGraphicsOptions();
1169:     if (options != DebugGraphics.NONE_OPTION)
1170:       {
1171:         if (!(g2 instanceof DebugGraphics))
1172:           g2 = new DebugGraphics(g);
1173:         DebugGraphics dg = (DebugGraphics) g2;
1174:         dg.setDebugOptions(dg.getDebugOptions() | options);
1175:       }
1176:     g2.setFont(this.getFont());
1177:     g2.setColor(this.getForeground());
1178:     return g2;
1179:   }
1180: 
1181:   /**
1182:    * Get the value of the {@link #debugGraphicsOptions} property.
1183:    *
1184:    * @return The current value of the property.
1185:    *
1186:    * @see #setDebugGraphicsOptions
1187:    * @see #debugGraphicsOptions
1188:    */
1189:   public int getDebugGraphicsOptions()
1190:   {
1191:     String option = System.getProperty("gnu.javax.swing.DebugGraphics");
1192:     int options = debugGraphicsOptions;
1193:     if (option != null && option.length() != 0)
1194:       {
1195:         if (options < 0)
1196:           options = 0;
1197: 
1198:         if (option.equals("LOG"))
1199:           options |= DebugGraphics.LOG_OPTION;
1200:         else if (option.equals("FLASH"))
1201:           options |= DebugGraphics.FLASH_OPTION;
1202:       }
1203:     return options;
1204:   }
1205: 
1206:   /**
1207:    * Get the component's insets, which are calculated from
1208:    * the {@link #border} property. If the border is <code>null</code>,
1209:    * calls {@link Container#getInsets}.
1210:    *
1211:    * @return The component's current insets
1212:    */
1213:   public Insets getInsets()
1214:   {
1215:     if (border == null)
1216:       return super.getInsets();
1217:     return getBorder().getBorderInsets(this);
1218:   }
1219: 
1220:   /**
1221:    * Get the component's insets, which are calculated from the {@link
1222:    * #border} property. If the border is <code>null</code>, calls {@link
1223:    * Container#getInsets}. The passed-in {@link Insets} value will be
1224:    * used as the return value, if possible.
1225:    *
1226:    * @param insets Return value object to reuse, if possible
1227:    *
1228:    * @return The component's current insets
1229:    */
1230:   public Insets getInsets(Insets insets)
1231:   {
1232:     Insets t = getInsets();
1233: 
1234:     if (insets == null)
1235:       return t;
1236: 
1237:     insets.left = t.left;
1238:     insets.right = t.right;
1239:     insets.top = t.top;
1240:     insets.bottom = t.bottom;
1241:     return insets;
1242:   }
1243: 
1244:   /**
1245:    * Get the component's location. The passed-in {@link Point} value
1246:    * will be used as the return value, if possible.
1247:    *
1248:    * @param rv Return value object to reuse, if possible
1249:    *
1250:    * @return The component's current location
1251:    */
1252:   public Point getLocation(Point rv)
1253:   {
1254:     if (rv == null)
1255:       return new Point(getX(), getY());
1256: 
1257:     rv.setLocation(getX(), getY());
1258:     return rv;
1259:   }
1260: 
1261:   /**
1262:    * Get the component's maximum size. If the {@link #maximumSize} property
1263:    * has been explicitly set, it is returned. If the {@link #maximumSize}
1264:    * property has not been set but the {@link #ui} property has been, the
1265:    * result of {@link ComponentUI#getMaximumSize} is returned. If neither
1266:    * property has been set, the result of {@link Container#getMaximumSize}
1267:    * is returned.
1268:    *
1269:    * @return The maximum size of the component
1270:    *
1271:    * @see #maximumSize
1272:    * @see #setMaximumSize
1273:    */
1274:   public Dimension getMaximumSize()
1275:   {
1276:     if (maximumSize != null)
1277:       return maximumSize;
1278: 
1279:     if (ui != null)
1280:       {
1281:         Dimension s = ui.getMaximumSize(this);
1282:         if (s != null)
1283:           return s;
1284:       }
1285: 
1286:     Dimension p = super.getMaximumSize();
1287:     return p;
1288:   }
1289: 
1290:   /**
1291:    * Get the component's minimum size. If the {@link #minimumSize} property
1292:    * has been explicitly set, it is returned. If the {@link #minimumSize}
1293:    * property has not been set but the {@link #ui} property has been, the
1294:    * result of {@link ComponentUI#getMinimumSize} is returned. If neither
1295:    * property has been set, the result of {@link Container#getMinimumSize}
1296:    * is returned.
1297:    *
1298:    * @return The minimum size of the component
1299:    *
1300:    * @see #minimumSize
1301:    * @see #setMinimumSize
1302:    */
1303:   public Dimension getMinimumSize()
1304:   {
1305:     if (minimumSize != null)
1306:       return minimumSize;
1307: 
1308:     if (ui != null)
1309:       {
1310:         Dimension s = ui.getMinimumSize(this);
1311:         if (s != null)
1312:           return s;
1313:       }
1314: 
1315:     Dimension p = super.getMinimumSize();
1316:     return p;
1317:   }
1318: 
1319:   /**
1320:    * Get the component's preferred size. If the {@link #preferredSize}
1321:    * property has been explicitly set, it is returned. If the {@link
1322:    * #preferredSize} property has not been set but the {@link #ui} property
1323:    * has been, the result of {@link ComponentUI#getPreferredSize} is
1324:    * returned. If neither property has been set, the result of {@link
1325:    * Container#getPreferredSize} is returned.
1326:    *
1327:    * @return The preferred size of the component
1328:    *
1329:    * @see #preferredSize
1330:    * @see #setPreferredSize
1331:    */
1332:   public Dimension getPreferredSize()
1333:   {
1334:     Dimension prefSize = null;
1335:     if (preferredSize != null)
1336:       prefSize = new Dimension(preferredSize);
1337: 
1338:     else if (ui != null)
1339:       {
1340:         Dimension s = ui.getPreferredSize(this);
1341:         if (s != null)
1342:           prefSize = s;
1343:       }
1344: 
1345:     if (prefSize == null)
1346:       prefSize = super.getPreferredSize();
1347: 
1348:     return prefSize;
1349:   }
1350: 
1351:   /**
1352:    * Checks if a maximum size was explicitely set on the component.
1353:    *
1354:    * @return <code>true</code> if a maximum size was set,
1355:    * <code>false</code> otherwise
1356:    * 
1357:    * @since 1.3
1358:    */
1359:   public boolean isMaximumSizeSet()
1360:   {
1361:     return maximumSize != null;
1362:   }
1363: 
1364:   /**
1365:    * Checks if a minimum size was explicitely set on the component.
1366:    *
1367:    * @return <code>true</code> if a minimum size was set,
1368:    * <code>false</code> otherwise
1369:    * 
1370:    * @since 1.3
1371:    */
1372:   public boolean isMinimumSizeSet()
1373:   {
1374:     return minimumSize != null;
1375:   }
1376: 
1377:   /**
1378:    * Checks if a preferred size was explicitely set on the component.
1379:    *
1380:    * @return <code>true</code> if a preferred size was set,
1381:    * <code>false</code> otherwise
1382:    * 
1383:    * @since 1.3
1384:    */
1385:   public boolean isPreferredSizeSet()
1386:   {
1387:     return preferredSize != null;
1388:   }
1389:   
1390:   /**
1391:    * Return the value of the <code>nextFocusableComponent</code> property.
1392:    *
1393:    * @return The current value of the property, or <code>null</code>
1394:    * if none has been set.
1395:    * 
1396:    * @deprecated See {@link java.awt.FocusTraversalPolicy}
1397:    */
1398:   public Component getNextFocusableComponent()
1399:   {
1400:     Container focusRoot = this;
1401:     if (! this.isFocusCycleRoot())
1402:       focusRoot = getFocusCycleRootAncestor();
1403: 
1404:     FocusTraversalPolicy policy  = focusRoot.getFocusTraversalPolicy();
1405:     return policy.getComponentAfter(focusRoot, this);
1406:   }
1407: 
1408:   /**
1409:    * Return the set of {@link KeyStroke} objects which are registered
1410:    * to initiate actions on this component.
1411:    *
1412:    * @return An array of the registered keystrokes
1413:    */
1414:   public KeyStroke[] getRegisteredKeyStrokes()
1415:   {
1416:     return null;
1417:   }
1418: 
1419:   /**
1420:    * Returns the first ancestor of this component which is a {@link JRootPane}.
1421:    * Equivalent to calling <code>SwingUtilities.getRootPane(this);</code>.
1422:    *
1423:    * @return An ancestral JRootPane, or <code>null</code> if none exists.
1424:    */
1425:   public JRootPane getRootPane()
1426:   {
1427:     JRootPane p = SwingUtilities.getRootPane(this);
1428:     return p;
1429:   }
1430: 
1431:   /**
1432:    * Get the component's size. The passed-in {@link Dimension} value
1433:    * will be used as the return value, if possible.
1434:    *
1435:    * @param rv Return value object to reuse, if possible
1436:    *
1437:    * @return The component's current size
1438:    */
1439:   public Dimension getSize(Dimension rv)
1440:   {
1441:     if (rv == null)
1442:       return new Dimension(getWidth(), getHeight());
1443:     else
1444:       {
1445:         rv.setSize(getWidth(), getHeight());
1446:         return rv;
1447:       }
1448:   }
1449: 
1450:   /**
1451:    * Return the <code>toolTip</code> property of this component, creating it and
1452:    * setting it if it is currently <code>null</code>. This method can be
1453:    * overridden in subclasses which wish to control the exact form of
1454:    * tooltip created.
1455:    *
1456:    * @return The current toolTip
1457:    */
1458:   public JToolTip createToolTip()
1459:   {
1460:     JToolTip toolTip = new JToolTip();
1461:     toolTip.setComponent(this);
1462:     toolTip.setTipText(toolTipText);
1463: 
1464:     return toolTip;
1465:   }
1466: 
1467:   /**
1468:    * Return the location at which the {@link #toolTipText} property should be
1469:    * displayed, when triggered by a particular mouse event. 
1470:    *
1471:    * @param event The event the tooltip is being presented in response to
1472:    *
1473:    * @return The point at which to display a tooltip, or <code>null</code>
1474:    *     if swing is to choose a default location.
1475:    */
1476:   public Point getToolTipLocation(MouseEvent event)
1477:   {
1478:     return null;
1479:   }
1480: 
1481:   /**
1482:    * Set the value of the {@link #toolTipText} property.
1483:    *
1484:    * @param text The new property value
1485:    *
1486:    * @see #getToolTipText()
1487:    */
1488:   public void setToolTipText(String text)
1489:   {
1490:     if (text == null)
1491:     {
1492:       ToolTipManager.sharedInstance().unregisterComponent(this);
1493:       toolTipText = null;
1494:       return;
1495:     }
1496: 
1497:     // XXX: The tip text doesn't get updated unless you set it to null
1498:     // and then to something not-null. This is consistent with the behaviour
1499:     // of Sun's ToolTipManager.
1500: 
1501:     String oldText = toolTipText;
1502:     toolTipText = text;
1503: 
1504:     if (oldText == null)
1505:       ToolTipManager.sharedInstance().registerComponent(this);
1506:   }
1507: 
1508:   /**
1509:    * Get the value of the {@link #toolTipText} property.
1510:    *
1511:    * @return The current property value
1512:    *
1513:    * @see #setToolTipText
1514:    */
1515:   public String getToolTipText()
1516:   {
1517:     return toolTipText;
1518:   }
1519: 
1520:   /**
1521:    * Get the value of the {@link #toolTipText} property, in response to a
1522:    * particular mouse event.
1523:    *
1524:    * @param event The mouse event which triggered the tooltip
1525:    *
1526:    * @return The current property value
1527:    *
1528:    * @see #setToolTipText
1529:    */
1530:   public String getToolTipText(MouseEvent event)
1531:   {
1532:     return getToolTipText();
1533:   }
1534: 
1535:   /**
1536:    * Return the top level ancestral container (usually a {@link
1537:    * java.awt.Window} or {@link java.applet.Applet}) which this component is
1538:    * contained within, or <code>null</code> if no ancestors exist.
1539:    *
1540:    * @return The top level container, if it exists
1541:    */
1542:   public Container getTopLevelAncestor()
1543:   {
1544:     Container c = getParent();
1545:     for (Container peek = c; peek != null; peek = peek.getParent())
1546:       c = peek;
1547:     return c;
1548:   }
1549: 
1550:   /**
1551:    * Compute the component's visible rectangle, which is defined
1552:    * recursively as either the component's bounds, if it has no parent, or
1553:    * the intersection of the component's bounds with the visible rectangle
1554:    * of its parent.
1555:    *
1556:    * @param rect The return value slot to place the visible rectangle in
1557:    */
1558:   public void computeVisibleRect(Rectangle rect)
1559:   {
1560:     Component c = getParent();
1561:     if (c != null && c instanceof JComponent)
1562:       {
1563:         ((JComponent) c).computeVisibleRect(rect);
1564:         rect.translate(-getX(), -getY());
1565:         rect = SwingUtilities.computeIntersection(0, 0, getWidth(),
1566:                                                   getHeight(), rect);
1567:       }
1568:     else
1569:       rect.setRect(0, 0, getWidth(), getHeight());
1570:   }
1571: 
1572:   /**
1573:    * Return the component's visible rectangle in a new {@link Rectangle},
1574:    * rather than via a return slot.
1575:    *
1576:    * @return the component's visible rectangle
1577:    *
1578:    * @see #computeVisibleRect(Rectangle)
1579:    */
1580:   public Rectangle getVisibleRect()
1581:   {
1582:     Rectangle r = new Rectangle();
1583:     computeVisibleRect(r);
1584:     return r;
1585:   }
1586: 
1587:   /**
1588:    * <p>Requests that this component receive input focus, giving window
1589:    * focus to the top level ancestor of this component. Only works on
1590:    * displayable, focusable, visible components.</p>
1591:    *
1592:    * <p>This method should not be called by clients; it is intended for
1593:    * focus implementations. Use {@link Component#requestFocus()} instead.</p>
1594:    *
1595:    * @see Component#requestFocus()
1596:    */
1597:   public void grabFocus()
1598:   {
1599:     requestFocus();
1600:   }
1601: 
1602:   /**
1603:    * Get the value of the {@link #doubleBuffered} property.
1604:    *
1605:    * @return The property's current value
1606:    */
1607:   public boolean isDoubleBuffered()
1608:   {
1609:     return doubleBuffered;
1610:   }
1611: 
1612:   /**
1613:    * Return <code>true</code> if the provided component has no native peer;
1614:    * in other words, if it is a "lightweight component".
1615:    *
1616:    * @param c The component to test for lightweight-ness
1617:    *
1618:    * @return Whether or not the component is lightweight
1619:    */
1620:   public static boolean isLightweightComponent(Component c)
1621:   {
1622:     return c.getPeer() instanceof LightweightPeer;
1623:   }
1624: 
1625:   /**
1626:    * Return <code>true</code> if you wish this component to manage its own
1627:    * focus. In particular: if you want this component to be sent
1628:    * <code>TAB</code> and <code>SHIFT+TAB</code> key events, and to not
1629:    * have its children considered as focus transfer targets. If
1630:    * <code>true</code>, focus traversal around this component changes to
1631:    * <code>CTRL+TAB</code> and <code>CTRL+SHIFT+TAB</code>.
1632:    *
1633:    * @return <code>true</code> if you want this component to manage its own
1634:    *     focus, otherwise (by default) <code>false</code>
1635:    *
1636:    * @deprecated 1.4 Use {@link Component#setFocusTraversalKeys(int, Set)} and
1637:    *     {@link Container#setFocusCycleRoot(boolean)} instead
1638:    */
1639:   public boolean isManagingFocus()
1640:   {
1641:     return false;
1642:   }
1643: 
1644:   /**
1645:    * Return the current value of the {@link #opaque} property. 
1646:    *
1647:    * @return The current property value
1648:    */
1649:   public boolean isOpaque()
1650:   {
1651:     return opaque;
1652:   }
1653: 
1654:   /**
1655:    * Return <code>true</code> if the component can guarantee that none of its
1656:    * children will overlap in Z-order. This is a hint to the painting system.
1657:    * The default is to return <code>true</code>, but some components such as
1658:    * {@link JLayeredPane} should override this to return <code>false</code>.
1659:    *
1660:    * @return Whether the component tiles its children
1661:    */
1662:   public boolean isOptimizedDrawingEnabled()
1663:   {
1664:     return true;
1665:   }
1666: 
1667:   /**
1668:    * Return <code>true</code> if this component is currently painting a tile,
1669:    * this means that paint() is called again on another child component. This
1670:    * method returns <code>false</code> if this component does not paint a tile
1671:    * or if the last tile is currently painted.
1672:    *
1673:    * @return whether the component is painting a tile
1674:    */
1675:   public boolean isPaintingTile()
1676:   {
1677:     return paintingTile;
1678:   }
1679: 
1680:   /**
1681:    * Get the value of the {@link #requestFocusEnabled} property.
1682:    *
1683:    * @return The current value of the property
1684:    */
1685:   public boolean isRequestFocusEnabled()
1686:   {
1687:     return requestFocusEnabled;
1688:   }
1689: 
1690:   /**
1691:    * Return <code>true</code> if this component is a validation root; this
1692:    * will cause calls to {@link #invalidate()} in this component's children
1693:    * to be "captured" at this component, and not propagate to its parents.
1694:    * For most components this should return <code>false</code>, but some
1695:    * components such as {@link JViewport} will want to return
1696:    * <code>true</code>.
1697:    *
1698:    * @return Whether this component is a validation root
1699:    */
1700:   public boolean isValidateRoot()
1701:   {
1702:     return false;
1703:   }
1704: 
1705:   /**
1706:    * <p>Paint the component. This is a delicate process, and should only be
1707:    * called from the repaint thread, under control of the {@link
1708:    * RepaintManager}. Client code should usually call {@link #repaint()} to
1709:    * trigger painting.</p>
1710:    *
1711:    * <p>The body of the <code>paint</code> call involves calling {@link
1712:    * #paintComponent}, {@link #paintBorder}, and {@link #paintChildren} in
1713:    * order. If you want to customize painting behavior, you should override
1714:    * one of these methods rather than <code>paint</code>.</p>
1715:    *
1716:    * <p>For more details on the painting sequence, see <a
1717:    * href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">
1718:    * this article</a>.</p>
1719:    *
1720:    * @param g The graphics context to paint with
1721:    *
1722:    * @see #paintImmediately(Rectangle)
1723:    */
1724:   public void paint(Graphics g)
1725:   {
1726:     RepaintManager rm = RepaintManager.currentManager(this);
1727:     // We do a little stunt act here to switch on double buffering if it's
1728:     // not already on. If we are not already doublebuffered, then we jump
1729:     // into the method paintDoubleBuffered, which turns on the double buffer
1730:     // and then calls paint(g) again. In the second call we go into the else
1731:     // branch of this if statement and actually paint things to the double
1732:     // buffer. When this method completes, the call stack unwinds back to
1733:     // paintDoubleBuffered, where the buffer contents is finally drawn to the
1734:     // screen.
1735:     if (!isPaintingDoubleBuffered && isDoubleBuffered()
1736:         && rm.isDoubleBufferingEnabled())
1737:       {
1738:         Rectangle clip = g.getClipBounds();
1739:         paintDoubleBuffered(clip);
1740:       }
1741:     else
1742:       {
1743:         if (getClientProperty("bufferedDragging") != null
1744:             && dragBuffer == null)
1745:           {
1746:             initializeDragBuffer();
1747:           }
1748:         else if (getClientProperty("bufferedDragging") == null
1749:             && dragBuffer != null)
1750:           {
1751:             dragBuffer = null;
1752:           }
1753: 
1754:         if (g.getClip() == null)
1755:           g.setClip(0, 0, getWidth(), getHeight());
1756:         if (dragBuffer != null && dragBufferInitialized)
1757:           {
1758:             g.drawImage(dragBuffer, 0, 0, this);
1759:           }
1760:         else
1761:           {
1762:             Graphics g2 = getComponentGraphics(g);
1763:             paintComponent(g2);
1764:             paintBorder(g2);
1765:             paintChildren(g2);
1766:             Rectangle clip = g2.getClipBounds();
1767:             if (clip == null
1768:                 || (clip.x == 0 && clip.y == 0 && clip.width == getWidth()
1769:                 && clip.height == getHeight()))
1770:               RepaintManager.currentManager(this).markCompletelyClean(this);
1771:           }
1772:       }
1773:   }
1774: 
1775:   /**
1776:    * Initializes the drag buffer by creating a new image and painting this
1777:    * component into it.
1778:    */
1779:   private void initializeDragBuffer()
1780:   {
1781:     dragBufferInitialized = false;
1782:     // Allocate new dragBuffer if the current one is too small.
1783:     if (dragBuffer == null || dragBuffer.getWidth(this) < getWidth()
1784:         || dragBuffer.getHeight(this) < getHeight())
1785:       {
1786:         dragBuffer = createImage(getWidth(), getHeight());
1787:       }
1788:     Graphics g = dragBuffer.getGraphics();
1789:     paint(g);
1790:     g.dispose();
1791:     dragBufferInitialized = true;
1792:   }
1793: 
1794:   /**
1795:    * Paint the component's border. This usually means calling {@link
1796:    * Border#paintBorder} on the {@link #border} property, if it is
1797:    * non-<code>null</code>. You may override this if you wish to customize
1798:    * border painting behavior. The border is painted after the component's
1799:    * body, but before the component's children.
1800:    *
1801:    * @param g The graphics context with which to paint the border
1802:    *
1803:    * @see #paint
1804:    * @see #paintChildren
1805:    * @see #paintComponent
1806:    */
1807:   protected void paintBorder(Graphics g)
1808:   {
1809:     if (getBorder() != null)
1810:       getBorder().paintBorder(this, g, 0, 0, getWidth(), getHeight());
1811:   }
1812: 
1813:   /**
1814:    * Paint the component's children. This usually means calling {@link
1815:    * Container#paint}, which recursively calls {@link #paint} on any of the
1816:    * component's children, with appropriate changes to coordinate space and
1817:    * clipping region. You may override this if you wish to customize
1818:    * children painting behavior. The children are painted after the
1819:    * component's body and border.
1820:    *
1821:    * @param g The graphics context with which to paint the children
1822:    *
1823:    * @see #paint
1824:    * @see #paintBorder
1825:    * @see #paintComponent
1826:    */
1827:   protected void paintChildren(Graphics g)
1828:   {
1829:     if (getComponentCount() > 0)
1830:       {
1831:         if (isOptimizedDrawingEnabled())
1832:           paintChildrenOptimized(g);
1833:         else
1834:           paintChildrenWithOverlap(g);
1835:       }
1836:   }
1837: 
1838:   /**
1839:    * Paints the children of this JComponent in the case when the component
1840:    * is not marked as optimizedDrawingEnabled, that means the container cannot
1841:    * guarantee that it's children are tiled. For this case we must
1842:    * perform a more complex optimization to determine the minimal rectangle
1843:    * to be painted for each child component.
1844:    *
1845:    * @param g the graphics context to use
1846:    */
1847:   private void paintChildrenWithOverlap(Graphics g)
1848:   {
1849:     Shape originalClip = g.getClip();
1850:     Rectangle inner = SwingUtilities.calculateInnerArea(this, rectCache);
1851:     g.clipRect(inner.x, inner.y, inner.width, inner.height);
1852:     Component[] children = getComponents();
1853: 
1854:     // Find the rectangles that need to be painted for each child component.
1855:     // We push on this list arrays that have the Rectangles to be painted as
1856:     // the first elements and the component to be painted as the last one.
1857:     // Later we go through that list in reverse order and paint the rectangles.
1858:     ArrayList paintRegions = new ArrayList(children.length);
1859:     ArrayList paintRectangles = new ArrayList();
1860:     ArrayList newPaintRects = new ArrayList();
1861:     paintRectangles.add(g.getClipBounds());
1862:     ArrayList componentRectangles = new ArrayList();
1863: 
1864:     // Go through children from top to bottom and find out their paint
1865:     // rectangles.
1866:     for (int index = 0; paintRectangles.size() > 0 &&
1867:       index < children.length; index++)
1868:       {
1869:         Component comp = children[index];
1870:         if (! comp.isVisible())
1871:           continue;
1872: 
1873:         Rectangle compBounds = comp.getBounds();
1874:         boolean isOpaque = comp instanceof JComponent
1875:                            && ((JComponent) comp).isOpaque();
1876: 
1877:         // Add all the current paint rectangles that intersect with the
1878:         // component to the component's paint rectangle array.
1879:         for (int i = paintRectangles.size() - 1; i >= 0; i--)
1880:           {
1881:             Rectangle r = (Rectangle) paintRectangles.get(i);
1882:             if (r.intersects(compBounds))
1883:               {
1884:                 Rectangle compRect = r.intersection(compBounds);
1885:                 componentRectangles.add(compRect);
1886:                 // If the component is opaque, split up each paint rect and
1887:                 // add paintRect - compBounds to the newPaintRects array.
1888:                 if (isOpaque)
1889:                   {
1890:                     int x, y, w, h;
1891:                     Rectangle rect = new Rectangle();
1892: 
1893:                     // The north retangle.
1894:                     x = Math.max(compBounds.x, r.x);
1895:                     y = r.y;
1896:                     w = Math.min(compBounds.width, r.width + r.x - x);
1897:                     h = compBounds.y - r.y;
1898:                     rect.setBounds(x, y, w, h);
1899:                     if (! rect.isEmpty())
1900:                       {
1901:                         newPaintRects.add(rect);
1902:                         rect = new Rectangle();
1903:                       }
1904: 
1905:                     // The south rectangle.
1906:                     x = Math.max(compBounds.x, r.x);
1907:                     y = compBounds.y + compBounds.height;
1908:                     w = Math.min(compBounds.width, r.width + r.x - x);
1909:                     h = r.height - (compBounds.y - r.y) - compBounds.height;
1910:                     rect.setBounds(x, y, w, h);
1911:                     if (! rect.isEmpty())
1912:                       {
1913:                         newPaintRects.add(rect);
1914:                         rect = new Rectangle();
1915:                       }
1916: 
1917:                     // The west rectangle.
1918:                     x = r.x;
1919:                     y = r.y;
1920:                     w = compBounds.x - r.x;
1921:                     h = r.height;
1922:                     rect.setBounds(x, y, w, h);
1923:                     if (! rect.isEmpty())
1924:                       {
1925:                         newPaintRects.add(rect);
1926:                         rect = new Rectangle();
1927:                       }
1928: 
1929:                     // The east rectangle.
1930:                     x = compBounds.x + compBounds.width;
1931:                     y = r.y;
1932:                     w = r.width - (compBounds.x - r.x) - compBounds.width;
1933:                     h = r.height;
1934:                     rect.setBounds(x, y, w, h);
1935:                     if (! rect.isEmpty())
1936:                       {
1937:                         newPaintRects.add(rect);
1938:                       }
1939:                   }
1940:                 else
1941:                   {
1942:                     // Not opaque, need to reuse the current paint rectangles
1943:                     // for the next component.
1944:                     newPaintRects.add(r);
1945:                   }
1946:                 
1947:               }
1948:             else
1949:               {
1950:                 newPaintRects.add(r);
1951:               }
1952:           }
1953: 
1954:         // Replace the paintRectangles with the new split up
1955:         // paintRectangles.
1956:         paintRectangles.clear();
1957:         paintRectangles.addAll(newPaintRects);
1958:         newPaintRects.clear();
1959: 
1960:         // Store paint rectangles if there are any for the current component.
1961:         int compRectsSize = componentRectangles.size();
1962:         if (compRectsSize > 0)
1963:           {
1964:             componentRectangles.add(comp);
1965:             paintRegions.add(componentRectangles);
1966:             componentRectangles = new ArrayList();
1967:           }
1968:       }
1969: 
1970:     // paintingTile becomes true just before we start painting the component's
1971:     // children.
1972:     paintingTile = true;
1973: 
1974:     // We must go through the painting regions backwards, because the
1975:     // topmost components have been added first, followed by the components
1976:     // below.
1977:     int prEndIndex = paintRegions.size() - 1;
1978:     for (int i = prEndIndex; i >= 0; i--)
1979:       {
1980:         // paintingTile must be set to false before we begin to start painting
1981:         // the last tile.
1982:         if (i == 0)
1983:           paintingTile = false;
1984: 
1985:         ArrayList paintingRects = (ArrayList) paintRegions.get(i);
1986:         // The last element is always the component.
1987:         Component c = (Component) paintingRects.get(paintingRects.size() - 1);
1988:         int endIndex = paintingRects.size() - 2;
1989:         for (int j = 0; j <= endIndex; j++)
1990:           {
1991:             Rectangle cBounds = c.getBounds();
1992:             Rectangle bounds = (Rectangle) paintingRects.get(j);
1993:             Rectangle oldClip = g.getClipBounds();
1994:             if (oldClip == null)
1995:               oldClip = bounds;
1996: 
1997:             boolean translated = false;
1998:             try
1999:               {
2000:                 g.setClip(bounds);
2001:                 g.translate(cBounds.x, cBounds.y);
2002:                 translated = true;
2003:                 c.paint(g);
2004:               }
2005:             finally
2006:               {
2007:                 if (translated)
2008:                   g.translate(-cBounds.x, -cBounds.y);
2009:                 g.setClip(oldClip);
2010:               }
2011:           }
2012:       }
2013:     g.setClip(originalClip);
2014:   }
2015: 
2016:   /**
2017:    * Paints the children of this container when it is marked as
2018:    * optimizedDrawingEnabled. In this case the container can guarantee that
2019:    * it's children are tiled, which allows for a much more efficient
2020:    * algorithm to determine the minimum rectangles to be painted for
2021:    * each child.
2022:    *
2023:    * @param g the graphics context to use
2024:    */
2025:   private void paintChildrenOptimized(Graphics g)
2026:   {
2027:     Shape originalClip = g.getClip();
2028:     Rectangle inner = SwingUtilities.calculateInnerArea(this, rectCache);
2029:     g.clipRect(inner.x, inner.y, inner.width, inner.height);
2030:     Component[] children = getComponents();
2031: 
2032:     // paintingTile becomes true just before we start painting the component's
2033:     // children.
2034:     paintingTile = true;
2035:     for (int i = children.length - 1; i >= 0; i--) //children.length; i++)
2036:       {
2037:         // paintingTile must be set to false before we begin to start painting
2038:         // the last tile.
2039:         if (i == children.length - 1)
2040:           paintingTile = false;
2041: 
2042:         if (!children[i].isVisible())
2043:           continue;
2044: 
2045:         Rectangle bounds = children[i].getBounds(rectCache);
2046:         Rectangle oldClip = g.getClipBounds();
2047:         if (oldClip == null)
2048:           oldClip = bounds;
2049: 
2050:         if (!g.hitClip(bounds.x, bounds.y, bounds.width, bounds.height))
2051:           continue;
2052: 
2053:         boolean translated = false;
2054:         try
2055:           {
2056:             g.clipRect(bounds.x, bounds.y, bounds.width, bounds.height);
2057:             g.translate(bounds.x, bounds.y);
2058:             translated = true;
2059:             children[i].paint(g);
2060:           }
2061:         finally
2062:           {
2063:             if (translated)
2064:               g.translate(-bounds.x, -bounds.y);
2065:             g.setClip(oldClip);
2066:           }
2067:       }
2068:     g.setClip(originalClip);
2069:   }
2070: 
2071:   /**
2072:    * Paint the component's body. This usually means calling {@link
2073:    * ComponentUI#update} on the {@link #ui} property of the component, if
2074:    * it is non-<code>null</code>. You may override this if you wish to
2075:    * customize the component's body-painting behavior. The component's body
2076:    * is painted first, before the border and children.
2077:    *
2078:    * @param g The graphics context with which to paint the body
2079:    *
2080:    * @see #paint
2081:    * @see #paintBorder
2082:    * @see #paintChildren
2083:    */
2084:   protected void paintComponent(Graphics g)
2085:   {
2086:     if (ui != null)
2087:       {
2088:         Graphics g2 = g;
2089:         if (!(g instanceof Graphics2D))
2090:           g2 = g.create();
2091:         ui.update(g2, this);
2092:         if (!(g instanceof Graphics2D))
2093:           g2.dispose();
2094:       }
2095:   }
2096: 
2097:   /**
2098:    * A variant of {@link #paintImmediately(Rectangle)} which takes
2099:    * integer parameters.
2100:    *
2101:    * @param x The left x coordinate of the dirty region
2102:    * @param y The top y coordinate of the dirty region
2103:    * @param w The width of the dirty region
2104:    * @param h The height of the dirty region
2105:    */
2106:   public void paintImmediately(int x, int y, int w, int h)
2107:   {
2108:     paintImmediately(new Rectangle(x, y, w, h));
2109:   }
2110: 
2111:   /**
2112:    * Transform the provided dirty rectangle for this component into the
2113:    * appropriate ancestral {@link JRootPane} and call {@link #paint} on
2114:    * that root pane. This method is called from the {@link RepaintManager}
2115:    * and should always be called within the painting thread.
2116:    *
2117:    * <p>This method will acquire a double buffer from the {@link
2118:    * RepaintManager} if the component's {@link #doubleBuffered} property is
2119:    * <code>true</code> and the <code>paint</code> call is the
2120:    * <em>first</em> recursive <code>paint</code> call inside swing.</p>
2121:    *
2122:    * <p>The method will also modify the provided {@link Graphics} context
2123:    * via the {@link #getComponentGraphics} method. If you want to customize
2124:    * the graphics object used for painting, you should override that method
2125:    * rather than <code>paint</code>.</p>
2126:    *
2127:    * @param r The dirty rectangle to paint
2128:    */
2129:   public void paintImmediately(Rectangle r)
2130:   {
2131:     // Try to find a root pane for this component.
2132:     //Component root = findPaintRoot(r);
2133:     Component root = findPaintRoot(r);
2134:     // If no paint root is found, then this component is completely overlapped
2135:     // by another component and we don't need repainting.
2136:     if (root == null)
2137:       return;
2138:     if (root == null || !root.isShowing())
2139:       return;
2140: 
2141:     Rectangle rootClip = SwingUtilities.convertRectangle(this, r, root);
2142:     if (root instanceof JComponent)
2143:       ((JComponent) root).paintImmediately2(rootClip);
2144:     else
2145:       root.repaint(rootClip.x, rootClip.y, rootClip.width, rootClip.height);
2146:   }
2147: 
2148:   /**
2149:    * Performs the actual work of paintImmediatly on the repaint root.
2150:    *
2151:    * @param r the area to be repainted
2152:    */
2153:   void paintImmediately2(Rectangle r)
2154:   {
2155:     RepaintManager rm = RepaintManager.currentManager(this);
2156:     if (rm.isDoubleBufferingEnabled() && isDoubleBuffered())
2157:       paintDoubleBuffered(r);
2158:     else
2159:       paintSimple(r);
2160:   }
2161: 
2162:   /**
2163:    * Gets the root of the component given. If a parent of the 
2164:    * component is an instance of Applet, then the applet is 
2165:    * returned. The applet is considered the root for painting
2166:    * and adding/removing components. Otherwise, the root Window
2167:    * is returned if it exists.
2168:    * 
2169:    * @param comp - The component to get the root for.
2170:    * @return the parent root. An applet if it is a parent,
2171:    * or the root window. If neither exist, null is returned.
2172:    */
2173:   private Component getRoot(Component comp)
2174:   {
2175:       Applet app = null;
2176:       
2177:       while (comp != null)
2178:         {
2179:           if (app == null && comp instanceof Window)
2180:             return comp;
2181:           else if (comp instanceof Applet)
2182:             app = (Applet) comp;
2183:           comp = comp.getParent();
2184:         }
2185:       
2186:       return app;
2187:   }
2188:   
2189:   /**
2190:    * Performs double buffered repainting.
2191:    */
2192:   private void paintDoubleBuffered(Rectangle r)
2193:   {
2194:     RepaintManager rm = RepaintManager.currentManager(this);
2195: 
2196:     // Paint on the offscreen buffer.
2197:     Component root = getRoot(this);
2198:     Image buffer = rm.getOffscreenBuffer(this, root.getWidth(),
2199:                                          root.getHeight());
2200:     //Rectangle targetClip = SwingUtilities.convertRectangle(this, r, root);
2201:     Point translation = SwingUtilities.convertPoint(this, 0, 0, root);
2202:     Graphics g2 = buffer.getGraphics();
2203:     g2.translate(translation.x, translation.y);
2204:     g2.setClip(r.x, r.y, r.width, r.height);
2205:     g2 = getComponentGraphics(g2);
2206:     isPaintingDoubleBuffered = true;
2207:     try
2208:       {
2209:         paint(g2);
2210:       }
2211:     finally
2212:       {
2213:         isPaintingDoubleBuffered = false;
2214:         g2.dispose();
2215:       }
2216: 
2217:     // Paint the buffer contents on screen.
2218:     rm.commitBuffer(root, new Rectangle(translation.x + r.x,
2219:                                         translation.y + r.y, r.width,
2220:                                         r.height));
2221:   }
2222: 
2223:   /**
2224:    * Performs normal painting without double buffering.
2225:    *
2226:    * @param r the area that should be repainted
2227:    */
2228:   void paintSimple(Rectangle r)
2229:   {
2230:     Graphics g = getGraphics();
2231:     Graphics g2 = getComponentGraphics(g);
2232:     g2.setClip(r);
2233:     paint(g2);
2234:     g2.dispose();
2235:     if (g != g2)
2236:       g.dispose();
2237:   }
2238: 
2239:   /**
2240:    * Return a string representation for this component, for use in
2241:    * debugging.
2242:    *
2243:    * @return A string describing this component.
2244:    */
2245:   protected String paramString()
2246:   {
2247:     StringBuffer sb = new StringBuffer();
2248:     sb.append(super.paramString());
2249:     sb.append(",alignmentX=").append(getAlignmentX());
2250:     sb.append(",alignmentY=").append(getAlignmentY());
2251:     sb.append(",border=");
2252:     if (getBorder() != null)
2253:       sb.append(getBorder());
2254:     sb.append(",maximumSize=");
2255:     if (getMaximumSize() != null)
2256:       sb.append(getMaximumSize());
2257:     sb.append(",minimumSize=");
2258:     if (getMinimumSize() != null)
2259:       sb.append(getMinimumSize());
2260:     sb.append(",preferredSize=");
2261:     if (getPreferredSize() != null)
2262:       sb.append(getPreferredSize());
2263:     return sb.toString();
2264:   }
2265: 
2266:   /**
2267:    * A variant of {@link
2268:    * #registerKeyboardAction(ActionListener,String,KeyStroke,int)} which
2269:    * provides <code>null</code> for the command name.   
2270:    */
2271:   public void registerKeyboardAction(ActionListener act,
2272:                                      KeyStroke stroke, 
2273:                                      int cond)
2274:   {
2275:     registerKeyboardAction(act, null, stroke, cond);
2276:   }
2277: 
2278:   /* 
2279:    * There is some charmingly undocumented behavior sun seems to be using
2280:    * to simulate the old register/unregister keyboard binding API. It's not
2281:    * clear to me why this matters, but we shall endeavour to follow suit.
2282:    *
2283:    * Two main thing seem to be happening when you do registerKeyboardAction():
2284:    * 
2285:    *  - no actionMap() entry gets created, just an entry in inputMap()
2286:    *
2287:    *  - the inputMap() entry is a proxy class which invokes the the
2288:    *  binding's actionListener as a target, and which clobbers the command
2289:    *  name sent in the ActionEvent, providing the binding command name
2290:    *  instead.
2291:    *
2292:    * This much you can work out just by asking the input and action maps
2293:    * what they contain after making bindings, and watching the event which
2294:    * gets delivered to the recipient. Beyond that, it seems to be a
2295:    * sun-private solution so I will only immitate it as much as it matters
2296:    * to external observers.
2297:    */
2298:   private static class ActionListenerProxy
2299:     extends AbstractAction
2300:   {
2301:     ActionListener target;
2302:     String bindingCommandName;
2303: 
2304:     public ActionListenerProxy(ActionListener li, 
2305:                                String cmd)
2306:     {
2307:       target = li;
2308:       bindingCommandName = cmd;
2309:     }
2310: 
2311:     public void actionPerformed(ActionEvent e)
2312:     {
2313:       ActionEvent derivedEvent = new ActionEvent(e.getSource(),
2314:                                                  e.getID(),
2315:                                                  bindingCommandName,
2316:                                                  e.getModifiers());
2317:       target.actionPerformed(derivedEvent);
2318:     }
2319:   }
2320: 
2321:   
2322:   /**
2323:    * An obsolete method to register a keyboard action on this component.
2324:    * You should use <code>getInputMap</code> and <code>getActionMap</code>
2325:    * to fetch mapping tables from keystrokes to commands, and commands to
2326:    * actions, respectively, and modify those mappings directly.
2327:    *
2328:    * @param act The action to be registered
2329:    * @param cmd The command to deliver in the delivered {@link
2330:    *     java.awt.event.ActionEvent}
2331:    * @param stroke The keystroke to register on
2332:    * @param cond One of the values {@link #UNDEFINED_CONDITION},
2333:    *     {@link #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}, {@link #WHEN_FOCUSED}, or
2334:    *     {@link #WHEN_IN_FOCUSED_WINDOW}, indicating the condition which must
2335:    *     be met for the action to be fired
2336:    *
2337:    * @see #unregisterKeyboardAction
2338:    * @see #getConditionForKeyStroke
2339:    * @see #resetKeyboardActions
2340:    */
2341:   public void registerKeyboardAction(ActionListener act, 
2342:                                      String cmd,
2343:                                      KeyStroke stroke, 
2344:                                      int cond)
2345:   {
2346:     getInputMap(cond).put(stroke, new ActionListenerProxy(act, cmd));
2347:   }
2348: 
2349:   public final void setInputMap(int condition, InputMap map)
2350:   {
2351:     enableEvents(AWTEvent.KEY_EVENT_MASK);
2352:     switch (condition)
2353:       {
2354:       case WHEN_FOCUSED:
2355:         inputMap_whenFocused = map;
2356:         break;
2357: 
2358:       case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
2359:         inputMap_whenAncestorOfFocused = map;
2360:         break;
2361: 
2362:       case WHEN_IN_FOCUSED_WINDOW:
2363:         if (map != null && !(map instanceof ComponentInputMap))
2364:             throw new 
2365:               IllegalArgumentException("WHEN_IN_FOCUSED_WINDOW " + 
2366:                                        "InputMap must be a ComponentInputMap");
2367:         inputMap_whenInFocusedWindow = (ComponentInputMap)map;
2368:         break;
2369:         
2370:       case UNDEFINED_CONDITION:
2371:       default:
2372:         throw new IllegalArgumentException();
2373:       }
2374:   }
2375: 
2376:   public final InputMap getInputMap(int condition)
2377:   {
2378:     enableEvents(AWTEvent.KEY_EVENT_MASK);
2379:     switch (condition)
2380:       {
2381:       case WHEN_FOCUSED:
2382:         if (inputMap_whenFocused == null)
2383:           inputMap_whenFocused = new InputMap();
2384:         return inputMap_whenFocused;
2385: 
2386:       case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
2387:         if (inputMap_whenAncestorOfFocused == null)
2388:           inputMap_whenAncestorOfFocused = new InputMap();
2389:         return inputMap_whenAncestorOfFocused;
2390: 
2391:       case WHEN_IN_FOCUSED_WINDOW:
2392:         if (inputMap_whenInFocusedWindow == null)
2393:           inputMap_whenInFocusedWindow = new ComponentInputMap(this);
2394:         return inputMap_whenInFocusedWindow;
2395: 
2396:       case UNDEFINED_CONDITION:
2397:       default:
2398:         return null;
2399:       }
2400:   }
2401: 
2402:   public final InputMap getInputMap()
2403:   {
2404:     return getInputMap(WHEN_FOCUSED);
2405:   }
2406: 
2407:   public final ActionMap getActionMap()
2408:   {
2409:     if (actionMap == null)
2410:       actionMap = new ActionMap();
2411:     return actionMap;
2412:   }
2413: 
2414:   public final void setActionMap(ActionMap map)
2415:   {
2416:     actionMap = map;
2417:   }
2418: 
2419:   /**
2420:    * Return the condition that determines whether a registered action
2421:    * occurs in response to the specified keystroke.
2422:    *
2423:    * As of 1.3 KeyStrokes can be registered with multiple simultaneous
2424:    * conditions.
2425:    *
2426:    * @param ks The keystroke to return the condition of
2427:    *
2428:    * @return One of the values {@link #UNDEFINED_CONDITION}, {@link
2429:    *     #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}, {@link #WHEN_FOCUSED}, or {@link
2430:    *     #WHEN_IN_FOCUSED_WINDOW}
2431:    *
2432:    * @see #registerKeyboardAction(ActionListener, KeyStroke, int)   
2433:    * @see #unregisterKeyboardAction   
2434:    * @see #resetKeyboardActions
2435:    */
2436:   public int getConditionForKeyStroke(KeyStroke ks)
2437:   {
2438:     if (inputMap_whenFocused != null 
2439:         && inputMap_whenFocused.get(ks) != null)
2440:       return WHEN_FOCUSED;
2441:     else if (inputMap_whenAncestorOfFocused != null 
2442:              && inputMap_whenAncestorOfFocused.get(ks) != null)
2443:       return WHEN_ANCESTOR_OF_FOCUSED_COMPONENT;
2444:     else if (inputMap_whenInFocusedWindow != null 
2445:              && inputMap_whenInFocusedWindow.get(ks) != null)
2446:       return WHEN_IN_FOCUSED_WINDOW;
2447:     else
2448:       return UNDEFINED_CONDITION;
2449:   }
2450: 
2451:   /**
2452:    * Get the ActionListener (typically an {@link Action} object) which is
2453:    * associated with a particular keystroke. 
2454:    *
2455:    * @param ks The keystroke to retrieve the action of
2456:    *
2457:    * @return The action associated with the specified keystroke
2458:    */
2459:   public ActionListener getActionForKeyStroke(KeyStroke ks)
2460:   {
2461:     Object cmd = getInputMap().get(ks);
2462:     if (cmd != null)
2463:       {
2464:         if (cmd instanceof ActionListenerProxy)
2465:           return (ActionListenerProxy) cmd;
2466:         else if (cmd instanceof String)
2467:           return getActionMap().get(cmd);
2468:       }
2469:     return null;
2470:   }
2471: 
2472:   /**
2473:    * A hook for subclasses which want to customize event processing.
2474:    */
2475:   protected void processComponentKeyEvent(KeyEvent e)
2476:   {
2477:     // This method does nothing, it is meant to be overridden by subclasses.
2478:   }
2479: 
2480:   /**
2481:    * Override the default key dispatch system from Component to hook into
2482:    * the swing {@link InputMap} / {@link ActionMap} system.
2483:    *
2484:    * See <a
2485:    * href="http://java.sun.com/products/jfc/tsc/special_report/kestrel/keybindings.html">
2486:    * this report</a> for more details, it's somewhat complex.
2487:    */
2488:   protected void processKeyEvent(KeyEvent e)
2489:   {
2490:     // let the AWT event processing send KeyEvents to registered listeners
2491:     super.processKeyEvent(e);
2492:     processComponentKeyEvent(e);
2493: 
2494:     if (e.isConsumed())
2495:       return;
2496: 
2497:     // Input maps are checked in this order:
2498:     // 1. The focused component's WHEN_FOCUSED map is checked.
2499:     // 2. The focused component's WHEN_ANCESTOR_OF_FOCUSED_COMPONENT map.
2500:     // 3. The WHEN_ANCESTOR_OF_FOCUSED_COMPONENT maps of the focused
2501:     //    component's parent, then its parent's parent, and so on.
2502:     //    Note: Input maps for disabled components are skipped.
2503:     // 4. The WHEN_IN_FOCUSED_WINDOW maps of all the enabled components in
2504:     //    the focused window are searched.
2505:     
2506:     KeyStroke keyStroke = KeyStroke.getKeyStrokeForEvent(e);
2507:     boolean pressed = e.getID() == KeyEvent.KEY_PRESSED;
2508:     
2509:     if (processKeyBinding(keyStroke, e, WHEN_FOCUSED, pressed))
2510:       {
2511:         // This is step 1 from above comment.
2512:         e.consume();
2513:         return;
2514:       }
2515:     else if (processKeyBinding
2516:              (keyStroke, e, WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed))
2517:       {
2518:         // This is step 2 from above comment.
2519:         e.consume();
2520:         return;
2521:       }
2522:     
2523:     // This is step 3 from above comment.
2524:     Container current = getParent();    
2525:     while (current != null)
2526:       { 
2527:         // If current is a JComponent, see if it handles the event in its
2528:         // WHEN_ANCESTOR_OF_FOCUSED_COMPONENT maps.
2529:         if ((current instanceof JComponent) && 
2530:             ((JComponent)current).processKeyBinding 
2531:             (keyStroke, e,WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed))
2532:           {
2533:             e.consume();
2534:             return;
2535:           }     
2536:         
2537:         // Stop when we've tried a top-level container and it didn't handle it
2538:         if (current instanceof Window || current instanceof Applet)
2539:           break;        
2540:         
2541:         // Move up the hierarchy
2542:         current = current.getParent();
2543:       }
2544:     
2545:     // Current being null means the JComponent does not currently have a
2546:     // top-level ancestor, in which case we don't need to check 
2547:     // WHEN_IN_FOCUSED_WINDOW bindings.
2548:     if (current == null || e.isConsumed())
2549:       return;
2550:     
2551:     // This is step 4 from above comment.  KeyboardManager maintains mappings
2552:     // related to WHEN_IN_FOCUSED_WINDOW bindings so that we don't have to 
2553:     // traverse the containment hierarchy each time.
2554:     if (KeyboardManager.getManager().processKeyStroke(current, keyStroke, e))
2555:       e.consume();
2556:   }
2557: 
2558:   protected boolean processKeyBinding(KeyStroke ks,
2559:                                       KeyEvent e,
2560:                                       int condition,
2561:                                       boolean pressed)
2562:   { 
2563:     if (isEnabled())
2564:       {
2565:         Action act = null;
2566:         InputMap map = getInputMap(condition);
2567:         if (map != null)
2568:           {
2569:             Object cmd = map.get(ks);
2570:             if (cmd != null)
2571:               {
2572:                 if (cmd instanceof ActionListenerProxy)
2573:                   act = (Action) cmd;
2574:                 else 
2575:                   act = (Action) getActionMap().get(cmd);
2576:               }
2577:           }
2578:         if (act != null && act.isEnabled())
2579:           return SwingUtilities.notifyAction(act, ks, e, this, e.getModifiers());
2580:       }
2581:     return false;
2582:   }
2583:   
2584:   /**
2585:    * Remove a keyboard action registry.
2586:    *
2587:    * @param aKeyStroke The keystroke to unregister
2588:    *
2589:    * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
2590:    * @see #getConditionForKeyStroke
2591:    * @see #resetKeyboardActions
2592:    */
2593:   public void unregisterKeyboardAction(KeyStroke aKeyStroke)
2594:   {
2595:     ActionMap am = getActionMap();
2596:     // This loops through the conditions WHEN_FOCUSED,
2597:     // WHEN_ANCESTOR_OF_FOCUSED_COMPONENT and WHEN_IN_FOCUSED_WINDOW.
2598:     for (int cond = 0; cond < 3; cond++)
2599:       {
2600:         InputMap im = getInputMap(cond);
2601:         if (im != null)
2602:           {
2603:             Object action = im.get(aKeyStroke);
2604:             if (action != null && am != null)
2605:               am.remove(action);
2606:             im.remove(aKeyStroke);
2607:           }
2608:       }
2609:   }
2610: 
2611: 
2612:   /**
2613:    * Reset all keyboard action registries.
2614:    *
2615:    * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
2616:    * @see #unregisterKeyboardAction
2617:    * @see #getConditionForKeyStroke
2618:    */
2619:   public void resetKeyboardActions()
2620:   {
2621:     if (inputMap_whenFocused != null)
2622:       inputMap_whenFocused.clear();
2623:     if (inputMap_whenAncestorOfFocused != null)
2624:       inputMap_whenAncestorOfFocused.clear();
2625:     if (inputMap_whenInFocusedWindow != null)
2626:       inputMap_whenInFocusedWindow.clear();
2627:     if (actionMap != null)
2628:       actionMap.clear();
2629:   }
2630: 
2631:   /**
2632:    * Mark the described region of this component as dirty in the current
2633:    * {@link RepaintManager}. This will queue an asynchronous repaint using
2634:    * the system painting thread in the near future.
2635:    *
2636:    * @param tm ignored
2637:    * @param x coordinate of the region to mark as dirty
2638:    * @param y coordinate of the region to mark as dirty
2639:    * @param width dimension of the region to mark as dirty
2640:    * @param height dimension of the region to mark as dirty
2641:    */
2642:   public void repaint(long tm, int x, int y, int width, int height)
2643:   {
2644:      RepaintManager.currentManager(this).addDirtyRegion(this, x, y, width,
2645:                                                         height);
2646:   }
2647: 
2648:   /**
2649:    * Mark the described region of this component as dirty in the current
2650:    * {@link RepaintManager}. This will queue an asynchronous repaint using
2651:    * the system painting thread in the near future.
2652:    *
2653:    * @param r The rectangle to mark as dirty
2654:    */
2655:   public void repaint(Rectangle r)
2656:   {
2657:     RepaintManager.currentManager(this).addDirtyRegion(this, r.x, r.y, r.width,
2658:                                                        r.height);
2659:   }
2660: 
2661:   /**
2662:    * Request focus on the default component of this component's {@link
2663:    * FocusTraversalPolicy}.
2664:    *
2665:    * @return The result of {@link #requestFocus()}
2666:    *
2667:    * @deprecated Use {@link #requestFocus()} on the default component provided
2668:    *     from the {@link FocusTraversalPolicy} instead.
2669:    */
2670:   public boolean requestDefaultFocus()
2671:   {
2672:     return false;
2673:   }
2674: 
2675:   /**
2676:    * Queue a an invalidation and revalidation of this component, using 
2677:    * {@link RepaintManager#addInvalidComponent}.
2678:    */
2679:   public void revalidate()
2680:   {
2681:     if (! EventQueue.isDispatchThread())
2682:       SwingUtilities.invokeLater(new Runnable()
2683:         {
2684:           public void run()
2685:           {
2686:             revalidate();
2687:           }
2688:         });
2689:     else
2690:       {
2691:         invalidate();
2692:         RepaintManager.currentManager(this).addInvalidComponent(this);
2693:       }
2694:   }
2695: 
2696:   /**
2697:    * Calls <code>scrollRectToVisible</code> on the component's parent. 
2698:    * Components which can service this call should override.
2699:    *
2700:    * @param r The rectangle to make visible
2701:    */
2702:   public void scrollRectToVisible(Rectangle r)
2703:   {
2704:     Component p = getParent();
2705:     if (p instanceof JComponent)
2706:       ((JComponent) p).scrollRectToVisible(r);
2707:   }
2708: 
2709:   /**
2710:    * Set the value of the {@link #alignmentX} property.
2711:    *
2712:    * @param a The new value of the property
2713:    */
2714:   public void setAlignmentX(float a)
2715:   {
2716:     if (a < 0.0F)
2717:       alignmentX = 0.0F;
2718:     else if (a > 1.0)
2719:       alignmentX = 1.0F;
2720:     else
2721:       alignmentX = a;
2722:   }
2723: 
2724:   /**
2725:    * Set the value of the {@link #alignmentY} property.
2726:    *
2727:    * @param a The new value of the property
2728:    */
2729:   public void setAlignmentY(float a)
2730:   {
2731:     if (a < 0.0F)
2732:       alignmentY = 0.0F;
2733:     else if (a > 1.0)
2734:       alignmentY = 1.0F;
2735:     else
2736:       alignmentY = a;
2737:   }
2738: 
2739:   /**
2740:    * Set the value of the {@link #autoscrolls} property.
2741:    *
2742:    * @param a The new value of the property
2743:    */
2744:   public void setAutoscrolls(boolean a)
2745:   {
2746:     autoscrolls = a;
2747:     clientAutoscrollsSet = true;
2748:   }
2749: 
2750:   /**
2751:    * Set the value of the {@link #debugGraphicsOptions} property.
2752:    *
2753:    * @param debugOptions The new value of the property
2754:    */
2755:   public void setDebugGraphicsOptions(int debugOptions)
2756:   {
2757:     debugGraphicsOptions = debugOptions;
2758:   }
2759: 
2760:   /**
2761:    * Set the value of the {@link #doubleBuffered} property.
2762:    *
2763:    * @param db The new value of the property
2764:    */
2765:   public void setDoubleBuffered(boolean db)
2766:   {
2767:     doubleBuffered = db;
2768:   }
2769: 
2770:   /**
2771:    * Set the value of the <code>enabled</code> property.
2772:    *
2773:    * @param enable The new value of the property
2774:    */
2775:   public void setEnabled(boolean enable)
2776:   {
2777:     if (enable == isEnabled())
2778:       return;
2779:     super.setEnabled(enable);
2780:     firePropertyChange("enabled", !enable, enable);
2781:     repaint();
2782:   }
2783: 
2784:   /**
2785:    * Set the value of the <code>font</code> property.
2786:    *
2787:    * @param f The new value of the property
2788:    */
2789:   public void setFont(Font f)
2790:   {
2791:     if (f == getFont())
2792:       return;
2793:     super.setFont(f);
2794:     revalidate();
2795:     repaint();
2796:   }
2797: 
2798:   /**
2799:    * Set the value of the <code>background</code> property.
2800:    *
2801:    * @param bg The new value of the property
2802:    */
2803:   public void setBackground(Color bg)
2804:   {
2805:     if (bg == getBackground())
2806:       return;
2807:     super.setBackground(bg);
2808:     repaint();
2809:   }
2810: 
2811:   /**
2812:    * Set the value of the <code>foreground</code> property.
2813:    *
2814:    * @param fg The new value of the property
2815:    */
2816:   public void setForeground(Color fg)
2817:   {
2818:     if (fg == getForeground())
2819:       return;
2820:     super.setForeground(fg);
2821:     repaint();
2822:   }
2823: 
2824:   /**
2825:    * Set the value of the {@link #maximumSize} property. The passed value is
2826:    * copied, the later direct changes on the argument have no effect on the
2827:    * property value.
2828:    *
2829:    * @param max The new value of the property
2830:    */
2831:   public void setMaximumSize(Dimension max)
2832:   {
2833:     Dimension oldMaximumSize = maximumSize;
2834:     if (max != null) 
2835:       maximumSize = new Dimension(max);
2836:     else
2837:       maximumSize = null;
2838:     firePropertyChange("maximumSize", oldMaximumSize, maximumSize);
2839:   }
2840: 
2841:   /**
2842:    * Set the value of the {@link #minimumSize} property. The passed value is
2843:    * copied, the later direct changes on the argument have no effect on the
2844:    * property value.
2845:    *
2846:    * @param min The new value of the property
2847:    */
2848:   public void setMinimumSize(Dimension min)
2849:   {
2850:     Dimension oldMinimumSize = minimumSize;
2851:     if (min != null)
2852:       minimumSize = new Dimension(min);
2853:     else
2854:       minimumSize = null;
2855:     firePropertyChange("minimumSize", oldMinimumSize, minimumSize);
2856:   }
2857: 
2858:   /**
2859:    * Set the value of the {@link #preferredSize} property. The passed value is
2860:    * copied, the later direct changes on the argument have no effect on the
2861:    * property value.
2862:    *
2863:    * @param pref The new value of the property
2864:    */
2865:   public void setPreferredSize(Dimension pref)
2866:   {
2867:     Dimension oldPreferredSize = preferredSize;
2868:     if (pref != null)
2869:       preferredSize = new Dimension(pref);
2870:     else
2871:       preferredSize = null;
2872:     firePropertyChange("preferredSize", oldPreferredSize, preferredSize);
2873:   }
2874: 
2875:   /**
2876:    * Set the specified component to be the next component in the 
2877:    * focus cycle, overriding the {@link FocusTraversalPolicy} for
2878:    * this component.
2879:    *
2880:    * @param aComponent The component to set as the next focusable
2881:    *
2882:    * @deprecated Use FocusTraversalPolicy instead
2883:    */
2884:   public void setNextFocusableComponent(Component aComponent)
2885:   {
2886:     Container focusRoot = this;
2887:     if (! this.isFocusCycleRoot())
2888:       focusRoot = getFocusCycleRootAncestor();
2889: 
2890:     FocusTraversalPolicy policy  = focusRoot.getFocusTraversalPolicy();
2891:     if (policy instanceof CompatibilityFocusTraversalPolicy)
2892:       {
2893:         policy = new CompatibilityFocusTraversalPolicy(policy);
2894:         focusRoot.setFocusTraversalPolicy(policy);
2895:       }
2896:     CompatibilityFocusTraversalPolicy p =
2897:       (CompatibilityFocusTraversalPolicy) policy;
2898: 
2899:     Component old = getNextFocusableComponent();
2900:     if (old != null)
2901:       {
2902:         p.removeNextFocusableComponent(this, old);
2903:       }
2904: 
2905:     if (aComponent != null)
2906:       {
2907:         p.addNextFocusableComponent(this, aComponent);
2908:       }
2909:   }
2910: 
2911:   /**
2912:    * Set the value of the {@link #requestFocusEnabled} property.
2913:    *
2914:    * @param e The new value of the property
2915:    */
2916:   public void setRequestFocusEnabled(boolean e)
2917:   {
2918:     requestFocusEnabled = e;
2919:   }
2920: 
2921:   /**
2922:    * Get the value of the {@link #transferHandler} property.
2923:    *
2924:    * @return The current value of the property
2925:    *
2926:    * @see #setTransferHandler
2927:    */
2928: 
2929:   public TransferHandler getTransferHandler()
2930:   {
2931:     return transferHandler;
2932:   }
2933: 
2934:   /**
2935:    * Set the value of the {@link #transferHandler} property.
2936:    *
2937:    * @param newHandler The new value of the property
2938:    *
2939:    * @see #getTransferHandler
2940:    */
2941: 
2942:   public void setTransferHandler(TransferHandler newHandler)
2943:   {
2944:     if (transferHandler == newHandler)
2945:       return;
2946: 
2947:     TransferHandler oldHandler = transferHandler;
2948:     transferHandler = newHandler;
2949:     firePropertyChange("transferHandler", oldHandler, newHandler);
2950:   }
2951: 
2952:   /**
2953:    * Set if the component should paint all pixels withing its bounds.
2954:    * If this property is set to false, the component expects the cleared
2955:    * background.
2956:    *
2957:    * @param isOpaque if true, paint all pixels. If false, expect the clean
2958:    * background. 
2959:    *
2960:    * @see ComponentUI#update
2961:    */
2962:   public void setOpaque(boolean isOpaque)
2963:   {
2964:     boolean oldOpaque = opaque;
2965:     opaque = isOpaque;
2966:     clientOpaqueSet = true;
2967:     firePropertyChange("opaque", oldOpaque, opaque);
2968:   }
2969: 
2970:   /**
2971:    * Set the value of the visible property.
2972:    *
2973:    * If the value is changed, then the AncestorListeners of this component
2974:    * and all its children (recursivly) are notified.
2975:    *
2976:    * @param v The new value of the property
2977:    */
2978:   public void setVisible(boolean v)
2979:   {
2980:     // No need to do anything if the actual value doesn't change.
2981:     if (isVisible() == v)
2982:       return;
2983: 
2984:     super.setVisible(v);
2985: 
2986:     // Notify AncestorListeners.
2987:     if (v == true)
2988:       fireAncestorEvent(this, AncestorEvent.ANCESTOR_ADDED);
2989:     else
2990:       fireAncestorEvent(this, AncestorEvent.ANCESTOR_REMOVED);
2991: 
2992:     Container parent = getParent();
2993:     if (parent != null)
2994:       parent.repaint(getX(), getY(), getWidth(), getHeight());
2995:     revalidate();
2996:   }
2997: 
2998:   /**
2999:    * Call {@link #paint}. 
3000:    * 
3001:    * @param g The graphics context to paint into
3002:    */
3003:   public void update(Graphics g)
3004:   {
3005:     paint(g);
3006:   }
3007: 
3008:   /**
3009:    * Get the value of the UIClassID property. This property should be a key
3010:    * in the {@link UIDefaults} table managed by {@link UIManager}, the
3011:    * value of which is the name of a class to load for the component's
3012:    * {@link #ui} property.
3013:    *
3014:    * @return A "symbolic" name which will map to a class to use for the
3015:    * component's UI, such as <code>"ComponentUI"</code>
3016:    *
3017:    * @see #setUI
3018:    * @see #updateUI
3019:    */
3020:   public String getUIClassID()
3021:   {
3022:     return "ComponentUI";
3023:   }
3024: 
3025:   /**
3026:    * Install a new UI delegate as the component's {@link #ui} property. In
3027:    * the process, this will call {@link ComponentUI#uninstallUI} on any
3028:    * existing value for the {@link #ui} property, and {@link
3029:    * ComponentUI#installUI} on the new UI delegate.
3030:    *
3031:    * @param newUI The new UI delegate to install
3032:    *
3033:    * @see #updateUI
3034:    * @see #getUIClassID
3035:    */
3036:   protected void setUI(ComponentUI newUI)
3037:   {
3038:     if (ui != null)
3039:       ui.uninstallUI(this);
3040: 
3041:     ComponentUI oldUI = ui;
3042:     ui = newUI;
3043: 
3044:     if (ui != null)
3045:       ui.installUI(this);
3046: 
3047:     firePropertyChange("UI", oldUI, newUI);
3048:     revalidate();
3049:     repaint();
3050:   }
3051: 
3052:   /**
3053:    * This method should be overridden in subclasses. In JComponent, the
3054:    * method does nothing. In subclasses, it should a UI delegate
3055:    * (corresponding to the symbolic name returned from {@link
3056:    * #getUIClassID}) from the {@link UIManager}, and calls {@link #setUI}
3057:    * with the new delegate.
3058:    */
3059:   public void updateUI()
3060:   {
3061:     // Nothing to do here.
3062:   }
3063: 
3064:   public static Locale getDefaultLocale()
3065:   {
3066:     return defaultLocale;
3067:   }
3068:   
3069:   public static void setDefaultLocale(Locale l)
3070:   {
3071:     defaultLocale = l;
3072:   }
3073:   
3074:   /**
3075:    * Returns the currently set input verifier for this component.
3076:    *
3077:    * @return the input verifier, or <code>null</code> if none
3078:    */
3079:   public InputVerifier getInputVerifier()
3080:   {
3081:     return inputVerifier;
3082:   }
3083: 
3084:   /**
3085:    * Sets the input verifier to use by this component.
3086:    *
3087:    * @param verifier the input verifier, or <code>null</code>
3088:    */
3089:   public void setInputVerifier(InputVerifier verifier)
3090:   {
3091:     InputVerifier oldVerifier = inputVerifier;
3092:     inputVerifier = verifier;
3093:     firePropertyChange("inputVerifier", oldVerifier, verifier);
3094:   }
3095: 
3096:   /**
3097:    * @since 1.3
3098:    */
3099:   public boolean getVerifyInputWhenFocusTarget()
3100:   {
3101:     return verifyInputWhenFocusTarget;
3102:   }
3103: 
3104:   /**
3105:    * @since 1.3
3106:    */
3107:   public void setVerifyInputWhenFocusTarget(boolean verifyInputWhenFocusTarget)
3108:   {
3109:     if (this.verifyInputWhenFocusTarget == verifyInputWhenFocusTarget)
3110:       return;
3111: 
3112:     this.verifyInputWhenFocusTarget = verifyInputWhenFocusTarget;
3113:     firePropertyChange("verifyInputWhenFocusTarget",
3114:                        ! verifyInputWhenFocusTarget,
3115:                        verifyInputWhenFocusTarget);
3116:   }
3117: 
3118:   /**
3119:    * Requests that this component gets the input focus if the
3120:    * requestFocusEnabled property is set to <code>true</code>.
3121:    * This also means that this component's top-level window becomes
3122:    * the focused window, if that is not already the case.
3123:    *
3124:    * The preconditions that have to be met to become a focus owner is that
3125:    * the component must be displayable, visible and focusable.
3126:    *
3127:    * Note that this signals only a request for becoming focused. There are
3128:    * situations in which it is not possible to get the focus. So developers
3129:    * should not assume that the component has the focus until it receives
3130:    * a {@link java.awt.event.FocusEvent} with a value of
3131:    * {@link java.awt.event.FocusEvent#FOCUS_GAINED}.
3132:    *
3133:    * @see Component#requestFocus()
3134:    */
3135:   public void requestFocus()
3136:   {
3137:     if (isRequestFocusEnabled())
3138:       super.requestFocus();
3139:   }
3140: 
3141:   /**
3142:    * This method is overridden to make it public so that it can be used
3143:    * by look and feel implementations.
3144:    *
3145:    * You should not use this method directly. Instead you are strongly
3146:    * encouraged to call {@link #requestFocus()} or 
3147:    * {@link #requestFocusInWindow()} instead.
3148:    *
3149:    * @param temporary if the focus change is temporary
3150:    *
3151:    * @return <code>false</code> if the focus change request will definitly
3152:    *     fail, <code>true</code> if it will likely succeed
3153:    *
3154:    * @see Component#requestFocus(boolean)
3155:    *
3156:    * @since 1.4
3157:    */
3158:   public boolean requestFocus(boolean temporary)
3159:   {
3160:     return super.requestFocus(temporary);
3161:   }
3162: 
3163:   /**
3164:    * Requests that this component gets the input focus if the top level
3165:    * window that contains this component has the focus and the
3166:    * requestFocusEnabled property is set to <code>true</code>.
3167:    *
3168:    * The preconditions that have to be met to become a focus owner is that
3169:    * the component must be displayable, visible and focusable.
3170:    *
3171:    * Note that this signals only a request for becoming focused. There are
3172:    * situations in which it is not possible to get the focus. So developers
3173:    * should not assume that the component has the focus until it receives
3174:    * a {@link java.awt.event.FocusEvent} with a value of
3175:    * {@link java.awt.event.FocusEvent#FOCUS_GAINED}.
3176:    *
3177:    * @return <code>false</code> if the focus change request will definitly
3178:    *     fail, <code>true</code> if it will likely succeed
3179:    *
3180:    * @see Component#requestFocusInWindow()
3181:    */
3182:   public boolean requestFocusInWindow()
3183:   {
3184:     if (isRequestFocusEnabled())
3185:       return super.requestFocusInWindow();
3186:     else
3187:       return false;
3188:   }
3189: 
3190:   /**
3191:    * This method is overridden to make it public so that it can be used
3192:    * by look and feel implementations.
3193:    *
3194:    * You should not use this method directly. Instead you are strongly
3195:    * encouraged to call {@link #requestFocus()} or 
3196:    * {@link #requestFocusInWindow()} instead.
3197:    *
3198:    * @param temporary if the focus change is temporary
3199:    *
3200:    * @return <code>false</code> if the focus change request will definitly
3201:    *     fail, <code>true</code> if it will likely succeed
3202:    *
3203:    * @see Component#requestFocus(boolean)
3204:    *
3205:    * @since 1.4
3206:    */
3207:   protected boolean requestFocusInWindow(boolean temporary)
3208:   {
3209:     return super.requestFocusInWindow(temporary);
3210:   }
3211: 
3212:   /**
3213:    * Receives notification if this component is added to a parent component.
3214:    *
3215:    * Notification is sent to all registered AncestorListeners about the
3216:    * new parent.
3217:    *
3218:    * This method sets up ActionListeners for all registered KeyStrokes of
3219:    * this component in the chain of parent components.
3220:    *
3221:    * A PropertyChange event is fired to indicate that the ancestor property
3222:    * has changed.
3223:    *
3224:    * This method is used internally and should not be used in applications.
3225:    */
3226:   public void addNotify()
3227:   {
3228:     // Register the WHEN_IN_FOCUSED_WINDOW keyboard bindings
3229:     // Note that here we unregister all bindings associated with
3230:     // this component and then re-register them.  This may be more than
3231:     // necessary if the top-level ancestor hasn't changed.  Should
3232:     // maybe improve this.
3233:     KeyboardManager km = KeyboardManager.getManager();
3234:     km.clearBindingsForComp(this);
3235:     km.registerEntireMap((ComponentInputMap)
3236:                          this.getInputMap(WHEN_IN_FOCUSED_WINDOW));
3237:     super.addNotify();
3238: 
3239:     // Notify AncestorListeners.
3240:     fireAncestorEvent(this, AncestorEvent.ANCESTOR_ADDED);
3241: 
3242:     // fire property change event for 'ancestor'
3243:     firePropertyChange("ancestor", null, getParent());
3244:   }
3245: 
3246:   /**
3247:    * Receives notification that this component no longer has a parent.
3248:    *
3249:    * This method sends an AncestorEvent to all registered AncestorListeners,
3250:    * notifying them that the parent is gone.
3251:    *
3252:    * The keybord actions of this component are removed from the parent and
3253:    * its ancestors.
3254:    *
3255:    * A PropertyChangeEvent is fired to indicate that the 'ancestor' property
3256:    * has changed.
3257:    *
3258:    * This method is called before the component is actually removed from
3259:    * its parent, so the parent is still visible through 
3260:    * {@link Component#getParent}.
3261:    */
3262:   public void removeNotify()
3263:   {
3264:     super.removeNotify();
3265: 
3266:     KeyboardManager.getManager().clearBindingsForComp(this);
3267:     
3268:     // Notify ancestor listeners.
3269:     fireAncestorEvent(this, AncestorEvent.ANCESTOR_REMOVED);
3270: 
3271:     // fire property change event for 'ancestor'
3272:     firePropertyChange("ancestor", getParent(), null);
3273:   }
3274: 
3275:   /**
3276:    * Returns <code>true</code> if the coordinates (x, y) lie within
3277:    * the bounds of this component and <code>false</code> otherwise.
3278:    * x and y are relative to the coordinate space of the component.
3279:    *
3280:    * @param x the X coordinate of the point to check
3281:    * @param y the Y coordinate of the point to check
3282:    *
3283:    * @return <code>true</code> if the specified point lies within the bounds
3284:    *     of this component, <code>false</code> otherwise
3285:    */
3286:   public boolean contains(int x, int y)
3287:   {
3288:     if (ui == null)
3289:       return super.contains(x, y);
3290:     else
3291:       return ui.contains(this, x, y);
3292:   }
3293: 
3294:   /**
3295:    * Disables this component.
3296:    *
3297:    * @deprecated replaced by {@link #setEnabled(boolean)}
3298:    */
3299:   public void disable()
3300:   {
3301:     super.disable();
3302:   }
3303: 
3304:   /**
3305:    * Enables this component.
3306:    *
3307:    * @deprecated replaced by {@link #setEnabled(boolean)}
3308:    */
3309:   public void enable()
3310:   {
3311:     super.enable();
3312:   }
3313: 
3314:   /**
3315:    * Returns the Graphics context for this component. This can be used
3316:    * to draw on a component.
3317:    *
3318:    * @return the Graphics context for this component
3319:    */
3320:   public Graphics getGraphics()
3321:   {
3322:     return super.getGraphics();
3323:   }
3324: 
3325:   /**
3326:    * Returns the X coordinate of the upper left corner of this component.
3327:    * Prefer this method over {@link #getBounds} or {@link #getLocation}
3328:    * because it does not cause any heap allocation.
3329:    *
3330:    * @return the X coordinate of the upper left corner of the component
3331:    */
3332:   public int getX()
3333:   {
3334:     return super.getX();
3335:   }
3336: 
3337:   /**
3338:    * Returns the Y coordinate of the upper left corner of this component.
3339:    * Prefer this method over {@link #getBounds} or {@link #getLocation}
3340:    * because it does not cause any heap allocation.
3341:    *
3342:    * @return the Y coordinate of the upper left corner of the component
3343:    */
3344:   public int getY()
3345:   {
3346:     return super.getY();
3347:   }
3348: 
3349:   /**
3350:    * Returns the height of this component. Prefer this method over
3351:    * {@link #getBounds} or {@link #getSize} because it does not cause
3352:    * any heap allocation.
3353:    *
3354:    * @return the height of the component
3355:    */
3356:   public int getHeight()
3357:   {
3358:     return super.getHeight();
3359:   }
3360: 
3361:   /**
3362:    * Returns the width of this component. Prefer this method over
3363:    * {@link #getBounds} or {@link #getSize} because it does not cause
3364:    * any heap allocation.
3365:    *
3366:    * @return the width of the component
3367:    */
3368:   public int getWidth()
3369:   {
3370:     return super.getWidth();
3371:   }
3372: 
3373:   /**
3374:    * Prints this component to the given Graphics context. A call to this
3375:    * method results in calls to the methods {@link #printComponent},
3376:    * {@link #printBorder} and {@link #printChildren} in this order.
3377:    *
3378:    * Double buffering is temporarily turned off so the painting goes directly
3379:    * to the supplied Graphics context.
3380:    *
3381:    * @param g the Graphics context to print onto
3382:    */
3383:   public void print(Graphics g)
3384:   {
3385:     boolean doubleBufferState = isDoubleBuffered();
3386:     setDoubleBuffered(false);
3387:     printComponent(g);
3388:     printBorder(g);
3389:     printChildren(g);
3390:     setDoubleBuffered(doubleBufferState);
3391:   }
3392: 
3393:   /**
3394:    * Prints this component to the given Graphics context. This invokes
3395:    * {@link #print}.
3396:    *
3397:    * @param g the Graphics context to print onto
3398:    */
3399:   public void printAll(Graphics g)
3400:   {
3401:     print(g);
3402:   }
3403: 
3404:   /**
3405:    * Prints this component to the specified Graphics context. The default
3406:    * behaviour is to invoke {@link #paintComponent}. Override this
3407:    * if you want special behaviour for printing.
3408:    *
3409:    * @param g the Graphics context to print onto
3410:    *
3411:    * @since 1.3
3412:    */
3413:   protected void printComponent(Graphics g)
3414:   {
3415:     paintComponent(g);
3416:   }
3417: 
3418:   /**
3419:    * Print this component's children to the specified Graphics context.
3420:    * The default behaviour is to invoke {@link #paintChildren}. Override this
3421:    * if you want special behaviour for printing.
3422:    *
3423:    * @param g the Graphics context to print onto
3424:    *
3425:    * @since 1.3
3426:    */
3427:   protected void printChildren(Graphics g)
3428:   {
3429:     paintChildren(g);
3430:   }
3431: 
3432:   /**
3433:    * Print this component's border to the specified Graphics context.
3434:    * The default behaviour is to invoke {@link #paintBorder}. Override this
3435:    * if you want special behaviour for printing.
3436:    *
3437:    * @param g the Graphics context to print onto
3438:    *
3439:    * @since 1.3
3440:    */
3441:   protected void printBorder(Graphics g)
3442:   {
3443:     paintBorder(g);
3444:   }
3445: 
3446:   /**
3447:    * Processes mouse motion event, like dragging and moving.
3448:    *
3449:    * @param ev the MouseEvent describing the mouse motion
3450:    */
3451:   protected void processMouseMotionEvent(MouseEvent ev)
3452:   {
3453:     super.processMouseMotionEvent(ev);
3454:   }
3455: 
3456:   /**
3457:    * Moves and resizes the component.
3458:    *
3459:    * @param x the new horizontal location
3460:    * @param y the new vertial location
3461:    * @param w the new width
3462:    * @param h the new height
3463:    */
3464:   public void reshape(int x, int y, int w, int h)
3465:   {
3466:     int oldX = getX();
3467:     int oldY = getY();
3468:     super.reshape(x, y, w, h);
3469:     // Notify AncestorListeners.
3470:     if (oldX != getX() || oldY != getY())
3471:       fireAncestorEvent(this, AncestorEvent.ANCESTOR_MOVED);
3472:   }
3473: 
3474:   /**
3475:    * Fires an AncestorEvent to this component's and all of its child
3476:    * component's AncestorListeners.
3477:    *
3478:    * @param ancestor the component that triggered the event
3479:    * @param id the kind of ancestor event that should be fired
3480:    */
3481:   void fireAncestorEvent(JComponent ancestor, int id)
3482:   {
3483:     // Fire event for registered ancestor listeners of this component.
3484:     AncestorListener[] listeners = getAncestorListeners();
3485:     if (listeners.length > 0)
3486:       {
3487:         AncestorEvent ev = new AncestorEvent(this, id,
3488:                                              ancestor, ancestor.getParent());
3489:         for (int i = 0; i < listeners.length; i++)
3490:           {
3491:             switch (id)
3492:               {
3493:               case AncestorEvent.ANCESTOR_MOVED:
3494:                 listeners[i].ancestorMoved(ev);
3495:                 break;
3496:               case AncestorEvent.ANCESTOR_ADDED:
3497:                 listeners[i].ancestorAdded(ev);
3498:                 break;
3499:               case AncestorEvent.ANCESTOR_REMOVED:
3500:                 listeners[i].ancestorRemoved(ev);
3501:                 break;
3502:               }
3503:           }
3504:       }
3505:     // Dispatch event to all children.
3506:     Component[] children = getComponents();
3507:     for (int i = 0; i < children.length; i++)
3508:       {
3509:         if (!(children[i] instanceof JComponent))
3510:           continue;
3511:         JComponent jc = (JComponent) children[i];
3512:         jc.fireAncestorEvent(ancestor, id);
3513:       }
3514:   }
3515: 
3516:   /**
3517:    * Finds a suitable paint root for painting this component. This method first
3518:    * checks if this component is overlapped using
3519:    * {@link #findOverlapFreeParent(Rectangle)}. The returned paint root is then
3520:    * feeded to {@link #findOpaqueParent(Component)} to find the nearest opaque
3521:    * component for this paint root. If no paint is necessary, then we return
3522:    * <code>null</code>.
3523:    *
3524:    * @param c the clip of this component
3525:    *
3526:    * @return the paint root or <code>null</code> if no painting is necessary
3527:    */
3528:   private Component findPaintRoot(Rectangle c)
3529:   {
3530:     Component p = findOverlapFreeParent(c);
3531:     if (p == null)
3532:       return null;
3533:     Component root = findOpaqueParent(p);
3534:     return root;
3535:   }
3536: 
3537:   /**
3538:    * Scans the containment hierarchy upwards for components that overlap the
3539:    * this component in the specified clip. This method returns
3540:    * <code>this</code>, if no component overlaps this component. It returns
3541:    * <code>null</code> if another component completely covers this component
3542:    * in the specified clip (no repaint necessary). If another component partly
3543:    * overlaps this component in the specified clip, then the parent of this
3544:    * component is returned (this is the component that must be used as repaint
3545:    * root). For efficient lookup, the method
3546:    * {@link #isOptimizedDrawingEnabled()} is used.
3547:    *
3548:    * @param clip the clip of this component
3549:    *
3550:    * @return the paint root, or <code>null</code> if no paint is necessary
3551:    */
3552:   private Component findOverlapFreeParent(Rectangle clip)
3553:   {
3554:     Rectangle currentClip = clip;
3555:     Component found = this;
3556:     Container parent = this; 
3557:     while (parent != null && !(parent instanceof Window))
3558:       {
3559:         Container newParent = parent.getParent();
3560:         if (newParent == null || newParent instanceof Window)
3561:           break;
3562:         // If the parent is optimizedDrawingEnabled, then its children are
3563:         // tiled and cannot have an overlapping child. Go directly to next
3564:         // parent.
3565:         if ((newParent instanceof JComponent
3566:             && ((JComponent) newParent).isOptimizedDrawingEnabled()))
3567:           
3568:           {
3569:             parent = newParent;
3570:             continue;
3571:           }
3572:         // If the parent is not optimizedDrawingEnabled, we must paint the
3573:         // parent.
3574:         Rectangle target = SwingUtilities.convertRectangle(found,
3575:                                                            currentClip,
3576:                                                            newParent);
3577:         found = newParent;
3578:         currentClip = target;
3579:         parent = newParent;
3580:       }
3581:     return found;
3582:   }
3583: 
3584:   /**
3585:    * Finds the nearest component to <code>c</code> (upwards in the containment
3586:    * hierarchy), that is opaque. If <code>c</code> itself is opaque,
3587:    * this returns <code>c</code> itself.
3588:    *
3589:    * @param c the start component for the search
3590:    * @return the nearest component to <code>c</code> (upwards in the containment
3591:    *         hierarchy), that is opaque; If <code>c</code> itself is opaque,
3592:    *         this returns <code>c</code> itself
3593:    */
3594:   private Component findOpaqueParent(Component c)
3595:   {
3596:     Component found = c;
3597:     while (true)
3598:       {
3599:         if ((found instanceof JComponent) && ((JComponent) found).isOpaque())
3600:           break;
3601:         else if (!(found instanceof JComponent))
3602:           break;
3603:         Container p = found.getParent();
3604:         if (p == null)
3605:           break;
3606:         else
3607:           found = p;
3608:       }
3609:     return found;
3610:   }
3611:   
3612:   /**
3613:    * This is the method that gets called when the WHEN_IN_FOCUSED_WINDOW map
3614:    * is changed.
3615:    *
3616:    * @param changed the JComponent associated with the WHEN_IN_FOCUSED_WINDOW
3617:    *        map
3618:    */
3619:   void updateComponentInputMap(ComponentInputMap changed)
3620:   {
3621:     // Since you can change a component's input map via
3622:     // setInputMap, we have to check if <code>changed</code>
3623:     // is still in our WHEN_IN_FOCUSED_WINDOW map hierarchy
3624:     InputMap curr = getInputMap(WHEN_IN_FOCUSED_WINDOW);
3625:     while (curr != null && curr != changed)
3626:       curr = curr.getParent();
3627:     
3628:     // If curr is null then changed is not in the hierarchy
3629:     if (curr == null)
3630:       return;
3631:     
3632:     // Now we have to update the keyboard manager's hashtable
3633:     KeyboardManager km = KeyboardManager.getManager();
3634:     
3635:     // This is a poor strategy, should be improved.  We currently 
3636:     // delete all the old bindings for the component and then register
3637:     // the current bindings.
3638:     km.clearBindingsForComp(changed.getComponent());
3639:     km.registerEntireMap((ComponentInputMap) 
3640:                          getInputMap(WHEN_IN_FOCUSED_WINDOW));
3641:   }
3642: 
3643:   /**
3644:    * Helper method for
3645:    * {@link LookAndFeel#installProperty(JComponent, String, Object)}.
3646:    * 
3647:    * @param propertyName the name of the property
3648:    * @param value the value of the property
3649:    *
3650:    * @throws IllegalArgumentException if the specified property cannot be set
3651:    *         by this method
3652:    * @throws ClassCastException if the property value does not match the
3653:    *         property type
3654:    * @throws NullPointerException if <code>c</code> or
3655:    *         <code>propertyValue</code> is <code>null</code>
3656:    */
3657:   void setUIProperty(String propertyName, Object value)
3658:   {
3659:     if (propertyName.equals("opaque"))
3660:       {
3661:         if (! clientOpaqueSet)
3662:           {
3663:             setOpaque(((Boolean) value).booleanValue());
3664:             clientOpaqueSet = false;
3665:           }
3666:       }
3667:     else if (propertyName.equals("autoscrolls"))
3668:       {
3669:         if (! clientAutoscrollsSet)
3670:           {
3671:             setAutoscrolls(((Boolean) value).booleanValue());
3672:             clientAutoscrollsSet = false;
3673:           }
3674:       }
3675:     else
3676:       {
3677:         throw new IllegalArgumentException
3678:             ("Unsupported property for LookAndFeel.installProperty(): "
3679:              + propertyName);
3680:       }
3681:   }
3682: }