Frames | No Frames |
1: /* Component.java -- a graphics component 2: Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation 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 java.awt; 40: 41: import java.awt.dnd.DropTarget; 42: import java.awt.event.ActionEvent; 43: import java.awt.event.ComponentEvent; 44: import java.awt.event.ComponentListener; 45: import java.awt.event.FocusEvent; 46: import java.awt.event.FocusListener; 47: import java.awt.event.HierarchyBoundsListener; 48: import java.awt.event.HierarchyEvent; 49: import java.awt.event.HierarchyListener; 50: import java.awt.event.InputEvent; 51: import java.awt.event.InputMethodEvent; 52: import java.awt.event.InputMethodListener; 53: import java.awt.event.KeyEvent; 54: import java.awt.event.KeyListener; 55: import java.awt.event.MouseEvent; 56: import java.awt.event.MouseListener; 57: import java.awt.event.MouseMotionListener; 58: import java.awt.event.MouseWheelEvent; 59: import java.awt.event.MouseWheelListener; 60: import java.awt.event.PaintEvent; 61: import java.awt.event.WindowEvent; 62: import java.awt.im.InputContext; 63: import java.awt.im.InputMethodRequests; 64: import java.awt.image.BufferStrategy; 65: import java.awt.image.ColorModel; 66: import java.awt.image.ImageObserver; 67: import java.awt.image.ImageProducer; 68: import java.awt.image.VolatileImage; 69: import java.awt.peer.ComponentPeer; 70: import java.awt.peer.LightweightPeer; 71: import java.beans.PropertyChangeListener; 72: import java.beans.PropertyChangeSupport; 73: import java.io.IOException; 74: import java.io.ObjectInputStream; 75: import java.io.ObjectOutputStream; 76: import java.io.PrintStream; 77: import java.io.PrintWriter; 78: import java.io.Serializable; 79: import java.lang.reflect.Array; 80: import java.util.Collections; 81: import java.util.EventListener; 82: import java.util.HashSet; 83: import java.util.Iterator; 84: import java.util.Locale; 85: import java.util.Set; 86: import java.util.Vector; 87: 88: import javax.accessibility.Accessible; 89: import javax.accessibility.AccessibleComponent; 90: import javax.accessibility.AccessibleContext; 91: import javax.accessibility.AccessibleRole; 92: import javax.accessibility.AccessibleState; 93: import javax.accessibility.AccessibleStateSet; 94: 95: /** 96: * The root of all evil. All graphical representations are subclasses of this 97: * giant class, which is designed for screen display and user interaction. 98: * This class can be extended directly to build a lightweight component (one 99: * not associated with a native window); lightweight components must reside 100: * inside a heavyweight window. 101: * 102: * <p>This class is Serializable, which has some big implications. A user can 103: * save the state of all graphical components in one VM, and reload them in 104: * another. Note that this class will only save Serializable listeners, and 105: * ignore the rest, without causing any serialization exceptions. However, by 106: * making a listener serializable, and adding it to another element, you link 107: * in that entire element to the state of this component. To get around this, 108: * use the idiom shown in the example below - make listeners non-serializable 109: * in inner classes, rather than using this object itself as the listener, if 110: * external objects do not need to save the state of this object. 111: * 112: * <pre> 113: * import java.awt.*; 114: * import java.awt.event.*; 115: * import java.io.Serializable; 116: * class MyApp implements Serializable 117: * { 118: * BigObjectThatShouldNotBeSerializedWithAButton bigOne; 119: * // Serializing aButton will not suck in an instance of MyApp, with its 120: * // accompanying field bigOne. 121: * Button aButton = new Button(); 122: * class MyActionListener implements ActionListener 123: * { 124: * public void actionPerformed(ActionEvent e) 125: * { 126: * System.out.println("Hello There"); 127: * } 128: * } 129: * MyApp() 130: * { 131: * aButton.addActionListener(new MyActionListener()); 132: * } 133: * } 134: * </pre> 135: * 136: * <p>Status: Incomplete. The event dispatch mechanism is implemented. All 137: * other methods defined in the J2SE 1.3 API javadoc exist, but are mostly 138: * incomplete or only stubs; except for methods relating to the Drag and 139: * Drop, Input Method, and Accessibility frameworks: These methods are 140: * present but commented out. 141: * 142: * @author original author unknown 143: * @author Eric Blake (ebb9@email.byu.edu) 144: * @since 1.0 145: * @status still missing 1.4 support 146: */ 147: public abstract class Component 148: implements ImageObserver, MenuContainer, Serializable 149: { 150: // Word to the wise - this file is huge. Search for '\f' (^L) for logical 151: // sectioning by fields, public API, private API, and nested classes. 152: 153: 154: /** 155: * Compatible with JDK 1.0+. 156: */ 157: private static final long serialVersionUID = -7644114512714619750L; 158: 159: /** 160: * Constant returned by the <code>getAlignmentY</code> method to indicate 161: * that the component wishes to be aligned to the top relative to 162: * other components. 163: * 164: * @see #getAlignmentY() 165: */ 166: public static final float TOP_ALIGNMENT = 0; 167: 168: /** 169: * Constant returned by the <code>getAlignmentY</code> and 170: * <code>getAlignmentX</code> methods to indicate 171: * that the component wishes to be aligned to the center relative to 172: * other components. 173: * 174: * @see #getAlignmentX() 175: * @see #getAlignmentY() 176: */ 177: public static final float CENTER_ALIGNMENT = 0.5f; 178: 179: /** 180: * Constant returned by the <code>getAlignmentY</code> method to indicate 181: * that the component wishes to be aligned to the bottom relative to 182: * other components. 183: * 184: * @see #getAlignmentY() 185: */ 186: public static final float BOTTOM_ALIGNMENT = 1; 187: 188: /** 189: * Constant returned by the <code>getAlignmentX</code> method to indicate 190: * that the component wishes to be aligned to the right relative to 191: * other components. 192: * 193: * @see #getAlignmentX() 194: */ 195: public static final float RIGHT_ALIGNMENT = 1; 196: 197: /** 198: * Constant returned by the <code>getAlignmentX</code> method to indicate 199: * that the component wishes to be aligned to the left relative to 200: * other components. 201: * 202: * @see #getAlignmentX() 203: */ 204: public static final float LEFT_ALIGNMENT = 0; 205: 206: /** 207: * Make the treelock a String so that it can easily be identified 208: * in debug dumps. We clone the String in order to avoid a conflict in 209: * the unlikely event that some other package uses exactly the same string 210: * as a lock object. 211: */ 212: static final Object treeLock = new String("AWT_TREE_LOCK"); 213: 214: // Serialized fields from the serialization spec. 215: 216: /** 217: * The x position of the component in the parent's coordinate system. 218: * 219: * @see #getLocation() 220: * @serial the x position 221: */ 222: int x; 223: 224: /** 225: * The y position of the component in the parent's coordinate system. 226: * 227: * @see #getLocation() 228: * @serial the y position 229: */ 230: int y; 231: 232: /** 233: * The component width. 234: * 235: * @see #getSize() 236: * @serial the width 237: */ 238: int width; 239: 240: /** 241: * The component height. 242: * 243: * @see #getSize() 244: * @serial the height 245: */ 246: int height; 247: 248: /** 249: * The foreground color for the component. This may be null. 250: * 251: * @see #getForeground() 252: * @see #setForeground(Color) 253: * @serial the foreground color 254: */ 255: Color foreground; 256: 257: /** 258: * The background color for the component. This may be null. 259: * 260: * @see #getBackground() 261: * @see #setBackground(Color) 262: * @serial the background color 263: */ 264: Color background; 265: 266: /** 267: * The default font used in the component. This may be null. 268: * 269: * @see #getFont() 270: * @see #setFont(Font) 271: * @serial the font 272: */ 273: Font font; 274: 275: /** 276: * The font in use by the peer, or null if there is no peer. 277: * 278: * @serial the peer's font 279: */ 280: Font peerFont; 281: 282: /** 283: * The cursor displayed when the pointer is over this component. This may 284: * be null. 285: * 286: * @see #getCursor() 287: * @see #setCursor(Cursor) 288: */ 289: Cursor cursor; 290: 291: /** 292: * The locale for the component. 293: * 294: * @see #getLocale() 295: * @see #setLocale(Locale) 296: */ 297: Locale locale = Locale.getDefault (); 298: 299: /** 300: * True if the object should ignore repaint events (usually because it is 301: * not showing). 302: * 303: * @see #getIgnoreRepaint() 304: * @see #setIgnoreRepaint(boolean) 305: * @serial true to ignore repaints 306: * @since 1.4 307: */ 308: boolean ignoreRepaint; 309: 310: /** 311: * True when the object is visible (although it is only showing if all 312: * ancestors are likewise visible). For component, this defaults to true. 313: * 314: * @see #isVisible() 315: * @see #setVisible(boolean) 316: * @serial true if visible 317: */ 318: boolean visible = true; 319: 320: /** 321: * True if the object is enabled, meaning it can interact with the user. 322: * For component, this defaults to true. 323: * 324: * @see #isEnabled() 325: * @see #setEnabled(boolean) 326: * @serial true if enabled 327: */ 328: boolean enabled = true; 329: 330: /** 331: * True if the object is valid. This is set to false any time a size 332: * adjustment means the component need to be layed out again. 333: * 334: * @see #isValid() 335: * @see #validate() 336: * @see #invalidate() 337: * @serial true if layout is valid 338: */ 339: boolean valid; 340: 341: /** 342: * The DropTarget for drag-and-drop operations. 343: * 344: * @see #getDropTarget() 345: * @see #setDropTarget(DropTarget) 346: * @serial the drop target, or null 347: * @since 1.2 348: */ 349: DropTarget dropTarget; 350: 351: /** 352: * The list of popup menus for this component. 353: * 354: * @see #add(PopupMenu) 355: * @serial the list of popups 356: */ 357: Vector popups; 358: 359: /** 360: * The component's name. May be null, in which case a default name is 361: * generated on the first use. 362: * 363: * @see #getName() 364: * @see #setName(String) 365: * @serial the name 366: */ 367: String name; 368: 369: /** 370: * True once the user has set the name. Note that the user may set the name 371: * to null. 372: * 373: * @see #name 374: * @see #getName() 375: * @see #setName(String) 376: * @serial true if the name has been explicitly set 377: */ 378: boolean nameExplicitlySet; 379: 380: /** 381: * Indicates if the object can be focused. Defaults to true for components. 382: * 383: * @see #isFocusable() 384: * @see #setFocusable(boolean) 385: * @since 1.4 386: */ 387: boolean focusable = true; 388: 389: /** 390: * Tracks whether this component's {@link #isFocusTraversable} 391: * method has been overridden. 392: * 393: * @since 1.4 394: */ 395: int isFocusTraversableOverridden; 396: 397: /** 398: * The focus traversal keys, if not inherited from the parent or 399: * default keyboard focus manager. These sets will contain only 400: * AWTKeyStrokes that represent press and release events to use as 401: * focus control. 402: * 403: * @see #getFocusTraversalKeys(int) 404: * @see #setFocusTraversalKeys(int, Set) 405: * @since 1.4 406: */ 407: Set[] focusTraversalKeys; 408: 409: /** 410: * True if focus traversal keys are enabled. This defaults to true for 411: * Component. If this is true, keystrokes in focusTraversalKeys are trapped 412: * and processed automatically rather than being passed on to the component. 413: * 414: * @see #getFocusTraversalKeysEnabled() 415: * @see #setFocusTraversalKeysEnabled(boolean) 416: * @since 1.4 417: */ 418: boolean focusTraversalKeysEnabled = true; 419: 420: /** 421: * Cached information on the minimum size. Should have been transient. 422: * 423: * @serial ignore 424: */ 425: Dimension minSize; 426: 427: /** 428: * Cached information on the preferred size. Should have been transient. 429: * 430: * @serial ignore 431: */ 432: Dimension prefSize; 433: 434: /** 435: * Set to true if an event is to be handled by this component, false if 436: * it is to be passed up the hierarcy. 437: * 438: * @see #dispatchEvent(AWTEvent) 439: * @serial true to process event locally 440: */ 441: boolean newEventsOnly; 442: 443: /** 444: * Set by subclasses to enable event handling of particular events, and 445: * left alone when modifying listeners. For component, this defaults to 446: * enabling only input methods. 447: * 448: * @see #enableInputMethods(boolean) 449: * @see AWTEvent 450: * @serial the mask of events to process 451: */ 452: long eventMask = AWTEvent.INPUT_ENABLED_EVENT_MASK; 453: 454: /** 455: * Describes all registered PropertyChangeListeners. 456: * 457: * @see #addPropertyChangeListener(PropertyChangeListener) 458: * @see #removePropertyChangeListener(PropertyChangeListener) 459: * @see #firePropertyChange(String, Object, Object) 460: * @serial the property change listeners 461: * @since 1.2 462: */ 463: PropertyChangeSupport changeSupport; 464: 465: /** 466: * True if the component has been packed (layed out). 467: * 468: * @serial true if this is packed 469: */ 470: boolean isPacked; 471: 472: /** 473: * The serialization version for this class. Currently at version 4. 474: * 475: * XXX How do we handle prior versions? 476: * 477: * @serial the serialization version 478: */ 479: int componentSerializedDataVersion = 4; 480: 481: /** 482: * The accessible context associated with this component. This is only set 483: * by subclasses. 484: * 485: * @see #getAccessibleContext() 486: * @serial the accessibility context 487: * @since 1.2 488: */ 489: AccessibleContext accessibleContext; 490: 491: 492: // Guess what - listeners are special cased in serialization. See 493: // readObject and writeObject. 494: 495: /** Component listener chain. */ 496: transient ComponentListener componentListener; 497: 498: /** Focus listener chain. */ 499: transient FocusListener focusListener; 500: 501: /** Key listener chain. */ 502: transient KeyListener keyListener; 503: 504: /** Mouse listener chain. */ 505: transient MouseListener mouseListener; 506: 507: /** Mouse motion listener chain. */ 508: transient MouseMotionListener mouseMotionListener; 509: 510: /** 511: * Mouse wheel listener chain. 512: * 513: * @since 1.4 514: */ 515: transient MouseWheelListener mouseWheelListener; 516: 517: /** 518: * Input method listener chain. 519: * 520: * @since 1.2 521: */ 522: transient InputMethodListener inputMethodListener; 523: 524: /** 525: * Hierarcy listener chain. 526: * 527: * @since 1.3 528: */ 529: transient HierarchyListener hierarchyListener; 530: 531: /** 532: * Hierarcy bounds listener chain. 533: * 534: * @since 1.3 535: */ 536: transient HierarchyBoundsListener hierarchyBoundsListener; 537: 538: // Anything else is non-serializable, and should be declared "transient". 539: 540: /** The parent. */ 541: transient Container parent; 542: 543: /** The associated native peer. */ 544: transient ComponentPeer peer; 545: 546: /** The preferred component orientation. */ 547: transient ComponentOrientation orientation = ComponentOrientation.UNKNOWN; 548: 549: /** 550: * The associated graphics configuration. 551: * 552: * @since 1.4 553: */ 554: transient GraphicsConfiguration graphicsConfig; 555: 556: /** 557: * The buffer strategy for repainting. 558: * 559: * @since 1.4 560: */ 561: transient BufferStrategy bufferStrategy; 562: 563: /** 564: * true if requestFocus was called on this component when its 565: * top-level ancestor was not focusable. 566: */ 567: private transient FocusEvent pendingFocusRequest = null; 568: 569: /** 570: * The system properties that affect image updating. 571: */ 572: private static transient boolean incrementalDraw; 573: private static transient Long redrawRate; 574: 575: static 576: { 577: incrementalDraw = Boolean.getBoolean ("awt.image.incrementalDraw"); 578: redrawRate = Long.getLong ("awt.image.redrawrate"); 579: } 580: 581: // Public and protected API. 582: 583: /** 584: * Default constructor for subclasses. When Component is extended directly, 585: * it forms a lightweight component that must be hosted in an opaque native 586: * container higher in the tree. 587: */ 588: protected Component() 589: { 590: // Nothing to do here. 591: } 592: 593: /** 594: * Returns the name of this component. 595: * 596: * @return the name of this component 597: * @see #setName(String) 598: * @since 1.1 599: */ 600: public String getName() 601: { 602: if (name == null && ! nameExplicitlySet) 603: name = generateName(); 604: return name; 605: } 606: 607: /** 608: * Sets the name of this component to the specified name. 609: * 610: * @param name the new name of this component 611: * @see #getName() 612: * @since 1.1 613: */ 614: public void setName(String name) 615: { 616: nameExplicitlySet = true; 617: this.name = name; 618: } 619: 620: /** 621: * Returns the parent of this component. 622: * 623: * @return the parent of this component 624: */ 625: public Container getParent() 626: { 627: return parent; 628: } 629: 630: /** 631: * Returns the native windowing system peer for this component. Only the 632: * platform specific implementation code should call this method. 633: * 634: * @return the peer for this component 635: * @deprecated user programs should not directly manipulate peers; use 636: * {@link #isDisplayable()} instead 637: */ 638: // Classpath's Gtk peers rely on this. 639: public ComponentPeer getPeer() 640: { 641: return peer; 642: } 643: 644: /** 645: * Set the associated drag-and-drop target, which receives events when this 646: * is enabled. 647: * 648: * @param dt the new drop target 649: * @see #isEnabled() 650: */ 651: public void setDropTarget(DropTarget dt) 652: { 653: this.dropTarget = dt; 654: } 655: 656: /** 657: * Gets the associated drag-and-drop target, if there is one. 658: * 659: * @return the drop target 660: */ 661: public DropTarget getDropTarget() 662: { 663: return dropTarget; 664: } 665: 666: /** 667: * Returns the graphics configuration of this component, if there is one. 668: * If it has not been set, it is inherited from the parent. 669: * 670: * @return the graphics configuration, or null 671: * @since 1.3 672: */ 673: public GraphicsConfiguration getGraphicsConfiguration() 674: { 675: return getGraphicsConfigurationImpl(); 676: } 677: 678: /** 679: * Returns the object used for synchronization locks on this component 680: * when performing tree and layout functions. 681: * 682: * @return the synchronization lock for this component 683: */ 684: public final Object getTreeLock() 685: { 686: return treeLock; 687: } 688: 689: /** 690: * Returns the toolkit in use for this component. The toolkit is associated 691: * with the frame this component belongs to. 692: * 693: * @return the toolkit for this component 694: */ 695: public Toolkit getToolkit() 696: { 697: if (peer != null) 698: { 699: Toolkit tk = peer.getToolkit(); 700: if (tk != null) 701: return tk; 702: } 703: // Get toolkit for lightweight component. 704: if (parent != null) 705: return parent.getToolkit(); 706: return Toolkit.getDefaultToolkit(); 707: } 708: 709: /** 710: * Tests whether or not this component is valid. A invalid component needs 711: * to have its layout redone. 712: * 713: * @return true if this component is valid 714: * @see #validate() 715: * @see #invalidate() 716: */ 717: public boolean isValid() 718: { 719: return valid; 720: } 721: 722: /** 723: * Tests if the component is displayable. It must be connected to a native 724: * screen resource. This reduces to checking that peer is not null. A 725: * containment hierarchy is made displayable when a window is packed or 726: * made visible. 727: * 728: * @return true if the component is displayable 729: * @see Container#add(Component) 730: * @see Container#remove(Component) 731: * @see Window#pack() 732: * @see Window#show() 733: * @see Window#dispose() 734: * @since 1.2 735: */ 736: public boolean isDisplayable() 737: { 738: return peer != null; 739: } 740: 741: /** 742: * Tests whether or not this component is visible. Except for top-level 743: * frames, components are initially visible. 744: * 745: * @return true if the component is visible 746: * @see #setVisible(boolean) 747: */ 748: public boolean isVisible() 749: { 750: return visible; 751: } 752: 753: /** 754: * Tests whether or not this component is actually being shown on 755: * the screen. This will be true if and only if it this component is 756: * visible and its parent components are all visible. 757: * 758: * @return true if the component is showing on the screen 759: * @see #setVisible(boolean) 760: */ 761: public boolean isShowing() 762: { 763: if (! visible || peer == null) 764: return false; 765: 766: return parent == null ? false : parent.isShowing(); 767: } 768: 769: /** 770: * Tests whether or not this component is enabled. Components are enabled 771: * by default, and must be enabled to receive user input or generate events. 772: * 773: * @return true if the component is enabled 774: * @see #setEnabled(boolean) 775: */ 776: public boolean isEnabled() 777: { 778: return enabled; 779: } 780: 781: /** 782: * Enables or disables this component. The component must be enabled to 783: * receive events (except that lightweight components always receive mouse 784: * events). 785: * 786: * @param enabled true to enable this component 787: * 788: * @see #isEnabled() 789: * @see #isLightweight() 790: * 791: * @since 1.1 792: */ 793: public void setEnabled(boolean enabled) 794: { 795: enable(enabled); 796: } 797: 798: /** 799: * Enables this component. 800: * 801: * @deprecated use {@link #setEnabled(boolean)} instead 802: */ 803: public void enable() 804: { 805: this.enabled = true; 806: if (peer != null) 807: peer.setEnabled (true); 808: } 809: 810: /** 811: * Enables or disables this component. 812: * 813: * @param enabled true to enable this component 814: * 815: * @deprecated use {@link #setEnabled(boolean)} instead 816: */ 817: public void enable(boolean enabled) 818: { 819: if (enabled) 820: enable(); 821: else 822: disable(); 823: } 824: 825: /** 826: * Disables this component. 827: * 828: * @deprecated use {@link #setEnabled(boolean)} instead 829: */ 830: public void disable() 831: { 832: this.enabled = false; 833: if (peer != null) 834: peer.setEnabled (false); 835: } 836: 837: /** 838: * Checks if this image is painted to an offscreen image buffer that is 839: * later copied to screen (double buffering reduces flicker). This version 840: * returns false, so subclasses must override it if they provide double 841: * buffering. 842: * 843: * @return true if this is double buffered; defaults to false 844: */ 845: public boolean isDoubleBuffered() 846: { 847: return false; 848: } 849: 850: /** 851: * Enables or disables input method support for this component. By default, 852: * components have this enabled. Input methods are given the opportunity 853: * to process key events before this component and its listeners. 854: * 855: * @param enable true to enable input method processing 856: * @see #processKeyEvent(KeyEvent) 857: * @since 1.2 858: */ 859: public void enableInputMethods(boolean enable) 860: { 861: if (enable) 862: eventMask |= AWTEvent.INPUT_ENABLED_EVENT_MASK; 863: else 864: eventMask &= ~AWTEvent.INPUT_ENABLED_EVENT_MASK; 865: } 866: 867: /** 868: * Makes this component visible or invisible. Note that it wtill might 869: * not show the component, if a parent is invisible. 870: * 871: * @param visible true to make this component visible 872: * 873: * @see #isVisible() 874: * 875: * @since 1.1 876: */ 877: public void setVisible(boolean visible) 878: { 879: // Inspection by subclassing shows that Sun's implementation calls 880: // show(boolean) which then calls show() or hide(). It is the show() 881: // method that is overriden in subclasses like Window. 882: show(visible); 883: } 884: 885: /** 886: * Makes this component visible on the screen. 887: * 888: * @deprecated use {@link #setVisible(boolean)} instead 889: */ 890: public void show() 891: { 892: // We must set visible before showing the peer. Otherwise the 893: // peer could post paint events before visible is true, in which 894: // case lightweight components are not initially painted -- 895: // Container.paint first calls isShowing () before painting itself 896: // and its children. 897: if(!isVisible()) 898: { 899: this.visible = true; 900: // Avoid NullPointerExceptions by creating a local reference. 901: ComponentPeer currentPeer=peer; 902: if (currentPeer != null) 903: currentPeer.setVisible(true); 904: 905: // The JDK repaints the component before invalidating the parent. 906: // So do we. 907: if (isShowing()) 908: repaint(); 909: // Invalidate the parent if we have one. The component itself must 910: // not be invalidated. We also avoid NullPointerException with 911: // a local reference here. 912: Container currentParent = parent; 913: if (currentParent != null) 914: currentParent.invalidate(); 915: 916: ComponentEvent ce = 917: new ComponentEvent(this,ComponentEvent.COMPONENT_SHOWN); 918: getToolkit().getSystemEventQueue().postEvent(ce); 919: } 920: } 921: 922: /** 923: * Makes this component visible or invisible. 924: * 925: * @param visible true to make this component visible 926: * 927: * @deprecated use {@link #setVisible(boolean)} instead 928: */ 929: public void show(boolean visible) 930: { 931: if (visible) 932: show(); 933: else 934: hide(); 935: } 936: 937: /** 938: * Hides this component so that it is no longer shown on the screen. 939: * 940: * @deprecated use {@link #setVisible(boolean)} instead 941: */ 942: public void hide() 943: { 944: if (isVisible()) 945: { 946: // Avoid NullPointerExceptions by creating a local reference. 947: ComponentPeer currentPeer=peer; 948: if (currentPeer != null) 949: currentPeer.setVisible(false); 950: boolean wasShowing = isShowing(); 951: this.visible = false; 952: 953: // The JDK repaints the component before invalidating the parent. 954: // So do we. 955: if (wasShowing) 956: repaint(); 957: // Invalidate the parent if we have one. The component itself must 958: // not be invalidated. We also avoid NullPointerException with 959: // a local reference here. 960: Container currentParent = parent; 961: if (currentParent != null) 962: currentParent.invalidate(); 963: 964: ComponentEvent ce = 965: new ComponentEvent(this,ComponentEvent.COMPONENT_HIDDEN); 966: getToolkit().getSystemEventQueue().postEvent(ce); 967: } 968: } 969: 970: /** 971: * Returns this component's foreground color. If not set, this is inherited 972: * from the parent. 973: * 974: * @return this component's foreground color, or null 975: * @see #setForeground(Color) 976: */ 977: public Color getForeground() 978: { 979: if (foreground != null) 980: return foreground; 981: return parent == null ? null : parent.getForeground(); 982: } 983: 984: /** 985: * Sets this component's foreground color to the specified color. This is a 986: * bound property. 987: * 988: * @param c the new foreground color 989: * @see #getForeground() 990: */ 991: public void setForeground(Color c) 992: { 993: if (peer != null) 994: peer.setForeground(c); 995: 996: Color previous = foreground; 997: foreground = c; 998: firePropertyChange("foreground", previous, c); 999: } 1000: 1001: /** 1002: * Tests if the foreground was explicitly set, or just inherited from the 1003: * parent. 1004: * 1005: * @return true if the foreground has been set 1006: * @since 1.4 1007: */ 1008: public boolean isForegroundSet() 1009: { 1010: return foreground != null; 1011: } 1012: 1013: /** 1014: * Returns this component's background color. If not set, this is inherited 1015: * from the parent. 1016: * 1017: * @return the background color of the component, or null 1018: * @see #setBackground(Color) 1019: */ 1020: public Color getBackground() 1021: { 1022: if (background != null) 1023: return background; 1024: return parent == null ? null : parent.getBackground(); 1025: } 1026: 1027: /** 1028: * Sets this component's background color to the specified color. The parts 1029: * of the component affected by the background color may by system dependent. 1030: * This is a bound property. 1031: * 1032: * @param c the new background color 1033: * @see #getBackground() 1034: */ 1035: public void setBackground(Color c) 1036: { 1037: // return if the background is already set to that color. 1038: if ((c != null) && c.equals(background)) 1039: return; 1040: 1041: // If c is null, inherit from closest ancestor whose bg is set. 1042: if (c == null && parent != null) 1043: c = parent.getBackground(); 1044: if (peer != null && c != null) 1045: peer.setBackground(c); 1046: 1047: Color previous = background; 1048: background = c; 1049: firePropertyChange("background", previous, c); 1050: } 1051: 1052: /** 1053: * Tests if the background was explicitly set, or just inherited from the 1054: * parent. 1055: * 1056: * @return true if the background has been set 1057: * @since 1.4 1058: */ 1059: public boolean isBackgroundSet() 1060: { 1061: return background != null; 1062: } 1063: 1064: /** 1065: * Returns the font in use for this component. If not set, this is inherited 1066: * from the parent. 1067: * 1068: * @return the font for this component 1069: * @see #setFont(Font) 1070: */ 1071: public Font getFont() 1072: { 1073: Font f = font; 1074: if (f != null) 1075: return f; 1076: 1077: Component p = parent; 1078: if (p != null) 1079: return p.getFont(); 1080: if (peer != null) 1081: return peer.getGraphics().getFont(); 1082: return null; 1083: } 1084: 1085: /** 1086: * Sets the font for this component to the specified font. This is a bound 1087: * property. 1088: * 1089: * @param newFont the new font for this component 1090: * 1091: * @see #getFont() 1092: */ 1093: public void setFont(Font newFont) 1094: { 1095: if((newFont != null && (font == null || !font.equals(newFont))) 1096: || newFont == null) 1097: { 1098: Font oldFont = font; 1099: font = newFont; 1100: if (peer != null) 1101: peer.setFont(font); 1102: firePropertyChange("font", oldFont, newFont); 1103: invalidate(); 1104: } 1105: } 1106: 1107: /** 1108: * Tests if the font was explicitly set, or just inherited from the parent. 1109: * 1110: * @return true if the font has been set 1111: * @since 1.4 1112: */ 1113: public boolean isFontSet() 1114: { 1115: return font != null; 1116: } 1117: 1118: /** 1119: * Returns the locale for this component. If this component does not 1120: * have a locale, the locale of the parent component is returned. 1121: * 1122: * @return the locale for this component 1123: * @throws IllegalComponentStateException if it has no locale or parent 1124: * @see #setLocale(Locale) 1125: * @since 1.1 1126: */ 1127: public Locale getLocale() 1128: { 1129: if (locale != null) 1130: return locale; 1131: if (parent == null) 1132: throw new IllegalComponentStateException 1133: ("Component has no parent: can't determine Locale"); 1134: return parent.getLocale(); 1135: } 1136: 1137: /** 1138: * Sets the locale for this component to the specified locale. This is a 1139: * bound property. 1140: * 1141: * @param newLocale the new locale for this component 1142: */ 1143: public void setLocale(Locale newLocale) 1144: { 1145: if (locale == newLocale) 1146: return; 1147: 1148: Locale oldLocale = locale; 1149: locale = newLocale; 1150: firePropertyChange("locale", oldLocale, newLocale); 1151: // New writing/layout direction or more/less room for localized labels. 1152: invalidate(); 1153: } 1154: 1155: /** 1156: * Returns the color model of the device this componet is displayed on. 1157: * 1158: * @return this object's color model 1159: * @see Toolkit#getColorModel() 1160: */ 1161: public ColorModel getColorModel() 1162: { 1163: GraphicsConfiguration config = getGraphicsConfiguration(); 1164: return config != null ? config.getColorModel() 1165: : getToolkit().getColorModel(); 1166: } 1167: 1168: /** 1169: * Returns the location of this component's top left corner relative to 1170: * its parent component. This may be outdated, so for synchronous behavior, 1171: * you should use a component listner. 1172: * 1173: * @return the location of this component 1174: * @see #setLocation(int, int) 1175: * @see #getLocationOnScreen() 1176: * @since 1.1 1177: */ 1178: public Point getLocation() 1179: { 1180: return location (); 1181: } 1182: 1183: /** 1184: * Returns the location of this component's top left corner in screen 1185: * coordinates. 1186: * 1187: * @return the location of this component in screen coordinates 1188: * @throws IllegalComponentStateException if the component is not showing 1189: */ 1190: public Point getLocationOnScreen() 1191: { 1192: if (! isShowing()) 1193: throw new IllegalComponentStateException("component " 1194: + getClass().getName() 1195: + " not showing"); 1196: // We know peer != null here. 1197: return peer.getLocationOnScreen(); 1198: } 1199: 1200: /** 1201: * Returns the location of this component's top left corner relative to 1202: * its parent component. 1203: * 1204: * @return the location of this component 1205: * @deprecated use {@link #getLocation()} instead 1206: */ 1207: public Point location() 1208: { 1209: return new Point (x, y); 1210: } 1211: 1212: /** 1213: * Moves this component to the specified location, relative to the parent's 1214: * coordinates. The coordinates are the new upper left corner of this 1215: * component. 1216: * 1217: * @param x the new X coordinate of this component 1218: * @param y the new Y coordinate of this component 1219: * @see #getLocation() 1220: * @see #setBounds(int, int, int, int) 1221: */ 1222: public void setLocation(int x, int y) 1223: { 1224: move (x, y); 1225: } 1226: 1227: /** 1228: * Moves this component to the specified location, relative to the parent's 1229: * coordinates. The coordinates are the new upper left corner of this 1230: * component. 1231: * 1232: * @param x the new X coordinate of this component 1233: * @param y the new Y coordinate of this component 1234: * @deprecated use {@link #setLocation(int, int)} instead 1235: */ 1236: public void move(int x, int y) 1237: { 1238: setBounds(x, y, this.width, this.height); 1239: } 1240: 1241: /** 1242: * Moves this component to the specified location, relative to the parent's 1243: * coordinates. The coordinates are the new upper left corner of this 1244: * component. 1245: * 1246: * @param p new coordinates for this component 1247: * @throws NullPointerException if p is null 1248: * @see #getLocation() 1249: * @see #setBounds(int, int, int, int) 1250: * @since 1.1 1251: */ 1252: public void setLocation(Point p) 1253: { 1254: setLocation(p.x, p.y); 1255: } 1256: 1257: /** 1258: * Returns the size of this object. 1259: * 1260: * @return the size of this object 1261: * @see #setSize(int, int) 1262: * @since 1.1 1263: */ 1264: public Dimension getSize() 1265: { 1266: return size (); 1267: } 1268: 1269: /** 1270: * Returns the size of this object. 1271: * 1272: * @return the size of this object 1273: * @deprecated use {@link #getSize()} instead 1274: */ 1275: public Dimension size() 1276: { 1277: return new Dimension (width, height); 1278: } 1279: 1280: /** 1281: * Sets the size of this component to the specified width and height. 1282: * 1283: * @param width the new width of this component 1284: * @param height the new height of this component 1285: * @see #getSize() 1286: * @see #setBounds(int, int, int, int) 1287: */ 1288: public void setSize(int width, int height) 1289: { 1290: resize (width, height); 1291: } 1292: 1293: /** 1294: * Sets the size of this component to the specified value. 1295: * 1296: * @param width the new width of the component 1297: * @param height the new height of the component 1298: * @deprecated use {@link #setSize(int, int)} instead 1299: */ 1300: public void resize(int width, int height) 1301: { 1302: setBounds(this.x, this.y, width, height); 1303: } 1304: 1305: /** 1306: * Sets the size of this component to the specified value. 1307: * 1308: * @param d the new size of this component 1309: * @throws NullPointerException if d is null 1310: * @see #setSize(int, int) 1311: * @see #setBounds(int, int, int, int) 1312: * @since 1.1 1313: */ 1314: public void setSize(Dimension d) 1315: { 1316: resize (d); 1317: } 1318: 1319: /** 1320: * Sets the size of this component to the specified value. 1321: * 1322: * @param d the new size of this component 1323: * @throws NullPointerException if d is null 1324: * @deprecated use {@link #setSize(Dimension)} instead 1325: */ 1326: public void resize(Dimension d) 1327: { 1328: resize (d.width, d.height); 1329: } 1330: 1331: /** 1332: * Returns a bounding rectangle for this component. Note that the 1333: * returned rectange is relative to this component's parent, not to 1334: * the screen. 1335: * 1336: * @return the bounding rectangle for this component 1337: * @see #setBounds(int, int, int, int) 1338: * @see #getLocation() 1339: * @see #getSize() 1340: */ 1341: public Rectangle getBounds() 1342: { 1343: return bounds (); 1344: } 1345: 1346: /** 1347: * Returns a bounding rectangle for this component. Note that the 1348: * returned rectange is relative to this component's parent, not to 1349: * the screen. 1350: * 1351: * @return the bounding rectangle for this component 1352: * @deprecated use {@link #getBounds()} instead 1353: */ 1354: public Rectangle bounds() 1355: { 1356: return new Rectangle (x, y, width, height); 1357: } 1358: 1359: /** 1360: * Sets the bounding rectangle for this component to the specified values. 1361: * Note that these coordinates are relative to the parent, not to the screen. 1362: * 1363: * @param x the X coordinate of the upper left corner of the rectangle 1364: * @param y the Y coordinate of the upper left corner of the rectangle 1365: * @param w the width of the rectangle 1366: * @param h the height of the rectangle 1367: * @see #getBounds() 1368: * @see #setLocation(int, int) 1369: * @see #setLocation(Point) 1370: * @see #setSize(int, int) 1371: * @see #setSize(Dimension) 1372: * @since 1.1 1373: */ 1374: public void setBounds(int x, int y, int w, int h) 1375: { 1376: reshape (x, y, w, h); 1377: } 1378: 1379: /** 1380: * Sets the bounding rectangle for this component to the specified values. 1381: * Note that these coordinates are relative to the parent, not to the screen. 1382: * 1383: * @param x the X coordinate of the upper left corner of the rectangle 1384: * @param y the Y coordinate of the upper left corner of the rectangle 1385: * @param width the width of the rectangle 1386: * @param height the height of the rectangle 1387: * @deprecated use {@link #setBounds(int, int, int, int)} instead 1388: */ 1389: public void reshape(int x, int y, int width, int height) 1390: { 1391: int oldx = this.x; 1392: int oldy = this.y; 1393: int oldwidth = this.width; 1394: int oldheight = this.height; 1395: 1396: if (this.x == x && this.y == y 1397: && this.width == width && this.height == height) 1398: return; 1399: invalidate (); 1400: this.x = x; 1401: this.y = y; 1402: this.width = width; 1403: this.height = height; 1404: if (peer != null) 1405: peer.setBounds (x, y, width, height); 1406: 1407: // Erase old bounds and repaint new bounds for lightweights. 1408: if (isLightweight() && isShowing()) 1409: { 1410: if (parent != null) 1411: { 1412: Rectangle oldBounds = new Rectangle(oldx, oldy, oldwidth, 1413: oldheight); 1414: Rectangle newBounds = new Rectangle(x, y, width, height); 1415: Rectangle destroyed = oldBounds.union(newBounds); 1416: if (!destroyed.isEmpty()) 1417: parent.repaint(0, destroyed.x, destroyed.y, destroyed.width, 1418: destroyed.height); 1419: } 1420: } 1421: 1422: // Only post event if this component is visible and has changed size. 1423: if (isShowing () 1424: && (oldx != x || oldy != y)) 1425: { 1426: ComponentEvent ce = new ComponentEvent(this, 1427: ComponentEvent.COMPONENT_MOVED); 1428: getToolkit().getSystemEventQueue().postEvent(ce); 1429: } 1430: if (isShowing () 1431: && (oldwidth != width || oldheight != height)) 1432: { 1433: ComponentEvent ce = new ComponentEvent(this, 1434: ComponentEvent.COMPONENT_RESIZED); 1435: getToolkit().getSystemEventQueue().postEvent(ce); 1436: } 1437: } 1438: 1439: /** 1440: * Sets the bounding rectangle for this component to the specified 1441: * rectangle. Note that these coordinates are relative to the parent, not 1442: * to the screen. 1443: * 1444: * @param r the new bounding rectangle 1445: * @throws NullPointerException if r is null 1446: * @see #getBounds() 1447: * @see #setLocation(Point) 1448: * @see #setSize(Dimension) 1449: * @since 1.1 1450: */ 1451: public void setBounds(Rectangle r) 1452: { 1453: setBounds (r.x, r.y, r.width, r.height); 1454: } 1455: 1456: /** 1457: * Gets the x coordinate of the upper left corner. This is more efficient 1458: * than getBounds().x or getLocation().x. 1459: * 1460: * @return the current x coordinate 1461: * @since 1.2 1462: */ 1463: public int getX() 1464: { 1465: return x; 1466: } 1467: 1468: /** 1469: * Gets the y coordinate of the upper left corner. This is more efficient 1470: * than getBounds().y or getLocation().y. 1471: * 1472: * @return the current y coordinate 1473: * @since 1.2 1474: */ 1475: public int getY() 1476: { 1477: return y; 1478: } 1479: 1480: /** 1481: * Gets the width of the component. This is more efficient than 1482: * getBounds().width or getSize().width. 1483: * 1484: * @return the current width 1485: * @since 1.2 1486: */ 1487: public int getWidth() 1488: { 1489: return width; 1490: } 1491: 1492: /** 1493: * Gets the height of the component. This is more efficient than 1494: * getBounds().height or getSize().height. 1495: * 1496: * @return the current width 1497: * @since 1.2 1498: */ 1499: public int getHeight() 1500: { 1501: return height; 1502: } 1503: 1504: /** 1505: * Returns the bounds of this component. This allows reuse of an existing 1506: * rectangle, if r is non-null. 1507: * 1508: * @param r the rectangle to use, or null 1509: * @return the bounds 1510: */ 1511: public Rectangle getBounds(Rectangle r) 1512: { 1513: if (r == null) 1514: r = new Rectangle(); 1515: r.x = x; 1516: r.y = y; 1517: r.width = width; 1518: r.height = height; 1519: return r; 1520: } 1521: 1522: /** 1523: * Returns the size of this component. This allows reuse of an existing 1524: * dimension, if d is non-null. 1525: * 1526: * @param d the dimension to use, or null 1527: * @return the size 1528: */ 1529: public Dimension getSize(Dimension d) 1530: { 1531: if (d == null) 1532: d = new Dimension(); 1533: d.width = width; 1534: d.height = height; 1535: return d; 1536: } 1537: 1538: /** 1539: * Returns the location of this component. This allows reuse of an existing 1540: * point, if p is non-null. 1541: * 1542: * @param p the point to use, or null 1543: * @return the location 1544: */ 1545: public Point getLocation(Point p) 1546: { 1547: if (p == null) 1548: p = new Point(); 1549: p.x = x; 1550: p.y = y; 1551: return p; 1552: } 1553: 1554: /** 1555: * Tests if this component is opaque. All "heavyweight" (natively-drawn) 1556: * components are opaque. A component is opaque if it draws all pixels in 1557: * the bounds; a lightweight component is partially transparent if it lets 1558: * pixels underneath show through. Subclasses that guarantee that all pixels 1559: * will be drawn should override this. 1560: * 1561: * @return true if this is opaque 1562: * @see #isLightweight() 1563: * @since 1.2 1564: */ 1565: public boolean isOpaque() 1566: { 1567: return ! isLightweight(); 1568: } 1569: 1570: /** 1571: * Return whether the component is lightweight. That means the component has 1572: * no native peer, but is displayable. This applies to subclasses of 1573: * Component not in this package, such as javax.swing. 1574: * 1575: * @return true if the component has a lightweight peer 1576: * @see #isDisplayable() 1577: * @since 1.2 1578: */ 1579: public boolean isLightweight() 1580: { 1581: return peer instanceof LightweightPeer; 1582: } 1583: 1584: /** 1585: * Returns the component's preferred size. 1586: * 1587: * @return the component's preferred size 1588: * @see #getMinimumSize() 1589: * @see LayoutManager 1590: */ 1591: public Dimension getPreferredSize() 1592: { 1593: return preferredSize(); 1594: } 1595: 1596: /** 1597: * Returns the component's preferred size. 1598: * 1599: * @return the component's preferred size 1600: * @deprecated use {@link #getPreferredSize()} instead 1601: */ 1602: public Dimension preferredSize() 1603: { 1604: if (prefSize == null) 1605: if (peer == null) 1606: return new Dimension(width, height); 1607: else 1608: prefSize = peer.getPreferredSize(); 1609: return prefSize; 1610: } 1611: 1612: /** 1613: * Returns the component's minimum size. 1614: * 1615: * @return the component's minimum size 1616: * @see #getPreferredSize() 1617: * @see LayoutManager 1618: */ 1619: public Dimension getMinimumSize() 1620: { 1621: return minimumSize(); 1622: } 1623: 1624: /** 1625: * Returns the component's minimum size. 1626: * 1627: * @return the component's minimum size 1628: * @deprecated use {@link #getMinimumSize()} instead 1629: */ 1630: public Dimension minimumSize() 1631: { 1632: if (minSize == null) 1633: minSize = (peer != null ? peer.getMinimumSize() 1634: : new Dimension(width, height)); 1635: return minSize; 1636: } 1637: 1638: /** 1639: * Returns the component's maximum size. 1640: * 1641: * @return the component's maximum size 1642: * @see #getMinimumSize() 1643: * @see #getPreferredSize() 1644: * @see LayoutManager 1645: */ 1646: public Dimension getMaximumSize() 1647: { 1648: return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE); 1649: } 1650: 1651: /** 1652: * Returns the preferred horizontal alignment of this component. The value 1653: * returned will be between {@link #LEFT_ALIGNMENT} and 1654: * {@link #RIGHT_ALIGNMENT}, inclusive. 1655: * 1656: * @return the preferred horizontal alignment of this component 1657: */ 1658: public float getAlignmentX() 1659: { 1660: return CENTER_ALIGNMENT; 1661: } 1662: 1663: /** 1664: * Returns the preferred vertical alignment of this component. The value 1665: * returned will be between {@link #TOP_ALIGNMENT} and 1666: * {@link #BOTTOM_ALIGNMENT}, inclusive. 1667: * 1668: * @return the preferred vertical alignment of this component 1669: */ 1670: public float getAlignmentY() 1671: { 1672: return CENTER_ALIGNMENT; 1673: } 1674: 1675: /** 1676: * Calls the layout manager to re-layout the component. This is called 1677: * during validation of a container in most cases. 1678: * 1679: * @see #validate() 1680: * @see LayoutManager 1681: */ 1682: public void doLayout() 1683: { 1684: layout (); 1685: } 1686: 1687: /** 1688: * Calls the layout manager to re-layout the component. This is called 1689: * during validation of a container in most cases. 1690: * 1691: * @deprecated use {@link #doLayout()} instead 1692: */ 1693: public void layout() 1694: { 1695: // Nothing to do unless we're a container. 1696: } 1697: 1698: /** 1699: * Called to ensure that the layout for this component is valid. This is 1700: * usually called on containers. 1701: * 1702: * @see #invalidate() 1703: * @see #doLayout() 1704: * @see LayoutManager 1705: * @see Container#validate() 1706: */ 1707: public void validate() 1708: { 1709: valid = true; 1710: } 1711: 1712: /** 1713: * Invalidates this component and all of its parent components. This will 1714: * cause them to have their layout redone. This is called frequently, so 1715: * make it fast. 1716: */ 1717: public void invalidate() 1718: { 1719: valid = false; 1720: prefSize = null; 1721: minSize = null; 1722: if (parent != null && parent.isValid()) 1723: parent.invalidate(); 1724: } 1725: 1726: /** 1727: * Returns a graphics object for this component. Returns <code>null</code> 1728: * if this component is not currently displayed on the screen. 1729: * 1730: * @return a graphics object for this component 1731: * @see #paint(Graphics) 1732: */ 1733: public Graphics getGraphics() 1734: { 1735: if (peer != null) 1736: { 1737: Graphics gfx = peer.getGraphics(); 1738: // Create peer for lightweights. 1739: if (gfx == null && parent != null) 1740: { 1741: gfx = parent.getGraphics(); 1742: Rectangle bounds = getBounds(); 1743: gfx.setClip(bounds); 1744: gfx.translate(bounds.x, bounds.y); 1745: return gfx; 1746: } 1747: gfx.setFont(font); 1748: return gfx; 1749: } 1750: return null; 1751: } 1752: 1753: /** 1754: * Returns the font metrics for the specified font in this component. 1755: * 1756: * @param font the font to retrieve metrics for 1757: * @return the font metrics for the specified font 1758: * @throws NullPointerException if font is null 1759: * @see #getFont() 1760: * @see Toolkit#getFontMetrics(Font) 1761: */ 1762: public FontMetrics getFontMetrics(Font font) 1763: { 1764: return peer == null ? getToolkit().getFontMetrics(font) 1765: : peer.getFontMetrics(font); 1766: } 1767: 1768: /** 1769: * Sets the cursor for this component to the specified cursor. The cursor 1770: * is displayed when the point is contained by the component, and the 1771: * component is visible, displayable, and enabled. This is inherited by 1772: * subcomponents unless they set their own cursor. 1773: * 1774: * @param cursor the new cursor for this component 1775: * @see #isEnabled() 1776: * @see #isShowing() 1777: * @see #getCursor() 1778: * @see #contains(int, int) 1779: * @see Toolkit#createCustomCursor(Image, Point, String) 1780: */ 1781: public void setCursor(Cursor cursor) 1782: { 1783: this.cursor = cursor; 1784: if (peer != null) 1785: peer.setCursor(cursor); 1786: } 1787: 1788: /** 1789: * Returns the cursor for this component. If not set, this is inherited 1790: * from the parent, or from Cursor.getDefaultCursor(). 1791: * 1792: * @return the cursor for this component 1793: */ 1794: public Cursor getCursor() 1795: { 1796: if (cursor != null) 1797: return cursor; 1798: return parent != null ? parent.getCursor() : Cursor.getDefaultCursor(); 1799: } 1800: 1801: /** 1802: * Tests if the cursor was explicitly set, or just inherited from the parent. 1803: * 1804: * @return true if the cursor has been set 1805: * @since 1.4 1806: */ 1807: public boolean isCursorSet() 1808: { 1809: return cursor != null; 1810: } 1811: 1812: /** 1813: * Paints this component on the screen. The clipping region in the graphics 1814: * context will indicate the region that requires painting. This is called 1815: * whenever the component first shows, or needs to be repaired because 1816: * something was temporarily drawn on top. It is not necessary for 1817: * subclasses to call <code>super.paint(g)</code>. Components with no area 1818: * are not painted. 1819: * 1820: * @param g the graphics context for this paint job 1821: * @see #update(Graphics) 1822: */ 1823: public void paint(Graphics g) 1824: { 1825: // This is a callback method and is meant to be overridden by subclasses 1826: // that want to perform custom painting. 1827: } 1828: 1829: /** 1830: * Updates this component. This is called in response to 1831: * <code>repaint</code>. This method fills the component with the 1832: * background color, then sets the foreground color of the specified 1833: * graphics context to the foreground color of this component and calls 1834: * the <code>paint()</code> method. The coordinates of the graphics are 1835: * relative to this component. Subclasses should call either 1836: * <code>super.update(g)</code> or <code>paint(g)</code>. 1837: * 1838: * @param g the graphics context for this update 1839: * 1840: * @see #paint(Graphics) 1841: * @see #repaint() 1842: * 1843: * @specnote In contrast to what the spec says, tests show that the exact 1844: * behaviour is to clear the background on lightweight and 1845: * top-level components only. Heavyweight components are not 1846: * affected by this method and only call paint(). 1847: */ 1848: public void update(Graphics g) 1849: { 1850: // Tests show that the clearing of the background is only done in 1851: // two cases: 1852: // - If the component is lightweight (yes this is in contrast to the spec). 1853: // or 1854: // - If the component is a toplevel container. 1855: if (isLightweight() || getParent() == null) 1856: { 1857: Rectangle clip = g.getClipBounds(); 1858: if (clip == null) 1859: g.clearRect(0, 0, width, height); 1860: else 1861: g.clearRect(clip.x, clip.y, clip.width, clip.height); 1862: } 1863: paint(g); 1864: } 1865: 1866: /** 1867: * Paints this entire component, including any sub-components. 1868: * 1869: * @param g the graphics context for this paint job 1870: * 1871: * @see #paint(Graphics) 1872: */ 1873: public void paintAll(Graphics g) 1874: { 1875: if (! visible) 1876: return; 1877: paint(g); 1878: } 1879: 1880: /** 1881: * Repaint this entire component. The <code>update()</code> method 1882: * on this component will be called as soon as possible. 1883: * 1884: * @see #update(Graphics) 1885: * @see #repaint(long, int, int, int, int) 1886: */ 1887: public void repaint() 1888: { 1889: if (isShowing()) 1890: repaint(0, 0, 0, width, height); 1891: } 1892: 1893: /** 1894: * Repaint this entire component. The <code>update()</code> method on this 1895: * component will be called in approximate the specified number of 1896: * milliseconds. 1897: * 1898: * @param tm milliseconds before this component should be repainted 1899: * @see #paint(Graphics) 1900: * @see #repaint(long, int, int, int, int) 1901: */ 1902: public void repaint(long tm) 1903: { 1904: if (isShowing()) 1905: repaint(tm, 0, 0, width, height); 1906: } 1907: 1908: /** 1909: * Repaints the specified rectangular region within this component. The 1910: * <code>update</code> method on this component will be called as soon as 1911: * possible. The coordinates are relative to this component. 1912: * 1913: * @param x the X coordinate of the upper left of the region to repaint 1914: * @param y the Y coordinate of the upper left of the region to repaint 1915: * @param w the width of the region to repaint 1916: * @param h the height of the region to repaint 1917: * @see #update(Graphics) 1918: * @see #repaint(long, int, int, int, int) 1919: */ 1920: public void repaint(int x, int y, int w, int h) 1921: { 1922: if (isShowing()) 1923: repaint(0, x, y, w, h); 1924: } 1925: 1926: /** 1927: * Repaints the specified rectangular region within this component. The 1928: * <code>update</code> method on this component will be called in 1929: * approximately the specified number of milliseconds. The coordinates 1930: * are relative to this component. 1931: * 1932: * @param tm milliseconds before this component should be repainted 1933: * @param x the X coordinate of the upper left of the region to repaint 1934: * @param y the Y coordinate of the upper left of the region to repaint 1935: * @param width the width of the region to repaint 1936: * @param height the height of the region to repaint 1937: * @see #update(Graphics) 1938: */ 1939: public void repaint(long tm, int x, int y, int width, int height) 1940: { 1941: if (isShowing()) 1942: { 1943: ComponentPeer p = peer; 1944: if (p != null) 1945: p.repaint(tm, x, y, width, height); 1946: } 1947: } 1948: 1949: /** 1950: * Prints this component. This method is provided so that printing can be 1951: * done in a different manner from painting. However, the implementation 1952: * in this class simply calls the <code>paint()</code> method. 1953: * 1954: * @param g the graphics context of the print device 1955: * 1956: * @see #paint(Graphics) 1957: */ 1958: public void print(Graphics g) 1959: { 1960: paint(g); 1961: } 1962: 1963: /** 1964: * Prints this component, including all sub-components. This method is 1965: * provided so that printing can be done in a different manner from 1966: * painting. However, the implementation in this class simply calls the 1967: * <code>paintAll()</code> method. 1968: * 1969: * @param g the graphics context of the print device 1970: * 1971: * @see #paintAll(Graphics) 1972: */ 1973: public void printAll(Graphics g) 1974: { 1975: paintAll(g); 1976: } 1977: 1978: /** 1979: * Called when an image has changed so that this component is repainted. 1980: * This incrementally draws an image as more bits are available, when 1981: * possible. Incremental drawing is enabled if the system property 1982: * <code>awt.image.incrementalDraw</code> is not present or is true, in which 1983: * case the redraw rate is set to 100ms or the value of the system property 1984: * <code>awt.image.redrawrate</code>. 1985: * 1986: * <p>The coordinate system used depends on the particular flags. 1987: * 1988: * @param img the image that has been updated 1989: * @param flags tlags as specified in <code>ImageObserver</code> 1990: * @param x the X coordinate 1991: * @param y the Y coordinate 1992: * @param w the width 1993: * @param h the height 1994: * @return false if the image is completely loaded, loading has been 1995: * aborted, or an error has occurred. true if more updates are 1996: * required. 1997: * @see ImageObserver 1998: * @see Graphics#drawImage(Image, int, int, Color, ImageObserver) 1999: * @see Graphics#drawImage(Image, int, int, ImageObserver) 2000: * @see Graphics#drawImage(Image, int, int, int, int, Color, ImageObserver) 2001: * @see Graphics#drawImage(Image, int, int, int, int, ImageObserver) 2002: * @see ImageObserver#imageUpdate(Image, int, int, int, int, int) 2003: */ 2004: public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h) 2005: { 2006: if ((flags & (FRAMEBITS | ALLBITS)) != 0) 2007: repaint(); 2008: else if ((flags & SOMEBITS) != 0) 2009: { 2010: if (incrementalDraw) 2011: { 2012: if (redrawRate != null) 2013: { 2014: long tm = redrawRate.longValue(); 2015: if (tm < 0) 2016: tm = 0; 2017: repaint(tm); 2018: } 2019: else 2020: repaint(100); 2021: } 2022: } 2023: return (flags & (ALLBITS | ABORT | ERROR)) == 0; 2024: } 2025: 2026: /** 2027: * Creates an image from the specified producer. 2028: * 2029: * @param producer the image procedure to create the image from 2030: * @return the resulting image 2031: */ 2032: public Image createImage(ImageProducer producer) 2033: { 2034: // Sun allows producer to be null. 2035: if (peer != null) 2036: return peer.createImage(producer); 2037: else 2038: return getToolkit().createImage(producer); 2039: } 2040: 2041: /** 2042: * Creates an image with the specified width and height for use in 2043: * double buffering. Headless environments do not support images. 2044: * 2045: * @param width the width of the image 2046: * @param height the height of the image 2047: * @return the requested image, or null if it is not supported 2048: */ 2049: public Image createImage (int width, int height) 2050: { 2051: Image returnValue = null; 2052: if (!GraphicsEnvironment.isHeadless ()) 2053: { 2054: if (isLightweight () && parent != null) 2055: returnValue = parent.createImage (width, height); 2056: else if (peer != null) 2057: returnValue = peer.createImage (width, height); 2058: } 2059: return returnValue; 2060: } 2061: 2062: /** 2063: * Creates an image with the specified width and height for use in 2064: * double buffering. Headless environments do not support images. 2065: * 2066: * @param width the width of the image 2067: * @param height the height of the image 2068: * @return the requested image, or null if it is not supported 2069: * @since 1.4 2070: */ 2071: public VolatileImage createVolatileImage(int width, int height) 2072: { 2073: if (GraphicsEnvironment.isHeadless()) 2074: return null; 2075: GraphicsConfiguration config = getGraphicsConfiguration(); 2076: return config == null ? null 2077: : config.createCompatibleVolatileImage(width, height); 2078: } 2079: 2080: /** 2081: * Creates an image with the specified width and height for use in 2082: * double buffering. Headless environments do not support images. The image 2083: * will support the specified capabilities. 2084: * 2085: * @param width the width of the image 2086: * @param height the height of the image 2087: * @param caps the requested capabilities 2088: * @return the requested image, or null if it is not supported 2089: * @throws AWTException if a buffer with the capabilities cannot be created 2090: * @since 1.4 2091: */ 2092: public VolatileImage createVolatileImage(int width, int height, 2093: ImageCapabilities caps) 2094: throws AWTException 2095: { 2096: if (GraphicsEnvironment.isHeadless()) 2097: return null; 2098: GraphicsConfiguration config = getGraphicsConfiguration(); 2099: return config == null ? null 2100: : config.createCompatibleVolatileImage(width, height, caps); 2101: } 2102: 2103: /** 2104: * Prepares the specified image for rendering on this component. 2105: * 2106: * @param image the image to prepare for rendering 2107: * @param observer the observer to notify of image preparation status 2108: * @return true if the image is already fully prepared 2109: * @throws NullPointerException if image is null 2110: */ 2111: public boolean prepareImage(Image image, ImageObserver observer) 2112: { 2113: return prepareImage(image, image.getWidth(observer), 2114: image.getHeight(observer), observer); 2115: } 2116: 2117: /** 2118: * Prepares the specified image for rendering on this component at the 2119: * specified scaled width and height 2120: * 2121: * @param image the image to prepare for rendering 2122: * @param width the scaled width of the image 2123: * @param height the scaled height of the image 2124: * @param observer the observer to notify of image preparation status 2125: * @return true if the image is already fully prepared 2126: */ 2127: public boolean prepareImage(Image image, int width, int height, 2128: ImageObserver observer) 2129: { 2130: if (peer != null) 2131: return peer.prepareImage(image, width, height, observer); 2132: else 2133: return getToolkit().prepareImage(image, width, height, observer); 2134: } 2135: 2136: /** 2137: * Returns the status of the loading of the specified image. The value 2138: * returned will be those flags defined in <code>ImageObserver</code>. 2139: * 2140: * @param image the image to check on 2141: * @param observer the observer to notify of image loading progress 2142: * @return the image observer flags indicating the status of the load 2143: * @see #prepareImage(Image, int, int, ImageObserver) 2144: * @see Toolkit#checkImage(Image, int, int, ImageObserver) 2145: * @throws NullPointerException if image is null 2146: */ 2147: public int checkImage(Image image, ImageObserver observer) 2148: { 2149: return checkImage(image, -1, -1, observer); 2150: } 2151: 2152: /** 2153: * Returns the status of the loading of the specified image. The value 2154: * returned will be those flags defined in <code>ImageObserver</code>. 2155: * 2156: * @param image the image to check on 2157: * @param width the scaled image width 2158: * @param height the scaled image height 2159: * @param observer the observer to notify of image loading progress 2160: * @return the image observer flags indicating the status of the load 2161: * @see #prepareImage(Image, int, int, ImageObserver) 2162: * @see Toolkit#checkImage(Image, int, int, ImageObserver) 2163: */ 2164: public int checkImage(Image image, int width, int height, 2165: ImageObserver observer) 2166: { 2167: if (peer != null) 2168: return peer.checkImage(image, width, height, observer); 2169: return getToolkit().checkImage(image, width, height, observer); 2170: } 2171: 2172: /** 2173: * Sets whether paint messages delivered by the operating system should be 2174: * ignored. This does not affect messages from AWT, except for those 2175: * triggered by OS messages. Setting this to true can allow faster 2176: * performance in full-screen mode or page-flipping. 2177: * 2178: * @param ignoreRepaint the new setting for ignoring repaint events 2179: * @see #getIgnoreRepaint() 2180: * @see BufferStrategy 2181: * @see GraphicsDevice#setFullScreenWindow(Window) 2182: * @since 1.4 2183: */ 2184: public void setIgnoreRepaint(boolean ignoreRepaint) 2185: { 2186: this.ignoreRepaint = ignoreRepaint; 2187: } 2188: 2189: /** 2190: * Test whether paint events from the operating system are ignored. 2191: * 2192: * @return the status of ignoring paint events 2193: * @see #setIgnoreRepaint(boolean) 2194: * @since 1.4 2195: */ 2196: public boolean getIgnoreRepaint() 2197: { 2198: return ignoreRepaint; 2199: } 2200: 2201: /** 2202: * Tests whether or not the specified point is contained within this 2203: * component. Coordinates are relative to this component. 2204: * 2205: * @param x the X coordinate of the point to test 2206: * @param y the Y coordinate of the point to test 2207: * @return true if the point is within this component 2208: * @see #getComponentAt(int, int) 2209: */ 2210: public boolean contains(int x, int y) 2211: { 2212: return inside (x, y); 2213: } 2214: 2215: /** 2216: * Tests whether or not the specified point is contained within this 2217: * component. Coordinates are relative to this component. 2218: * 2219: * @param x the X coordinate of the point to test 2220: * @param y the Y coordinate of the point to test 2221: * @return true if the point is within this component 2222: * @deprecated use {@link #contains(int, int)} instead 2223: */ 2224: public boolean inside(int x, int y) 2225: { 2226: return x >= 0 && y >= 0 && x < width && y < height; 2227: } 2228: 2229: /** 2230: * Tests whether or not the specified point is contained within this 2231: * component. Coordinates are relative to this component. 2232: * 2233: * @param p the point to test 2234: * @return true if the point is within this component 2235: * @throws NullPointerException if p is null 2236: * @see #getComponentAt(Point) 2237: * @since 1.1 2238: */ 2239: public boolean contains(Point p) 2240: { 2241: return contains (p.x, p.y); 2242: } 2243: 2244: /** 2245: * Returns the component occupying the position (x,y). This will either 2246: * be this component, an immediate child component, or <code>null</code> 2247: * if neither of the first two occupies the specified location. 2248: * 2249: * @param x the X coordinate to search for components at 2250: * @param y the Y coordinate to search for components at 2251: * @return the component at the specified location, or null 2252: * @see #contains(int, int) 2253: */ 2254: public Component getComponentAt(int x, int y) 2255: { 2256: return locate (x, y); 2257: } 2258: 2259: /** 2260: * Returns the component occupying the position (x,y). This will either 2261: * be this component, an immediate child component, or <code>null</code> 2262: * if neither of the first two occupies the specified location. 2263: * 2264: * @param x the X coordinate to search for components at 2265: * @param y the Y coordinate to search for components at 2266: * @return the component at the specified location, or null 2267: * @deprecated use {@link #getComponentAt(int, int)} instead 2268: */ 2269: public Component locate(int x, int y) 2270: { 2271: return contains (x, y) ? this : null; 2272: } 2273: 2274: /** 2275: * Returns the component occupying the position (x,y). This will either 2276: * be this component, an immediate child component, or <code>null</code> 2277: * if neither of the first two occupies the specified location. 2278: * 2279: * @param p the point to search for components at 2280: * @return the component at the specified location, or null 2281: * @throws NullPointerException if p is null 2282: * @see #contains(Point) 2283: * @since 1.1 2284: */ 2285: public Component getComponentAt(Point p) 2286: { 2287: return getComponentAt (p.x, p.y); 2288: } 2289: 2290: /** 2291: * AWT 1.0 event delivery. 2292: * 2293: * Deliver an AWT 1.0 event to this Component. This method simply 2294: * calls {@link #postEvent}. 2295: * 2296: * @param e the event to deliver 2297: * @deprecated use {@link #dispatchEvent (AWTEvent)} instead 2298: */ 2299: public void deliverEvent (Event e) 2300: { 2301: postEvent (e); 2302: } 2303: 2304: /** 2305: * Forwards AWT events to processEvent() if:<ul> 2306: * <li>Events have been enabled for this type of event via 2307: * <code>enableEvents()</code></li>, 2308: * <li>There is at least one registered listener for this type of event</li> 2309: * </ul> 2310: * 2311: * @param e the event to dispatch 2312: */ 2313: public final void dispatchEvent(AWTEvent e) 2314: { 2315: // Some subclasses in the AWT package need to override this behavior, 2316: // hence the use of dispatchEventImpl(). 2317: dispatchEventImpl(e); 2318: } 2319: 2320: /** 2321: * AWT 1.0 event handler. 2322: * 2323: * This method simply calls handleEvent and returns the result. 2324: * 2325: * @param e the event to handle 2326: * @return true if the event was handled, false otherwise 2327: * @deprecated use {@link #dispatchEvent(AWTEvent)} instead 2328: */ 2329: public boolean postEvent (Event e) 2330: { 2331: boolean handled = handleEvent (e); 2332: 2333: if (!handled && getParent() != null) 2334: // FIXME: need to translate event coordinates to parent's 2335: // coordinate space. 2336: handled = getParent ().postEvent (e); 2337: 2338: return handled; 2339: } 2340: 2341: /** 2342: * Adds the specified listener to this component. This is harmless if the 2343: * listener is null, but if the listener has already been registered, it 2344: * will now be registered twice. 2345: * 2346: * @param listener the new listener to add 2347: * @see ComponentEvent 2348: * @see #removeComponentListener(ComponentListener) 2349: * @see #getComponentListeners() 2350: * @since 1.1 2351: */ 2352: public synchronized void addComponentListener(ComponentListener listener) 2353: { 2354: componentListener = AWTEventMulticaster.add(componentListener, listener); 2355: if (componentListener != null) 2356: enableEvents(AWTEvent.COMPONENT_EVENT_MASK); 2357: } 2358: 2359: /** 2360: * Removes the specified listener from the component. This is harmless if 2361: * the listener was not previously registered. 2362: * 2363: * @param listener the listener to remove 2364: * @see ComponentEvent 2365: * @see #addComponentListener(ComponentListener) 2366: * @see #getComponentListeners() 2367: * @since 1.1 2368: */ 2369: public synchronized void removeComponentListener(ComponentListener listener) 2370: { 2371: componentListener = AWTEventMulticaster.remove(componentListener, listener); 2372: } 2373: 2374: /** 2375: * Returns an array of all specified listeners registered on this component. 2376: * 2377: * @return an array of listeners 2378: * @see #addComponentListener(ComponentListener) 2379: * @see #removeComponentListener(ComponentListener) 2380: * @since 1.4 2381: */ 2382: public synchronized ComponentListener[] getComponentListeners() 2383: { 2384: return (ComponentListener[]) 2385: AWTEventMulticaster.getListeners(componentListener, 2386: ComponentListener.class); 2387: } 2388: 2389: /** 2390: * Adds the specified listener to this component. This is harmless if the 2391: * listener is null, but if the listener has already been registered, it 2392: * will now be registered twice. 2393: * 2394: * @param listener the new listener to add 2395: * @see FocusEvent 2396: * @see #removeFocusListener(FocusListener) 2397: * @see #getFocusListeners() 2398: * @since 1.1 2399: */ 2400: public synchronized void addFocusListener(FocusListener listener) 2401: { 2402: focusListener = AWTEventMulticaster.add(focusListener, listener); 2403: if (focusListener != null) 2404: enableEvents(AWTEvent.FOCUS_EVENT_MASK); 2405: } 2406: 2407: /** 2408: * Removes the specified listener from the component. This is harmless if 2409: * the listener was not previously registered. 2410: * 2411: * @param listener the listener to remove 2412: * @see FocusEvent 2413: * @see #addFocusListener(FocusListener) 2414: * @see #getFocusListeners() 2415: * @since 1.1 2416: */ 2417: public synchronized void removeFocusListener(FocusListener listener) 2418: { 2419: focusListener = AWTEventMulticaster.remove(focusListener, listener); 2420: } 2421: 2422: /** 2423: * Returns an array of all specified listeners registered on this component. 2424: * 2425: * @return an array of listeners 2426: * @see #addFocusListener(FocusListener) 2427: * @see #removeFocusListener(FocusListener) 2428: * @since 1.4 2429: */ 2430: public synchronized FocusListener[] getFocusListeners() 2431: { 2432: return (FocusListener[]) 2433: AWTEventMulticaster.getListeners(focusListener, FocusListener.class); 2434: } 2435: 2436: /** 2437: * Adds the specified listener to this component. This is harmless if the 2438: * listener is null, but if the listener has already been registered, it 2439: * will now be registered twice. 2440: * 2441: * @param listener the new listener to add 2442: * @see HierarchyEvent 2443: * @see #removeHierarchyListener(HierarchyListener) 2444: * @see #getHierarchyListeners() 2445: * @since 1.3 2446: */ 2447: public synchronized void addHierarchyListener(HierarchyListener listener) 2448: { 2449: hierarchyListener = AWTEventMulticaster.add(hierarchyListener, listener); 2450: if (hierarchyListener != null) 2451: enableEvents(AWTEvent.HIERARCHY_EVENT_MASK); 2452: } 2453: 2454: /** 2455: * Removes the specified listener from the component. This is harmless if 2456: * the listener was not previously registered. 2457: * 2458: * @param listener the listener to remove 2459: * @see HierarchyEvent 2460: * @see #addHierarchyListener(HierarchyListener) 2461: * @see #getHierarchyListeners() 2462: * @since 1.3 2463: */ 2464: public synchronized void removeHierarchyListener(HierarchyListener listener) 2465: { 2466: hierarchyListener = AWTEventMulticaster.remove(hierarchyListener, listener); 2467: } 2468: 2469: /** 2470: * Returns an array of all specified listeners registered on this component. 2471: * 2472: * @return an array of listeners 2473: * @see #addHierarchyListener(HierarchyListener) 2474: * @see #removeHierarchyListener(HierarchyListener) 2475: * @since 1.4 2476: */ 2477: public synchronized HierarchyListener[] getHierarchyListeners() 2478: { 2479: return (HierarchyListener[]) 2480: AWTEventMulticaster.getListeners(hierarchyListener, 2481: HierarchyListener.class); 2482: } 2483: 2484: /** 2485: * Adds the specified listener to this component. This is harmless if the 2486: * listener is null, but if the listener has already been registered, it 2487: * will now be registered twice. 2488: * 2489: * @param listener the new listener to add 2490: * @see HierarchyEvent 2491: * @see #removeHierarchyBoundsListener(HierarchyBoundsListener) 2492: * @see #getHierarchyBoundsListeners() 2493: * @since 1.3 2494: */ 2495: public synchronized void 2496: addHierarchyBoundsListener(HierarchyBoundsListener listener) 2497: { 2498: hierarchyBoundsListener = 2499: AWTEventMulticaster.add(hierarchyBoundsListener, listener); 2500: if (hierarchyBoundsListener != null) 2501: enableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); 2502: } 2503: 2504: /** 2505: * Removes the specified listener from the component. This is harmless if 2506: * the listener was not previously registered. 2507: * 2508: * @param listener the listener to remove 2509: * @see HierarchyEvent 2510: * @see #addHierarchyBoundsListener(HierarchyBoundsListener) 2511: * @see #getHierarchyBoundsListeners() 2512: * @since 1.3 2513: */ 2514: public synchronized void 2515: removeHierarchyBoundsListener(HierarchyBoundsListener listener) 2516: { 2517: hierarchyBoundsListener = 2518: AWTEventMulticaster.remove(hierarchyBoundsListener, listener); 2519: } 2520: 2521: /** 2522: * Returns an array of all specified listeners registered on this component. 2523: * 2524: * @return an array of listeners 2525: * @see #addHierarchyBoundsListener(HierarchyBoundsListener) 2526: * @see #removeHierarchyBoundsListener(HierarchyBoundsListener) 2527: * @since 1.4 2528: */ 2529: public synchronized HierarchyBoundsListener[] getHierarchyBoundsListeners() 2530: { 2531: return (HierarchyBoundsListener[]) 2532: AWTEventMulticaster.getListeners(hierarchyBoundsListener, 2533: HierarchyBoundsListener.class); 2534: } 2535: 2536: /** 2537: * Adds the specified listener to this component. This is harmless if the 2538: * listener is null, but if the listener has already been registered, it 2539: * will now be registered twice. 2540: * 2541: * @param listener the new listener to add 2542: * @see KeyEvent 2543: * @see #removeKeyListener(KeyListener) 2544: * @see #getKeyListeners() 2545: * @since 1.1 2546: */ 2547: public synchronized void addKeyListener(KeyListener listener) 2548: { 2549: keyListener = AWTEventMulticaster.add(keyListener, listener); 2550: if (keyListener != null) 2551: enableEvents(AWTEvent.KEY_EVENT_MASK); 2552: } 2553: 2554: /** 2555: * Removes the specified listener from the component. This is harmless if 2556: * the listener was not previously registered. 2557: * 2558: * @param listener the listener to remove 2559: * @see KeyEvent 2560: * @see #addKeyListener(KeyListener) 2561: * @see #getKeyListeners() 2562: * @since 1.1 2563: */ 2564: public synchronized void removeKeyListener(KeyListener listener) 2565: { 2566: keyListener = AWTEventMulticaster.remove(keyListener, listener); 2567: } 2568: 2569: /** 2570: * Returns an array of all specified listeners registered on this component. 2571: * 2572: * @return an array of listeners 2573: * @see #addKeyListener(KeyListener) 2574: * @see #removeKeyListener(KeyListener) 2575: * @since 1.4 2576: */ 2577: public synchronized KeyListener[] getKeyListeners() 2578: { 2579: return (KeyListener[]) 2580: AWTEventMulticaster.getListeners(keyListener, KeyListener.class); 2581: } 2582: 2583: /** 2584: * Adds the specified listener to this component. This is harmless if the 2585: * listener is null, but if the listener has already been registered, it 2586: * will now be registered twice. 2587: * 2588: * @param listener the new listener to add 2589: * @see MouseEvent 2590: * @see #removeMouseListener(MouseListener) 2591: * @see #getMouseListeners() 2592: * @since 1.1 2593: */ 2594: public synchronized void addMouseListener(MouseListener listener) 2595: { 2596: mouseListener = AWTEventMulticaster.add(mouseListener, listener); 2597: if (mouseListener != null) 2598: enableEvents(AWTEvent.MOUSE_EVENT_MASK); 2599: } 2600: 2601: /** 2602: * Removes the specified listener from the component. This is harmless if 2603: * the listener was not previously registered. 2604: * 2605: * @param listener the listener to remove 2606: * @see MouseEvent 2607: * @see #addMouseListener(MouseListener) 2608: * @see #getMouseListeners() 2609: * @since 1.1 2610: */ 2611: public synchronized void removeMouseListener(MouseListener listener) 2612: { 2613: mouseListener = AWTEventMulticaster.remove(mouseListener, listener); 2614: } 2615: 2616: /** 2617: * Returns an array of all specified listeners registered on this component. 2618: * 2619: * @return an array of listeners 2620: * @see #addMouseListener(MouseListener) 2621: * @see #removeMouseListener(MouseListener) 2622: * @since 1.4 2623: */ 2624: public synchronized MouseListener[] getMouseListeners() 2625: { 2626: return (MouseListener[]) 2627: AWTEventMulticaster.getListeners(mouseListener, MouseListener.class); 2628: } 2629: 2630: /** 2631: * Adds the specified listener to this component. This is harmless if the 2632: * listener is null, but if the listener has already been registered, it 2633: * will now be registered twice. 2634: * 2635: * @param listener the new listener to add 2636: * @see MouseEvent 2637: * @see #removeMouseMotionListener(MouseMotionListener) 2638: * @see #getMouseMotionListeners() 2639: * @since 1.1 2640: */ 2641: public synchronized void addMouseMotionListener(MouseMotionListener listener) 2642: { 2643: mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener, listener); 2644: if (mouseMotionListener != null) 2645: enableEvents(AWTEvent.MOUSE_EVENT_MASK); 2646: } 2647: 2648: /** 2649: * Removes the specified listener from the component. This is harmless if 2650: * the listener was not previously registered. 2651: * 2652: * @param listener the listener to remove 2653: * @see MouseEvent 2654: * @see #addMouseMotionListener(MouseMotionListener) 2655: * @see #getMouseMotionListeners() 2656: * @since 1.1 2657: */ 2658: public synchronized void removeMouseMotionListener(MouseMotionListener listener) 2659: { 2660: mouseMotionListener = AWTEventMulticaster.remove(mouseMotionListener, listener); 2661: } 2662: 2663: /** 2664: * Returns an array of all specified listeners registered on this component. 2665: * 2666: * @return an array of listeners 2667: * @see #addMouseMotionListener(MouseMotionListener) 2668: * @see #removeMouseMotionListener(MouseMotionListener) 2669: * @since 1.4 2670: */ 2671: public synchronized MouseMotionListener[] getMouseMotionListeners() 2672: { 2673: return (MouseMotionListener[]) 2674: AWTEventMulticaster.getListeners(mouseMotionListener, 2675: MouseMotionListener.class); 2676: } 2677: 2678: /** 2679: * Adds the specified listener to this component. This is harmless if the 2680: * listener is null, but if the listener has already been registered, it 2681: * will now be registered twice. 2682: * 2683: * @param listener the new listener to add 2684: * @see MouseEvent 2685: * @see MouseWheelEvent 2686: * @see #removeMouseWheelListener(MouseWheelListener) 2687: * @see #getMouseWheelListeners() 2688: * @since 1.4 2689: */ 2690: public synchronized void addMouseWheelListener(MouseWheelListener listener) 2691: { 2692: mouseWheelListener = AWTEventMulticaster.add(mouseWheelListener, listener); 2693: if (mouseWheelListener != null) 2694: enableEvents(AWTEvent.MOUSE_WHEEL_EVENT_MASK); 2695: } 2696: 2697: /** 2698: * Removes the specified listener from the component. This is harmless if 2699: * the listener was not previously registered. 2700: * 2701: * @param listener the listener to remove 2702: * @see MouseEvent 2703: * @see MouseWheelEvent 2704: * @see #addMouseWheelListener(MouseWheelListener) 2705: * @see #getMouseWheelListeners() 2706: * @since 1.4 2707: */ 2708: public synchronized void removeMouseWheelListener(MouseWheelListener listener) 2709: { 2710: mouseWheelListener = AWTEventMulticaster.remove(mouseWheelListener, listener); 2711: } 2712: 2713: /** 2714: * Returns an array of all specified listeners registered on this component. 2715: * 2716: * @return an array of listeners 2717: * @see #addMouseWheelListener(MouseWheelListener) 2718: * @see #removeMouseWheelListener(MouseWheelListener) 2719: * @since 1.4 2720: */ 2721: public synchronized MouseWheelListener[] getMouseWheelListeners() 2722: { 2723: return (MouseWheelListener[]) 2724: AWTEventMulticaster.getListeners(mouseWheelListener, 2725: MouseWheelListener.class); 2726: } 2727: 2728: /** 2729: * Adds the specified listener to this component. This is harmless if the 2730: * listener is null, but if the listener has already been registered, it 2731: * will now be registered twice. 2732: * 2733: * @param listener the new listener to add 2734: * @see InputMethodEvent 2735: * @see #removeInputMethodListener(InputMethodListener) 2736: * @see #getInputMethodListeners() 2737: * @see #getInputMethodRequests() 2738: * @since 1.2 2739: */ 2740: public synchronized void addInputMethodListener(InputMethodListener listener) 2741: { 2742: inputMethodListener = AWTEventMulticaster.add(inputMethodListener, listener); 2743: if (inputMethodListener != null) 2744: enableEvents(AWTEvent.INPUT_METHOD_EVENT_MASK); 2745: } 2746: 2747: /** 2748: * Removes the specified listener from the component. This is harmless if 2749: * the listener was not previously registered. 2750: * 2751: * @param listener the listener to remove 2752: * @see InputMethodEvent 2753: * @see #addInputMethodListener(InputMethodListener) 2754: * @see #getInputMethodRequests() 2755: * @since 1.2 2756: */ 2757: public synchronized void removeInputMethodListener(InputMethodListener listener) 2758: { 2759: inputMethodListener = AWTEventMulticaster.remove(inputMethodListener, listener); 2760: } 2761: 2762: /** 2763: * Returns an array of all specified listeners registered on this component. 2764: * 2765: * @return an array of listeners 2766: * @see #addInputMethodListener(InputMethodListener) 2767: * @see #removeInputMethodListener(InputMethodListener) 2768: * @since 1.4 2769: */ 2770: public synchronized InputMethodListener[] getInputMethodListeners() 2771: { 2772: return (InputMethodListener[]) 2773: AWTEventMulticaster.getListeners(inputMethodListener, 2774: InputMethodListener.class); 2775: } 2776: 2777: /** 2778: * Returns all registered EventListers of the given listenerType. 2779: * 2780: * @param listenerType the class of listeners to filter 2781: * @return an array of registered listeners 2782: * @see #getComponentListeners() 2783: * @see #getFocusListeners() 2784: * @see #getHierarchyListeners() 2785: * @see #getHierarchyBoundsListeners() 2786: * @see #getKeyListeners() 2787: * @see #getMouseListeners() 2788: * @see #getMouseMotionListeners() 2789: * @see #getMouseWheelListeners() 2790: * @see #getInputMethodListeners() 2791: * @see #getPropertyChangeListeners() 2792: * @since 1.3 2793: */ 2794: public EventListener[] getListeners(Class listenerType) 2795: { 2796: if (listenerType == ComponentListener.class) 2797: return getComponentListeners(); 2798: if (listenerType == FocusListener.class) 2799: return getFocusListeners(); 2800: if (listenerType == HierarchyListener.class) 2801: return getHierarchyListeners(); 2802: if (listenerType == HierarchyBoundsListener.class) 2803: return getHierarchyBoundsListeners(); 2804: if (listenerType == KeyListener.class) 2805: return getKeyListeners(); 2806: if (listenerType == MouseListener.class) 2807: return getMouseListeners(); 2808: if (listenerType == MouseMotionListener.class) 2809: return getMouseMotionListeners(); 2810: if (listenerType == MouseWheelListener.class) 2811: return getMouseWheelListeners(); 2812: if (listenerType == InputMethodListener.class) 2813: return getInputMethodListeners(); 2814: if (listenerType == PropertyChangeListener.class) 2815: return getPropertyChangeListeners(); 2816: return (EventListener[]) Array.newInstance(listenerType, 0); 2817: } 2818: 2819: /** 2820: * Returns the input method request handler, for subclasses which support 2821: * on-the-spot text input. By default, input methods are handled by AWT, 2822: * and this returns null. 2823: * 2824: * @return the input method handler, null by default 2825: * @since 1.2 2826: */ 2827: public InputMethodRequests getInputMethodRequests() 2828: { 2829: return null; 2830: } 2831: 2832: /** 2833: * Gets the input context of this component, which is inherited from the 2834: * parent unless this is overridden. 2835: * 2836: * @return the text input context 2837: * @since 1.2 2838: */ 2839: public InputContext getInputContext() 2840: { 2841: return parent == null ? null : parent.getInputContext(); 2842: } 2843: 2844: /** 2845: * Enables the specified events. The events to enable are specified 2846: * by OR-ing together the desired masks from <code>AWTEvent</code>. 2847: * 2848: * <p>Events are enabled by default when a listener is attached to the 2849: * component for that event type. This method can be used by subclasses 2850: * to ensure the delivery of a specified event regardless of whether 2851: * or not a listener is attached. 2852: * 2853: * @param eventsToEnable the desired events to enable 2854: * @see #processEvent(AWTEvent) 2855: * @see #disableEvents(long) 2856: * @see AWTEvent 2857: * @since 1.1 2858: */ 2859: protected final void enableEvents(long eventsToEnable) 2860: { 2861: eventMask |= eventsToEnable; 2862: // TODO: Unlike Sun's implementation, I think we should try and 2863: // enable/disable events at the peer (gtk/X) level. This will avoid 2864: // clogging the event pipeline with useless mousemove events that 2865: // we arn't interested in, etc. This will involve extending the peer 2866: // interface, but thats okay because the peer interfaces have been 2867: // deprecated for a long time, and no longer feature in the 2868: // API specification at all. 2869: if (isLightweight() && parent != null) 2870: parent.enableEvents(eventsToEnable); 2871: else if (peer != null) 2872: peer.setEventMask(eventMask); 2873: } 2874: 2875: /** 2876: * Disables the specified events. The events to disable are specified 2877: * by OR-ing together the desired masks from <code>AWTEvent</code>. 2878: * 2879: * @param eventsToDisable the desired events to disable 2880: * @see #enableEvents(long) 2881: * @since 1.1 2882: */ 2883: protected final void disableEvents(long eventsToDisable) 2884: { 2885: eventMask &= ~eventsToDisable; 2886: // forward new event mask to peer? 2887: } 2888: 2889: /** 2890: * This is called by the EventQueue if two events with the same event id 2891: * and owner component are queued. Returns a new combined event, or null if 2892: * no combining is done. The coelesced events are currently mouse moves 2893: * (intermediate ones are discarded) and paint events (a merged paint is 2894: * created in place of the two events). 2895: * 2896: * @param existingEvent the event on the queue 2897: * @param newEvent the new event that might be entered on the queue 2898: * @return null if both events are kept, or the replacement coelesced event 2899: */ 2900: protected AWTEvent coalesceEvents(AWTEvent existingEvent, AWTEvent newEvent) 2901: { 2902: switch (existingEvent.id) 2903: { 2904: case MouseEvent.MOUSE_MOVED: 2905: case MouseEvent.MOUSE_DRAGGED: 2906: // Just drop the old (intermediate) event and return the new one. 2907: return newEvent; 2908: case PaintEvent.PAINT: 2909: case PaintEvent.UPDATE: 2910: return coalescePaintEvents((PaintEvent) existingEvent, 2911: (PaintEvent) newEvent); 2912: default: 2913: return null; 2914: } 2915: } 2916: 2917: /** 2918: * Processes the specified event. In this class, this method simply 2919: * calls one of the more specific event handlers. 2920: * 2921: * @param e the event to process 2922: * @throws NullPointerException if e is null 2923: * @see #processComponentEvent(ComponentEvent) 2924: * @see #processFocusEvent(FocusEvent) 2925: * @see #processKeyEvent(KeyEvent) 2926: * @see #processMouseEvent(MouseEvent) 2927: * @see #processMouseMotionEvent(MouseEvent) 2928: * @see #processInputMethodEvent(InputMethodEvent) 2929: * @see #processHierarchyEvent(HierarchyEvent) 2930: * @see #processMouseWheelEvent(MouseWheelEvent) 2931: * @since 1.1 2932: */ 2933: protected void processEvent(AWTEvent e) 2934: { 2935: /* Note: the order of these if statements are 2936: important. Subclasses must be checked first. Eg. MouseEvent 2937: must be checked before ComponentEvent, since a MouseEvent 2938: object is also an instance of a ComponentEvent. */ 2939: 2940: if (e instanceof FocusEvent) 2941: processFocusEvent((FocusEvent) e); 2942: else if (e instanceof MouseWheelEvent) 2943: processMouseWheelEvent((MouseWheelEvent) e); 2944: else if (e instanceof MouseEvent) 2945: { 2946: if (e.id == MouseEvent.MOUSE_MOVED 2947: || e.id == MouseEvent.MOUSE_DRAGGED) 2948: processMouseMotionEvent((MouseEvent) e); 2949: else 2950: processMouseEvent((MouseEvent) e); 2951: } 2952: else if (e instanceof KeyEvent) 2953: processKeyEvent((KeyEvent) e); 2954: else if (e instanceof InputMethodEvent) 2955: processInputMethodEvent((InputMethodEvent) e); 2956: else if (e instanceof ComponentEvent) 2957: processComponentEvent((ComponentEvent) e); 2958: else if (e instanceof HierarchyEvent) 2959: { 2960: if (e.id == HierarchyEvent.HIERARCHY_CHANGED) 2961: processHierarchyEvent((HierarchyEvent) e); 2962: else 2963: processHierarchyBoundsEvent((HierarchyEvent) e); 2964: } 2965: } 2966: 2967: /** 2968: * Called when a component event is dispatched and component events are 2969: * enabled. This method passes the event along to any listeners 2970: * that are attached. 2971: * 2972: * @param e the <code>ComponentEvent</code> to process 2973: * @throws NullPointerException if e is null 2974: * @see ComponentListener 2975: * @see #addComponentListener(ComponentListener) 2976: * @see #enableEvents(long) 2977: * @since 1.1 2978: */ 2979: protected void processComponentEvent(ComponentEvent e) 2980: { 2981: if (componentListener == null) 2982: return; 2983: switch (e.id) 2984: { 2985: case ComponentEvent.COMPONENT_HIDDEN: 2986: componentListener.componentHidden(e); 2987: break; 2988: case ComponentEvent.COMPONENT_MOVED: 2989: componentListener.componentMoved(e); 2990: break; 2991: case ComponentEvent.COMPONENT_RESIZED: 2992: componentListener.componentResized(e); 2993: break; 2994: case ComponentEvent.COMPONENT_SHOWN: 2995: componentListener.componentShown(e); 2996: break; 2997: } 2998: } 2999: 3000: /** 3001: * Called when a focus event is dispatched and component events are 3002: * enabled. This method passes the event along to any listeners 3003: * that are attached. 3004: * 3005: * @param e the <code>FocusEvent</code> to process 3006: * @throws NullPointerException if e is null 3007: * @see FocusListener 3008: * @see #addFocusListener(FocusListener) 3009: * @see #enableEvents(long) 3010: * @since 1.1 3011: */ 3012: protected void processFocusEvent(FocusEvent e) 3013: { 3014: if (focusListener == null) 3015: return; 3016: 3017: switch (e.id) 3018: { 3019: case FocusEvent.FOCUS_GAINED: 3020: focusListener.focusGained(e); 3021: break; 3022: case FocusEvent.FOCUS_LOST: 3023: focusListener.focusLost(e); 3024: break; 3025: } 3026: } 3027: 3028: /** 3029: * Called when a key event is dispatched and component events are 3030: * enabled. This method passes the event along to any listeners 3031: * that are attached. 3032: * 3033: * @param e the <code>KeyEvent</code> to process 3034: * @throws NullPointerException if e is null 3035: * @see KeyListener 3036: * @see #addKeyListener(KeyListener) 3037: * @see #enableEvents(long) 3038: * @since 1.1 3039: */ 3040: protected void processKeyEvent(KeyEvent e) 3041: { 3042: if (keyListener == null) 3043: return; 3044: switch (e.id) 3045: { 3046: case KeyEvent.KEY_PRESSED: 3047: keyListener.keyPressed(e); 3048: break; 3049: case KeyEvent.KEY_RELEASED: 3050: keyListener.keyReleased(e); 3051: break; 3052: case KeyEvent.KEY_TYPED: 3053: keyListener.keyTyped(e); 3054: break; 3055: } 3056: } 3057: 3058: /** 3059: * Called when a regular mouse event is dispatched and component events are 3060: * enabled. This method passes the event along to any listeners 3061: * that are attached. 3062: * 3063: * @param e the <code>MouseEvent</code> to process 3064: * @throws NullPointerException if e is null 3065: * @see MouseListener 3066: * @see #addMouseListener(MouseListener) 3067: * @see #enableEvents(long) 3068: * @since 1.1 3069: */ 3070: protected void processMouseEvent(MouseEvent e) 3071: { 3072: if (mouseListener == null) 3073: return; 3074: switch (e.id) 3075: { 3076: case MouseEvent.MOUSE_CLICKED: 3077: mouseListener.mouseClicked(e); 3078: break; 3079: case MouseEvent.MOUSE_ENTERED: 3080: mouseListener.mouseEntered(e); 3081: break; 3082: case MouseEvent.MOUSE_EXITED: 3083: mouseListener.mouseExited(e); 3084: break; 3085: case MouseEvent.MOUSE_PRESSED: 3086: mouseListener.mousePressed(e); 3087: break; 3088: case MouseEvent.MOUSE_RELEASED: 3089: mouseListener.mouseReleased(e); 3090: break; 3091: } 3092: e.consume(); 3093: } 3094: 3095: /** 3096: * Called when a mouse motion event is dispatched and component events are 3097: * enabled. This method passes the event along to any listeners 3098: * that are attached. 3099: * 3100: * @param e the <code>MouseMotionEvent</code> to process 3101: * @throws NullPointerException if e is null 3102: * @see MouseMotionListener 3103: * @see #addMouseMotionListener(MouseMotionListener) 3104: * @see #enableEvents(long) 3105: * @since 1.1 3106: */ 3107: protected void processMouseMotionEvent(MouseEvent e) 3108: { 3109: if (mouseMotionListener == null) 3110: return; 3111: switch (e.id) 3112: { 3113: case MouseEvent.MOUSE_DRAGGED: 3114: mouseMotionListener.mouseDragged(e); 3115: break; 3116: case MouseEvent.MOUSE_MOVED: 3117: mouseMotionListener.mouseMoved(e); 3118: break; 3119: } 3120: e.consume(); 3121: } 3122: 3123: /** 3124: * Called when a mouse wheel event is dispatched and component events are 3125: * enabled. This method passes the event along to any listeners that are 3126: * attached. 3127: * 3128: * @param e the <code>MouseWheelEvent</code> to process 3129: * @throws NullPointerException if e is null 3130: * @see MouseWheelListener 3131: * @see #addMouseWheelListener(MouseWheelListener) 3132: * @see #enableEvents(long) 3133: * @since 1.4 3134: */ 3135: protected void processMouseWheelEvent(MouseWheelEvent e) 3136: { 3137: if (mouseWheelListener != null 3138: && e.id == MouseEvent.MOUSE_WHEEL) 3139: { 3140: mouseWheelListener.mouseWheelMoved(e); 3141: e.consume(); 3142: } 3143: } 3144: 3145: /** 3146: * Called when an input method event is dispatched and component events are 3147: * enabled. This method passes the event along to any listeners that are 3148: * attached. 3149: * 3150: * @param e the <code>InputMethodEvent</code> to process 3151: * @throws NullPointerException if e is null 3152: * @see InputMethodListener 3153: * @see #addInputMethodListener(InputMethodListener) 3154: * @see #enableEvents(long) 3155: * @since 1.2 3156: */ 3157: protected void processInputMethodEvent(InputMethodEvent e) 3158: { 3159: if (inputMethodListener == null) 3160: return; 3161: switch (e.id) 3162: { 3163: case InputMethodEvent.CARET_POSITION_CHANGED: 3164: inputMethodListener.caretPositionChanged(e); 3165: break; 3166: case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED: 3167: inputMethodListener.inputMethodTextChanged(e); 3168: break; 3169: } 3170: } 3171: 3172: /** 3173: * Called when a hierarchy change event is dispatched and component events 3174: * are enabled. This method passes the event along to any listeners that are 3175: * attached. 3176: * 3177: * @param e the <code>HierarchyEvent</code> to process 3178: * @throws NullPointerException if e is null 3179: * @see HierarchyListener 3180: * @see #addHierarchyListener(HierarchyListener) 3181: * @see #enableEvents(long) 3182: * @since 1.3 3183: */ 3184: protected void processHierarchyEvent(HierarchyEvent e) 3185: { 3186: if (hierarchyListener == null) 3187: return; 3188: if (e.id == HierarchyEvent.HIERARCHY_CHANGED) 3189: hierarchyListener.hierarchyChanged(e); 3190: } 3191: 3192: /** 3193: * Called when a hierarchy bounds event is dispatched and component events 3194: * are enabled. This method passes the event along to any listeners that are 3195: * attached. 3196: * 3197: * @param e the <code>HierarchyEvent</code> to process 3198: * @throws NullPointerException if e is null 3199: * @see HierarchyBoundsListener 3200: * @see #addHierarchyBoundsListener(HierarchyBoundsListener) 3201: * @see #enableEvents(long) 3202: * @since 1.3 3203: */ 3204: protected void processHierarchyBoundsEvent(HierarchyEvent e) 3205: { 3206: if (hierarchyBoundsListener == null) 3207: return; 3208: switch (e.id) 3209: { 3210: case HierarchyEvent.ANCESTOR_MOVED: 3211: hierarchyBoundsListener.ancestorMoved(e); 3212: break; 3213: case HierarchyEvent.ANCESTOR_RESIZED: 3214: hierarchyBoundsListener.ancestorResized(e); 3215: break; 3216: } 3217: } 3218: 3219: /** 3220: * AWT 1.0 event handler. 3221: * 3222: * This method calls one of the event-specific handler methods. For 3223: * example for key events, either {@link #keyDown(Event,int)} 3224: * or {@link #keyUp(Event,int)} is called. A derived 3225: * component can override one of these event-specific methods if it 3226: * only needs to handle certain event types. Otherwise it can 3227: * override handleEvent itself and handle any event. 3228: * 3229: * @param evt the event to handle 3230: * @return true if the event was handled, false otherwise 3231: * @deprecated use {@link #processEvent(AWTEvent)} instead 3232: */ 3233: public boolean handleEvent (Event evt) 3234: { 3235: switch (evt.id) 3236: { 3237: // Handle key events. 3238: case Event.KEY_ACTION: 3239: case Event.KEY_PRESS: 3240: return keyDown (evt, evt.key); 3241: case Event.KEY_ACTION_RELEASE: 3242: case Event.KEY_RELEASE: 3243: return keyUp (evt, evt.key); 3244: 3245: // Handle mouse events. 3246: case Event.MOUSE_DOWN: 3247: return mouseDown (evt, evt.x, evt.y); 3248: case Event.MOUSE_UP: 3249: return mouseUp (evt, evt.x, evt.y); 3250: case Event.MOUSE_MOVE: 3251: return mouseMove (evt, evt.x, evt.y); 3252: case Event.MOUSE_DRAG: 3253: return mouseDrag (evt, evt.x, evt.y); 3254: case Event.MOUSE_ENTER: 3255: return mouseEnter (evt, evt.x, evt.y); 3256: case Event.MOUSE_EXIT: 3257: return mouseExit (evt, evt.x, evt.y); 3258: 3259: // Handle focus events. 3260: case Event.GOT_FOCUS: 3261: return gotFocus (evt, evt.arg); 3262: case Event.LOST_FOCUS: 3263: return lostFocus (evt, evt.arg); 3264: 3265: // Handle action event. 3266: case Event.ACTION_EVENT: 3267: return action (evt, evt.arg); 3268: } 3269: // Unknown event. 3270: return false; 3271: } 3272: 3273: /** 3274: * AWT 1.0 MOUSE_DOWN event handler. This method is meant to be 3275: * overridden by components providing their own MOUSE_DOWN handler. 3276: * The default implementation simply returns false. 3277: * 3278: * @param evt the event to handle 3279: * @param x the x coordinate, ignored 3280: * @param y the y coordinate, ignored 3281: * @return false 3282: * @deprecated use {@link #processMouseEvent(MouseEvent)} instead 3283: */ 3284: public boolean mouseDown(Event evt, int x, int y) 3285: { 3286: return false; 3287: } 3288: 3289: /** 3290: * AWT 1.0 MOUSE_DRAG event handler. This method is meant to be 3291: * overridden by components providing their own MOUSE_DRAG handler. 3292: * The default implementation simply returns false. 3293: * 3294: * @param evt the event to handle 3295: * @param x the x coordinate, ignored 3296: * @param y the y coordinate, ignored 3297: * @return false 3298: * @deprecated use {@link #processMouseMotionEvent(MouseEvent)} instead 3299: */ 3300: public boolean mouseDrag(Event evt, int x, int y) 3301: { 3302: return false; 3303: } 3304: 3305: /** 3306: * AWT 1.0 MOUSE_UP event handler. This method is meant to be 3307: * overridden by components providing their own MOUSE_UP handler. 3308: * The default implementation simply returns false. 3309: * 3310: * @param evt the event to handle 3311: * @param x the x coordinate, ignored 3312: * @param y the y coordinate, ignored 3313: * @return false 3314: * @deprecated use {@link #processMouseEvent(MouseEvent)} instead 3315: */ 3316: public boolean mouseUp(Event evt, int x, int y) 3317: { 3318: return false; 3319: } 3320: 3321: /** 3322: * AWT 1.0 MOUSE_MOVE event handler. This method is meant to be 3323: * overridden by components providing their own MOUSE_MOVE handler. 3324: * The default implementation simply returns false. 3325: * 3326: * @param evt the event to handle 3327: * @param x the x coordinate, ignored 3328: * @param y the y coordinate, ignored 3329: * @return false 3330: * @deprecated use {@link #processMouseMotionEvent(MouseEvent)} instead 3331: */ 3332: public boolean mouseMove(Event evt, int x, int y) 3333: { 3334: return false; 3335: } 3336: 3337: /** 3338: * AWT 1.0 MOUSE_ENTER event handler. This method is meant to be 3339: * overridden by components providing their own MOUSE_ENTER handler. 3340: * The default implementation simply returns false. 3341: * 3342: * @param evt the event to handle 3343: * @param x the x coordinate, ignored 3344: * @param y the y coordinate, ignored 3345: * @return false 3346: * @deprecated use {@link #processMouseEvent(MouseEvent)} instead 3347: */ 3348: public boolean mouseEnter(Event evt, int x, int y) 3349: { 3350: return false; 3351: } 3352: 3353: /** 3354: * AWT 1.0 MOUSE_EXIT event handler. This method is meant to be 3355: * overridden by components providing their own MOUSE_EXIT handler. 3356: * The default implementation simply returns false. 3357: * 3358: * @param evt the event to handle 3359: * @param x the x coordinate, ignored 3360: * @param y the y coordinate, ignored 3361: * @return false 3362: * @deprecated use {@link #processMouseEvent(MouseEvent)} instead 3363: */ 3364: public boolean mouseExit(Event evt, int x, int y) 3365: { 3366: return false; 3367: } 3368: 3369: /** 3370: * AWT 1.0 KEY_PRESS and KEY_ACTION event handler. This method is 3371: * meant to be overridden by components providing their own key 3372: * press handler. The default implementation simply returns false. 3373: * 3374: * @param evt the event to handle 3375: * @param key the key pressed, ignored 3376: * @return false 3377: * @deprecated use {@link #processKeyEvent(KeyEvent)} instead 3378: */ 3379: public boolean keyDown(Event evt, int key) 3380: { 3381: return false; 3382: } 3383: 3384: /** 3385: * AWT 1.0 KEY_RELEASE and KEY_ACTION_RELEASE event handler. This 3386: * method is meant to be overridden by components providing their 3387: * own key release handler. The default implementation simply 3388: * returns false. 3389: * 3390: * @param evt the event to handle 3391: * @param key the key pressed, ignored 3392: * @return false 3393: * @deprecated use {@link #processKeyEvent(KeyEvent)} instead 3394: */ 3395: public boolean keyUp(Event evt, int key) 3396: { 3397: return false; 3398: } 3399: 3400: /** 3401: * AWT 1.0 ACTION_EVENT event handler. This method is meant to be 3402: * overridden by components providing their own action event 3403: * handler. The default implementation simply returns false. 3404: * 3405: * @param evt the event to handle 3406: * @param what the object acted on, ignored 3407: * @return false 3408: * @deprecated in classes which support actions, use 3409: * <code>processActionEvent(ActionEvent)</code> instead 3410: */ 3411: public boolean action(Event evt, Object what) 3412: { 3413: return false; 3414: } 3415: 3416: /** 3417: * Called to inform this component it has been added to a container. 3418: * A native peer - if any - is created at this time. This method is 3419: * called automatically by the AWT system and should not be called by 3420: * user level code. 3421: * 3422: * @see #isDisplayable() 3423: * @see #removeNotify() 3424: */ 3425: public void addNotify() 3426: { 3427: if (peer == null) 3428: peer = getToolkit().createComponent(this); 3429: /* Now that all the children has gotten their peers, we should 3430: have the event mask needed for this component and its 3431: lightweight subcomponents. */ 3432: peer.setEventMask(eventMask); 3433: /* We do not invalidate here, but rather leave that job up to 3434: the peer. For efficiency, the peer can choose not to 3435: invalidate if it is happy with the current dimensions, 3436: etc. */ 3437: } 3438: 3439: /** 3440: * Called to inform this component is has been removed from its 3441: * container. Its native peer - if any - is destroyed at this time. 3442: * This method is called automatically by the AWT system and should 3443: * not be called by user level code. 3444: * 3445: * @see #isDisplayable() 3446: * @see #addNotify() 3447: */ 3448: public void removeNotify() 3449: { 3450: // We null our peer field before disposing of it, such that if we're 3451: // not the event dispatch thread and the dispatch thread is awoken by 3452: // the dispose call, there will be no race checking the peer's null 3453: // status. 3454: 3455: ComponentPeer tmp = peer; 3456: peer = null; 3457: if (tmp != null) 3458: { 3459: tmp.hide(); 3460: tmp.dispose(); 3461: } 3462: } 3463: 3464: /** 3465: * AWT 1.0 GOT_FOCUS event handler. This method is meant to be 3466: * overridden by components providing their own GOT_FOCUS handler. 3467: * The default implementation simply returns false. 3468: * 3469: * @param evt the event to handle 3470: * @param what the Object focused, ignored 3471: * @return false 3472: * @deprecated use {@link #processFocusEvent(FocusEvent)} instead 3473: */ 3474: public boolean gotFocus(Event evt, Object what) 3475: { 3476: return false; 3477: } 3478: 3479: /** 3480: * AWT 1.0 LOST_FOCUS event handler. This method is meant to be 3481: * overridden by components providing their own LOST_FOCUS handler. 3482: * The default implementation simply returns false. 3483: * 3484: * @param evt the event to handle 3485: * @param what the Object focused, ignored 3486: * @return false 3487: * @deprecated use {@link #processFocusEvent(FocusEvent)} instead 3488: */ 3489: public boolean lostFocus(Event evt, Object what) 3490: { 3491: return false; 3492: } 3493: 3494: /** 3495: * Tests whether or not this component is in the group that can be 3496: * traversed using the keyboard traversal mechanism (such as the TAB key). 3497: * 3498: * @return true if the component is traversed via the TAB key 3499: * @see #setFocusable(boolean) 3500: * @since 1.1 3501: * @deprecated use {@link #isFocusable()} instead 3502: */ 3503: public boolean isFocusTraversable() 3504: { 3505: return enabled && visible && (peer == null || isLightweight() || peer.isFocusTraversable()); 3506: } 3507: 3508: /** 3509: * Tests if this component can receive focus. 3510: * 3511: * @return true if this component can receive focus 3512: * @since 1.4 3513: */ 3514: public boolean isFocusable() 3515: { 3516: return focusable; 3517: } 3518: 3519: /** 3520: * Specify whether this component can receive focus. This method also 3521: * sets the {@link #isFocusTraversableOverridden} field to 1, which 3522: * appears to be the undocumented way {@link 3523: * DefaultFocusTraversalPolicy#accept(Component)} determines whether to 3524: * respect the {@link #isFocusable()} method of the component. 3525: * 3526: * @param focusable the new focusable status 3527: * @since 1.4 3528: */ 3529: public void setFocusable(boolean focusable) 3530: { 3531: firePropertyChange("focusable", this.focusable, focusable); 3532: this.focusable = focusable; 3533: this.isFocusTraversableOverridden = 1; 3534: } 3535: 3536: /** 3537: * Sets the focus traversal keys for one of the three focus 3538: * traversal directions supported by Components: 3539: * {@link KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS}, 3540: * {@link KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS}, or 3541: * {@link KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS}. Normally, the 3542: * default values should match the operating system's native 3543: * choices. To disable a given traversal, use 3544: * <code>Collections.EMPTY_SET</code>. The event dispatcher will 3545: * consume PRESSED, RELEASED, and TYPED events for the specified 3546: * key, although focus can only transfer on PRESSED or RELEASED. 3547: * 3548: * <p>The defaults are: 3549: * <table> 3550: * <th><td>Identifier</td><td>Meaning</td><td>Default</td></th> 3551: * <tr><td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</td> 3552: * <td>Normal forward traversal</td> 3553: * <td>TAB on KEY_PRESSED, Ctrl-TAB on KEY_PRESSED</td></tr> 3554: * <tr><td>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</td> 3555: * <td>Normal backward traversal</td> 3556: * <td>Shift-TAB on KEY_PRESSED, Ctrl-Shift-TAB on KEY_PRESSED</td></tr> 3557: * <tr><td>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</td> 3558: * <td>Go up a traversal cycle</td><td>None</td></tr> 3559: * </table> 3560: * 3561: * If keystrokes is null, this component's focus traversal key set 3562: * is inherited from one of its ancestors. If none of its ancestors 3563: * has its own set of focus traversal keys, the focus traversal keys 3564: * are set to the defaults retrieved from the current 3565: * KeyboardFocusManager. If not null, the set must contain only 3566: * AWTKeyStrokes that are not already focus keys and are not 3567: * KEY_TYPED events. 3568: * 3569: * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS, or 3570: * UP_CYCLE_TRAVERSAL_KEYS 3571: * @param keystrokes a set of keys, or null 3572: * @throws IllegalArgumentException if id or keystrokes is invalid 3573: * @see #getFocusTraversalKeys(int) 3574: * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS 3575: * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS 3576: * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS 3577: * @since 1.4 3578: */ 3579: public void setFocusTraversalKeys(int id, Set keystrokes) 3580: { 3581: if (keystrokes == null) 3582: { 3583: Container parent = getParent (); 3584: 3585: while (parent != null) 3586: { 3587: if (parent.areFocusTraversalKeysSet (id)) 3588: { 3589: keystrokes = parent.getFocusTraversalKeys (id); 3590: break; 3591: } 3592: parent = parent.getParent (); 3593: } 3594: 3595: if (keystrokes == null) 3596: keystrokes = KeyboardFocusManager.getCurrentKeyboardFocusManager (). 3597: getDefaultFocusTraversalKeys (id); 3598: } 3599: 3600: Set sa; 3601: Set sb; 3602: String name; 3603: switch (id) 3604: { 3605: case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS: 3606: sa = getFocusTraversalKeys 3607: (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS); 3608: sb = getFocusTraversalKeys 3609: (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS); 3610: name = "forwardFocusTraversalKeys"; 3611: break; 3612: case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS: 3613: sa = getFocusTraversalKeys 3614: (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS); 3615: sb = getFocusTraversalKeys 3616: (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS); 3617: name = "backwardFocusTraversalKeys"; 3618: break; 3619: case KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS: 3620: sa = getFocusTraversalKeys 3621: (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS); 3622: sb = getFocusTraversalKeys 3623: (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS); 3624: name = "upCycleFocusTraversalKeys"; 3625: break; 3626: default: 3627: throw new IllegalArgumentException (); 3628: } 3629: 3630: int i = keystrokes.size (); 3631: Iterator iter = keystrokes.iterator (); 3632: 3633: while (--i >= 0) 3634: { 3635: Object o = iter.next (); 3636: if (!(o instanceof AWTKeyStroke) 3637: || sa.contains (o) || sb.contains (o) 3638: || ((AWTKeyStroke) o).keyCode == KeyEvent.VK_UNDEFINED) 3639: throw new IllegalArgumentException (); 3640: } 3641: 3642: if (focusTraversalKeys == null) 3643: focusTraversalKeys = new Set[3]; 3644: 3645: keystrokes = Collections.unmodifiableSet (new HashSet (keystrokes)); 3646: firePropertyChange (name, focusTraversalKeys[id], keystrokes); 3647: 3648: focusTraversalKeys[id] = keystrokes; 3649: } 3650: 3651: /** 3652: * Returns the set of keys for a given focus traversal action, as 3653: * defined in <code>setFocusTraversalKeys</code>. If not set, this 3654: * is inherited from the parent component, which may have gotten it 3655: * from the KeyboardFocusManager. 3656: * 3657: * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS, 3658: * or UP_CYCLE_TRAVERSAL_KEYS 3659: * 3660: * @return set of traversal keys 3661: * 3662: * @throws IllegalArgumentException if id is invalid 3663: * 3664: * @see #setFocusTraversalKeys (int, Set) 3665: * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS 3666: * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS 3667: * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS 3668: * 3669: * @since 1.4 3670: */ 3671: public Set getFocusTraversalKeys (int id) 3672: { 3673: if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS && 3674: id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS && 3675: id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS) 3676: throw new IllegalArgumentException(); 3677: 3678: Set s = null; 3679: 3680: if (focusTraversalKeys != null) 3681: s = focusTraversalKeys[id]; 3682: 3683: if (s == null && parent != null) 3684: s = parent.getFocusTraversalKeys (id); 3685: 3686: return s == null ? (KeyboardFocusManager.getCurrentKeyboardFocusManager() 3687: .getDefaultFocusTraversalKeys(id)) : s; 3688: } 3689: 3690: /** 3691: * Tests whether the focus traversal keys for a given action are explicitly 3692: * set or inherited. 3693: * 3694: * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS, 3695: * or UP_CYCLE_TRAVERSAL_KEYS 3696: * @return true if that set is explicitly specified 3697: * @throws IllegalArgumentException if id is invalid 3698: * @see #getFocusTraversalKeys (int) 3699: * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS 3700: * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS 3701: * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS 3702: * @since 1.4 3703: */ 3704: public boolean areFocusTraversalKeysSet (int id) 3705: { 3706: if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS && 3707: id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS && 3708: id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS) 3709: throw new IllegalArgumentException (); 3710: 3711: return focusTraversalKeys != null && focusTraversalKeys[id] != null; 3712: } 3713: 3714: /** 3715: * Enable or disable focus traversal keys on this Component. If 3716: * they are, then the keyboard focus manager consumes and acts on 3717: * key press and release events that trigger focus traversal, and 3718: * discards the corresponding key typed events. If focus traversal 3719: * keys are disabled, then all key events that would otherwise 3720: * trigger focus traversal are sent to this Component. 3721: * 3722: * @param focusTraversalKeysEnabled the new value of the flag 3723: * @see #getFocusTraversalKeysEnabled () 3724: * @see #setFocusTraversalKeys (int, Set) 3725: * @see #getFocusTraversalKeys (int) 3726: * @since 1.4 3727: */ 3728: public void setFocusTraversalKeysEnabled (boolean focusTraversalKeysEnabled) 3729: { 3730: firePropertyChange ("focusTraversalKeysEnabled", 3731: this.focusTraversalKeysEnabled, 3732: focusTraversalKeysEnabled); 3733: this.focusTraversalKeysEnabled = focusTraversalKeysEnabled; 3734: } 3735: 3736: /** 3737: * Check whether or not focus traversal keys are enabled on this 3738: * Component. If they are, then the keyboard focus manager consumes 3739: * and acts on key press and release events that trigger focus 3740: * traversal, and discards the corresponding key typed events. If 3741: * focus traversal keys are disabled, then all key events that would 3742: * otherwise trigger focus traversal are sent to this Component. 3743: * 3744: * @return true if focus traversal keys are enabled 3745: * @see #setFocusTraversalKeysEnabled (boolean) 3746: * @see #setFocusTraversalKeys (int, Set) 3747: * @see #getFocusTraversalKeys (int) 3748: * @since 1.4 3749: */ 3750: public boolean getFocusTraversalKeysEnabled () 3751: { 3752: return focusTraversalKeysEnabled; 3753: } 3754: 3755: /** 3756: * Request that this Component be given the keyboard input focus and 3757: * that its top-level ancestor become the focused Window. 3758: * 3759: * For the request to be granted, the Component must be focusable, 3760: * displayable and showing and the top-level Window to which it 3761: * belongs must be focusable. If the request is initially denied on 3762: * the basis that the top-level Window is not focusable, the request 3763: * will be remembered and granted when the Window does become 3764: * focused. 3765: * 3766: * Never assume that this Component is the focus owner until it 3767: * receives a FOCUS_GAINED event. 3768: * 3769: * The behaviour of this method is platform-dependent. 3770: * {@link #requestFocusInWindow()} should be used instead. 3771: * 3772: * @see #requestFocusInWindow () 3773: * @see FocusEvent 3774: * @see #addFocusListener (FocusListener) 3775: * @see #isFocusable () 3776: * @see #isDisplayable () 3777: * @see KeyboardFocusManager#clearGlobalFocusOwner () 3778: */ 3779: public void requestFocus () 3780: { 3781: if (isDisplayable () 3782: && isShowing () 3783: && isFocusable ()) 3784: { 3785: synchronized (getTreeLock ()) 3786: { 3787: // Find this Component's top-level ancestor. 3788: Container parent = (this instanceof Container) ? (Container) this 3789: : getParent(); 3790: while (parent != null 3791: && !(parent instanceof Window)) 3792: parent = parent.getParent (); 3793: 3794: if (parent == null) 3795: return; 3796: 3797: Window toplevel = (Window) parent; 3798: if (toplevel.isFocusableWindow ()) 3799: { 3800: if (peer != null && !isLightweight()) 3801: // This call will cause a FOCUS_GAINED event to be 3802: // posted to the system event queue if the native 3803: // windowing system grants the focus request. 3804: peer.requestFocus (); 3805: else 3806: { 3807: // Either our peer hasn't been created yet or we're a 3808: // lightweight component. In either case we want to 3809: // post a FOCUS_GAINED event. 3810: EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue (); 3811: synchronized (eq) 3812: { 3813: KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager (); 3814: Component currentFocusOwner = manager.getGlobalPermanentFocusOwner (); 3815: if (currentFocusOwner != null) 3816: { 3817: eq.postEvent (new FocusEvent(currentFocusOwner, FocusEvent.FOCUS_LOST, 3818: false, this)); 3819: eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, false, 3820: currentFocusOwner)); 3821: } 3822: else 3823: eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, false)); 3824: } 3825: } 3826: } 3827: else 3828: pendingFocusRequest = new FocusEvent(this, FocusEvent.FOCUS_GAINED); 3829: } 3830: } 3831: } 3832: 3833: /** 3834: * Request that this Component be given the keyboard input focus and 3835: * that its top-level ancestor become the focused Window. 3836: * 3837: * For the request to be granted, the Component must be focusable, 3838: * displayable and showing and the top-level Window to which it 3839: * belongs must be focusable. If the request is initially denied on 3840: * the basis that the top-level Window is not focusable, the request 3841: * will be remembered and granted when the Window does become 3842: * focused. 3843: * 3844: * Never assume that this Component is the focus owner until it 3845: * receives a FOCUS_GAINED event. 3846: * 3847: * The behaviour of this method is platform-dependent. 3848: * {@link #requestFocusInWindow()} should be used instead. 3849: * 3850: * If the return value is false, the request is guaranteed to fail. 3851: * If the return value is true, the request will succeed unless it 3852: * is vetoed or something in the native windowing system intervenes, 3853: * preventing this Component's top-level ancestor from becoming 3854: * focused. This method is meant to be called by derived 3855: * lightweight Components that want to avoid unnecessary repainting 3856: * when they know a given focus transfer need only be temporary. 3857: * 3858: * @param temporary true if the focus request is temporary 3859: * @return true if the request has a chance of success 3860: * @see #requestFocusInWindow () 3861: * @see FocusEvent 3862: * @see #addFocusListener (FocusListener) 3863: * @see #isFocusable () 3864: * @see #isDisplayable () 3865: * @see KeyboardFocusManager#clearGlobalFocusOwner () 3866: * @since 1.4 3867: */ 3868: protected boolean requestFocus (boolean temporary) 3869: { 3870: if (isDisplayable () 3871: && isShowing () 3872: && isFocusable ()) 3873: { 3874: synchronized (getTreeLock ()) 3875: { 3876: // Find this Component's top-level ancestor. 3877: Container parent = getParent (); 3878: 3879: while (parent != null 3880: && !(parent instanceof Window)) 3881: parent = parent.getParent (); 3882: 3883: Window toplevel = (Window) parent; 3884: if (toplevel.isFocusableWindow ()) 3885: { 3886: if (peer != null && !isLightweight()) 3887: // This call will cause a FOCUS_GAINED event to be 3888: // posted to the system event queue if the native 3889: // windowing system grants the focus request. 3890: peer.requestFocus (); 3891: else 3892: { 3893: // Either our peer hasn't been created yet or we're a 3894: // lightweight component. In either case we want to 3895: // post a FOCUS_GAINED event. 3896: EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue (); 3897: synchronized (eq) 3898: { 3899: KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager (); 3900: Component currentFocusOwner = manager.getGlobalPermanentFocusOwner (); 3901: if (currentFocusOwner != null) 3902: { 3903: eq.postEvent (new FocusEvent(currentFocusOwner, 3904: FocusEvent.FOCUS_LOST, 3905: temporary, this)); 3906: eq.postEvent (new FocusEvent(this, 3907: FocusEvent.FOCUS_GAINED, 3908: temporary, 3909: currentFocusOwner)); 3910: } 3911: else 3912: eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary)); 3913: } 3914: } 3915: } 3916: else 3917: // FIXME: need to add a focus listener to our top-level 3918: // ancestor, so that we can post this event when it becomes 3919: // the focused window. 3920: pendingFocusRequest = new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary); 3921: } 3922: } 3923: // Always return true. 3924: return true; 3925: } 3926: 3927: /** 3928: * Request that this component be given the keyboard input focus, if 3929: * its top-level ancestor is the currently focused Window. A 3930: * <code>FOCUS_GAINED</code> event will be fired if and only if this 3931: * request is successful. To be successful, the component must be 3932: * displayable, showing, and focusable, and its ancestor top-level 3933: * Window must be focused. 3934: * 3935: * If the return value is false, the request is guaranteed to fail. 3936: * If the return value is true, the request will succeed unless it 3937: * is vetoed or something in the native windowing system intervenes, 3938: * preventing this Component's top-level ancestor from becoming 3939: * focused. 3940: * 3941: * @return true if the request has a chance of success 3942: * @see #requestFocus () 3943: * @see FocusEvent 3944: * @see #addFocusListener (FocusListener) 3945: * @see #isFocusable () 3946: * @see #isDisplayable () 3947: * @see KeyboardFocusManager#clearGlobalFocusOwner () 3948: * @since 1.4 3949: */ 3950: public boolean requestFocusInWindow () 3951: { 3952: return requestFocusInWindow (false); 3953: } 3954: 3955: /** 3956: * Request that this component be given the keyboard input focus, if 3957: * its top-level ancestor is the currently focused Window. A 3958: * <code>FOCUS_GAINED</code> event will be fired if and only if this 3959: * request is successful. To be successful, the component must be 3960: * displayable, showing, and focusable, and its ancestor top-level 3961: * Window must be focused. 3962: * 3963: * If the return value is false, the request is guaranteed to fail. 3964: * If the return value is true, the request will succeed unless it 3965: * is vetoed or something in the native windowing system intervenes, 3966: * preventing this Component's top-level ancestor from becoming 3967: * focused. This method is meant to be called by derived 3968: * lightweight Components that want to avoid unnecessary repainting 3969: * when they know a given focus transfer need only be temporary. 3970: * 3971: * @param temporary true if the focus request is temporary 3972: * @return true if the request has a chance of success 3973: * @see #requestFocus () 3974: * @see FocusEvent 3975: * @see #addFocusListener (FocusListener) 3976: * @see #isFocusable () 3977: * @see #isDisplayable () 3978: * @see KeyboardFocusManager#clearGlobalFocusOwner () 3979: * @since 1.4 3980: */ 3981: protected boolean requestFocusInWindow (boolean temporary) 3982: { 3983: KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager (); 3984: 3985: Window focusedWindow = manager.getFocusedWindow (); 3986: 3987: if (isDisplayable () 3988: && isShowing () 3989: && isFocusable ()) 3990: { 3991: if (focusedWindow != null) 3992: { 3993: synchronized (getTreeLock ()) 3994: { 3995: Container parent = getParent (); 3996: 3997: while (parent != null 3998: && !(parent instanceof Window)) 3999: parent = parent.getParent (); 4000: 4001: Window toplevel = (Window) parent; 4002: 4003: // Check if top-level ancestor is currently focused window. 4004: if (focusedWindow == toplevel) 4005: { 4006: if (peer != null 4007: && !isLightweight() 4008: && !(this instanceof Window)) 4009: // This call will cause a FOCUS_GAINED event to be 4010: // posted to the system event queue if the native 4011: // windowing system grants the focus request. 4012: peer.requestFocus (); 4013: else 4014: { 4015: // Either our peer hasn't been created yet or we're a 4016: // lightweight component. In either case we want to 4017: // post a FOCUS_GAINED event. 4018: EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue (); 4019: synchronized (eq) 4020: { 4021: Component currentFocusOwner = manager.getGlobalPermanentFocusOwner (); 4022: if (currentFocusOwner != null) 4023: { 4024: eq.postEvent (new FocusEvent(currentFocusOwner, FocusEvent.FOCUS_LOST, 4025: temporary, this)); 4026: eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary, 4027: currentFocusOwner)); 4028: } 4029: else 4030: eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary)); 4031: } 4032: } 4033: } 4034: else 4035: return false; 4036: } 4037: } 4038: 4039: return true; 4040: } 4041: return false; 4042: } 4043: 4044: /** 4045: * Transfers focus to the next component in the focus traversal 4046: * order, as though this were the current focus owner. 4047: * 4048: * @see #requestFocus() 4049: * @since 1.1 4050: */ 4051: public void transferFocus () 4052: { 4053: nextFocus (); 4054: } 4055: 4056: /** 4057: * Returns the root container that owns the focus cycle where this 4058: * component resides. A focus cycle root is in two cycles, one as 4059: * the ancestor, and one as the focusable element; this call always 4060: * returns the ancestor. 4061: * 4062: * @return the ancestor container that owns the focus cycle 4063: * @since 1.4 4064: */ 4065: public Container getFocusCycleRootAncestor () 4066: { 4067: if (this instanceof Window 4068: && ((Container) this).isFocusCycleRoot ()) 4069: return (Container) this; 4070: 4071: Container parent = getParent (); 4072: 4073: while (parent != null 4074: && !parent.isFocusCycleRoot ()) 4075: parent = parent.getParent (); 4076: 4077: return parent; 4078: } 4079: 4080: /** 4081: * Tests if the container is the ancestor of the focus cycle that 4082: * this component belongs to. 4083: * 4084: * @param c the container to test 4085: * @return true if c is the focus cycle root 4086: * @since 1.4 4087: */ 4088: public boolean isFocusCycleRoot (Container c) 4089: { 4090: return c == getFocusCycleRootAncestor (); 4091: } 4092: 4093: /** 4094: * AWT 1.0 focus event processor. Transfers focus to the next 4095: * component in the focus traversal order, as though this were the 4096: * current focus owner. 4097: * 4098: * @deprecated use {@link #transferFocus ()} instead 4099: */ 4100: public void nextFocus () 4101: { 4102: KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager (); 4103: 4104: manager.focusNextComponent (this); 4105: } 4106: 4107: /** 4108: * Transfers focus to the previous component in the focus traversal 4109: * order, as though this were the current focus owner. 4110: * 4111: * @see #requestFocus () 4112: * @since 1.4 4113: */ 4114: public void transferFocusBackward () 4115: { 4116: KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager (); 4117: 4118: manager.focusPreviousComponent (this); 4119: } 4120: 4121: /** 4122: * Transfers focus to the focus cycle root of this component. 4123: * However, if this is a Window, the default focus owner in the 4124: * window in the current focus cycle is focused instead. 4125: * 4126: * @see #requestFocus() 4127: * @see #isFocusCycleRoot(Container) 4128: * @since 1.4 4129: */ 4130: public void transferFocusUpCycle () 4131: { 4132: KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager (); 4133: 4134: manager.upFocusCycle (this); 4135: } 4136: 4137: /** 4138: * Tests if this component is the focus owner. Use {@link 4139: * #isFocusOwner ()} instead. 4140: * 4141: * @return true if this component owns focus 4142: * @since 1.2 4143: */ 4144: public boolean hasFocus () 4145: { 4146: KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager (); 4147: 4148: Component focusOwner = manager.getFocusOwner (); 4149: 4150: return this == focusOwner; 4151: } 4152: 4153: /** 4154: * Tests if this component is the focus owner. 4155: * 4156: * @return true if this component owns focus 4157: * @since 1.4 4158: */ 4159: public boolean isFocusOwner() 4160: { 4161: return hasFocus (); 4162: } 4163: 4164: /** 4165: * Adds the specified popup menu to this component. 4166: * 4167: * @param popup the popup menu to be added 4168: * 4169: * @see #remove(MenuComponent) 4170: * 4171: * @since 1.1 4172: */ 4173: public synchronized void add(PopupMenu popup) 4174: { 4175: if (popups == null) 4176: popups = new Vector(); 4177: popups.add(popup); 4178: 4179: if (popup.parent != null) 4180: popup.parent.remove(popup); 4181: popup.parent = this; 4182: if (peer != null) 4183: popup.addNotify(); 4184: } 4185: 4186: /** 4187: * Removes the specified popup menu from this component. 4188: * 4189: * @param popup the popup menu to remove 4190: * @see #add(PopupMenu) 4191: * @since 1.1 4192: */ 4193: public synchronized void remove(MenuComponent popup) 4194: { 4195: if (popups != null) 4196: popups.remove(popup); 4197: } 4198: 4199: /** 4200: * Returns a debugging string representing this component. The string may 4201: * be empty but not null. 4202: * 4203: * @return a string representing this component 4204: */ 4205: protected String paramString() 4206: { 4207: StringBuffer param = new StringBuffer(); 4208: String name = getName(); 4209: if (name != null) 4210: param.append(name).append(","); 4211: param.append(x).append(",").append(y).append(",").append(width) 4212: .append("x").append(height); 4213: if (! isValid()) 4214: param.append(",invalid"); 4215: if (! isVisible()) 4216: param.append(",invisible"); 4217: if (! isEnabled()) 4218: param.append(",disabled"); 4219: if (! isOpaque()) 4220: param.append(",translucent"); 4221: if (isDoubleBuffered()) 4222: param.append(",doublebuffered"); 4223: if (parent == null) 4224: param.append(",parent=null"); 4225: else 4226: param.append(",parent=").append(parent.getName()); 4227: return param.toString(); 4228: } 4229: 4230: /** 4231: * Returns a string representation of this component. This is implemented 4232: * as <code>getClass().getName() + '[' + paramString() + ']'</code>. 4233: * 4234: * @return a string representation of this component 4235: */ 4236: public String toString() 4237: { 4238: return getClass().getName() + '[' + paramString() + ']'; 4239: } 4240: 4241: /** 4242: * Prints a listing of this component to <code>System.out</code>. 4243: * 4244: * @see #list(PrintStream) 4245: */ 4246: public void list() 4247: { 4248: list(System.out, 0); 4249: } 4250: 4251: /** 4252: * Prints a listing of this component to the specified print stream. 4253: * 4254: * @param out the <code>PrintStream</code> to print to 4255: */ 4256: public void list(PrintStream out) 4257: { 4258: list(out, 0); 4259: } 4260: 4261: /** 4262: * Prints a listing of this component to the specified print stream, 4263: * starting at the specified indentation point. 4264: * 4265: * @param out the <code>PrintStream</code> to print to 4266: * @param indent the indentation point 4267: */ 4268: public void list(PrintStream out, int indent) 4269: { 4270: for (int i = 0; i < indent; ++i) 4271: out.print(' '); 4272: out.println(toString()); 4273: } 4274: 4275: /** 4276: * Prints a listing of this component to the specified print writer. 4277: * 4278: * @param out the <code>PrintWrinter</code> to print to 4279: * @since 1.1 4280: */ 4281: public void list(PrintWriter out) 4282: { 4283: list(out, 0); 4284: } 4285: 4286: /** 4287: * Prints a listing of this component to the specified print writer, 4288: * starting at the specified indentation point. 4289: * 4290: * @param out the <code>PrintWriter</code> to print to 4291: * @param indent the indentation point 4292: * @since 1.1 4293: */ 4294: public void list(PrintWriter out, int indent) 4295: { 4296: for (int i = 0; i < indent; ++i) 4297: out.print(' '); 4298: out.println(toString()); 4299: } 4300: 4301: /** 4302: * Adds the specified property listener to this component. This is harmless 4303: * if the listener is null, but if the listener has already been registered, 4304: * it will now be registered twice. The property listener ignores inherited 4305: * properties. Recognized properties include:<br> 4306: * <ul> 4307: * <li>the font (<code>"font"</code>)</li> 4308: * <li>the background color (<code>"background"</code>)</li> 4309: * <li>the foreground color (<code>"foreground"</code>)</li> 4310: * <li>the focusability (<code>"focusable"</code>)</li> 4311: * <li>the focus key traversal enabled state 4312: * (<code>"focusTraversalKeysEnabled"</code>)</li> 4313: * <li>the set of forward traversal keys 4314: * (<code>"forwardFocusTraversalKeys"</code>)</li> 4315: * <li>the set of backward traversal keys 4316: * (<code>"backwardFocusTraversalKeys"</code>)</li> 4317: * <li>the set of up-cycle traversal keys 4318: * (<code>"upCycleFocusTraversalKeys"</code>)</li> 4319: * </ul> 4320: * 4321: * @param listener the new listener to add 4322: * @see #removePropertyChangeListener(PropertyChangeListener) 4323: * @see #getPropertyChangeListeners() 4324: * @see #addPropertyChangeListener(String, PropertyChangeListener) 4325: * @since 1.1 4326: */ 4327: public void addPropertyChangeListener(PropertyChangeListener listener) 4328: { 4329: if (changeSupport == null) 4330: changeSupport = new PropertyChangeSupport(this); 4331: changeSupport.addPropertyChangeListener(listener); 4332: } 4333: 4334: /** 4335: * Removes the specified property listener from the component. This is 4336: * harmless if the listener was not previously registered. 4337: * 4338: * @param listener the listener to remove 4339: * @see #addPropertyChangeListener(PropertyChangeListener) 4340: * @see #getPropertyChangeListeners() 4341: * @see #removePropertyChangeListener(String, PropertyChangeListener) 4342: * @since 1.1 4343: */ 4344: public void removePropertyChangeListener(PropertyChangeListener listener) 4345: { 4346: if (changeSupport != null) 4347: changeSupport.removePropertyChangeListener(listener); 4348: } 4349: 4350: /** 4351: * Returns an array of all specified listeners registered on this component. 4352: * 4353: * @return an array of listeners 4354: * @see #addPropertyChangeListener(PropertyChangeListener) 4355: * @see #removePropertyChangeListener(PropertyChangeListener) 4356: * @see #getPropertyChangeListeners(String) 4357: * @since 1.4 4358: */ 4359: public PropertyChangeListener[] getPropertyChangeListeners() 4360: { 4361: return changeSupport == null ? new PropertyChangeListener[0] 4362: : changeSupport.getPropertyChangeListeners(); 4363: } 4364: 4365: /** 4366: * Adds the specified property listener to this component. This is harmless 4367: * if the listener is null, but if the listener has already been registered, 4368: * it will now be registered twice. The property listener ignores inherited 4369: * properties. The listener is keyed to a single property. Recognized 4370: * properties include:<br> 4371: * <ul> 4372: * <li>the font (<code>"font"</code>)</li> 4373: * <li>the background color (<code>"background"</code>)</li> 4374: * <li>the foreground color (<code>"foreground"</code>)</li> 4375: * <li>the focusability (<code>"focusable"</code>)</li> 4376: * <li>the focus key traversal enabled state 4377: * (<code>"focusTraversalKeysEnabled"</code>)</li> 4378: * <li>the set of forward traversal keys 4379: * (<code>"forwardFocusTraversalKeys"</code>)</li> 4380: p * <li>the set of backward traversal keys 4381: * (<code>"backwardFocusTraversalKeys"</code>)</li> 4382: * <li>the set of up-cycle traversal keys 4383: * (<code>"upCycleFocusTraversalKeys"</code>)</li> 4384: * </ul> 4385: * 4386: * @param propertyName the property name to filter on 4387: * @param listener the new listener to add 4388: * @see #removePropertyChangeListener(String, PropertyChangeListener) 4389: * @see #getPropertyChangeListeners(String) 4390: * @see #addPropertyChangeListener(PropertyChangeListener) 4391: * @since 1.1 4392: */ 4393: public void addPropertyChangeListener(String propertyName, 4394: PropertyChangeListener listener) 4395: { 4396: if (changeSupport == null) 4397: changeSupport = new PropertyChangeSupport(this); 4398: changeSupport.addPropertyChangeListener(propertyName, listener); 4399: } 4400: 4401: /** 4402: * Removes the specified property listener on a particular property from 4403: * the component. This is harmless if the listener was not previously 4404: * registered. 4405: * 4406: * @param propertyName the property name to filter on 4407: * @param listener the listener to remove 4408: * @see #addPropertyChangeListener(String, PropertyChangeListener) 4409: * @see #getPropertyChangeListeners(String) 4410: * @see #removePropertyChangeListener(PropertyChangeListener) 4411: * @since 1.1 4412: */ 4413: public void removePropertyChangeListener(String propertyName, 4414: PropertyChangeListener listener) 4415: { 4416: if (changeSupport != null) 4417: changeSupport.removePropertyChangeListener(propertyName, listener); 4418: } 4419: 4420: /** 4421: * Returns an array of all specified listeners on the named property that 4422: * are registered on this component. 4423: * 4424: * @return an array of listeners 4425: * @see #addPropertyChangeListener(String, PropertyChangeListener) 4426: * @see #removePropertyChangeListener(String, PropertyChangeListener) 4427: * @see #getPropertyChangeListeners() 4428: * @since 1.4 4429: */ 4430: public PropertyChangeListener[] getPropertyChangeListeners(String property) 4431: { 4432: return changeSupport == null ? new PropertyChangeListener[0] 4433: : changeSupport.getPropertyChangeListeners(property); 4434: } 4435: 4436: /** 4437: * Report a change in a bound property to any registered property listeners. 4438: * 4439: * @param propertyName the property that changed 4440: * @param oldValue the old property value 4441: * @param newValue the new property value 4442: */ 4443: protected void firePropertyChange(String propertyName, Object oldValue, 4444: Object newValue) 4445: { 4446: if (changeSupport != null) 4447: changeSupport.firePropertyChange(propertyName, oldValue, newValue); 4448: } 4449: 4450: /** 4451: * Report a change in a bound property to any registered property listeners. 4452: * 4453: * @param propertyName the property that changed 4454: * @param oldValue the old property value 4455: * @param newValue the new property value 4456: */ 4457: protected void firePropertyChange(String propertyName, boolean oldValue, 4458: boolean newValue) 4459: { 4460: if (changeSupport != null) 4461: changeSupport.firePropertyChange(propertyName, oldValue, newValue); 4462: } 4463: 4464: /** 4465: * Report a change in a bound property to any registered property listeners. 4466: * 4467: * @param propertyName the property that changed 4468: * @param oldValue the old property value 4469: * @param newValue the new property value 4470: */ 4471: protected void firePropertyChange(String propertyName, int oldValue, 4472: int newValue) 4473: { 4474: if (changeSupport != null) 4475: changeSupport.firePropertyChange(propertyName, oldValue, newValue); 4476: } 4477: 4478: /** 4479: * Sets the text layout orientation of this component. New components default 4480: * to UNKNOWN (which behaves like LEFT_TO_RIGHT). This method affects only 4481: * the current component, while 4482: * {@link #applyComponentOrientation(ComponentOrientation)} affects the 4483: * entire hierarchy. 4484: * 4485: * @param o the new orientation 4486: * @throws NullPointerException if o is null 4487: * @see #getComponentOrientation() 4488: */ 4489: public void setComponentOrientation(ComponentOrientation o) 4490: { 4491: if (o == null) 4492: throw new NullPointerException(); 4493: ComponentOrientation oldOrientation = orientation; 4494: orientation = o; 4495: firePropertyChange("componentOrientation", oldOrientation, o); 4496: } 4497: 4498: /** 4499: * Determines the text layout orientation used by this component. 4500: * 4501: * @return the component orientation 4502: * @see #setComponentOrientation(ComponentOrientation) 4503: */ 4504: public ComponentOrientation getComponentOrientation() 4505: { 4506: return orientation; 4507: } 4508: 4509: /** 4510: * Sets the text layout orientation of this component. New components default 4511: * to UNKNOWN (which behaves like LEFT_TO_RIGHT). This method affects the 4512: * entire hierarchy, while 4513: * {@link #setComponentOrientation(ComponentOrientation)} affects only the 4514: * current component. 4515: * 4516: * @param o the new orientation 4517: * @throws NullPointerException if o is null 4518: * @see #getComponentOrientation() 4519: * @since 1.4 4520: */ 4521: public void applyComponentOrientation(ComponentOrientation o) 4522: { 4523: setComponentOrientation(o); 4524: } 4525: 4526: /** 4527: * Returns the accessibility framework context of this class. Component is 4528: * not accessible, so the default implementation returns null. Subclasses 4529: * must override this behavior, and return an appropriate subclass of 4530: * {@link AccessibleAWTComponent}. 4531: * 4532: * @return the accessibility context 4533: */ 4534: public AccessibleContext getAccessibleContext() 4535: { 4536: return null; 4537: } 4538: 4539: 4540: // Helper methods; some are package visible for use by subclasses. 4541: 4542: /** 4543: * Subclasses should override this to return unique component names like 4544: * "menuitem0". 4545: * 4546: * @return the generated name for this component 4547: */ 4548: String generateName() 4549: { 4550: // Component is abstract. 4551: return null; 4552: } 4553: 4554: /** 4555: * Sets the peer for this component. 4556: * 4557: * @param peer the new peer 4558: */ 4559: final void setPeer(ComponentPeer peer) 4560: { 4561: this.peer = peer; 4562: } 4563: 4564: /** 4565: * Implementation method that allows classes such as Canvas and Window to 4566: * override the graphics configuration without violating the published API. 4567: * 4568: * @return the graphics configuration 4569: */ 4570: GraphicsConfiguration getGraphicsConfigurationImpl() 4571: { 4572: if (peer != null) 4573: { 4574: GraphicsConfiguration config = peer.getGraphicsConfiguration(); 4575: if (config != null) 4576: return config; 4577: } 4578: 4579: if (parent != null) 4580: return parent.getGraphicsConfiguration(); 4581: 4582: return null; 4583: } 4584: 4585: /** 4586: * Translate an AWT 1.1 event ({@link AWTEvent}) into an AWT 1.0 4587: * event ({@link Event}). 4588: * 4589: * @param e an AWT 1.1 event to translate 4590: * 4591: * @return an AWT 1.0 event representing e 4592: */ 4593: static Event translateEvent (AWTEvent e) 4594: { 4595: Component target = (Component) e.getSource (); 4596: Event translated = null; 4597: 4598: if (e instanceof InputEvent) 4599: { 4600: InputEvent ie = (InputEvent) e; 4601: long when = ie.getWhen (); 4602: 4603: int oldID = 0; 4604: int id = e.getID (); 4605: 4606: int oldMods = 0; 4607: int mods = ie.getModifiersEx (); 4608: 4609: if ((mods & InputEvent.BUTTON2_DOWN_MASK) != 0) 4610: oldMods |= Event.META_MASK; 4611: else if ((mods & InputEvent.BUTTON3_DOWN_MASK) != 0) 4612: oldMods |= Event.ALT_MASK; 4613: 4614: if ((mods & InputEvent.SHIFT_DOWN_MASK) != 0) 4615: oldMods |= Event.SHIFT_MASK; 4616: 4617: if ((mods & InputEvent.CTRL_DOWN_MASK) != 0) 4618: oldMods |= Event.CTRL_MASK; 4619: 4620: if ((mods & InputEvent.META_DOWN_MASK) != 0) 4621: oldMods |= Event.META_MASK; 4622: 4623: if ((mods & InputEvent.ALT_DOWN_MASK) != 0) 4624: oldMods |= Event.ALT_MASK; 4625: 4626: if (e instanceof MouseEvent) 4627: { 4628: if (id == MouseEvent.MOUSE_PRESSED) 4629: oldID = Event.MOUSE_DOWN; 4630: else if (id == MouseEvent.MOUSE_RELEASED) 4631: oldID = Event.MOUSE_UP; 4632: else if (id == MouseEvent.MOUSE_MOVED) 4633: oldID = Event.MOUSE_MOVE; 4634: else if (id == MouseEvent.MOUSE_DRAGGED) 4635: oldID = Event.MOUSE_DRAG; 4636: else if (id == MouseEvent.MOUSE_ENTERED) 4637: oldID = Event.MOUSE_ENTER; 4638: else if (id == MouseEvent.MOUSE_EXITED) 4639: oldID = Event.MOUSE_EXIT; 4640: else 4641: // No analogous AWT 1.0 mouse event. 4642: return null; 4643: 4644: MouseEvent me = (MouseEvent) e; 4645: 4646: translated = new Event (target, when, oldID, 4647: me.getX (), me.getY (), 0, oldMods); 4648: } 4649: else if (e instanceof KeyEvent) 4650: { 4651: if (id == KeyEvent.KEY_PRESSED) 4652: oldID = Event.KEY_PRESS; 4653: else if (e.getID () == KeyEvent.KEY_RELEASED) 4654: oldID = Event.KEY_RELEASE; 4655: else 4656: // No analogous AWT 1.0 key event. 4657: return null; 4658: 4659: int oldKey = 0; 4660: int newKey = ((KeyEvent) e).getKeyCode (); 4661: switch (newKey) 4662: { 4663: case KeyEvent.VK_BACK_SPACE: 4664: oldKey = Event.BACK_SPACE; 4665: break; 4666: case KeyEvent.VK_CAPS_LOCK: 4667: oldKey = Event.CAPS_LOCK; 4668: break; 4669: case KeyEvent.VK_DELETE: 4670: oldKey = Event.DELETE; 4671: break; 4672: case KeyEvent.VK_DOWN: 4673: case KeyEvent.VK_KP_DOWN: 4674: oldKey = Event.DOWN; 4675: break; 4676: case KeyEvent.VK_END: 4677: oldKey = Event.END; 4678: break; 4679: case KeyEvent.VK_ENTER: 4680: oldKey = Event.ENTER; 4681: break; 4682: case KeyEvent.VK_ESCAPE: 4683: oldKey = Event.ESCAPE; 4684: break; 4685: case KeyEvent.VK_F1: 4686: oldKey = Event.F1; 4687: break; 4688: case KeyEvent.VK_F10: 4689: oldKey = Event.F10; 4690: break; 4691: case KeyEvent.VK_F11: 4692: oldKey = Event.F11; 4693: break; 4694: case KeyEvent.VK_F12: 4695: oldKey = Event.F12; 4696: break; 4697: case KeyEvent.VK_F2: 4698: oldKey = Event.F2; 4699: break; 4700: case KeyEvent.VK_F3: 4701: oldKey = Event.F3; 4702: break; 4703: case KeyEvent.VK_F4: 4704: oldKey = Event.F4; 4705: break; 4706: case KeyEvent.VK_F5: 4707: oldKey = Event.F5; 4708: break; 4709: case KeyEvent.VK_F6: 4710: oldKey = Event.F6; 4711: break; 4712: case KeyEvent.VK_F7: 4713: oldKey = Event.F7; 4714: break; 4715: case KeyEvent.VK_F8: 4716: oldKey = Event.F8; 4717: break; 4718: case KeyEvent.VK_F9: 4719: oldKey = Event.F9; 4720: break; 4721: case KeyEvent.VK_HOME: 4722: oldKey = Event.HOME; 4723: break; 4724: case KeyEvent.VK_INSERT: 4725: oldKey = Event.INSERT; 4726: break; 4727: case KeyEvent.VK_LEFT: 4728: case KeyEvent.VK_KP_LEFT: 4729: oldKey = Event.LEFT; 4730: break; 4731: case KeyEvent.VK_NUM_LOCK: 4732: oldKey = Event.NUM_LOCK; 4733: break; 4734: case KeyEvent.VK_PAUSE: 4735: oldKey = Event.PAUSE; 4736: break; 4737: case KeyEvent.VK_PAGE_DOWN: 4738: oldKey = Event.PGDN; 4739: break; 4740: case KeyEvent.VK_PAGE_UP: 4741: oldKey = Event.PGUP; 4742: break; 4743: case KeyEvent.VK_PRINTSCREEN: 4744: oldKey = Event.PRINT_SCREEN; 4745: break; 4746: case KeyEvent.VK_RIGHT: 4747: case KeyEvent.VK_KP_RIGHT: 4748: oldKey = Event.RIGHT; 4749: break; 4750: case KeyEvent.VK_SCROLL_LOCK: 4751: oldKey = Event.SCROLL_LOCK; 4752: break; 4753: case KeyEvent.VK_TAB: 4754: oldKey = Event.TAB; 4755: break; 4756: case KeyEvent.VK_UP: 4757: case KeyEvent.VK_KP_UP: 4758: oldKey = Event.UP; 4759: break; 4760: default: 4761: oldKey = newKey; 4762: } 4763: 4764: translated = new Event (target, when, oldID, 4765: 0, 0, oldKey, oldMods); 4766: } 4767: } 4768: else if (e instanceof ActionEvent) 4769: translated = new Event (target, Event.ACTION_EVENT, 4770: ((ActionEvent) e).getActionCommand ()); 4771: 4772: return translated; 4773: } 4774: 4775: /** 4776: * Implementation of dispatchEvent. Allows trusted package classes 4777: * to dispatch additional events first. This implementation first 4778: * translates <code>e</code> to an AWT 1.0 event and sends the 4779: * result to {@link #postEvent}. If the AWT 1.0 event is not 4780: * handled, and events of type <code>e</code> are enabled for this 4781: * component, e is passed on to {@link #processEvent}. 4782: * 4783: * @param e the event to dispatch 4784: */ 4785: 4786: void dispatchEventImpl(AWTEvent e) 4787: { 4788: Event oldEvent = translateEvent (e); 4789: 4790: if (oldEvent != null) 4791: postEvent (oldEvent); 4792: 4793: if (eventTypeEnabled (e.id)) 4794: { 4795: // the trick we use to communicate between dispatch and redispatch 4796: // is to have KeyboardFocusManager.redispatch synchronize on the 4797: // object itself. we then do not redispatch to KeyboardFocusManager 4798: // if we are already holding the lock. 4799: if (! Thread.holdsLock(e)) 4800: { 4801: switch (e.id) 4802: { 4803: case WindowEvent.WINDOW_GAINED_FOCUS: 4804: case WindowEvent.WINDOW_LOST_FOCUS: 4805: case KeyEvent.KEY_PRESSED: 4806: case KeyEvent.KEY_RELEASED: 4807: case KeyEvent.KEY_TYPED: 4808: case FocusEvent.FOCUS_GAINED: 4809: case FocusEvent.FOCUS_LOST: 4810: if (KeyboardFocusManager 4811: .getCurrentKeyboardFocusManager() 4812: .dispatchEvent(e)) 4813: return; 4814: case MouseEvent.MOUSE_PRESSED: 4815: if (isLightweight()) 4816: requestFocus(); 4817: break; 4818: } 4819: } 4820: if (e.id != PaintEvent.PAINT && e.id != PaintEvent.UPDATE) 4821: processEvent(e); 4822: } 4823: 4824: if (peer != null) 4825: peer.handleEvent(e); 4826: } 4827: 4828: /** 4829: * Tells whether or not an event type is enabled. 4830: */ 4831: boolean eventTypeEnabled (int type) 4832: { 4833: if (type > AWTEvent.RESERVED_ID_MAX) 4834: return true; 4835: 4836: switch (type) 4837: { 4838: case ComponentEvent.COMPONENT_HIDDEN: 4839: case ComponentEvent.COMPONENT_MOVED: 4840: case ComponentEvent.COMPONENT_RESIZED: 4841: case ComponentEvent.COMPONENT_SHOWN: 4842: return (componentListener != null 4843: || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0); 4844: 4845: case KeyEvent.KEY_PRESSED: 4846: case KeyEvent.KEY_RELEASED: 4847: case KeyEvent.KEY_TYPED: 4848: return (keyListener != null 4849: || (eventMask & AWTEvent.KEY_EVENT_MASK) != 0); 4850: 4851: case MouseEvent.MOUSE_CLICKED: 4852: case MouseEvent.MOUSE_ENTERED: 4853: case MouseEvent.MOUSE_EXITED: 4854: case MouseEvent.MOUSE_PRESSED: 4855: case MouseEvent.MOUSE_RELEASED: 4856: case MouseEvent.MOUSE_MOVED: 4857: case MouseEvent.MOUSE_DRAGGED: 4858: return (mouseListener != null 4859: || mouseMotionListener != null 4860: || (eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0); 4861: 4862: case FocusEvent.FOCUS_GAINED: 4863: case FocusEvent.FOCUS_LOST: 4864: return (focusListener != null 4865: || (eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0); 4866: 4867: case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED: 4868: case InputMethodEvent.CARET_POSITION_CHANGED: 4869: return (inputMethodListener != null 4870: || (eventMask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0); 4871: 4872: case PaintEvent.PAINT: 4873: case PaintEvent.UPDATE: 4874: return (eventMask & AWTEvent.PAINT_EVENT_MASK) != 0; 4875: 4876: default: 4877: return false; 4878: } 4879: } 4880: 4881: /** 4882: * Coalesce paint events. Current heuristic is: Merge if the union of 4883: * areas is less than twice that of the sum of the areas. The X server 4884: * tend to create a lot of paint events that are adjacent but not 4885: * overlapping. 4886: * 4887: * <pre> 4888: * +------+ 4889: * | +-----+ ...will be merged 4890: * | | | 4891: * | | | 4892: * +------+ | 4893: * +-----+ 4894: * 4895: * +---------------+--+ 4896: * | | | ...will not be merged 4897: * +---------------+ | 4898: * | | 4899: * | | 4900: * | | 4901: * | | 4902: * | | 4903: * +--+ 4904: * </pre> 4905: * 4906: * @param queuedEvent the first paint event 4907: * @param newEvent the second paint event 4908: * @return the combined paint event, or null 4909: */ 4910: private PaintEvent coalescePaintEvents(PaintEvent queuedEvent, 4911: PaintEvent newEvent) 4912: { 4913: Rectangle r1 = queuedEvent.getUpdateRect(); 4914: Rectangle r2 = newEvent.getUpdateRect(); 4915: Rectangle union = r1.union(r2); 4916: 4917: int r1a = r1.width * r1.height; 4918: int r2a = r2.width * r2.height; 4919: int ua = union.width * union.height; 4920: 4921: if (ua > (r1a+r2a)*2) 4922: return null; 4923: /* The 2 factor should maybe be reconsidered. Perhaps 3/2 4924: would be better? */ 4925: 4926: newEvent.setUpdateRect(union); 4927: return newEvent; 4928: } 4929: 4930: /** 4931: * This method is used to implement transferFocus(). CHILD is the child 4932: * making the request. This is overridden by Container; when called for an 4933: * ordinary component there is no child and so we always return null. 4934: * 4935: * FIXME: is this still needed, in light of focus traversal policies? 4936: * 4937: * @param child the component making the request 4938: * @return the next component to focus on 4939: */ 4940: Component findNextFocusComponent(Component child) 4941: { 4942: return null; 4943: } 4944: 4945: /** 4946: * Deserializes this component. This regenerates all serializable listeners 4947: * which were registered originally. 4948: * 4949: * @param s the stream to read from 4950: * @throws ClassNotFoundException if deserialization fails 4951: * @throws IOException if the stream fails 4952: */ 4953: private void readObject(ObjectInputStream s) 4954: throws ClassNotFoundException, IOException 4955: { 4956: s.defaultReadObject(); 4957: String key = (String) s.readObject(); 4958: while (key != null) 4959: { 4960: Object listener = s.readObject(); 4961: if ("componentL".equals(key)) 4962: addComponentListener((ComponentListener) listener); 4963: else if ("focusL".equals(key)) 4964: addFocusListener((FocusListener) listener); 4965: else if ("keyL".equals(key)) 4966: addKeyListener((KeyListener) listener); 4967: else if ("mouseL".equals(key)) 4968: addMouseListener((MouseListener) listener); 4969: else if ("mouseMotionL".equals(key)) 4970: addMouseMotionListener((MouseMotionListener) listener); 4971: else if ("inputMethodL".equals(key)) 4972: addInputMethodListener((InputMethodListener) listener); 4973: else if ("hierarchyL".equals(key)) 4974: addHierarchyListener((HierarchyListener) listener); 4975: else if ("hierarchyBoundsL".equals(key)) 4976: addHierarchyBoundsListener((HierarchyBoundsListener) listener); 4977: else if ("mouseWheelL".equals(key)) 4978: addMouseWheelListener((MouseWheelListener) listener); 4979: key = (String) s.readObject(); 4980: } 4981: } 4982: 4983: /** 4984: * Serializes this component. This ignores all listeners which do not 4985: * implement Serializable, but includes those that do. 4986: * 4987: * @param s the stream to write to 4988: * @throws IOException if the stream fails 4989: */ 4990: private void writeObject(ObjectOutputStream s) throws IOException 4991: { 4992: s.defaultWriteObject(); 4993: AWTEventMulticaster.save(s, "componentL", componentListener); 4994: AWTEventMulticaster.save(s, "focusL", focusListener); 4995: AWTEventMulticaster.save(s, "keyL", keyListener); 4996: AWTEventMulticaster.save(s, "mouseL", mouseListener); 4997: AWTEventMulticaster.save(s, "mouseMotionL", mouseMotionListener); 4998: AWTEventMulticaster.save(s, "inputMethodL", inputMethodListener); 4999: AWTEventMulticaster.save(s, "hierarchyL", hierarchyListener); 5000: AWTEventMulticaster.save(s, "hierarchyBoundsL", hierarchyBoundsListener); 5001: AWTEventMulticaster.save(s, "mouseWheelL", mouseWheelListener); 5002: s.writeObject(null); 5003: } 5004: 5005: 5006: // Nested classes. 5007: 5008: /** 5009: * This class provides accessibility support for subclasses of container. 5010: * 5011: * @author Eric Blake (ebb9@email.byu.edu) 5012: * @since 1.3 5013: * @status updated to 1.4 5014: */ 5015: protected abstract class AccessibleAWTComponent extends AccessibleContext 5016: implements Serializable, AccessibleComponent 5017: { 5018: /** 5019: * Compatible with JDK 1.3+. 5020: */ 5021: private static final long serialVersionUID = 642321655757800191L; 5022: 5023: /** 5024: * Converts show/hide events to PropertyChange events, and is registered 5025: * as a component listener on this component. 5026: * 5027: * @serial the component handler 5028: */ 5029: protected ComponentListener accessibleAWTComponentHandler 5030: = new AccessibleAWTComponentHandler(); 5031: 5032: /** 5033: * Converts focus events to PropertyChange events, and is registered 5034: * as a focus listener on this component. 5035: * 5036: * @serial the focus handler 5037: */ 5038: protected FocusListener accessibleAWTFocusHandler 5039: = new AccessibleAWTFocusHandler(); 5040: 5041: /** 5042: * The default constructor. 5043: */ 5044: protected AccessibleAWTComponent() 5045: { 5046: Component.this.addComponentListener(accessibleAWTComponentHandler); 5047: Component.this.addFocusListener(accessibleAWTFocusHandler); 5048: } 5049: 5050: /** 5051: * Adds a global property change listener to the accessible component. 5052: * 5053: * @param l the listener to add 5054: * @see #ACCESSIBLE_NAME_PROPERTY 5055: * @see #ACCESSIBLE_DESCRIPTION_PROPERTY 5056: * @see #ACCESSIBLE_STATE_PROPERTY 5057: * @see #ACCESSIBLE_VALUE_PROPERTY 5058: * @see #ACCESSIBLE_SELECTION_PROPERTY 5059: * @see #ACCESSIBLE_TEXT_PROPERTY 5060: * @see #ACCESSIBLE_VISIBLE_DATA_PROPERTY 5061: */ 5062: public void addPropertyChangeListener(PropertyChangeListener l) 5063: { 5064: Component.this.addPropertyChangeListener(l); 5065: super.addPropertyChangeListener(l); 5066: } 5067: 5068: /** 5069: * Removes a global property change listener from this accessible 5070: * component. 5071: * 5072: * @param l the listener to remove 5073: */ 5074: public void removePropertyChangeListener(PropertyChangeListener l) 5075: { 5076: Component.this.removePropertyChangeListener(l); 5077: super.removePropertyChangeListener(l); 5078: } 5079: 5080: /** 5081: * Returns the accessible name of this component. It is almost always 5082: * wrong to return getName(), since it is not localized. In fact, for 5083: * things like buttons, this should be the text of the button, not the 5084: * name of the object. The tooltip text might also be appropriate. 5085: * 5086: * @return the name 5087: * @see #setAccessibleName(String) 5088: */ 5089: public String getAccessibleName() 5090: { 5091: return accessibleName == null ? getName() : accessibleName; 5092: } 5093: 5094: /** 5095: * Returns a brief description of this accessible context. This should 5096: * be localized. 5097: * 5098: * @return a description of this component 5099: * @see #setAccessibleDescription(String) 5100: */ 5101: public String getAccessibleDescription() 5102: { 5103: return accessibleDescription; 5104: } 5105: 5106: /** 5107: * Returns the role of this component. 5108: * 5109: * @return the accessible role 5110: */ 5111: public AccessibleRole getAccessibleRole() 5112: { 5113: return AccessibleRole.AWT_COMPONENT; 5114: } 5115: 5116: /** 5117: * Returns a state set describing this component's state. 5118: * 5119: * @return a new state set 5120: * @see AccessibleState 5121: */ 5122: public AccessibleStateSet getAccessibleStateSet() 5123: { 5124: AccessibleStateSet s = new AccessibleStateSet(); 5125: if (Component.this.isEnabled()) 5126: s.add(AccessibleState.ENABLED); 5127: if (isFocusable()) 5128: s.add(AccessibleState.FOCUSABLE); 5129: if (isFocusOwner()) 5130: s.add(AccessibleState.FOCUSED); 5131: if (isOpaque()) 5132: s.add(AccessibleState.OPAQUE); 5133: if (Component.this.isShowing()) 5134: s.add(AccessibleState.SHOWING); 5135: if (Component.this.isVisible()) 5136: s.add(AccessibleState.VISIBLE); 5137: return s; 5138: } 5139: 5140: /** 5141: * Returns the parent of this component, if it is accessible. 5142: * 5143: * @return the accessible parent 5144: */ 5145: public Accessible getAccessibleParent() 5146: { 5147: if (accessibleParent == null) 5148: { 5149: Container parent = getParent(); 5150: accessibleParent = parent instanceof Accessible 5151: ? (Accessible) parent : null; 5152: } 5153: return accessibleParent; 5154: } 5155: 5156: /** 5157: * Returns the index of this component in its accessible parent. 5158: * 5159: * @return the index, or -1 if the parent is not accessible 5160: * @see #getAccessibleParent() 5161: */ 5162: public int getAccessibleIndexInParent() 5163: { 5164: if (getAccessibleParent() == null) 5165: return -1; 5166: AccessibleContext context 5167: = ((Component) accessibleParent).getAccessibleContext(); 5168: if (context == null) 5169: return -1; 5170: for (int i = context.getAccessibleChildrenCount(); --i >= 0; ) 5171: if (context.getAccessibleChild(i) == Component.this) 5172: return i; 5173: return -1; 5174: } 5175: 5176: /** 5177: * Returns the number of children of this component which implement 5178: * Accessible. Subclasses must override this if they can have children. 5179: * 5180: * @return the number of accessible children, default 0 5181: */ 5182: public int getAccessibleChildrenCount() 5183: { 5184: return 0; 5185: } 5186: 5187: /** 5188: * Returns the ith accessible child. Subclasses must override this if 5189: * they can have children. 5190: * 5191: * @return the ith accessible child, or null 5192: * @see #getAccessibleChildrenCount() 5193: */ 5194: public Accessible getAccessibleChild(int i) 5195: { 5196: return null; 5197: } 5198: 5199: /** 5200: * Returns the locale of this component. 5201: * 5202: * @return the locale 5203: * @throws IllegalComponentStateException if the locale is unknown 5204: */ 5205: public Locale getLocale() 5206: { 5207: return Component.this.getLocale(); 5208: } 5209: 5210: /** 5211: * Returns this, since it is an accessible component. 5212: * 5213: * @return the accessible component 5214: */ 5215: public AccessibleComponent getAccessibleComponent() 5216: { 5217: return this; 5218: } 5219: 5220: /** 5221: * Gets the background color. 5222: * 5223: * @return the background color 5224: * @see #setBackground(Color) 5225: */ 5226: public Color getBackground() 5227: { 5228: return Component.this.getBackground(); 5229: } 5230: 5231: /** 5232: * Sets the background color. 5233: * 5234: * @param c the background color 5235: * @see #getBackground() 5236: * @see #isOpaque() 5237: */ 5238: public void setBackground(Color c) 5239: { 5240: Component.this.setBackground(c); 5241: } 5242: 5243: /** 5244: * Gets the foreground color. 5245: * 5246: * @return the foreground color 5247: * @see #setForeground(Color) 5248: */ 5249: public Color getForeground() 5250: { 5251: return Component.this.getForeground(); 5252: } 5253: 5254: /** 5255: * Sets the foreground color. 5256: * 5257: * @param c the foreground color 5258: * @see #getForeground() 5259: */ 5260: public void setForeground(Color c) 5261: { 5262: Component.this.setForeground(c); 5263: } 5264: 5265: /** 5266: * Gets the cursor. 5267: * 5268: * @return the cursor 5269: * @see #setCursor(Cursor) 5270: */ 5271: public Cursor getCursor() 5272: { 5273: return Component.this.getCursor(); 5274: } 5275: 5276: /** 5277: * Sets the cursor. 5278: * 5279: * @param cursor the cursor 5280: * @see #getCursor() 5281: */ 5282: public void setCursor(Cursor cursor) 5283: { 5284: Component.this.setCursor(cursor); 5285: } 5286: 5287: /** 5288: * Gets the font. 5289: * 5290: * @return the font 5291: * @see #setFont(Font) 5292: */ 5293: public Font getFont() 5294: { 5295: return Component.this.getFont(); 5296: } 5297: 5298: /** 5299: * Sets the font. 5300: * 5301: * @param f the font 5302: * @see #getFont() 5303: */ 5304: public void setFont(Font f) 5305: { 5306: Component.this.setFont(f); 5307: } 5308: 5309: /** 5310: * Gets the font metrics for a font. 5311: * 5312: * @param f the font to look up 5313: * @return its metrics 5314: * @throws NullPointerException if f is null 5315: * @see #getFont() 5316: */ 5317: public FontMetrics getFontMetrics(Font f) 5318: { 5319: return Component.this.getFontMetrics(f); 5320: } 5321: 5322: /** 5323: * Tests if the component is enabled. 5324: * 5325: * @return true if the component is enabled 5326: * @see #setEnabled(boolean) 5327: * @see #getAccessibleStateSet() 5328: * @see AccessibleState#ENABLED 5329: */ 5330: public boolean isEnabled() 5331: { 5332: return Component.this.isEnabled(); 5333: } 5334: 5335: /** 5336: * Set whether the component is enabled. 5337: * 5338: * @param b the new enabled status 5339: * @see #isEnabled() 5340: */ 5341: public void setEnabled(boolean b) 5342: { 5343: Component.this.setEnabled(b); 5344: } 5345: 5346: /** 5347: * Test whether the component is visible (not necesarily showing). 5348: * 5349: * @return true if it is visible 5350: * @see #setVisible(boolean) 5351: * @see #getAccessibleStateSet() 5352: * @see AccessibleState#VISIBLE 5353: */ 5354: public boolean isVisible() 5355: { 5356: return Component.this.isVisible(); 5357: } 5358: 5359: /** 5360: * Sets the visibility of this component. 5361: * 5362: * @param b the desired visibility 5363: * @see #isVisible() 5364: */ 5365: public void setVisible(boolean b) 5366: { 5367: Component.this.setVisible(b); 5368: } 5369: 5370: /** 5371: * Tests if the component is showing. 5372: * 5373: * @return true if this is showing 5374: */ 5375: public boolean isShowing() 5376: { 5377: return Component.this.isShowing(); 5378: } 5379: 5380: /** 5381: * Tests if the point is contained in this component. 5382: * 5383: * @param p the point to check 5384: * @return true if it is contained 5385: * @throws NullPointerException if p is null 5386: */ 5387: public boolean contains(Point p) 5388: { 5389: return Component.this.contains(p.x, p.y); 5390: } 5391: 5392: /** 5393: * Returns the location of this object on the screen, or null if it is 5394: * not showing. 5395: * 5396: * @return the location relative to screen coordinates, if showing 5397: * @see #getBounds() 5398: * @see #getLocation() 5399: */ 5400: public Point getLocationOnScreen() 5401: { 5402: return Component.this.isShowing() ? Component.this.getLocationOnScreen() 5403: : null; 5404: } 5405: 5406: /** 5407: * Returns the location of this object relative to its parent's coordinate 5408: * system, or null if it is not showing. 5409: * 5410: * @return the location 5411: * @see #getBounds() 5412: * @see #getLocationOnScreen() 5413: */ 5414: public Point getLocation() 5415: { 5416: return Component.this.isShowing() ? Component.this.getLocation() : null; 5417: } 5418: 5419: /** 5420: * Sets the location of this relative to its parent's coordinate system. 5421: * 5422: * @param p the location 5423: * @throws NullPointerException if p is null 5424: * @see #getLocation() 5425: */ 5426: public void setLocation(Point p) 5427: { 5428: Component.this.setLocation(p.x, p.y); 5429: } 5430: 5431: /** 5432: * Gets the bounds of this component, or null if it is not on screen. 5433: * 5434: * @return the bounds 5435: * @see #contains(Point) 5436: * @see #setBounds(Rectangle) 5437: */ 5438: public Rectangle getBounds() 5439: { 5440: return Component.this.isShowing() ? Component.this.getBounds() : null; 5441: } 5442: 5443: /** 5444: * Sets the bounds of this component. 5445: * 5446: * @param r the bounds 5447: * @throws NullPointerException if r is null 5448: * @see #getBounds() 5449: */ 5450: public void setBounds(Rectangle r) 5451: { 5452: Component.this.setBounds(r.x, r.y, r.width, r.height); 5453: } 5454: 5455: /** 5456: * Gets the size of this component, or null if it is not showing. 5457: * 5458: * @return the size 5459: * @see #setSize(Dimension) 5460: */ 5461: public Dimension getSize() 5462: { 5463: return Component.this.isShowing() ? Component.this.getSize() : null; 5464: } 5465: 5466: /** 5467: * Sets the size of this component. 5468: * 5469: * @param d the size 5470: * @throws NullPointerException if d is null 5471: * @see #getSize() 5472: */ 5473: public void setSize(Dimension d) 5474: { 5475: Component.this.setSize(d.width, d.height); 5476: } 5477: 5478: /** 5479: * Returns the Accessible child at a point relative to the coordinate 5480: * system of this component, if one exists, or null. Since components 5481: * have no children, subclasses must override this to get anything besides 5482: * null. 5483: * 5484: * @param p the point to check 5485: * @return the accessible child at that point 5486: * @throws NullPointerException if p is null 5487: */ 5488: public Accessible getAccessibleAt(Point p) 5489: { 5490: return null; 5491: } 5492: 5493: /** 5494: * Tests whether this component can accept focus. 5495: * 5496: * @return true if this is focus traversable 5497: * @see #getAccessibleStateSet () 5498: * @see AccessibleState#FOCUSABLE 5499: * @see AccessibleState#FOCUSED 5500: */ 5501: public boolean isFocusTraversable () 5502: { 5503: return Component.this.isFocusTraversable (); 5504: } 5505: 5506: /** 5507: * Requests focus for this component. 5508: * 5509: * @see #isFocusTraversable () 5510: */ 5511: public void requestFocus () 5512: { 5513: Component.this.requestFocus (); 5514: } 5515: 5516: /** 5517: * Adds a focus listener. 5518: * 5519: * @param l the listener to add 5520: */ 5521: public void addFocusListener(FocusListener l) 5522: { 5523: Component.this.addFocusListener(l); 5524: } 5525: 5526: /** 5527: * Removes a focus listener. 5528: * 5529: * @param l the listener to remove 5530: */ 5531: public void removeFocusListener(FocusListener l) 5532: { 5533: Component.this.removeFocusListener(l); 5534: } 5535: 5536: /** 5537: * Converts component changes into property changes. 5538: * 5539: * @author Eric Blake (ebb9@email.byu.edu) 5540: * @since 1.3 5541: * @status updated to 1.4 5542: */ 5543: protected class AccessibleAWTComponentHandler implements ComponentListener 5544: { 5545: /** 5546: * Default constructor. 5547: */ 5548: protected AccessibleAWTComponentHandler() 5549: { 5550: // Nothing to do here. 5551: } 5552: 5553: /** 5554: * Convert a component hidden to a property change. 5555: * 5556: * @param e the event to convert 5557: */ 5558: public void componentHidden(ComponentEvent e) 5559: { 5560: AccessibleAWTComponent.this.firePropertyChange 5561: (ACCESSIBLE_STATE_PROPERTY, AccessibleState.VISIBLE, null); 5562: } 5563: 5564: /** 5565: * Convert a component shown to a property change. 5566: * 5567: * @param e the event to convert 5568: */ 5569: public void componentShown(ComponentEvent e) 5570: { 5571: AccessibleAWTComponent.this.firePropertyChange 5572: (ACCESSIBLE_STATE_PROPERTY, null, AccessibleState.VISIBLE); 5573: } 5574: 5575: /** 5576: * Moving a component does not affect properties. 5577: * 5578: * @param e ignored 5579: */ 5580: public void componentMoved(ComponentEvent e) 5581: { 5582: // Nothing to do here. 5583: } 5584: 5585: /** 5586: * Resizing a component does not affect properties. 5587: * 5588: * @param e ignored 5589: */ 5590: public void componentResized(ComponentEvent e) 5591: { 5592: // Nothing to do here. 5593: } 5594: } // class AccessibleAWTComponentHandler 5595: 5596: /** 5597: * Converts focus changes into property changes. 5598: * 5599: * @author Eric Blake (ebb9@email.byu.edu) 5600: * @since 1.3 5601: * @status updated to 1.4 5602: */ 5603: protected class AccessibleAWTFocusHandler implements FocusListener 5604: { 5605: /** 5606: * Default constructor. 5607: */ 5608: protected AccessibleAWTFocusHandler() 5609: { 5610: // Nothing to do here. 5611: } 5612: 5613: /** 5614: * Convert a focus gained to a property change. 5615: * 5616: * @param e the event to convert 5617: */ 5618: public void focusGained(FocusEvent e) 5619: { 5620: AccessibleAWTComponent.this.firePropertyChange 5621: (ACCESSIBLE_STATE_PROPERTY, null, AccessibleState.FOCUSED); 5622: } 5623: 5624: /** 5625: * Convert a focus lost to a property change. 5626: * 5627: * @param e the event to convert 5628: */ 5629: public void focusLost(FocusEvent e) 5630: { 5631: AccessibleAWTComponent.this.firePropertyChange 5632: (ACCESSIBLE_STATE_PROPERTY, AccessibleState.FOCUSED, null); 5633: } 5634: } // class AccessibleAWTComponentHandler 5635: } // class AccessibleAWTComponent 5636: 5637: /** 5638: * This class provides support for blitting offscreen surfaces to a 5639: * component. 5640: * 5641: * @see BufferStrategy 5642: * 5643: * @since 1.4 5644: */ 5645: protected class BltBufferStrategy extends BufferStrategy 5646: { 5647: /** 5648: * The capabilities of the image buffer. 5649: */ 5650: protected BufferCapabilities caps; 5651: 5652: /** 5653: * The back buffers used in this strategy. 5654: */ 5655: protected VolatileImage[] backBuffers; 5656: 5657: /** 5658: * Whether or not the image buffer resources are allocated and 5659: * ready to be drawn into. 5660: */ 5661: protected boolean validatedContents; 5662: 5663: /** 5664: * The width of the back buffers. 5665: */ 5666: protected int width; 5667: 5668: /** 5669: * The height of the back buffers. 5670: */ 5671: protected int height; 5672: 5673: /** 5674: * The front buffer. 5675: */ 5676: private VolatileImage frontBuffer; 5677: 5678: /** 5679: * Creates a blitting buffer strategy. 5680: * 5681: * @param numBuffers the number of buffers, including the front 5682: * buffer 5683: * @param caps the capabilities of this strategy 5684: */ 5685: protected BltBufferStrategy(int numBuffers, BufferCapabilities caps) 5686: { 5687: this.caps = caps; 5688: createBackBuffers(numBuffers - 1); 5689: width = getWidth(); 5690: height = getHeight(); 5691: } 5692: 5693: /** 5694: * Initializes the backBuffers field with an array of numBuffers 5695: * VolatileImages. 5696: * 5697: * @param numBuffers the number of backbuffers to create 5698: */ 5699: protected void createBackBuffers(int numBuffers) 5700: { 5701: GraphicsConfiguration c = 5702: GraphicsEnvironment.getLocalGraphicsEnvironment() 5703: .getDefaultScreenDevice().getDefaultConfiguration(); 5704: 5705: backBuffers = new VolatileImage[numBuffers]; 5706: 5707: for (int i = 0; i < numBuffers; i++) 5708: backBuffers[i] = c.createCompatibleVolatileImage(width, height); 5709: } 5710: 5711: /** 5712: * Retrieves the capabilities of this buffer strategy. 5713: * 5714: * @return the capabilities of this buffer strategy 5715: */ 5716: public BufferCapabilities getCapabilities() 5717: { 5718: return caps; 5719: } 5720: 5721: /** 5722: * Retrieves a graphics object that can be used to draw into this 5723: * strategy's image buffer. 5724: * 5725: * @return a graphics object 5726: */ 5727: public Graphics getDrawGraphics() 5728: { 5729: // Return the backmost buffer's graphics. 5730: return backBuffers[0].getGraphics(); 5731: } 5732: 5733: /** 5734: * Bring the contents of the back buffer to the front buffer. 5735: */ 5736: public void show() 5737: { 5738: GraphicsConfiguration c = 5739: GraphicsEnvironment.getLocalGraphicsEnvironment() 5740: .getDefaultScreenDevice().getDefaultConfiguration(); 5741: 5742: // draw the front buffer. 5743: getGraphics().drawImage(backBuffers[backBuffers.length - 1], 5744: width, height, null); 5745: 5746: BufferCapabilities.FlipContents f = getCapabilities().getFlipContents(); 5747: 5748: // blit the back buffers. 5749: for (int i = backBuffers.length - 1; i > 0 ; i--) 5750: backBuffers[i] = backBuffers[i - 1]; 5751: 5752: // create new backmost buffer. 5753: if (f == BufferCapabilities.FlipContents.UNDEFINED) 5754: backBuffers[0] = c.createCompatibleVolatileImage(width, height); 5755: 5756: // create new backmost buffer and clear it to the background 5757: // color. 5758: if (f == BufferCapabilities.FlipContents.BACKGROUND) 5759: { 5760: backBuffers[0] = c.createCompatibleVolatileImage(width, height); 5761: backBuffers[0].getGraphics().clearRect(0, 0, width, height); 5762: } 5763: 5764: // FIXME: set the backmost buffer to the prior contents of the 5765: // front buffer. How do we retrieve the contents of the front 5766: // buffer? 5767: // 5768: // if (f == BufferCapabilities.FlipContents.PRIOR) 5769: 5770: // set the backmost buffer to a copy of the new front buffer. 5771: if (f == BufferCapabilities.FlipContents.COPIED) 5772: backBuffers[0] = backBuffers[backBuffers.length - 1]; 5773: } 5774: 5775: /** 5776: * Re-create the image buffer resources if they've been lost. 5777: */ 5778: protected void revalidate() 5779: { 5780: GraphicsConfiguration c = 5781: GraphicsEnvironment.getLocalGraphicsEnvironment() 5782: .getDefaultScreenDevice().getDefaultConfiguration(); 5783: 5784: for (int i = 0; i < backBuffers.length; i++) 5785: { 5786: int result = backBuffers[i].validate(c); 5787: if (result == VolatileImage.IMAGE_INCOMPATIBLE) 5788: backBuffers[i] = c.createCompatibleVolatileImage(width, height); 5789: } 5790: validatedContents = true; 5791: } 5792: 5793: /** 5794: * Returns whether or not the image buffer resources have been 5795: * lost. 5796: * 5797: * @return true if the resources have been lost, false otherwise 5798: */ 5799: public boolean contentsLost() 5800: { 5801: for (int i = 0; i < backBuffers.length; i++) 5802: { 5803: if (backBuffers[i].contentsLost()) 5804: { 5805: validatedContents = false; 5806: return true; 5807: } 5808: } 5809: // we know that the buffer resources are valid now because we 5810: // just checked them 5811: validatedContents = true; 5812: return false; 5813: } 5814: 5815: /** 5816: * Returns whether or not the image buffer resources have been 5817: * restored. 5818: * 5819: * @return true if the resources have been restored, false 5820: * otherwise 5821: */ 5822: public boolean contentsRestored() 5823: { 5824: GraphicsConfiguration c = 5825: GraphicsEnvironment.getLocalGraphicsEnvironment() 5826: .getDefaultScreenDevice().getDefaultConfiguration(); 5827: 5828: boolean imageRestored = false; 5829: 5830: for (int i = 0; i < backBuffers.length; i++) 5831: { 5832: int result = backBuffers[i].validate(c); 5833: if (result == VolatileImage.IMAGE_RESTORED) 5834: imageRestored = true; 5835: else if (result == VolatileImage.IMAGE_INCOMPATIBLE) 5836: return false; 5837: } 5838: // we know that the buffer resources are valid now because we 5839: // just checked them 5840: validatedContents = true; 5841: return imageRestored; 5842: } 5843: } 5844: 5845: /** 5846: * This class provides support for flipping component buffers. It 5847: * can only be used on Canvases and Windows. 5848: * 5849: * @since 1.4 5850: */ 5851: protected class FlipBufferStrategy extends BufferStrategy 5852: { 5853: /** 5854: * The number of buffers. 5855: */ 5856: protected int numBuffers; 5857: 5858: /** 5859: * The capabilities of this buffering strategy. 5860: */ 5861: protected BufferCapabilities caps; 5862: 5863: /** 5864: * An Image reference to the drawing buffer. 5865: */ 5866: protected Image drawBuffer; 5867: 5868: /** 5869: * A VolatileImage reference to the drawing buffer. 5870: */ 5871: protected VolatileImage drawVBuffer; 5872: 5873: /** 5874: * Whether or not the image buffer resources are allocated and 5875: * ready to be drawn into. 5876: */ 5877: protected boolean validatedContents; 5878: 5879: /** 5880: * The width of the back buffer. 5881: */ 5882: private int width; 5883: 5884: /** 5885: * The height of the back buffer. 5886: */ 5887: private int height; 5888: 5889: /** 5890: * Creates a flipping buffer strategy. The only supported 5891: * strategy for FlipBufferStrategy itself is a double-buffer page 5892: * flipping strategy. It forms the basis for more complex derived 5893: * strategies. 5894: * 5895: * @param numBuffers the number of buffers 5896: * @param caps the capabilities of this buffering strategy 5897: * 5898: * @throws AWTException if the requested 5899: * number-of-buffers/capabilities combination is not supported 5900: */ 5901: protected FlipBufferStrategy(int numBuffers, BufferCapabilities caps) 5902: throws AWTException 5903: { 5904: this.caps = caps; 5905: width = getWidth(); 5906: height = getHeight(); 5907: 5908: if (numBuffers > 1) 5909: createBuffers(numBuffers, caps); 5910: else 5911: { 5912: drawVBuffer = peer.createVolatileImage(width, height); 5913: drawBuffer = drawVBuffer; 5914: } 5915: } 5916: 5917: /** 5918: * Creates a multi-buffer flipping strategy. The number of 5919: * buffers must be greater than one and the buffer capabilities 5920: * must specify page flipping. 5921: * 5922: * @param numBuffers the number of flipping buffers; must be 5923: * greater than one 5924: * @param caps the buffering capabilities; caps.isPageFlipping() 5925: * must return true 5926: * 5927: * @throws IllegalArgumentException if numBuffers is not greater 5928: * than one or if the page flipping capability is not requested 5929: * 5930: * @throws AWTException if the requested flipping strategy is not 5931: * supported 5932: */ 5933: protected void createBuffers(int numBuffers, BufferCapabilities caps) 5934: throws AWTException 5935: { 5936: if (numBuffers <= 1) 5937: throw new IllegalArgumentException("FlipBufferStrategy.createBuffers:" 5938: + " numBuffers must be greater than" 5939: + " one."); 5940: 5941: if (!caps.isPageFlipping()) 5942: throw new IllegalArgumentException("FlipBufferStrategy.createBuffers:" 5943: + " flipping must be a specified" 5944: + " capability."); 5945: 5946: peer.createBuffers(numBuffers, caps); 5947: } 5948: 5949: /** 5950: * Return a direct reference to the back buffer image. 5951: * 5952: * @return a direct reference to the back buffer image. 5953: */ 5954: protected Image getBackBuffer() 5955: { 5956: return peer.getBackBuffer(); 5957: } 5958: 5959: /** 5960: * Perform a flip operation to transfer the contents of the back 5961: * buffer to the front buffer. 5962: */ 5963: protected void flip(BufferCapabilities.FlipContents flipAction) 5964: { 5965: peer.flip(flipAction); 5966: } 5967: 5968: /** 5969: * Release the back buffer's resources. 5970: */ 5971: protected void destroyBuffers() 5972: { 5973: peer.destroyBuffers(); 5974: } 5975: 5976: /** 5977: * Retrieves the capabilities of this buffer strategy. 5978: * 5979: * @return the capabilities of this buffer strategy 5980: */ 5981: public BufferCapabilities getCapabilities() 5982: { 5983: return caps; 5984: } 5985: 5986: /** 5987: * Retrieves a graphics object that can be used to draw into this 5988: * strategy's image buffer. 5989: * 5990: * @return a graphics object 5991: */ 5992: public Graphics getDrawGraphics() 5993: { 5994: return drawVBuffer.getGraphics(); 5995: } 5996: 5997: /** 5998: * Re-create the image buffer resources if they've been lost. 5999: */ 6000: protected void revalidate() 6001: { 6002: GraphicsConfiguration c = 6003: GraphicsEnvironment.getLocalGraphicsEnvironment() 6004: .getDefaultScreenDevice().getDefaultConfiguration(); 6005: 6006: if (drawVBuffer.validate(c) == VolatileImage.IMAGE_INCOMPATIBLE) 6007: drawVBuffer = peer.createVolatileImage(width, height); 6008: validatedContents = true; 6009: } 6010: 6011: /** 6012: * Returns whether or not the image buffer resources have been 6013: * lost. 6014: * 6015: * @return true if the resources have been lost, false otherwise 6016: */ 6017: public boolean contentsLost() 6018: { 6019: if (drawVBuffer.contentsLost()) 6020: { 6021: validatedContents = false; 6022: return true; 6023: } 6024: // we know that the buffer resources are valid now because we 6025: // just checked them 6026: validatedContents = true; 6027: return false; 6028: } 6029: 6030: /** 6031: * Returns whether or not the image buffer resources have been 6032: * restored. 6033: * 6034: * @return true if the resources have been restored, false 6035: * otherwise 6036: */ 6037: public boolean contentsRestored() 6038: { 6039: GraphicsConfiguration c = 6040: GraphicsEnvironment.getLocalGraphicsEnvironment() 6041: .getDefaultScreenDevice().getDefaultConfiguration(); 6042: 6043: int result = drawVBuffer.validate(c); 6044: 6045: boolean imageRestored = false; 6046: 6047: if (result == VolatileImage.IMAGE_RESTORED) 6048: imageRestored = true; 6049: else if (result == VolatileImage.IMAGE_INCOMPATIBLE) 6050: return false; 6051: 6052: // we know that the buffer resources are valid now because we 6053: // just checked them 6054: validatedContents = true; 6055: return imageRestored; 6056: } 6057: 6058: /** 6059: * Bring the contents of the back buffer to the front buffer. 6060: */ 6061: public void show() 6062: { 6063: flip(caps.getFlipContents()); 6064: } 6065: } 6066: }