Source for javax.swing.JComponent

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