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 the opaque property has been set by a client program or by
 764:    * the UI.
 765:    *
 766:    * @see #setUIProperty(String, Object)
 767:    * @see LookAndFeel#installProperty(JComponent, String, Object)
 768:    */
 769:   private boolean clientOpaqueSet = false;
 770: 
 771:   /**
 772:    * Indicates if the autoscrolls property has been set by a client program or
 773:    * by the UI.
 774:    *
 775:    * @see #setUIProperty(String, Object)
 776:    * @see LookAndFeel#installProperty(JComponent, String, Object)
 777:    */
 778:   private boolean clientAutoscrollsSet = false;
 779: 
 780:   /**
 781:    * Creates a new <code>JComponent</code> instance.
 782:    */
 783:   public JComponent()
 784:   {
 785:     super();
 786:     setDropTarget(new DropTarget());
 787:     defaultLocale = Locale.getDefault();
 788:     debugGraphicsOptions = DebugGraphics.NONE_OPTION;
 789:     setRequestFocusEnabled(true);
 790:   }
 791: 
 792:   /**
 793:    * Helper to lazily construct and return the client properties table.
 794:    * 
 795:    * @return The current client properties table
 796:    *
 797:    * @see #clientProperties
 798:    * @see #getClientProperty
 799:    * @see #putClientProperty
 800:    */
 801:   private Hashtable getClientProperties()
 802:   {
 803:     if (clientProperties == null)
 804:       clientProperties = new Hashtable();
 805:     return clientProperties;
 806:   }
 807: 
 808:   /**
 809:    * Get a client property associated with this component and a particular
 810:    * key.
 811:    *
 812:    * @param key The key with which to look up the client property
 813:    *
 814:    * @return A client property associated with this object and key
 815:    *
 816:    * @see #clientProperties
 817:    * @see #getClientProperties
 818:    * @see #putClientProperty
 819:    */
 820:   public final Object getClientProperty(Object key)
 821:   {
 822:     return getClientProperties().get(key);
 823:   }
 824: 
 825:   /**
 826:    * Add a client property <code>value</code> to this component, associated
 827:    * with <code>key</code>. If there is an existing client property
 828:    * associated with <code>key</code>, it will be replaced.  A
 829:    * {@link PropertyChangeEvent} is sent to registered listeners (with the
 830:    * name of the property being <code>key.toString()</code>).
 831:    *
 832:    * @param key The key of the client property association to add
 833:    * @param value The value of the client property association to add
 834:    *
 835:    * @see #clientProperties
 836:    * @see #getClientProperties
 837:    * @see #getClientProperty
 838:    */
 839:   public final void putClientProperty(Object key, Object value)
 840:   {
 841:     Hashtable t = getClientProperties();
 842:     Object old = t.get(key);
 843:     if (value != null)
 844:       t.put(key, value);
 845:     else
 846:       t.remove(key);
 847:     firePropertyChange(key.toString(), old, value);
 848:   }
 849: 
 850:   /**
 851:    * Unregister an <code>AncestorListener</code>.
 852:    *
 853:    * @param listener The listener to unregister
 854:    * 
 855:    * @see #addAncestorListener
 856:    */
 857:   public void removeAncestorListener(AncestorListener listener)
 858:   {
 859:     listenerList.remove(AncestorListener.class, listener);
 860:   }
 861: 
 862:   /**
 863:    * Unregister a <code>VetoableChangeChangeListener</code>.
 864:    *
 865:    * @param listener The listener to unregister
 866:    *
 867:    * @see #addVetoableChangeListener
 868:    */
 869:   public void removeVetoableChangeListener(VetoableChangeListener listener)
 870:   {
 871:     listenerList.remove(VetoableChangeListener.class, listener);
 872:   }
 873: 
 874:   /**
 875:    * Register an <code>AncestorListener</code>.
 876:    *
 877:    * @param listener The listener to register
 878:    *
 879:    * @see #removeVetoableChangeListener
 880:    */
 881:   public void addAncestorListener(AncestorListener listener)
 882:   {
 883:     listenerList.add(AncestorListener.class, listener);
 884:   }
 885: 
 886:   /**
 887:    * Register a <code>PropertyChangeListener</code> for a specific, named
 888:    * property. To listen to all property changes, regardless of name, use
 889:    * {@link #addPropertyChangeListener(PropertyChangeListener)} instead.
 890:    *
 891:    * @param propertyName The property name to listen to
 892:    * @param listener The listener to register
 893:    *
 894:    * @see #removePropertyChangeListener(String, PropertyChangeListener)
 895:    * @see #changeSupport
 896:    */
 897:   public void addPropertyChangeListener(String propertyName,
 898:                                         PropertyChangeListener listener)
 899:   {
 900:     listenerList.add(PropertyChangeListener.class, listener);
 901:   }
 902: 
 903:   /**
 904:    * Register a <code>VetoableChangeListener</code>.
 905:    *
 906:    * @param listener The listener to register
 907:    *
 908:    * @see #removeVetoableChangeListener
 909:    * @see #listenerList
 910:    */
 911:   public void addVetoableChangeListener(VetoableChangeListener listener)
 912:   {
 913:     listenerList.add(VetoableChangeListener.class, listener);
 914:   }
 915: 
 916:   /**
 917:    * Returns all registered {@link EventListener}s of the given 
 918:    * <code>listenerType</code>.
 919:    *
 920:    * @param listenerType the class of listeners to filter (<code>null</code> 
 921:    *                     not permitted).
 922:    *                     
 923:    * @return An array of registered listeners.
 924:    * 
 925:    * @throws ClassCastException if <code>listenerType</code> does not implement
 926:    *                            the {@link EventListener} interface.
 927:    * @throws NullPointerException if <code>listenerType</code> is 
 928:    *                              <code>null</code>.
 929:    *                            
 930:    * @see #getAncestorListeners()
 931:    * @see #listenerList
 932:    * 
 933:    * @since 1.3
 934:    */
 935:   public EventListener[] getListeners(Class listenerType)
 936:   {
 937:     if (listenerType == PropertyChangeListener.class)
 938:       return getPropertyChangeListeners();
 939:     else
 940:       return listenerList.getListeners(listenerType);
 941:   }
 942: 
 943:   /**
 944:    * Return all registered <code>AncestorListener</code> objects.
 945:    *
 946:    * @return The set of <code>AncestorListener</code> objects in {@link
 947:    * #listenerList}
 948:    */
 949:   public AncestorListener[] getAncestorListeners()
 950:   {
 951:     return (AncestorListener[]) getListeners(AncestorListener.class);
 952:   }
 953: 
 954:   /**
 955:    * Return all registered <code>VetoableChangeListener</code> objects.
 956:    *
 957:    * @return The set of <code>VetoableChangeListener</code> objects in {@link
 958:    * #listenerList}
 959:    */
 960:   public VetoableChangeListener[] getVetoableChangeListeners()
 961:   {
 962:     return (VetoableChangeListener[]) getListeners(VetoableChangeListener.class);
 963:   }
 964: 
 965:   /**
 966:    * A variant of {@link #firePropertyChange(String,Object,Object)} 
 967:    * for properties with <code>boolean</code> values.
 968:    *
 969:    * @specnote It seems that in JDK1.5 all property related methods have been 
 970:    *           moved to java.awt.Component, except this and 2 others. We call
 971:    *           super here. I guess this will also be removed in one of the next
 972:    *           releases.
 973:    */
 974:   public void firePropertyChange(String propertyName, boolean oldValue,
 975:                                  boolean newValue)
 976:   {
 977:     super.firePropertyChange(propertyName, oldValue, newValue);
 978:   }
 979: 
 980:   /**
 981:    * A variant of {@link #firePropertyChange(String,Object,Object)} 
 982:    * for properties with <code>char</code> values.
 983:    *
 984:    * @specnote It seems that in JDK1.5 all property related methods have been 
 985:    *           moved to java.awt.Component, except this and 2 others. We call
 986:    *           super here. I guess this will also be removed in one of the next
 987:    *           releases.
 988:    */
 989:   public void firePropertyChange(String propertyName, char oldValue,
 990:                                  char newValue)
 991:   {
 992:     super.firePropertyChange(propertyName, oldValue, newValue);
 993:   }
 994: 
 995:   /**
 996:    * A variant of {@link #firePropertyChange(String,Object,Object)} 
 997:    * for properties with <code>int</code> values.
 998:    *
 999:    * @specnote It seems that in JDK1.5 all property related methods have been 
1000:    *           moved to java.awt.Component, except this and 2 others. We call
1001:    *           super here. I guess this will also be removed in one of the next
1002:    *           releases.
1003:    */
1004:   public void firePropertyChange(String propertyName, int oldValue,
1005:                                  int newValue)
1006:   {
1007:     super.firePropertyChange(propertyName, oldValue, newValue);
1008:   }
1009: 
1010:   /**
1011:    * Call {@link VetoableChangeListener#vetoableChange} on all listeners
1012:    * registered to listen to a given property. Any method which changes
1013:    * the specified property of this component should call this method.
1014:    *
1015:    * @param propertyName The property which changed
1016:    * @param oldValue The old value of the property
1017:    * @param newValue The new value of the property
1018:    *
1019:    * @throws PropertyVetoException if the change was vetoed by a listener
1020:    *
1021:    * @see #addVetoableChangeListener
1022:    * @see #removeVetoableChangeListener
1023:    */
1024:   protected void fireVetoableChange(String propertyName, Object oldValue,
1025:                                     Object newValue)
1026:     throws PropertyVetoException
1027:   {
1028:     VetoableChangeListener[] listeners = getVetoableChangeListeners();
1029: 
1030:     PropertyChangeEvent evt = 
1031:       new PropertyChangeEvent(this, propertyName, oldValue, newValue);
1032: 
1033:     for (int i = 0; i < listeners.length; i++)
1034:       listeners[i].vetoableChange(evt);
1035:   }
1036: 
1037:   /**
1038:    * Get the value of the accessibleContext property for this component.
1039:    *
1040:    * @return the current value of the property
1041:    */
1042:   public AccessibleContext getAccessibleContext()
1043:   {
1044:     return null;
1045:   }
1046: 
1047:   /**
1048:    * Get the value of the {@link #alignmentX} property.
1049:    *
1050:    * @return The current value of the property.
1051:    *
1052:    * @see #setAlignmentX
1053:    * @see #alignmentY
1054:    */
1055:   public float getAlignmentX()
1056:   {
1057:     float ret = alignmentX;
1058:     if (alignmentX < 0)
1059:       // alignment has not been set explicitly.
1060:       ret = super.getAlignmentX();
1061: 
1062:     return ret;
1063:   }
1064: 
1065:   /**
1066:    * Get the value of the {@link #alignmentY} property.
1067:    *
1068:    * @return The current value of the property.
1069:    *
1070:    * @see #setAlignmentY
1071:    * @see #alignmentX
1072:    */
1073:   public float getAlignmentY()
1074:   {
1075:     float ret = alignmentY;
1076:     if (alignmentY < 0)
1077:       // alignment has not been set explicitly.
1078:       ret = super.getAlignmentY();
1079: 
1080:     return ret;
1081:   }
1082: 
1083:   /**
1084:    * Get the current value of the {@link #autoscrolls} property.
1085:    *
1086:    * @return The current value of the property
1087:    */
1088:   public boolean getAutoscrolls()
1089:   {
1090:     return autoscrolls;
1091:   }
1092: 
1093:   /**
1094:    * Set the value of the {@link #border} property.
1095:    *   
1096:    * @param newBorder The new value of the property
1097:    *
1098:    * @see #getBorder
1099:    */
1100:   public void setBorder(Border newBorder)
1101:   {
1102:     Border oldBorder = getBorder();
1103:     if (oldBorder == newBorder)
1104:       return;
1105: 
1106:     border = newBorder;
1107:     firePropertyChange("border", oldBorder, newBorder);
1108:     repaint();
1109:   }
1110: 
1111:   /**
1112:    * Get the value of the {@link #border} property.
1113:    *
1114:    * @return The property's current value
1115:    *
1116:    * @see #setBorder
1117:    */
1118:   public Border getBorder()
1119:   {
1120:     return border;
1121:   }
1122: 
1123:   /**
1124:    * Get the component's current bounding box. If a rectangle is provided,
1125:    * use this as the return value (adjusting its fields in place);
1126:    * otherwise (of <code>null</code> is provided) return a new {@link
1127:    * Rectangle}.
1128:    *
1129:    * @param rv Optional return value to use
1130:    *
1131:    * @return A rectangle bounding the component
1132:    */
1133:   public Rectangle getBounds(Rectangle rv)
1134:   {
1135:     if (rv == null)
1136:       return new Rectangle(getX(), getY(), getWidth(), getHeight());
1137:     else
1138:       {
1139:         rv.setBounds(getX(), getY(), getWidth(), getHeight());
1140:         return rv;
1141:       }
1142:   }
1143: 
1144:   /**
1145:    * Prepares a graphics context for painting this object. If {@link
1146:    * #debugGraphicsOptions} is not equal to {@link
1147:    * DebugGraphics#NONE_OPTION}, produce a new {@link DebugGraphics} object
1148:    * wrapping the parameter. Otherwise configure the parameter with this
1149:    * component's foreground color and font.
1150:    *
1151:    * @param g The graphics context to wrap or configure
1152:    *
1153:    * @return A graphics context to paint this object with
1154:    *
1155:    * @see #debugGraphicsOptions
1156:    * @see #paint
1157:    */
1158:   protected Graphics getComponentGraphics(Graphics g)
1159:   {
1160:     Graphics g2 = g;
1161:     int options = getDebugGraphicsOptions();
1162:     if (options != DebugGraphics.NONE_OPTION)
1163:       {
1164:         if (!(g2 instanceof DebugGraphics))
1165:           g2 = new DebugGraphics(g);
1166:         DebugGraphics dg = (DebugGraphics) g2;
1167:         dg.setDebugOptions(dg.getDebugOptions() | options);
1168:       }
1169:     g2.setFont(this.getFont());
1170:     g2.setColor(this.getForeground());
1171:     return g2;
1172:   }
1173: 
1174:   /**
1175:    * Get the value of the {@link #debugGraphicsOptions} property.
1176:    *
1177:    * @return The current value of the property.
1178:    *
1179:    * @see #setDebugGraphicsOptions
1180:    * @see #debugGraphicsOptions
1181:    */
1182:   public int getDebugGraphicsOptions()
1183:   {
1184:     String option = System.getProperty("gnu.javax.swing.DebugGraphics");
1185:     int options = debugGraphicsOptions;
1186:     if (option != null && option.length() != 0)
1187:       {
1188:         if (options < 0)
1189:           options = 0;
1190: 
1191:         if (option.equals("LOG"))
1192:           options |= DebugGraphics.LOG_OPTION;
1193:         else if (option.equals("FLASH"))
1194:           options |= DebugGraphics.FLASH_OPTION;
1195:       }
1196:     return options;
1197:   }
1198: 
1199:   /**
1200:    * Get the component's insets, which are calculated from
1201:    * the {@link #border} property. If the border is <code>null</code>,
1202:    * calls {@link Container#getInsets}.
1203:    *
1204:    * @return The component's current insets
1205:    */
1206:   public Insets getInsets()
1207:   {
1208:     if (border == null)
1209:       return super.getInsets();
1210:     return getBorder().getBorderInsets(this);
1211:   }
1212: 
1213:   /**
1214:    * Get the component's insets, which are calculated from the {@link
1215:    * #border} property. If the border is <code>null</code>, calls {@link
1216:    * Container#getInsets}. The passed-in {@link Insets} value will be
1217:    * used as the return value, if possible.
1218:    *
1219:    * @param insets Return value object to reuse, if possible
1220:    *
1221:    * @return The component's current insets
1222:    */
1223:   public Insets getInsets(Insets insets)
1224:   {
1225:     Insets t = getInsets();
1226: 
1227:     if (insets == null)
1228:       return t;
1229: 
1230:     insets.left = t.left;
1231:     insets.right = t.right;
1232:     insets.top = t.top;
1233:     insets.bottom = t.bottom;
1234:     return insets;
1235:   }
1236: 
1237:   /**
1238:    * Get the component's location. The passed-in {@link Point} value
1239:    * will be used as the return value, if possible.
1240:    *
1241:    * @param rv Return value object to reuse, if possible
1242:    *
1243:    * @return The component's current location
1244:    */
1245:   public Point getLocation(Point rv)
1246:   {
1247:     if (rv == null)
1248:       return new Point(getX(), getY());
1249: 
1250:     rv.setLocation(getX(), getY());
1251:     return rv;
1252:   }
1253: 
1254:   /**
1255:    * Get the component's maximum size. If the {@link #maximumSize} property
1256:    * has been explicitly set, it is returned. If the {@link #maximumSize}
1257:    * property has not been set but the {@link #ui} property has been, the
1258:    * result of {@link ComponentUI#getMaximumSize} is returned. If neither
1259:    * property has been set, the result of {@link Container#getMaximumSize}
1260:    * is returned.
1261:    *
1262:    * @return The maximum size of the component
1263:    *
1264:    * @see #maximumSize
1265:    * @see #setMaximumSize
1266:    */
1267:   public Dimension getMaximumSize()
1268:   {
1269:     if (maximumSize != null)
1270:       return maximumSize;
1271: 
1272:     if (ui != null)
1273:       {
1274:         Dimension s = ui.getMaximumSize(this);
1275:         if (s != null)
1276:           return s;
1277:       }
1278: 
1279:     Dimension p = super.getMaximumSize();
1280:     return p;
1281:   }
1282: 
1283:   /**
1284:    * Get the component's minimum size. If the {@link #minimumSize} property
1285:    * has been explicitly set, it is returned. If the {@link #minimumSize}
1286:    * property has not been set but the {@link #ui} property has been, the
1287:    * result of {@link ComponentUI#getMinimumSize} is returned. If neither
1288:    * property has been set, the result of {@link Container#getMinimumSize}
1289:    * is returned.
1290:    *
1291:    * @return The minimum size of the component
1292:    *
1293:    * @see #minimumSize
1294:    * @see #setMinimumSize
1295:    */
1296:   public Dimension getMinimumSize()
1297:   {
1298:     if (minimumSize != null)
1299:       return minimumSize;
1300: 
1301:     if (ui != null)
1302:       {
1303:         Dimension s = ui.getMinimumSize(this);
1304:         if (s != null)
1305:           return s;
1306:       }
1307: 
1308:     Dimension p = super.getMinimumSize();
1309:     return p;
1310:   }
1311: 
1312:   /**
1313:    * Get the component's preferred size. If the {@link #preferredSize}
1314:    * property has been explicitly set, it is returned. If the {@link
1315:    * #preferredSize} property has not been set but the {@link #ui} property
1316:    * has been, the result of {@link ComponentUI#getPreferredSize} is
1317:    * returned. If neither property has been set, the result of {@link
1318:    * Container#getPreferredSize} is returned.
1319:    *
1320:    * @return The preferred size of the component
1321:    *
1322:    * @see #preferredSize
1323:    * @see #setPreferredSize
1324:    */
1325:   public Dimension getPreferredSize()
1326:   {
1327:     Dimension prefSize = null;
1328:     if (preferredSize != null)
1329:       prefSize = new Dimension(preferredSize);
1330: 
1331:     else if (ui != null)
1332:       {
1333:         Dimension s = ui.getPreferredSize(this);
1334:         if (s != null)
1335:           prefSize = s;
1336:       }
1337: 
1338:     if (prefSize == null)
1339:       prefSize = super.getPreferredSize();
1340: 
1341:     return prefSize;
1342:   }
1343: 
1344:   /**
1345:    * Checks if a maximum size was explicitely set on the component.
1346:    *
1347:    * @return <code>true</code> if a maximum size was set,
1348:    * <code>false</code> otherwise
1349:    * 
1350:    * @since 1.3
1351:    */
1352:   public boolean isMaximumSizeSet()
1353:   {
1354:     return maximumSize != null;
1355:   }
1356: 
1357:   /**
1358:    * Checks if a minimum size was explicitely set on the component.
1359:    *
1360:    * @return <code>true</code> if a minimum size was set,
1361:    * <code>false</code> otherwise
1362:    * 
1363:    * @since 1.3
1364:    */
1365:   public boolean isMinimumSizeSet()
1366:   {
1367:     return minimumSize != null;
1368:   }
1369: 
1370:   /**
1371:    * Checks if a preferred size was explicitely set on the component.
1372:    *
1373:    * @return <code>true</code> if a preferred size was set,
1374:    * <code>false</code> otherwise
1375:    * 
1376:    * @since 1.3
1377:    */
1378:   public boolean isPreferredSizeSet()
1379:   {
1380:     return preferredSize != null;
1381:   }
1382:   
1383:   /**
1384:    * Return the value of the <code>nextFocusableComponent</code> property.
1385:    *
1386:    * @return The current value of the property, or <code>null</code>
1387:    * if none has been set.
1388:    * 
1389:    * @deprecated See {@link java.awt.FocusTraversalPolicy}
1390:    */
1391:   public Component getNextFocusableComponent()
1392:   {
1393:     Container focusRoot = this;
1394:     if (! this.isFocusCycleRoot())
1395:       focusRoot = getFocusCycleRootAncestor();
1396: 
1397:     FocusTraversalPolicy policy  = focusRoot.getFocusTraversalPolicy();
1398:     return policy.getComponentAfter(focusRoot, this);
1399:   }
1400: 
1401:   /**
1402:    * Return the set of {@link KeyStroke} objects which are registered
1403:    * to initiate actions on this component.
1404:    *
1405:    * @return An array of the registered keystrokes
1406:    */
1407:   public KeyStroke[] getRegisteredKeyStrokes()
1408:   {
1409:     return null;
1410:   }
1411: 
1412:   /**
1413:    * Returns the first ancestor of this component which is a {@link JRootPane}.
1414:    * Equivalent to calling <code>SwingUtilities.getRootPane(this);</code>.
1415:    *
1416:    * @return An ancestral JRootPane, or <code>null</code> if none exists.
1417:    */
1418:   public JRootPane getRootPane()
1419:   {
1420:     JRootPane p = SwingUtilities.getRootPane(this);
1421:     return p;
1422:   }
1423: 
1424:   /**
1425:    * Get the component's size. The passed-in {@link Dimension} value
1426:    * will be used as the return value, if possible.
1427:    *
1428:    * @param rv Return value object to reuse, if possible
1429:    *
1430:    * @return The component's current size
1431:    */
1432:   public Dimension getSize(Dimension rv)
1433:   {
1434:     if (rv == null)
1435:       return new Dimension(getWidth(), getHeight());
1436:     else
1437:       {
1438:         rv.setSize(getWidth(), getHeight());
1439:         return rv;
1440:       }
1441:   }
1442: 
1443:   /**
1444:    * Return the <code>toolTip</code> property of this component, creating it and
1445:    * setting it if it is currently <code>null</code>. This method can be
1446:    * overridden in subclasses which wish to control the exact form of
1447:    * tooltip created.
1448:    *
1449:    * @return The current toolTip
1450:    */
1451:   public JToolTip createToolTip()
1452:   {
1453:     JToolTip toolTip = new JToolTip();
1454:     toolTip.setComponent(this);
1455:     toolTip.setTipText(toolTipText);
1456: 
1457:     return toolTip;
1458:   }
1459: 
1460:   /**
1461:    * Return the location at which the {@link #toolTipText} property should be
1462:    * displayed, when triggered by a particular mouse event. 
1463:    *
1464:    * @param event The event the tooltip is being presented in response to
1465:    *
1466:    * @return The point at which to display a tooltip, or <code>null</code>
1467:    *     if swing is to choose a default location.
1468:    */
1469:   public Point getToolTipLocation(MouseEvent event)
1470:   {
1471:     return null;
1472:   }
1473: 
1474:   /**
1475:    * Set the value of the {@link #toolTipText} property.
1476:    *
1477:    * @param text The new property value
1478:    *
1479:    * @see #getToolTipText()
1480:    */
1481:   public void setToolTipText(String text)
1482:   {
1483:     if (text == null)
1484:     {
1485:       ToolTipManager.sharedInstance().unregisterComponent(this);
1486:       toolTipText = null;
1487:       return;
1488:     }
1489: 
1490:     // XXX: The tip text doesn't get updated unless you set it to null
1491:     // and then to something not-null. This is consistent with the behaviour
1492:     // of Sun's ToolTipManager.
1493: 
1494:     String oldText = toolTipText;
1495:     toolTipText = text;
1496: 
1497:     if (oldText == null)
1498:       ToolTipManager.sharedInstance().registerComponent(this);
1499:   }
1500: 
1501:   /**
1502:    * Get the value of the {@link #toolTipText} property.
1503:    *
1504:    * @return The current property value
1505:    *
1506:    * @see #setToolTipText
1507:    */
1508:   public String getToolTipText()
1509:   {
1510:     return toolTipText;
1511:   }
1512: 
1513:   /**
1514:    * Get the value of the {@link #toolTipText} property, in response to a
1515:    * particular mouse event.
1516:    *
1517:    * @param event The mouse event which triggered the tooltip
1518:    *
1519:    * @return The current property value
1520:    *
1521:    * @see #setToolTipText
1522:    */
1523:   public String getToolTipText(MouseEvent event)
1524:   {
1525:     return getToolTipText();
1526:   }
1527: 
1528:   /**
1529:    * Return the top level ancestral container (usually a {@link
1530:    * java.awt.Window} or {@link java.applet.Applet}) which this component is
1531:    * contained within, or <code>null</code> if no ancestors exist.
1532:    *
1533:    * @return The top level container, if it exists
1534:    */
1535:   public Container getTopLevelAncestor()
1536:   {
1537:     Container c = getParent();
1538:     for (Container peek = c; peek != null; peek = peek.getParent())
1539:       c = peek;
1540:     return c;
1541:   }
1542: 
1543:   /**
1544:    * Compute the component's visible rectangle, which is defined
1545:    * recursively as either the component's bounds, if it has no parent, or
1546:    * the intersection of the component's bounds with the visible rectangle
1547:    * of its parent.
1548:    *
1549:    * @param rect The return value slot to place the visible rectangle in
1550:    */
1551:   public void computeVisibleRect(Rectangle rect)
1552:   {
1553:     Component c = getParent();
1554:     if (c != null && c instanceof JComponent)
1555:       {
1556:         ((JComponent) c).computeVisibleRect(rect);
1557:         rect.translate(-getX(), -getY());
1558:         rect = SwingUtilities.computeIntersection(0, 0, getWidth(),
1559:                                                   getHeight(), rect);
1560:       }
1561:     else
1562:       rect.setRect(0, 0, getWidth(), getHeight());
1563:   }
1564: 
1565:   /**
1566:    * Return the component's visible rectangle in a new {@link Rectangle},
1567:    * rather than via a return slot.
1568:    *
1569:    * @return the component's visible rectangle
1570:    *
1571:    * @see #computeVisibleRect(Rectangle)
1572:    */
1573:   public Rectangle getVisibleRect()
1574:   {
1575:     Rectangle r = new Rectangle();
1576:     computeVisibleRect(r);
1577:     return r;
1578:   }
1579: 
1580:   /**
1581:    * <p>Requests that this component receive input focus, giving window
1582:    * focus to the top level ancestor of this component. Only works on
1583:    * displayable, focusable, visible components.</p>
1584:    *
1585:    * <p>This method should not be called by clients; it is intended for
1586:    * focus implementations. Use {@link Component#requestFocus()} instead.</p>
1587:    *
1588:    * @see Component#requestFocus()
1589:    */
1590:   public void grabFocus()
1591:   {
1592:     requestFocus();
1593:   }
1594: 
1595:   /**
1596:    * Get the value of the {@link #doubleBuffered} property.
1597:    *
1598:    * @return The property's current value
1599:    */
1600:   public boolean isDoubleBuffered()
1601:   {
1602:     return doubleBuffered;
1603:   }
1604: 
1605:   /**
1606:    * Return <code>true</code> if the provided component has no native peer;
1607:    * in other words, if it is a "lightweight component".
1608:    *
1609:    * @param c The component to test for lightweight-ness
1610:    *
1611:    * @return Whether or not the component is lightweight
1612:    */
1613:   public static boolean isLightweightComponent(Component c)
1614:   {
1615:     return c.getPeer() instanceof LightweightPeer;
1616:   }
1617: 
1618:   /**
1619:    * Return <code>true</code> if you wish this component to manage its own
1620:    * focus. In particular: if you want this component to be sent
1621:    * <code>TAB</code> and <code>SHIFT+TAB</code> key events, and to not
1622:    * have its children considered as focus transfer targets. If
1623:    * <code>true</code>, focus traversal around this component changes to
1624:    * <code>CTRL+TAB</code> and <code>CTRL+SHIFT+TAB</code>.
1625:    *
1626:    * @return <code>true</code> if you want this component to manage its own
1627:    *     focus, otherwise (by default) <code>false</code>
1628:    *
1629:    * @deprecated 1.4 Use {@link Component#setFocusTraversalKeys(int, Set)} and
1630:    *     {@link Container#setFocusCycleRoot(boolean)} instead
1631:    */
1632:   public boolean isManagingFocus()
1633:   {
1634:     return false;
1635:   }
1636: 
1637:   /**
1638:    * Return the current value of the {@link #opaque} property. 
1639:    *
1640:    * @return The current property value
1641:    */
1642:   public boolean isOpaque()
1643:   {
1644:     return opaque;
1645:   }
1646: 
1647:   /**
1648:    * Return <code>true</code> if the component can guarantee that none of its
1649:    * children will overlap in Z-order. This is a hint to the painting system.
1650:    * The default is to return <code>true</code>, but some components such as
1651:    * {@link JLayeredPane} should override this to return <code>false</code>.
1652:    *
1653:    * @return Whether the component tiles its children
1654:    */
1655:   public boolean isOptimizedDrawingEnabled()
1656:   {
1657:     return true;
1658:   }
1659: 
1660:   /**
1661:    * Return <code>true</code> if this component is currently painting a tile,
1662:    * this means that paint() is called again on another child component. This
1663:    * method returns <code>false</code> if this component does not paint a tile
1664:    * or if the last tile is currently painted.
1665:    *
1666:    * @return whether the component is painting a tile
1667:    */
1668:   public boolean isPaintingTile()
1669:   {
1670:     return paintingTile;
1671:   }
1672: 
1673:   /**
1674:    * Get the value of the {@link #requestFocusEnabled} property.
1675:    *
1676:    * @return The current value of the property
1677:    */
1678:   public boolean isRequestFocusEnabled()
1679:   {
1680:     return requestFocusEnabled;
1681:   }
1682: 
1683:   /**
1684:    * Return <code>true</code> if this component is a validation root; this
1685:    * will cause calls to {@link #invalidate()} in this component's children
1686:    * to be "captured" at this component, and not propagate to its parents.
1687:    * For most components this should return <code>false</code>, but some
1688:    * components such as {@link JViewport} will want to return
1689:    * <code>true</code>.
1690:    *
1691:    * @return Whether this component is a validation root
1692:    */
1693:   public boolean isValidateRoot()
1694:   {
1695:     return false;
1696:   }
1697: 
1698:   /**
1699:    * <p>Paint the component. This is a delicate process, and should only be
1700:    * called from the repaint thread, under control of the {@link
1701:    * RepaintManager}. Client code should usually call {@link #repaint()} to
1702:    * trigger painting.</p>
1703:    *
1704:    * <p>The body of the <code>paint</code> call involves calling {@link
1705:    * #paintComponent}, {@link #paintBorder}, and {@link #paintChildren} in
1706:    * order. If you want to customize painting behavior, you should override
1707:    * one of these methods rather than <code>paint</code>.</p>
1708:    *
1709:    * <p>For more details on the painting sequence, see <a
1710:    * href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">
1711:    * this article</a>.</p>
1712:    *
1713:    * @param g The graphics context to paint with
1714:    *
1715:    * @see #paintImmediately(Rectangle)
1716:    */
1717:   public void paint(Graphics g)
1718:   {
1719:     RepaintManager rm = RepaintManager.currentManager(this);
1720:     // We do a little stunt act here to switch on double buffering if it's
1721:     // not already on. If we are not already doublebuffered, then we jump
1722:     // into the method paintDoubleBuffered, which turns on the double buffer
1723:     // and then calls paint(g) again. In the second call we go into the else
1724:     // branch of this if statement and actually paint things to the double
1725:     // buffer. When this method completes, the call stack unwinds back to
1726:     // paintDoubleBuffered, where the buffer contents is finally drawn to the
1727:     // screen.
1728:     if (!isPaintingDoubleBuffered && isDoubleBuffered()
1729:         && rm.isDoubleBufferingEnabled())
1730:       {
1731:         Rectangle clip = g.getClipBounds();
1732:         paintDoubleBuffered(clip);
1733:       }
1734:     else
1735:       {
1736:         if (getClientProperty("bufferedDragging") != null
1737:             && dragBuffer == null)
1738:           {
1739:             initializeDragBuffer();
1740:           }
1741:         else if (getClientProperty("bufferedDragging") == null
1742:             && dragBuffer != null)
1743:           {
1744:             dragBuffer = null;
1745:           }
1746: 
1747:         if (g.getClip() == null)
1748:           g.setClip(0, 0, getWidth(), getHeight());
1749:         if (dragBuffer != null && dragBufferInitialized)
1750:           {
1751:             g.drawImage(dragBuffer, 0, 0, this);
1752:           }
1753:         else
1754:           {
1755:             Graphics g2 = getComponentGraphics(g);
1756:             paintComponent(g2);
1757:             paintBorder(g2);
1758:             paintChildren(g2);
1759:           }
1760:       }
1761:   }
1762: 
1763:   /**
1764:    * Initializes the drag buffer by creating a new image and painting this
1765:    * component into it.
1766:    */
1767:   private void initializeDragBuffer()
1768:   {
1769:     dragBufferInitialized = false;
1770:     // Allocate new dragBuffer if the current one is too small.
1771:     if (dragBuffer == null || dragBuffer.getWidth(this) < getWidth()
1772:         || dragBuffer.getHeight(this) < getHeight())
1773:       {
1774:         dragBuffer = createImage(getWidth(), getHeight());
1775:       }
1776:     Graphics g = dragBuffer.getGraphics();
1777:     paint(g);
1778:     g.dispose();
1779:     dragBufferInitialized = true;
1780:   }
1781: 
1782:   /**
1783:    * Paint the component's border. This usually means calling {@link
1784:    * Border#paintBorder} on the {@link #border} property, if it is
1785:    * non-<code>null</code>. You may override this if you wish to customize
1786:    * border painting behavior. The border is painted after the component's
1787:    * body, but before the component's children.
1788:    *
1789:    * @param g The graphics context with which to paint the border
1790:    *
1791:    * @see #paint
1792:    * @see #paintChildren
1793:    * @see #paintComponent
1794:    */
1795:   protected void paintBorder(Graphics g)
1796:   {
1797:     if (getBorder() != null)
1798:       getBorder().paintBorder(this, g, 0, 0, getWidth(), getHeight());
1799:   }
1800: 
1801:   /**
1802:    * Paint the component's children. This usually means calling {@link
1803:    * Container#paint}, which recursively calls {@link #paint} on any of the
1804:    * component's children, with appropriate changes to coordinate space and
1805:    * clipping region. You may override this if you wish to customize
1806:    * children painting behavior. The children are painted after the
1807:    * component's body and border.
1808:    *
1809:    * @param g The graphics context with which to paint the children
1810:    *
1811:    * @see #paint
1812:    * @see #paintBorder
1813:    * @see #paintComponent
1814:    */
1815:   protected void paintChildren(Graphics g)
1816:   {
1817:     if (getComponentCount() > 0)
1818:       {
1819:         if (isOptimizedDrawingEnabled())
1820:           paintChildrenOptimized(g);
1821:         else
1822:           paintChildrenWithOverlap(g);
1823:       }
1824:   }
1825: 
1826:   /**
1827:    * Paints the children of this JComponent in the case when the component
1828:    * is not marked as optimizedDrawingEnabled, that means the container cannot
1829:    * guarantee that it's children are tiled. For this case we must
1830:    * perform a more complex optimization to determine the minimal rectangle
1831:    * to be painted for each child component.
1832:    *
1833:    * @param g the graphics context to use
1834:    */
1835:   private void paintChildrenWithOverlap(Graphics g)
1836:   {
1837:     Shape originalClip = g.getClip();
1838:     Rectangle inner = SwingUtilities.calculateInnerArea(this, rectCache);
1839:     g.clipRect(inner.x, inner.y, inner.width, inner.height);
1840:     Component[] children = getComponents();
1841: 
1842:     // Find the rectangles that need to be painted for each child component.
1843:     // We push on this list arrays that have the Rectangles to be painted as
1844:     // the first elements and the component to be painted as the last one.
1845:     // Later we go through that list in reverse order and paint the rectangles.
1846:     ArrayList paintRegions = new ArrayList(children.length);
1847:     ArrayList paintRectangles = new ArrayList();
1848:     ArrayList newPaintRects = new ArrayList();
1849:     paintRectangles.add(g.getClipBounds());
1850:     ArrayList componentRectangles = new ArrayList();
1851: 
1852:     // Go through children from top to bottom and find out their paint
1853:     // rectangles.
1854:     for (int index = 0; paintRectangles.size() > 0 &&
1855:       index < children.length; index++)
1856:       {
1857:         Component comp = children[index];
1858:         if (! comp.isVisible())
1859:           continue;
1860: 
1861:         Rectangle compBounds = comp.getBounds();
1862:         boolean isOpaque = comp instanceof JComponent
1863:                            && ((JComponent) comp).isOpaque();
1864: 
1865:         // Add all the current paint rectangles that intersect with the
1866:         // component to the component's paint rectangle array.
1867:         for (int i = paintRectangles.size() - 1; i >= 0; i--)
1868:           {
1869:             Rectangle r = (Rectangle) paintRectangles.get(i);
1870:             if (r.intersects(compBounds))
1871:               {
1872:                 Rectangle compRect = r.intersection(compBounds);
1873:                 componentRectangles.add(compRect);
1874:                 // If the component is opaque, split up each paint rect and
1875:                 // add paintRect - compBounds to the newPaintRects array.
1876:                 if (isOpaque)
1877:                   {
1878:                     int x, y, w, h;
1879:                     Rectangle rect = new Rectangle();
1880: 
1881:                     // The north retangle.
1882:                     x = Math.max(compBounds.x, r.x);
1883:                     y = r.y;
1884:                     w = Math.min(compBounds.width, r.width + r.x - x);
1885:                     h = compBounds.y - r.y;
1886:                     rect.setBounds(x, y, w, h);
1887:                     if (! rect.isEmpty())
1888:                       {
1889:                         newPaintRects.add(rect);
1890:                         rect = new Rectangle();
1891:                       }
1892: 
1893:                     // The south rectangle.
1894:                     x = Math.max(compBounds.x, r.x);
1895:                     y = compBounds.y + compBounds.height;
1896:                     w = Math.min(compBounds.width, r.width + r.x - x);
1897:                     h = r.height - (compBounds.y - r.y) - compBounds.height;
1898:                     rect.setBounds(x, y, w, h);
1899:                     if (! rect.isEmpty())
1900:                       {
1901:                         newPaintRects.add(rect);
1902:                         rect = new Rectangle();
1903:                       }
1904: 
1905:                     // The west rectangle.
1906:                     x = r.x;
1907:                     y = r.y;
1908:                     w = compBounds.x - r.x;
1909:                     h = r.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 east rectangle.
1918:                     x = compBounds.x + compBounds.width;
1919:                     y = r.y;
1920:                     w = r.width - (compBounds.x - r.x) - compBounds.width;
1921:                     h = r.height;
1922:                     rect.setBounds(x, y, w, h);
1923:                     if (! rect.isEmpty())
1924:                       {
1925:                         newPaintRects.add(rect);
1926:                       }
1927:                   }
1928:                 else
1929:                   {
1930:                     // Not opaque, need to reuse the current paint rectangles
1931:                     // for the next component.
1932:                     newPaintRects.add(r);
1933:                   }
1934:                 
1935:               }
1936:             else
1937:               {
1938:                 newPaintRects.add(r);
1939:               }
1940:           }
1941: 
1942:         // Replace the paintRectangles with the new split up
1943:         // paintRectangles.
1944:         paintRectangles.clear();
1945:         paintRectangles.addAll(newPaintRects);
1946:         newPaintRects.clear();
1947: 
1948:         // Store paint rectangles if there are any for the current component.
1949:         int compRectsSize = componentRectangles.size();
1950:         if (compRectsSize > 0)
1951:           {
1952:             componentRectangles.add(comp);
1953:             paintRegions.add(componentRectangles);
1954:             componentRectangles = new ArrayList();
1955:           }
1956:       }
1957: 
1958:     // paintingTile becomes true just before we start painting the component's
1959:     // children.
1960:     paintingTile = true;
1961: 
1962:     // We must go through the painting regions backwards, because the
1963:     // topmost components have been added first, followed by the components
1964:     // below.
1965:     int prEndIndex = paintRegions.size() - 1;
1966:     for (int i = prEndIndex; i >= 0; i--)
1967:       {
1968:         // paintingTile must be set to false before we begin to start painting
1969:         // the last tile.
1970:         if (i == 0)
1971:           paintingTile = false;
1972: 
1973:         ArrayList paintingRects = (ArrayList) paintRegions.get(i);
1974:         // The last element is always the component.
1975:         Component c = (Component) paintingRects.get(paintingRects.size() - 1);
1976:         int endIndex = paintingRects.size() - 2;
1977:         for (int j = 0; j <= endIndex; j++)
1978:           {
1979:             Rectangle cBounds = c.getBounds();
1980:             Rectangle bounds = (Rectangle) paintingRects.get(j);
1981:             Rectangle oldClip = g.getClipBounds();
1982:             if (oldClip == null)
1983:               oldClip = bounds;
1984: 
1985:             boolean translated = false;
1986:             try
1987:               {
1988:                 g.setClip(bounds);
1989:                 g.translate(cBounds.x, cBounds.y);
1990:                 translated = true;
1991:                 c.paint(g);
1992:               }
1993:             finally
1994:               {
1995:                 if (translated)
1996:                   g.translate(-cBounds.x, -cBounds.y);
1997:                 g.setClip(oldClip);
1998:               }
1999:           }
2000:       }
2001:     g.setClip(originalClip);
2002:   }
2003: 
2004:   /**
2005:    * Paints the children of this container when it is marked as
2006:    * optimizedDrawingEnabled. In this case the container can guarantee that
2007:    * it's children are tiled, which allows for a much more efficient
2008:    * algorithm to determine the minimum rectangles to be painted for
2009:    * each child.
2010:    *
2011:    * @param g the graphics context to use
2012:    */
2013:   private void paintChildrenOptimized(Graphics g)
2014:   {
2015:     Shape originalClip = g.getClip();
2016:     Rectangle inner = SwingUtilities.calculateInnerArea(this, rectCache);
2017:     g.clipRect(inner.x, inner.y, inner.width, inner.height);
2018:     Component[] children = getComponents();
2019: 
2020:     // paintingTile becomes true just before we start painting the component's
2021:     // children.
2022:     paintingTile = true;
2023:     for (int i = children.length - 1; i >= 0; i--) //children.length; i++)
2024:       {
2025:         // paintingTile must be set to false before we begin to start painting
2026:         // the last tile.
2027:         if (i == children.length - 1)
2028:           paintingTile = false;
2029: 
2030:         if (!children[i].isVisible())
2031:           continue;
2032: 
2033:         Rectangle bounds = children[i].getBounds(rectCache);
2034:         Rectangle oldClip = g.getClipBounds();
2035:         if (oldClip == null)
2036:           oldClip = bounds;
2037: 
2038:         if (!g.hitClip(bounds.x, bounds.y, bounds.width, bounds.height))
2039:           continue;
2040: 
2041:         boolean translated = false;
2042:         Graphics g2 = g.create(bounds.x, bounds.y, bounds.width,
2043:                                bounds.height);
2044:         children[i].paint(g2);
2045:         g2.dispose();
2046:       }
2047:     g.setClip(originalClip);
2048:   }
2049: 
2050:   /**
2051:    * Paint the component's body. This usually means calling {@link
2052:    * ComponentUI#update} on the {@link #ui} property of the component, if
2053:    * it is non-<code>null</code>. You may override this if you wish to
2054:    * customize the component's body-painting behavior. The component's body
2055:    * is painted first, before the border and children.
2056:    *
2057:    * @param g The graphics context with which to paint the body
2058:    *
2059:    * @see #paint
2060:    * @see #paintBorder
2061:    * @see #paintChildren
2062:    */
2063:   protected void paintComponent(Graphics g)
2064:   {
2065:     if (ui != null)
2066:       {
2067:         Graphics g2 = g;
2068:         if (!(g instanceof Graphics2D))
2069:           g2 = g.create();
2070:         ui.update(g2, this);
2071:         if (!(g instanceof Graphics2D))
2072:           g2.dispose();
2073:       }
2074:   }
2075: 
2076:   /**
2077:    * A variant of {@link #paintImmediately(Rectangle)} which takes
2078:    * integer parameters.
2079:    *
2080:    * @param x The left x coordinate of the dirty region
2081:    * @param y The top y coordinate of the dirty region
2082:    * @param w The width of the dirty region
2083:    * @param h The height of the dirty region
2084:    */
2085:   public void paintImmediately(int x, int y, int w, int h)
2086:   {
2087:     paintImmediately(new Rectangle(x, y, w, h));
2088:   }
2089: 
2090:   /**
2091:    * Transform the provided dirty rectangle for this component into the
2092:    * appropriate ancestral {@link JRootPane} and call {@link #paint} on
2093:    * that root pane. This method is called from the {@link RepaintManager}
2094:    * and should always be called within the painting thread.
2095:    *
2096:    * <p>This method will acquire a double buffer from the {@link
2097:    * RepaintManager} if the component's {@link #doubleBuffered} property is
2098:    * <code>true</code> and the <code>paint</code> call is the
2099:    * <em>first</em> recursive <code>paint</code> call inside swing.</p>
2100:    *
2101:    * <p>The method will also modify the provided {@link Graphics} context
2102:    * via the {@link #getComponentGraphics} method. If you want to customize
2103:    * the graphics object used for painting, you should override that method
2104:    * rather than <code>paint</code>.</p>
2105:    *
2106:    * @param r The dirty rectangle to paint
2107:    */
2108:   public void paintImmediately(Rectangle r)
2109:   {
2110:     // Try to find a root pane for this component.
2111:     //Component root = findPaintRoot(r);
2112:     Component root = findPaintRoot(r);
2113:     // If no paint root is found, then this component is completely overlapped
2114:     // by another component and we don't need repainting.
2115:     if (root == null)
2116:       return;
2117:     if (root == null || !root.isShowing())
2118:       return;
2119: 
2120:     Rectangle rootClip = SwingUtilities.convertRectangle(this, r, root);
2121:     if (root instanceof JComponent)
2122:       ((JComponent) root).paintImmediately2(rootClip);
2123:     else
2124:       root.repaint(rootClip.x, rootClip.y, rootClip.width, rootClip.height);
2125:   }
2126: 
2127:   /**
2128:    * Performs the actual work of paintImmediatly on the repaint root.
2129:    *
2130:    * @param r the area to be repainted
2131:    */
2132:   void paintImmediately2(Rectangle r)
2133:   {
2134:     RepaintManager rm = RepaintManager.currentManager(this);
2135:     if (rm.isDoubleBufferingEnabled() && isDoubleBuffered())
2136:       paintDoubleBuffered(r);
2137:     else
2138:       paintSimple(r);
2139:   }
2140: 
2141:   /**
2142:    * Gets the root of the component given. If a parent of the 
2143:    * component is an instance of Applet, then the applet is 
2144:    * returned. The applet is considered the root for painting
2145:    * and adding/removing components. Otherwise, the root Window
2146:    * is returned if it exists.
2147:    * 
2148:    * @param comp - The component to get the root for.
2149:    * @return the parent root. An applet if it is a parent,
2150:    * or the root window. If neither exist, null is returned.
2151:    */
2152:   private Component getRoot(Component comp)
2153:   {
2154:       Applet app = null;
2155:       
2156:       while (comp != null)
2157:         {
2158:           if (app == null && comp instanceof Window)
2159:             return comp;
2160:           else if (comp instanceof Applet)
2161:             app = (Applet) comp;
2162:           comp = comp.getParent();
2163:         }
2164:       
2165:       return app;
2166:   }
2167:   
2168:   /**
2169:    * Performs double buffered repainting.
2170:    */
2171:   private void paintDoubleBuffered(Rectangle r)
2172:   {
2173:     RepaintManager rm = RepaintManager.currentManager(this);
2174: 
2175:     // Paint on the offscreen buffer.
2176:     Component root = getRoot(this);
2177:     Image buffer = rm.getVolatileOffscreenBuffer(this, root.getWidth(),
2178:                                                  root.getHeight());
2179: 
2180:     // The volatile offscreen buffer may be null when that's not supported
2181:     // by the AWT backend. Fall back to normal backbuffer in this case.
2182:     if (buffer == null)
2183:       buffer = rm.getOffscreenBuffer(this, root.getWidth(), root.getHeight());
2184: 
2185:     //Rectangle targetClip = SwingUtilities.convertRectangle(this, r, root);
2186:     Point translation = SwingUtilities.convertPoint(this, 0, 0, root);
2187:     Graphics g2 = buffer.getGraphics();
2188:     clipAndTranslateGraphics(root, this, g2);
2189:     g2.clipRect(r.x, r.y, r.width, r.height);
2190:     g2 = getComponentGraphics(g2);
2191:     isPaintingDoubleBuffered = true;
2192:     try
2193:       {
2194:         paint(g2);
2195:       }
2196:     finally
2197:       {
2198:         isPaintingDoubleBuffered = false;
2199:         g2.dispose();
2200:       }
2201: 
2202:     // Paint the buffer contents on screen.
2203:     rm.commitBuffer(root, new Rectangle(translation.x + r.x,
2204:                                         translation.y + r.y, r.width,
2205:                                         r.height));
2206:   }
2207: 
2208:   /**
2209:    * Clips and translates the Graphics instance for painting on the double
2210:    * buffer. This has to be done, so that it reflects the component clip of the
2211:    * target component.
2212:    *
2213:    * @param root the root component (top-level container usually)
2214:    * @param target the component to be painted
2215:    * @param g the Graphics instance
2216:    */
2217:   private void clipAndTranslateGraphics(Component root, Component target,
2218:                                         Graphics g)
2219:   {
2220:     Component parent = target.getParent();
2221:     if (parent != root)
2222:       clipAndTranslateGraphics(root, parent, g);
2223: 
2224:     g.translate(target.getX(), target.getY());
2225:     g.clipRect(0, 0, target.getWidth(), target.getHeight());
2226:   }
2227: 
2228:   /**
2229:    * Performs normal painting without double buffering.
2230:    *
2231:    * @param r the area that should be repainted
2232:    */
2233:   void paintSimple(Rectangle r)
2234:   {
2235:     Graphics g = getGraphics();
2236:     Graphics g2 = getComponentGraphics(g);
2237:     g2.setClip(r);
2238:     paint(g2);
2239:     g2.dispose();
2240:     if (g != g2)
2241:       g.dispose();
2242:   }
2243: 
2244:   /**
2245:    * Return a string representation for this component, for use in
2246:    * debugging.
2247:    *
2248:    * @return A string describing this component.
2249:    */
2250:   protected String paramString()
2251:   {
2252:     StringBuffer sb = new StringBuffer();
2253:     sb.append(super.paramString());
2254:     sb.append(",alignmentX=").append(getAlignmentX());
2255:     sb.append(",alignmentY=").append(getAlignmentY());
2256:     sb.append(",border=");
2257:     if (getBorder() != null)
2258:       sb.append(getBorder());
2259:     sb.append(",maximumSize=");
2260:     if (getMaximumSize() != null)
2261:       sb.append(getMaximumSize());
2262:     sb.append(",minimumSize=");
2263:     if (getMinimumSize() != null)
2264:       sb.append(getMinimumSize());
2265:     sb.append(",preferredSize=");
2266:     if (getPreferredSize() != null)
2267:       sb.append(getPreferredSize());
2268:     return sb.toString();
2269:   }
2270: 
2271:   /**
2272:    * A variant of {@link
2273:    * #registerKeyboardAction(ActionListener,String,KeyStroke,int)} which
2274:    * provides <code>null</code> for the command name.   
2275:    */
2276:   public void registerKeyboardAction(ActionListener act,
2277:                                      KeyStroke stroke, 
2278:                                      int cond)
2279:   {
2280:     registerKeyboardAction(act, null, stroke, cond);
2281:   }
2282: 
2283:   /* 
2284:    * There is some charmingly undocumented behavior sun seems to be using
2285:    * to simulate the old register/unregister keyboard binding API. It's not
2286:    * clear to me why this matters, but we shall endeavour to follow suit.
2287:    *
2288:    * Two main thing seem to be happening when you do registerKeyboardAction():
2289:    * 
2290:    *  - no actionMap() entry gets created, just an entry in inputMap()
2291:    *
2292:    *  - the inputMap() entry is a proxy class which invokes the the
2293:    *  binding's actionListener as a target, and which clobbers the command
2294:    *  name sent in the ActionEvent, providing the binding command name
2295:    *  instead.
2296:    *
2297:    * This much you can work out just by asking the input and action maps
2298:    * what they contain after making bindings, and watching the event which
2299:    * gets delivered to the recipient. Beyond that, it seems to be a
2300:    * sun-private solution so I will only immitate it as much as it matters
2301:    * to external observers.
2302:    */
2303:   private static class ActionListenerProxy
2304:     extends AbstractAction
2305:   {
2306:     ActionListener target;
2307:     String bindingCommandName;
2308: 
2309:     public ActionListenerProxy(ActionListener li, 
2310:                                String cmd)
2311:     {
2312:       target = li;
2313:       bindingCommandName = cmd;
2314:     }
2315: 
2316:     public void actionPerformed(ActionEvent e)
2317:     {
2318:       ActionEvent derivedEvent = new ActionEvent(e.getSource(),
2319:                                                  e.getID(),
2320:                                                  bindingCommandName,
2321:                                                  e.getModifiers());
2322:       target.actionPerformed(derivedEvent);
2323:     }
2324:   }
2325: 
2326:   
2327:   /**
2328:    * An obsolete method to register a keyboard action on this component.
2329:    * You should use <code>getInputMap</code> and <code>getActionMap</code>
2330:    * to fetch mapping tables from keystrokes to commands, and commands to
2331:    * actions, respectively, and modify those mappings directly.
2332:    *
2333:    * @param act The action to be registered
2334:    * @param cmd The command to deliver in the delivered {@link
2335:    *     java.awt.event.ActionEvent}
2336:    * @param stroke The keystroke to register on
2337:    * @param cond One of the values {@link #UNDEFINED_CONDITION},
2338:    *     {@link #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}, {@link #WHEN_FOCUSED}, or
2339:    *     {@link #WHEN_IN_FOCUSED_WINDOW}, indicating the condition which must
2340:    *     be met for the action to be fired
2341:    *
2342:    * @see #unregisterKeyboardAction
2343:    * @see #getConditionForKeyStroke
2344:    * @see #resetKeyboardActions
2345:    */
2346:   public void registerKeyboardAction(ActionListener act, 
2347:                                      String cmd,
2348:                                      KeyStroke stroke, 
2349:                                      int cond)
2350:   {
2351:     getInputMap(cond).put(stroke, new ActionListenerProxy(act, cmd));
2352:   }
2353: 
2354:   public final void setInputMap(int condition, InputMap map)
2355:   {
2356:     enableEvents(AWTEvent.KEY_EVENT_MASK);
2357:     switch (condition)
2358:       {
2359:       case WHEN_FOCUSED:
2360:         inputMap_whenFocused = map;
2361:         break;
2362: 
2363:       case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
2364:         inputMap_whenAncestorOfFocused = map;
2365:         break;
2366: 
2367:       case WHEN_IN_FOCUSED_WINDOW:
2368:         if (map != null && !(map instanceof ComponentInputMap))
2369:             throw new 
2370:               IllegalArgumentException("WHEN_IN_FOCUSED_WINDOW " + 
2371:                                        "InputMap must be a ComponentInputMap");
2372:         inputMap_whenInFocusedWindow = (ComponentInputMap)map;
2373:         break;
2374:         
2375:       case UNDEFINED_CONDITION:
2376:       default:
2377:         throw new IllegalArgumentException();
2378:       }
2379:   }
2380: 
2381:   /**
2382:    * Returns the input map associated with this component for the given
2383:    * state/condition.
2384:    * 
2385:    * @param condition  the state (one of {@link #WHEN_FOCUSED}, 
2386:    *     {@link #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT} and 
2387:    *     {@link #WHEN_IN_FOCUSED_WINDOW}).
2388:    * 
2389:    * @return The input map.
2390:    * @throws IllegalArgumentException if <code>condition</code> is not one of 
2391:    *             the specified values.
2392:    * @since 1.3
2393:    */
2394:   public final InputMap getInputMap(int condition)
2395:   {
2396:     enableEvents(AWTEvent.KEY_EVENT_MASK);
2397:     switch (condition)
2398:       {
2399:       case WHEN_FOCUSED:
2400:         if (inputMap_whenFocused == null)
2401:           inputMap_whenFocused = new InputMap();
2402:         return inputMap_whenFocused;
2403: 
2404:       case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
2405:         if (inputMap_whenAncestorOfFocused == null)
2406:           inputMap_whenAncestorOfFocused = new InputMap();
2407:         return inputMap_whenAncestorOfFocused;
2408: 
2409:       case WHEN_IN_FOCUSED_WINDOW:
2410:         if (inputMap_whenInFocusedWindow == null)
2411:           inputMap_whenInFocusedWindow = new ComponentInputMap(this);
2412:         return inputMap_whenInFocusedWindow;
2413: 
2414:       case UNDEFINED_CONDITION:
2415:       default:
2416:         throw new IllegalArgumentException("Invalid 'condition' argument: " 
2417:                                            + condition);
2418:       }
2419:   }
2420: 
2421:   /**
2422:    * Returns the input map associated with this component for the 
2423:    * {@link #WHEN_FOCUSED} state.
2424:    * 
2425:    * @return The input map.
2426:    * 
2427:    * @since 1.3
2428:    * @see #getInputMap(int)
2429:    */
2430:   public final InputMap getInputMap()
2431:   {
2432:     return getInputMap(WHEN_FOCUSED);
2433:   }
2434: 
2435:   public final ActionMap getActionMap()
2436:   {
2437:     if (actionMap == null)
2438:       actionMap = new ActionMap();
2439:     return actionMap;
2440:   }
2441: 
2442:   public final void setActionMap(ActionMap map)
2443:   {
2444:     actionMap = map;
2445:   }
2446: 
2447:   /**
2448:    * Return the condition that determines whether a registered action
2449:    * occurs in response to the specified keystroke.
2450:    *
2451:    * As of 1.3 KeyStrokes can be registered with multiple simultaneous
2452:    * conditions.
2453:    *
2454:    * @param ks The keystroke to return the condition of
2455:    *
2456:    * @return One of the values {@link #UNDEFINED_CONDITION}, {@link
2457:    *     #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}, {@link #WHEN_FOCUSED}, or {@link
2458:    *     #WHEN_IN_FOCUSED_WINDOW}
2459:    *
2460:    * @see #registerKeyboardAction(ActionListener, KeyStroke, int)   
2461:    * @see #unregisterKeyboardAction   
2462:    * @see #resetKeyboardActions
2463:    */
2464:   public int getConditionForKeyStroke(KeyStroke ks)
2465:   {
2466:     if (inputMap_whenFocused != null 
2467:         && inputMap_whenFocused.get(ks) != null)
2468:       return WHEN_FOCUSED;
2469:     else if (inputMap_whenAncestorOfFocused != null 
2470:              && inputMap_whenAncestorOfFocused.get(ks) != null)
2471:       return WHEN_ANCESTOR_OF_FOCUSED_COMPONENT;
2472:     else if (inputMap_whenInFocusedWindow != null 
2473:              && inputMap_whenInFocusedWindow.get(ks) != null)
2474:       return WHEN_IN_FOCUSED_WINDOW;
2475:     else
2476:       return UNDEFINED_CONDITION;
2477:   }
2478: 
2479:   /**
2480:    * Get the ActionListener (typically an {@link Action} object) which is
2481:    * associated with a particular keystroke. 
2482:    *
2483:    * @param ks The keystroke to retrieve the action of
2484:    *
2485:    * @return The action associated with the specified keystroke
2486:    */
2487:   public ActionListener getActionForKeyStroke(KeyStroke ks)
2488:   {
2489:     Object cmd = getInputMap().get(ks);
2490:     if (cmd != null)
2491:       {
2492:         if (cmd instanceof ActionListenerProxy)
2493:           return (ActionListenerProxy) cmd;
2494:         else if (cmd instanceof String)
2495:           return getActionMap().get(cmd);
2496:       }
2497:     return null;
2498:   }
2499: 
2500:   /**
2501:    * A hook for subclasses which want to customize event processing.
2502:    */
2503:   protected void processComponentKeyEvent(KeyEvent e)
2504:   {
2505:     // This method does nothing, it is meant to be overridden by subclasses.
2506:   }
2507: 
2508:   /**
2509:    * Override the default key dispatch system from Component to hook into
2510:    * the swing {@link InputMap} / {@link ActionMap} system.
2511:    *
2512:    * See <a
2513:    * href="http://java.sun.com/products/jfc/tsc/special_report/kestrel/keybindings.html">
2514:    * this report</a> for more details, it's somewhat complex.
2515:    */
2516:   protected void processKeyEvent(KeyEvent e)
2517:   {
2518:     // let the AWT event processing send KeyEvents to registered listeners
2519:     super.processKeyEvent(e);
2520:     processComponentKeyEvent(e);
2521: 
2522:     if (e.isConsumed())
2523:       return;
2524: 
2525:     // Input maps are checked in this order:
2526:     // 1. The focused component's WHEN_FOCUSED map is checked.
2527:     // 2. The focused component's WHEN_ANCESTOR_OF_FOCUSED_COMPONENT map.
2528:     // 3. The WHEN_ANCESTOR_OF_FOCUSED_COMPONENT maps of the focused
2529:     //    component's parent, then its parent's parent, and so on.
2530:     //    Note: Input maps for disabled components are skipped.
2531:     // 4. The WHEN_IN_FOCUSED_WINDOW maps of all the enabled components in
2532:     //    the focused window are searched.
2533:     
2534:     KeyStroke keyStroke = KeyStroke.getKeyStrokeForEvent(e);
2535:     boolean pressed = e.getID() == KeyEvent.KEY_PRESSED;
2536:     
2537:     if (processKeyBinding(keyStroke, e, WHEN_FOCUSED, pressed))
2538:       {
2539:         // This is step 1 from above comment.
2540:         e.consume();
2541:         return;
2542:       }
2543:     else if (processKeyBinding
2544:              (keyStroke, e, WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed))
2545:       {
2546:         // This is step 2 from above comment.
2547:         e.consume();
2548:         return;
2549:       }
2550:     
2551:     // This is step 3 from above comment.
2552:     Container current = getParent();    
2553:     while (current != null)
2554:       { 
2555:         // If current is a JComponent, see if it handles the event in its
2556:         // WHEN_ANCESTOR_OF_FOCUSED_COMPONENT maps.
2557:         if ((current instanceof JComponent) && 
2558:             ((JComponent)current).processKeyBinding 
2559:             (keyStroke, e,WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed))
2560:           {
2561:             e.consume();
2562:             return;
2563:           }     
2564:         
2565:         // Stop when we've tried a top-level container and it didn't handle it
2566:         if (current instanceof Window || current instanceof Applet)
2567:           break;        
2568:         
2569:         // Move up the hierarchy
2570:         current = current.getParent();
2571:       }
2572:     
2573:     // Current being null means the JComponent does not currently have a
2574:     // top-level ancestor, in which case we don't need to check 
2575:     // WHEN_IN_FOCUSED_WINDOW bindings.
2576:     if (current == null || e.isConsumed())
2577:       return;
2578:     
2579:     // This is step 4 from above comment.  KeyboardManager maintains mappings
2580:     // related to WHEN_IN_FOCUSED_WINDOW bindings so that we don't have to 
2581:     // traverse the containment hierarchy each time.
2582:     if (KeyboardManager.getManager().processKeyStroke(current, keyStroke, e))
2583:       e.consume();
2584:   }
2585: 
2586:   protected boolean processKeyBinding(KeyStroke ks,
2587:                                       KeyEvent e,
2588:                                       int condition,
2589:                                       boolean pressed)
2590:   { 
2591:     if (isEnabled())
2592:       {
2593:         Action act = null;
2594:         InputMap map = getInputMap(condition);
2595:         if (map != null)
2596:           {
2597:             Object cmd = map.get(ks);
2598:             if (cmd != null)
2599:               {
2600:                 if (cmd instanceof ActionListenerProxy)
2601:                   act = (Action) cmd;
2602:                 else 
2603:                   act = (Action) getActionMap().get(cmd);
2604:               }
2605:           }
2606:         if (act != null && act.isEnabled())
2607:           return SwingUtilities.notifyAction(act, ks, e, this, e.getModifiers());
2608:       }
2609:     return false;
2610:   }
2611:   
2612:   /**
2613:    * Remove a keyboard action registry.
2614:    *
2615:    * @param aKeyStroke The keystroke to unregister
2616:    *
2617:    * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
2618:    * @see #getConditionForKeyStroke
2619:    * @see #resetKeyboardActions
2620:    */
2621:   public void unregisterKeyboardAction(KeyStroke aKeyStroke)
2622:   {
2623:     ActionMap am = getActionMap();
2624:     // This loops through the conditions WHEN_FOCUSED,
2625:     // WHEN_ANCESTOR_OF_FOCUSED_COMPONENT and WHEN_IN_FOCUSED_WINDOW.
2626:     for (int cond = 0; cond < 3; cond++)
2627:       {
2628:         InputMap im = getInputMap(cond);
2629:         if (im != null)
2630:           {
2631:             Object action = im.get(aKeyStroke);
2632:             if (action != null && am != null)
2633:               am.remove(action);
2634:             im.remove(aKeyStroke);
2635:           }
2636:       }
2637:   }
2638: 
2639: 
2640:   /**
2641:    * Reset all keyboard action registries.
2642:    *
2643:    * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
2644:    * @see #unregisterKeyboardAction
2645:    * @see #getConditionForKeyStroke
2646:    */
2647:   public void resetKeyboardActions()
2648:   {
2649:     if (inputMap_whenFocused != null)
2650:       inputMap_whenFocused.clear();
2651:     if (inputMap_whenAncestorOfFocused != null)
2652:       inputMap_whenAncestorOfFocused.clear();
2653:     if (inputMap_whenInFocusedWindow != null)
2654:       inputMap_whenInFocusedWindow.clear();
2655:     if (actionMap != null)
2656:       actionMap.clear();
2657:   }
2658: 
2659:   /**
2660:    * Mark the described region of this component as dirty in the current
2661:    * {@link RepaintManager}. This will queue an asynchronous repaint using
2662:    * the system painting thread in the near future.
2663:    *
2664:    * @param tm ignored
2665:    * @param x coordinate of the region to mark as dirty
2666:    * @param y coordinate of the region to mark as dirty
2667:    * @param width dimension of the region to mark as dirty
2668:    * @param height dimension of the region to mark as dirty
2669:    */
2670:   public void repaint(long tm, int x, int y, int width, int height)
2671:   {
2672:      RepaintManager.currentManager(this).addDirtyRegion(this, x, y, width,
2673:                                                         height);
2674:   }
2675: 
2676:   /**
2677:    * Mark the described region of this component as dirty in the current
2678:    * {@link RepaintManager}. This will queue an asynchronous repaint using
2679:    * the system painting thread in the near future.
2680:    *
2681:    * @param r The rectangle to mark as dirty
2682:    */
2683:   public void repaint(Rectangle r)
2684:   {
2685:     RepaintManager.currentManager(this).addDirtyRegion(this, r.x, r.y, r.width,
2686:                                                        r.height);
2687:   }
2688: 
2689:   /**
2690:    * Request focus on the default component of this component's {@link
2691:    * FocusTraversalPolicy}.
2692:    *
2693:    * @return The result of {@link #requestFocus()}
2694:    *
2695:    * @deprecated Use {@link #requestFocus()} on the default component provided
2696:    *     from the {@link FocusTraversalPolicy} instead.
2697:    */
2698:   public boolean requestDefaultFocus()
2699:   {
2700:     return false;
2701:   }
2702: 
2703:   /**
2704:    * Queue a an invalidation and revalidation of this component, using 
2705:    * {@link RepaintManager#addInvalidComponent}.
2706:    */
2707:   public void revalidate()
2708:   {
2709:     if (! EventQueue.isDispatchThread())
2710:       SwingUtilities.invokeLater(new Runnable()
2711:         {
2712:           public void run()
2713:           {
2714:             revalidate();
2715:           }
2716:         });
2717:     else
2718:       {
2719:         invalidate();
2720:         RepaintManager.currentManager(this).addInvalidComponent(this);
2721:       }
2722:   }
2723: 
2724:   /**
2725:    * Calls <code>scrollRectToVisible</code> on the component's parent. 
2726:    * Components which can service this call should override.
2727:    *
2728:    * @param r The rectangle to make visible
2729:    */
2730:   public void scrollRectToVisible(Rectangle r)
2731:   {
2732:     Component p = getParent();
2733:     if (p instanceof JComponent)
2734:       ((JComponent) p).scrollRectToVisible(r);
2735:   }
2736: 
2737:   /**
2738:    * Set the value of the {@link #alignmentX} property.
2739:    *
2740:    * @param a The new value of the property
2741:    */
2742:   public void setAlignmentX(float a)
2743:   {
2744:     if (a < 0.0F)
2745:       alignmentX = 0.0F;
2746:     else if (a > 1.0)
2747:       alignmentX = 1.0F;
2748:     else
2749:       alignmentX = a;
2750:   }
2751: 
2752:   /**
2753:    * Set the value of the {@link #alignmentY} property.
2754:    *
2755:    * @param a The new value of the property
2756:    */
2757:   public void setAlignmentY(float a)
2758:   {
2759:     if (a < 0.0F)
2760:       alignmentY = 0.0F;
2761:     else if (a > 1.0)
2762:       alignmentY = 1.0F;
2763:     else
2764:       alignmentY = a;
2765:   }
2766: 
2767:   /**
2768:    * Set the value of the {@link #autoscrolls} property.
2769:    *
2770:    * @param a The new value of the property
2771:    */
2772:   public void setAutoscrolls(boolean a)
2773:   {
2774:     autoscrolls = a;
2775:     clientAutoscrollsSet = true;
2776:   }
2777: 
2778:   /**
2779:    * Set the value of the {@link #debugGraphicsOptions} property.
2780:    *
2781:    * @param debugOptions The new value of the property
2782:    */
2783:   public void setDebugGraphicsOptions(int debugOptions)
2784:   {
2785:     debugGraphicsOptions = debugOptions;
2786:   }
2787: 
2788:   /**
2789:    * Set the value of the {@link #doubleBuffered} property.
2790:    *
2791:    * @param db The new value of the property
2792:    */
2793:   public void setDoubleBuffered(boolean db)
2794:   {
2795:     doubleBuffered = db;
2796:   }
2797: 
2798:   /**
2799:    * Set the value of the <code>enabled</code> property.
2800:    *
2801:    * @param enable The new value of the property
2802:    */
2803:   public void setEnabled(boolean enable)
2804:   {
2805:     if (enable == isEnabled())
2806:       return;
2807:     super.setEnabled(enable);
2808:     firePropertyChange("enabled", !enable, enable);
2809:     repaint();
2810:   }
2811: 
2812:   /**
2813:    * Set the value of the <code>font</code> property.
2814:    *
2815:    * @param f The new value of the property
2816:    */
2817:   public void setFont(Font f)
2818:   {
2819:     if (f == getFont())
2820:       return;
2821:     super.setFont(f);
2822:     revalidate();
2823:     repaint();
2824:   }
2825: 
2826:   /**
2827:    * Set the value of the <code>background</code> property.
2828:    *
2829:    * @param bg The new value of the property
2830:    */
2831:   public void setBackground(Color bg)
2832:   {
2833:     if (bg == getBackground())
2834:       return;
2835:     super.setBackground(bg);
2836:     repaint();
2837:   }
2838: 
2839:   /**
2840:    * Set the value of the <code>foreground</code> property.
2841:    *
2842:    * @param fg The new value of the property
2843:    */
2844:   public void setForeground(Color fg)
2845:   {
2846:     if (fg == getForeground())
2847:       return;
2848:     super.setForeground(fg);
2849:     repaint();
2850:   }
2851: 
2852:   /**
2853:    * Set the value of the {@link #maximumSize} property. The passed value is
2854:    * copied, the later direct changes on the argument have no effect on the
2855:    * property value.
2856:    *
2857:    * @param max The new value of the property
2858:    */
2859:   public void setMaximumSize(Dimension max)
2860:   {
2861:     Dimension oldMaximumSize = maximumSize;
2862:     if (max != null) 
2863:       maximumSize = new Dimension(max);
2864:     else
2865:       maximumSize = null;
2866:     firePropertyChange("maximumSize", oldMaximumSize, maximumSize);
2867:   }
2868: 
2869:   /**
2870:    * Set the value of the {@link #minimumSize} property. The passed value is
2871:    * copied, the later direct changes on the argument have no effect on the
2872:    * property value.
2873:    *
2874:    * @param min The new value of the property
2875:    */
2876:   public void setMinimumSize(Dimension min)
2877:   {
2878:     Dimension oldMinimumSize = minimumSize;
2879:     if (min != null)
2880:       minimumSize = new Dimension(min);
2881:     else
2882:       minimumSize = null;
2883:     firePropertyChange("minimumSize", oldMinimumSize, minimumSize);
2884:   }
2885: 
2886:   /**
2887:    * Set the value of the {@link #preferredSize} property. The passed value is
2888:    * copied, the later direct changes on the argument have no effect on the
2889:    * property value.
2890:    *
2891:    * @param pref The new value of the property
2892:    */
2893:   public void setPreferredSize(Dimension pref)
2894:   {
2895:     Dimension oldPreferredSize = preferredSize;
2896:     if (pref != null)
2897:       preferredSize = new Dimension(pref);
2898:     else
2899:       preferredSize = null;
2900:     firePropertyChange("preferredSize", oldPreferredSize, preferredSize);
2901:   }
2902: 
2903:   /**
2904:    * Set the specified component to be the next component in the 
2905:    * focus cycle, overriding the {@link FocusTraversalPolicy} for
2906:    * this component.
2907:    *
2908:    * @param aComponent The component to set as the next focusable
2909:    *
2910:    * @deprecated Use FocusTraversalPolicy instead
2911:    */
2912:   public void setNextFocusableComponent(Component aComponent)
2913:   {
2914:     Container focusRoot = this;
2915:     if (! this.isFocusCycleRoot())
2916:       focusRoot = getFocusCycleRootAncestor();
2917: 
2918:     FocusTraversalPolicy policy  = focusRoot.getFocusTraversalPolicy();
2919:     if (policy instanceof CompatibilityFocusTraversalPolicy)
2920:       {
2921:         policy = new CompatibilityFocusTraversalPolicy(policy);
2922:         focusRoot.setFocusTraversalPolicy(policy);
2923:       }
2924:     CompatibilityFocusTraversalPolicy p =
2925:       (CompatibilityFocusTraversalPolicy) policy;
2926: 
2927:     Component old = getNextFocusableComponent();
2928:     if (old != null)
2929:       {
2930:         p.removeNextFocusableComponent(this, old);
2931:       }
2932: 
2933:     if (aComponent != null)
2934:       {
2935:         p.addNextFocusableComponent(this, aComponent);
2936:       }
2937:   }
2938: 
2939:   /**
2940:    * Set the value of the {@link #requestFocusEnabled} property.
2941:    *
2942:    * @param e The new value of the property
2943:    */
2944:   public void setRequestFocusEnabled(boolean e)
2945:   {
2946:     requestFocusEnabled = e;
2947:   }
2948: 
2949:   /**
2950:    * Get the value of the {@link #transferHandler} property.
2951:    *
2952:    * @return The current value of the property
2953:    *
2954:    * @see #setTransferHandler
2955:    */
2956: 
2957:   public TransferHandler getTransferHandler()
2958:   {
2959:     return transferHandler;
2960:   }
2961: 
2962:   /**
2963:    * Set the value of the {@link #transferHandler} property.
2964:    *
2965:    * @param newHandler The new value of the property
2966:    *
2967:    * @see #getTransferHandler
2968:    */
2969: 
2970:   public void setTransferHandler(TransferHandler newHandler)
2971:   {
2972:     if (transferHandler == newHandler)
2973:       return;
2974: 
2975:     TransferHandler oldHandler = transferHandler;
2976:     transferHandler = newHandler;
2977:     firePropertyChange("transferHandler", oldHandler, newHandler);
2978:   }
2979: 
2980:   /**
2981:    * Set if the component should paint all pixels withing its bounds.
2982:    * If this property is set to false, the component expects the cleared
2983:    * background.
2984:    *
2985:    * @param isOpaque if true, paint all pixels. If false, expect the clean
2986:    * background. 
2987:    *
2988:    * @see ComponentUI#update
2989:    */
2990:   public void setOpaque(boolean isOpaque)
2991:   {
2992:     boolean oldOpaque = opaque;
2993:     opaque = isOpaque;
2994:     clientOpaqueSet = true;
2995:     firePropertyChange("opaque", oldOpaque, opaque);
2996:   }
2997: 
2998:   /**
2999:    * Set the value of the visible property.
3000:    *
3001:    * If the value is changed, then the AncestorListeners of this component
3002:    * and all its children (recursivly) are notified.
3003:    *
3004:    * @param v The new value of the property
3005:    */
3006:   public void setVisible(boolean v)
3007:   {
3008:     // No need to do anything if the actual value doesn't change.
3009:     if (isVisible() == v)
3010:       return;
3011: 
3012:     super.setVisible(v);
3013: 
3014:     // Notify AncestorListeners.
3015:     if (v == true)
3016:       fireAncestorEvent(this, AncestorEvent.ANCESTOR_ADDED);
3017:     else
3018:       fireAncestorEvent(this, AncestorEvent.ANCESTOR_REMOVED);
3019: 
3020:     Container parent = getParent();
3021:     if (parent != null)
3022:       parent.repaint(getX(), getY(), getWidth(), getHeight());
3023:     revalidate();
3024:   }
3025: 
3026:   /**
3027:    * Call {@link #paint}. 
3028:    * 
3029:    * @param g The graphics context to paint into
3030:    */
3031:   public void update(Graphics g)
3032:   {
3033:     paint(g);
3034:   }
3035: 
3036:   /**
3037:    * Get the value of the UIClassID property. This property should be a key
3038:    * in the {@link UIDefaults} table managed by {@link UIManager}, the
3039:    * value of which is the name of a class to load for the component's
3040:    * {@link #ui} property.
3041:    *
3042:    * @return A "symbolic" name which will map to a class to use for the
3043:    * component's UI, such as <code>"ComponentUI"</code>
3044:    *
3045:    * @see #setUI
3046:    * @see #updateUI
3047:    */
3048:   public String getUIClassID()
3049:   {
3050:     return "ComponentUI";
3051:   }
3052: 
3053:   /**
3054:    * Install a new UI delegate as the component's {@link #ui} property. In
3055:    * the process, this will call {@link ComponentUI#uninstallUI} on any
3056:    * existing value for the {@link #ui} property, and {@link
3057:    * ComponentUI#installUI} on the new UI delegate.
3058:    *
3059:    * @param newUI The new UI delegate to install
3060:    *
3061:    * @see #updateUI
3062:    * @see #getUIClassID
3063:    */
3064:   protected void setUI(ComponentUI newUI)
3065:   {
3066:     if (ui != null)
3067:       ui.uninstallUI(this);
3068: 
3069:     ComponentUI oldUI = ui;
3070:     ui = newUI;
3071: 
3072:     if (ui != null)
3073:       ui.installUI(this);
3074: 
3075:     firePropertyChange("UI", oldUI, newUI);
3076:     revalidate();
3077:     repaint();
3078:   }
3079: 
3080:   /**
3081:    * This method should be overridden in subclasses. In JComponent, the
3082:    * method does nothing. In subclasses, it should a UI delegate
3083:    * (corresponding to the symbolic name returned from {@link
3084:    * #getUIClassID}) from the {@link UIManager}, and calls {@link #setUI}
3085:    * with the new delegate.
3086:    */
3087:   public void updateUI()
3088:   {
3089:     // Nothing to do here.
3090:   }
3091: 
3092:   public static Locale getDefaultLocale()
3093:   {
3094:     return defaultLocale;
3095:   }
3096:   
3097:   public static void setDefaultLocale(Locale l)
3098:   {
3099:     defaultLocale = l;
3100:   }
3101:   
3102:   /**
3103:    * Returns the currently set input verifier for this component.
3104:    *
3105:    * @return the input verifier, or <code>null</code> if none
3106:    */
3107:   public InputVerifier getInputVerifier()
3108:   {
3109:     return inputVerifier;
3110:   }
3111: 
3112:   /**
3113:    * Sets the input verifier to use by this component.
3114:    *
3115:    * @param verifier the input verifier, or <code>null</code>
3116:    */
3117:   public void setInputVerifier(InputVerifier verifier)
3118:   {
3119:     InputVerifier oldVerifier = inputVerifier;
3120:     inputVerifier = verifier;
3121:     firePropertyChange("inputVerifier", oldVerifier, verifier);
3122:   }
3123: 
3124:   /**
3125:    * @since 1.3
3126:    */
3127:   public boolean getVerifyInputWhenFocusTarget()
3128:   {
3129:     return verifyInputWhenFocusTarget;
3130:   }
3131: 
3132:   /**
3133:    * @since 1.3
3134:    */
3135:   public void setVerifyInputWhenFocusTarget(boolean verifyInputWhenFocusTarget)
3136:   {
3137:     if (this.verifyInputWhenFocusTarget == verifyInputWhenFocusTarget)
3138:       return;
3139: 
3140:     this.verifyInputWhenFocusTarget = verifyInputWhenFocusTarget;
3141:     firePropertyChange("verifyInputWhenFocusTarget",
3142:                        ! verifyInputWhenFocusTarget,
3143:                        verifyInputWhenFocusTarget);
3144:   }
3145: 
3146:   /**
3147:    * Requests that this component gets the input focus if the
3148:    * requestFocusEnabled property is set to <code>true</code>.
3149:    * This also means that this component's top-level window becomes
3150:    * the focused window, if that is not already the case.
3151:    *
3152:    * The preconditions that have to be met to become a focus owner is that
3153:    * the component must be displayable, visible and focusable.
3154:    *
3155:    * Note that this signals only a request for becoming focused. There are
3156:    * situations in which it is not possible to get the focus. So developers
3157:    * should not assume that the component has the focus until it receives
3158:    * a {@link java.awt.event.FocusEvent} with a value of
3159:    * {@link java.awt.event.FocusEvent#FOCUS_GAINED}.
3160:    *
3161:    * @see Component#requestFocus()
3162:    */
3163:   public void requestFocus()
3164:   {
3165:     if (isRequestFocusEnabled())
3166:       super.requestFocus();
3167:   }
3168: 
3169:   /**
3170:    * This method is overridden to make it public so that it can be used
3171:    * by look and feel implementations.
3172:    *
3173:    * You should not use this method directly. Instead you are strongly
3174:    * encouraged to call {@link #requestFocus()} or 
3175:    * {@link #requestFocusInWindow()} instead.
3176:    *
3177:    * @param temporary if the focus change is temporary
3178:    *
3179:    * @return <code>false</code> if the focus change request will definitly
3180:    *     fail, <code>true</code> if it will likely succeed
3181:    *
3182:    * @see Component#requestFocus(boolean)
3183:    *
3184:    * @since 1.4
3185:    */
3186:   public boolean requestFocus(boolean temporary)
3187:   {
3188:     return super.requestFocus(temporary);
3189:   }
3190: 
3191:   /**
3192:    * Requests that this component gets the input focus if the top level
3193:    * window that contains this component has the focus and the
3194:    * requestFocusEnabled property is set to <code>true</code>.
3195:    *
3196:    * The preconditions that have to be met to become a focus owner is that
3197:    * the component must be displayable, visible and focusable.
3198:    *
3199:    * Note that this signals only a request for becoming focused. There are
3200:    * situations in which it is not possible to get the focus. So developers
3201:    * should not assume that the component has the focus until it receives
3202:    * a {@link java.awt.event.FocusEvent} with a value of
3203:    * {@link java.awt.event.FocusEvent#FOCUS_GAINED}.
3204:    *
3205:    * @return <code>false</code> if the focus change request will definitly
3206:    *     fail, <code>true</code> if it will likely succeed
3207:    *
3208:    * @see Component#requestFocusInWindow()
3209:    */
3210:   public boolean requestFocusInWindow()
3211:   {
3212:     if (isRequestFocusEnabled())
3213:       return super.requestFocusInWindow();
3214:     else
3215:       return false;
3216:   }
3217: 
3218:   /**
3219:    * This method is overridden to make it public so that it can be used
3220:    * by look and feel implementations.
3221:    *
3222:    * You should not use this method directly. Instead you are strongly
3223:    * encouraged to call {@link #requestFocus()} or 
3224:    * {@link #requestFocusInWindow()} instead.
3225:    *
3226:    * @param temporary if the focus change is temporary
3227:    *
3228:    * @return <code>false</code> if the focus change request will definitly
3229:    *     fail, <code>true</code> if it will likely succeed
3230:    *
3231:    * @see Component#requestFocus(boolean)
3232:    *
3233:    * @since 1.4
3234:    */
3235:   protected boolean requestFocusInWindow(boolean temporary)
3236:   {
3237:     return super.requestFocusInWindow(temporary);
3238:   }
3239: 
3240:   /**
3241:    * Receives notification if this component is added to a parent component.
3242:    *
3243:    * Notification is sent to all registered AncestorListeners about the
3244:    * new parent.
3245:    *
3246:    * This method sets up ActionListeners for all registered KeyStrokes of
3247:    * this component in the chain of parent components.
3248:    *
3249:    * A PropertyChange event is fired to indicate that the ancestor property
3250:    * has changed.
3251:    *
3252:    * This method is used internally and should not be used in applications.
3253:    */
3254:   public void addNotify()
3255:   {
3256:     // Register the WHEN_IN_FOCUSED_WINDOW keyboard bindings
3257:     // Note that here we unregister all bindings associated with
3258:     // this component and then re-register them.  This may be more than
3259:     // necessary if the top-level ancestor hasn't changed.  Should
3260:     // maybe improve this.
3261:     KeyboardManager km = KeyboardManager.getManager();
3262:     km.clearBindingsForComp(this);
3263:     km.registerEntireMap((ComponentInputMap)
3264:                          this.getInputMap(WHEN_IN_FOCUSED_WINDOW));
3265:     super.addNotify();
3266: 
3267:     // Notify AncestorListeners.
3268:     fireAncestorEvent(this, AncestorEvent.ANCESTOR_ADDED);
3269: 
3270:     // fire property change event for 'ancestor'
3271:     firePropertyChange("ancestor", null, getParent());
3272:   }
3273: 
3274:   /**
3275:    * Receives notification that this component no longer has a parent.
3276:    *
3277:    * This method sends an AncestorEvent to all registered AncestorListeners,
3278:    * notifying them that the parent is gone.
3279:    *
3280:    * The keybord actions of this component are removed from the parent and
3281:    * its ancestors.
3282:    *
3283:    * A PropertyChangeEvent is fired to indicate that the 'ancestor' property
3284:    * has changed.
3285:    *
3286:    * This method is called before the component is actually removed from
3287:    * its parent, so the parent is still visible through 
3288:    * {@link Component#getParent}.
3289:    */
3290:   public void removeNotify()
3291:   {
3292:     super.removeNotify();
3293: 
3294:     KeyboardManager.getManager().clearBindingsForComp(this);
3295:     
3296:     // Notify ancestor listeners.
3297:     fireAncestorEvent(this, AncestorEvent.ANCESTOR_REMOVED);
3298: 
3299:     // fire property change event for 'ancestor'
3300:     firePropertyChange("ancestor", getParent(), null);
3301:   }
3302: 
3303:   /**
3304:    * Returns <code>true</code> if the coordinates (x, y) lie within
3305:    * the bounds of this component and <code>false</code> otherwise.
3306:    * x and y are relative to the coordinate space of the component.
3307:    *
3308:    * @param x the X coordinate of the point to check
3309:    * @param y the Y coordinate of the point to check
3310:    *
3311:    * @return <code>true</code> if the specified point lies within the bounds
3312:    *     of this component, <code>false</code> otherwise
3313:    */
3314:   public boolean contains(int x, int y)
3315:   {
3316:     if (ui == null)
3317:       return super.contains(x, y);
3318:     else
3319:       return ui.contains(this, x, y);
3320:   }
3321: 
3322:   /**
3323:    * Disables this component.
3324:    *
3325:    * @deprecated replaced by {@link #setEnabled(boolean)}
3326:    */
3327:   public void disable()
3328:   {
3329:     super.disable();
3330:   }
3331: 
3332:   /**
3333:    * Enables this component.
3334:    *
3335:    * @deprecated replaced by {@link #setEnabled(boolean)}
3336:    */
3337:   public void enable()
3338:   {
3339:     super.enable();
3340:   }
3341: 
3342:   /**
3343:    * Returns the Graphics context for this component. This can be used
3344:    * to draw on a component.
3345:    *
3346:    * @return the Graphics context for this component
3347:    */
3348:   public Graphics getGraphics()
3349:   {
3350:     return super.getGraphics();
3351:   }
3352: 
3353:   /**
3354:    * Returns the X coordinate of the upper left corner of this component.
3355:    * Prefer this method over {@link #getBounds} or {@link #getLocation}
3356:    * because it does not cause any heap allocation.
3357:    *
3358:    * @return the X coordinate of the upper left corner of the component
3359:    */
3360:   public int getX()
3361:   {
3362:     return super.getX();
3363:   }
3364: 
3365:   /**
3366:    * Returns the Y coordinate of the upper left corner of this component.
3367:    * Prefer this method over {@link #getBounds} or {@link #getLocation}
3368:    * because it does not cause any heap allocation.
3369:    *
3370:    * @return the Y coordinate of the upper left corner of the component
3371:    */
3372:   public int getY()
3373:   {
3374:     return super.getY();
3375:   }
3376: 
3377:   /**
3378:    * Returns the height of this component. Prefer this method over
3379:    * {@link #getBounds} or {@link #getSize} because it does not cause
3380:    * any heap allocation.
3381:    *
3382:    * @return the height of the component
3383:    */
3384:   public int getHeight()
3385:   {
3386:     return super.getHeight();
3387:   }
3388: 
3389:   /**
3390:    * Returns the width of this component. Prefer this method over
3391:    * {@link #getBounds} or {@link #getSize} because it does not cause
3392:    * any heap allocation.
3393:    *
3394:    * @return the width of the component
3395:    */
3396:   public int getWidth()
3397:   {
3398:     return super.getWidth();
3399:   }
3400: 
3401:   /**
3402:    * Prints this component to the given Graphics context. A call to this
3403:    * method results in calls to the methods {@link #printComponent},
3404:    * {@link #printBorder} and {@link #printChildren} in this order.
3405:    *
3406:    * Double buffering is temporarily turned off so the painting goes directly
3407:    * to the supplied Graphics context.
3408:    *
3409:    * @param g the Graphics context to print onto
3410:    */
3411:   public void print(Graphics g)
3412:   {
3413:     boolean doubleBufferState = isDoubleBuffered();
3414:     setDoubleBuffered(false);
3415:     printComponent(g);
3416:     printBorder(g);
3417:     printChildren(g);
3418:     setDoubleBuffered(doubleBufferState);
3419:   }
3420: 
3421:   /**
3422:    * Prints this component to the given Graphics context. This invokes
3423:    * {@link #print}.
3424:    *
3425:    * @param g the Graphics context to print onto
3426:    */
3427:   public void printAll(Graphics g)
3428:   {
3429:     print(g);
3430:   }
3431: 
3432:   /**
3433:    * Prints this component to the specified Graphics context. The default
3434:    * behaviour is to invoke {@link #paintComponent}. 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 printComponent(Graphics g)
3442:   {
3443:     paintComponent(g);
3444:   }
3445: 
3446:   /**
3447:    * Print this component's children to the specified Graphics context.
3448:    * The default behaviour is to invoke {@link #paintChildren}. Override this
3449:    * if you want special behaviour for printing.
3450:    *
3451:    * @param g the Graphics context to print onto
3452:    *
3453:    * @since 1.3
3454:    */
3455:   protected void printChildren(Graphics g)
3456:   {
3457:     paintChildren(g);
3458:   }
3459: 
3460:   /**
3461:    * Print this component's border to the specified Graphics context.
3462:    * The default behaviour is to invoke {@link #paintBorder}. Override this
3463:    * if you want special behaviour for printing.
3464:    *
3465:    * @param g the Graphics context to print onto
3466:    *
3467:    * @since 1.3
3468:    */
3469:   protected void printBorder(Graphics g)
3470:   {
3471:     paintBorder(g);
3472:   }
3473: 
3474:   /**
3475:    * Processes mouse motion event, like dragging and moving.
3476:    *
3477:    * @param ev the MouseEvent describing the mouse motion
3478:    */
3479:   protected void processMouseMotionEvent(MouseEvent ev)
3480:   {
3481:     super.processMouseMotionEvent(ev);
3482:   }
3483: 
3484:   /**
3485:    * Moves and resizes the component.
3486:    *
3487:    * @param x the new horizontal location
3488:    * @param y the new vertial location
3489:    * @param w the new width
3490:    * @param h the new height
3491:    */
3492:   public void reshape(int x, int y, int w, int h)
3493:   {
3494:     int oldX = getX();
3495:     int oldY = getY();
3496:     super.reshape(x, y, w, h);
3497:     // Notify AncestorListeners.
3498:     if (oldX != getX() || oldY != getY())
3499:       fireAncestorEvent(this, AncestorEvent.ANCESTOR_MOVED);
3500:   }
3501: 
3502:   /**
3503:    * Fires an AncestorEvent to this component's and all of its child
3504:    * component's AncestorListeners.
3505:    *
3506:    * @param ancestor the component that triggered the event
3507:    * @param id the kind of ancestor event that should be fired
3508:    */
3509:   void fireAncestorEvent(JComponent ancestor, int id)
3510:   {
3511:     // Fire event for registered ancestor listeners of this component.
3512:     AncestorListener[] listeners = getAncestorListeners();
3513:     if (listeners.length > 0)
3514:       {
3515:         AncestorEvent ev = new AncestorEvent(this, id,
3516:                                              ancestor, ancestor.getParent());
3517:         for (int i = 0; i < listeners.length; i++)
3518:           {
3519:             switch (id)
3520:               {
3521:               case AncestorEvent.ANCESTOR_MOVED:
3522:                 listeners[i].ancestorMoved(ev);
3523:                 break;
3524:               case AncestorEvent.ANCESTOR_ADDED:
3525:                 listeners[i].ancestorAdded(ev);
3526:                 break;
3527:               case AncestorEvent.ANCESTOR_REMOVED:
3528:                 listeners[i].ancestorRemoved(ev);
3529:                 break;
3530:               }
3531:           }
3532:       }
3533:     // Dispatch event to all children.
3534:     Component[] children = getComponents();
3535:     for (int i = 0; i < children.length; i++)
3536:       {
3537:         if (!(children[i] instanceof JComponent))
3538:           continue;
3539:         JComponent jc = (JComponent) children[i];
3540:         jc.fireAncestorEvent(ancestor, id);
3541:       }
3542:   }
3543: 
3544:   /**
3545:    * Finds a suitable paint root for painting this component. This method first
3546:    * checks if this component is overlapped using
3547:    * {@link #findOverlapFreeParent(Rectangle)}. The returned paint root is then
3548:    * feeded to {@link #findOpaqueParent(Component)} to find the nearest opaque
3549:    * component for this paint root. If no paint is necessary, then we return
3550:    * <code>null</code>.
3551:    *
3552:    * @param c the clip of this component
3553:    *
3554:    * @return the paint root or <code>null</code> if no painting is necessary
3555:    */
3556:   private Component findPaintRoot(Rectangle c)
3557:   {
3558:     Component p = findOverlapFreeParent(c);
3559:     if (p == null)
3560:       return null;
3561:     Component root = findOpaqueParent(p);
3562:     return root;
3563:   }
3564: 
3565:   /**
3566:    * Scans the containment hierarchy upwards for components that overlap the
3567:    * this component in the specified clip. This method returns
3568:    * <code>this</code>, if no component overlaps this component. It returns
3569:    * <code>null</code> if another component completely covers this component
3570:    * in the specified clip (no repaint necessary). If another component partly
3571:    * overlaps this component in the specified clip, then the parent of this
3572:    * component is returned (this is the component that must be used as repaint
3573:    * root). For efficient lookup, the method
3574:    * {@link #isOptimizedDrawingEnabled()} is used.
3575:    *
3576:    * @param clip the clip of this component
3577:    *
3578:    * @return the paint root, or <code>null</code> if no paint is necessary
3579:    */
3580:   private Component findOverlapFreeParent(Rectangle clip)
3581:   {
3582:     Rectangle currentClip = clip;
3583:     Component found = this;
3584:     Container parent = this; 
3585: 
3586:     while (parent != null && !(parent instanceof Window))
3587:       {
3588:         Container newParent = parent.getParent();
3589:         if (newParent == null || newParent instanceof Window)
3590:           break;
3591:         // If the parent is optimizedDrawingEnabled, then its children are
3592:         // tiled and cannot have an overlapping child. Go directly to next
3593:         // parent.
3594:         if ((newParent instanceof JComponent
3595:             && ((JComponent) newParent).isOptimizedDrawingEnabled()))
3596:           
3597:           {
3598:             parent = newParent;
3599:             continue;
3600:           }
3601: 
3602:         // If the parent is not optimizedDrawingEnabled, we must check if the
3603:         // parent or some neighbor overlaps the current clip.
3604: 
3605:         // This is the current clip converted to the parent's coordinate
3606:         // system. TODO: We can do this more efficiently by succesively
3607:         // cumulating the parent-child translations.
3608:         Rectangle target = SwingUtilities.convertRectangle(found,
3609:                                                            currentClip,
3610:                                                            newParent);
3611: 
3612:         // We have an overlap if either:
3613:         // - The new parent itself doesn't completely cover the clip
3614:         //   (this can be the case with viewports).
3615:         // - If some higher-level (than the current) children of the new parent
3616:         //   intersect the target rectangle.
3617:         Rectangle parentRect = SwingUtilities.getLocalBounds(newParent);
3618:         boolean haveOverlap =
3619:           ! SwingUtilities.isRectangleContainingRectangle(parentRect, target);
3620:         if (! haveOverlap)
3621:           {
3622:             Component[] children = newParent.getComponents();
3623:             for (int i = 0; children[i] != parent && !haveOverlap; i++)
3624:               {
3625:                 Rectangle childRect = children[i].getBounds();
3626:                 haveOverlap = target.intersects(childRect);
3627:               }
3628:           }
3629:         if (haveOverlap)
3630:           {
3631:             found = newParent;
3632:             currentClip = target;
3633:           }
3634:         parent = newParent;
3635:       }
3636:     //System.err.println("overlapfree parent: " + found);
3637:     return found;
3638:   }
3639: 
3640:   /**
3641:    * Finds the nearest component to <code>c</code> (upwards in the containment
3642:    * hierarchy), that is opaque. If <code>c</code> itself is opaque,
3643:    * this returns <code>c</code> itself.
3644:    *
3645:    * @param c the start component for the search
3646:    * @return the nearest component to <code>c</code> (upwards in the containment
3647:    *         hierarchy), that is opaque; If <code>c</code> itself is opaque,
3648:    *         this returns <code>c</code> itself
3649:    */
3650:   private Component findOpaqueParent(Component c)
3651:   {
3652:     Component found = c;
3653:     while (true)
3654:       {
3655:         if ((found instanceof JComponent) && ((JComponent) found).isOpaque())
3656:           break;
3657:         else if (!(found instanceof JComponent))
3658:           break;
3659:         Container p = found.getParent();
3660:         if (p == null)
3661:           break;
3662:         else
3663:           found = p;
3664:       }
3665:     return found;
3666:   }
3667:   
3668:   /**
3669:    * This is the method that gets called when the WHEN_IN_FOCUSED_WINDOW map
3670:    * is changed.
3671:    *
3672:    * @param changed the JComponent associated with the WHEN_IN_FOCUSED_WINDOW
3673:    *        map
3674:    */
3675:   void updateComponentInputMap(ComponentInputMap changed)
3676:   {
3677:     // Since you can change a component's input map via
3678:     // setInputMap, we have to check if <code>changed</code>
3679:     // is still in our WHEN_IN_FOCUSED_WINDOW map hierarchy
3680:     InputMap curr = getInputMap(WHEN_IN_FOCUSED_WINDOW);
3681:     while (curr != null && curr != changed)
3682:       curr = curr.getParent();
3683:     
3684:     // If curr is null then changed is not in the hierarchy
3685:     if (curr == null)
3686:       return;
3687:     
3688:     // Now we have to update the keyboard manager's hashtable
3689:     KeyboardManager km = KeyboardManager.getManager();
3690:     
3691:     // This is a poor strategy, should be improved.  We currently 
3692:     // delete all the old bindings for the component and then register
3693:     // the current bindings.
3694:     km.clearBindingsForComp(changed.getComponent());
3695:     km.registerEntireMap((ComponentInputMap) 
3696:                          getInputMap(WHEN_IN_FOCUSED_WINDOW));
3697:   }
3698: 
3699:   /**
3700:    * Helper method for
3701:    * {@link LookAndFeel#installProperty(JComponent, String, Object)}.
3702:    * 
3703:    * @param propertyName the name of the property
3704:    * @param value the value of the property
3705:    *
3706:    * @throws IllegalArgumentException if the specified property cannot be set
3707:    *         by this method
3708:    * @throws ClassCastException if the property value does not match the
3709:    *         property type
3710:    * @throws NullPointerException if <code>c</code> or
3711:    *         <code>propertyValue</code> is <code>null</code>
3712:    */
3713:   void setUIProperty(String propertyName, Object value)
3714:   {
3715:     if (propertyName.equals("opaque"))
3716:       {
3717:         if (! clientOpaqueSet)
3718:           {
3719:             setOpaque(((Boolean) value).booleanValue());
3720:             clientOpaqueSet = false;
3721:           }
3722:       }
3723:     else if (propertyName.equals("autoscrolls"))
3724:       {
3725:         if (! clientAutoscrollsSet)
3726:           {
3727:             setAutoscrolls(((Boolean) value).booleanValue());
3728:             clientAutoscrollsSet = false;
3729:           }
3730:       }
3731:     else
3732:       {
3733:         throw new IllegalArgumentException
3734:             ("Unsupported property for LookAndFeel.installProperty(): "
3735:              + propertyName);
3736:       }
3737:   }
3738: }