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