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