Source for javax.swing.JComponent

   1: /* JComponent.java -- Every component in swing inherits from this class.
   2:    Copyright (C) 2002, 2004, 2005, 2006,  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package javax.swing;
  40: 
  41: import java.applet.Applet;
  42: import java.awt.AWTEvent;
  43: import java.awt.Color;
  44: import java.awt.Component;
  45: import java.awt.Container;
  46: import java.awt.Dimension;
  47: import java.awt.EventQueue;
  48: import java.awt.FocusTraversalPolicy;
  49: import java.awt.Font;
  50: import java.awt.Graphics;
  51: import java.awt.Image;
  52: import java.awt.Insets;
  53: import java.awt.Point;
  54: import java.awt.Rectangle;
  55: import java.awt.Window;
  56: import java.awt.dnd.DropTarget;
  57: import java.awt.event.ActionEvent;
  58: import java.awt.event.ActionListener;
  59: import java.awt.event.ContainerEvent;
  60: import java.awt.event.ContainerListener;
  61: import java.awt.event.FocusEvent;
  62: import java.awt.event.FocusListener;
  63: import java.awt.event.KeyEvent;
  64: import java.awt.event.MouseEvent;
  65: import java.awt.peer.LightweightPeer;
  66: import java.beans.PropertyChangeEvent;
  67: import java.beans.PropertyChangeListener;
  68: import java.beans.PropertyVetoException;
  69: import java.beans.VetoableChangeListener;
  70: import java.beans.VetoableChangeSupport;
  71: import java.io.Serializable;
  72: import java.util.ArrayList;
  73: import java.util.EventListener;
  74: import java.util.Hashtable;
  75: import java.util.Locale;
  76: import java.util.Set;
  77: 
  78: import javax.accessibility.Accessible;
  79: import javax.accessibility.AccessibleContext;
  80: import javax.accessibility.AccessibleExtendedComponent;
  81: import javax.accessibility.AccessibleKeyBinding;
  82: import javax.accessibility.AccessibleRole;
  83: import javax.accessibility.AccessibleState;
  84: import javax.accessibility.AccessibleStateSet;
  85: import javax.swing.border.Border;
  86: import javax.swing.border.CompoundBorder;
  87: import javax.swing.border.TitledBorder;
  88: import javax.swing.event.AncestorEvent;
  89: import javax.swing.event.AncestorListener;
  90: import javax.swing.event.EventListenerList;
  91: import javax.swing.plaf.ComponentUI;
  92: 
  93: /**
  94:  * The base class of all Swing components.
  95:  * It contains generic methods to manage events, properties and sizes. Actual
  96:  * drawing of the component is channeled to a look-and-feel class that is
  97:  * implemented elsewhere.
  98:  *
  99:  * @author Ronald Veldema (rveldema&064;cs.vu.nl)
 100:  * @author Graydon Hoare (graydon&064;redhat.com)
 101:  */
 102: public abstract class JComponent extends Container implements Serializable
 103: {
 104:   private static final long serialVersionUID = -7908749299918704233L;
 105: 
 106:   /** 
 107:    * The accessible context of this <code>JComponent</code>.
 108:    */
 109:   protected AccessibleContext accessibleContext;
 110: 
 111:   /**
 112:    * Basic accessibility support for <code>JComponent</code> derived
 113:    * widgets.
 114:    */
 115:   public abstract class AccessibleJComponent 
 116:     extends AccessibleAWTContainer
 117:     implements AccessibleExtendedComponent
 118:   {
 119:     /**
 120:      * Receives notification if the focus on the JComponent changes and
 121:      * fires appropriate PropertyChangeEvents to listeners registered with
 122:      * the AccessibleJComponent.
 123:      */
 124:     protected class AccessibleFocusHandler 
 125:       implements FocusListener
 126:     {
 127:       /**
 128:        * Creates a new AccessibleFocusHandler.
 129:        */
 130:       protected AccessibleFocusHandler()
 131:       {
 132:         // Nothing to do here.
 133:       }
 134: 
 135:       /**
 136:        * Receives notification when the JComponent gained focus and fires
 137:        * a PropertyChangeEvent to listeners registered on the
 138:        * AccessibleJComponent with a property name of
 139:        * {@link AccessibleContext#ACCESSIBLE_STATE_PROPERTY} and a new value
 140:        * of {@link AccessibleState#FOCUSED}.
 141:        */
 142:       public void focusGained(FocusEvent event)
 143:       {
 144:         AccessibleJComponent.this.firePropertyChange
 145:           (AccessibleContext.ACCESSIBLE_STATE_PROPERTY, null,
 146:            AccessibleState.FOCUSED);
 147:       }
 148: 
 149:       /**
 150:        * Receives notification when the JComponent lost focus and fires
 151:        * a PropertyChangeEvent to listeners registered on the
 152:        * AccessibleJComponent with a property name of
 153:        * {@link AccessibleContext#ACCESSIBLE_STATE_PROPERTY} and an old value
 154:        * of {@link AccessibleState#FOCUSED}.
 155:        */
 156:       public void focusLost(FocusEvent valevent)
 157:       {
 158:         AccessibleJComponent.this.firePropertyChange
 159:           (AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
 160:            AccessibleState.FOCUSED, null);
 161:       }
 162:     }
 163: 
 164:     /**
 165:      * Receives notification if there are child components are added or removed
 166:      * from the JComponent and fires appropriate PropertyChangeEvents to
 167:      * interested listeners on the AccessibleJComponent.
 168:      */
 169:     protected class AccessibleContainerHandler 
 170:       implements ContainerListener
 171:     {
 172:       /**
 173:        * Creates a new AccessibleContainerHandler.
 174:        */
 175:       protected AccessibleContainerHandler()
 176:       {
 177:         // Nothing to do here.
 178:       }
 179: 
 180:       /**
 181:        * Receives notification when a child component is added to the
 182:        * JComponent and fires a PropertyChangeEvent on listeners registered
 183:        * with the AccessibleJComponent with a property name of
 184:        * {@link AccessibleContext#ACCESSIBLE_CHILD_PROPERTY}.
 185:        *
 186:        * @param event the container event
 187:        */
 188:       public void componentAdded(ContainerEvent event)
 189:       {
 190:         Component c = event.getChild();
 191:         if (c != null && c instanceof Accessible)
 192:           {
 193:             AccessibleContext childCtx = c.getAccessibleContext();
 194:             AccessibleJComponent.this.firePropertyChange
 195:               (AccessibleContext.ACCESSIBLE_CHILD_PROPERTY, null, childCtx);
 196:           }
 197:       }
 198: 
 199:       /**
 200:        * Receives notification when a child component is removed from the
 201:        * JComponent and fires a PropertyChangeEvent on listeners registered
 202:        * with the AccessibleJComponent with a property name of
 203:        * {@link AccessibleContext#ACCESSIBLE_CHILD_PROPERTY}.
 204:        *
 205:        * @param event the container event
 206:        */
 207:       public void componentRemoved(ContainerEvent event)
 208:       {
 209:         Component c = event.getChild();
 210:         if (c != null && c instanceof Accessible)
 211:           {
 212:             AccessibleContext childCtx = c.getAccessibleContext();
 213:             AccessibleJComponent.this.firePropertyChange
 214:               (AccessibleContext.ACCESSIBLE_CHILD_PROPERTY, childCtx, null);
 215:           }
 216:       }
 217:     }
 218: 
 219:     private static final long serialVersionUID = -7047089700479897799L;
 220: 
 221:     /**
 222:      * Receives notification when a child component is added to the
 223:      * JComponent and fires a PropertyChangeEvent on listeners registered
 224:      * with the AccessibleJComponent.
 225:      *
 226:      * @specnote AccessibleAWTContainer has a protected field with the same
 227:      *           name. Looks like a bug or nasty misdesign to me.
 228:      */
 229:     protected ContainerListener accessibleContainerHandler;
 230: 
 231:     /**
 232:      * Receives notification if the focus on the JComponent changes and
 233:      * fires appropriate PropertyChangeEvents to listeners registered with
 234:      * the AccessibleJComponent.
 235:      *
 236:      * @specnote AccessibleAWTComponent has a protected field
 237:      *           accessibleAWTFocusHandler. Looks like a bug or nasty misdesign
 238:      *           to me.
 239:      */
 240:     protected FocusListener accessibleFocusHandler;
 241: 
 242:     /**
 243:      * Creates a new AccessibleJComponent.
 244:      */
 245:     protected AccessibleJComponent()
 246:     {
 247:       // Nothing to do here.
 248:     }
 249: 
 250:     /**
 251:      * Adds a property change listener to the list of registered listeners.
 252:      *
 253:      * This sets up the {@link #accessibleContainerHandler} and
 254:      * {@link #accessibleFocusHandler} fields and calls
 255:      * <code>super.addPropertyChangeListener(listener)</code>.
 256:      *
 257:      * @param listener the listener to add
 258:      */
 259:     public void addPropertyChangeListener(PropertyChangeListener listener)
 260:     {
 261:       // Tests seem to indicate that this method also sets up the other two
 262:       // handlers.
 263:       if (accessibleContainerHandler == null)
 264:         {
 265:           accessibleContainerHandler = new AccessibleContainerHandler();
 266:           addContainerListener(accessibleContainerHandler);
 267:         }
 268:       if (accessibleFocusHandler == null)
 269:         {
 270:           accessibleFocusHandler = new AccessibleFocusHandler();
 271:           addFocusListener(accessibleFocusHandler);
 272:         }
 273:       super.addPropertyChangeListener(listener);
 274:     }
 275: 
 276:     /**
 277:      * Removes a property change listener from the list of registered listeners.
 278:      *
 279:      * This uninstalls the {@link #accessibleContainerHandler} and
 280:      * {@link #accessibleFocusHandler} fields and calls
 281:      * <code>super.removePropertyChangeListener(listener)</code>.
 282:      *
 283:      * @param listener the listener to remove
 284:      */
 285:     public void removePropertyChangeListener(PropertyChangeListener listener)
 286:     {
 287:       // Tests seem to indicate that this method also resets the other two
 288:       // handlers.
 289:       if (accessibleContainerHandler != null)
 290:         {
 291:           removeContainerListener(accessibleContainerHandler);
 292:           accessibleContainerHandler = null;
 293:         }
 294:       if (accessibleFocusHandler != null)
 295:         {
 296:           removeFocusListener(accessibleFocusHandler);
 297:           accessibleFocusHandler = null;
 298:         }
 299:       super.removePropertyChangeListener(listener);
 300:     }
 301: 
 302:     /**
 303:      * Returns the number of accessible children of this object.
 304:      *
 305:      * @return  the number of accessible children of this object
 306:      */
 307:     public int getAccessibleChildrenCount()
 308:     {
 309:       // TODO: The functionality should be performed in the superclass.
 310:       // Find out why this is overridden. However, it is very well possible
 311:       // that this is left over from times when there was no such superclass
 312:       // method.
 313:       return super.getAccessibleChildrenCount();
 314:     }
 315: 
 316:     /**
 317:      * Returns the accessible child component at index <code>i</code>.
 318:      *
 319:      * @param i the index of the accessible child to return
 320:      *
 321:      * @return the accessible child component at index <code>i</code>
 322:      */
 323:     public Accessible getAccessibleChild(int i)
 324:     {
 325:       // TODO: The functionality should be performed in the superclass.
 326:       // Find out why this is overridden. However, it is very well possible
 327:       // that this is left over from times when there was no such superclass
 328:       // method.
 329:       return super.getAccessibleChild(i);
 330:     }
 331: 
 332:     /**
 333:      * Returns the accessible state set of this component.
 334:      *
 335:      * @return the accessible state set of this component
 336:      */
 337:     public AccessibleStateSet getAccessibleStateSet()
 338:     {
 339:       // Note: While the java.awt.Component has an 'opaque' property, it
 340:       // seems that it is not added to the accessible state set there, even
 341:       // if this property is true. However, it is handled for JComponent, so
 342:       // we add it here.
 343:       AccessibleStateSet state = super.getAccessibleStateSet();
 344:       if (isOpaque())
 345:         state.add(AccessibleState.OPAQUE);
 346:       return state;
 347:     }
 348: 
 349:     /**
 350:      * Returns the localized name for this object. Generally this should
 351:      * almost never return {@link Component#getName()} since that is not
 352:      * a localized name. If the object is some kind of text component (like
 353:      * a menu item), then the value of the object may be returned. Also, if
 354:      * the object has a tooltip, the value of the tooltip may also be
 355:      * appropriate.
 356:      *
 357:      * @return the localized name for this object or <code>null</code> if this
 358:      *         object has no name
 359:      */
 360:     public String getAccessibleName()
 361:     {
 362:       String name = super.getAccessibleName();
 363: 
 364:       // There are two fallbacks provided by the JComponent in the case the
 365:       // superclass returns null:
 366:       // - If the component is inside a titled border, then it inherits the
 367:       //   name from the border title.
 368:       // - If the component is not inside a titled border but has a label
 369:       //   (via JLabel.setLabelFor()), then it gets the name from the label's
 370:       //   accessible context.
 371: 
 372:       if (name == null)
 373:         {
 374:           name = getTitledBorderText();
 375:         }
 376: 
 377:       if (name == null)
 378:         {
 379:           Object l = getClientProperty(JLabel.LABEL_PROPERTY);
 380:           if (l instanceof Accessible)
 381:             {
 382:               AccessibleContext labelCtx =
 383:                 ((Accessible) l).getAccessibleContext();
 384:               name = labelCtx.getAccessibleName();
 385:             }
 386:         }
 387: 
 388:       return name;
 389:     }
 390: 
 391:     /**
 392:      * Returns the localized description of this object.
 393:      *
 394:      * @return the localized description of this object or <code>null</code>
 395:      *         if this object has no description
 396:      */
 397:     public String getAccessibleDescription()
 398:     {
 399:       // There are two fallbacks provided by the JComponent in the case the
 400:       // superclass returns null:
 401:       // - If the component has a tooltip, then inherit the description from
 402:       //   the tooltip.
 403:       // - If the component is not inside a titled border but has a label
 404:       //   (via JLabel.setLabelFor()), then it gets the name from the label's
 405:       //   accessible context.
 406:       String descr = super.getAccessibleDescription();
 407: 
 408:       if (descr == null)
 409:         {
 410:           descr = getToolTipText();
 411:         }
 412: 
 413:       if (descr == null)
 414:         {
 415:           Object l = getClientProperty(JLabel.LABEL_PROPERTY);
 416:           if (l instanceof Accessible)
 417:             {
 418:               AccessibleContext labelCtx =
 419:                 ((Accessible) l).getAccessibleContext();
 420:               descr = labelCtx.getAccessibleName();
 421:             }
 422:         }
 423: 
 424:       return descr;
 425:     }
 426: 
 427:     /**
 428:      * Returns the accessible role of this component.
 429:      *
 430:      * @return the accessible role of this component
 431:      *
 432:      * @see AccessibleRole
 433:      */
 434:     public AccessibleRole getAccessibleRole()
 435:     {
 436:       return AccessibleRole.SWING_COMPONENT;
 437:     }
 438: 
 439:     /**
 440:      * Recursivly searches a border hierarchy (starting at <code>border) for
 441:      * a titled border and returns the title if one is found, <code>null</code>
 442:      * otherwise.
 443:      *
 444:      * @param border the border to start search from
 445:      *
 446:      * @return the border title of a possibly found titled border
 447:      */
 448:     protected String getBorderTitle(Border border)
 449:     {
 450:       String title = null;
 451:       if (border instanceof CompoundBorder)
 452:         {
 453:           CompoundBorder compound = (CompoundBorder) border;
 454:           Border inner = compound.getInsideBorder();
 455:           title = getBorderTitle(inner);
 456:           if (title == null)
 457:             {
 458:               Border outer = compound.getOutsideBorder();
 459:               title = getBorderTitle(outer);
 460:             }
 461:         }
 462:       else if (border instanceof TitledBorder)
 463:         {
 464:           TitledBorder titled = (TitledBorder) border;
 465:           title = titled.getTitle(); 
 466:         }
 467:       return title;
 468:     }
 469: 
 470:     /**
 471:      * Returns the tooltip text for this accessible component.
 472:      *
 473:      * @return the tooltip text for this accessible component
 474:      */
 475:     public String getToolTipText()
 476:     {
 477:       return JComponent.this.getToolTipText();
 478:     }
 479: 
 480:     /**
 481:      * Returns the title of the border of this accessible component if
 482:      * this component has a titled border, otherwise returns <code>null</code>.
 483:      *
 484:      * @return the title of the border of this accessible component if
 485:      *         this component has a titled border, otherwise returns
 486:      *         <code>null</code>
 487:      */
 488:     public String getTitledBorderText()
 489:     {
 490:       return getBorderTitle(getBorder()); 
 491:     }
 492: 
 493:     /**
 494:      * Returns the keybindings associated with this accessible component or
 495:      * <code>null</code> if the component does not support key bindings.
 496:      *
 497:      * @return the keybindings associated with this accessible component
 498:      */
 499:     public AccessibleKeyBinding getAccessibleKeyBinding()
 500:     {
 501:       // The reference implementation seems to always return null here,
 502:       // independent of the key bindings of the JComponent. So do we.
 503:       return null;
 504:     }
 505:   }
 506: 
 507:   /**
 508:    * A value between 0.0 and 1.0 indicating the preferred horizontal
 509:    * alignment of the component, relative to its siblings. The values
 510:    * {@link #LEFT_ALIGNMENT}, {@link #CENTER_ALIGNMENT}, and {@link
 511:    * #RIGHT_ALIGNMENT} can also be used, as synonyms for <code>0.0</code>,
 512:    * <code>0.5</code>, and <code>1.0</code>, respectively. Not all layout
 513:    * managers use this property.
 514:    *
 515:    * @see #getAlignmentX
 516:    * @see #setAlignmentX
 517:    * @see javax.swing.OverlayLayout
 518:    * @see javax.swing.BoxLayout
 519:    */
 520:   float alignmentX = -1.0F;
 521: 
 522:   /**
 523:    * A value between 0.0 and 1.0 indicating the preferred vertical
 524:    * alignment of the component, relative to its siblings. The values
 525:    * {@link #TOP_ALIGNMENT}, {@link #CENTER_ALIGNMENT}, and {@link
 526:    * #BOTTOM_ALIGNMENT} can also be used, as synonyms for <code>0.0</code>,
 527:    * <code>0.5</code>, and <code>1.0</code>, respectively. Not all layout
 528:    * managers use this property.
 529:    *
 530:    * @see #getAlignmentY
 531:    * @see #setAlignmentY
 532:    * @see javax.swing.OverlayLayout
 533:    * @see javax.swing.BoxLayout
 534:    */
 535:   float alignmentY = -1.0F;
 536: 
 537:   /** 
 538:    * The border painted around this component.
 539:    * 
 540:    * @see #paintBorder
 541:    */
 542:   Border border;
 543: 
 544:   /**
 545:    * The popup menu for the component.
 546:    * 
 547:    * @see #getComponentPopupMenu()
 548:    * @see #setComponentPopupMenu(JPopupMenu)
 549:    */
 550:   JPopupMenu componentPopupMenu;
 551:    
 552:   /**
 553:    * A flag that controls whether the {@link #getComponentPopupMenu()} method
 554:    * looks to the component's parent when the <code>componentPopupMenu</code>
 555:    * field is <code>null</code>.
 556:    */
 557:   boolean inheritsPopupMenu;
 558:   
 559:   /** 
 560:    * <p>Whether to double buffer this component when painting. This flag
 561:    * should generally be <code>true</code>, to ensure good painting
 562:    * performance.</p>
 563:    *
 564:    * <p>All children of a double buffered component are painted into the
 565:    * double buffer automatically, so only the top widget in a window needs
 566:    * to be double buffered.</p>
 567:    *
 568:    * @see #setDoubleBuffered
 569:    * @see #isDoubleBuffered
 570:    * @see #paint
 571:    */
 572:   boolean doubleBuffered = true;
 573: 
 574:   /**
 575:    * A set of flags indicating which debugging graphics facilities should
 576:    * be enabled on this component. The values should be a combination of
 577:    * {@link DebugGraphics#NONE_OPTION}, {@link DebugGraphics#LOG_OPTION},
 578:    * {@link DebugGraphics#FLASH_OPTION}, or {@link
 579:    * DebugGraphics#BUFFERED_OPTION}.
 580:    *
 581:    * @see #setDebugGraphicsOptions
 582:    * @see #getDebugGraphicsOptions
 583:    * @see DebugGraphics
 584:    * @see #getComponentGraphics
 585:    */
 586:   int debugGraphicsOptions;
 587: 
 588:   /** 
 589:    * <p>This property controls two independent behaviors simultaneously.</p>
 590:    *
 591:    * <p>First, it controls whether to fill the background of this widget
 592:    * when painting its body. This affects calls to {@link
 593:    * JComponent#paintComponent}, which in turn calls {@link
 594:    * ComponentUI#update} on the component's {@link #ui} property. If the
 595:    * component is opaque during this call, the background will be filled
 596:    * before calling {@link ComponentUI#paint}. This happens merely as a
 597:    * convenience; you may fill the component's background yourself too,
 598:    * but there is no need to do so if you will be filling with the same
 599:    * color.</p>
 600:    *
 601:    * <p>Second, it the opaque property informs swing's repaint system
 602:    * whether it will be necessary to paint the components "underneath" this
 603:    * component, in Z-order. If the component is opaque, it is considered to
 604:    * completely occlude components "underneath" it, so they will not be
 605:    * repainted along with the opaque component.</p>
 606:    *
 607:    * <p>The default value for this property is <code>false</code>, but most
 608:    * components will want to set it to <code>true</code> when installing UI
 609:    * defaults in {@link ComponentUI#installUI}.</p>
 610:    *
 611:    * @see #setOpaque
 612:    * @see #isOpaque
 613:    * @see #paintComponent
 614:    */
 615:   boolean opaque = false;
 616: 
 617:   /** 
 618:    * The user interface delegate for this component. Event delivery and
 619:    * repainting of the component are usually delegated to this object. 
 620:    *
 621:    * @see #setUI
 622:    * @see #getUIClassID
 623:    * @see #updateUI
 624:    */
 625:   protected ComponentUI ui;
 626: 
 627:   /**
 628:    * A hint to the focus system that this component should or should not
 629:    * get focus. If this is <code>false</code>, swing will not try to
 630:    * request focus on this component; if <code>true</code>, swing might
 631:    * try to request focus, but the request might fail. Thus it is only 
 632:    * a hint guiding swing's behavior.
 633:    *
 634:    * @see #requestFocus()
 635:    * @see #isRequestFocusEnabled
 636:    * @see #setRequestFocusEnabled
 637:    */
 638:   boolean requestFocusEnabled;
 639: 
 640:   /**
 641:    * Flag indicating behavior of this component when the mouse is dragged
 642:    * outside the component and the mouse <em>stops moving</em>. If
 643:    * <code>true</code>, synthetic mouse events will be delivered on regular
 644:    * timed intervals, continuing off in the direction the mouse exited the
 645:    * component, until the mouse is released or re-enters the component.
 646:    *
 647:    * @see #setAutoscrolls
 648:    * @see #getAutoscrolls
 649:    */
 650:   boolean autoscrolls = false;
 651: 
 652:   /**
 653:    * Indicates whether the current paint call is already double buffered or
 654:    * not. 
 655:    */
 656:   static boolean paintingDoubleBuffered = false;
 657: 
 658:   /**
 659:    * Indicates whether we are calling paintDoubleBuffered() from
 660:    * paintImmadiately (RepaintManager) or from paint() (AWT refresh).
 661:    */
 662:   static boolean isRepainting = false;
 663: 
 664:   /**
 665:    * Listeners for events other than {@link PropertyChangeEvent} are
 666:    * handled by this listener list. PropertyChangeEvents are handled in
 667:    * {@link #changeSupport}.
 668:    */
 669:   protected EventListenerList listenerList = new EventListenerList();
 670: 
 671:   /**
 672:    * Handles VetoableChangeEvents.
 673:    */
 674:   private VetoableChangeSupport vetoableChangeSupport;
 675: 
 676:   /** 
 677:    * Storage for "client properties", which are key/value pairs associated
 678:    * with this component by a "client", such as a user application or a
 679:    * layout manager. This is lazily constructed when the component gets its
 680:    * first client property.
 681:    */
 682:   private Hashtable clientProperties;
 683:   
 684:   private InputMap inputMap_whenFocused;
 685:   private InputMap inputMap_whenAncestorOfFocused;
 686:   private ComponentInputMap inputMap_whenInFocusedWindow;
 687:   private ActionMap actionMap;
 688:   /** @since 1.3 */
 689:   private boolean verifyInputWhenFocusTarget = true;
 690:   private InputVerifier inputVerifier;
 691: 
 692:   private TransferHandler transferHandler;
 693: 
 694:   /**
 695:    * Indicates if this component is currently painting a tile or not.
 696:    */
 697:   private boolean paintingTile;
 698: 
 699:   /**
 700:    * A temporary buffer used for fast dragging of components.
 701:    */
 702:   private Image dragBuffer;
 703: 
 704:   /**
 705:    * Indicates if the dragBuffer is already initialized.
 706:    */
 707:   private boolean dragBufferInitialized;
 708: 
 709:   /**
 710:    * A cached Rectangle object to be reused. Be careful when you use that,
 711:    * so that it doesn't get modified in another context within the same
 712:    * method call chain.
 713:    */
 714:   private static transient Rectangle rectCache;
 715: 
 716:   /**
 717:    * The default locale of the component.
 718:    * 
 719:    * @see #getDefaultLocale
 720:    * @see #setDefaultLocale
 721:    */
 722:   private static Locale defaultLocale;
 723:   
 724:   public static final String TOOL_TIP_TEXT_KEY = "ToolTipText";
 725: 
 726:   /**
 727:    * Constant used to indicate that no condition has been assigned to a
 728:    * particular action.
 729:    *
 730:    * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
 731:    */
 732:   public static final int UNDEFINED_CONDITION = -1;
 733: 
 734:   /**
 735:    * Constant used to indicate that an action should be performed only when 
 736:    * the component has focus.
 737:    *
 738:    * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
 739:    */
 740:   public static final int WHEN_FOCUSED = 0;
 741: 
 742:   /**
 743:    * Constant used to indicate that an action should be performed only when 
 744:    * the component is an ancestor of the component which has focus.
 745:    *
 746:    * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
 747:    */
 748:   public static final int WHEN_ANCESTOR_OF_FOCUSED_COMPONENT = 1;
 749: 
 750:   /**
 751:    * Constant used to indicate that an action should be performed only when 
 752:    * the component is in the window which has focus.
 753:    *
 754:    * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
 755:    */
 756:   public static final int WHEN_IN_FOCUSED_WINDOW = 2;
 757: 
 758: 
 759:   /**
 760:    * Used to optimize painting. This is set in paintImmediately2() to specify
 761:    * the exact component path to be painted by paintChildren.
 762:    */
 763:   Component paintChild;
 764: 
 765:   /**
 766:    * Indicates if the opaque property has been set by a client program or by
 767:    * the UI.
 768:    *
 769:    * @see #setUIProperty(String, Object)
 770:    * @see LookAndFeel#installProperty(JComponent, String, Object)
 771:    */
 772:   private boolean clientOpaqueSet = false;
 773: 
 774:   /**
 775:    * Indicates if the autoscrolls property has been set by a client program or
 776:    * by the UI.
 777:    *
 778:    * @see #setUIProperty(String, Object)
 779:    * @see LookAndFeel#installProperty(JComponent, String, Object)
 780:    */
 781:   private boolean clientAutoscrollsSet = false;
 782: 
 783:   /**
 784:    * Creates a new <code>JComponent</code> instance.
 785:    */
 786:   public JComponent()
 787:   {
 788:     super();
 789:     setDropTarget(new DropTarget());
 790:     setLocale(getDefaultLocale());
 791:     debugGraphicsOptions = DebugGraphics.NONE_OPTION;
 792:     setRequestFocusEnabled(true);
 793:   }
 794: 
 795:   /**
 796:    * Helper to lazily construct and return the client properties table.
 797:    * 
 798:    * @return The current client properties table
 799:    *
 800:    * @see #clientProperties
 801:    * @see #getClientProperty
 802:    * @see #putClientProperty
 803:    */
 804:   private Hashtable getClientProperties()
 805:   {
 806:     if (clientProperties == null)
 807:       clientProperties = new Hashtable();
 808:     return clientProperties;
 809:   }
 810: 
 811:   /**
 812:    * Get a client property associated with this component and a particular
 813:    * key.
 814:    *
 815:    * @param key The key with which to look up the client property
 816:    *
 817:    * @return A client property associated with this object and key
 818:    *
 819:    * @see #clientProperties
 820:    * @see #getClientProperties
 821:    * @see #putClientProperty
 822:    */
 823:   public final Object getClientProperty(Object key)
 824:   {
 825:     return getClientProperties().get(key);
 826:   }
 827: 
 828:   /**
 829:    * Add a client property <code>value</code> to this component, associated
 830:    * with <code>key</code>. If there is an existing client property
 831:    * associated with <code>key</code>, it will be replaced.  A
 832:    * {@link PropertyChangeEvent} is sent to registered listeners (with the
 833:    * name of the property being <code>key.toString()</code>).
 834:    *
 835:    * @param key The key of the client property association to add
 836:    * @param value The value of the client property association to add
 837:    *
 838:    * @see #clientProperties
 839:    * @see #getClientProperties
 840:    * @see #getClientProperty
 841:    */
 842:   public final void putClientProperty(Object key, Object value)
 843:   {
 844:     Hashtable t = getClientProperties();
 845:     Object old = t.get(key);
 846:     if (value != null)
 847:       t.put(key, value);
 848:     else
 849:       t.remove(key);
 850: 
 851:     // When both old and new value are null, no event is fired. This is
 852:     // different from what firePropertyChange() normally does, so we add this
 853:     // check here.
 854:     if (old != null || value != null)
 855:       firePropertyChange(key.toString(), old, value);
 856:   }
 857: 
 858:   /**
 859:    * Unregister an <code>AncestorListener</code>.
 860:    *
 861:    * @param listener The listener to unregister
 862:    * 
 863:    * @see #addAncestorListener
 864:    */
 865:   public void removeAncestorListener(AncestorListener listener)
 866:   {
 867:     listenerList.remove(AncestorListener.class, listener);
 868:   }
 869: 
 870:   /**
 871:    * Unregister a <code>VetoableChangeChangeListener</code>.
 872:    *
 873:    * @param listener The listener to unregister
 874:    *
 875:    * @see #addVetoableChangeListener
 876:    */
 877:   public void removeVetoableChangeListener(VetoableChangeListener listener)
 878:   {
 879:     if (vetoableChangeSupport != null)
 880:       vetoableChangeSupport.removeVetoableChangeListener(listener);
 881:   }
 882: 
 883:   /**
 884:    * Register an <code>AncestorListener</code>.
 885:    *
 886:    * @param listener The listener to register
 887:    *
 888:    * @see #removeVetoableChangeListener
 889:    */
 890:   public void addAncestorListener(AncestorListener listener)
 891:   {
 892:     listenerList.add(AncestorListener.class, listener);
 893:   }
 894: 
 895:   /**
 896:    * Register a <code>VetoableChangeListener</code>.
 897:    *
 898:    * @param listener The listener to register
 899:    *
 900:    * @see #removeVetoableChangeListener
 901:    * @see #listenerList
 902:    */
 903:   public void addVetoableChangeListener(VetoableChangeListener listener)
 904:   {
 905:     // Lazily instantiate this, it's rarely needed.
 906:     if (vetoableChangeSupport == null)
 907:       vetoableChangeSupport = new VetoableChangeSupport(this);
 908:     vetoableChangeSupport.addVetoableChangeListener(listener);
 909:   }
 910: 
 911:   /**
 912:    * Returns all registered {@link EventListener}s of the given 
 913:    * <code>listenerType</code>.
 914:    *
 915:    * @param listenerType the class of listeners to filter (<code>null</code> 
 916:    *                     not permitted).
 917:    *                     
 918:    * @return An array of registered listeners.
 919:    * 
 920:    * @throws ClassCastException if <code>listenerType</code> does not implement
 921:    *                            the {@link EventListener} interface.
 922:    * @throws NullPointerException if <code>listenerType</code> is 
 923:    *                              <code>null</code>.
 924:    *                            
 925:    * @see #getAncestorListeners()
 926:    * @see #listenerList
 927:    * 
 928:    * @since 1.3
 929:    */
 930:   public <T extends EventListener> T[] getListeners(Class<T> listenerType)
 931:   {
 932:     if (listenerType == PropertyChangeListener.class)
 933:       return (T[]) getPropertyChangeListeners();
 934:     else if (listenerType == VetoableChangeListener.class)
 935:       return (T[]) getVetoableChangeListeners();
 936:     else
 937:       return listenerList.getListeners(listenerType);
 938:   }
 939: 
 940:   /**
 941:    * Return all registered <code>AncestorListener</code> objects.
 942:    *
 943:    * @return The set of <code>AncestorListener</code> objects in {@link
 944:    * #listenerList}
 945:    */
 946:   public AncestorListener[] getAncestorListeners()
 947:   {
 948:     return (AncestorListener[]) getListeners(AncestorListener.class);
 949:   }
 950: 
 951:   /**
 952:    * Return all registered <code>VetoableChangeListener</code> objects.