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