| GNU Classpath (0.95) | |
| Frames | No Frames |
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.