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