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