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