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