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