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