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