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