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