1 /* 2 * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package java.awt; 26 27 import java.io.PrintStream; 28 import java.io.PrintWriter; 29 import java.util.Objects; 30 import java.util.Vector; 31 import java.util.Locale; 32 import java.util.EventListener; 33 import java.util.HashSet; 34 import java.util.Map; 35 import java.util.Set; 36 import java.util.Collections; 37 import java.awt.peer.ComponentPeer; 38 import java.awt.peer.ContainerPeer; 39 import java.awt.peer.LightweightPeer; 40 import java.awt.image.BufferStrategy; 41 import java.awt.image.ImageObserver; 42 import java.awt.image.ImageProducer; 43 import java.awt.image.ColorModel; 44 import java.awt.image.VolatileImage; 45 import java.awt.event.*; 46 import java.io.Serializable; 47 import java.io.ObjectOutputStream; 48 import java.io.ObjectInputStream; 49 import java.io.IOException; 50 import java.beans.PropertyChangeListener; 51 import java.beans.PropertyChangeSupport; 52 import java.beans.Transient; 53 import java.awt.im.InputContext; 54 import java.awt.im.InputMethodRequests; 55 import java.awt.dnd.DropTarget; 56 import java.lang.reflect.InvocationTargetException; 57 import java.lang.reflect.Method; 58 import java.security.AccessController; 59 import java.security.PrivilegedAction; 60 import java.security.AccessControlContext; 61 import javax.accessibility.*; 62 import java.applet.Applet; 63 64 import sun.security.action.GetPropertyAction; 65 import sun.awt.AppContext; 66 import sun.awt.AWTAccessor; 67 import sun.awt.ConstrainableGraphics; 68 import sun.awt.SubRegionShowable; 69 import sun.awt.SunToolkit; 70 import sun.awt.WindowClosingListener; 71 import sun.awt.CausedFocusEvent; 72 import sun.awt.EmbeddedFrame; 73 import sun.awt.dnd.SunDropTargetEvent; 74 import sun.awt.im.CompositionArea; 75 import sun.font.FontManager; 76 import sun.font.FontManagerFactory; 77 import sun.font.SunFontManager; 78 import sun.java2d.SunGraphics2D; 79 import sun.java2d.pipe.Region; 80 import sun.awt.image.VSyncedBSManager; 81 import sun.java2d.pipe.hw.ExtendedBufferCapabilities; 82 import static sun.java2d.pipe.hw.ExtendedBufferCapabilities.VSyncType.*; 83 import sun.awt.RequestFocusController; 84 import sun.java2d.SunGraphicsEnvironment; 85 import sun.util.logging.PlatformLogger; 86 87 /** 88 * A <em>component</em> is an object having a graphical representation 89 * that can be displayed on the screen and that can interact with the 90 * user. Examples of components are the buttons, checkboxes, and scrollbars 91 * of a typical graphical user interface. <p> 92 * The <code>Component</code> class is the abstract superclass of 93 * the nonmenu-related Abstract Window Toolkit components. Class 94 * <code>Component</code> can also be extended directly to create a 95 * lightweight component. A lightweight component is a component that is 96 * not associated with a native window. On the contrary, a heavyweight 97 * component is associated with a native window. The {@link #isLightweight()} 98 * method may be used to distinguish between the two kinds of the components. 99 * <p> 100 * Lightweight and heavyweight components may be mixed in a single component 101 * hierarchy. However, for correct operating of such a mixed hierarchy of 102 * components, the whole hierarchy must be valid. When the hierarchy gets 103 * invalidated, like after changing the bounds of components, or 104 * adding/removing components to/from containers, the whole hierarchy must be 105 * validated afterwards by means of the {@link Container#validate()} method 106 * invoked on the top-most invalid container of the hierarchy. 107 * 108 * <h3>Serialization</h3> 109 * It is important to note that only AWT listeners which conform 110 * to the <code>Serializable</code> protocol will be saved when 111 * the object is stored. If an AWT object has listeners that 112 * aren't marked serializable, they will be dropped at 113 * <code>writeObject</code> time. Developers will need, as always, 114 * to consider the implications of making an object serializable. 115 * One situation to watch out for is this: 116 * <pre> 117 * import java.awt.*; 118 * import java.awt.event.*; 119 * import java.io.Serializable; 120 * 121 * class MyApp implements ActionListener, Serializable 122 * { 123 * BigObjectThatShouldNotBeSerializedWithAButton bigOne; 124 * Button aButton = new Button(); 125 * 126 * MyApp() 127 * { 128 * // Oops, now aButton has a listener with a reference 129 * // to bigOne! 130 * aButton.addActionListener(this); 131 * } 132 * 133 * public void actionPerformed(ActionEvent e) 134 * { 135 * System.out.println("Hello There"); 136 * } 137 * } 138 * </pre> 139 * In this example, serializing <code>aButton</code> by itself 140 * will cause <code>MyApp</code> and everything it refers to 141 * to be serialized as well. The problem is that the listener 142 * is serializable by coincidence, not by design. To separate 143 * the decisions about <code>MyApp</code> and the 144 * <code>ActionListener</code> being serializable one can use a 145 * nested class, as in the following example: 146 * <pre> 147 * import java.awt.*; 148 * import java.awt.event.*; 149 * import java.io.Serializable; 150 * 151 * class MyApp implements java.io.Serializable 152 * { 153 * BigObjectThatShouldNotBeSerializedWithAButton bigOne; 154 * Button aButton = new Button(); 155 * 156 * static class MyActionListener implements ActionListener 157 * { 158 * public void actionPerformed(ActionEvent e) 159 * { 160 * System.out.println("Hello There"); 161 * } 162 * } 163 * 164 * MyApp() 165 * { 166 * aButton.addActionListener(new MyActionListener()); 167 * } 168 * } 169 * </pre> 170 * <p> 171 * <b>Note</b>: For more information on the paint mechanisms utilitized 172 * by AWT and Swing, including information on how to write the most 173 * efficient painting code, see 174 * <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>. 175 * <p> 176 * For details on the focus subsystem, see 177 * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> 178 * How to Use the Focus Subsystem</a>, 179 * a section in <em>The Java Tutorial</em>, and the 180 * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a> 181 * for more information. 182 * 183 * @author Arthur van Hoff 184 * @author Sami Shaio 185 */ 186 public abstract class Component implements ImageObserver, MenuContainer, 187 Serializable 188 { 189 190 private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.Component"); 191 private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.Component"); 192 private static final PlatformLogger focusLog = PlatformLogger.getLogger("java.awt.focus.Component"); 193 private static final PlatformLogger mixingLog = PlatformLogger.getLogger("java.awt.mixing.Component"); 194 195 /** 196 * The peer of the component. The peer implements the component's 197 * behavior. The peer is set when the <code>Component</code> is 198 * added to a container that also is a peer. 199 * @see #addNotify 200 * @see #removeNotify 201 */ 202 transient ComponentPeer peer; 203 204 /** 205 * The parent of the object. It may be <code>null</code> 206 * for top-level components. 207 * @see #getParent 208 */ 209 transient Container parent; 210 211 /** 212 * The <code>AppContext</code> of the component. Applets/Plugin may 213 * change the AppContext. 214 */ 215 transient AppContext appContext; 216 217 /** 218 * The x position of the component in the parent's coordinate system. 219 * 220 * @serial 221 * @see #getLocation 222 */ 223 int x; 224 225 /** 226 * The y position of the component in the parent's coordinate system. 227 * 228 * @serial 229 * @see #getLocation 230 */ 231 int y; 232 233 /** 234 * The width of the component. 235 * 236 * @serial 237 * @see #getSize 238 */ 239 int width; 240 241 /** 242 * The height of the component. 243 * 244 * @serial 245 * @see #getSize 246 */ 247 int height; 248 249 /** 250 * The foreground color for this component. 251 * <code>foreground</code> can be <code>null</code>. 252 * 253 * @serial 254 * @see #getForeground 255 * @see #setForeground 256 */ 257 Color foreground; 258 259 /** 260 * The background color for this component. 261 * <code>background</code> can be <code>null</code>. 262 * 263 * @serial 264 * @see #getBackground 265 * @see #setBackground 266 */ 267 Color background; 268 269 /** 270 * The font used by this component. 271 * The <code>font</code> can be <code>null</code>. 272 * 273 * @serial 274 * @see #getFont 275 * @see #setFont 276 */ 277 volatile Font font; 278 279 /** 280 * The font which the peer is currently using. 281 * (<code>null</code> if no peer exists.) 282 */ 283 Font peerFont; 284 285 /** 286 * The cursor displayed when pointer is over this component. 287 * This value can be <code>null</code>. 288 * 289 * @serial 290 * @see #getCursor 291 * @see #setCursor 292 */ 293 Cursor cursor; 294 295 /** 296 * The locale for the component. 297 * 298 * @serial 299 * @see #getLocale 300 * @see #setLocale 301 */ 302 Locale locale; 303 304 /** 305 * A reference to a <code>GraphicsConfiguration</code> object 306 * used to describe the characteristics of a graphics 307 * destination. 308 * This value can be <code>null</code>. 309 * 310 * @since 1.3 311 * @serial 312 * @see GraphicsConfiguration 313 * @see #getGraphicsConfiguration 314 */ 315 private transient volatile GraphicsConfiguration graphicsConfig; 316 317 /** 318 * A reference to a <code>BufferStrategy</code> object 319 * used to manipulate the buffers on this component. 320 * 321 * @since 1.4 322 * @see java.awt.image.BufferStrategy 323 * @see #getBufferStrategy() 324 */ 325 transient BufferStrategy bufferStrategy = null; 326 327 /** 328 * True when the object should ignore all repaint events. 329 * 330 * @since 1.4 331 * @serial 332 * @see #setIgnoreRepaint 333 * @see #getIgnoreRepaint 334 */ 335 boolean ignoreRepaint = false; 336 337 /** 338 * True when the object is visible. An object that is not 339 * visible is not drawn on the screen. 340 * 341 * @serial 342 * @see #isVisible 343 * @see #setVisible 344 */ 345 boolean visible = true; 346 347 /** 348 * True when the object is enabled. An object that is not 349 * enabled does not interact with the user. 350 * 351 * @serial 352 * @see #isEnabled 353 * @see #setEnabled 354 */ 355 boolean enabled = true; 356 357 /** 358 * True when the object is valid. An invalid object needs to 359 * be layed out. This flag is set to false when the object 360 * size is changed. 361 * 362 * @serial 363 * @see #isValid 364 * @see #validate 365 * @see #invalidate 366 */ 367 private volatile boolean valid = false; 368 369 /** 370 * The <code>DropTarget</code> associated with this component. 371 * 372 * @since 1.2 373 * @serial 374 * @see #setDropTarget 375 * @see #getDropTarget 376 */ 377 DropTarget dropTarget; 378 379 /** 380 * @serial 381 * @see #add 382 */ 383 Vector<PopupMenu> popups; 384 385 /** 386 * A component's name. 387 * This field can be <code>null</code>. 388 * 389 * @serial 390 * @see #getName 391 * @see #setName(String) 392 */ 393 private String name; 394 395 /** 396 * A bool to determine whether the name has 397 * been set explicitly. <code>nameExplicitlySet</code> will 398 * be false if the name has not been set and 399 * true if it has. 400 * 401 * @serial 402 * @see #getName 403 * @see #setName(String) 404 */ 405 private boolean nameExplicitlySet = false; 406 407 /** 408 * Indicates whether this Component can be focused. 409 * 410 * @serial 411 * @see #setFocusable 412 * @see #isFocusable 413 * @since 1.4 414 */ 415 private boolean focusable = true; 416 417 private static final int FOCUS_TRAVERSABLE_UNKNOWN = 0; 418 private static final int FOCUS_TRAVERSABLE_DEFAULT = 1; 419 private static final int FOCUS_TRAVERSABLE_SET = 2; 420 421 /** 422 * Tracks whether this Component is relying on default focus travesability. 423 * 424 * @serial 425 * @since 1.4 426 */ 427 private int isFocusTraversableOverridden = FOCUS_TRAVERSABLE_UNKNOWN; 428 429 /** 430 * The focus traversal keys. These keys will generate focus traversal 431 * behavior for Components for which focus traversal keys are enabled. If a 432 * value of null is specified for a traversal key, this Component inherits 433 * that traversal key from its parent. If all ancestors of this Component 434 * have null specified for that traversal key, then the current 435 * KeyboardFocusManager's default traversal key is used. 436 * 437 * @serial 438 * @see #setFocusTraversalKeys 439 * @see #getFocusTraversalKeys 440 * @since 1.4 441 */ 442 Set<AWTKeyStroke>[] focusTraversalKeys; 443 444 private static final String[] focusTraversalKeyPropertyNames = { 445 "forwardFocusTraversalKeys", 446 "backwardFocusTraversalKeys", 447 "upCycleFocusTraversalKeys", 448 "downCycleFocusTraversalKeys" 449 }; 450 451 /** 452 * Indicates whether focus traversal keys are enabled for this Component. 453 * Components for which focus traversal keys are disabled receive key 454 * events for focus traversal keys. Components for which focus traversal 455 * keys are enabled do not see these events; instead, the events are 456 * automatically converted to traversal operations. 457 * 458 * @serial 459 * @see #setFocusTraversalKeysEnabled 460 * @see #getFocusTraversalKeysEnabled 461 * @since 1.4 462 */ 463 private boolean focusTraversalKeysEnabled = true; 464 465 /** 466 * The locking object for AWT component-tree and layout operations. 467 * 468 * @see #getTreeLock 469 */ 470 static final Object LOCK = new AWTTreeLock(); 471 static class AWTTreeLock {} 472 473 /* 474 * The component's AccessControlContext. 475 */ 476 private transient volatile AccessControlContext acc = 477 AccessController.getContext(); 478 479 /** 480 * Minimum size. 481 * (This field perhaps should have been transient). 482 * 483 * @serial 484 */ 485 Dimension minSize; 486 487 /** 488 * Whether or not setMinimumSize has been invoked with a non-null value. 489 */ 490 boolean minSizeSet; 491 492 /** 493 * Preferred size. 494 * (This field perhaps should have been transient). 495 * 496 * @serial 497 */ 498 Dimension prefSize; 499 500 /** 501 * Whether or not setPreferredSize has been invoked with a non-null value. 502 */ 503 boolean prefSizeSet; 504 505 /** 506 * Maximum size 507 * 508 * @serial 509 */ 510 Dimension maxSize; 511 512 /** 513 * Whether or not setMaximumSize has been invoked with a non-null value. 514 */ 515 boolean maxSizeSet; 516 517 /** 518 * The orientation for this component. 519 * @see #getComponentOrientation 520 * @see #setComponentOrientation 521 */ 522 transient ComponentOrientation componentOrientation 523 = ComponentOrientation.UNKNOWN; 524 525 /** 526 * <code>newEventsOnly</code> will be true if the event is 527 * one of the event types enabled for the component. 528 * It will then allow for normal processing to 529 * continue. If it is false the event is passed 530 * to the component's parent and up the ancestor 531 * tree until the event has been consumed. 532 * 533 * @serial 534 * @see #dispatchEvent 535 */ 536 boolean newEventsOnly = false; 537 transient ComponentListener componentListener; 538 transient FocusListener focusListener; 539 transient HierarchyListener hierarchyListener; 540 transient HierarchyBoundsListener hierarchyBoundsListener; 541 transient KeyListener keyListener; 542 transient MouseListener mouseListener; 543 transient MouseMotionListener mouseMotionListener; 544 transient MouseWheelListener mouseWheelListener; 545 transient InputMethodListener inputMethodListener; 546 547 transient RuntimeException windowClosingException = null; 548 549 /** Internal, constants for serialization */ 550 final static String actionListenerK = "actionL"; 551 final static String adjustmentListenerK = "adjustmentL"; 552 final static String componentListenerK = "componentL"; 553 final static String containerListenerK = "containerL"; 554 final static String focusListenerK = "focusL"; 555 final static String itemListenerK = "itemL"; 556 final static String keyListenerK = "keyL"; 557 final static String mouseListenerK = "mouseL"; 558 final static String mouseMotionListenerK = "mouseMotionL"; 559 final static String mouseWheelListenerK = "mouseWheelL"; 560 final static String textListenerK = "textL"; 561 final static String ownedWindowK = "ownedL"; 562 final static String windowListenerK = "windowL"; 563 final static String inputMethodListenerK = "inputMethodL"; 564 final static String hierarchyListenerK = "hierarchyL"; 565 final static String hierarchyBoundsListenerK = "hierarchyBoundsL"; 566 final static String windowStateListenerK = "windowStateL"; 567 final static String windowFocusListenerK = "windowFocusL"; 568 569 /** 570 * The <code>eventMask</code> is ONLY set by subclasses via 571 * <code>enableEvents</code>. 572 * The mask should NOT be set when listeners are registered 573 * so that we can distinguish the difference between when 574 * listeners request events and subclasses request them. 575 * One bit is used to indicate whether input methods are 576 * enabled; this bit is set by <code>enableInputMethods</code> and is 577 * on by default. 578 * 579 * @serial 580 * @see #enableInputMethods 581 * @see AWTEvent 582 */ 583 long eventMask = AWTEvent.INPUT_METHODS_ENABLED_MASK; 584 585 /** 586 * Static properties for incremental drawing. 587 * @see #imageUpdate 588 */ 589 static boolean isInc; 590 static int incRate; 591 static { 592 /* ensure that the necessary native libraries are loaded */ Toolkit.loadLibraries()593 Toolkit.loadLibraries(); 594 /* initialize JNI field and method ids */ 595 if (!GraphicsEnvironment.isHeadless()) { initIDs()596 initIDs(); 597 } 598 599 String s = java.security.AccessController.doPrivileged( 600 new GetPropertyAction("awt.image.incrementaldraw")); 601 isInc = (s == null || s.equals("true")); 602 603 s = java.security.AccessController.doPrivileged( 604 new GetPropertyAction("awt.image.redrawrate")); 605 incRate = (s != null) ? Integer.parseInt(s) : 100; 606 } 607 608 /** 609 * Ease-of-use constant for <code>getAlignmentY()</code>. 610 * Specifies an alignment to the top of the component. 611 * @see #getAlignmentY 612 */ 613 public static final float TOP_ALIGNMENT = 0.0f; 614 615 /** 616 * Ease-of-use constant for <code>getAlignmentY</code> and 617 * <code>getAlignmentX</code>. Specifies an alignment to 618 * the center of the component 619 * @see #getAlignmentX 620 * @see #getAlignmentY 621 */ 622 public static final float CENTER_ALIGNMENT = 0.5f; 623 624 /** 625 * Ease-of-use constant for <code>getAlignmentY</code>. 626 * Specifies an alignment to the bottom of the component. 627 * @see #getAlignmentY 628 */ 629 public static final float BOTTOM_ALIGNMENT = 1.0f; 630 631 /** 632 * Ease-of-use constant for <code>getAlignmentX</code>. 633 * Specifies an alignment to the left side of the component. 634 * @see #getAlignmentX 635 */ 636 public static final float LEFT_ALIGNMENT = 0.0f; 637 638 /** 639 * Ease-of-use constant for <code>getAlignmentX</code>. 640 * Specifies an alignment to the right side of the component. 641 * @see #getAlignmentX 642 */ 643 public static final float RIGHT_ALIGNMENT = 1.0f; 644 645 /* 646 * JDK 1.1 serialVersionUID 647 */ 648 private static final long serialVersionUID = -7644114512714619750L; 649 650 /** 651 * If any <code>PropertyChangeListeners</code> have been registered, 652 * the <code>changeSupport</code> field describes them. 653 * 654 * @serial 655 * @since 1.2 656 * @see #addPropertyChangeListener 657 * @see #removePropertyChangeListener 658 * @see #firePropertyChange 659 */ 660 private PropertyChangeSupport changeSupport; 661 662 /* 663 * In some cases using "this" as an object to synchronize by 664 * can lead to a deadlock if client code also uses synchronization 665 * by a component object. For every such situation revealed we should 666 * consider possibility of replacing "this" with the package private 667 * objectLock object introduced below. So far there're 3 issues known: 668 * - CR 6708322 (the getName/setName methods); 669 * - CR 6608764 (the PropertyChangeListener machinery); 670 * - CR 7108598 (the Container.paint/KeyboardFocusManager.clearMostRecentFocusOwner methods). 671 * 672 * Note: this field is considered final, though readObject() prohibits 673 * initializing final fields. 674 */ 675 private transient Object objectLock = new Object(); getObjectLock()676 Object getObjectLock() { 677 return objectLock; 678 } 679 680 /* 681 * Returns the acc this component was constructed with. 682 */ getAccessControlContext()683 final AccessControlContext getAccessControlContext() { 684 if (acc == null) { 685 throw new SecurityException("Component is missing AccessControlContext"); 686 } 687 return acc; 688 } 689 690 boolean isPacked = false; 691 692 /** 693 * Pseudoparameter for direct Geometry API (setLocation, setBounds setSize 694 * to signal setBounds what's changing. Should be used under TreeLock. 695 * This is only needed due to the inability to change the cross-calling 696 * order of public and deprecated methods. 697 */ 698 private int boundsOp = ComponentPeer.DEFAULT_OPERATION; 699 700 /** 701 * Enumeration of the common ways the baseline of a component can 702 * change as the size changes. The baseline resize behavior is 703 * primarily for layout managers that need to know how the 704 * position of the baseline changes as the component size changes. 705 * In general the baseline resize behavior will be valid for sizes 706 * greater than or equal to the minimum size (the actual minimum 707 * size; not a developer specified minimum size). For sizes 708 * smaller than the minimum size the baseline may change in a way 709 * other than the baseline resize behavior indicates. Similarly, 710 * as the size approaches <code>Integer.MAX_VALUE</code> and/or 711 * <code>Short.MAX_VALUE</code> the baseline may change in a way 712 * other than the baseline resize behavior indicates. 713 * 714 * @see #getBaselineResizeBehavior 715 * @see #getBaseline(int,int) 716 * @since 1.6 717 */ 718 public enum BaselineResizeBehavior { 719 /** 720 * Indicates the baseline remains fixed relative to the 721 * y-origin. That is, <code>getBaseline</code> returns 722 * the same value regardless of the height or width. For example, a 723 * <code>JLabel</code> containing non-empty text with a 724 * vertical alignment of <code>TOP</code> should have a 725 * baseline type of <code>CONSTANT_ASCENT</code>. 726 */ 727 CONSTANT_ASCENT, 728 729 /** 730 * Indicates the baseline remains fixed relative to the height 731 * and does not change as the width is varied. That is, for 732 * any height H the difference between H and 733 * <code>getBaseline(w, H)</code> is the same. For example, a 734 * <code>JLabel</code> containing non-empty text with a 735 * vertical alignment of <code>BOTTOM</code> should have a 736 * baseline type of <code>CONSTANT_DESCENT</code>. 737 */ 738 CONSTANT_DESCENT, 739 740 /** 741 * Indicates the baseline remains a fixed distance from 742 * the center of the component. That is, for any height H the 743 * difference between <code>getBaseline(w, H)</code> and 744 * <code>H / 2</code> is the same (plus or minus one depending upon 745 * rounding error). 746 * <p> 747 * Because of possible rounding errors it is recommended 748 * you ask for the baseline with two consecutive heights and use 749 * the return value to determine if you need to pad calculations 750 * by 1. The following shows how to calculate the baseline for 751 * any height: 752 * <pre> 753 * Dimension preferredSize = component.getPreferredSize(); 754 * int baseline = getBaseline(preferredSize.width, 755 * preferredSize.height); 756 * int nextBaseline = getBaseline(preferredSize.width, 757 * preferredSize.height + 1); 758 * // Amount to add to height when calculating where baseline 759 * // lands for a particular height: 760 * int padding = 0; 761 * // Where the baseline is relative to the mid point 762 * int baselineOffset = baseline - height / 2; 763 * if (preferredSize.height % 2 == 0 && 764 * baseline != nextBaseline) { 765 * padding = 1; 766 * } 767 * else if (preferredSize.height % 2 == 1 && 768 * baseline == nextBaseline) { 769 * baselineOffset--; 770 * padding = 1; 771 * } 772 * // The following calculates where the baseline lands for 773 * // the height z: 774 * int calculatedBaseline = (z + padding) / 2 + baselineOffset; 775 * </pre> 776 */ 777 CENTER_OFFSET, 778 779 /** 780 * Indicates the baseline resize behavior can not be expressed using 781 * any of the other constants. This may also indicate the baseline 782 * varies with the width of the component. This is also returned 783 * by components that do not have a baseline. 784 */ 785 OTHER 786 } 787 788 /* 789 * The shape set with the applyCompoundShape() method. It uncludes the result 790 * of the HW/LW mixing related shape computation. It may also include 791 * the user-specified shape of the component. 792 * The 'null' value means the component has normal shape (or has no shape at all) 793 * and applyCompoundShape() will skip the following shape identical to normal. 794 */ 795 private transient Region compoundShape = null; 796 797 /* 798 * Represents the shape of this lightweight component to be cut out from 799 * heavyweight components should they intersect. Possible values: 800 * 1. null - consider the shape rectangular 801 * 2. EMPTY_REGION - nothing gets cut out (children still get cut out) 802 * 3. non-empty - this shape gets cut out. 803 */ 804 private transient Region mixingCutoutRegion = null; 805 806 /* 807 * Indicates whether addNotify() is complete 808 * (i.e. the peer is created). 809 */ 810 private transient boolean isAddNotifyComplete = false; 811 812 /** 813 * Should only be used in subclass getBounds to check that part of bounds 814 * is actualy changing 815 */ getBoundsOp()816 int getBoundsOp() { 817 assert Thread.holdsLock(getTreeLock()); 818 return boundsOp; 819 } 820 setBoundsOp(int op)821 void setBoundsOp(int op) { 822 assert Thread.holdsLock(getTreeLock()); 823 if (op == ComponentPeer.RESET_OPERATION) { 824 boundsOp = ComponentPeer.DEFAULT_OPERATION; 825 } else 826 if (boundsOp == ComponentPeer.DEFAULT_OPERATION) { 827 boundsOp = op; 828 } 829 } 830 831 // Whether this Component has had the background erase flag 832 // specified via SunToolkit.disableBackgroundErase(). This is 833 // needed in order to make this function work on X11 platforms, 834 // where currently there is no chance to interpose on the creation 835 // of the peer and therefore the call to XSetBackground. 836 transient boolean backgroundEraseDisabled; 837 838 static { AWTAccessor.setComponentAccessor(new AWTAccessor.ComponentAccessor() { public void setBackgroundEraseDisabled(Component comp, boolean disabled) { comp.backgroundEraseDisabled = disabled; } public boolean getBackgroundEraseDisabled(Component comp) { return comp.backgroundEraseDisabled; } public Rectangle getBounds(Component comp) { return new Rectangle(comp.x, comp.y, comp.width, comp.height); } public void setMixingCutoutShape(Component comp, Shape shape) { Region region = shape == null ? null : Region.getInstance(shape, null); synchronized (comp.getTreeLock()) { boolean needShowing = false; boolean needHiding = false; if (!comp.isNonOpaqueForMixing()) { needHiding = true; } comp.mixingCutoutRegion = region; if (!comp.isNonOpaqueForMixing()) { needShowing = true; } if (comp.isMixingNeeded()) { if (needHiding) { comp.mixOnHiding(comp.isLightweight()); } if (needShowing) { comp.mixOnShowing(); } } } } public void setGraphicsConfiguration(Component comp, GraphicsConfiguration gc) { comp.setGraphicsConfiguration(gc); } public boolean requestFocus(Component comp, CausedFocusEvent.Cause cause) { return comp.requestFocus(cause); } public boolean canBeFocusOwner(Component comp) { return comp.canBeFocusOwner(); } public boolean isVisible(Component comp) { return comp.isVisible_NoClientCode(); } public void setRequestFocusController (RequestFocusController requestController) { Component.setRequestFocusController(requestController); } public AppContext getAppContext(Component comp) { return comp.appContext; } public void setAppContext(Component comp, AppContext appContext) { comp.appContext = appContext; } public Container getParent(Component comp) { return comp.getParent_NoClientCode(); } public void setParent(Component comp, Container parent) { comp.parent = parent; } public void setSize(Component comp, int width, int height) { comp.width = width; comp.height = height; } public Point getLocation(Component comp) { return comp.location_NoClientCode(); } public void setLocation(Component comp, int x, int y) { comp.x = x; comp.y = y; } public boolean isEnabled(Component comp) { return comp.isEnabledImpl(); } public boolean isDisplayable(Component comp) { return comp.peer != null; } public Cursor getCursor(Component comp) { return comp.getCursor_NoClientCode(); } public ComponentPeer getPeer(Component comp) { return comp.peer; } public void setPeer(Component comp, ComponentPeer peer) { comp.peer = peer; } public boolean isLightweight(Component comp) { return (comp.peer instanceof LightweightPeer); } public boolean getIgnoreRepaint(Component comp) { return comp.ignoreRepaint; } public int getWidth(Component comp) { return comp.width; } public int getHeight(Component comp) { return comp.height; } public int getX(Component comp) { return comp.x; } public int getY(Component comp) { return comp.y; } public Color getForeground(Component comp) { return comp.foreground; } public Color getBackground(Component comp) { return comp.background; } public void setBackground(Component comp, Color background) { comp.background = background; } public Font getFont(Component comp) { return comp.getFont_NoClientCode(); } public void processEvent(Component comp, AWTEvent e) { comp.processEvent(e); } public AccessControlContext getAccessControlContext(Component comp) { return comp.getAccessControlContext(); } public void revalidateSynchronously(Component comp) { comp.revalidateSynchronously(); } })839 AWTAccessor.setComponentAccessor(new AWTAccessor.ComponentAccessor() { 840 public void setBackgroundEraseDisabled(Component comp, boolean disabled) { 841 comp.backgroundEraseDisabled = disabled; 842 } 843 public boolean getBackgroundEraseDisabled(Component comp) { 844 return comp.backgroundEraseDisabled; 845 } 846 public Rectangle getBounds(Component comp) { 847 return new Rectangle(comp.x, comp.y, comp.width, comp.height); 848 } 849 public void setMixingCutoutShape(Component comp, Shape shape) { 850 Region region = shape == null ? null : 851 Region.getInstance(shape, null); 852 853 synchronized (comp.getTreeLock()) { 854 boolean needShowing = false; 855 boolean needHiding = false; 856 857 if (!comp.isNonOpaqueForMixing()) { 858 needHiding = true; 859 } 860 861 comp.mixingCutoutRegion = region; 862 863 if (!comp.isNonOpaqueForMixing()) { 864 needShowing = true; 865 } 866 867 if (comp.isMixingNeeded()) { 868 if (needHiding) { 869 comp.mixOnHiding(comp.isLightweight()); 870 } 871 if (needShowing) { 872 comp.mixOnShowing(); 873 } 874 } 875 } 876 } 877 878 public void setGraphicsConfiguration(Component comp, 879 GraphicsConfiguration gc) 880 { 881 comp.setGraphicsConfiguration(gc); 882 } 883 public boolean requestFocus(Component comp, CausedFocusEvent.Cause cause) { 884 return comp.requestFocus(cause); 885 } 886 public boolean canBeFocusOwner(Component comp) { 887 return comp.canBeFocusOwner(); 888 } 889 890 public boolean isVisible(Component comp) { 891 return comp.isVisible_NoClientCode(); 892 } 893 public void setRequestFocusController 894 (RequestFocusController requestController) 895 { 896 Component.setRequestFocusController(requestController); 897 } 898 public AppContext getAppContext(Component comp) { 899 return comp.appContext; 900 } 901 public void setAppContext(Component comp, AppContext appContext) { 902 comp.appContext = appContext; 903 } 904 public Container getParent(Component comp) { 905 return comp.getParent_NoClientCode(); 906 } 907 public void setParent(Component comp, Container parent) { 908 comp.parent = parent; 909 } 910 public void setSize(Component comp, int width, int height) { 911 comp.width = width; 912 comp.height = height; 913 } 914 public Point getLocation(Component comp) { 915 return comp.location_NoClientCode(); 916 } 917 public void setLocation(Component comp, int x, int y) { 918 comp.x = x; 919 comp.y = y; 920 } 921 public boolean isEnabled(Component comp) { 922 return comp.isEnabledImpl(); 923 } 924 public boolean isDisplayable(Component comp) { 925 return comp.peer != null; 926 } 927 public Cursor getCursor(Component comp) { 928 return comp.getCursor_NoClientCode(); 929 } 930 public ComponentPeer getPeer(Component comp) { 931 return comp.peer; 932 } 933 public void setPeer(Component comp, ComponentPeer peer) { 934 comp.peer = peer; 935 } 936 public boolean isLightweight(Component comp) { 937 return (comp.peer instanceof LightweightPeer); 938 } 939 public boolean getIgnoreRepaint(Component comp) { 940 return comp.ignoreRepaint; 941 } 942 public int getWidth(Component comp) { 943 return comp.width; 944 } 945 public int getHeight(Component comp) { 946 return comp.height; 947 } 948 public int getX(Component comp) { 949 return comp.x; 950 } 951 public int getY(Component comp) { 952 return comp.y; 953 } 954 public Color getForeground(Component comp) { 955 return comp.foreground; 956 } 957 public Color getBackground(Component comp) { 958 return comp.background; 959 } 960 public void setBackground(Component comp, Color background) { 961 comp.background = background; 962 } 963 public Font getFont(Component comp) { 964 return comp.getFont_NoClientCode(); 965 } 966 public void processEvent(Component comp, AWTEvent e) { 967 comp.processEvent(e); 968 } 969 970 public AccessControlContext getAccessControlContext(Component comp) { 971 return comp.getAccessControlContext(); 972 } 973 974 public void revalidateSynchronously(Component comp) { 975 comp.revalidateSynchronously(); 976 } 977 }); 978 } 979 980 /** 981 * Constructs a new component. Class <code>Component</code> can be 982 * extended directly to create a lightweight component that does not 983 * utilize an opaque native window. A lightweight component must be 984 * hosted by a native container somewhere higher up in the component 985 * tree (for example, by a <code>Frame</code> object). 986 */ Component()987 protected Component() { 988 appContext = AppContext.getAppContext(); 989 } 990 991 @SuppressWarnings({"rawtypes", "unchecked"}) initializeFocusTraversalKeys()992 void initializeFocusTraversalKeys() { 993 focusTraversalKeys = new Set[3]; 994 } 995 996 /** 997 * Constructs a name for this component. Called by <code>getName</code> 998 * when the name is <code>null</code>. 999 */ constructComponentName()1000 String constructComponentName() { 1001 return null; // For strict compliance with prior platform versions, a Component 1002 // that doesn't set its name should return null from 1003 // getName() 1004 } 1005 1006 /** 1007 * Gets the name of the component. 1008 * @return this component's name 1009 * @see #setName 1010 * @since JDK1.1 1011 */ getName()1012 public String getName() { 1013 if (name == null && !nameExplicitlySet) { 1014 synchronized(getObjectLock()) { 1015 if (name == null && !nameExplicitlySet) 1016 name = constructComponentName(); 1017 } 1018 } 1019 return name; 1020 } 1021 1022 /** 1023 * Sets the name of the component to the specified string. 1024 * @param name the string that is to be this 1025 * component's name 1026 * @see #getName 1027 * @since JDK1.1 1028 */ setName(String name)1029 public void setName(String name) { 1030 String oldName; 1031 synchronized(getObjectLock()) { 1032 oldName = this.name; 1033 this.name = name; 1034 nameExplicitlySet = true; 1035 } 1036 firePropertyChange("name", oldName, name); 1037 } 1038 1039 /** 1040 * Gets the parent of this component. 1041 * @return the parent container of this component 1042 * @since JDK1.0 1043 */ getParent()1044 public Container getParent() { 1045 return getParent_NoClientCode(); 1046 } 1047 1048 // NOTE: This method may be called by privileged threads. 1049 // This functionality is implemented in a package-private method 1050 // to insure that it cannot be overridden by client subclasses. 1051 // DO NOT INVOKE CLIENT CODE ON THIS THREAD! getParent_NoClientCode()1052 final Container getParent_NoClientCode() { 1053 return parent; 1054 } 1055 1056 // This method is overridden in the Window class to return null, 1057 // because the parent field of the Window object contains 1058 // the owner of the window, not its parent. getContainer()1059 Container getContainer() { 1060 return getParent_NoClientCode(); 1061 } 1062 1063 /** 1064 * @deprecated As of JDK version 1.1, 1065 * programs should not directly manipulate peers; 1066 * replaced by <code>boolean isDisplayable()</code>. 1067 */ 1068 @Deprecated getPeer()1069 public ComponentPeer getPeer() { 1070 return peer; 1071 } 1072 1073 /** 1074 * Associate a <code>DropTarget</code> with this component. 1075 * The <code>Component</code> will receive drops only if it 1076 * is enabled. 1077 * 1078 * @see #isEnabled 1079 * @param dt The DropTarget 1080 */ 1081 setDropTarget(DropTarget dt)1082 public synchronized void setDropTarget(DropTarget dt) { 1083 if (dt == dropTarget || (dropTarget != null && dropTarget.equals(dt))) 1084 return; 1085 1086 DropTarget old; 1087 1088 if ((old = dropTarget) != null) { 1089 if (peer != null) dropTarget.removeNotify(peer); 1090 1091 DropTarget t = dropTarget; 1092 1093 dropTarget = null; 1094 1095 try { 1096 t.setComponent(null); 1097 } catch (IllegalArgumentException iae) { 1098 // ignore it. 1099 } 1100 } 1101 1102 // if we have a new one, and we have a peer, add it! 1103 1104 if ((dropTarget = dt) != null) { 1105 try { 1106 dropTarget.setComponent(this); 1107 if (peer != null) dropTarget.addNotify(peer); 1108 } catch (IllegalArgumentException iae) { 1109 if (old != null) { 1110 try { 1111 old.setComponent(this); 1112 if (peer != null) dropTarget.addNotify(peer); 1113 } catch (IllegalArgumentException iae1) { 1114 // ignore it! 1115 } 1116 } 1117 } 1118 } 1119 } 1120 1121 /** 1122 * Gets the <code>DropTarget</code> associated with this 1123 * <code>Component</code>. 1124 */ 1125 getDropTarget()1126 public synchronized DropTarget getDropTarget() { return dropTarget; } 1127 1128 /** 1129 * Gets the <code>GraphicsConfiguration</code> associated with this 1130 * <code>Component</code>. 1131 * If the <code>Component</code> has not been assigned a specific 1132 * <code>GraphicsConfiguration</code>, 1133 * the <code>GraphicsConfiguration</code> of the 1134 * <code>Component</code> object's top-level container is 1135 * returned. 1136 * If the <code>Component</code> has been created, but not yet added 1137 * to a <code>Container</code>, this method returns <code>null</code>. 1138 * 1139 * @return the <code>GraphicsConfiguration</code> used by this 1140 * <code>Component</code> or <code>null</code> 1141 * @since 1.3 1142 */ getGraphicsConfiguration()1143 public GraphicsConfiguration getGraphicsConfiguration() { 1144 return getGraphicsConfiguration_NoClientCode(); 1145 } 1146 getGraphicsConfiguration_NoClientCode()1147 final GraphicsConfiguration getGraphicsConfiguration_NoClientCode() { 1148 return graphicsConfig; 1149 } 1150 setGraphicsConfiguration(GraphicsConfiguration gc)1151 void setGraphicsConfiguration(GraphicsConfiguration gc) { 1152 synchronized(getTreeLock()) { 1153 if (updateGraphicsData(gc)) { 1154 removeNotify(); 1155 addNotify(); 1156 } 1157 } 1158 } 1159 updateGraphicsData(GraphicsConfiguration gc)1160 boolean updateGraphicsData(GraphicsConfiguration gc) { 1161 checkTreeLock(); 1162 1163 if (graphicsConfig == gc) { 1164 return false; 1165 } 1166 1167 graphicsConfig = gc; 1168 1169 ComponentPeer peer = getPeer(); 1170 if (peer != null) { 1171 return peer.updateGraphicsData(gc); 1172 } 1173 return false; 1174 } 1175 1176 /** 1177 * Checks that this component's <code>GraphicsDevice</code> 1178 * <code>idString</code> matches the string argument. 1179 */ checkGD(String stringID)1180 void checkGD(String stringID) { 1181 if (graphicsConfig != null) { 1182 if (!graphicsConfig.getDevice().getIDstring().equals(stringID)) { 1183 throw new IllegalArgumentException( 1184 "adding a container to a container on a different GraphicsDevice"); 1185 } 1186 } 1187 } 1188 1189 /** 1190 * Gets this component's locking object (the object that owns the thread 1191 * synchronization monitor) for AWT component-tree and layout 1192 * operations. 1193 * @return this component's locking object 1194 */ getTreeLock()1195 public final Object getTreeLock() { 1196 return LOCK; 1197 } 1198 checkTreeLock()1199 final void checkTreeLock() { 1200 if (!Thread.holdsLock(getTreeLock())) { 1201 throw new IllegalStateException("This function should be called while holding treeLock"); 1202 } 1203 } 1204 1205 /** 1206 * Gets the toolkit of this component. Note that 1207 * the frame that contains a component controls which 1208 * toolkit is used by that component. Therefore if the component 1209 * is moved from one frame to another, the toolkit it uses may change. 1210 * @return the toolkit of this component 1211 * @since JDK1.0 1212 */ getToolkit()1213 public Toolkit getToolkit() { 1214 return getToolkitImpl(); 1215 } 1216 1217 /* 1218 * This is called by the native code, so client code can't 1219 * be called on the toolkit thread. 1220 */ getToolkitImpl()1221 final Toolkit getToolkitImpl() { 1222 Container parent = this.parent; 1223 if (parent != null) { 1224 return parent.getToolkitImpl(); 1225 } 1226 return Toolkit.getDefaultToolkit(); 1227 } 1228 1229 /** 1230 * Determines whether this component is valid. A component is valid 1231 * when it is correctly sized and positioned within its parent 1232 * container and all its children are also valid. 1233 * In order to account for peers' size requirements, components are invalidated 1234 * before they are first shown on the screen. By the time the parent container 1235 * is fully realized, all its components will be valid. 1236 * @return <code>true</code> if the component is valid, <code>false</code> 1237 * otherwise 1238 * @see #validate 1239 * @see #invalidate 1240 * @since JDK1.0 1241 */ isValid()1242 public boolean isValid() { 1243 return (peer != null) && valid; 1244 } 1245 1246 /** 1247 * Determines whether this component is displayable. A component is 1248 * displayable when it is connected to a native screen resource. 1249 * <p> 1250 * A component is made displayable either when it is added to 1251 * a displayable containment hierarchy or when its containment 1252 * hierarchy is made displayable. 1253 * A containment hierarchy is made displayable when its ancestor 1254 * window is either packed or made visible. 1255 * <p> 1256 * A component is made undisplayable either when it is removed from 1257 * a displayable containment hierarchy or when its containment hierarchy 1258 * is made undisplayable. A containment hierarchy is made 1259 * undisplayable when its ancestor window is disposed. 1260 * 1261 * @return <code>true</code> if the component is displayable, 1262 * <code>false</code> otherwise 1263 * @see Container#add(Component) 1264 * @see Window#pack 1265 * @see Window#show 1266 * @see Container#remove(Component) 1267 * @see Window#dispose 1268 * @since 1.2 1269 */ isDisplayable()1270 public boolean isDisplayable() { 1271 return getPeer() != null; 1272 } 1273 1274 /** 1275 * Determines whether this component should be visible when its 1276 * parent is visible. Components are 1277 * initially visible, with the exception of top level components such 1278 * as <code>Frame</code> objects. 1279 * @return <code>true</code> if the component is visible, 1280 * <code>false</code> otherwise 1281 * @see #setVisible 1282 * @since JDK1.0 1283 */ 1284 @Transient isVisible()1285 public boolean isVisible() { 1286 return isVisible_NoClientCode(); 1287 } isVisible_NoClientCode()1288 final boolean isVisible_NoClientCode() { 1289 return visible; 1290 } 1291 1292 /** 1293 * Determines whether this component will be displayed on the screen. 1294 * @return <code>true</code> if the component and all of its ancestors 1295 * until a toplevel window or null parent are visible, 1296 * <code>false</code> otherwise 1297 */ isRecursivelyVisible()1298 boolean isRecursivelyVisible() { 1299 return visible && (parent == null || parent.isRecursivelyVisible()); 1300 } 1301 1302 /** 1303 * Determines the bounds of a visible part of the component relative to its 1304 * parent. 1305 * 1306 * @return the visible part of bounds 1307 */ getRecursivelyVisibleBounds()1308 private Rectangle getRecursivelyVisibleBounds() { 1309 final Component container = getContainer(); 1310 final Rectangle bounds = getBounds(); 1311 if (container == null) { 1312 // we are top level window or haven't a container, return our bounds 1313 return bounds; 1314 } 1315 // translate the container's bounds to our coordinate space 1316 final Rectangle parentsBounds = container.getRecursivelyVisibleBounds(); 1317 parentsBounds.setLocation(0, 0); 1318 return parentsBounds.intersection(bounds); 1319 } 1320 1321 /** 1322 * Translates absolute coordinates into coordinates in the coordinate 1323 * space of this component. 1324 */ pointRelativeToComponent(Point absolute)1325 Point pointRelativeToComponent(Point absolute) { 1326 Point compCoords = getLocationOnScreen(); 1327 return new Point(absolute.x - compCoords.x, 1328 absolute.y - compCoords.y); 1329 } 1330 1331 /** 1332 * Assuming that mouse location is stored in PointerInfo passed 1333 * to this method, it finds a Component that is in the same 1334 * Window as this Component and is located under the mouse pointer. 1335 * If no such Component exists, null is returned. 1336 * NOTE: this method should be called under the protection of 1337 * tree lock, as it is done in Component.getMousePosition() and 1338 * Container.getMousePosition(boolean). 1339 */ findUnderMouseInWindow(PointerInfo pi)1340 Component findUnderMouseInWindow(PointerInfo pi) { 1341 if (!isShowing()) { 1342 return null; 1343 } 1344 Window win = getContainingWindow(); 1345 if (!Toolkit.getDefaultToolkit().getMouseInfoPeer().isWindowUnderMouse(win)) { 1346 return null; 1347 } 1348 final boolean INCLUDE_DISABLED = true; 1349 Point relativeToWindow = win.pointRelativeToComponent(pi.getLocation()); 1350 Component inTheSameWindow = win.findComponentAt(relativeToWindow.x, 1351 relativeToWindow.y, 1352 INCLUDE_DISABLED); 1353 return inTheSameWindow; 1354 } 1355 1356 /** 1357 * Returns the position of the mouse pointer in this <code>Component</code>'s 1358 * coordinate space if the <code>Component</code> is directly under the mouse 1359 * pointer, otherwise returns <code>null</code>. 1360 * If the <code>Component</code> is not showing on the screen, this method 1361 * returns <code>null</code> even if the mouse pointer is above the area 1362 * where the <code>Component</code> would be displayed. 1363 * If the <code>Component</code> is partially or fully obscured by other 1364 * <code>Component</code>s or native windows, this method returns a non-null 1365 * value only if the mouse pointer is located above the unobscured part of the 1366 * <code>Component</code>. 1367 * <p> 1368 * For <code>Container</code>s it returns a non-null value if the mouse is 1369 * above the <code>Container</code> itself or above any of its descendants. 1370 * Use {@link Container#getMousePosition(boolean)} if you need to exclude children. 1371 * <p> 1372 * Sometimes the exact mouse coordinates are not important, and the only thing 1373 * that matters is whether a specific <code>Component</code> is under the mouse 1374 * pointer. If the return value of this method is <code>null</code>, mouse 1375 * pointer is not directly above the <code>Component</code>. 1376 * 1377 * @exception HeadlessException if GraphicsEnvironment.isHeadless() returns true 1378 * @see #isShowing 1379 * @see Container#getMousePosition 1380 * @return mouse coordinates relative to this <code>Component</code>, or null 1381 * @since 1.5 1382 */ getMousePosition()1383 public Point getMousePosition() throws HeadlessException { 1384 if (GraphicsEnvironment.isHeadless()) { 1385 throw new HeadlessException(); 1386 } 1387 1388 PointerInfo pi = java.security.AccessController.doPrivileged( 1389 new java.security.PrivilegedAction<PointerInfo>() { 1390 public PointerInfo run() { 1391 return MouseInfo.getPointerInfo(); 1392 } 1393 } 1394 ); 1395 1396 synchronized (getTreeLock()) { 1397 Component inTheSameWindow = findUnderMouseInWindow(pi); 1398 if (!isSameOrAncestorOf(inTheSameWindow, true)) { 1399 return null; 1400 } 1401 return pointRelativeToComponent(pi.getLocation()); 1402 } 1403 } 1404 1405 /** 1406 * Overridden in Container. Must be called under TreeLock. 1407 */ isSameOrAncestorOf(Component comp, boolean allowChildren)1408 boolean isSameOrAncestorOf(Component comp, boolean allowChildren) { 1409 return comp == this; 1410 } 1411 1412 /** 1413 * Determines whether this component is showing on screen. This means 1414 * that the component must be visible, and it must be in a container 1415 * that is visible and showing. 1416 * <p> 1417 * <strong>Note:</strong> sometimes there is no way to detect whether the 1418 * {@code Component} is actually visible to the user. This can happen when: 1419 * <ul> 1420 * <li>the component has been added to a visible {@code ScrollPane} but 1421 * the {@code Component} is not currently in the scroll pane's view port. 1422 * <li>the {@code Component} is obscured by another {@code Component} or 1423 * {@code Container}. 1424 * </ul> 1425 * @return <code>true</code> if the component is showing, 1426 * <code>false</code> otherwise 1427 * @see #setVisible 1428 * @since JDK1.0 1429 */ isShowing()1430 public boolean isShowing() { 1431 if (visible && (peer != null)) { 1432 Container parent = this.parent; 1433 return (parent == null) || parent.isShowing(); 1434 } 1435 return false; 1436 } 1437 1438 /** 1439 * Determines whether this component is enabled. An enabled component 1440 * can respond to user input and generate events. Components are 1441 * enabled initially by default. A component may be enabled or disabled by 1442 * calling its <code>setEnabled</code> method. 1443 * @return <code>true</code> if the component is enabled, 1444 * <code>false</code> otherwise 1445 * @see #setEnabled 1446 * @since JDK1.0 1447 */ isEnabled()1448 public boolean isEnabled() { 1449 return isEnabledImpl(); 1450 } 1451 1452 /* 1453 * This is called by the native code, so client code can't 1454 * be called on the toolkit thread. 1455 */ isEnabledImpl()1456 final boolean isEnabledImpl() { 1457 return enabled; 1458 } 1459 1460 /** 1461 * Enables or disables this component, depending on the value of the 1462 * parameter <code>b</code>. An enabled component can respond to user 1463 * input and generate events. Components are enabled initially by default. 1464 * 1465 * <p>Note: Disabling a lightweight component does not prevent it from 1466 * receiving MouseEvents. 1467 * <p>Note: Disabling a heavyweight container prevents all components 1468 * in this container from receiving any input events. But disabling a 1469 * lightweight container affects only this container. 1470 * 1471 * @param b If <code>true</code>, this component is 1472 * enabled; otherwise this component is disabled 1473 * @see #isEnabled 1474 * @see #isLightweight 1475 * @since JDK1.1 1476 */ setEnabled(boolean b)1477 public void setEnabled(boolean b) { 1478 enable(b); 1479 } 1480 1481 /** 1482 * @deprecated As of JDK version 1.1, 1483 * replaced by <code>setEnabled(boolean)</code>. 1484 */ 1485 @Deprecated enable()1486 public void enable() { 1487 if (!enabled) { 1488 synchronized (getTreeLock()) { 1489 enabled = true; 1490 ComponentPeer peer = this.peer; 1491 if (peer != null) { 1492 peer.setEnabled(true); 1493 if (visible && !getRecursivelyVisibleBounds().isEmpty()) { 1494 updateCursorImmediately(); 1495 } 1496 } 1497 } 1498 if (accessibleContext != null) { 1499 accessibleContext.firePropertyChange( 1500 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 1501 null, AccessibleState.ENABLED); 1502 } 1503 } 1504 } 1505 1506 /** 1507 * @deprecated As of JDK version 1.1, 1508 * replaced by <code>setEnabled(boolean)</code>. 1509 */ 1510 @Deprecated enable(boolean b)1511 public void enable(boolean b) { 1512 if (b) { 1513 enable(); 1514 } else { 1515 disable(); 1516 } 1517 } 1518 1519 /** 1520 * @deprecated As of JDK version 1.1, 1521 * replaced by <code>setEnabled(boolean)</code>. 1522 */ 1523 @Deprecated disable()1524 public void disable() { 1525 if (enabled) { 1526 KeyboardFocusManager.clearMostRecentFocusOwner(this); 1527 synchronized (getTreeLock()) { 1528 enabled = false; 1529 // A disabled lw container is allowed to contain a focus owner. 1530 if ((isFocusOwner() || (containsFocus() && !isLightweight())) && 1531 KeyboardFocusManager.isAutoFocusTransferEnabled()) 1532 { 1533 // Don't clear the global focus owner. If transferFocus 1534 // fails, we want the focus to stay on the disabled 1535 // Component so that keyboard traversal, et. al. still 1536 // makes sense to the user. 1537 transferFocus(false); 1538 } 1539 ComponentPeer peer = this.peer; 1540 if (peer != null) { 1541 peer.setEnabled(false); 1542 if (visible && !getRecursivelyVisibleBounds().isEmpty()) { 1543 updateCursorImmediately(); 1544 } 1545 } 1546 } 1547 if (accessibleContext != null) { 1548 accessibleContext.firePropertyChange( 1549 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 1550 null, AccessibleState.ENABLED); 1551 } 1552 } 1553 } 1554 1555 /** 1556 * Returns true if this component is painted to an offscreen image 1557 * ("buffer") that's copied to the screen later. Component 1558 * subclasses that support double buffering should override this 1559 * method to return true if double buffering is enabled. 1560 * 1561 * @return false by default 1562 */ isDoubleBuffered()1563 public boolean isDoubleBuffered() { 1564 return false; 1565 } 1566 1567 /** 1568 * Enables or disables input method support for this component. If input 1569 * method support is enabled and the component also processes key events, 1570 * incoming events are offered to 1571 * the current input method and will only be processed by the component or 1572 * dispatched to its listeners if the input method does not consume them. 1573 * By default, input method support is enabled. 1574 * 1575 * @param enable true to enable, false to disable 1576 * @see #processKeyEvent 1577 * @since 1.2 1578 */ enableInputMethods(boolean enable)1579 public void enableInputMethods(boolean enable) { 1580 if (enable) { 1581 if ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) 1582 return; 1583 1584 // If this component already has focus, then activate the 1585 // input method by dispatching a synthesized focus gained 1586 // event. 1587 if (isFocusOwner()) { 1588 InputContext inputContext = getInputContext(); 1589 if (inputContext != null) { 1590 FocusEvent focusGainedEvent = 1591 new FocusEvent(this, FocusEvent.FOCUS_GAINED); 1592 inputContext.dispatchEvent(focusGainedEvent); 1593 } 1594 } 1595 1596 eventMask |= AWTEvent.INPUT_METHODS_ENABLED_MASK; 1597 } else { 1598 if ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) { 1599 InputContext inputContext = getInputContext(); 1600 if (inputContext != null) { 1601 inputContext.endComposition(); 1602 inputContext.removeNotify(this); 1603 } 1604 } 1605 eventMask &= ~AWTEvent.INPUT_METHODS_ENABLED_MASK; 1606 } 1607 } 1608 1609 /** 1610 * Shows or hides this component depending on the value of parameter 1611 * <code>b</code>. 1612 * <p> 1613 * This method changes layout-related information, and therefore, 1614 * invalidates the component hierarchy. 1615 * 1616 * @param b if <code>true</code>, shows this component; 1617 * otherwise, hides this component 1618 * @see #isVisible 1619 * @see #invalidate 1620 * @since JDK1.1 1621 */ setVisible(boolean b)1622 public void setVisible(boolean b) { 1623 show(b); 1624 } 1625 1626 /** 1627 * @deprecated As of JDK version 1.1, 1628 * replaced by <code>setVisible(boolean)</code>. 1629 */ 1630 @Deprecated show()1631 public void show() { 1632 if (!visible) { 1633 synchronized (getTreeLock()) { 1634 visible = true; 1635 mixOnShowing(); 1636 ComponentPeer peer = this.peer; 1637 if (peer != null) { 1638 peer.setVisible(true); 1639 createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED, 1640 this, parent, 1641 HierarchyEvent.SHOWING_CHANGED, 1642 Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK)); 1643 if (peer instanceof LightweightPeer) { 1644 repaint(); 1645 } 1646 updateCursorImmediately(); 1647 } 1648 1649 if (componentListener != null || 1650 (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 || 1651 Toolkit.enabledOnToolkit(AWTEvent.COMPONENT_EVENT_MASK)) { 1652 ComponentEvent e = new ComponentEvent(this, 1653 ComponentEvent.COMPONENT_SHOWN); 1654 Toolkit.getEventQueue().postEvent(e); 1655 } 1656 } 1657 Container parent = this.parent; 1658 if (parent != null) { 1659 parent.invalidate(); 1660 } 1661 } 1662 } 1663 1664 /** 1665 * @deprecated As of JDK version 1.1, 1666 * replaced by <code>setVisible(boolean)</code>. 1667 */ 1668 @Deprecated show(boolean b)1669 public void show(boolean b) { 1670 if (b) { 1671 show(); 1672 } else { 1673 hide(); 1674 } 1675 } 1676 containsFocus()1677 boolean containsFocus() { 1678 return isFocusOwner(); 1679 } 1680 clearMostRecentFocusOwnerOnHide()1681 void clearMostRecentFocusOwnerOnHide() { 1682 KeyboardFocusManager.clearMostRecentFocusOwner(this); 1683 } 1684 clearCurrentFocusCycleRootOnHide()1685 void clearCurrentFocusCycleRootOnHide() { 1686 /* do nothing */ 1687 } 1688 1689 /** 1690 * @deprecated As of JDK version 1.1, 1691 * replaced by <code>setVisible(boolean)</code>. 1692 */ 1693 @Deprecated hide()1694 public void hide() { 1695 isPacked = false; 1696 1697 if (visible) { 1698 clearCurrentFocusCycleRootOnHide(); 1699 clearMostRecentFocusOwnerOnHide(); 1700 synchronized (getTreeLock()) { 1701 visible = false; 1702 mixOnHiding(isLightweight()); 1703 if (containsFocus() && KeyboardFocusManager.isAutoFocusTransferEnabled()) { 1704 transferFocus(true); 1705 } 1706 ComponentPeer peer = this.peer; 1707 if (peer != null) { 1708 peer.setVisible(false); 1709 createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED, 1710 this, parent, 1711 HierarchyEvent.SHOWING_CHANGED, 1712 Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK)); 1713 if (peer instanceof LightweightPeer) { 1714 repaint(); 1715 } 1716 updateCursorImmediately(); 1717 } 1718 if (componentListener != null || 1719 (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 || 1720 Toolkit.enabledOnToolkit(AWTEvent.COMPONENT_EVENT_MASK)) { 1721 ComponentEvent e = new ComponentEvent(this, 1722 ComponentEvent.COMPONENT_HIDDEN); 1723 Toolkit.getEventQueue().postEvent(e); 1724 } 1725 } 1726 Container parent = this.parent; 1727 if (parent != null) { 1728 parent.invalidate(); 1729 } 1730 } 1731 } 1732 1733 /** 1734 * Gets the foreground color of this component. 1735 * @return this component's foreground color; if this component does 1736 * not have a foreground color, the foreground color of its parent 1737 * is returned 1738 * @see #setForeground 1739 * @since JDK1.0 1740 * @beaninfo 1741 * bound: true 1742 */ 1743 @Transient getForeground()1744 public Color getForeground() { 1745 Color foreground = this.foreground; 1746 if (foreground != null) { 1747 return foreground; 1748 } 1749 Container parent = this.parent; 1750 return (parent != null) ? parent.getForeground() : null; 1751 } 1752 1753 /** 1754 * Sets the foreground color of this component. 1755 * @param c the color to become this component's 1756 * foreground color; if this parameter is <code>null</code> 1757 * then this component will inherit 1758 * the foreground color of its parent 1759 * @see #getForeground 1760 * @since JDK1.0 1761 */ setForeground(Color c)1762 public void setForeground(Color c) { 1763 Color oldColor = foreground; 1764 ComponentPeer peer = this.peer; 1765 foreground = c; 1766 if (peer != null) { 1767 c = getForeground(); 1768 if (c != null) { 1769 peer.setForeground(c); 1770 } 1771 } 1772 // This is a bound property, so report the change to 1773 // any registered listeners. (Cheap if there are none.) 1774 firePropertyChange("foreground", oldColor, c); 1775 } 1776 1777 /** 1778 * Returns whether the foreground color has been explicitly set for this 1779 * Component. If this method returns <code>false</code>, this Component is 1780 * inheriting its foreground color from an ancestor. 1781 * 1782 * @return <code>true</code> if the foreground color has been explicitly 1783 * set for this Component; <code>false</code> otherwise. 1784 * @since 1.4 1785 */ isForegroundSet()1786 public boolean isForegroundSet() { 1787 return (foreground != null); 1788 } 1789 1790 /** 1791 * Gets the background color of this component. 1792 * @return this component's background color; if this component does 1793 * not have a background color, 1794 * the background color of its parent is returned 1795 * @see #setBackground 1796 * @since JDK1.0 1797 */ 1798 @Transient getBackground()1799 public Color getBackground() { 1800 Color background = this.background; 1801 if (background != null) { 1802 return background; 1803 } 1804 Container parent = this.parent; 1805 return (parent != null) ? parent.getBackground() : null; 1806 } 1807 1808 /** 1809 * Sets the background color of this component. 1810 * <p> 1811 * The background color affects each component differently and the 1812 * parts of the component that are affected by the background color 1813 * may differ between operating systems. 1814 * 1815 * @param c the color to become this component's color; 1816 * if this parameter is <code>null</code>, then this 1817 * component will inherit the background color of its parent 1818 * @see #getBackground 1819 * @since JDK1.0 1820 * @beaninfo 1821 * bound: true 1822 */ setBackground(Color c)1823 public void setBackground(Color c) { 1824 Color oldColor = background; 1825 ComponentPeer peer = this.peer; 1826 background = c; 1827 if (peer != null) { 1828 c = getBackground(); 1829 if (c != null) { 1830 peer.setBackground(c); 1831 } 1832 } 1833 // This is a bound property, so report the change to 1834 // any registered listeners. (Cheap if there are none.) 1835 firePropertyChange("background", oldColor, c); 1836 } 1837 1838 /** 1839 * Returns whether the background color has been explicitly set for this 1840 * Component. If this method returns <code>false</code>, this Component is 1841 * inheriting its background color from an ancestor. 1842 * 1843 * @return <code>true</code> if the background color has been explicitly 1844 * set for this Component; <code>false</code> otherwise. 1845 * @since 1.4 1846 */ isBackgroundSet()1847 public boolean isBackgroundSet() { 1848 return (background != null); 1849 } 1850 1851 /** 1852 * Gets the font of this component. 1853 * @return this component's font; if a font has not been set 1854 * for this component, the font of its parent is returned 1855 * @see #setFont 1856 * @since JDK1.0 1857 */ 1858 @Transient getFont()1859 public Font getFont() { 1860 return getFont_NoClientCode(); 1861 } 1862 1863 // NOTE: This method may be called by privileged threads. 1864 // This functionality is implemented in a package-private method 1865 // to insure that it cannot be overridden by client subclasses. 1866 // DO NOT INVOKE CLIENT CODE ON THIS THREAD! getFont_NoClientCode()1867 final Font getFont_NoClientCode() { 1868 Font font = this.font; 1869 if (font != null) { 1870 return font; 1871 } 1872 Container parent = this.parent; 1873 return (parent != null) ? parent.getFont_NoClientCode() : null; 1874 } 1875 1876 /** 1877 * Sets the font of this component. 1878 * <p> 1879 * This method changes layout-related information, and therefore, 1880 * invalidates the component hierarchy. 1881 * 1882 * @param f the font to become this component's font; 1883 * if this parameter is <code>null</code> then this 1884 * component will inherit the font of its parent 1885 * @see #getFont 1886 * @see #invalidate 1887 * @since JDK1.0 1888 * @beaninfo 1889 * bound: true 1890 */ setFont(Font f)1891 public void setFont(Font f) { 1892 Font oldFont, newFont; 1893 synchronized(getTreeLock()) { 1894 oldFont = font; 1895 newFont = font = f; 1896 ComponentPeer peer = this.peer; 1897 if (peer != null) { 1898 f = getFont(); 1899 if (f != null) { 1900 peer.setFont(f); 1901 peerFont = f; 1902 } 1903 } 1904 } 1905 // This is a bound property, so report the change to 1906 // any registered listeners. (Cheap if there are none.) 1907 firePropertyChange("font", oldFont, newFont); 1908 1909 // This could change the preferred size of the Component. 1910 // Fix for 6213660. Should compare old and new fonts and do not 1911 // call invalidate() if they are equal. 1912 if (f != oldFont && (oldFont == null || 1913 !oldFont.equals(f))) { 1914 invalidateIfValid(); 1915 } 1916 } 1917 1918 /** 1919 * Returns whether the font has been explicitly set for this Component. If 1920 * this method returns <code>false</code>, this Component is inheriting its 1921 * font from an ancestor. 1922 * 1923 * @return <code>true</code> if the font has been explicitly set for this 1924 * Component; <code>false</code> otherwise. 1925 * @since 1.4 1926 */ isFontSet()1927 public boolean isFontSet() { 1928 return (font != null); 1929 } 1930 1931 /** 1932 * Gets the locale of this component. 1933 * @return this component's locale; if this component does not 1934 * have a locale, the locale of its parent is returned 1935 * @see #setLocale 1936 * @exception IllegalComponentStateException if the <code>Component</code> 1937 * does not have its own locale and has not yet been added to 1938 * a containment hierarchy such that the locale can be determined 1939 * from the containing parent 1940 * @since JDK1.1 1941 */ getLocale()1942 public Locale getLocale() { 1943 Locale locale = this.locale; 1944 if (locale != null) { 1945 return locale; 1946 } 1947 Container parent = this.parent; 1948 1949 if (parent == null) { 1950 throw new IllegalComponentStateException("This component must have a parent in order to determine its locale"); 1951 } else { 1952 return parent.getLocale(); 1953 } 1954 } 1955 1956 /** 1957 * Sets the locale of this component. This is a bound property. 1958 * <p> 1959 * This method changes layout-related information, and therefore, 1960 * invalidates the component hierarchy. 1961 * 1962 * @param l the locale to become this component's locale 1963 * @see #getLocale 1964 * @see #invalidate 1965 * @since JDK1.1 1966 */ setLocale(Locale l)1967 public void setLocale(Locale l) { 1968 Locale oldValue = locale; 1969 locale = l; 1970 1971 // This is a bound property, so report the change to 1972 // any registered listeners. (Cheap if there are none.) 1973 firePropertyChange("locale", oldValue, l); 1974 1975 // This could change the preferred size of the Component. 1976 invalidateIfValid(); 1977 } 1978 1979 /** 1980 * Gets the instance of <code>ColorModel</code> used to display 1981 * the component on the output device. 1982 * @return the color model used by this component 1983 * @see java.awt.image.ColorModel 1984 * @see java.awt.peer.ComponentPeer#getColorModel() 1985 * @see Toolkit#getColorModel() 1986 * @since JDK1.0 1987 */ getColorModel()1988 public ColorModel getColorModel() { 1989 ComponentPeer peer = this.peer; 1990 if ((peer != null) && ! (peer instanceof LightweightPeer)) { 1991 return peer.getColorModel(); 1992 } else if (GraphicsEnvironment.isHeadless()) { 1993 return ColorModel.getRGBdefault(); 1994 } // else 1995 return getToolkit().getColorModel(); 1996 } 1997 1998 /** 1999 * Gets the location of this component in the form of a 2000 * point specifying the component's top-left corner. 2001 * The location will be relative to the parent's coordinate space. 2002 * <p> 2003 * Due to the asynchronous nature of native event handling, this 2004 * method can return outdated values (for instance, after several calls 2005 * of <code>setLocation()</code> in rapid succession). For this 2006 * reason, the recommended method of obtaining a component's position is 2007 * within <code>java.awt.event.ComponentListener.componentMoved()</code>, 2008 * which is called after the operating system has finished moving the 2009 * component. 2010 * </p> 2011 * @return an instance of <code>Point</code> representing 2012 * the top-left corner of the component's bounds in 2013 * the coordinate space of the component's parent 2014 * @see #setLocation 2015 * @see #getLocationOnScreen 2016 * @since JDK1.1 2017 */ getLocation()2018 public Point getLocation() { 2019 return location(); 2020 } 2021 2022 /** 2023 * Gets the location of this component in the form of a point 2024 * specifying the component's top-left corner in the screen's 2025 * coordinate space. 2026 * @return an instance of <code>Point</code> representing 2027 * the top-left corner of the component's bounds in the 2028 * coordinate space of the screen 2029 * @throws IllegalComponentStateException if the 2030 * component is not showing on the screen 2031 * @see #setLocation 2032 * @see #getLocation 2033 */ getLocationOnScreen()2034 public Point getLocationOnScreen() { 2035 synchronized (getTreeLock()) { 2036 return getLocationOnScreen_NoTreeLock(); 2037 } 2038 } 2039 2040 /* 2041 * a package private version of getLocationOnScreen 2042 * used by GlobalCursormanager to update cursor 2043 */ getLocationOnScreen_NoTreeLock()2044 final Point getLocationOnScreen_NoTreeLock() { 2045 2046 if (peer != null && isShowing()) { 2047 if (peer instanceof LightweightPeer) { 2048 // lightweight component location needs to be translated 2049 // relative to a native component. 2050 Container host = getNativeContainer(); 2051 Point pt = host.peer.getLocationOnScreen(); 2052 for(Component c = this; c != host; c = c.getParent()) { 2053 pt.x += c.x; 2054 pt.y += c.y; 2055 } 2056 return pt; 2057 } else { 2058 Point pt = peer.getLocationOnScreen(); 2059 return pt; 2060 } 2061 } else { 2062 throw new IllegalComponentStateException("component must be showing on the screen to determine its location"); 2063 } 2064 } 2065 2066 2067 /** 2068 * @deprecated As of JDK version 1.1, 2069 * replaced by <code>getLocation()</code>. 2070 */ 2071 @Deprecated location()2072 public Point location() { 2073 return location_NoClientCode(); 2074 } 2075 location_NoClientCode()2076 private Point location_NoClientCode() { 2077 return new Point(x, y); 2078 } 2079 2080 /** 2081 * Moves this component to a new location. The top-left corner of 2082 * the new location is specified by the <code>x</code> and <code>y</code> 2083 * parameters in the coordinate space of this component's parent. 2084 * <p> 2085 * This method changes layout-related information, and therefore, 2086 * invalidates the component hierarchy. 2087 * 2088 * @param x the <i>x</i>-coordinate of the new location's 2089 * top-left corner in the parent's coordinate space 2090 * @param y the <i>y</i>-coordinate of the new location's 2091 * top-left corner in the parent's coordinate space 2092 * @see #getLocation 2093 * @see #setBounds 2094 * @see #invalidate 2095 * @since JDK1.1 2096 */ setLocation(int x, int y)2097 public void setLocation(int x, int y) { 2098 move(x, y); 2099 } 2100 2101 /** 2102 * @deprecated As of JDK version 1.1, 2103 * replaced by <code>setLocation(int, int)</code>. 2104 */ 2105 @Deprecated move(int x, int y)2106 public void move(int x, int y) { 2107 synchronized(getTreeLock()) { 2108 setBoundsOp(ComponentPeer.SET_LOCATION); 2109 setBounds(x, y, width, height); 2110 } 2111 } 2112 2113 /** 2114 * Moves this component to a new location. The top-left corner of 2115 * the new location is specified by point <code>p</code>. Point 2116 * <code>p</code> is given in the parent's coordinate space. 2117 * <p> 2118 * This method changes layout-related information, and therefore, 2119 * invalidates the component hierarchy. 2120 * 2121 * @param p the point defining the top-left corner 2122 * of the new location, given in the coordinate space of this 2123 * component's parent 2124 * @see #getLocation 2125 * @see #setBounds 2126 * @see #invalidate 2127 * @since JDK1.1 2128 */ setLocation(Point p)2129 public void setLocation(Point p) { 2130 setLocation(p.x, p.y); 2131 } 2132 2133 /** 2134 * Returns the size of this component in the form of a 2135 * <code>Dimension</code> object. The <code>height</code> 2136 * field of the <code>Dimension</code> object contains 2137 * this component's height, and the <code>width</code> 2138 * field of the <code>Dimension</code> object contains 2139 * this component's width. 2140 * @return a <code>Dimension</code> object that indicates the 2141 * size of this component 2142 * @see #setSize 2143 * @since JDK1.1 2144 */ getSize()2145 public Dimension getSize() { 2146 return size(); 2147 } 2148 2149 /** 2150 * @deprecated As of JDK version 1.1, 2151 * replaced by <code>getSize()</code>. 2152 */ 2153 @Deprecated size()2154 public Dimension size() { 2155 return new Dimension(width, height); 2156 } 2157 2158 /** 2159 * Resizes this component so that it has width <code>width</code> 2160 * and height <code>height</code>. 2161 * <p> 2162 * This method changes layout-related information, and therefore, 2163 * invalidates the component hierarchy. 2164 * 2165 * @param width the new width of this component in pixels 2166 * @param height the new height of this component in pixels 2167 * @see #getSize 2168 * @see #setBounds 2169 * @see #invalidate 2170 * @since JDK1.1 2171 */ setSize(int width, int height)2172 public void setSize(int width, int height) { 2173 resize(width, height); 2174 } 2175 2176 /** 2177 * @deprecated As of JDK version 1.1, 2178 * replaced by <code>setSize(int, int)</code>. 2179 */ 2180 @Deprecated resize(int width, int height)2181 public void resize(int width, int height) { 2182 synchronized(getTreeLock()) { 2183 setBoundsOp(ComponentPeer.SET_SIZE); 2184 setBounds(x, y, width, height); 2185 } 2186 } 2187 2188 /** 2189 * Resizes this component so that it has width <code>d.width</code> 2190 * and height <code>d.height</code>. 2191 * <p> 2192 * This method changes layout-related information, and therefore, 2193 * invalidates the component hierarchy. 2194 * 2195 * @param d the dimension specifying the new size 2196 * of this component 2197 * @throws NullPointerException if {@code d} is {@code null} 2198 * @see #setSize 2199 * @see #setBounds 2200 * @see #invalidate 2201 * @since JDK1.1 2202 */ setSize(Dimension d)2203 public void setSize(Dimension d) { 2204 resize(d); 2205 } 2206 2207 /** 2208 * @deprecated As of JDK version 1.1, 2209 * replaced by <code>setSize(Dimension)</code>. 2210 */ 2211 @Deprecated resize(Dimension d)2212 public void resize(Dimension d) { 2213 setSize(d.width, d.height); 2214 } 2215 2216 /** 2217 * Gets the bounds of this component in the form of a 2218 * <code>Rectangle</code> object. The bounds specify this 2219 * component's width, height, and location relative to 2220 * its parent. 2221 * @return a rectangle indicating this component's bounds 2222 * @see #setBounds 2223 * @see #getLocation 2224 * @see #getSize 2225 */ getBounds()2226 public Rectangle getBounds() { 2227 return bounds(); 2228 } 2229 2230 /** 2231 * @deprecated As of JDK version 1.1, 2232 * replaced by <code>getBounds()</code>. 2233 */ 2234 @Deprecated bounds()2235 public Rectangle bounds() { 2236 return new Rectangle(x, y, width, height); 2237 } 2238 2239 /** 2240 * Moves and resizes this component. The new location of the top-left 2241 * corner is specified by <code>x</code> and <code>y</code>, and the 2242 * new size is specified by <code>width</code> and <code>height</code>. 2243 * <p> 2244 * This method changes layout-related information, and therefore, 2245 * invalidates the component hierarchy. 2246 * 2247 * @param x the new <i>x</i>-coordinate of this component 2248 * @param y the new <i>y</i>-coordinate of this component 2249 * @param width the new <code>width</code> of this component 2250 * @param height the new <code>height</code> of this 2251 * component 2252 * @see #getBounds 2253 * @see #setLocation(int, int) 2254 * @see #setLocation(Point) 2255 * @see #setSize(int, int) 2256 * @see #setSize(Dimension) 2257 * @see #invalidate 2258 * @since JDK1.1 2259 */ setBounds(int x, int y, int width, int height)2260 public void setBounds(int x, int y, int width, int height) { 2261 reshape(x, y, width, height); 2262 } 2263 2264 /** 2265 * @deprecated As of JDK version 1.1, 2266 * replaced by <code>setBounds(int, int, int, int)</code>. 2267 */ 2268 @Deprecated reshape(int x, int y, int width, int height)2269 public void reshape(int x, int y, int width, int height) { 2270 synchronized (getTreeLock()) { 2271 try { 2272 setBoundsOp(ComponentPeer.SET_BOUNDS); 2273 boolean resized = (this.width != width) || (this.height != height); 2274 boolean moved = (this.x != x) || (this.y != y); 2275 if (!resized && !moved) { 2276 return; 2277 } 2278 int oldX = this.x; 2279 int oldY = this.y; 2280 int oldWidth = this.width; 2281 int oldHeight = this.height; 2282 this.x = x; 2283 this.y = y; 2284 this.width = width; 2285 this.height = height; 2286 2287 if (resized) { 2288 isPacked = false; 2289 } 2290 2291 boolean needNotify = true; 2292 mixOnReshaping(); 2293 if (peer != null) { 2294 // LightwightPeer is an empty stub so can skip peer.reshape 2295 if (!(peer instanceof LightweightPeer)) { 2296 reshapeNativePeer(x, y, width, height, getBoundsOp()); 2297 // Check peer actualy changed coordinates 2298 resized = (oldWidth != this.width) || (oldHeight != this.height); 2299 moved = (oldX != this.x) || (oldY != this.y); 2300 // fix for 5025858: do not send ComponentEvents for toplevel 2301 // windows here as it is done from peer or native code when 2302 // the window is really resized or moved, otherwise some 2303 // events may be sent twice 2304 if (this instanceof Window) { 2305 needNotify = false; 2306 } 2307 } 2308 if (resized) { 2309 invalidate(); 2310 } 2311 if (parent != null) { 2312 parent.invalidateIfValid(); 2313 } 2314 } 2315 if (needNotify) { 2316 notifyNewBounds(resized, moved); 2317 } 2318 repaintParentIfNeeded(oldX, oldY, oldWidth, oldHeight); 2319 } finally { 2320 setBoundsOp(ComponentPeer.RESET_OPERATION); 2321 } 2322 } 2323 } 2324 repaintParentIfNeeded(int oldX, int oldY, int oldWidth, int oldHeight)2325 private void repaintParentIfNeeded(int oldX, int oldY, int oldWidth, 2326 int oldHeight) 2327 { 2328 if (parent != null && peer instanceof LightweightPeer && isShowing()) { 2329 // Have the parent redraw the area this component occupied. 2330 parent.repaint(oldX, oldY, oldWidth, oldHeight); 2331 // Have the parent redraw the area this component *now* occupies. 2332 repaint(); 2333 } 2334 } 2335 reshapeNativePeer(int x, int y, int width, int height, int op)2336 private void reshapeNativePeer(int x, int y, int width, int height, int op) { 2337 // native peer might be offset by more than direct 2338 // parent since parent might be lightweight. 2339 int nativeX = x; 2340 int nativeY = y; 2341 for (Component c = parent; 2342 (c != null) && (c.peer instanceof LightweightPeer); 2343 c = c.parent) 2344 { 2345 nativeX += c.x; 2346 nativeY += c.y; 2347 } 2348 peer.setBounds(nativeX, nativeY, width, height, op); 2349 } 2350 2351 @SuppressWarnings("deprecation") notifyNewBounds(boolean resized, boolean moved)2352 private void notifyNewBounds(boolean resized, boolean moved) { 2353 if (componentListener != null 2354 || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 2355 || Toolkit.enabledOnToolkit(AWTEvent.COMPONENT_EVENT_MASK)) 2356 { 2357 if (resized) { 2358 ComponentEvent e = new ComponentEvent(this, 2359 ComponentEvent.COMPONENT_RESIZED); 2360 Toolkit.getEventQueue().postEvent(e); 2361 } 2362 if (moved) { 2363 ComponentEvent e = new ComponentEvent(this, 2364 ComponentEvent.COMPONENT_MOVED); 2365 Toolkit.getEventQueue().postEvent(e); 2366 } 2367 } else { 2368 if (this instanceof Container && ((Container)this).countComponents() > 0) { 2369 boolean enabledOnToolkit = 2370 Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); 2371 if (resized) { 2372 2373 ((Container)this).createChildHierarchyEvents( 2374 HierarchyEvent.ANCESTOR_RESIZED, 0, enabledOnToolkit); 2375 } 2376 if (moved) { 2377 ((Container)this).createChildHierarchyEvents( 2378 HierarchyEvent.ANCESTOR_MOVED, 0, enabledOnToolkit); 2379 } 2380 } 2381 } 2382 } 2383 2384 /** 2385 * Moves and resizes this component to conform to the new 2386 * bounding rectangle <code>r</code>. This component's new 2387 * position is specified by <code>r.x</code> and <code>r.y</code>, 2388 * and its new size is specified by <code>r.width</code> and 2389 * <code>r.height</code> 2390 * <p> 2391 * This method changes layout-related information, and therefore, 2392 * invalidates the component hierarchy. 2393 * 2394 * @param r the new bounding rectangle for this component 2395 * @throws NullPointerException if {@code r} is {@code null} 2396 * @see #getBounds 2397 * @see #setLocation(int, int) 2398 * @see #setLocation(Point) 2399 * @see #setSize(int, int) 2400 * @see #setSize(Dimension) 2401 * @see #invalidate 2402 * @since JDK1.1 2403 */ setBounds(Rectangle r)2404 public void setBounds(Rectangle r) { 2405 setBounds(r.x, r.y, r.width, r.height); 2406 } 2407 2408 2409 /** 2410 * Returns the current x coordinate of the components origin. 2411 * This method is preferable to writing 2412 * <code>component.getBounds().x</code>, 2413 * or <code>component.getLocation().x</code> because it doesn't 2414 * cause any heap allocations. 2415 * 2416 * @return the current x coordinate of the components origin 2417 * @since 1.2 2418 */ getX()2419 public int getX() { 2420 return x; 2421 } 2422 2423 2424 /** 2425 * Returns the current y coordinate of the components origin. 2426 * This method is preferable to writing 2427 * <code>component.getBounds().y</code>, 2428 * or <code>component.getLocation().y</code> because it 2429 * doesn't cause any heap allocations. 2430 * 2431 * @return the current y coordinate of the components origin 2432 * @since 1.2 2433 */ getY()2434 public int getY() { 2435 return y; 2436 } 2437 2438 2439 /** 2440 * Returns the current width of this component. 2441 * This method is preferable to writing 2442 * <code>component.getBounds().width</code>, 2443 * or <code>component.getSize().width</code> because it 2444 * doesn't cause any heap allocations. 2445 * 2446 * @return the current width of this component 2447 * @since 1.2 2448 */ getWidth()2449 public int getWidth() { 2450 return width; 2451 } 2452 2453 2454 /** 2455 * Returns the current height of this component. 2456 * This method is preferable to writing 2457 * <code>component.getBounds().height</code>, 2458 * or <code>component.getSize().height</code> because it 2459 * doesn't cause any heap allocations. 2460 * 2461 * @return the current height of this component 2462 * @since 1.2 2463 */ getHeight()2464 public int getHeight() { 2465 return height; 2466 } 2467 2468 /** 2469 * Stores the bounds of this component into "return value" <b>rv</b> and 2470 * return <b>rv</b>. If rv is <code>null</code> a new 2471 * <code>Rectangle</code> is allocated. 2472 * This version of <code>getBounds</code> is useful if the caller 2473 * wants to avoid allocating a new <code>Rectangle</code> object 2474 * on the heap. 2475 * 2476 * @param rv the return value, modified to the components bounds 2477 * @return rv 2478 */ getBounds(Rectangle rv)2479 public Rectangle getBounds(Rectangle rv) { 2480 if (rv == null) { 2481 return new Rectangle(getX(), getY(), getWidth(), getHeight()); 2482 } 2483 else { 2484 rv.setBounds(getX(), getY(), getWidth(), getHeight()); 2485 return rv; 2486 } 2487 } 2488 2489 /** 2490 * Stores the width/height of this component into "return value" <b>rv</b> 2491 * and return <b>rv</b>. If rv is <code>null</code> a new 2492 * <code>Dimension</code> object is allocated. This version of 2493 * <code>getSize</code> is useful if the caller wants to avoid 2494 * allocating a new <code>Dimension</code> object on the heap. 2495 * 2496 * @param rv the return value, modified to the components size 2497 * @return rv 2498 */ getSize(Dimension rv)2499 public Dimension getSize(Dimension rv) { 2500 if (rv == null) { 2501 return new Dimension(getWidth(), getHeight()); 2502 } 2503 else { 2504 rv.setSize(getWidth(), getHeight()); 2505 return rv; 2506 } 2507 } 2508 2509 /** 2510 * Stores the x,y origin of this component into "return value" <b>rv</b> 2511 * and return <b>rv</b>. If rv is <code>null</code> a new 2512 * <code>Point</code> is allocated. 2513 * This version of <code>getLocation</code> is useful if the 2514 * caller wants to avoid allocating a new <code>Point</code> 2515 * object on the heap. 2516 * 2517 * @param rv the return value, modified to the components location 2518 * @return rv 2519 */ getLocation(Point rv)2520 public Point getLocation(Point rv) { 2521 if (rv == null) { 2522 return new Point(getX(), getY()); 2523 } 2524 else { 2525 rv.setLocation(getX(), getY()); 2526 return rv; 2527 } 2528 } 2529 2530 /** 2531 * Returns true if this component is completely opaque, returns 2532 * false by default. 2533 * <p> 2534 * An opaque component paints every pixel within its 2535 * rectangular region. A non-opaque component paints only some of 2536 * its pixels, allowing the pixels underneath it to "show through". 2537 * A component that does not fully paint its pixels therefore 2538 * provides a degree of transparency. 2539 * <p> 2540 * Subclasses that guarantee to always completely paint their 2541 * contents should override this method and return true. 2542 * 2543 * @return true if this component is completely opaque 2544 * @see #isLightweight 2545 * @since 1.2 2546 */ isOpaque()2547 public boolean isOpaque() { 2548 if (getPeer() == null) { 2549 return false; 2550 } 2551 else { 2552 return !isLightweight(); 2553 } 2554 } 2555 2556 2557 /** 2558 * A lightweight component doesn't have a native toolkit peer. 2559 * Subclasses of <code>Component</code> and <code>Container</code>, 2560 * other than the ones defined in this package like <code>Button</code> 2561 * or <code>Scrollbar</code>, are lightweight. 2562 * All of the Swing components are lightweights. 2563 * <p> 2564 * This method will always return <code>false</code> if this component 2565 * is not displayable because it is impossible to determine the 2566 * weight of an undisplayable component. 2567 * 2568 * @return true if this component has a lightweight peer; false if 2569 * it has a native peer or no peer 2570 * @see #isDisplayable 2571 * @since 1.2 2572 */ isLightweight()2573 public boolean isLightweight() { 2574 return getPeer() instanceof LightweightPeer; 2575 } 2576 2577 2578 /** 2579 * Sets the preferred size of this component to a constant 2580 * value. Subsequent calls to <code>getPreferredSize</code> will always 2581 * return this value. Setting the preferred size to <code>null</code> 2582 * restores the default behavior. 2583 * 2584 * @param preferredSize The new preferred size, or null 2585 * @see #getPreferredSize 2586 * @see #isPreferredSizeSet 2587 * @since 1.5 2588 */ setPreferredSize(Dimension preferredSize)2589 public void setPreferredSize(Dimension preferredSize) { 2590 Dimension old; 2591 // If the preferred size was set, use it as the old value, otherwise 2592 // use null to indicate we didn't previously have a set preferred 2593 // size. 2594 if (prefSizeSet) { 2595 old = this.prefSize; 2596 } 2597 else { 2598 old = null; 2599 } 2600 this.prefSize = preferredSize; 2601 prefSizeSet = (preferredSize != null); 2602 firePropertyChange("preferredSize", old, preferredSize); 2603 } 2604 2605 2606 /** 2607 * Returns true if the preferred size has been set to a 2608 * non-<code>null</code> value otherwise returns false. 2609 * 2610 * @return true if <code>setPreferredSize</code> has been invoked 2611 * with a non-null value. 2612 * @since 1.5 2613 */ isPreferredSizeSet()2614 public boolean isPreferredSizeSet() { 2615 return prefSizeSet; 2616 } 2617 2618 2619 /** 2620 * Gets the preferred size of this component. 2621 * @return a dimension object indicating this component's preferred size 2622 * @see #getMinimumSize 2623 * @see LayoutManager 2624 */ getPreferredSize()2625 public Dimension getPreferredSize() { 2626 return preferredSize(); 2627 } 2628 2629 2630 /** 2631 * @deprecated As of JDK version 1.1, 2632 * replaced by <code>getPreferredSize()</code>. 2633 */ 2634 @Deprecated preferredSize()2635 public Dimension preferredSize() { 2636 /* Avoid grabbing the lock if a reasonable cached size value 2637 * is available. 2638 */ 2639 Dimension dim = prefSize; 2640 if (dim == null || !(isPreferredSizeSet() || isValid())) { 2641 synchronized (getTreeLock()) { 2642 prefSize = (peer != null) ? 2643 peer.getPreferredSize() : 2644 getMinimumSize(); 2645 dim = prefSize; 2646 } 2647 } 2648 return new Dimension(dim); 2649 } 2650 2651 /** 2652 * Sets the minimum size of this component to a constant 2653 * value. Subsequent calls to <code>getMinimumSize</code> will always 2654 * return this value. Setting the minimum size to <code>null</code> 2655 * restores the default behavior. 2656 * 2657 * @param minimumSize the new minimum size of this component 2658 * @see #getMinimumSize 2659 * @see #isMinimumSizeSet 2660 * @since 1.5 2661 */ setMinimumSize(Dimension minimumSize)2662 public void setMinimumSize(Dimension minimumSize) { 2663 Dimension old; 2664 // If the minimum size was set, use it as the old value, otherwise 2665 // use null to indicate we didn't previously have a set minimum 2666 // size. 2667 if (minSizeSet) { 2668 old = this.minSize; 2669 } 2670 else { 2671 old = null; 2672 } 2673 this.minSize = minimumSize; 2674 minSizeSet = (minimumSize != null); 2675 firePropertyChange("minimumSize", old, minimumSize); 2676 } 2677 2678 /** 2679 * Returns whether or not <code>setMinimumSize</code> has been 2680 * invoked with a non-null value. 2681 * 2682 * @return true if <code>setMinimumSize</code> has been invoked with a 2683 * non-null value. 2684 * @since 1.5 2685 */ isMinimumSizeSet()2686 public boolean isMinimumSizeSet() { 2687 return minSizeSet; 2688 } 2689 2690 /** 2691 * Gets the minimum size of this component. 2692 * @return a dimension object indicating this component's minimum size 2693 * @see #getPreferredSize 2694 * @see LayoutManager 2695 */ getMinimumSize()2696 public Dimension getMinimumSize() { 2697 return minimumSize(); 2698 } 2699 2700 /** 2701 * @deprecated As of JDK version 1.1, 2702 * replaced by <code>getMinimumSize()</code>. 2703 */ 2704 @Deprecated minimumSize()2705 public Dimension minimumSize() { 2706 /* Avoid grabbing the lock if a reasonable cached size value 2707 * is available. 2708 */ 2709 Dimension dim = minSize; 2710 if (dim == null || !(isMinimumSizeSet() || isValid())) { 2711 synchronized (getTreeLock()) { 2712 minSize = (peer != null) ? 2713 peer.getMinimumSize() : 2714 size(); 2715 dim = minSize; 2716 } 2717 } 2718 return new Dimension(dim); 2719 } 2720 2721 /** 2722 * Sets the maximum size of this component to a constant 2723 * value. Subsequent calls to <code>getMaximumSize</code> will always 2724 * return this value. Setting the maximum size to <code>null</code> 2725 * restores the default behavior. 2726 * 2727 * @param maximumSize a <code>Dimension</code> containing the 2728 * desired maximum allowable size 2729 * @see #getMaximumSize 2730 * @see #isMaximumSizeSet 2731 * @since 1.5 2732 */ setMaximumSize(Dimension maximumSize)2733 public void setMaximumSize(Dimension maximumSize) { 2734 // If the maximum size was set, use it as the old value, otherwise 2735 // use null to indicate we didn't previously have a set maximum 2736 // size. 2737 Dimension old; 2738 if (maxSizeSet) { 2739 old = this.maxSize; 2740 } 2741 else { 2742 old = null; 2743 } 2744 this.maxSize = maximumSize; 2745 maxSizeSet = (maximumSize != null); 2746 firePropertyChange("maximumSize", old, maximumSize); 2747 } 2748 2749 /** 2750 * Returns true if the maximum size has been set to a non-<code>null</code> 2751 * value otherwise returns false. 2752 * 2753 * @return true if <code>maximumSize</code> is non-<code>null</code>, 2754 * false otherwise 2755 * @since 1.5 2756 */ isMaximumSizeSet()2757 public boolean isMaximumSizeSet() { 2758 return maxSizeSet; 2759 } 2760 2761 /** 2762 * Gets the maximum size of this component. 2763 * @return a dimension object indicating this component's maximum size 2764 * @see #getMinimumSize 2765 * @see #getPreferredSize 2766 * @see LayoutManager 2767 */ getMaximumSize()2768 public Dimension getMaximumSize() { 2769 if (isMaximumSizeSet()) { 2770 return new Dimension(maxSize); 2771 } 2772 return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE); 2773 } 2774 2775 /** 2776 * Returns the alignment along the x axis. This specifies how 2777 * the component would like to be aligned relative to other 2778 * components. The value should be a number between 0 and 1 2779 * where 0 represents alignment along the origin, 1 is aligned 2780 * the furthest away from the origin, 0.5 is centered, etc. 2781 */ getAlignmentX()2782 public float getAlignmentX() { 2783 return CENTER_ALIGNMENT; 2784 } 2785 2786 /** 2787 * Returns the alignment along the y axis. This specifies how 2788 * the component would like to be aligned relative to other 2789 * components. The value should be a number between 0 and 1 2790 * where 0 represents alignment along the origin, 1 is aligned 2791 * the furthest away from the origin, 0.5 is centered, etc. 2792 */ getAlignmentY()2793 public float getAlignmentY() { 2794 return CENTER_ALIGNMENT; 2795 } 2796 2797 /** 2798 * Returns the baseline. The baseline is measured from the top of 2799 * the component. This method is primarily meant for 2800 * <code>LayoutManager</code>s to align components along their 2801 * baseline. A return value less than 0 indicates this component 2802 * does not have a reasonable baseline and that 2803 * <code>LayoutManager</code>s should not align this component on 2804 * its baseline. 2805 * <p> 2806 * The default implementation returns -1. Subclasses that support 2807 * baseline should override appropriately. If a value >= 0 is 2808 * returned, then the component has a valid baseline for any 2809 * size >= the minimum size and <code>getBaselineResizeBehavior</code> 2810 * can be used to determine how the baseline changes with size. 2811 * 2812 * @param width the width to get the baseline for 2813 * @param height the height to get the baseline for 2814 * @return the baseline or < 0 indicating there is no reasonable 2815 * baseline 2816 * @throws IllegalArgumentException if width or height is < 0 2817 * @see #getBaselineResizeBehavior 2818 * @see java.awt.FontMetrics 2819 * @since 1.6 2820 */ getBaseline(int width, int height)2821 public int getBaseline(int width, int height) { 2822 if (width < 0 || height < 0) { 2823 throw new IllegalArgumentException( 2824 "Width and height must be >= 0"); 2825 } 2826 return -1; 2827 } 2828 2829 /** 2830 * Returns an enum indicating how the baseline of the component 2831 * changes as the size changes. This method is primarily meant for 2832 * layout managers and GUI builders. 2833 * <p> 2834 * The default implementation returns 2835 * <code>BaselineResizeBehavior.OTHER</code>. Subclasses that have a 2836 * baseline should override appropriately. Subclasses should 2837 * never return <code>null</code>; if the baseline can not be 2838 * calculated return <code>BaselineResizeBehavior.OTHER</code>. Callers 2839 * should first ask for the baseline using 2840 * <code>getBaseline</code> and if a value >= 0 is returned use 2841 * this method. It is acceptable for this method to return a 2842 * value other than <code>BaselineResizeBehavior.OTHER</code> even if 2843 * <code>getBaseline</code> returns a value less than 0. 2844 * 2845 * @return an enum indicating how the baseline changes as the component 2846 * size changes 2847 * @see #getBaseline(int, int) 2848 * @since 1.6 2849 */ getBaselineResizeBehavior()2850 public BaselineResizeBehavior getBaselineResizeBehavior() { 2851 return BaselineResizeBehavior.OTHER; 2852 } 2853 2854 /** 2855 * Prompts the layout manager to lay out this component. This is 2856 * usually called when the component (more specifically, container) 2857 * is validated. 2858 * @see #validate 2859 * @see LayoutManager 2860 */ doLayout()2861 public void doLayout() { 2862 layout(); 2863 } 2864 2865 /** 2866 * @deprecated As of JDK version 1.1, 2867 * replaced by <code>doLayout()</code>. 2868 */ 2869 @Deprecated layout()2870 public void layout() { 2871 } 2872 2873 /** 2874 * Validates this component. 2875 * <p> 2876 * The meaning of the term <i>validating</i> is defined by the ancestors of 2877 * this class. See {@link Container#validate} for more details. 2878 * 2879 * @see #invalidate 2880 * @see #doLayout() 2881 * @see LayoutManager 2882 * @see Container#validate 2883 * @since JDK1.0 2884 */ validate()2885 public void validate() { 2886 synchronized (getTreeLock()) { 2887 ComponentPeer peer = this.peer; 2888 boolean wasValid = isValid(); 2889 if (!wasValid && peer != null) { 2890 Font newfont = getFont(); 2891 Font oldfont = peerFont; 2892 if (newfont != oldfont && (oldfont == null 2893 || !oldfont.equals(newfont))) { 2894 peer.setFont(newfont); 2895 peerFont = newfont; 2896 } 2897 peer.layout(); 2898 } 2899 valid = true; 2900 if (!wasValid) { 2901 mixOnValidating(); 2902 } 2903 } 2904 } 2905 2906 /** 2907 * Invalidates this component and its ancestors. 2908 * <p> 2909 * By default, all the ancestors of the component up to the top-most 2910 * container of the hierarchy are marked invalid. If the {@code 2911 * java.awt.smartInvalidate} system property is set to {@code true}, 2912 * invalidation stops on the nearest validate root of this component. 2913 * Marking a container <i>invalid</i> indicates that the container needs to 2914 * be laid out. 2915 * <p> 2916 * This method is called automatically when any layout-related information 2917 * changes (e.g. setting the bounds of the component, or adding the 2918 * component to a container). 2919 * <p> 2920 * This method might be called often, so it should work fast. 2921 * 2922 * @see #validate 2923 * @see #doLayout 2924 * @see LayoutManager 2925 * @see java.awt.Container#isValidateRoot 2926 * @since JDK1.0 2927 */ invalidate()2928 public void invalidate() { 2929 synchronized (getTreeLock()) { 2930 /* Nullify cached layout and size information. 2931 * For efficiency, propagate invalidate() upwards only if 2932 * some other component hasn't already done so first. 2933 */ 2934 valid = false; 2935 if (!isPreferredSizeSet()) { 2936 prefSize = null; 2937 } 2938 if (!isMinimumSizeSet()) { 2939 minSize = null; 2940 } 2941 if (!isMaximumSizeSet()) { 2942 maxSize = null; 2943 } 2944 invalidateParent(); 2945 } 2946 } 2947 2948 /** 2949 * Invalidates the parent of this component if any. 2950 * 2951 * This method MUST BE invoked under the TreeLock. 2952 */ invalidateParent()2953 void invalidateParent() { 2954 if (parent != null) { 2955 parent.invalidateIfValid(); 2956 } 2957 } 2958 2959 /** Invalidates the component unless it is already invalid. 2960 */ invalidateIfValid()2961 final void invalidateIfValid() { 2962 if (isValid()) { 2963 invalidate(); 2964 } 2965 } 2966 2967 /** 2968 * Revalidates the component hierarchy up to the nearest validate root. 2969 * <p> 2970 * This method first invalidates the component hierarchy starting from this 2971 * component up to the nearest validate root. Afterwards, the component 2972 * hierarchy is validated starting from the nearest validate root. 2973 * <p> 2974 * This is a convenience method supposed to help application developers 2975 * avoid looking for validate roots manually. Basically, it's equivalent to 2976 * first calling the {@link #invalidate()} method on this component, and 2977 * then calling the {@link #validate()} method on the nearest validate 2978 * root. 2979 * 2980 * @see Container#isValidateRoot 2981 * @since 1.7 2982 */ revalidate()2983 public void revalidate() { 2984 revalidateSynchronously(); 2985 } 2986 2987 /** 2988 * Revalidates the component synchronously. 2989 */ revalidateSynchronously()2990 final void revalidateSynchronously() { 2991 synchronized (getTreeLock()) { 2992 invalidate(); 2993 2994 Container root = getContainer(); 2995 if (root == null) { 2996 // There's no parents. Just validate itself. 2997 validate(); 2998 } else { 2999 while (!root.isValidateRoot()) { 3000 if (root.getContainer() == null) { 3001 // If there's no validate roots, we'll validate the 3002 // topmost container 3003 break; 3004 } 3005 3006 root = root.getContainer(); 3007 } 3008 3009 root.validate(); 3010 } 3011 } 3012 } 3013 3014 /** 3015 * Creates a graphics context for this component. This method will 3016 * return <code>null</code> if this component is currently not 3017 * displayable. 3018 * @return a graphics context for this component, or <code>null</code> 3019 * if it has none 3020 * @see #paint 3021 * @since JDK1.0 3022 */ getGraphics()3023 public Graphics getGraphics() { 3024 if (peer instanceof LightweightPeer) { 3025 // This is for a lightweight component, need to 3026 // translate coordinate spaces and clip relative 3027 // to the parent. 3028 if (parent == null) return null; 3029 Graphics g = parent.getGraphics(); 3030 if (g == null) return null; 3031 if (g instanceof ConstrainableGraphics) { 3032 ((ConstrainableGraphics) g).constrain(x, y, width, height); 3033 } else { 3034 g.translate(x,y); 3035 g.setClip(0, 0, width, height); 3036 } 3037 g.setFont(getFont()); 3038 return g; 3039 } else { 3040 ComponentPeer peer = this.peer; 3041 return (peer != null) ? peer.getGraphics() : null; 3042 } 3043 } 3044 getGraphics_NoClientCode()3045 final Graphics getGraphics_NoClientCode() { 3046 ComponentPeer peer = this.peer; 3047 if (peer instanceof LightweightPeer) { 3048 // This is for a lightweight component, need to 3049 // translate coordinate spaces and clip relative 3050 // to the parent. 3051 Container parent = this.parent; 3052 if (parent == null) return null; 3053 Graphics g = parent.getGraphics_NoClientCode(); 3054 if (g == null) return null; 3055 if (g instanceof ConstrainableGraphics) { 3056 ((ConstrainableGraphics) g).constrain(x, y, width, height); 3057 } else { 3058 g.translate(x,y); 3059 g.setClip(0, 0, width, height); 3060 } 3061 g.setFont(getFont_NoClientCode()); 3062 return g; 3063 } else { 3064 return (peer != null) ? peer.getGraphics() : null; 3065 } 3066 } 3067 3068 /** 3069 * Gets the font metrics for the specified font. 3070 * Warning: Since Font metrics are affected by the 3071 * {@link java.awt.font.FontRenderContext FontRenderContext} and 3072 * this method does not provide one, it can return only metrics for 3073 * the default render context which may not match that used when 3074 * rendering on the Component if {@link Graphics2D} functionality is being 3075 * used. Instead metrics can be obtained at rendering time by calling 3076 * {@link Graphics#getFontMetrics()} or text measurement APIs on the 3077 * {@link Font Font} class. 3078 * @param font the font for which font metrics is to be 3079 * obtained 3080 * @return the font metrics for <code>font</code> 3081 * @see #getFont 3082 * @see #getPeer 3083 * @see java.awt.peer.ComponentPeer#getFontMetrics(Font) 3084 * @see Toolkit#getFontMetrics(Font) 3085 * @since JDK1.0 3086 */ getFontMetrics(Font font)3087 public FontMetrics getFontMetrics(Font font) { 3088 // This is an unsupported hack, but left in for a customer. 3089 // Do not remove. 3090 FontManager fm = FontManagerFactory.getInstance(); 3091 if (fm instanceof SunFontManager 3092 && ((SunFontManager) fm).usePlatformFontMetrics()) { 3093 3094 if (peer != null && 3095 !(peer instanceof LightweightPeer)) { 3096 return peer.getFontMetrics(font); 3097 } 3098 } 3099 return sun.font.FontDesignMetrics.getMetrics(font); 3100 } 3101 3102 /** 3103 * Sets the cursor image to the specified cursor. This cursor 3104 * image is displayed when the <code>contains</code> method for 3105 * this component returns true for the current cursor location, and 3106 * this Component is visible, displayable, and enabled. Setting the 3107 * cursor of a <code>Container</code> causes that cursor to be displayed 3108 * within all of the container's subcomponents, except for those 3109 * that have a non-<code>null</code> cursor. 3110 * <p> 3111 * The method may have no visual effect if the Java platform 3112 * implementation and/or the native system do not support 3113 * changing the mouse cursor shape. 3114 * @param cursor One of the constants defined 3115 * by the <code>Cursor</code> class; 3116 * if this parameter is <code>null</code> 3117 * then this component will inherit 3118 * the cursor of its parent 3119 * @see #isEnabled 3120 * @see #isShowing 3121 * @see #getCursor 3122 * @see #contains 3123 * @see Toolkit#createCustomCursor 3124 * @see Cursor 3125 * @since JDK1.1 3126 */ setCursor(Cursor cursor)3127 public void setCursor(Cursor cursor) { 3128 this.cursor = cursor; 3129 updateCursorImmediately(); 3130 } 3131 3132 /** 3133 * Updates the cursor. May not be invoked from the native 3134 * message pump. 3135 */ updateCursorImmediately()3136 final void updateCursorImmediately() { 3137 if (peer instanceof LightweightPeer) { 3138 Container nativeContainer = getNativeContainer(); 3139 3140 if (nativeContainer == null) return; 3141 3142 ComponentPeer cPeer = nativeContainer.getPeer(); 3143 3144 if (cPeer != null) { 3145 cPeer.updateCursorImmediately(); 3146 } 3147 } else if (peer != null) { 3148 peer.updateCursorImmediately(); 3149 } 3150 } 3151 3152 /** 3153 * Gets the cursor set in the component. If the component does 3154 * not have a cursor set, the cursor of its parent is returned. 3155 * If no cursor is set in the entire hierarchy, 3156 * <code>Cursor.DEFAULT_CURSOR</code> is returned. 3157 * @see #setCursor 3158 * @since JDK1.1 3159 */ getCursor()3160 public Cursor getCursor() { 3161 return getCursor_NoClientCode(); 3162 } 3163 getCursor_NoClientCode()3164 final Cursor getCursor_NoClientCode() { 3165 Cursor cursor = this.cursor; 3166 if (cursor != null) { 3167 return cursor; 3168 } 3169 Container parent = this.parent; 3170 if (parent != null) { 3171 return parent.getCursor_NoClientCode(); 3172 } else { 3173 return Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR); 3174 } 3175 } 3176 3177 /** 3178 * Returns whether the cursor has been explicitly set for this Component. 3179 * If this method returns <code>false</code>, this Component is inheriting 3180 * its cursor from an ancestor. 3181 * 3182 * @return <code>true</code> if the cursor has been explicitly set for this 3183 * Component; <code>false</code> otherwise. 3184 * @since 1.4 3185 */ isCursorSet()3186 public boolean isCursorSet() { 3187 return (cursor != null); 3188 } 3189 3190 /** 3191 * Paints this component. 3192 * <p> 3193 * This method is called when the contents of the component should 3194 * be painted; such as when the component is first being shown or 3195 * is damaged and in need of repair. The clip rectangle in the 3196 * <code>Graphics</code> parameter is set to the area 3197 * which needs to be painted. 3198 * Subclasses of <code>Component</code> that override this 3199 * method need not call <code>super.paint(g)</code>. 3200 * <p> 3201 * For performance reasons, <code>Component</code>s with zero width 3202 * or height aren't considered to need painting when they are first shown, 3203 * and also aren't considered to need repair. 3204 * <p> 3205 * <b>Note</b>: For more information on the paint mechanisms utilitized 3206 * by AWT and Swing, including information on how to write the most 3207 * efficient painting code, see 3208 * <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>. 3209 * 3210 * @param g the graphics context to use for painting 3211 * @see #update 3212 * @since JDK1.0 3213 */ paint(Graphics g)3214 public void paint(Graphics g) { 3215 } 3216 3217 /** 3218 * Updates this component. 3219 * <p> 3220 * If this component is not a lightweight component, the 3221 * AWT calls the <code>update</code> method in response to 3222 * a call to <code>repaint</code>. You can assume that 3223 * the background is not cleared. 3224 * <p> 3225 * The <code>update</code> method of <code>Component</code> 3226 * calls this component's <code>paint</code> method to redraw 3227 * this component. This method is commonly overridden by subclasses 3228 * which need to do additional work in response to a call to 3229 * <code>repaint</code>. 3230 * Subclasses of Component that override this method should either 3231 * call <code>super.update(g)</code>, or call <code>paint(g)</code> 3232 * directly from their <code>update</code> method. 3233 * <p> 3234 * The origin of the graphics context, its 3235 * (<code>0</code>, <code>0</code>) coordinate point, is the 3236 * top-left corner of this component. The clipping region of the 3237 * graphics context is the bounding rectangle of this component. 3238 * 3239 * <p> 3240 * <b>Note</b>: For more information on the paint mechanisms utilitized 3241 * by AWT and Swing, including information on how to write the most 3242 * efficient painting code, see 3243 * <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>. 3244 * 3245 * @param g the specified context to use for updating 3246 * @see #paint 3247 * @see #repaint() 3248 * @since JDK1.0 3249 */ update(Graphics g)3250 public void update(Graphics g) { 3251 paint(g); 3252 } 3253 3254 /** 3255 * Paints this component and all of its subcomponents. 3256 * <p> 3257 * The origin of the graphics context, its 3258 * (<code>0</code>, <code>0</code>) coordinate point, is the 3259 * top-left corner of this component. The clipping region of the 3260 * graphics context is the bounding rectangle of this component. 3261 * 3262 * @param g the graphics context to use for painting 3263 * @see #paint 3264 * @since JDK1.0 3265 */ paintAll(Graphics g)3266 public void paintAll(Graphics g) { 3267 if (isShowing()) { 3268 GraphicsCallback.PeerPaintCallback.getInstance(). 3269 runOneComponent(this, new Rectangle(0, 0, width, height), 3270 g, g.getClip(), 3271 GraphicsCallback.LIGHTWEIGHTS | 3272 GraphicsCallback.HEAVYWEIGHTS); 3273 } 3274 } 3275 3276 /** 3277 * Simulates the peer callbacks into java.awt for painting of 3278 * lightweight Components. 3279 * @param g the graphics context to use for painting 3280 * @see #paintAll 3281 */ lightweightPaint(Graphics g)3282 void lightweightPaint(Graphics g) { 3283 paint(g); 3284 } 3285 3286 /** 3287 * Paints all the heavyweight subcomponents. 3288 */ paintHeavyweightComponents(Graphics g)3289 void paintHeavyweightComponents(Graphics g) { 3290 } 3291 3292 /** 3293 * Repaints this component. 3294 * <p> 3295 * If this component is a lightweight component, this method 3296 * causes a call to this component's <code>paint</code> 3297 * method as soon as possible. Otherwise, this method causes 3298 * a call to this component's <code>update</code> method as soon 3299 * as possible. 3300 * <p> 3301 * <b>Note</b>: For more information on the paint mechanisms utilitized 3302 * by AWT and Swing, including information on how to write the most 3303 * efficient painting code, see 3304 * <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>. 3305 3306 * 3307 * @see #update(Graphics) 3308 * @since JDK1.0 3309 */ repaint()3310 public void repaint() { 3311 repaint(0, 0, 0, width, height); 3312 } 3313 3314 /** 3315 * Repaints the component. If this component is a lightweight 3316 * component, this results in a call to <code>paint</code> 3317 * within <code>tm</code> milliseconds. 3318 * <p> 3319 * <b>Note</b>: For more information on the paint mechanisms utilitized 3320 * by AWT and Swing, including information on how to write the most 3321 * efficient painting code, see 3322 * <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>. 3323 * 3324 * @param tm maximum time in milliseconds before update 3325 * @see #paint 3326 * @see #update(Graphics) 3327 * @since JDK1.0 3328 */ repaint(long tm)3329 public void repaint(long tm) { 3330 repaint(tm, 0, 0, width, height); 3331 } 3332 3333 /** 3334 * Repaints the specified rectangle of this component. 3335 * <p> 3336 * If this component is a lightweight component, this method 3337 * causes a call to this component's <code>paint</code> method 3338 * as soon as possible. Otherwise, this method causes a call to 3339 * this component's <code>update</code> method as soon as possible. 3340 * <p> 3341 * <b>Note</b>: For more information on the paint mechanisms utilitized 3342 * by AWT and Swing, including information on how to write the most 3343 * efficient painting code, see 3344 * <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>. 3345 * 3346 * @param x the <i>x</i> coordinate 3347 * @param y the <i>y</i> coordinate 3348 * @param width the width 3349 * @param height the height 3350 * @see #update(Graphics) 3351 * @since JDK1.0 3352 */ repaint(int x, int y, int width, int height)3353 public void repaint(int x, int y, int width, int height) { 3354 repaint(0, x, y, width, height); 3355 } 3356 3357 /** 3358 * Repaints the specified rectangle of this component within 3359 * <code>tm</code> milliseconds. 3360 * <p> 3361 * If this component is a lightweight component, this method causes 3362 * a call to this component's <code>paint</code> method. 3363 * Otherwise, this method causes a call to this component's 3364 * <code>update</code> method. 3365 * <p> 3366 * <b>Note</b>: For more information on the paint mechanisms utilitized 3367 * by AWT and Swing, including information on how to write the most 3368 * efficient painting code, see 3369 * <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>. 3370 * 3371 * @param tm maximum time in milliseconds before update 3372 * @param x the <i>x</i> coordinate 3373 * @param y the <i>y</i> coordinate 3374 * @param width the width 3375 * @param height the height 3376 * @see #update(Graphics) 3377 * @since JDK1.0 3378 */ repaint(long tm, int x, int y, int width, int height)3379 public void repaint(long tm, int x, int y, int width, int height) { 3380 if (this.peer instanceof LightweightPeer) { 3381 // Needs to be translated to parent coordinates since 3382 // a parent native container provides the actual repaint 3383 // services. Additionally, the request is restricted to 3384 // the bounds of the component. 3385 if (parent != null) { 3386 if (x < 0) { 3387 width += x; 3388 x = 0; 3389 } 3390 if (y < 0) { 3391 height += y; 3392 y = 0; 3393 } 3394 3395 int pwidth = (width > this.width) ? this.width : width; 3396 int pheight = (height > this.height) ? this.height : height; 3397 3398 if (pwidth <= 0 || pheight <= 0) { 3399 return; 3400 } 3401 3402 int px = this.x + x; 3403 int py = this.y + y; 3404 parent.repaint(tm, px, py, pwidth, pheight); 3405 } 3406 } else { 3407 if (isVisible() && (this.peer != null) && 3408 (width > 0) && (height > 0)) { 3409 PaintEvent e = new PaintEvent(this, PaintEvent.UPDATE, 3410 new Rectangle(x, y, width, height)); 3411 SunToolkit.postEvent(SunToolkit.targetToAppContext(this), e); 3412 } 3413 } 3414 } 3415 3416 /** 3417 * Prints this component. Applications should override this method 3418 * for components that must do special processing before being 3419 * printed or should be printed differently than they are painted. 3420 * <p> 3421 * The default implementation of this method calls the 3422 * <code>paint</code> method. 3423 * <p> 3424 * The origin of the graphics context, its 3425 * (<code>0</code>, <code>0</code>) coordinate point, is the 3426 * top-left corner of this component. The clipping region of the 3427 * graphics context is the bounding rectangle of this component. 3428 * @param g the graphics context to use for printing 3429 * @see #paint(Graphics) 3430 * @since JDK1.0 3431 */ print(Graphics g)3432 public void print(Graphics g) { 3433 paint(g); 3434 } 3435 3436 /** 3437 * Prints this component and all of its subcomponents. 3438 * <p> 3439 * The origin of the graphics context, its 3440 * (<code>0</code>, <code>0</code>) coordinate point, is the 3441 * top-left corner of this component. The clipping region of the 3442 * graphics context is the bounding rectangle of this component. 3443 * @param g the graphics context to use for printing 3444 * @see #print(Graphics) 3445 * @since JDK1.0 3446 */ printAll(Graphics g)3447 public void printAll(Graphics g) { 3448 if (isShowing()) { 3449 GraphicsCallback.PeerPrintCallback.getInstance(). 3450 runOneComponent(this, new Rectangle(0, 0, width, height), 3451 g, g.getClip(), 3452 GraphicsCallback.LIGHTWEIGHTS | 3453 GraphicsCallback.HEAVYWEIGHTS); 3454 } 3455 } 3456 3457 /** 3458 * Simulates the peer callbacks into java.awt for printing of 3459 * lightweight Components. 3460 * @param g the graphics context to use for printing 3461 * @see #printAll 3462 */ lightweightPrint(Graphics g)3463 void lightweightPrint(Graphics g) { 3464 print(g); 3465 } 3466 3467 /** 3468 * Prints all the heavyweight subcomponents. 3469 */ printHeavyweightComponents(Graphics g)3470 void printHeavyweightComponents(Graphics g) { 3471 } 3472 getInsets_NoClientCode()3473 private Insets getInsets_NoClientCode() { 3474 ComponentPeer peer = this.peer; 3475 if (peer instanceof ContainerPeer) { 3476 return (Insets)((ContainerPeer)peer).getInsets().clone(); 3477 } 3478 return new Insets(0, 0, 0, 0); 3479 } 3480 3481 /** 3482 * Repaints the component when the image has changed. 3483 * This <code>imageUpdate</code> method of an <code>ImageObserver</code> 3484 * is called when more information about an 3485 * image which had been previously requested using an asynchronous 3486 * routine such as the <code>drawImage</code> method of 3487 * <code>Graphics</code> becomes available. 3488 * See the definition of <code>imageUpdate</code> for 3489 * more information on this method and its arguments. 3490 * <p> 3491 * The <code>imageUpdate</code> method of <code>Component</code> 3492 * incrementally draws an image on the component as more of the bits 3493 * of the image are available. 3494 * <p> 3495 * If the system property <code>awt.image.incrementaldraw</code> 3496 * is missing or has the value <code>true</code>, the image is 3497 * incrementally drawn. If the system property has any other value, 3498 * then the image is not drawn until it has been completely loaded. 3499 * <p> 3500 * Also, if incremental drawing is in effect, the value of the 3501 * system property <code>awt.image.redrawrate</code> is interpreted 3502 * as an integer to give the maximum redraw rate, in milliseconds. If 3503 * the system property is missing or cannot be interpreted as an 3504 * integer, the redraw rate is once every 100ms. 3505 * <p> 3506 * The interpretation of the <code>x</code>, <code>y</code>, 3507 * <code>width</code>, and <code>height</code> arguments depends on 3508 * the value of the <code>infoflags</code> argument. 3509 * 3510 * @param img the image being observed 3511 * @param infoflags see <code>imageUpdate</code> for more information 3512 * @param x the <i>x</i> coordinate 3513 * @param y the <i>y</i> coordinate 3514 * @param w the width 3515 * @param h the height 3516 * @return <code>false</code> if the infoflags indicate that the 3517 * image is completely loaded; <code>true</code> otherwise. 3518 * 3519 * @see java.awt.image.ImageObserver 3520 * @see Graphics#drawImage(Image, int, int, Color, java.awt.image.ImageObserver) 3521 * @see Graphics#drawImage(Image, int, int, java.awt.image.ImageObserver) 3522 * @see Graphics#drawImage(Image, int, int, int, int, Color, java.awt.image.ImageObserver) 3523 * @see Graphics#drawImage(Image, int, int, int, int, java.awt.image.ImageObserver) 3524 * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) 3525 * @since JDK1.0 3526 */ imageUpdate(Image img, int infoflags, int x, int y, int w, int h)3527 public boolean imageUpdate(Image img, int infoflags, 3528 int x, int y, int w, int h) { 3529 int rate = -1; 3530 if ((infoflags & (FRAMEBITS|ALLBITS)) != 0) { 3531 rate = 0; 3532 } else if ((infoflags & SOMEBITS) != 0) { 3533 if (isInc) { 3534 rate = incRate; 3535 if (rate < 0) { 3536 rate = 0; 3537 } 3538 } 3539 } 3540 if (rate >= 0) { 3541 repaint(rate, 0, 0, width, height); 3542 } 3543 return (infoflags & (ALLBITS|ABORT)) == 0; 3544 } 3545 3546 /** 3547 * Creates an image from the specified image producer. 3548 * @param producer the image producer 3549 * @return the image produced 3550 * @since JDK1.0 3551 */ createImage(ImageProducer producer)3552 public Image createImage(ImageProducer producer) { 3553 ComponentPeer peer = this.peer; 3554 if ((peer != null) && ! (peer instanceof LightweightPeer)) { 3555 return peer.createImage(producer); 3556 } 3557 return getToolkit().createImage(producer); 3558 } 3559 3560 /** 3561 * Creates an off-screen drawable image 3562 * to be used for double buffering. 3563 * @param width the specified width 3564 * @param height the specified height 3565 * @return an off-screen drawable image, which can be used for double 3566 * buffering. The return value may be <code>null</code> if the 3567 * component is not displayable. This will always happen if 3568 * <code>GraphicsEnvironment.isHeadless()</code> returns 3569 * <code>true</code>. 3570 * @see #isDisplayable 3571 * @see GraphicsEnvironment#isHeadless 3572 * @since JDK1.0 3573 */ createImage(int width, int height)3574 public Image createImage(int width, int height) { 3575 ComponentPeer peer = this.peer; 3576 if (peer instanceof LightweightPeer) { 3577 if (parent != null) { return parent.createImage(width, height); } 3578 else { return null;} 3579 } else { 3580 return (peer != null) ? peer.createImage(width, height) : null; 3581 } 3582 } 3583 3584 /** 3585 * Creates a volatile off-screen drawable image 3586 * to be used for double buffering. 3587 * @param width the specified width. 3588 * @param height the specified height. 3589 * @return an off-screen drawable image, which can be used for double 3590 * buffering. The return value may be <code>null</code> if the 3591 * component is not displayable. This will always happen if 3592 * <code>GraphicsEnvironment.isHeadless()</code> returns 3593 * <code>true</code>. 3594 * @see java.awt.image.VolatileImage 3595 * @see #isDisplayable 3596 * @see GraphicsEnvironment#isHeadless 3597 * @since 1.4 3598 */ createVolatileImage(int width, int height)3599 public VolatileImage createVolatileImage(int width, int height) { 3600 ComponentPeer peer = this.peer; 3601 if (peer instanceof LightweightPeer) { 3602 if (parent != null) { 3603 return parent.createVolatileImage(width, height); 3604 } 3605 else { return null;} 3606 } else { 3607 return (peer != null) ? 3608 peer.createVolatileImage(width, height) : null; 3609 } 3610 } 3611 3612 /** 3613 * Creates a volatile off-screen drawable image, with the given capabilities. 3614 * The contents of this image may be lost at any time due 3615 * to operating system issues, so the image must be managed 3616 * via the <code>VolatileImage</code> interface. 3617 * @param width the specified width. 3618 * @param height the specified height. 3619 * @param caps the image capabilities 3620 * @exception AWTException if an image with the specified capabilities cannot 3621 * be created 3622 * @return a VolatileImage object, which can be used 3623 * to manage surface contents loss and capabilities. 3624 * @see java.awt.image.VolatileImage 3625 * @since 1.4 3626 */ createVolatileImage(int width, int height, ImageCapabilities caps)3627 public VolatileImage createVolatileImage(int width, int height, 3628 ImageCapabilities caps) throws AWTException { 3629 // REMIND : check caps 3630 return createVolatileImage(width, height); 3631 } 3632 3633 /** 3634 * Prepares an image for rendering on this component. The image 3635 * data is downloaded asynchronously in another thread and the 3636 * appropriate screen representation of the image is generated. 3637 * @param image the <code>Image</code> for which to 3638 * prepare a screen representation 3639 * @param observer the <code>ImageObserver</code> object 3640 * to be notified as the image is being prepared 3641 * @return <code>true</code> if the image has already been fully 3642 * prepared; <code>false</code> otherwise 3643 * @since JDK1.0 3644 */ prepareImage(Image image, ImageObserver observer)3645 public boolean prepareImage(Image image, ImageObserver observer) { 3646 return prepareImage(image, -1, -1, observer); 3647 } 3648 3649 /** 3650 * Prepares an image for rendering on this component at the 3651 * specified width and height. 3652 * <p> 3653 * The image data is downloaded asynchronously in another thread, 3654 * and an appropriately scaled screen representation of the image is 3655 * generated. 3656 * @param image the instance of <code>Image</code> 3657 * for which to prepare a screen representation 3658 * @param width the width of the desired screen representation 3659 * @param height the height of the desired screen representation 3660 * @param observer the <code>ImageObserver</code> object 3661 * to be notified as the image is being prepared 3662 * @return <code>true</code> if the image has already been fully 3663 * prepared; <code>false</code> otherwise 3664 * @see java.awt.image.ImageObserver 3665 * @since JDK1.0 3666 */ prepareImage(Image image, int width, int height, ImageObserver observer)3667 public boolean prepareImage(Image image, int width, int height, 3668 ImageObserver observer) { 3669 ComponentPeer peer = this.peer; 3670 if (peer instanceof LightweightPeer) { 3671 return (parent != null) 3672 ? parent.prepareImage(image, width, height, observer) 3673 : getToolkit().prepareImage(image, width, height, observer); 3674 } else { 3675 return (peer != null) 3676 ? peer.prepareImage(image, width, height, observer) 3677 : getToolkit().prepareImage(image, width, height, observer); 3678 } 3679 } 3680 3681 /** 3682 * Returns the status of the construction of a screen representation 3683 * of the specified image. 3684 * <p> 3685 * This method does not cause the image to begin loading. An 3686 * application must use the <code>prepareImage</code> method 3687 * to force the loading of an image. 3688 * <p> 3689 * Information on the flags returned by this method can be found 3690 * with the discussion of the <code>ImageObserver</code> interface. 3691 * @param image the <code>Image</code> object whose status 3692 * is being checked 3693 * @param observer the <code>ImageObserver</code> 3694 * object to be notified as the image is being prepared 3695 * @return the bitwise inclusive <b>OR</b> of 3696 * <code>ImageObserver</code> flags indicating what 3697 * information about the image is currently available 3698 * @see #prepareImage(Image, int, int, java.awt.image.ImageObserver) 3699 * @see Toolkit#checkImage(Image, int, int, java.awt.image.ImageObserver) 3700 * @see java.awt.image.ImageObserver 3701 * @since JDK1.0 3702 */ checkImage(Image image, ImageObserver observer)3703 public int checkImage(Image image, ImageObserver observer) { 3704 return checkImage(image, -1, -1, observer); 3705 } 3706 3707 /** 3708 * Returns the status of the construction of a screen representation 3709 * of the specified image. 3710 * <p> 3711 * This method does not cause the image to begin loading. An 3712 * application must use the <code>prepareImage</code> method 3713 * to force the loading of an image. 3714 * <p> 3715 * The <code>checkImage</code> method of <code>Component</code> 3716 * calls its peer's <code>checkImage</code> method to calculate 3717 * the flags. If this component does not yet have a peer, the 3718 * component's toolkit's <code>checkImage</code> method is called 3719 * instead. 3720 * <p> 3721 * Information on the flags returned by this method can be found 3722 * with the discussion of the <code>ImageObserver</code> interface. 3723 * @param image the <code>Image</code> object whose status 3724 * is being checked 3725 * @param width the width of the scaled version 3726 * whose status is to be checked 3727 * @param height the height of the scaled version 3728 * whose status is to be checked 3729 * @param observer the <code>ImageObserver</code> object 3730 * to be notified as the image is being prepared 3731 * @return the bitwise inclusive <b>OR</b> of 3732 * <code>ImageObserver</code> flags indicating what 3733 * information about the image is currently available 3734 * @see #prepareImage(Image, int, int, java.awt.image.ImageObserver) 3735 * @see Toolkit#checkImage(Image, int, int, java.awt.image.ImageObserver) 3736 * @see java.awt.image.ImageObserver 3737 * @since JDK1.0 3738 */ checkImage(Image image, int width, int height, ImageObserver observer)3739 public int checkImage(Image image, int width, int height, 3740 ImageObserver observer) { 3741 ComponentPeer peer = this.peer; 3742 if (peer instanceof LightweightPeer) { 3743 return (parent != null) 3744 ? parent.checkImage(image, width, height, observer) 3745 : getToolkit().checkImage(image, width, height, observer); 3746 } else { 3747 return (peer != null) 3748 ? peer.checkImage(image, width, height, observer) 3749 : getToolkit().checkImage(image, width, height, observer); 3750 } 3751 } 3752 3753 /** 3754 * Creates a new strategy for multi-buffering on this component. 3755 * Multi-buffering is useful for rendering performance. This method 3756 * attempts to create the best strategy available with the number of 3757 * buffers supplied. It will always create a <code>BufferStrategy</code> 3758 * with that number of buffers. 3759 * A page-flipping strategy is attempted first, then a blitting strategy 3760 * using accelerated buffers. Finally, an unaccelerated blitting 3761 * strategy is used. 3762 * <p> 3763 * Each time this method is called, 3764 * the existing buffer strategy for this component is discarded. 3765 * @param numBuffers number of buffers to create, including the front buffer 3766 * @exception IllegalArgumentException if numBuffers is less than 1. 3767 * @exception IllegalStateException if the component is not displayable 3768 * @see #isDisplayable 3769 * @see Window#getBufferStrategy() 3770 * @see Canvas#getBufferStrategy() 3771 * @since 1.4 3772 */ createBufferStrategy(int numBuffers)3773 void createBufferStrategy(int numBuffers) { 3774 BufferCapabilities bufferCaps; 3775 if (numBuffers > 1) { 3776 // Try to create a page-flipping strategy 3777 bufferCaps = new BufferCapabilities(new ImageCapabilities(true), 3778 new ImageCapabilities(true), 3779 BufferCapabilities.FlipContents.UNDEFINED); 3780 try { 3781 createBufferStrategy(numBuffers, bufferCaps); 3782 return; // Success 3783 } catch (AWTException e) { 3784 // Failed 3785 } 3786 } 3787 // Try a blitting (but still accelerated) strategy 3788 bufferCaps = new BufferCapabilities(new ImageCapabilities(true), 3789 new ImageCapabilities(true), 3790 null); 3791 try { 3792 createBufferStrategy(numBuffers, bufferCaps); 3793 return; // Success 3794 } catch (AWTException e) { 3795 // Failed 3796 } 3797 // Try an unaccelerated blitting strategy 3798 bufferCaps = new BufferCapabilities(new ImageCapabilities(false), 3799 new ImageCapabilities(false), 3800 null); 3801 try { 3802 createBufferStrategy(numBuffers, bufferCaps); 3803 return; // Success 3804 } catch (AWTException e) { 3805 // Code should never reach here (an unaccelerated blitting 3806 // strategy should always work) 3807 throw new InternalError("Could not create a buffer strategy", e); 3808 } 3809 } 3810 3811 /** 3812 * Creates a new strategy for multi-buffering on this component with the 3813 * required buffer capabilities. This is useful, for example, if only 3814 * accelerated memory or page flipping is desired (as specified by the 3815 * buffer capabilities). 3816 * <p> 3817 * Each time this method 3818 * is called, <code>dispose</code> will be invoked on the existing 3819 * <code>BufferStrategy</code>. 3820 * @param numBuffers number of buffers to create 3821 * @param caps the required capabilities for creating the buffer strategy; 3822 * cannot be <code>null</code> 3823 * @exception AWTException if the capabilities supplied could not be 3824 * supported or met; this may happen, for example, if there is not enough 3825 * accelerated memory currently available, or if page flipping is specified 3826 * but not possible. 3827 * @exception IllegalArgumentException if numBuffers is less than 1, or if 3828 * caps is <code>null</code> 3829 * @see Window#getBufferStrategy() 3830 * @see Canvas#getBufferStrategy() 3831 * @since 1.4 3832 */ createBufferStrategy(int numBuffers, BufferCapabilities caps)3833 void createBufferStrategy(int numBuffers, 3834 BufferCapabilities caps) throws AWTException { 3835 // Check arguments 3836 if (numBuffers < 1) { 3837 throw new IllegalArgumentException( 3838 "Number of buffers must be at least 1"); 3839 } 3840 if (caps == null) { 3841 throw new IllegalArgumentException("No capabilities specified"); 3842 } 3843 // Destroy old buffers 3844 if (bufferStrategy != null) { 3845 bufferStrategy.dispose(); 3846 } 3847 if (numBuffers == 1) { 3848 bufferStrategy = new SingleBufferStrategy(caps); 3849 } else { 3850 SunGraphicsEnvironment sge = (SunGraphicsEnvironment) 3851 GraphicsEnvironment.getLocalGraphicsEnvironment(); 3852 if (!caps.isPageFlipping() && sge.isFlipStrategyPreferred(peer)) { 3853 caps = new ProxyCapabilities(caps); 3854 } 3855 // assert numBuffers > 1; 3856 if (caps.isPageFlipping()) { 3857 bufferStrategy = new FlipSubRegionBufferStrategy(numBuffers, caps); 3858 } else { 3859 bufferStrategy = new BltSubRegionBufferStrategy(numBuffers, caps); 3860 } 3861 } 3862 } 3863 3864 /** 3865 * This is a proxy capabilities class used when a FlipBufferStrategy 3866 * is created instead of the requested Blit strategy. 3867 * 3868 * @see sun.java2d.SunGraphicsEnvironment#isFlipStrategyPreferred(ComponentPeer) 3869 */ 3870 private class ProxyCapabilities extends ExtendedBufferCapabilities { 3871 private BufferCapabilities orig; ProxyCapabilities(BufferCapabilities orig)3872 private ProxyCapabilities(BufferCapabilities orig) { 3873 super(orig.getFrontBufferCapabilities(), 3874 orig.getBackBufferCapabilities(), 3875 orig.getFlipContents() == 3876 BufferCapabilities.FlipContents.BACKGROUND ? 3877 BufferCapabilities.FlipContents.BACKGROUND : 3878 BufferCapabilities.FlipContents.COPIED); 3879 this.orig = orig; 3880 } 3881 } 3882 3883 /** 3884 * @return the buffer strategy used by this component 3885 * @see Window#createBufferStrategy 3886 * @see Canvas#createBufferStrategy 3887 * @since 1.4 3888 */ getBufferStrategy()3889 BufferStrategy getBufferStrategy() { 3890 return bufferStrategy; 3891 } 3892 3893 /** 3894 * @return the back buffer currently used by this component's 3895 * BufferStrategy. If there is no BufferStrategy or no 3896 * back buffer, this method returns null. 3897 */ getBackBuffer()3898 Image getBackBuffer() { 3899 if (bufferStrategy != null) { 3900 if (bufferStrategy instanceof BltBufferStrategy) { 3901 BltBufferStrategy bltBS = (BltBufferStrategy)bufferStrategy; 3902 return bltBS.getBackBuffer(); 3903 } else if (bufferStrategy instanceof FlipBufferStrategy) { 3904 FlipBufferStrategy flipBS = (FlipBufferStrategy)bufferStrategy; 3905 return flipBS.getBackBuffer(); 3906 } 3907 } 3908 return null; 3909 } 3910 3911 /** 3912 * Inner class for flipping buffers on a component. That component must 3913 * be a <code>Canvas</code> or <code>Window</code>. 3914 * @see Canvas 3915 * @see Window 3916 * @see java.awt.image.BufferStrategy 3917 * @author Michael Martak 3918 * @since 1.4 3919 */ 3920 protected class FlipBufferStrategy extends BufferStrategy { 3921 /** 3922 * The number of buffers 3923 */ 3924 protected int numBuffers; // = 0 3925 /** 3926 * The buffering capabilities 3927 */ 3928 protected BufferCapabilities caps; // = null 3929 /** 3930 * The drawing buffer 3931 */ 3932 protected Image drawBuffer; // = null 3933 /** 3934 * The drawing buffer as a volatile image 3935 */ 3936 protected VolatileImage drawVBuffer; // = null 3937 /** 3938 * Whether or not the drawing buffer has been recently restored from 3939 * a lost state. 3940 */ 3941 protected boolean validatedContents; // = false 3942 /** 3943 * Size of the back buffers. (Note: these fields were added in 6.0 3944 * but kept package-private to avoid exposing them in the spec. 3945 * None of these fields/methods really should have been marked 3946 * protected when they were introduced in 1.4, but now we just have 3947 * to live with that decision.) 3948 */ 3949 int width; 3950 int height; 3951 3952 /** 3953 * Creates a new flipping buffer strategy for this component. 3954 * The component must be a <code>Canvas</code> or <code>Window</code>. 3955 * @see Canvas 3956 * @see Window 3957 * @param numBuffers the number of buffers 3958 * @param caps the capabilities of the buffers 3959 * @exception AWTException if the capabilities supplied could not be 3960 * supported or met 3961 * @exception ClassCastException if the component is not a canvas or 3962 * window. 3963 * @exception IllegalStateException if the component has no peer 3964 * @exception IllegalArgumentException if {@code numBuffers} is less than two, 3965 * or if {@code BufferCapabilities.isPageFlipping} is not 3966 * {@code true}. 3967 * @see #createBuffers(int, BufferCapabilities) 3968 */ FlipBufferStrategy(int numBuffers, BufferCapabilities caps)3969 protected FlipBufferStrategy(int numBuffers, BufferCapabilities caps) 3970 throws AWTException 3971 { 3972 if (!(Component.this instanceof Window) && 3973 !(Component.this instanceof Canvas)) 3974 { 3975 throw new ClassCastException( 3976 "Component must be a Canvas or Window"); 3977 } 3978 this.numBuffers = numBuffers; 3979 this.caps = caps; 3980 createBuffers(numBuffers, caps); 3981 } 3982 3983 /** 3984 * Creates one or more complex, flipping buffers with the given 3985 * capabilities. 3986 * @param numBuffers number of buffers to create; must be greater than 3987 * one 3988 * @param caps the capabilities of the buffers. 3989 * <code>BufferCapabilities.isPageFlipping</code> must be 3990 * <code>true</code>. 3991 * @exception AWTException if the capabilities supplied could not be 3992 * supported or met 3993 * @exception IllegalStateException if the component has no peer 3994 * @exception IllegalArgumentException if numBuffers is less than two, 3995 * or if <code>BufferCapabilities.isPageFlipping</code> is not 3996 * <code>true</code>. 3997 * @see java.awt.BufferCapabilities#isPageFlipping() 3998 */ createBuffers(int numBuffers, BufferCapabilities caps)3999 protected void createBuffers(int numBuffers, BufferCapabilities caps) 4000 throws AWTException 4001 { 4002 if (numBuffers < 2) { 4003 throw new IllegalArgumentException( 4004 "Number of buffers cannot be less than two"); 4005 } else if (peer == null) { 4006 throw new IllegalStateException( 4007 "Component must have a valid peer"); 4008 } else if (caps == null || !caps.isPageFlipping()) { 4009 throw new IllegalArgumentException( 4010 "Page flipping capabilities must be specified"); 4011 } 4012 4013 // save the current bounds 4014 width = getWidth(); 4015 height = getHeight(); 4016 4017 if (drawBuffer != null) { 4018 // dispose the existing backbuffers 4019 drawBuffer = null; 4020 drawVBuffer = null; 4021 destroyBuffers(); 4022 // ... then recreate the backbuffers 4023 } 4024 4025 if (caps instanceof ExtendedBufferCapabilities) { 4026 ExtendedBufferCapabilities ebc = 4027 (ExtendedBufferCapabilities)caps; 4028 if (ebc.getVSync() == VSYNC_ON) { 4029 // if this buffer strategy is not allowed to be v-synced, 4030 // change the caps that we pass to the peer but keep on 4031 // trying to create v-synced buffers; 4032 // do not throw IAE here in case it is disallowed, see 4033 // ExtendedBufferCapabilities for more info 4034 if (!VSyncedBSManager.vsyncAllowed(this)) { 4035 caps = ebc.derive(VSYNC_DEFAULT); 4036 } 4037 } 4038 } 4039 4040 peer.createBuffers(numBuffers, caps); 4041 updateInternalBuffers(); 4042 } 4043 4044 /** 4045 * Updates internal buffers (both volatile and non-volatile) 4046 * by requesting the back-buffer from the peer. 4047 */ updateInternalBuffers()4048 private void updateInternalBuffers() { 4049 // get the images associated with the draw buffer 4050 drawBuffer = getBackBuffer(); 4051 if (drawBuffer instanceof VolatileImage) { 4052 drawVBuffer = (VolatileImage)drawBuffer; 4053 } else { 4054 drawVBuffer = null; 4055 } 4056 } 4057 4058 /** 4059 * @return direct access to the back buffer, as an image. 4060 * @exception IllegalStateException if the buffers have not yet 4061 * been created 4062 */ getBackBuffer()4063 protected Image getBackBuffer() { 4064 if (peer != null) { 4065 return peer.getBackBuffer(); 4066 } else { 4067 throw new IllegalStateException( 4068 "Component must have a valid peer"); 4069 } 4070 } 4071 4072 /** 4073 * Flipping moves the contents of the back buffer to the front buffer, 4074 * either by copying or by moving the video pointer. 4075 * @param flipAction an integer value describing the flipping action 4076 * for the contents of the back buffer. This should be one of the 4077 * values of the <code>BufferCapabilities.FlipContents</code> 4078 * property. 4079 * @exception IllegalStateException if the buffers have not yet 4080 * been created 4081 * @see java.awt.BufferCapabilities#getFlipContents() 4082 */ flip(BufferCapabilities.FlipContents flipAction)4083 protected void flip(BufferCapabilities.FlipContents flipAction) { 4084 if (peer != null) { 4085 Image backBuffer = getBackBuffer(); 4086 if (backBuffer != null) { 4087 peer.flip(0, 0, 4088 backBuffer.getWidth(null), 4089 backBuffer.getHeight(null), flipAction); 4090 } 4091 } else { 4092 throw new IllegalStateException( 4093 "Component must have a valid peer"); 4094 } 4095 } 4096 flipSubRegion(int x1, int y1, int x2, int y2, BufferCapabilities.FlipContents flipAction)4097 void flipSubRegion(int x1, int y1, int x2, int y2, 4098 BufferCapabilities.FlipContents flipAction) 4099 { 4100 if (peer != null) { 4101 peer.flip(x1, y1, x2, y2, flipAction); 4102 } else { 4103 throw new IllegalStateException( 4104 "Component must have a valid peer"); 4105 } 4106 } 4107 4108 /** 4109 * Destroys the buffers created through this object 4110 */ destroyBuffers()4111 protected void destroyBuffers() { 4112 VSyncedBSManager.releaseVsync(this); 4113 if (peer != null) { 4114 peer.destroyBuffers(); 4115 } else { 4116 throw new IllegalStateException( 4117 "Component must have a valid peer"); 4118 } 4119 } 4120 4121 /** 4122 * @return the buffering capabilities of this strategy 4123 */ getCapabilities()4124 public BufferCapabilities getCapabilities() { 4125 if (caps instanceof ProxyCapabilities) { 4126 return ((ProxyCapabilities)caps).orig; 4127 } else { 4128 return caps; 4129 } 4130 } 4131 4132 /** 4133 * @return the graphics on the drawing buffer. This method may not 4134 * be synchronized for performance reasons; use of this method by multiple 4135 * threads should be handled at the application level. Disposal of the 4136 * graphics object must be handled by the application. 4137 */ getDrawGraphics()4138 public Graphics getDrawGraphics() { 4139 revalidate(); 4140 return drawBuffer.getGraphics(); 4141 } 4142 4143 /** 4144 * Restore the drawing buffer if it has been lost 4145 */ revalidate()4146 protected void revalidate() { 4147 revalidate(true); 4148 } 4149 revalidate(boolean checkSize)4150 void revalidate(boolean checkSize) { 4151 validatedContents = false; 4152 4153 if (checkSize && (getWidth() != width || getHeight() != height)) { 4154 // component has been resized; recreate the backbuffers 4155 try { 4156 createBuffers(numBuffers, caps); 4157 } catch (AWTException e) { 4158 // shouldn't be possible 4159 } 4160 validatedContents = true; 4161 } 4162 4163 // get the buffers from the peer every time since they 4164 // might have been replaced in response to a display change event 4165 updateInternalBuffers(); 4166 4167 // now validate the backbuffer 4168 if (drawVBuffer != null) { 4169 GraphicsConfiguration gc = 4170 getGraphicsConfiguration_NoClientCode(); 4171 int returnCode = drawVBuffer.validate(gc); 4172 if (returnCode == VolatileImage.IMAGE_INCOMPATIBLE) { 4173 try { 4174 createBuffers(numBuffers, caps); 4175 } catch (AWTException e) { 4176 // shouldn't be possible 4177 } 4178 if (drawVBuffer != null) { 4179 // backbuffers were recreated, so validate again 4180 drawVBuffer.validate(gc); 4181 } 4182 validatedContents = true; 4183 } else if (returnCode == VolatileImage.IMAGE_RESTORED) { 4184 validatedContents = true; 4185 } 4186 } 4187 } 4188 4189 /** 4190 * @return whether the drawing buffer was lost since the last call to 4191 * <code>getDrawGraphics</code> 4192 */ contentsLost()4193 public boolean contentsLost() { 4194 if (drawVBuffer == null) { 4195 return false; 4196 } 4197 return drawVBuffer.contentsLost(); 4198 } 4199 4200 /** 4201 * @return whether the drawing buffer was recently restored from a lost 4202 * state and reinitialized to the default background color (white) 4203 */ contentsRestored()4204 public boolean contentsRestored() { 4205 return validatedContents; 4206 } 4207 4208 /** 4209 * Makes the next available buffer visible by either blitting or 4210 * flipping. 4211 */ show()4212 public void show() { 4213 flip(caps.getFlipContents()); 4214 } 4215 4216 /** 4217 * Makes specified region of the the next available buffer visible 4218 * by either blitting or flipping. 4219 */ showSubRegion(int x1, int y1, int x2, int y2)4220 void showSubRegion(int x1, int y1, int x2, int y2) { 4221 flipSubRegion(x1, y1, x2, y2, caps.getFlipContents()); 4222 } 4223 4224 /** 4225 * {@inheritDoc} 4226 * @since 1.6 4227 */ dispose()4228 public void dispose() { 4229 if (Component.this.bufferStrategy == this) { 4230 Component.this.bufferStrategy = null; 4231 if (peer != null) { 4232 destroyBuffers(); 4233 } 4234 } 4235 } 4236 4237 } // Inner class FlipBufferStrategy 4238 4239 /** 4240 * Inner class for blitting offscreen surfaces to a component. 4241 * 4242 * @author Michael Martak 4243 * @since 1.4 4244 */ 4245 protected class BltBufferStrategy extends BufferStrategy { 4246 4247 /** 4248 * The buffering capabilities 4249 */ 4250 protected BufferCapabilities caps; // = null 4251 /** 4252 * The back buffers 4253 */ 4254 protected VolatileImage[] backBuffers; // = null 4255 /** 4256 * Whether or not the drawing buffer has been recently restored from 4257 * a lost state. 4258 */ 4259 protected boolean validatedContents; // = false 4260 /** 4261 * Size of the back buffers 4262 */ 4263 protected int width; 4264 protected int height; 4265 4266 /** 4267 * Insets for the hosting Component. The size of the back buffer 4268 * is constrained by these. 4269 */ 4270 private Insets insets; 4271 4272 /** 4273 * Creates a new blt buffer strategy around a component 4274 * @param numBuffers number of buffers to create, including the 4275 * front buffer 4276 * @param caps the capabilities of the buffers 4277 */ BltBufferStrategy(int numBuffers, BufferCapabilities caps)4278 protected BltBufferStrategy(int numBuffers, BufferCapabilities caps) { 4279 this.caps = caps; 4280 createBackBuffers(numBuffers - 1); 4281 } 4282 4283 /** 4284 * {@inheritDoc} 4285 * @since 1.6 4286 */ dispose()4287 public void dispose() { 4288 if (backBuffers != null) { 4289 for (int counter = backBuffers.length - 1; counter >= 0; 4290 counter--) { 4291 if (backBuffers[counter] != null) { 4292 backBuffers[counter].flush(); 4293 backBuffers[counter] = null; 4294 } 4295 } 4296 } 4297 if (Component.this.bufferStrategy == this) { 4298 Component.this.bufferStrategy = null; 4299 } 4300 } 4301 4302 /** 4303 * Creates the back buffers 4304 */ createBackBuffers(int numBuffers)4305 protected void createBackBuffers(int numBuffers) { 4306 if (numBuffers == 0) { 4307 backBuffers = null; 4308 } else { 4309 // save the current bounds 4310 width = getWidth(); 4311 height = getHeight(); 4312 insets = getInsets_NoClientCode(); 4313 int iWidth = width - insets.left - insets.right; 4314 int iHeight = height - insets.top - insets.bottom; 4315 4316 // It is possible for the component's width and/or height 4317 // to be 0 here. Force the size of the backbuffers to 4318 // be > 0 so that creating the image won't fail. 4319 iWidth = Math.max(1, iWidth); 4320 iHeight = Math.max(1, iHeight); 4321 if (backBuffers == null) { 4322 backBuffers = new VolatileImage[numBuffers]; 4323 } else { 4324 // flush any existing backbuffers 4325 for (int i = 0; i < numBuffers; i++) { 4326 if (backBuffers[i] != null) { 4327 backBuffers[i].flush(); 4328 backBuffers[i] = null; 4329 } 4330 } 4331 } 4332 4333 // create the backbuffers 4334 for (int i = 0; i < numBuffers; i++) { 4335 backBuffers[i] = createVolatileImage(iWidth, iHeight); 4336 } 4337 } 4338 } 4339 4340 /** 4341 * @return the buffering capabilities of this strategy 4342 */ getCapabilities()4343 public BufferCapabilities getCapabilities() { 4344 return caps; 4345 } 4346 4347 /** 4348 * @return the draw graphics 4349 */ getDrawGraphics()4350 public Graphics getDrawGraphics() { 4351 revalidate(); 4352 Image backBuffer = getBackBuffer(); 4353 if (backBuffer == null) { 4354 return getGraphics(); 4355 } 4356 SunGraphics2D g = (SunGraphics2D)backBuffer.getGraphics(); 4357 g.constrain(-insets.left, -insets.top, 4358 backBuffer.getWidth(null) + insets.left, 4359 backBuffer.getHeight(null) + insets.top); 4360 return g; 4361 } 4362 4363 /** 4364 * @return direct access to the back buffer, as an image. 4365 * If there is no back buffer, returns null. 4366 */ getBackBuffer()4367 Image getBackBuffer() { 4368 if (backBuffers != null) { 4369 return backBuffers[backBuffers.length - 1]; 4370 } else { 4371 return null; 4372 } 4373 } 4374 4375 /** 4376 * Makes the next available buffer visible. 4377 */ show()4378 public void show() { 4379 showSubRegion(insets.left, insets.top, 4380 width - insets.right, 4381 height - insets.bottom); 4382 } 4383 4384 /** 4385 * Package-private method to present a specific rectangular area 4386 * of this buffer. This class currently shows only the entire 4387 * buffer, by calling showSubRegion() with the full dimensions of 4388 * the buffer. Subclasses (e.g., BltSubRegionBufferStrategy 4389 * and FlipSubRegionBufferStrategy) may have region-specific show 4390 * methods that call this method with actual sub regions of the 4391 * buffer. 4392 */ showSubRegion(int x1, int y1, int x2, int y2)4393 void showSubRegion(int x1, int y1, int x2, int y2) { 4394 if (backBuffers == null) { 4395 return; 4396 } 4397 // Adjust location to be relative to client area. 4398 x1 -= insets.left; 4399 x2 -= insets.left; 4400 y1 -= insets.top; 4401 y2 -= insets.top; 4402 Graphics g = getGraphics_NoClientCode(); 4403 if (g == null) { 4404 // Not showing, bail 4405 return; 4406 } 4407 try { 4408 // First image copy is in terms of Frame's coordinates, need 4409 // to translate to client area. 4410 g.translate(insets.left, insets.top); 4411 for (int i = 0; i < backBuffers.length; i++) { 4412 g.drawImage(backBuffers[i], 4413 x1, y1, x2, y2, 4414 x1, y1, x2, y2, 4415 null); 4416 g.dispose(); 4417 g = null; 4418 g = backBuffers[i].getGraphics(); 4419 } 4420 } finally { 4421 if (g != null) { 4422 g.dispose(); 4423 } 4424 } 4425 } 4426 4427 /** 4428 * Restore the drawing buffer if it has been lost 4429 */ revalidate()4430 protected void revalidate() { 4431 revalidate(true); 4432 } 4433 revalidate(boolean checkSize)4434 void revalidate(boolean checkSize) { 4435 validatedContents = false; 4436 4437 if (backBuffers == null) { 4438 return; 4439 } 4440 4441 if (checkSize) { 4442 Insets insets = getInsets_NoClientCode(); 4443 if (getWidth() != width || getHeight() != height || 4444 !insets.equals(this.insets)) { 4445 // component has been resized; recreate the backbuffers 4446 createBackBuffers(backBuffers.length); 4447 validatedContents = true; 4448 } 4449 } 4450 4451 // now validate the backbuffer 4452 GraphicsConfiguration gc = getGraphicsConfiguration_NoClientCode(); 4453 int returnCode = 4454 backBuffers[backBuffers.length - 1].validate(gc); 4455 if (returnCode == VolatileImage.IMAGE_INCOMPATIBLE) { 4456 if (checkSize) { 4457 createBackBuffers(backBuffers.length); 4458 // backbuffers were recreated, so validate again 4459 backBuffers[backBuffers.length - 1].validate(gc); 4460 } 4461 // else case means we're called from Swing on the toolkit 4462 // thread, don't recreate buffers as that'll deadlock 4463 // (creating VolatileImages invokes getting GraphicsConfig 4464 // which grabs treelock). 4465 validatedContents = true; 4466 } else if (returnCode == VolatileImage.IMAGE_RESTORED) { 4467 validatedContents = true; 4468 } 4469 } 4470 4471 /** 4472 * @return whether the drawing buffer was lost since the last call to 4473 * <code>getDrawGraphics</code> 4474 */ contentsLost()4475 public boolean contentsLost() { 4476 if (backBuffers == null) { 4477 return false; 4478 } else { 4479 return backBuffers[backBuffers.length - 1].contentsLost(); 4480 } 4481 } 4482 4483 /** 4484 * @return whether the drawing buffer was recently restored from a lost 4485 * state and reinitialized to the default background color (white) 4486 */ contentsRestored()4487 public boolean contentsRestored() { 4488 return validatedContents; 4489 } 4490 } // Inner class BltBufferStrategy 4491 4492 /** 4493 * Private class to perform sub-region flipping. 4494 */ 4495 private class FlipSubRegionBufferStrategy extends FlipBufferStrategy 4496 implements SubRegionShowable 4497 { 4498 FlipSubRegionBufferStrategy(int numBuffers, BufferCapabilities caps)4499 protected FlipSubRegionBufferStrategy(int numBuffers, 4500 BufferCapabilities caps) 4501 throws AWTException 4502 { 4503 super(numBuffers, caps); 4504 } 4505 show(int x1, int y1, int x2, int y2)4506 public void show(int x1, int y1, int x2, int y2) { 4507 showSubRegion(x1, y1, x2, y2); 4508 } 4509 4510 // This is invoked by Swing on the toolkit thread. showIfNotLost(int x1, int y1, int x2, int y2)4511 public boolean showIfNotLost(int x1, int y1, int x2, int y2) { 4512 if (!contentsLost()) { 4513 showSubRegion(x1, y1, x2, y2); 4514 return !contentsLost(); 4515 } 4516 return false; 4517 } 4518 } 4519 4520 /** 4521 * Private class to perform sub-region blitting. Swing will use 4522 * this subclass via the SubRegionShowable interface in order to 4523 * copy only the area changed during a repaint. 4524 * See javax.swing.BufferStrategyPaintManager. 4525 */ 4526 private class BltSubRegionBufferStrategy extends BltBufferStrategy 4527 implements SubRegionShowable 4528 { 4529 BltSubRegionBufferStrategy(int numBuffers, BufferCapabilities caps)4530 protected BltSubRegionBufferStrategy(int numBuffers, 4531 BufferCapabilities caps) 4532 { 4533 super(numBuffers, caps); 4534 } 4535 show(int x1, int y1, int x2, int y2)4536 public void show(int x1, int y1, int x2, int y2) { 4537 showSubRegion(x1, y1, x2, y2); 4538 } 4539 4540 // This method is called by Swing on the toolkit thread. showIfNotLost(int x1, int y1, int x2, int y2)4541 public boolean showIfNotLost(int x1, int y1, int x2, int y2) { 4542 if (!contentsLost()) { 4543 showSubRegion(x1, y1, x2, y2); 4544 return !contentsLost(); 4545 } 4546 return false; 4547 } 4548 } 4549 4550 /** 4551 * Inner class for flipping buffers on a component. That component must 4552 * be a <code>Canvas</code> or <code>Window</code>. 4553 * @see Canvas 4554 * @see Window 4555 * @see java.awt.image.BufferStrategy 4556 * @author Michael Martak 4557 * @since 1.4 4558 */ 4559 private class SingleBufferStrategy extends BufferStrategy { 4560 4561 private BufferCapabilities caps; 4562 SingleBufferStrategy(BufferCapabilities caps)4563 public SingleBufferStrategy(BufferCapabilities caps) { 4564 this.caps = caps; 4565 } getCapabilities()4566 public BufferCapabilities getCapabilities() { 4567 return caps; 4568 } getDrawGraphics()4569 public Graphics getDrawGraphics() { 4570 return getGraphics(); 4571 } contentsLost()4572 public boolean contentsLost() { 4573 return false; 4574 } contentsRestored()4575 public boolean contentsRestored() { 4576 return false; 4577 } show()4578 public void show() { 4579 // Do nothing 4580 } 4581 } // Inner class SingleBufferStrategy 4582 4583 /** 4584 * Sets whether or not paint messages received from the operating system 4585 * should be ignored. This does not affect paint events generated in 4586 * software by the AWT, unless they are an immediate response to an 4587 * OS-level paint message. 4588 * <p> 4589 * This is useful, for example, if running under full-screen mode and 4590 * better performance is desired, or if page-flipping is used as the 4591 * buffer strategy. 4592 * 4593 * @since 1.4 4594 * @see #getIgnoreRepaint 4595 * @see Canvas#createBufferStrategy 4596 * @see Window#createBufferStrategy 4597 * @see java.awt.image.BufferStrategy 4598 * @see GraphicsDevice#setFullScreenWindow 4599 */ setIgnoreRepaint(boolean ignoreRepaint)4600 public void setIgnoreRepaint(boolean ignoreRepaint) { 4601 this.ignoreRepaint = ignoreRepaint; 4602 } 4603 4604 /** 4605 * @return whether or not paint messages received from the operating system 4606 * should be ignored. 4607 * 4608 * @since 1.4 4609 * @see #setIgnoreRepaint 4610 */ getIgnoreRepaint()4611 public boolean getIgnoreRepaint() { 4612 return ignoreRepaint; 4613 } 4614 4615 /** 4616 * Checks whether this component "contains" the specified point, 4617 * where <code>x</code> and <code>y</code> are defined to be 4618 * relative to the coordinate system of this component. 4619 * @param x the <i>x</i> coordinate of the point 4620 * @param y the <i>y</i> coordinate of the point 4621 * @see #getComponentAt(int, int) 4622 * @since JDK1.1 4623 */ contains(int x, int y)4624 public boolean contains(int x, int y) { 4625 return inside(x, y); 4626 } 4627 4628 /** 4629 * @deprecated As of JDK version 1.1, 4630 * replaced by contains(int, int). 4631 */ 4632 @Deprecated inside(int x, int y)4633 public boolean inside(int x, int y) { 4634 return (x >= 0) && (x < width) && (y >= 0) && (y < height); 4635 } 4636 4637 /** 4638 * Checks whether this component "contains" the specified point, 4639 * where the point's <i>x</i> and <i>y</i> coordinates are defined 4640 * to be relative to the coordinate system of this component. 4641 * @param p the point 4642 * @throws NullPointerException if {@code p} is {@code null} 4643 * @see #getComponentAt(Point) 4644 * @since JDK1.1 4645 */ contains(Point p)4646 public boolean contains(Point p) { 4647 return contains(p.x, p.y); 4648 } 4649 4650 /** 4651 * Determines if this component or one of its immediate 4652 * subcomponents contains the (<i>x</i>, <i>y</i>) location, 4653 * and if so, returns the containing component. This method only 4654 * looks one level deep. If the point (<i>x</i>, <i>y</i>) is 4655 * inside a subcomponent that itself has subcomponents, it does not 4656 * go looking down the subcomponent tree. 4657 * <p> 4658 * The <code>locate</code> method of <code>Component</code> simply 4659 * returns the component itself if the (<i>x</i>, <i>y</i>) 4660 * coordinate location is inside its bounding box, and <code>null</code> 4661 * otherwise. 4662 * @param x the <i>x</i> coordinate 4663 * @param y the <i>y</i> coordinate 4664 * @return the component or subcomponent that contains the 4665 * (<i>x</i>, <i>y</i>) location; 4666 * <code>null</code> if the location 4667 * is outside this component 4668 * @see #contains(int, int) 4669 * @since JDK1.0 4670 */ getComponentAt(int x, int y)4671 public Component getComponentAt(int x, int y) { 4672 return locate(x, y); 4673 } 4674 4675 /** 4676 * @deprecated As of JDK version 1.1, 4677 * replaced by getComponentAt(int, int). 4678 */ 4679 @Deprecated locate(int x, int y)4680 public Component locate(int x, int y) { 4681 return contains(x, y) ? this : null; 4682 } 4683 4684 /** 4685 * Returns the component or subcomponent that contains the 4686 * specified point. 4687 * @param p the point 4688 * @see java.awt.Component#contains 4689 * @since JDK1.1 4690 */ getComponentAt(Point p)4691 public Component getComponentAt(Point p) { 4692 return getComponentAt(p.x, p.y); 4693 } 4694 4695 /** 4696 * @deprecated As of JDK version 1.1, 4697 * replaced by <code>dispatchEvent(AWTEvent e)</code>. 4698 */ 4699 @Deprecated deliverEvent(Event e)4700 public void deliverEvent(Event e) { 4701 postEvent(e); 4702 } 4703 4704 /** 4705 * Dispatches an event to this component or one of its sub components. 4706 * Calls <code>processEvent</code> before returning for 1.1-style 4707 * events which have been enabled for the <code>Component</code>. 4708 * @param e the event 4709 */ dispatchEvent(AWTEvent e)4710 public final void dispatchEvent(AWTEvent e) { 4711 dispatchEventImpl(e); 4712 } 4713 4714 @SuppressWarnings("deprecation") dispatchEventImpl(AWTEvent e)4715 void dispatchEventImpl(AWTEvent e) { 4716 int id = e.getID(); 4717 4718 // Check that this component belongs to this app-context 4719 AppContext compContext = appContext; 4720 if (compContext != null && !compContext.equals(AppContext.getAppContext())) { 4721 if (eventLog.isLoggable(PlatformLogger.Level.FINE)) { 4722 eventLog.fine("Event " + e + " is being dispatched on the wrong AppContext"); 4723 } 4724 } 4725 4726 if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) { 4727 eventLog.finest("{0}", e); 4728 } 4729 4730 /* 4731 * 0. Set timestamp and modifiers of current event. 4732 */ 4733 if (!(e instanceof KeyEvent)) { 4734 // Timestamp of a key event is set later in DKFM.preDispatchKeyEvent(KeyEvent). 4735 EventQueue.setCurrentEventAndMostRecentTime(e); 4736 } 4737 4738 /* 4739 * 1. Pre-dispatchers. Do any necessary retargeting/reordering here 4740 * before we notify AWTEventListeners. 4741 */ 4742 4743 if (e instanceof SunDropTargetEvent) { 4744 ((SunDropTargetEvent)e).dispatch(); 4745 return; 4746 } 4747 4748 if (!e.focusManagerIsDispatching) { 4749 // Invoke the private focus retargeting method which provides 4750 // lightweight Component support 4751 if (e.isPosted) { 4752 e = KeyboardFocusManager.retargetFocusEvent(e); 4753 e.isPosted = true; 4754 } 4755 4756 // Now, with the event properly targeted to a lightweight 4757 // descendant if necessary, invoke the public focus retargeting 4758 // and dispatching function 4759 if (KeyboardFocusManager.getCurrentKeyboardFocusManager(). 4760 dispatchEvent(e)) 4761 { 4762 return; 4763 } 4764 } 4765 if ((e instanceof FocusEvent) && focusLog.isLoggable(PlatformLogger.Level.FINEST)) { 4766 focusLog.finest("" + e); 4767 } 4768 // MouseWheel may need to be retargeted here so that 4769 // AWTEventListener sees the event go to the correct 4770 // Component. If the MouseWheelEvent needs to go to an ancestor, 4771 // the event is dispatched to the ancestor, and dispatching here 4772 // stops. 4773 if (id == MouseEvent.MOUSE_WHEEL && 4774 (!eventTypeEnabled(id)) && 4775 (peer != null && !peer.handlesWheelScrolling()) && 4776 (dispatchMouseWheelToAncestor((MouseWheelEvent)e))) 4777 { 4778 return; 4779 } 4780 4781 /* 4782 * 2. Allow the Toolkit to pass this to AWTEventListeners. 4783 */ 4784 Toolkit toolkit = Toolkit.getDefaultToolkit(); 4785 toolkit.notifyAWTEventListeners(e); 4786 4787 4788 /* 4789 * 3. If no one has consumed a key event, allow the 4790 * KeyboardFocusManager to process it. 4791 */ 4792 if (!e.isConsumed()) { 4793 if (e instanceof java.awt.event.KeyEvent) { 4794 KeyboardFocusManager.getCurrentKeyboardFocusManager(). 4795 processKeyEvent(this, (KeyEvent)e); 4796 if (e.isConsumed()) { 4797 return; 4798 } 4799 } 4800 } 4801 4802 /* 4803 * 4. Allow input methods to process the event 4804 */ 4805 if (areInputMethodsEnabled()) { 4806 // We need to pass on InputMethodEvents since some host 4807 // input method adapters send them through the Java 4808 // event queue instead of directly to the component, 4809 // and the input context also handles the Java composition window 4810 if(((e instanceof InputMethodEvent) && !(this instanceof CompositionArea)) 4811 || 4812 // Otherwise, we only pass on input and focus events, because 4813 // a) input methods shouldn't know about semantic or component-level events 4814 // b) passing on the events takes time 4815 // c) isConsumed() is always true for semantic events. 4816 (e instanceof InputEvent) || (e instanceof FocusEvent)) { 4817 InputContext inputContext = getInputContext(); 4818 4819 4820 if (inputContext != null) { 4821 inputContext.dispatchEvent(e); 4822 if (e.isConsumed()) { 4823 if ((e instanceof FocusEvent) && focusLog.isLoggable(PlatformLogger.Level.FINEST)) { 4824 focusLog.finest("3579: Skipping " + e); 4825 } 4826 return; 4827 } 4828 } 4829 } 4830 } else { 4831 // When non-clients get focus, we need to explicitly disable the native 4832 // input method. The native input method is actually not disabled when 4833 // the active/passive/peered clients loose focus. 4834 if (id == FocusEvent.FOCUS_GAINED) { 4835 InputContext inputContext = getInputContext(); 4836 if (inputContext != null && inputContext instanceof sun.awt.im.InputContext) { 4837 ((sun.awt.im.InputContext)inputContext).disableNativeIM(); 4838 } 4839 } 4840 } 4841 4842 4843 /* 4844 * 5. Pre-process any special events before delivery 4845 */ 4846 switch(id) { 4847 // Handling of the PAINT and UPDATE events is now done in the 4848 // peer's handleEvent() method so the background can be cleared 4849 // selectively for non-native components on Windows only. 4850 // - Fred.Ecks@Eng.sun.com, 5-8-98 4851 4852 case KeyEvent.KEY_PRESSED: 4853 case KeyEvent.KEY_RELEASED: 4854 Container p = (Container)((this instanceof Container) ? this : parent); 4855 if (p != null) { 4856 p.preProcessKeyEvent((KeyEvent)e); 4857 if (e.isConsumed()) { 4858 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) { 4859 focusLog.finest("Pre-process consumed event"); 4860 } 4861 return; 4862 } 4863 } 4864 break; 4865 4866 case WindowEvent.WINDOW_CLOSING: 4867 if (toolkit instanceof WindowClosingListener) { 4868 windowClosingException = ((WindowClosingListener) 4869 toolkit).windowClosingNotify((WindowEvent)e); 4870 if (checkWindowClosingException()) { 4871 return; 4872 } 4873 } 4874 break; 4875 4876 default: 4877 break; 4878 } 4879 4880 /* 4881 * 6. Deliver event for normal processing 4882 */ 4883 if (newEventsOnly) { 4884 // Filtering needs to really be moved to happen at a lower 4885 // level in order to get maximum performance gain; it is 4886 // here temporarily to ensure the API spec is honored. 4887 // 4888 if (eventEnabled(e)) { 4889 processEvent(e); 4890 } 4891 } else if (id == MouseEvent.MOUSE_WHEEL) { 4892 // newEventsOnly will be false for a listenerless ScrollPane, but 4893 // MouseWheelEvents still need to be dispatched to it so scrolling 4894 // can be done. 4895 autoProcessMouseWheel((MouseWheelEvent)e); 4896 } else if (!(e instanceof MouseEvent && !postsOldMouseEvents())) { 4897 // 4898 // backward compatibility 4899 // 4900 Event olde = e.convertToOld(); 4901 if (olde != null) { 4902 int key = olde.key; 4903 int modifiers = olde.modifiers; 4904 4905 postEvent(olde); 4906 if (olde.isConsumed()) { 4907 e.consume(); 4908 } 4909 // if target changed key or modifier values, copy them 4910 // back to original event 4911 // 4912 switch(olde.id) { 4913 case Event.KEY_PRESS: 4914 case Event.KEY_RELEASE: 4915 case Event.KEY_ACTION: 4916 case Event.KEY_ACTION_RELEASE: 4917 if (olde.key != key) { 4918 ((KeyEvent)e).setKeyChar(olde.getKeyEventChar()); 4919 } 4920 if (olde.modifiers != modifiers) { 4921 ((KeyEvent)e).setModifiers(olde.modifiers); 4922 } 4923 break; 4924 default: 4925 break; 4926 } 4927 } 4928 } 4929 4930 /* 4931 * 8. Special handling for 4061116 : Hook for browser to close modal 4932 * dialogs. 4933 */ 4934 if (id == WindowEvent.WINDOW_CLOSING && !e.isConsumed()) { 4935 if (toolkit instanceof WindowClosingListener) { 4936 windowClosingException = 4937 ((WindowClosingListener)toolkit). 4938 windowClosingDelivered((WindowEvent)e); 4939 if (checkWindowClosingException()) { 4940 return; 4941 } 4942 } 4943 } 4944 4945 /* 4946 * 9. Allow the peer to process the event. 4947 * Except KeyEvents, they will be processed by peer after 4948 * all KeyEventPostProcessors 4949 * (see DefaultKeyboardFocusManager.dispatchKeyEvent()) 4950 */ 4951 if (!(e instanceof KeyEvent)) { 4952 ComponentPeer tpeer = peer; 4953 if (e instanceof FocusEvent && (tpeer == null || tpeer instanceof LightweightPeer)) { 4954 // if focus owner is lightweight then its native container 4955 // processes event 4956 Component source = (Component)e.getSource(); 4957 if (source != null) { 4958 Container target = source.getNativeContainer(); 4959 if (target != null) { 4960 tpeer = target.getPeer(); 4961 } 4962 } 4963 } 4964 if (tpeer != null) { 4965 tpeer.handleEvent(e); 4966 } 4967 } 4968 4969 if (SunToolkit.isTouchKeyboardAutoShowEnabled() && 4970 (toolkit instanceof SunToolkit) && 4971 ((e instanceof MouseEvent) || (e instanceof FocusEvent))) { 4972 ((SunToolkit)toolkit).showOrHideTouchKeyboard(this, e); 4973 } 4974 } // dispatchEventImpl() 4975 4976 /* 4977 * If newEventsOnly is false, method is called so that ScrollPane can 4978 * override it and handle common-case mouse wheel scrolling. NOP 4979 * for Component. 4980 */ autoProcessMouseWheel(MouseWheelEvent e)4981 void autoProcessMouseWheel(MouseWheelEvent e) {} 4982 4983 /* 4984 * Dispatch given MouseWheelEvent to the first ancestor for which 4985 * MouseWheelEvents are enabled. 4986 * 4987 * Returns whether or not event was dispatched to an ancestor 4988 */ dispatchMouseWheelToAncestor(MouseWheelEvent e)4989 boolean dispatchMouseWheelToAncestor(MouseWheelEvent e) { 4990 int newX, newY; 4991 newX = e.getX() + getX(); // Coordinates take into account at least 4992 newY = e.getY() + getY(); // the cursor's position relative to this 4993 // Component (e.getX()), and this Component's 4994 // position relative to its parent. 4995 MouseWheelEvent newMWE; 4996 4997 if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) { 4998 eventLog.finest("dispatchMouseWheelToAncestor"); 4999 eventLog.finest("orig event src is of " + e.getSource().getClass()); 5000 } 5001 5002 /* parent field for Window refers to the owning Window. 5003 * MouseWheelEvents should NOT be propagated into owning Windows 5004 */ 5005 synchronized (getTreeLock()) { 5006 Container anc = getParent(); 5007 while (anc != null && !anc.eventEnabled(e)) { 5008 // fix coordinates to be relative to new event source 5009 newX += anc.getX(); 5010 newY += anc.getY(); 5011 5012 if (!(anc instanceof Window)) { 5013 anc = anc.getParent(); 5014 } 5015 else { 5016 break; 5017 } 5018 } 5019 5020 if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) { 5021 eventLog.finest("new event src is " + anc.getClass()); 5022 } 5023 5024 if (anc != null && anc.eventEnabled(e)) { 5025 // Change event to be from new source, with new x,y 5026 // For now, just create a new event - yucky 5027 5028 newMWE = new MouseWheelEvent(anc, // new source 5029 e.getID(), 5030 e.getWhen(), 5031 e.getModifiers(), 5032 newX, // x relative to new source 5033 newY, // y relative to new source 5034 e.getXOnScreen(), 5035 e.getYOnScreen(), 5036 e.getClickCount(), 5037 e.isPopupTrigger(), 5038 e.getScrollType(), 5039 e.getScrollAmount(), 5040 e.getWheelRotation(), 5041 e.getPreciseWheelRotation()); 5042 ((AWTEvent)e).copyPrivateDataInto(newMWE); 5043 // When dispatching a wheel event to 5044 // ancestor, there is no need trying to find descendant 5045 // lightweights to dispatch event to. 5046 // If we dispatch the event to toplevel ancestor, 5047 // this could encolse the loop: 6480024. 5048 anc.dispatchEventToSelf(newMWE); 5049 if (newMWE.isConsumed()) { 5050 e.consume(); 5051 } 5052 return true; 5053 } 5054 } 5055 return false; 5056 } 5057 checkWindowClosingException()5058 boolean checkWindowClosingException() { 5059 if (windowClosingException != null) { 5060 if (this instanceof Dialog) { 5061 ((Dialog)this).interruptBlocking(); 5062 } else { 5063 windowClosingException.fillInStackTrace(); 5064 windowClosingException.printStackTrace(); 5065 windowClosingException = null; 5066 } 5067 return true; 5068 } 5069 return false; 5070 } 5071 areInputMethodsEnabled()5072 boolean areInputMethodsEnabled() { 5073 // in 1.2, we assume input method support is required for all 5074 // components that handle key events, but components can turn off 5075 // input methods by calling enableInputMethods(false). 5076 return ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) && 5077 ((eventMask & AWTEvent.KEY_EVENT_MASK) != 0 || keyListener != null); 5078 } 5079 5080 // REMIND: remove when filtering is handled at lower level eventEnabled(AWTEvent e)5081 boolean eventEnabled(AWTEvent e) { 5082 return eventTypeEnabled(e.id); 5083 } 5084 eventTypeEnabled(int type)5085 boolean eventTypeEnabled(int type) { 5086 switch(type) { 5087 case ComponentEvent.COMPONENT_MOVED: 5088 case ComponentEvent.COMPONENT_RESIZED: 5089 case ComponentEvent.COMPONENT_SHOWN: 5090 case ComponentEvent.COMPONENT_HIDDEN: 5091 if ((eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 || 5092 componentListener != null) { 5093 return true; 5094 } 5095 break; 5096 case FocusEvent.FOCUS_GAINED: 5097 case FocusEvent.FOCUS_LOST: 5098 if ((eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0 || 5099 focusListener != null) { 5100 return true; 5101 } 5102 break; 5103 case KeyEvent.KEY_PRESSED: 5104 case KeyEvent.KEY_RELEASED: 5105 case KeyEvent.KEY_TYPED: 5106 if ((eventMask & AWTEvent.KEY_EVENT_MASK) != 0 || 5107 keyListener != null) { 5108 return true; 5109 } 5110 break; 5111 case MouseEvent.MOUSE_PRESSED: 5112 case MouseEvent.MOUSE_RELEASED: 5113 case MouseEvent.MOUSE_ENTERED: 5114 case MouseEvent.MOUSE_EXITED: 5115 case MouseEvent.MOUSE_CLICKED: 5116 if ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0 || 5117 mouseListener != null) { 5118 return true; 5119 } 5120 break; 5121 case MouseEvent.MOUSE_MOVED: 5122 case MouseEvent.MOUSE_DRAGGED: 5123 if ((eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0 || 5124 mouseMotionListener != null) { 5125 return true; 5126 } 5127 break; 5128 case MouseEvent.MOUSE_WHEEL: 5129 if ((eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0 || 5130 mouseWheelListener != null) { 5131 return true; 5132 } 5133 break; 5134 case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED: 5135 case InputMethodEvent.CARET_POSITION_CHANGED: 5136 if ((eventMask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0 || 5137 inputMethodListener != null) { 5138 return true; 5139 } 5140 break; 5141 case HierarchyEvent.HIERARCHY_CHANGED: 5142 if ((eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 || 5143 hierarchyListener != null) { 5144 return true; 5145 } 5146 break; 5147 case HierarchyEvent.ANCESTOR_MOVED: 5148 case HierarchyEvent.ANCESTOR_RESIZED: 5149 if ((eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 || 5150 hierarchyBoundsListener != null) { 5151 return true; 5152 } 5153 break; 5154 case ActionEvent.ACTION_PERFORMED: 5155 if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0) { 5156 return true; 5157 } 5158 break; 5159 case TextEvent.TEXT_VALUE_CHANGED: 5160 if ((eventMask & AWTEvent.TEXT_EVENT_MASK) != 0) { 5161 return true; 5162 } 5163 break; 5164 case ItemEvent.ITEM_STATE_CHANGED: 5165 if ((eventMask & AWTEvent.ITEM_EVENT_MASK) != 0) { 5166 return true; 5167 } 5168 break; 5169 case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED: 5170 if ((eventMask & AWTEvent.ADJUSTMENT_EVENT_MASK) != 0) { 5171 return true; 5172 } 5173 break; 5174 default: 5175 break; 5176 } 5177 // 5178 // Always pass on events defined by external programs. 5179 // 5180 if (type > AWTEvent.RESERVED_ID_MAX) { 5181 return true; 5182 } 5183 return false; 5184 } 5185 5186 /** 5187 * @deprecated As of JDK version 1.1, 5188 * replaced by dispatchEvent(AWTEvent). 5189 */ 5190 @Deprecated postEvent(Event e)5191 public boolean postEvent(Event e) { 5192 ComponentPeer peer = this.peer; 5193 5194 if (handleEvent(e)) { 5195 e.consume(); 5196 return true; 5197 } 5198 5199 Component parent = this.parent; 5200 int eventx = e.x; 5201 int eventy = e.y; 5202 if (parent != null) { 5203 e.translate(x, y); 5204 if (parent.postEvent(e)) { 5205 e.consume(); 5206 return true; 5207 } 5208 // restore coords 5209 e.x = eventx; 5210 e.y = eventy; 5211 } 5212 return false; 5213 } 5214 5215 // Event source interfaces 5216 5217 /** 5218 * Adds the specified component listener to receive component events from 5219 * this component. 5220 * If listener <code>l</code> is <code>null</code>, 5221 * no exception is thrown and no action is performed. 5222 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 5223 * >AWT Threading Issues</a> for details on AWT's threading model. 5224 * 5225 * @param l the component listener 5226 * @see java.awt.event.ComponentEvent 5227 * @see java.awt.event.ComponentListener 5228 * @see #removeComponentListener 5229 * @see #getComponentListeners 5230 * @since JDK1.1 5231 */ addComponentListener(ComponentListener l)5232 public synchronized void addComponentListener(ComponentListener l) { 5233 if (l == null) { 5234 return; 5235 } 5236 componentListener = AWTEventMulticaster.add(componentListener, l); 5237 newEventsOnly = true; 5238 } 5239 5240 /** 5241 * Removes the specified component listener so that it no longer 5242 * receives component events from this component. This method performs 5243 * no function, nor does it throw an exception, if the listener 5244 * specified by the argument was not previously added to this component. 5245 * If listener <code>l</code> is <code>null</code>, 5246 * no exception is thrown and no action is performed. 5247 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 5248 * >AWT Threading Issues</a> for details on AWT's threading model. 5249 * @param l the component listener 5250 * @see java.awt.event.ComponentEvent 5251 * @see java.awt.event.ComponentListener 5252 * @see #addComponentListener 5253 * @see #getComponentListeners 5254 * @since JDK1.1 5255 */ removeComponentListener(ComponentListener l)5256 public synchronized void removeComponentListener(ComponentListener l) { 5257 if (l == null) { 5258 return; 5259 } 5260 componentListener = AWTEventMulticaster.remove(componentListener, l); 5261 } 5262 5263 /** 5264 * Returns an array of all the component listeners 5265 * registered on this component. 5266 * 5267 * @return all <code>ComponentListener</code>s of this component 5268 * or an empty array if no component 5269 * listeners are currently registered 5270 * 5271 * @see #addComponentListener 5272 * @see #removeComponentListener 5273 * @since 1.4 5274 */ getComponentListeners()5275 public synchronized ComponentListener[] getComponentListeners() { 5276 return getListeners(ComponentListener.class); 5277 } 5278 5279 /** 5280 * Adds the specified focus listener to receive focus events from 5281 * this component when this component gains input focus. 5282 * If listener <code>l</code> is <code>null</code>, 5283 * no exception is thrown and no action is performed. 5284 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 5285 * >AWT Threading Issues</a> for details on AWT's threading model. 5286 * 5287 * @param l the focus listener 5288 * @see java.awt.event.FocusEvent 5289 * @see java.awt.event.FocusListener 5290 * @see #removeFocusListener 5291 * @see #getFocusListeners 5292 * @since JDK1.1 5293 */ addFocusListener(FocusListener l)5294 public synchronized void addFocusListener(FocusListener l) { 5295 if (l == null) { 5296 return; 5297 } 5298 focusListener = AWTEventMulticaster.add(focusListener, l); 5299 newEventsOnly = true; 5300 5301 // if this is a lightweight component, enable focus events 5302 // in the native container. 5303 if (peer instanceof LightweightPeer) { 5304 parent.proxyEnableEvents(AWTEvent.FOCUS_EVENT_MASK); 5305 } 5306 } 5307 5308 /** 5309 * Removes the specified focus listener so that it no longer 5310 * receives focus events from this component. This method performs 5311 * no function, nor does it throw an exception, if the listener 5312 * specified by the argument was not previously added to this component. 5313 * If listener <code>l</code> is <code>null</code>, 5314 * no exception is thrown and no action is performed. 5315 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 5316 * >AWT Threading Issues</a> for details on AWT's threading model. 5317 * 5318 * @param l the focus listener 5319 * @see java.awt.event.FocusEvent 5320 * @see java.awt.event.FocusListener 5321 * @see #addFocusListener 5322 * @see #getFocusListeners 5323 * @since JDK1.1 5324 */ removeFocusListener(FocusListener l)5325 public synchronized void removeFocusListener(FocusListener l) { 5326 if (l == null) { 5327 return; 5328 } 5329 focusListener = AWTEventMulticaster.remove(focusListener, l); 5330 } 5331 5332 /** 5333 * Returns an array of all the focus listeners 5334 * registered on this component. 5335 * 5336 * @return all of this component's <code>FocusListener</code>s 5337 * or an empty array if no component 5338 * listeners are currently registered 5339 * 5340 * @see #addFocusListener 5341 * @see #removeFocusListener 5342 * @since 1.4 5343 */ getFocusListeners()5344 public synchronized FocusListener[] getFocusListeners() { 5345 return getListeners(FocusListener.class); 5346 } 5347 5348 /** 5349 * Adds the specified hierarchy listener to receive hierarchy changed 5350 * events from this component when the hierarchy to which this container 5351 * belongs changes. 5352 * If listener <code>l</code> is <code>null</code>, 5353 * no exception is thrown and no action is performed. 5354 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 5355 * >AWT Threading Issues</a> for details on AWT's threading model. 5356 * 5357 * @param l the hierarchy listener 5358 * @see java.awt.event.HierarchyEvent 5359 * @see java.awt.event.HierarchyListener 5360 * @see #removeHierarchyListener 5361 * @see #getHierarchyListeners 5362 * @since 1.3 5363 */ addHierarchyListener(HierarchyListener l)5364 public void addHierarchyListener(HierarchyListener l) { 5365 if (l == null) { 5366 return; 5367 } 5368 boolean notifyAncestors; 5369 synchronized (this) { 5370 notifyAncestors = 5371 (hierarchyListener == null && 5372 (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) == 0); 5373 hierarchyListener = AWTEventMulticaster.add(hierarchyListener, l); 5374 notifyAncestors = (notifyAncestors && hierarchyListener != null); 5375 newEventsOnly = true; 5376 } 5377 if (notifyAncestors) { 5378 synchronized (getTreeLock()) { 5379 adjustListeningChildrenOnParent(AWTEvent.HIERARCHY_EVENT_MASK, 5380 1); 5381 } 5382 } 5383 } 5384 5385 /** 5386 * Removes the specified hierarchy listener so that it no longer 5387 * receives hierarchy changed events from this component. This method 5388 * performs no function, nor does it throw an exception, if the listener 5389 * specified by the argument was not previously added to this component. 5390 * If listener <code>l</code> is <code>null</code>, 5391 * no exception is thrown and no action is performed. 5392 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 5393 * >AWT Threading Issues</a> for details on AWT's threading model. 5394 * 5395 * @param l the hierarchy listener 5396 * @see java.awt.event.HierarchyEvent 5397 * @see java.awt.event.HierarchyListener 5398 * @see #addHierarchyListener 5399 * @see #getHierarchyListeners 5400 * @since 1.3 5401 */ removeHierarchyListener(HierarchyListener l)5402 public void removeHierarchyListener(HierarchyListener l) { 5403 if (l == null) { 5404 return; 5405 } 5406 boolean notifyAncestors; 5407 synchronized (this) { 5408 notifyAncestors = 5409 (hierarchyListener != null && 5410 (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) == 0); 5411 hierarchyListener = 5412 AWTEventMulticaster.remove(hierarchyListener, l); 5413 notifyAncestors = (notifyAncestors && hierarchyListener == null); 5414 } 5415 if (notifyAncestors) { 5416 synchronized (getTreeLock()) { 5417 adjustListeningChildrenOnParent(AWTEvent.HIERARCHY_EVENT_MASK, 5418 -1); 5419 } 5420 } 5421 } 5422 5423 /** 5424 * Returns an array of all the hierarchy listeners 5425 * registered on this component. 5426 * 5427 * @return all of this component's <code>HierarchyListener</code>s 5428 * or an empty array if no hierarchy 5429 * listeners are currently registered 5430 * 5431 * @see #addHierarchyListener 5432 * @see #removeHierarchyListener 5433 * @since 1.4 5434 */ getHierarchyListeners()5435 public synchronized HierarchyListener[] getHierarchyListeners() { 5436 return getListeners(HierarchyListener.class); 5437 } 5438 5439 /** 5440 * Adds the specified hierarchy bounds listener to receive hierarchy 5441 * bounds events from this component when the hierarchy to which this 5442 * container belongs changes. 5443 * If listener <code>l</code> is <code>null</code>, 5444 * no exception is thrown and no action is performed. 5445 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 5446 * >AWT Threading Issues</a> for details on AWT's threading model. 5447 * 5448 * @param l the hierarchy bounds listener 5449 * @see java.awt.event.HierarchyEvent 5450 * @see java.awt.event.HierarchyBoundsListener 5451 * @see #removeHierarchyBoundsListener 5452 * @see #getHierarchyBoundsListeners 5453 * @since 1.3 5454 */ addHierarchyBoundsListener(HierarchyBoundsListener l)5455 public void addHierarchyBoundsListener(HierarchyBoundsListener l) { 5456 if (l == null) { 5457 return; 5458 } 5459 boolean notifyAncestors; 5460 synchronized (this) { 5461 notifyAncestors = 5462 (hierarchyBoundsListener == null && 5463 (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) == 0); 5464 hierarchyBoundsListener = 5465 AWTEventMulticaster.add(hierarchyBoundsListener, l); 5466 notifyAncestors = (notifyAncestors && 5467 hierarchyBoundsListener != null); 5468 newEventsOnly = true; 5469 } 5470 if (notifyAncestors) { 5471 synchronized (getTreeLock()) { 5472 adjustListeningChildrenOnParent( 5473 AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK, 1); 5474 } 5475 } 5476 } 5477 5478 /** 5479 * Removes the specified hierarchy bounds listener so that it no longer 5480 * receives hierarchy bounds events from this component. This method 5481 * performs no function, nor does it throw an exception, if the listener 5482 * specified by the argument was not previously added to this component. 5483 * If listener <code>l</code> is <code>null</code>, 5484 * no exception is thrown and no action is performed. 5485 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 5486 * >AWT Threading Issues</a> for details on AWT's threading model. 5487 * 5488 * @param l the hierarchy bounds listener 5489 * @see java.awt.event.HierarchyEvent 5490 * @see java.awt.event.HierarchyBoundsListener 5491 * @see #addHierarchyBoundsListener 5492 * @see #getHierarchyBoundsListeners 5493 * @since 1.3 5494 */ removeHierarchyBoundsListener(HierarchyBoundsListener l)5495 public void removeHierarchyBoundsListener(HierarchyBoundsListener l) { 5496 if (l == null) { 5497 return; 5498 } 5499 boolean notifyAncestors; 5500 synchronized (this) { 5501 notifyAncestors = 5502 (hierarchyBoundsListener != null && 5503 (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) == 0); 5504 hierarchyBoundsListener = 5505 AWTEventMulticaster.remove(hierarchyBoundsListener, l); 5506 notifyAncestors = (notifyAncestors && 5507 hierarchyBoundsListener == null); 5508 } 5509 if (notifyAncestors) { 5510 synchronized (getTreeLock()) { 5511 adjustListeningChildrenOnParent( 5512 AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK, -1); 5513 } 5514 } 5515 } 5516 5517 // Should only be called while holding the tree lock numListening(long mask)5518 int numListening(long mask) { 5519 // One mask or the other, but not neither or both. 5520 if (eventLog.isLoggable(PlatformLogger.Level.FINE)) { 5521 if ((mask != AWTEvent.HIERARCHY_EVENT_MASK) && 5522 (mask != AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK)) 5523 { 5524 eventLog.fine("Assertion failed"); 5525 } 5526 } 5527 if ((mask == AWTEvent.HIERARCHY_EVENT_MASK && 5528 (hierarchyListener != null || 5529 (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0)) || 5530 (mask == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK && 5531 (hierarchyBoundsListener != null || 5532 (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0))) { 5533 return 1; 5534 } else { 5535 return 0; 5536 } 5537 } 5538 5539 // Should only be called while holding tree lock countHierarchyMembers()5540 int countHierarchyMembers() { 5541 return 1; 5542 } 5543 // Should only be called while holding the tree lock createHierarchyEvents(int id, Component changed, Container changedParent, long changeFlags, boolean enabledOnToolkit)5544 int createHierarchyEvents(int id, Component changed, 5545 Container changedParent, long changeFlags, 5546 boolean enabledOnToolkit) { 5547 switch (id) { 5548 case HierarchyEvent.HIERARCHY_CHANGED: 5549 if (hierarchyListener != null || 5550 (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 || 5551 enabledOnToolkit) { 5552 HierarchyEvent e = new HierarchyEvent(this, id, changed, 5553 changedParent, 5554 changeFlags); 5555 dispatchEvent(e); 5556 return 1; 5557 } 5558 break; 5559 case HierarchyEvent.ANCESTOR_MOVED: 5560 case HierarchyEvent.ANCESTOR_RESIZED: 5561 if (eventLog.isLoggable(PlatformLogger.Level.FINE)) { 5562 if (changeFlags != 0) { 5563 eventLog.fine("Assertion (changeFlags == 0) failed"); 5564 } 5565 } 5566 if (hierarchyBoundsListener != null || 5567 (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 || 5568 enabledOnToolkit) { 5569 HierarchyEvent e = new HierarchyEvent(this, id, changed, 5570 changedParent); 5571 dispatchEvent(e); 5572 return 1; 5573 } 5574 break; 5575 default: 5576 // assert false 5577 if (eventLog.isLoggable(PlatformLogger.Level.FINE)) { 5578 eventLog.fine("This code must never be reached"); 5579 } 5580 break; 5581 } 5582 return 0; 5583 } 5584 5585 /** 5586 * Returns an array of all the hierarchy bounds listeners 5587 * registered on this component. 5588 * 5589 * @return all of this component's <code>HierarchyBoundsListener</code>s 5590 * or an empty array if no hierarchy bounds 5591 * listeners are currently registered 5592 * 5593 * @see #addHierarchyBoundsListener 5594 * @see #removeHierarchyBoundsListener 5595 * @since 1.4 5596 */ getHierarchyBoundsListeners()5597 public synchronized HierarchyBoundsListener[] getHierarchyBoundsListeners() { 5598 return getListeners(HierarchyBoundsListener.class); 5599 } 5600 5601 /* 5602 * Should only be called while holding the tree lock. 5603 * It's added only for overriding in java.awt.Window 5604 * because parent in Window is owner. 5605 */ adjustListeningChildrenOnParent(long mask, int num)5606 void adjustListeningChildrenOnParent(long mask, int num) { 5607 if (parent != null) { 5608 parent.adjustListeningChildren(mask, num); 5609 } 5610 } 5611 5612 /** 5613 * Adds the specified key listener to receive key events from 5614 * this component. 5615 * If l is null, no exception is thrown and no action is performed. 5616 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 5617 * >AWT Threading Issues</a> for details on AWT's threading model. 5618 * 5619 * @param l the key listener. 5620 * @see java.awt.event.KeyEvent 5621 * @see java.awt.event.KeyListener 5622 * @see #removeKeyListener 5623 * @see #getKeyListeners 5624 * @since JDK1.1 5625 */ addKeyListener(KeyListener l)5626 public synchronized void addKeyListener(KeyListener l) { 5627 if (l == null) { 5628 return; 5629 } 5630 keyListener = AWTEventMulticaster.add(keyListener, l); 5631 newEventsOnly = true; 5632 5633 // if this is a lightweight component, enable key events 5634 // in the native container. 5635 if (peer instanceof LightweightPeer) { 5636 parent.proxyEnableEvents(AWTEvent.KEY_EVENT_MASK); 5637 } 5638 } 5639 5640 /** 5641 * Removes the specified key listener so that it no longer 5642 * receives key events from this component. This method performs 5643 * no function, nor does it throw an exception, if the listener 5644 * specified by the argument was not previously added to this component. 5645 * If listener <code>l</code> is <code>null</code>, 5646 * no exception is thrown and no action is performed. 5647 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 5648 * >AWT Threading Issues</a> for details on AWT's threading model. 5649 * 5650 * @param l the key listener 5651 * @see java.awt.event.KeyEvent 5652 * @see java.awt.event.KeyListener 5653 * @see #addKeyListener 5654 * @see #getKeyListeners 5655 * @since JDK1.1 5656 */ removeKeyListener(KeyListener l)5657 public synchronized void removeKeyListener(KeyListener l) { 5658 if (l == null) { 5659 return; 5660 } 5661 keyListener = AWTEventMulticaster.remove(keyListener, l); 5662 } 5663 5664 /** 5665 * Returns an array of all the key listeners 5666 * registered on this component. 5667 * 5668 * @return all of this component's <code>KeyListener</code>s 5669 * or an empty array if no key 5670 * listeners are currently registered 5671 * 5672 * @see #addKeyListener 5673 * @see #removeKeyListener 5674 * @since 1.4 5675 */ getKeyListeners()5676 public synchronized KeyListener[] getKeyListeners() { 5677 return getListeners(KeyListener.class); 5678 } 5679 5680 /** 5681 * Adds the specified mouse listener to receive mouse events from 5682 * this component. 5683 * If listener <code>l</code> is <code>null</code>, 5684 * no exception is thrown and no action is performed. 5685 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 5686 * >AWT Threading Issues</a> for details on AWT's threading model. 5687 * 5688 * @param l the mouse listener 5689 * @see java.awt.event.MouseEvent 5690 * @see java.awt.event.MouseListener 5691 * @see #removeMouseListener 5692 * @see #getMouseListeners 5693 * @since JDK1.1 5694 */ addMouseListener(MouseListener l)5695 public synchronized void addMouseListener(MouseListener l) { 5696 if (l == null) { 5697 return; 5698 } 5699 mouseListener = AWTEventMulticaster.add(mouseListener,l); 5700 newEventsOnly = true; 5701 5702 // if this is a lightweight component, enable mouse events 5703 // in the native container. 5704 if (peer instanceof LightweightPeer) { 5705 parent.proxyEnableEvents(AWTEvent.MOUSE_EVENT_MASK); 5706 } 5707 } 5708 5709 /** 5710 * Removes the specified mouse listener so that it no longer 5711 * receives mouse events from this component. This method performs 5712 * no function, nor does it throw an exception, if the listener 5713 * specified by the argument was not previously added to this component. 5714 * If listener <code>l</code> is <code>null</code>, 5715 * no exception is thrown and no action is performed. 5716 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 5717 * >AWT Threading Issues</a> for details on AWT's threading model. 5718 * 5719 * @param l the mouse listener 5720 * @see java.awt.event.MouseEvent 5721 * @see java.awt.event.MouseListener 5722 * @see #addMouseListener 5723 * @see #getMouseListeners 5724 * @since JDK1.1 5725 */ removeMouseListener(MouseListener l)5726 public synchronized void removeMouseListener(MouseListener l) { 5727 if (l == null) { 5728 return; 5729 } 5730 mouseListener = AWTEventMulticaster.remove(mouseListener, l); 5731 } 5732 5733 /** 5734 * Returns an array of all the mouse listeners 5735 * registered on this component. 5736 * 5737 * @return all of this component's <code>MouseListener</code>s 5738 * or an empty array if no mouse 5739 * listeners are currently registered 5740 * 5741 * @see #addMouseListener 5742 * @see #removeMouseListener 5743 * @since 1.4 5744 */ getMouseListeners()5745 public synchronized MouseListener[] getMouseListeners() { 5746 return getListeners(MouseListener.class); 5747 } 5748 5749 /** 5750 * Adds the specified mouse motion listener to receive mouse motion 5751 * events from this component. 5752 * If listener <code>l</code> is <code>null</code>, 5753 * no exception is thrown and no action is performed. 5754 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 5755 * >AWT Threading Issues</a> for details on AWT's threading model. 5756 * 5757 * @param l the mouse motion listener 5758 * @see java.awt.event.MouseEvent 5759 * @see java.awt.event.MouseMotionListener 5760 * @see #removeMouseMotionListener 5761 * @see #getMouseMotionListeners 5762 * @since JDK1.1 5763 */ addMouseMotionListener(MouseMotionListener l)5764 public synchronized void addMouseMotionListener(MouseMotionListener l) { 5765 if (l == null) { 5766 return; 5767 } 5768 mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener,l); 5769 newEventsOnly = true; 5770 5771 // if this is a lightweight component, enable mouse events 5772 // in the native container. 5773 if (peer instanceof LightweightPeer) { 5774 parent.proxyEnableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK); 5775 } 5776 } 5777 5778 /** 5779 * Removes the specified mouse motion listener so that it no longer 5780 * receives mouse motion events from this component. This method performs 5781 * no function, nor does it throw an exception, if the listener 5782 * specified by the argument was not previously added to this component. 5783 * If listener <code>l</code> is <code>null</code>, 5784 * no exception is thrown and no action is performed. 5785 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 5786 * >AWT Threading Issues</a> for details on AWT's threading model. 5787 * 5788 * @param l the mouse motion listener 5789 * @see java.awt.event.MouseEvent 5790 * @see java.awt.event.MouseMotionListener 5791 * @see #addMouseMotionListener 5792 * @see #getMouseMotionListeners 5793 * @since JDK1.1 5794 */ removeMouseMotionListener(MouseMotionListener l)5795 public synchronized void removeMouseMotionListener(MouseMotionListener l) { 5796 if (l == null) { 5797 return; 5798 } 5799 mouseMotionListener = AWTEventMulticaster.remove(mouseMotionListener, l); 5800 } 5801 5802 /** 5803 * Returns an array of all the mouse motion listeners 5804 * registered on this component. 5805 * 5806 * @return all of this component's <code>MouseMotionListener</code>s 5807 * or an empty array if no mouse motion 5808 * listeners are currently registered 5809 * 5810 * @see #addMouseMotionListener 5811 * @see #removeMouseMotionListener 5812 * @since 1.4 5813 */ getMouseMotionListeners()5814 public synchronized MouseMotionListener[] getMouseMotionListeners() { 5815 return getListeners(MouseMotionListener.class); 5816 } 5817 5818 /** 5819 * Adds the specified mouse wheel listener to receive mouse wheel events 5820 * from this component. Containers also receive mouse wheel events from 5821 * sub-components. 5822 * <p> 5823 * For information on how mouse wheel events are dispatched, see 5824 * the class description for {@link MouseWheelEvent}. 5825 * <p> 5826 * If l is <code>null</code>, no exception is thrown and no 5827 * action is performed. 5828 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 5829 * >AWT Threading Issues</a> for details on AWT's threading model. 5830 * 5831 * @param l the mouse wheel listener 5832 * @see java.awt.event.MouseWheelEvent 5833 * @see java.awt.event.MouseWheelListener 5834 * @see #removeMouseWheelListener 5835 * @see #getMouseWheelListeners 5836 * @since 1.4 5837 */ addMouseWheelListener(MouseWheelListener l)5838 public synchronized void addMouseWheelListener(MouseWheelListener l) { 5839 if (l == null) { 5840 return; 5841 } 5842 mouseWheelListener = AWTEventMulticaster.add(mouseWheelListener,l); 5843 newEventsOnly = true; 5844 5845 // if this is a lightweight component, enable mouse events 5846 // in the native container. 5847 if (peer instanceof LightweightPeer) { 5848 parent.proxyEnableEvents(AWTEvent.MOUSE_WHEEL_EVENT_MASK); 5849 } 5850 } 5851 5852 /** 5853 * Removes the specified mouse wheel listener so that it no longer 5854 * receives mouse wheel events from this component. This method performs 5855 * no function, nor does it throw an exception, if the listener 5856 * specified by the argument was not previously added to this component. 5857 * If l is null, no exception is thrown and no action is performed. 5858 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 5859 * >AWT Threading Issues</a> for details on AWT's threading model. 5860 * 5861 * @param l the mouse wheel listener. 5862 * @see java.awt.event.MouseWheelEvent 5863 * @see java.awt.event.MouseWheelListener 5864 * @see #addMouseWheelListener 5865 * @see #getMouseWheelListeners 5866 * @since 1.4 5867 */ removeMouseWheelListener(MouseWheelListener l)5868 public synchronized void removeMouseWheelListener(MouseWheelListener l) { 5869 if (l == null) { 5870 return; 5871 } 5872 mouseWheelListener = AWTEventMulticaster.remove(mouseWheelListener, l); 5873 } 5874 5875 /** 5876 * Returns an array of all the mouse wheel listeners 5877 * registered on this component. 5878 * 5879 * @return all of this component's <code>MouseWheelListener</code>s 5880 * or an empty array if no mouse wheel 5881 * listeners are currently registered 5882 * 5883 * @see #addMouseWheelListener 5884 * @see #removeMouseWheelListener 5885 * @since 1.4 5886 */ getMouseWheelListeners()5887 public synchronized MouseWheelListener[] getMouseWheelListeners() { 5888 return getListeners(MouseWheelListener.class); 5889 } 5890 5891 /** 5892 * Adds the specified input method listener to receive 5893 * input method events from this component. A component will 5894 * only receive input method events from input methods 5895 * if it also overrides <code>getInputMethodRequests</code> to return an 5896 * <code>InputMethodRequests</code> instance. 5897 * If listener <code>l</code> is <code>null</code>, 5898 * no exception is thrown and no action is performed. 5899 * <p>Refer to <a href="{@docRoot}/java/awt/doc-files/AWTThreadIssues.html#ListenersThreads" 5900 * >AWT Threading Issues</a> for details on AWT's threading model. 5901 * 5902 * @param l the input method listener 5903 * @see java.awt.event.InputMethodEvent 5904 * @see java.awt.event.InputMethodListener 5905 * @see #removeInputMethodListener 5906 * @see #getInputMethodListeners 5907 * @see #getInputMethodRequests 5908 * @since 1.2 5909 */ addInputMethodListener(InputMethodListener l)5910 public synchronized void addInputMethodListener(InputMethodListener l) { 5911 if (l == null) { 5912 return; 5913 } 5914 inputMethodListener = AWTEventMulticaster.add(inputMethodListener, l); 5915 newEventsOnly = true; 5916 } 5917 5918 /** 5919 * Removes the specified input method listener so that it no longer 5920 * receives input method events from this component. This method performs 5921 * no function, nor does it throw an exception, if the listener 5922 * specified by the argument was not previously added to this component. 5923 * If listener <code>l</code> is <code>null</code>, 5924 * no exception is thrown and no action is performed. 5925 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 5926 * >AWT Threading Issues</a> for details on AWT's threading model. 5927 * 5928 * @param l the input method listener 5929 * @see java.awt.event.InputMethodEvent 5930 * @see java.awt.event.InputMethodListener 5931 * @see #addInputMethodListener 5932 * @see #getInputMethodListeners 5933 * @since 1.2 5934 */ removeInputMethodListener(InputMethodListener l)5935 public synchronized void removeInputMethodListener(InputMethodListener l) { 5936 if (l == null) { 5937 return; 5938 } 5939 inputMethodListener = AWTEventMulticaster.remove(inputMethodListener, l); 5940 } 5941 5942 /** 5943 * Returns an array of all the input method listeners 5944 * registered on this component. 5945 * 5946 * @return all of this component's <code>InputMethodListener</code>s 5947 * or an empty array if no input method 5948 * listeners are currently registered 5949 * 5950 * @see #addInputMethodListener 5951 * @see #removeInputMethodListener 5952 * @since 1.4 5953 */ getInputMethodListeners()5954 public synchronized InputMethodListener[] getInputMethodListeners() { 5955 return getListeners(InputMethodListener.class); 5956 } 5957 5958 /** 5959 * Returns an array of all the objects currently registered 5960 * as <code><em>Foo</em>Listener</code>s 5961 * upon this <code>Component</code>. 5962 * <code><em>Foo</em>Listener</code>s are registered using the 5963 * <code>add<em>Foo</em>Listener</code> method. 5964 * 5965 * <p> 5966 * You can specify the <code>listenerType</code> argument 5967 * with a class literal, such as 5968 * <code><em>Foo</em>Listener.class</code>. 5969 * For example, you can query a 5970 * <code>Component</code> <code>c</code> 5971 * for its mouse listeners with the following code: 5972 * 5973 * <pre>MouseListener[] mls = (MouseListener[])(c.getListeners(MouseListener.class));</pre> 5974 * 5975 * If no such listeners exist, this method returns an empty array. 5976 * 5977 * @param listenerType the type of listeners requested; this parameter 5978 * should specify an interface that descends from 5979 * <code>java.util.EventListener</code> 5980 * @return an array of all objects registered as 5981 * <code><em>Foo</em>Listener</code>s on this component, 5982 * or an empty array if no such listeners have been added 5983 * @exception ClassCastException if <code>listenerType</code> 5984 * doesn't specify a class or interface that implements 5985 * <code>java.util.EventListener</code> 5986 * @throws NullPointerException if {@code listenerType} is {@code null} 5987 * @see #getComponentListeners 5988 * @see #getFocusListeners 5989 * @see #getHierarchyListeners 5990 * @see #getHierarchyBoundsListeners 5991 * @see #getKeyListeners 5992 * @see #getMouseListeners 5993 * @see #getMouseMotionListeners 5994 * @see #getMouseWheelListeners 5995 * @see #getInputMethodListeners 5996 * @see #getPropertyChangeListeners 5997 * 5998 * @since 1.3 5999 */ 6000 @SuppressWarnings("unchecked") getListeners(Class<T> listenerType)6001 public <T extends EventListener> T[] getListeners(Class<T> listenerType) { 6002 EventListener l = null; 6003 if (listenerType == ComponentListener.class) { 6004 l = componentListener; 6005 } else if (listenerType == FocusListener.class) { 6006 l = focusListener; 6007 } else if (listenerType == HierarchyListener.class) { 6008 l = hierarchyListener; 6009 } else if (listenerType == HierarchyBoundsListener.class) { 6010 l = hierarchyBoundsListener; 6011 } else if (listenerType == KeyListener.class) { 6012 l = keyListener; 6013 } else if (listenerType == MouseListener.class) { 6014 l = mouseListener; 6015 } else if (listenerType == MouseMotionListener.class) { 6016 l = mouseMotionListener; 6017 } else if (listenerType == MouseWheelListener.class) { 6018 l = mouseWheelListener; 6019 } else if (listenerType == InputMethodListener.class) { 6020 l = inputMethodListener; 6021 } else if (listenerType == PropertyChangeListener.class) { 6022 return (T[])getPropertyChangeListeners(); 6023 } 6024 return AWTEventMulticaster.getListeners(l, listenerType); 6025 } 6026 6027 /** 6028 * Gets the input method request handler which supports 6029 * requests from input methods for this component. A component 6030 * that supports on-the-spot text input must override this 6031 * method to return an <code>InputMethodRequests</code> instance. 6032 * At the same time, it also has to handle input method events. 6033 * 6034 * @return the input method request handler for this component, 6035 * <code>null</code> by default 6036 * @see #addInputMethodListener 6037 * @since 1.2 6038 */ getInputMethodRequests()6039 public InputMethodRequests getInputMethodRequests() { 6040 return null; 6041 } 6042 6043 /** 6044 * Gets the input context used by this component for handling 6045 * the communication with input methods when text is entered 6046 * in this component. By default, the input context used for 6047 * the parent component is returned. Components may 6048 * override this to return a private input context. 6049 * 6050 * @return the input context used by this component; 6051 * <code>null</code> if no context can be determined 6052 * @since 1.2 6053 */ getInputContext()6054 public InputContext getInputContext() { 6055 Container parent = this.parent; 6056 if (parent == null) { 6057 return null; 6058 } else { 6059 return parent.getInputContext(); 6060 } 6061 } 6062 6063 /** 6064 * Enables the events defined by the specified event mask parameter 6065 * to be delivered to this component. 6066 * <p> 6067 * Event types are automatically enabled when a listener for 6068 * that event type is added to the component. 6069 * <p> 6070 * This method only needs to be invoked by subclasses of 6071 * <code>Component</code> which desire to have the specified event 6072 * types delivered to <code>processEvent</code> regardless of whether 6073 * or not a listener is registered. 6074 * @param eventsToEnable the event mask defining the event types 6075 * @see #processEvent 6076 * @see #disableEvents 6077 * @see AWTEvent 6078 * @since JDK1.1 6079 */ enableEvents(long eventsToEnable)6080 protected final void enableEvents(long eventsToEnable) { 6081 long notifyAncestors = 0; 6082 synchronized (this) { 6083 if ((eventsToEnable & AWTEvent.HIERARCHY_EVENT_MASK) != 0 && 6084 hierarchyListener == null && 6085 (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) == 0) { 6086 notifyAncestors |= AWTEvent.HIERARCHY_EVENT_MASK; 6087 } 6088 if ((eventsToEnable & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 && 6089 hierarchyBoundsListener == null && 6090 (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) == 0) { 6091 notifyAncestors |= AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK; 6092 } 6093 eventMask |= eventsToEnable; 6094 newEventsOnly = true; 6095 } 6096 6097 // if this is a lightweight component, enable mouse events 6098 // in the native container. 6099 if (peer instanceof LightweightPeer) { 6100 parent.proxyEnableEvents(eventMask); 6101 } 6102 if (notifyAncestors != 0) { 6103 synchronized (getTreeLock()) { 6104 adjustListeningChildrenOnParent(notifyAncestors, 1); 6105 } 6106 } 6107 } 6108 6109 /** 6110 * Disables the events defined by the specified event mask parameter 6111 * from being delivered to this component. 6112 * @param eventsToDisable the event mask defining the event types 6113 * @see #enableEvents 6114 * @since JDK1.1 6115 */ disableEvents(long eventsToDisable)6116 protected final void disableEvents(long eventsToDisable) { 6117 long notifyAncestors = 0; 6118 synchronized (this) { 6119 if ((eventsToDisable & AWTEvent.HIERARCHY_EVENT_MASK) != 0 && 6120 hierarchyListener == null && 6121 (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0) { 6122 notifyAncestors |= AWTEvent.HIERARCHY_EVENT_MASK; 6123 } 6124 if ((eventsToDisable & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK)!=0 && 6125 hierarchyBoundsListener == null && 6126 (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0) { 6127 notifyAncestors |= AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK; 6128 } 6129 eventMask &= ~eventsToDisable; 6130 } 6131 if (notifyAncestors != 0) { 6132 synchronized (getTreeLock()) { 6133 adjustListeningChildrenOnParent(notifyAncestors, -1); 6134 } 6135 } 6136 } 6137 6138 transient sun.awt.EventQueueItem[] eventCache; 6139 6140 /** 6141 * @see #isCoalescingEnabled 6142 * @see #checkCoalescing 6143 */ 6144 transient private boolean coalescingEnabled = checkCoalescing(); 6145 6146 /** 6147 * Weak map of known coalesceEvent overriders. 6148 * Value indicates whether overriden. 6149 * Bootstrap classes are not included. 6150 */ 6151 private static final Map<Class<?>, Boolean> coalesceMap = 6152 new java.util.WeakHashMap<Class<?>, Boolean>(); 6153 6154 /** 6155 * Indicates whether this class overrides coalesceEvents. 6156 * It is assumed that all classes that are loaded from the bootstrap 6157 * do not. 6158 * The boostrap class loader is assumed to be represented by null. 6159 * We do not check that the method really overrides 6160 * (it might be static, private or package private). 6161 */ checkCoalescing()6162 private boolean checkCoalescing() { 6163 if (getClass().getClassLoader()==null) { 6164 return false; 6165 } 6166 final Class<? extends Component> clazz = getClass(); 6167 synchronized (coalesceMap) { 6168 // Check cache. 6169 Boolean value = coalesceMap.get(clazz); 6170 if (value != null) { 6171 return value; 6172 } 6173 6174 // Need to check non-bootstraps. 6175 Boolean enabled = java.security.AccessController.doPrivileged( 6176 new java.security.PrivilegedAction<Boolean>() { 6177 public Boolean run() { 6178 return isCoalesceEventsOverriden(clazz); 6179 } 6180 } 6181 ); 6182 coalesceMap.put(clazz, enabled); 6183 return enabled; 6184 } 6185 } 6186 6187 /** 6188 * Parameter types of coalesceEvents(AWTEvent,AWTEVent). 6189 */ 6190 private static final Class[] coalesceEventsParams = { 6191 AWTEvent.class, AWTEvent.class 6192 }; 6193 6194 /** 6195 * Indicates whether a class or its superclasses override coalesceEvents. 6196 * Must be called with lock on coalesceMap and privileged. 6197 * @see checkCoalescing 6198 */ isCoalesceEventsOverriden(Class<?> clazz)6199 private static boolean isCoalesceEventsOverriden(Class<?> clazz) { 6200 assert Thread.holdsLock(coalesceMap); 6201 6202 // First check superclass - we may not need to bother ourselves. 6203 Class<?> superclass = clazz.getSuperclass(); 6204 if (superclass == null) { 6205 // Only occurs on implementations that 6206 // do not use null to represent the bootsrap class loader. 6207 return false; 6208 } 6209 if (superclass.getClassLoader() != null) { 6210 Boolean value = coalesceMap.get(superclass); 6211 if (value == null) { 6212 // Not done already - recurse. 6213 if (isCoalesceEventsOverriden(superclass)) { 6214 coalesceMap.put(superclass, true); 6215 return true; 6216 } 6217 } else if (value) { 6218 return true; 6219 } 6220 } 6221 6222 try { 6223 // Throws if not overriden. 6224 clazz.getDeclaredMethod( 6225 "coalesceEvents", coalesceEventsParams 6226 ); 6227 return true; 6228 } catch (NoSuchMethodException e) { 6229 // Not present in this class. 6230 return false; 6231 } 6232 } 6233 6234 /** 6235 * Indicates whether coalesceEvents may do something. 6236 */ isCoalescingEnabled()6237 final boolean isCoalescingEnabled() { 6238 return coalescingEnabled; 6239 } 6240 6241 6242 /** 6243 * Potentially coalesce an event being posted with an existing 6244 * event. This method is called by <code>EventQueue.postEvent</code> 6245 * if an event with the same ID as the event to be posted is found in 6246 * the queue (both events must have this component as their source). 6247 * This method either returns a coalesced event which replaces 6248 * the existing event (and the new event is then discarded), or 6249 * <code>null</code> to indicate that no combining should be done 6250 * (add the second event to the end of the queue). Either event 6251 * parameter may be modified and returned, as the other one is discarded 6252 * unless <code>null</code> is returned. 6253 * <p> 6254 * This implementation of <code>coalesceEvents</code> coalesces 6255 * two event types: mouse move (and drag) events, 6256 * and paint (and update) events. 6257 * For mouse move events the last event is always returned, causing 6258 * intermediate moves to be discarded. For paint events, the new 6259 * event is coalesced into a complex <code>RepaintArea</code> in the peer. 6260 * The new <code>AWTEvent</code> is always returned. 6261 * 6262 * @param existingEvent the event already on the <code>EventQueue</code> 6263 * @param newEvent the event being posted to the 6264 * <code>EventQueue</code> 6265 * @return a coalesced event, or <code>null</code> indicating that no 6266 * coalescing was done 6267 */ coalesceEvents(AWTEvent existingEvent, AWTEvent newEvent)6268 protected AWTEvent coalesceEvents(AWTEvent existingEvent, 6269 AWTEvent newEvent) { 6270 return null; 6271 } 6272 6273 /** 6274 * Processes events occurring on this component. By default this 6275 * method calls the appropriate 6276 * <code>process<event type>Event</code> 6277 * method for the given class of event. 6278 * <p>Note that if the event parameter is <code>null</code> 6279 * the behavior is unspecified and may result in an 6280 * exception. 6281 * 6282 * @param e the event 6283 * @see #processComponentEvent 6284 * @see #processFocusEvent 6285 * @see #processKeyEvent 6286 * @see #processMouseEvent 6287 * @see #processMouseMotionEvent 6288 * @see #processInputMethodEvent 6289 * @see #processHierarchyEvent 6290 * @see #processMouseWheelEvent 6291 * @since JDK1.1 6292 */ processEvent(AWTEvent e)6293 protected void processEvent(AWTEvent e) { 6294 if (e instanceof FocusEvent) { 6295 processFocusEvent((FocusEvent)e); 6296 6297 } else if (e instanceof MouseEvent) { 6298 switch(e.getID()) { 6299 case MouseEvent.MOUSE_PRESSED: 6300 case MouseEvent.MOUSE_RELEASED: 6301 case MouseEvent.MOUSE_CLICKED: 6302 case MouseEvent.MOUSE_ENTERED: 6303 case MouseEvent.MOUSE_EXITED: 6304 processMouseEvent((MouseEvent)e); 6305 break; 6306 case MouseEvent.MOUSE_MOVED: 6307 case MouseEvent.MOUSE_DRAGGED: 6308 processMouseMotionEvent((MouseEvent)e); 6309 break; 6310 case MouseEvent.MOUSE_WHEEL: 6311 processMouseWheelEvent((MouseWheelEvent)e); 6312 break; 6313 } 6314 6315 } else if (e instanceof KeyEvent) { 6316 processKeyEvent((KeyEvent)e); 6317 6318 } else if (e instanceof ComponentEvent) { 6319 processComponentEvent((ComponentEvent)e); 6320 } else if (e instanceof InputMethodEvent) { 6321 processInputMethodEvent((InputMethodEvent)e); 6322 } else if (e instanceof HierarchyEvent) { 6323 switch (e.getID()) { 6324 case HierarchyEvent.HIERARCHY_CHANGED: 6325 processHierarchyEvent((HierarchyEvent)e); 6326 break; 6327 case HierarchyEvent.ANCESTOR_MOVED: 6328 case HierarchyEvent.ANCESTOR_RESIZED: 6329 processHierarchyBoundsEvent((HierarchyEvent)e); 6330 break; 6331 } 6332 } 6333 } 6334 6335 /** 6336 * Processes component events occurring on this component by 6337 * dispatching them to any registered 6338 * <code>ComponentListener</code> objects. 6339 * <p> 6340 * This method is not called unless component events are 6341 * enabled for this component. Component events are enabled 6342 * when one of the following occurs: 6343 * <ul> 6344 * <li>A <code>ComponentListener</code> object is registered 6345 * via <code>addComponentListener</code>. 6346 * <li>Component events are enabled via <code>enableEvents</code>. 6347 * </ul> 6348 * <p>Note that if the event parameter is <code>null</code> 6349 * the behavior is unspecified and may result in an 6350 * exception. 6351 * 6352 * @param e the component event 6353 * @see java.awt.event.ComponentEvent 6354 * @see java.awt.event.ComponentListener 6355 * @see #addComponentListener 6356 * @see #enableEvents 6357 * @since JDK1.1 6358 */ processComponentEvent(ComponentEvent e)6359 protected void processComponentEvent(ComponentEvent e) { 6360 ComponentListener listener = componentListener; 6361 if (listener != null) { 6362 int id = e.getID(); 6363 switch(id) { 6364 case ComponentEvent.COMPONENT_RESIZED: 6365 listener.componentResized(e); 6366 break; 6367 case ComponentEvent.COMPONENT_MOVED: 6368 listener.componentMoved(e); 6369 break; 6370 case ComponentEvent.COMPONENT_SHOWN: 6371 listener.componentShown(e); 6372 break; 6373 case ComponentEvent.COMPONENT_HIDDEN: 6374 listener.componentHidden(e); 6375 break; 6376 } 6377 } 6378 } 6379 6380 /** 6381 * Processes focus events occurring on this component by 6382 * dispatching them to any registered 6383 * <code>FocusListener</code> objects. 6384 * <p> 6385 * This method is not called unless focus events are 6386 * enabled for this component. Focus events are enabled 6387 * when one of the following occurs: 6388 * <ul> 6389 * <li>A <code>FocusListener</code> object is registered 6390 * via <code>addFocusListener</code>. 6391 * <li>Focus events are enabled via <code>enableEvents</code>. 6392 * </ul> 6393 * <p> 6394 * If focus events are enabled for a <code>Component</code>, 6395 * the current <code>KeyboardFocusManager</code> determines 6396 * whether or not a focus event should be dispatched to 6397 * registered <code>FocusListener</code> objects. If the 6398 * events are to be dispatched, the <code>KeyboardFocusManager</code> 6399 * calls the <code>Component</code>'s <code>dispatchEvent</code> 6400 * method, which results in a call to the <code>Component</code>'s 6401 * <code>processFocusEvent</code> method. 6402 * <p> 6403 * If focus events are enabled for a <code>Component</code>, calling 6404 * the <code>Component</code>'s <code>dispatchEvent</code> method 6405 * with a <code>FocusEvent</code> as the argument will result in a 6406 * call to the <code>Component</code>'s <code>processFocusEvent</code> 6407 * method regardless of the current <code>KeyboardFocusManager</code>. 6408 * 6409 * <p>Note that if the event parameter is <code>null</code> 6410 * the behavior is unspecified and may result in an 6411 * exception. 6412 * 6413 * @param e the focus event 6414 * @see java.awt.event.FocusEvent 6415 * @see java.awt.event.FocusListener 6416 * @see java.awt.KeyboardFocusManager 6417 * @see #addFocusListener 6418 * @see #enableEvents 6419 * @see #dispatchEvent 6420 * @since JDK1.1 6421 */ processFocusEvent(FocusEvent e)6422 protected void processFocusEvent(FocusEvent e) { 6423 FocusListener listener = focusListener; 6424 if (listener != null) { 6425 int id = e.getID(); 6426 switch(id) { 6427 case FocusEvent.FOCUS_GAINED: 6428 listener.focusGained(e); 6429 break; 6430 case FocusEvent.FOCUS_LOST: 6431 listener.focusLost(e); 6432 break; 6433 } 6434 } 6435 } 6436 6437 /** 6438 * Processes key events occurring on this component by 6439 * dispatching them to any registered 6440 * <code>KeyListener</code> objects. 6441 * <p> 6442 * This method is not called unless key events are 6443 * enabled for this component. Key events are enabled 6444 * when one of the following occurs: 6445 * <ul> 6446 * <li>A <code>KeyListener</code> object is registered 6447 * via <code>addKeyListener</code>. 6448 * <li>Key events are enabled via <code>enableEvents</code>. 6449 * </ul> 6450 * 6451 * <p> 6452 * If key events are enabled for a <code>Component</code>, 6453 * the current <code>KeyboardFocusManager</code> determines 6454 * whether or not a key event should be dispatched to 6455 * registered <code>KeyListener</code> objects. The 6456 * <code>DefaultKeyboardFocusManager</code> will not dispatch 6457 * key events to a <code>Component</code> that is not the focus 6458 * owner or is not showing. 6459 * <p> 6460 * As of J2SE 1.4, <code>KeyEvent</code>s are redirected to 6461 * the focus owner. Please see the 6462 * <a href="doc-files/FocusSpec.html">Focus Specification</a> 6463 * for further information. 6464 * <p> 6465 * Calling a <code>Component</code>'s <code>dispatchEvent</code> 6466 * method with a <code>KeyEvent</code> as the argument will 6467 * result in a call to the <code>Component</code>'s 6468 * <code>processKeyEvent</code> method regardless of the 6469 * current <code>KeyboardFocusManager</code> as long as the 6470 * component is showing, focused, and enabled, and key events 6471 * are enabled on it. 6472 * <p>If the event parameter is <code>null</code> 6473 * the behavior is unspecified and may result in an 6474 * exception. 6475 * 6476 * @param e the key event 6477 * @see java.awt.event.KeyEvent 6478 * @see java.awt.event.KeyListener 6479 * @see java.awt.KeyboardFocusManager 6480 * @see java.awt.DefaultKeyboardFocusManager 6481 * @see #processEvent 6482 * @see #dispatchEvent 6483 * @see #addKeyListener 6484 * @see #enableEvents 6485 * @see #isShowing 6486 * @since JDK1.1 6487 */ processKeyEvent(KeyEvent e)6488 protected void processKeyEvent(KeyEvent e) { 6489 KeyListener listener = keyListener; 6490 if (listener != null) { 6491 int id = e.getID(); 6492 switch(id) { 6493 case KeyEvent.KEY_TYPED: 6494 listener.keyTyped(e); 6495 break; 6496 case KeyEvent.KEY_PRESSED: 6497 listener.keyPressed(e); 6498 break; 6499 case KeyEvent.KEY_RELEASED: 6500 listener.keyReleased(e); 6501 break; 6502 } 6503 } 6504 } 6505 6506 /** 6507 * Processes mouse events occurring on this component by 6508 * dispatching them to any registered 6509 * <code>MouseListener</code> objects. 6510 * <p> 6511 * This method is not called unless mouse events are 6512 * enabled for this component. Mouse events are enabled 6513 * when one of the following occurs: 6514 * <ul> 6515 * <li>A <code>MouseListener</code> object is registered 6516 * via <code>addMouseListener</code>. 6517 * <li>Mouse events are enabled via <code>enableEvents</code>. 6518 * </ul> 6519 * <p>Note that if the event parameter is <code>null</code> 6520 * the behavior is unspecified and may result in an 6521 * exception. 6522 * 6523 * @param e the mouse event 6524 * @see java.awt.event.MouseEvent 6525 * @see java.awt.event.MouseListener 6526 * @see #addMouseListener 6527 * @see #enableEvents 6528 * @since JDK1.1 6529 */ processMouseEvent(MouseEvent e)6530 protected void processMouseEvent(MouseEvent e) { 6531 MouseListener listener = mouseListener; 6532 if (listener != null) { 6533 int id = e.getID(); 6534 switch(id) { 6535 case MouseEvent.MOUSE_PRESSED: 6536 listener.mousePressed(e); 6537 break; 6538 case MouseEvent.MOUSE_RELEASED: 6539 listener.mouseReleased(e); 6540 break; 6541 case MouseEvent.MOUSE_CLICKED: 6542 listener.mouseClicked(e); 6543 break; 6544 case MouseEvent.MOUSE_EXITED: 6545 listener.mouseExited(e); 6546 break; 6547 case MouseEvent.MOUSE_ENTERED: 6548 listener.mouseEntered(e); 6549 break; 6550 } 6551 } 6552 } 6553 6554 /** 6555 * Processes mouse motion events occurring on this component by 6556 * dispatching them to any registered 6557 * <code>MouseMotionListener</code> objects. 6558 * <p> 6559 * This method is not called unless mouse motion events are 6560 * enabled for this component. Mouse motion events are enabled 6561 * when one of the following occurs: 6562 * <ul> 6563 * <li>A <code>MouseMotionListener</code> object is registered 6564 * via <code>addMouseMotionListener</code>. 6565 * <li>Mouse motion events are enabled via <code>enableEvents</code>. 6566 * </ul> 6567 * <p>Note that if the event parameter is <code>null</code> 6568 * the behavior is unspecified and may result in an 6569 * exception. 6570 * 6571 * @param e the mouse motion event 6572 * @see java.awt.event.MouseEvent 6573 * @see java.awt.event.MouseMotionListener 6574 * @see #addMouseMotionListener 6575 * @see #enableEvents 6576 * @since JDK1.1 6577 */ processMouseMotionEvent(MouseEvent e)6578 protected void processMouseMotionEvent(MouseEvent e) { 6579 MouseMotionListener listener = mouseMotionListener; 6580 if (listener != null) { 6581 int id = e.getID(); 6582 switch(id) { 6583 case MouseEvent.MOUSE_MOVED: 6584 listener.mouseMoved(e); 6585 break; 6586 case MouseEvent.MOUSE_DRAGGED: 6587 listener.mouseDragged(e); 6588 break; 6589 } 6590 } 6591 } 6592 6593 /** 6594 * Processes mouse wheel events occurring on this component by 6595 * dispatching them to any registered 6596 * <code>MouseWheelListener</code> objects. 6597 * <p> 6598 * This method is not called unless mouse wheel events are 6599 * enabled for this component. Mouse wheel events are enabled 6600 * when one of the following occurs: 6601 * <ul> 6602 * <li>A <code>MouseWheelListener</code> object is registered 6603 * via <code>addMouseWheelListener</code>. 6604 * <li>Mouse wheel events are enabled via <code>enableEvents</code>. 6605 * </ul> 6606 * <p> 6607 * For information on how mouse wheel events are dispatched, see 6608 * the class description for {@link MouseWheelEvent}. 6609 * <p> 6610 * Note that if the event parameter is <code>null</code> 6611 * the behavior is unspecified and may result in an 6612 * exception. 6613 * 6614 * @param e the mouse wheel event 6615 * @see java.awt.event.MouseWheelEvent 6616 * @see java.awt.event.MouseWheelListener 6617 * @see #addMouseWheelListener 6618 * @see #enableEvents 6619 * @since 1.4 6620 */ processMouseWheelEvent(MouseWheelEvent e)6621 protected void processMouseWheelEvent(MouseWheelEvent e) { 6622 MouseWheelListener listener = mouseWheelListener; 6623 if (listener != null) { 6624 int id = e.getID(); 6625 switch(id) { 6626 case MouseEvent.MOUSE_WHEEL: 6627 listener.mouseWheelMoved(e); 6628 break; 6629 } 6630 } 6631 } 6632 postsOldMouseEvents()6633 boolean postsOldMouseEvents() { 6634 return false; 6635 } 6636 6637 /** 6638 * Processes input method events occurring on this component by 6639 * dispatching them to any registered 6640 * <code>InputMethodListener</code> objects. 6641 * <p> 6642 * This method is not called unless input method events 6643 * are enabled for this component. Input method events are enabled 6644 * when one of the following occurs: 6645 * <ul> 6646 * <li>An <code>InputMethodListener</code> object is registered 6647 * via <code>addInputMethodListener</code>. 6648 * <li>Input method events are enabled via <code>enableEvents</code>. 6649 * </ul> 6650 * <p>Note that if the event parameter is <code>null</code> 6651 * the behavior is unspecified and may result in an 6652 * exception. 6653 * 6654 * @param e the input method event 6655 * @see java.awt.event.InputMethodEvent 6656 * @see java.awt.event.InputMethodListener 6657 * @see #addInputMethodListener 6658 * @see #enableEvents 6659 * @since 1.2 6660 */ processInputMethodEvent(InputMethodEvent e)6661 protected void processInputMethodEvent(InputMethodEvent e) { 6662 InputMethodListener listener = inputMethodListener; 6663 if (listener != null) { 6664 int id = e.getID(); 6665 switch (id) { 6666 case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED: 6667 listener.inputMethodTextChanged(e); 6668 break; 6669 case InputMethodEvent.CARET_POSITION_CHANGED: 6670 listener.caretPositionChanged(e); 6671 break; 6672 } 6673 } 6674 } 6675 6676 /** 6677 * Processes hierarchy events occurring on this component by 6678 * dispatching them to any registered 6679 * <code>HierarchyListener</code> objects. 6680 * <p> 6681 * This method is not called unless hierarchy events 6682 * are enabled for this component. Hierarchy events are enabled 6683 * when one of the following occurs: 6684 * <ul> 6685 * <li>An <code>HierarchyListener</code> object is registered 6686 * via <code>addHierarchyListener</code>. 6687 * <li>Hierarchy events are enabled via <code>enableEvents</code>. 6688 * </ul> 6689 * <p>Note that if the event parameter is <code>null</code> 6690 * the behavior is unspecified and may result in an 6691 * exception. 6692 * 6693 * @param e the hierarchy event 6694 * @see java.awt.event.HierarchyEvent 6695 * @see java.awt.event.HierarchyListener 6696 * @see #addHierarchyListener 6697 * @see #enableEvents 6698 * @since 1.3 6699 */ processHierarchyEvent(HierarchyEvent e)6700 protected void processHierarchyEvent(HierarchyEvent e) { 6701 HierarchyListener listener = hierarchyListener; 6702 if (listener != null) { 6703 int id = e.getID(); 6704 switch (id) { 6705 case HierarchyEvent.HIERARCHY_CHANGED: 6706 listener.hierarchyChanged(e); 6707 break; 6708 } 6709 } 6710 } 6711 6712 /** 6713 * Processes hierarchy bounds events occurring on this component by 6714 * dispatching them to any registered 6715 * <code>HierarchyBoundsListener</code> objects. 6716 * <p> 6717 * This method is not called unless hierarchy bounds events 6718 * are enabled for this component. Hierarchy bounds events are enabled 6719 * when one of the following occurs: 6720 * <ul> 6721 * <li>An <code>HierarchyBoundsListener</code> object is registered 6722 * via <code>addHierarchyBoundsListener</code>. 6723 * <li>Hierarchy bounds events are enabled via <code>enableEvents</code>. 6724 * </ul> 6725 * <p>Note that if the event parameter is <code>null</code> 6726 * the behavior is unspecified and may result in an 6727 * exception. 6728 * 6729 * @param e the hierarchy event 6730 * @see java.awt.event.HierarchyEvent 6731 * @see java.awt.event.HierarchyBoundsListener 6732 * @see #addHierarchyBoundsListener 6733 * @see #enableEvents 6734 * @since 1.3 6735 */ processHierarchyBoundsEvent(HierarchyEvent e)6736 protected void processHierarchyBoundsEvent(HierarchyEvent e) { 6737 HierarchyBoundsListener listener = hierarchyBoundsListener; 6738 if (listener != null) { 6739 int id = e.getID(); 6740 switch (id) { 6741 case HierarchyEvent.ANCESTOR_MOVED: 6742 listener.ancestorMoved(e); 6743 break; 6744 case HierarchyEvent.ANCESTOR_RESIZED: 6745 listener.ancestorResized(e); 6746 break; 6747 } 6748 } 6749 } 6750 6751 /** 6752 * @deprecated As of JDK version 1.1 6753 * replaced by processEvent(AWTEvent). 6754 */ 6755 @Deprecated handleEvent(Event evt)6756 public boolean handleEvent(Event evt) { 6757 switch (evt.id) { 6758 case Event.MOUSE_ENTER: 6759 return mouseEnter(evt, evt.x, evt.y); 6760 6761 case Event.MOUSE_EXIT: 6762 return mouseExit(evt, evt.x, evt.y); 6763 6764 case Event.MOUSE_MOVE: 6765 return mouseMove(evt, evt.x, evt.y); 6766 6767 case Event.MOUSE_DOWN: 6768 return mouseDown(evt, evt.x, evt.y); 6769 6770 case Event.MOUSE_DRAG: 6771 return mouseDrag(evt, evt.x, evt.y); 6772 6773 case Event.MOUSE_UP: 6774 return mouseUp(evt, evt.x, evt.y); 6775 6776 case Event.KEY_PRESS: 6777 case Event.KEY_ACTION: 6778 return keyDown(evt, evt.key); 6779 6780 case Event.KEY_RELEASE: 6781 case Event.KEY_ACTION_RELEASE: 6782 return keyUp(evt, evt.key); 6783 6784 case Event.ACTION_EVENT: 6785 return action(evt, evt.arg); 6786 case Event.GOT_FOCUS: 6787 return gotFocus(evt, evt.arg); 6788 case Event.LOST_FOCUS: 6789 return lostFocus(evt, evt.arg); 6790 } 6791 return false; 6792 } 6793 6794 /** 6795 * @deprecated As of JDK version 1.1, 6796 * replaced by processMouseEvent(MouseEvent). 6797 */ 6798 @Deprecated mouseDown(Event evt, int x, int y)6799 public boolean mouseDown(Event evt, int x, int y) { 6800 return false; 6801 } 6802 6803 /** 6804 * @deprecated As of JDK version 1.1, 6805 * replaced by processMouseMotionEvent(MouseEvent). 6806 */ 6807 @Deprecated mouseDrag(Event evt, int x, int y)6808 public boolean mouseDrag(Event evt, int x, int y) { 6809 return false; 6810 } 6811 6812 /** 6813 * @deprecated As of JDK version 1.1, 6814 * replaced by processMouseEvent(MouseEvent). 6815 */ 6816 @Deprecated mouseUp(Event evt, int x, int y)6817 public boolean mouseUp(Event evt, int x, int y) { 6818 return false; 6819 } 6820 6821 /** 6822 * @deprecated As of JDK version 1.1, 6823 * replaced by processMouseMotionEvent(MouseEvent). 6824 */ 6825 @Deprecated mouseMove(Event evt, int x, int y)6826 public boolean mouseMove(Event evt, int x, int y) { 6827 return false; 6828 } 6829 6830 /** 6831 * @deprecated As of JDK version 1.1, 6832 * replaced by processMouseEvent(MouseEvent). 6833 */ 6834 @Deprecated mouseEnter(Event evt, int x, int y)6835 public boolean mouseEnter(Event evt, int x, int y) { 6836 return false; 6837 } 6838 6839 /** 6840 * @deprecated As of JDK version 1.1, 6841 * replaced by processMouseEvent(MouseEvent). 6842 */ 6843 @Deprecated mouseExit(Event evt, int x, int y)6844 public boolean mouseExit(Event evt, int x, int y) { 6845 return false; 6846 } 6847 6848 /** 6849 * @deprecated As of JDK version 1.1, 6850 * replaced by processKeyEvent(KeyEvent). 6851 */ 6852 @Deprecated keyDown(Event evt, int key)6853 public boolean keyDown(Event evt, int key) { 6854 return false; 6855 } 6856 6857 /** 6858 * @deprecated As of JDK version 1.1, 6859 * replaced by processKeyEvent(KeyEvent). 6860 */ 6861 @Deprecated keyUp(Event evt, int key)6862 public boolean keyUp(Event evt, int key) { 6863 return false; 6864 } 6865 6866 /** 6867 * @deprecated As of JDK version 1.1, 6868 * should register this component as ActionListener on component 6869 * which fires action events. 6870 */ 6871 @Deprecated action(Event evt, Object what)6872 public boolean action(Event evt, Object what) { 6873 return false; 6874 } 6875 6876 /** 6877 * Makes this <code>Component</code> displayable by connecting it to a 6878 * native screen resource. 6879 * This method is called internally by the toolkit and should 6880 * not be called directly by programs. 6881 * <p> 6882 * This method changes layout-related information, and therefore, 6883 * invalidates the component hierarchy. 6884 * 6885 * @see #isDisplayable 6886 * @see #removeNotify 6887 * @see #invalidate 6888 * @since JDK1.0 6889 */ addNotify()6890 public void addNotify() { 6891 synchronized (getTreeLock()) { 6892 ComponentPeer peer = this.peer; 6893 if (peer == null || peer instanceof LightweightPeer){ 6894 if (peer == null) { 6895 // Update both the Component's peer variable and the local 6896 // variable we use for thread safety. 6897 this.peer = peer = getToolkit().createComponent(this); 6898 } 6899 6900 // This is a lightweight component which means it won't be 6901 // able to get window-related events by itself. If any 6902 // have been enabled, then the nearest native container must 6903 // be enabled. 6904 if (parent != null) { 6905 long mask = 0; 6906 if ((mouseListener != null) || ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0)) { 6907 mask |= AWTEvent.MOUSE_EVENT_MASK; 6908 } 6909 if ((mouseMotionListener != null) || 6910 ((eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0)) { 6911 mask |= AWTEvent.MOUSE_MOTION_EVENT_MASK; 6912 } 6913 if ((mouseWheelListener != null ) || 6914 ((eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0)) { 6915 mask |= AWTEvent.MOUSE_WHEEL_EVENT_MASK; 6916 } 6917 if (focusListener != null || (eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0) { 6918 mask |= AWTEvent.FOCUS_EVENT_MASK; 6919 } 6920 if (keyListener != null || (eventMask & AWTEvent.KEY_EVENT_MASK) != 0) { 6921 mask |= AWTEvent.KEY_EVENT_MASK; 6922 } 6923 if (mask != 0) { 6924 parent.proxyEnableEvents(mask); 6925 } 6926 } 6927 } else { 6928 // It's native. If the parent is lightweight it will need some 6929 // help. 6930 Container parent = getContainer(); 6931 if (parent != null && parent.isLightweight()) { 6932 relocateComponent(); 6933 if (!parent.isRecursivelyVisibleUpToHeavyweightContainer()) 6934 { 6935 peer.setVisible(false); 6936 } 6937 } 6938 } 6939 invalidate(); 6940 6941 int npopups = (popups != null? popups.size() : 0); 6942 for (int i = 0 ; i < npopups ; i++) { 6943 PopupMenu popup = popups.elementAt(i); 6944 popup.addNotify(); 6945 } 6946 6947 if (dropTarget != null) dropTarget.addNotify(peer); 6948 6949 peerFont = getFont(); 6950 6951 if (getContainer() != null && !isAddNotifyComplete) { 6952 getContainer().increaseComponentCount(this); 6953 } 6954 6955 6956 // Update stacking order 6957 updateZOrder(); 6958 6959 if (!isAddNotifyComplete) { 6960 mixOnShowing(); 6961 } 6962 6963 isAddNotifyComplete = true; 6964 6965 if (hierarchyListener != null || 6966 (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 || 6967 Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK)) { 6968 HierarchyEvent e = 6969 new HierarchyEvent(this, HierarchyEvent.HIERARCHY_CHANGED, 6970 this, parent, 6971 HierarchyEvent.DISPLAYABILITY_CHANGED | 6972 ((isRecursivelyVisible()) 6973 ? HierarchyEvent.SHOWING_CHANGED 6974 : 0)); 6975 dispatchEvent(e); 6976 } 6977 } 6978 } 6979 6980 /** 6981 * Makes this <code>Component</code> undisplayable by destroying it native 6982 * screen resource. 6983 * <p> 6984 * This method is called by the toolkit internally and should 6985 * not be called directly by programs. Code overriding 6986 * this method should call <code>super.removeNotify</code> as 6987 * the first line of the overriding method. 6988 * 6989 * @see #isDisplayable 6990 * @see #addNotify 6991 * @since JDK1.0 6992 */ removeNotify()6993 public void removeNotify() { 6994 KeyboardFocusManager.clearMostRecentFocusOwner(this); 6995 if (KeyboardFocusManager.getCurrentKeyboardFocusManager(). 6996 getPermanentFocusOwner() == this) 6997 { 6998 KeyboardFocusManager.getCurrentKeyboardFocusManager(). 6999 setGlobalPermanentFocusOwner(null); 7000 } 7001 7002 synchronized (getTreeLock()) { 7003 if (isFocusOwner() && KeyboardFocusManager.isAutoFocusTransferEnabledFor(this)) { 7004 transferFocus(true); 7005 } 7006 7007 if (getContainer() != null && isAddNotifyComplete) { 7008 getContainer().decreaseComponentCount(this); 7009 } 7010 7011 int npopups = (popups != null? popups.size() : 0); 7012 for (int i = 0 ; i < npopups ; i++) { 7013 PopupMenu popup = popups.elementAt(i); 7014 popup.removeNotify(); 7015 } 7016 // If there is any input context for this component, notify 7017 // that this component is being removed. (This has to be done 7018 // before hiding peer.) 7019 if ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) { 7020 InputContext inputContext = getInputContext(); 7021 if (inputContext != null) { 7022 inputContext.removeNotify(this); 7023 } 7024 } 7025 7026 ComponentPeer p = peer; 7027 if (p != null) { 7028 boolean isLightweight = isLightweight(); 7029 7030 if (bufferStrategy instanceof FlipBufferStrategy) { 7031 ((FlipBufferStrategy)bufferStrategy).destroyBuffers(); 7032 } 7033 7034 if (dropTarget != null) dropTarget.removeNotify(peer); 7035 7036 // Hide peer first to stop system events such as cursor moves. 7037 if (visible) { 7038 p.setVisible(false); 7039 } 7040 7041 peer = null; // Stop peer updates. 7042 peerFont = null; 7043 7044 Toolkit.getEventQueue().removeSourceEvents(this, false); 7045 KeyboardFocusManager.getCurrentKeyboardFocusManager(). 7046 discardKeyEvents(this); 7047 7048 p.dispose(); 7049 7050 mixOnHiding(isLightweight); 7051 7052 isAddNotifyComplete = false; 7053 // Nullifying compoundShape means that the component has normal shape 7054 // (or has no shape at all). 7055 this.compoundShape = null; 7056 } 7057 7058 if (hierarchyListener != null || 7059 (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 || 7060 Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK)) { 7061 HierarchyEvent e = 7062 new HierarchyEvent(this, HierarchyEvent.HIERARCHY_CHANGED, 7063 this, parent, 7064 HierarchyEvent.DISPLAYABILITY_CHANGED | 7065 ((isRecursivelyVisible()) 7066 ? HierarchyEvent.SHOWING_CHANGED 7067 : 0)); 7068 dispatchEvent(e); 7069 } 7070 } 7071 } 7072 7073 /** 7074 * @deprecated As of JDK version 1.1, 7075 * replaced by processFocusEvent(FocusEvent). 7076 */ 7077 @Deprecated gotFocus(Event evt, Object what)7078 public boolean gotFocus(Event evt, Object what) { 7079 return false; 7080 } 7081 7082 /** 7083 * @deprecated As of JDK version 1.1, 7084 * replaced by processFocusEvent(FocusEvent). 7085 */ 7086 @Deprecated lostFocus(Event evt, Object what)7087 public boolean lostFocus(Event evt, Object what) { 7088 return false; 7089 } 7090 7091 /** 7092 * Returns whether this <code>Component</code> can become the focus 7093 * owner. 7094 * 7095 * @return <code>true</code> if this <code>Component</code> is 7096 * focusable; <code>false</code> otherwise 7097 * @see #setFocusable 7098 * @since JDK1.1 7099 * @deprecated As of 1.4, replaced by <code>isFocusable()</code>. 7100 */ 7101 @Deprecated isFocusTraversable()7102 public boolean isFocusTraversable() { 7103 if (isFocusTraversableOverridden == FOCUS_TRAVERSABLE_UNKNOWN) { 7104 isFocusTraversableOverridden = FOCUS_TRAVERSABLE_DEFAULT; 7105 } 7106 return focusable; 7107 } 7108 7109 /** 7110 * Returns whether this Component can be focused. 7111 * 7112 * @return <code>true</code> if this Component is focusable; 7113 * <code>false</code> otherwise. 7114 * @see #setFocusable 7115 * @since 1.4 7116 */ isFocusable()7117 public boolean isFocusable() { 7118 return isFocusTraversable(); 7119 } 7120 7121 /** 7122 * Sets the focusable state of this Component to the specified value. This 7123 * value overrides the Component's default focusability. 7124 * 7125 * @param focusable indicates whether this Component is focusable 7126 * @see #isFocusable 7127 * @since 1.4 7128 * @beaninfo 7129 * bound: true 7130 */ setFocusable(boolean focusable)7131 public void setFocusable(boolean focusable) { 7132 boolean oldFocusable; 7133 synchronized (this) { 7134 oldFocusable = this.focusable; 7135 this.focusable = focusable; 7136 } 7137 isFocusTraversableOverridden = FOCUS_TRAVERSABLE_SET; 7138 7139 firePropertyChange("focusable", oldFocusable, focusable); 7140 if (oldFocusable && !focusable) { 7141 if (isFocusOwner() && KeyboardFocusManager.isAutoFocusTransferEnabled()) { 7142 transferFocus(true); 7143 } 7144 KeyboardFocusManager.clearMostRecentFocusOwner(this); 7145 } 7146 } 7147 isFocusTraversableOverridden()7148 final boolean isFocusTraversableOverridden() { 7149 return (isFocusTraversableOverridden != FOCUS_TRAVERSABLE_DEFAULT); 7150 } 7151 7152 /** 7153 * Sets the focus traversal keys for a given traversal operation for this 7154 * Component. 7155 * <p> 7156 * The default values for a Component's focus traversal keys are 7157 * implementation-dependent. Sun recommends that all implementations for a 7158 * particular native platform use the same default values. The 7159 * recommendations for Windows and Unix are listed below. These 7160 * recommendations are used in the Sun AWT implementations. 7161 * 7162 * <table border=1 summary="Recommended default values for a Component's focus traversal keys"> 7163 * <tr> 7164 * <th>Identifier</th> 7165 * <th>Meaning</th> 7166 * <th>Default</th> 7167 * </tr> 7168 * <tr> 7169 * <td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</td> 7170 * <td>Normal forward keyboard traversal</td> 7171 * <td>TAB on KEY_PRESSED, CTRL-TAB on KEY_PRESSED</td> 7172 * </tr> 7173 * <tr> 7174 * <td>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</td> 7175 * <td>Normal reverse keyboard traversal</td> 7176 * <td>SHIFT-TAB on KEY_PRESSED, CTRL-SHIFT-TAB on KEY_PRESSED</td> 7177 * </tr> 7178 * <tr> 7179 * <td>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</td> 7180 * <td>Go up one focus traversal cycle</td> 7181 * <td>none</td> 7182 * </tr> 7183 * </table> 7184 * 7185 * To disable a traversal key, use an empty Set; Collections.EMPTY_SET is 7186 * recommended. 7187 * <p> 7188 * Using the AWTKeyStroke API, client code can specify on which of two 7189 * specific KeyEvents, KEY_PRESSED or KEY_RELEASED, the focus traversal 7190 * operation will occur. Regardless of which KeyEvent is specified, 7191 * however, all KeyEvents related to the focus traversal key, including the 7192 * associated KEY_TYPED event, will be consumed, and will not be dispatched 7193 * to any Component. It is a runtime error to specify a KEY_TYPED event as 7194 * mapping to a focus traversal operation, or to map the same event to 7195 * multiple default focus traversal operations. 7196 * <p> 7197 * If a value of null is specified for the Set, this Component inherits the 7198 * Set from its parent. If all ancestors of this Component have null 7199 * specified for the Set, then the current KeyboardFocusManager's default 7200 * Set is used. 7201 * <p> 7202 * This method may throw a {@code ClassCastException} if any {@code Object} 7203 * in {@code keystrokes} is not an {@code AWTKeyStroke}. 7204 * 7205 * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, 7206 * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or 7207 * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS 7208 * @param keystrokes the Set of AWTKeyStroke for the specified operation 7209 * @see #getFocusTraversalKeys 7210 * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS 7211 * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS 7212 * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS 7213 * @throws IllegalArgumentException if id is not one of 7214 * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, 7215 * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or 7216 * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or if keystrokes 7217 * contains null, or if any keystroke represents a KEY_TYPED event, 7218 * or if any keystroke already maps to another focus traversal 7219 * operation for this Component 7220 * @since 1.4 7221 * @beaninfo 7222 * bound: true 7223 */ setFocusTraversalKeys(int id, Set<? extends AWTKeyStroke> keystrokes)7224 public void setFocusTraversalKeys(int id, 7225 Set<? extends AWTKeyStroke> keystrokes) 7226 { 7227 if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH - 1) { 7228 throw new IllegalArgumentException("invalid focus traversal key identifier"); 7229 } 7230 7231 setFocusTraversalKeys_NoIDCheck(id, keystrokes); 7232 } 7233 7234 /** 7235 * Returns the Set of focus traversal keys for a given traversal operation 7236 * for this Component. (See 7237 * <code>setFocusTraversalKeys</code> for a full description of each key.) 7238 * <p> 7239 * If a Set of traversal keys has not been explicitly defined for this 7240 * Component, then this Component's parent's Set is returned. If no Set 7241 * has been explicitly defined for any of this Component's ancestors, then 7242 * the current KeyboardFocusManager's default Set is returned. 7243 * 7244 * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, 7245 * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or 7246 * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS 7247 * @return the Set of AWTKeyStrokes for the specified operation. The Set 7248 * will be unmodifiable, and may be empty. null will never be 7249 * returned. 7250 * @see #setFocusTraversalKeys 7251 * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS 7252 * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS 7253 * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS 7254 * @throws IllegalArgumentException if id is not one of 7255 * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, 7256 * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or 7257 * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS 7258 * @since 1.4 7259 */ getFocusTraversalKeys(int id)7260 public Set<AWTKeyStroke> getFocusTraversalKeys(int id) { 7261 if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH - 1) { 7262 throw new IllegalArgumentException("invalid focus traversal key identifier"); 7263 } 7264 7265 return getFocusTraversalKeys_NoIDCheck(id); 7266 } 7267 7268 // We define these methods so that Container does not need to repeat this 7269 // code. Container cannot call super.<method> because Container allows 7270 // DOWN_CYCLE_TRAVERSAL_KEY while Component does not. The Component method 7271 // would erroneously generate an IllegalArgumentException for 7272 // DOWN_CYCLE_TRAVERSAL_KEY. setFocusTraversalKeys_NoIDCheck(int id, Set<? extends AWTKeyStroke> keystrokes)7273 final void setFocusTraversalKeys_NoIDCheck(int id, Set<? extends AWTKeyStroke> keystrokes) { 7274 Set<AWTKeyStroke> oldKeys; 7275 7276 synchronized (this) { 7277 if (focusTraversalKeys == null) { 7278 initializeFocusTraversalKeys(); 7279 } 7280 7281 if (keystrokes != null) { 7282 for (AWTKeyStroke keystroke : keystrokes ) { 7283 7284 if (keystroke == null) { 7285 throw new IllegalArgumentException("cannot set null focus traversal key"); 7286 } 7287 7288 if (keystroke.getKeyChar() != KeyEvent.CHAR_UNDEFINED) { 7289 throw new IllegalArgumentException("focus traversal keys cannot map to KEY_TYPED events"); 7290 } 7291 7292 for (int i = 0; i < focusTraversalKeys.length; i++) { 7293 if (i == id) { 7294 continue; 7295 } 7296 7297 if (getFocusTraversalKeys_NoIDCheck(i).contains(keystroke)) 7298 { 7299 throw new IllegalArgumentException("focus traversal keys must be unique for a Component"); 7300 } 7301 } 7302 } 7303 } 7304 7305 oldKeys = focusTraversalKeys[id]; 7306 focusTraversalKeys[id] = (keystrokes != null) 7307 ? Collections.unmodifiableSet(new HashSet<AWTKeyStroke>(keystrokes)) 7308 : null; 7309 } 7310 7311 firePropertyChange(focusTraversalKeyPropertyNames[id], oldKeys, 7312 keystrokes); 7313 } getFocusTraversalKeys_NoIDCheck(int id)7314 final Set<AWTKeyStroke> getFocusTraversalKeys_NoIDCheck(int id) { 7315 // Okay to return Set directly because it is an unmodifiable view 7316 @SuppressWarnings("unchecked") 7317 Set<AWTKeyStroke> keystrokes = (focusTraversalKeys != null) 7318 ? focusTraversalKeys[id] 7319 : null; 7320 7321 if (keystrokes != null) { 7322 return keystrokes; 7323 } else { 7324 Container parent = this.parent; 7325 if (parent != null) { 7326 return parent.getFocusTraversalKeys(id); 7327 } else { 7328 return KeyboardFocusManager.getCurrentKeyboardFocusManager(). 7329 getDefaultFocusTraversalKeys(id); 7330 } 7331 } 7332 } 7333 7334 /** 7335 * Returns whether the Set of focus traversal keys for the given focus 7336 * traversal operation has been explicitly defined for this Component. If 7337 * this method returns <code>false</code>, this Component is inheriting the 7338 * Set from an ancestor, or from the current KeyboardFocusManager. 7339 * 7340 * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, 7341 * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or 7342 * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS 7343 * @return <code>true</code> if the the Set of focus traversal keys for the 7344 * given focus traversal operation has been explicitly defined for 7345 * this Component; <code>false</code> otherwise. 7346 * @throws IllegalArgumentException if id is not one of 7347 * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, 7348 * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or 7349 * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS 7350 * @since 1.4 7351 */ areFocusTraversalKeysSet(int id)7352 public boolean areFocusTraversalKeysSet(int id) { 7353 if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH - 1) { 7354 throw new IllegalArgumentException("invalid focus traversal key identifier"); 7355 } 7356 7357 return (focusTraversalKeys != null && focusTraversalKeys[id] != null); 7358 } 7359 7360 /** 7361 * Sets whether focus traversal keys are enabled for this Component. 7362 * Components for which focus traversal keys are disabled receive key 7363 * events for focus traversal keys. Components for which focus traversal 7364 * keys are enabled do not see these events; instead, the events are 7365 * automatically converted to traversal operations. 7366 * 7367 * @param focusTraversalKeysEnabled whether focus traversal keys are 7368 * enabled for this Component 7369 * @see #getFocusTraversalKeysEnabled 7370 * @see #setFocusTraversalKeys 7371 * @see #getFocusTraversalKeys 7372 * @since 1.4 7373 * @beaninfo 7374 * bound: true 7375 */ setFocusTraversalKeysEnabled(boolean focusTraversalKeysEnabled)7376 public void setFocusTraversalKeysEnabled(boolean 7377 focusTraversalKeysEnabled) { 7378 boolean oldFocusTraversalKeysEnabled; 7379 synchronized (this) { 7380 oldFocusTraversalKeysEnabled = this.focusTraversalKeysEnabled; 7381 this.focusTraversalKeysEnabled = focusTraversalKeysEnabled; 7382 } 7383 firePropertyChange("focusTraversalKeysEnabled", 7384 oldFocusTraversalKeysEnabled, 7385 focusTraversalKeysEnabled); 7386 } 7387 7388 /** 7389 * Returns whether focus traversal keys are enabled for this Component. 7390 * Components for which focus traversal keys are disabled receive key 7391 * events for focus traversal keys. Components for which focus traversal 7392 * keys are enabled do not see these events; instead, the events are 7393 * automatically converted to traversal operations. 7394 * 7395 * @return whether focus traversal keys are enabled for this Component 7396 * @see #setFocusTraversalKeysEnabled 7397 * @see #setFocusTraversalKeys 7398 * @see #getFocusTraversalKeys 7399 * @since 1.4 7400 */ getFocusTraversalKeysEnabled()7401 public boolean getFocusTraversalKeysEnabled() { 7402 return focusTraversalKeysEnabled; 7403 } 7404 7405 /** 7406 * Requests that this Component get the input focus, and that this 7407 * Component's top-level ancestor become the focused Window. This 7408 * component must be displayable, focusable, visible and all of 7409 * its ancestors (with the exception of the top-level Window) must 7410 * be visible for the request to be granted. Every effort will be 7411 * made to honor the request; however, in some cases it may be 7412 * impossible to do so. Developers must never assume that this 7413 * Component is the focus owner until this Component receives a 7414 * FOCUS_GAINED event. If this request is denied because this 7415 * Component's top-level Window cannot become the focused Window, 7416 * the request will be remembered and will be granted when the 7417 * Window is later focused by the user. 7418 * <p> 7419 * This method cannot be used to set the focus owner to no Component at 7420 * all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner()</code> 7421 * instead. 7422 * <p> 7423 * Because the focus behavior of this method is platform-dependent, 7424 * developers are strongly encouraged to use 7425 * <code>requestFocusInWindow</code> when possible. 7426 * 7427 * <p>Note: Not all focus transfers result from invoking this method. As 7428 * such, a component may receive focus without this or any of the other 7429 * {@code requestFocus} methods of {@code Component} being invoked. 7430 * 7431 * @see #requestFocusInWindow 7432 * @see java.awt.event.FocusEvent 7433 * @see #addFocusListener 7434 * @see #isFocusable 7435 * @see #isDisplayable 7436 * @see KeyboardFocusManager#clearGlobalFocusOwner 7437 * @since JDK1.0 7438 */ requestFocus()7439 public void requestFocus() { 7440 requestFocusHelper(false, true); 7441 } 7442 requestFocus(CausedFocusEvent.Cause cause)7443 boolean requestFocus(CausedFocusEvent.Cause cause) { 7444 return requestFocusHelper(false, true, cause); 7445 } 7446 7447 /** 7448 * Requests that this <code>Component</code> get the input focus, 7449 * and that this <code>Component</code>'s top-level ancestor 7450 * become the focused <code>Window</code>. This component must be 7451 * displayable, focusable, visible and all of its ancestors (with 7452 * the exception of the top-level Window) must be visible for the 7453 * request to be granted. Every effort will be made to honor the 7454 * request; however, in some cases it may be impossible to do 7455 * so. Developers must never assume that this component is the 7456 * focus owner until this component receives a FOCUS_GAINED 7457 * event. If this request is denied because this component's 7458 * top-level window cannot become the focused window, the request 7459 * will be remembered and will be granted when the window is later 7460 * focused by the user. 7461 * <p> 7462 * This method returns a boolean value. If <code>false</code> is returned, 7463 * the request is <b>guaranteed to fail</b>. If <code>true</code> is 7464 * returned, the request will succeed <b>unless</b> it is vetoed, or an 7465 * extraordinary event, such as disposal of the component's peer, occurs 7466 * before the request can be granted by the native windowing system. Again, 7467 * while a return value of <code>true</code> indicates that the request is 7468 * likely to succeed, developers must never assume that this component is 7469 * the focus owner until this component receives a FOCUS_GAINED event. 7470 * <p> 7471 * This method cannot be used to set the focus owner to no component at 7472 * all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner</code> 7473 * instead. 7474 * <p> 7475 * Because the focus behavior of this method is platform-dependent, 7476 * developers are strongly encouraged to use 7477 * <code>requestFocusInWindow</code> when possible. 7478 * <p> 7479 * Every effort will be made to ensure that <code>FocusEvent</code>s 7480 * generated as a 7481 * result of this request will have the specified temporary value. However, 7482 * because specifying an arbitrary temporary state may not be implementable 7483 * on all native windowing systems, correct behavior for this method can be 7484 * guaranteed only for lightweight <code>Component</code>s. 7485 * This method is not intended 7486 * for general use, but exists instead as a hook for lightweight component 7487 * libraries, such as Swing. 7488 * 7489 * <p>Note: Not all focus transfers result from invoking this method. As 7490 * such, a component may receive focus without this or any of the other 7491 * {@code requestFocus} methods of {@code Component} being invoked. 7492 * 7493 * @param temporary true if the focus change is temporary, 7494 * such as when the window loses the focus; for 7495 * more information on temporary focus changes see the 7496 *<a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a> 7497 * @return <code>false</code> if the focus change request is guaranteed to 7498 * fail; <code>true</code> if it is likely to succeed 7499 * @see java.awt.event.FocusEvent 7500 * @see #addFocusListener 7501 * @see #isFocusable 7502 * @see #isDisplayable 7503 * @see KeyboardFocusManager#clearGlobalFocusOwner 7504 * @since 1.4 7505 */ requestFocus(boolean temporary)7506 protected boolean requestFocus(boolean temporary) { 7507 return requestFocusHelper(temporary, true); 7508 } 7509 requestFocus(boolean temporary, CausedFocusEvent.Cause cause)7510 boolean requestFocus(boolean temporary, CausedFocusEvent.Cause cause) { 7511 return requestFocusHelper(temporary, true, cause); 7512 } 7513 /** 7514 * Requests that this Component get the input focus, if this 7515 * Component's top-level ancestor is already the focused 7516 * Window. This component must be displayable, focusable, visible 7517 * and all of its ancestors (with the exception of the top-level 7518 * Window) must be visible for the request to be granted. Every 7519 * effort will be made to honor the request; however, in some 7520 * cases it may be impossible to do so. Developers must never 7521 * assume that this Component is the focus owner until this 7522 * Component receives a FOCUS_GAINED event. 7523 * <p> 7524 * This method returns a boolean value. If <code>false</code> is returned, 7525 * the request is <b>guaranteed to fail</b>. If <code>true</code> is 7526 * returned, the request will succeed <b>unless</b> it is vetoed, or an 7527 * extraordinary event, such as disposal of the Component's peer, occurs 7528 * before the request can be granted by the native windowing system. Again, 7529 * while a return value of <code>true</code> indicates that the request is 7530 * likely to succeed, developers must never assume that this Component is 7531 * the focus owner until this Component receives a FOCUS_GAINED event. 7532 * <p> 7533 * This method cannot be used to set the focus owner to no Component at 7534 * all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner()</code> 7535 * instead. 7536 * <p> 7537 * The focus behavior of this method can be implemented uniformly across 7538 * platforms, and thus developers are strongly encouraged to use this 7539 * method over <code>requestFocus</code> when possible. Code which relies 7540 * on <code>requestFocus</code> may exhibit different focus behavior on 7541 * different platforms. 7542 * 7543 * <p>Note: Not all focus transfers result from invoking this method. As 7544 * such, a component may receive focus without this or any of the other 7545 * {@code requestFocus} methods of {@code Component} being invoked. 7546 * 7547 * @return <code>false</code> if the focus change request is guaranteed to 7548 * fail; <code>true</code> if it is likely to succeed 7549 * @see #requestFocus 7550 * @see java.awt.event.FocusEvent 7551 * @see #addFocusListener 7552 * @see #isFocusable 7553 * @see #isDisplayable 7554 * @see KeyboardFocusManager#clearGlobalFocusOwner 7555 * @since 1.4 7556 */ requestFocusInWindow()7557 public boolean requestFocusInWindow() { 7558 return requestFocusHelper(false, false); 7559 } 7560 requestFocusInWindow(CausedFocusEvent.Cause cause)7561 boolean requestFocusInWindow(CausedFocusEvent.Cause cause) { 7562 return requestFocusHelper(false, false, cause); 7563 } 7564 7565 /** 7566 * Requests that this <code>Component</code> get the input focus, 7567 * if this <code>Component</code>'s top-level ancestor is already 7568 * the focused <code>Window</code>. This component must be 7569 * displayable, focusable, visible and all of its ancestors (with 7570 * the exception of the top-level Window) must be visible for the 7571 * request to be granted. Every effort will be made to honor the 7572 * request; however, in some cases it may be impossible to do 7573 * so. Developers must never assume that this component is the 7574 * focus owner until this component receives a FOCUS_GAINED event. 7575 * <p> 7576 * This method returns a boolean value. If <code>false</code> is returned, 7577 * the request is <b>guaranteed to fail</b>. If <code>true</code> is 7578 * returned, the request will succeed <b>unless</b> it is vetoed, or an 7579 * extraordinary event, such as disposal of the component's peer, occurs 7580 * before the request can be granted by the native windowing system. Again, 7581 * while a return value of <code>true</code> indicates that the request is 7582 * likely to succeed, developers must never assume that this component is 7583 * the focus owner until this component receives a FOCUS_GAINED event. 7584 * <p> 7585 * This method cannot be used to set the focus owner to no component at 7586 * all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner</code> 7587 * instead. 7588 * <p> 7589 * The focus behavior of this method can be implemented uniformly across 7590 * platforms, and thus developers are strongly encouraged to use this 7591 * method over <code>requestFocus</code> when possible. Code which relies 7592 * on <code>requestFocus</code> may exhibit different focus behavior on 7593 * different platforms. 7594 * <p> 7595 * Every effort will be made to ensure that <code>FocusEvent</code>s 7596 * generated as a 7597 * result of this request will have the specified temporary value. However, 7598 * because specifying an arbitrary temporary state may not be implementable 7599 * on all native windowing systems, correct behavior for this method can be 7600 * guaranteed only for lightweight components. This method is not intended 7601 * for general use, but exists instead as a hook for lightweight component 7602 * libraries, such as Swing. 7603 * 7604 * <p>Note: Not all focus transfers result from invoking this method. As 7605 * such, a component may receive focus without this or any of the other 7606 * {@code requestFocus} methods of {@code Component} being invoked. 7607 * 7608 * @param temporary true if the focus change is temporary, 7609 * such as when the window loses the focus; for 7610 * more information on temporary focus changes see the 7611 *<a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a> 7612 * @return <code>false</code> if the focus change request is guaranteed to 7613 * fail; <code>true</code> if it is likely to succeed 7614 * @see #requestFocus 7615 * @see java.awt.event.FocusEvent 7616 * @see #addFocusListener 7617 * @see #isFocusable 7618 * @see #isDisplayable 7619 * @see KeyboardFocusManager#clearGlobalFocusOwner 7620 * @since 1.4 7621 */ requestFocusInWindow(boolean temporary)7622 protected boolean requestFocusInWindow(boolean temporary) { 7623 return requestFocusHelper(temporary, false); 7624 } 7625 requestFocusInWindow(boolean temporary, CausedFocusEvent.Cause cause)7626 boolean requestFocusInWindow(boolean temporary, CausedFocusEvent.Cause cause) { 7627 return requestFocusHelper(temporary, false, cause); 7628 } 7629 requestFocusHelper(boolean temporary, boolean focusedWindowChangeAllowed)7630 final boolean requestFocusHelper(boolean temporary, 7631 boolean focusedWindowChangeAllowed) { 7632 return requestFocusHelper(temporary, focusedWindowChangeAllowed, CausedFocusEvent.Cause.UNKNOWN); 7633 } 7634 requestFocusHelper(boolean temporary, boolean focusedWindowChangeAllowed, CausedFocusEvent.Cause cause)7635 final boolean requestFocusHelper(boolean temporary, 7636 boolean focusedWindowChangeAllowed, 7637 CausedFocusEvent.Cause cause) 7638 { 7639 // 1) Check if the event being dispatched is a system-generated mouse event. 7640 AWTEvent currentEvent = EventQueue.getCurrentEvent(); 7641 if (currentEvent instanceof MouseEvent && 7642 SunToolkit.isSystemGenerated(currentEvent)) 7643 { 7644 // 2) Sanity check: if the mouse event component source belongs to the same containing window. 7645 Component source = ((MouseEvent)currentEvent).getComponent(); 7646 if (source == null || source.getContainingWindow() == getContainingWindow()) { 7647 focusLog.finest("requesting focus by mouse event \"in window\""); 7648 7649 // If both the conditions are fulfilled the focus request should be strictly 7650 // bounded by the toplevel window. It's assumed that the mouse event activates 7651 // the window (if it wasn't active) and this makes it possible for a focus 7652 // request with a strong in-window requirement to change focus in the bounds 7653 // of the toplevel. If, by any means, due to asynchronous nature of the event 7654 // dispatching mechanism, the window happens to be natively inactive by the time 7655 // this focus request is eventually handled, it should not re-activate the 7656 // toplevel. Otherwise the result may not meet user expectations. See 6981400. 7657 focusedWindowChangeAllowed = false; 7658 } 7659 } 7660 if (!isRequestFocusAccepted(temporary, focusedWindowChangeAllowed, cause)) { 7661 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) { 7662 focusLog.finest("requestFocus is not accepted"); 7663 } 7664 return false; 7665 } 7666 // Update most-recent map 7667 KeyboardFocusManager.setMostRecentFocusOwner(this); 7668 7669 Component window = this; 7670 while ( (window != null) && !(window instanceof Window)) { 7671 if (!window.isVisible()) { 7672 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) { 7673 focusLog.finest("component is recurively invisible"); 7674 } 7675 return false; 7676 } 7677 window = window.parent; 7678 } 7679 7680 ComponentPeer peer = this.peer; 7681 Component heavyweight = (peer instanceof LightweightPeer) 7682 ? getNativeContainer() : this; 7683 if (heavyweight == null || !heavyweight.isVisible()) { 7684 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) { 7685 focusLog.finest("Component is not a part of visible hierarchy"); 7686 } 7687 return false; 7688 } 7689 peer = heavyweight.peer; 7690 if (peer == null) { 7691 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) { 7692 focusLog.finest("Peer is null"); 7693 } 7694 return false; 7695 } 7696 7697 // Focus this Component 7698 long time = 0; 7699 if (EventQueue.isDispatchThread()) { 7700 time = Toolkit.getEventQueue().getMostRecentKeyEventTime(); 7701 } else { 7702 // A focus request made from outside EDT should not be associated with any event 7703 // and so its time stamp is simply set to the current time. 7704 time = System.currentTimeMillis(); 7705 } 7706 7707 boolean success = peer.requestFocus 7708 (this, temporary, focusedWindowChangeAllowed, time, cause); 7709 if (!success) { 7710 KeyboardFocusManager.getCurrentKeyboardFocusManager 7711 (appContext).dequeueKeyEvents(time, this); 7712 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) { 7713 focusLog.finest("Peer request failed"); 7714 } 7715 } else { 7716 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) { 7717 focusLog.finest("Pass for " + this); 7718 } 7719 } 7720 return success; 7721 } 7722 isRequestFocusAccepted(boolean temporary, boolean focusedWindowChangeAllowed, CausedFocusEvent.Cause cause)7723 private boolean isRequestFocusAccepted(boolean temporary, 7724 boolean focusedWindowChangeAllowed, 7725 CausedFocusEvent.Cause cause) 7726 { 7727 if (!isFocusable() || !isVisible()) { 7728 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) { 7729 focusLog.finest("Not focusable or not visible"); 7730 } 7731 return false; 7732 } 7733 7734 ComponentPeer peer = this.peer; 7735 if (peer == null) { 7736 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) { 7737 focusLog.finest("peer is null"); 7738 } 7739 return false; 7740 } 7741 7742 Window window = getContainingWindow(); 7743 if (window == null || !window.isFocusableWindow()) { 7744 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) { 7745 focusLog.finest("Component doesn't have toplevel"); 7746 } 7747 return false; 7748 } 7749 7750 // We have passed all regular checks for focus request, 7751 // now let's call RequestFocusController and see what it says. 7752 Component focusOwner = KeyboardFocusManager.getMostRecentFocusOwner(window); 7753 if (focusOwner == null) { 7754 // sometimes most recent focus owner may be null, but focus owner is not 7755 // e.g. we reset most recent focus owner if user removes focus owner 7756 focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); 7757 if (focusOwner != null && focusOwner.getContainingWindow() != window) { 7758 focusOwner = null; 7759 } 7760 } 7761 7762 if (focusOwner == this || focusOwner == null) { 7763 // Controller is supposed to verify focus transfers and for this it 7764 // should know both from and to components. And it shouldn't verify 7765 // transfers from when these components are equal. 7766 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) { 7767 focusLog.finest("focus owner is null or this"); 7768 } 7769 return true; 7770 } 7771 7772 if (CausedFocusEvent.Cause.ACTIVATION == cause) { 7773 // we shouldn't call RequestFocusController in case we are 7774 // in activation. We do request focus on component which 7775 // has got temporary focus lost and then on component which is 7776 // most recent focus owner. But most recent focus owner can be 7777 // changed by requestFocsuXXX() call only, so this transfer has 7778 // been already approved. 7779 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) { 7780 focusLog.finest("cause is activation"); 7781 } 7782 return true; 7783 } 7784 7785 boolean ret = Component.requestFocusController.acceptRequestFocus(focusOwner, 7786 this, 7787 temporary, 7788 focusedWindowChangeAllowed, 7789 cause); 7790 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) { 7791 focusLog.finest("RequestFocusController returns {0}", ret); 7792 } 7793 7794 return ret; 7795 } 7796 7797 private static RequestFocusController requestFocusController = new DummyRequestFocusController(); 7798 7799 // Swing access this method through reflection to implement InputVerifier's functionality. 7800 // Perhaps, we should make this method public (later ;) 7801 private static class DummyRequestFocusController implements RequestFocusController { acceptRequestFocus(Component from, Component to, boolean temporary, boolean focusedWindowChangeAllowed, CausedFocusEvent.Cause cause)7802 public boolean acceptRequestFocus(Component from, Component to, 7803 boolean temporary, boolean focusedWindowChangeAllowed, 7804 CausedFocusEvent.Cause cause) 7805 { 7806 return true; 7807 } 7808 }; 7809 setRequestFocusController(RequestFocusController requestController)7810 synchronized static void setRequestFocusController(RequestFocusController requestController) 7811 { 7812 if (requestController == null) { 7813 requestFocusController = new DummyRequestFocusController(); 7814 } else { 7815 requestFocusController = requestController; 7816 } 7817 } 7818 7819 /** 7820 * Returns the Container which is the focus cycle root of this Component's 7821 * focus traversal cycle. Each focus traversal cycle has only a single 7822 * focus cycle root and each Component which is not a Container belongs to 7823 * only a single focus traversal cycle. Containers which are focus cycle 7824 * roots belong to two cycles: one rooted at the Container itself, and one 7825 * rooted at the Container's nearest focus-cycle-root ancestor. For such 7826 * Containers, this method will return the Container's nearest focus-cycle- 7827 * root ancestor. 7828 * 7829 * @return this Component's nearest focus-cycle-root ancestor 7830 * @see Container#isFocusCycleRoot() 7831 * @since 1.4 7832 */ getFocusCycleRootAncestor()7833 public Container getFocusCycleRootAncestor() { 7834 Container rootAncestor = this.parent; 7835 while (rootAncestor != null && !rootAncestor.isFocusCycleRoot()) { 7836 rootAncestor = rootAncestor.parent; 7837 } 7838 return rootAncestor; 7839 } 7840 7841 /** 7842 * Returns whether the specified Container is the focus cycle root of this 7843 * Component's focus traversal cycle. Each focus traversal cycle has only 7844 * a single focus cycle root and each Component which is not a Container 7845 * belongs to only a single focus traversal cycle. 7846 * 7847 * @param container the Container to be tested 7848 * @return <code>true</code> if the specified Container is a focus-cycle- 7849 * root of this Component; <code>false</code> otherwise 7850 * @see Container#isFocusCycleRoot() 7851 * @since 1.4 7852 */ isFocusCycleRoot(Container container)7853 public boolean isFocusCycleRoot(Container container) { 7854 Container rootAncestor = getFocusCycleRootAncestor(); 7855 return (rootAncestor == container); 7856 } 7857 getTraversalRoot()7858 Container getTraversalRoot() { 7859 return getFocusCycleRootAncestor(); 7860 } 7861 7862 /** 7863 * Transfers the focus to the next component, as though this Component were 7864 * the focus owner. 7865 * @see #requestFocus() 7866 * @since JDK1.1 7867 */ transferFocus()7868 public void transferFocus() { 7869 nextFocus(); 7870 } 7871 7872 /** 7873 * @deprecated As of JDK version 1.1, 7874 * replaced by transferFocus(). 7875 */ 7876 @Deprecated nextFocus()7877 public void nextFocus() { 7878 transferFocus(false); 7879 } 7880 transferFocus(boolean clearOnFailure)7881 boolean transferFocus(boolean clearOnFailure) { 7882 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) { 7883 focusLog.finer("clearOnFailure = " + clearOnFailure); 7884 } 7885 Component toFocus = getNextFocusCandidate(); 7886 boolean res = false; 7887 if (toFocus != null && !toFocus.isFocusOwner() && toFocus != this) { 7888 res = toFocus.requestFocusInWindow(CausedFocusEvent.Cause.TRAVERSAL_FORWARD); 7889 } 7890 if (clearOnFailure && !res) { 7891 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) { 7892 focusLog.finer("clear global focus owner"); 7893 } 7894 KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwnerPriv(); 7895 } 7896 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) { 7897 focusLog.finer("returning result: " + res); 7898 } 7899 return res; 7900 } 7901 getNextFocusCandidate()7902 final Component getNextFocusCandidate() { 7903 Container rootAncestor = getTraversalRoot(); 7904 Component comp = this; 7905 while (rootAncestor != null && 7906 !(rootAncestor.isShowing() && rootAncestor.canBeFocusOwner())) 7907 { 7908 comp = rootAncestor; 7909 rootAncestor = comp.getFocusCycleRootAncestor(); 7910 } 7911 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) { 7912 focusLog.finer("comp = " + comp + ", root = " + rootAncestor); 7913 } 7914 Component candidate = null; 7915 if (rootAncestor != null) { 7916 FocusTraversalPolicy policy = rootAncestor.getFocusTraversalPolicy(); 7917 Component toFocus = policy.getComponentAfter(rootAncestor, comp); 7918 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) { 7919 focusLog.finer("component after is " + toFocus); 7920 } 7921 if (toFocus == null) { 7922 toFocus = policy.getDefaultComponent(rootAncestor); 7923 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) { 7924 focusLog.finer("default component is " + toFocus); 7925 } 7926 } 7927 if (toFocus == null) { 7928 Applet applet = EmbeddedFrame.getAppletIfAncestorOf(this); 7929 if (applet != null) { 7930 toFocus = applet; 7931 } 7932 } 7933 candidate = toFocus; 7934 } 7935 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) { 7936 focusLog.finer("Focus transfer candidate: " + candidate); 7937 } 7938 return candidate; 7939 } 7940 7941 /** 7942 * Transfers the focus to the previous component, as though this Component 7943 * were the focus owner. 7944 * @see #requestFocus() 7945 * @since 1.4 7946 */ transferFocusBackward()7947 public void transferFocusBackward() { 7948 transferFocusBackward(false); 7949 } 7950 transferFocusBackward(boolean clearOnFailure)7951 boolean transferFocusBackward(boolean clearOnFailure) { 7952 Container rootAncestor = getTraversalRoot(); 7953 Component comp = this; 7954 while (rootAncestor != null && 7955 !(rootAncestor.isShowing() && rootAncestor.canBeFocusOwner())) 7956 { 7957 comp = rootAncestor; 7958 rootAncestor = comp.getFocusCycleRootAncestor(); 7959 } 7960 boolean res = false; 7961 if (rootAncestor != null) { 7962 FocusTraversalPolicy policy = rootAncestor.getFocusTraversalPolicy(); 7963 Component toFocus = policy.getComponentBefore(rootAncestor, comp); 7964 if (toFocus == null) { 7965 toFocus = policy.getDefaultComponent(rootAncestor); 7966 } 7967 if (toFocus != null) { 7968 res = toFocus.requestFocusInWindow(CausedFocusEvent.Cause.TRAVERSAL_BACKWARD); 7969 } 7970 } 7971 if (clearOnFailure && !res) { 7972 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) { 7973 focusLog.finer("clear global focus owner"); 7974 } 7975 KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwnerPriv(); 7976 } 7977 if (focusLog.isLoggable(PlatformLogger.Level.FINER)) { 7978 focusLog.finer("returning result: " + res); 7979 } 7980 return res; 7981 } 7982 7983 /** 7984 * Transfers the focus up one focus traversal cycle. Typically, the focus 7985 * owner is set to this Component's focus cycle root, and the current focus 7986 * cycle root is set to the new focus owner's focus cycle root. If, 7987 * however, this Component's focus cycle root is a Window, then the focus 7988 * owner is set to the focus cycle root's default Component to focus, and 7989 * the current focus cycle root is unchanged. 7990 * 7991 * @see #requestFocus() 7992 * @see Container#isFocusCycleRoot() 7993 * @see Container#setFocusCycleRoot(boolean) 7994 * @since 1.4 7995 */ transferFocusUpCycle()7996 public void transferFocusUpCycle() { 7997 Container rootAncestor; 7998 for (rootAncestor = getFocusCycleRootAncestor(); 7999 rootAncestor != null && !(rootAncestor.isShowing() && 8000 rootAncestor.isFocusable() && 8001 rootAncestor.isEnabled()); 8002 rootAncestor = rootAncestor.getFocusCycleRootAncestor()) { 8003 } 8004 8005 if (rootAncestor != null) { 8006 Container rootAncestorRootAncestor = 8007 rootAncestor.getFocusCycleRootAncestor(); 8008 Container fcr = (rootAncestorRootAncestor != null) ? 8009 rootAncestorRootAncestor : rootAncestor; 8010 8011 KeyboardFocusManager.getCurrentKeyboardFocusManager(). 8012 setGlobalCurrentFocusCycleRootPriv(fcr); 8013 rootAncestor.requestFocus(CausedFocusEvent.Cause.TRAVERSAL_UP); 8014 } else { 8015 Window window = getContainingWindow(); 8016 8017 if (window != null) { 8018 Component toFocus = window.getFocusTraversalPolicy(). 8019 getDefaultComponent(window); 8020 if (toFocus != null) { 8021 KeyboardFocusManager.getCurrentKeyboardFocusManager(). 8022 setGlobalCurrentFocusCycleRootPriv(window); 8023 toFocus.requestFocus(CausedFocusEvent.Cause.TRAVERSAL_UP); 8024 } 8025 } 8026 } 8027 } 8028 8029 /** 8030 * Returns <code>true</code> if this <code>Component</code> is the 8031 * focus owner. This method is obsolete, and has been replaced by 8032 * <code>isFocusOwner()</code>. 8033 * 8034 * @return <code>true</code> if this <code>Component</code> is the 8035 * focus owner; <code>false</code> otherwise 8036 * @since 1.2 8037 */ hasFocus()8038 public boolean hasFocus() { 8039 return (KeyboardFocusManager.getCurrentKeyboardFocusManager(). 8040 getFocusOwner() == this); 8041 } 8042 8043 /** 8044 * Returns <code>true</code> if this <code>Component</code> is the 8045 * focus owner. 8046 * 8047 * @return <code>true</code> if this <code>Component</code> is the 8048 * focus owner; <code>false</code> otherwise 8049 * @since 1.4 8050 */ isFocusOwner()8051 public boolean isFocusOwner() { 8052 return hasFocus(); 8053 } 8054 8055 /* 8056 * Used to disallow auto-focus-transfer on disposal of the focus owner 8057 * in the process of disposing its parent container. 8058 */ 8059 private boolean autoFocusTransferOnDisposal = true; 8060 setAutoFocusTransferOnDisposal(boolean value)8061 void setAutoFocusTransferOnDisposal(boolean value) { 8062 autoFocusTransferOnDisposal = value; 8063 } 8064 isAutoFocusTransferOnDisposal()8065 boolean isAutoFocusTransferOnDisposal() { 8066 return autoFocusTransferOnDisposal; 8067 } 8068 8069 /** 8070 * Adds the specified popup menu to the component. 8071 * @param popup the popup menu to be added to the component. 8072 * @see #remove(MenuComponent) 8073 * @exception NullPointerException if {@code popup} is {@code null} 8074 * @since JDK1.1 8075 */ add(PopupMenu popup)8076 public void add(PopupMenu popup) { 8077 synchronized (getTreeLock()) { 8078 if (popup.parent != null) { 8079 popup.parent.remove(popup); 8080 } 8081 if (popups == null) { 8082 popups = new Vector<PopupMenu>(); 8083 } 8084 popups.addElement(popup); 8085 popup.parent = this; 8086 8087 if (peer != null) { 8088 if (popup.peer == null) { 8089 popup.addNotify(); 8090 } 8091 } 8092 } 8093 } 8094 8095 /** 8096 * Removes the specified popup menu from the component. 8097 * @param popup the popup menu to be removed 8098 * @see #add(PopupMenu) 8099 * @since JDK1.1 8100 */ 8101 @SuppressWarnings("unchecked") remove(MenuComponent popup)8102 public void remove(MenuComponent popup) { 8103 synchronized (getTreeLock()) { 8104 if (popups == null) { 8105 return; 8106 } 8107 int index = popups.indexOf(popup); 8108 if (index >= 0) { 8109 PopupMenu pmenu = (PopupMenu)popup; 8110 if (pmenu.peer != null) { 8111 pmenu.removeNotify(); 8112 } 8113 pmenu.parent = null; 8114 popups.removeElementAt(index); 8115 if (popups.size() == 0) { 8116 popups = null; 8117 } 8118 } 8119 } 8120 } 8121 8122 /** 8123 * Returns a string representing the state of this component. This 8124 * method is intended to be used only for debugging purposes, and the 8125 * content and format of the returned string may vary between 8126 * implementations. The returned string may be empty but may not be 8127 * <code>null</code>. 8128 * 8129 * @return a string representation of this component's state 8130 * @since JDK1.0 8131 */ paramString()8132 protected String paramString() { 8133 final String thisName = Objects.toString(getName(), ""); 8134 final String invalid = isValid() ? "" : ",invalid"; 8135 final String hidden = visible ? "" : ",hidden"; 8136 final String disabled = enabled ? "" : ",disabled"; 8137 return thisName + ',' + x + ',' + y + ',' + width + 'x' + height 8138 + invalid + hidden + disabled; 8139 } 8140 8141 /** 8142 * Returns a string representation of this component and its values. 8143 * @return a string representation of this component 8144 * @since JDK1.0 8145 */ toString()8146 public String toString() { 8147 return getClass().getName() + '[' + paramString() + ']'; 8148 } 8149 8150 /** 8151 * Prints a listing of this component to the standard system output 8152 * stream <code>System.out</code>. 8153 * @see java.lang.System#out 8154 * @since JDK1.0 8155 */ list()8156 public void list() { 8157 list(System.out, 0); 8158 } 8159 8160 /** 8161 * Prints a listing of this component to the specified output 8162 * stream. 8163 * @param out a print stream 8164 * @throws NullPointerException if {@code out} is {@code null} 8165 * @since JDK1.0 8166 */ list(PrintStream out)8167 public void list(PrintStream out) { 8168 list(out, 0); 8169 } 8170 8171 /** 8172 * Prints out a list, starting at the specified indentation, to the 8173 * specified print stream. 8174 * @param out a print stream 8175 * @param indent number of spaces to indent 8176 * @see java.io.PrintStream#println(java.lang.Object) 8177 * @throws NullPointerException if {@code out} is {@code null} 8178 * @since JDK1.0 8179 */ list(PrintStream out, int indent)8180 public void list(PrintStream out, int indent) { 8181 for (int i = 0 ; i < indent ; i++) { 8182 out.print(" "); 8183 } 8184 out.println(this); 8185 } 8186 8187 /** 8188 * Prints a listing to the specified print writer. 8189 * @param out the print writer to print to 8190 * @throws NullPointerException if {@code out} is {@code null} 8191 * @since JDK1.1 8192 */ list(PrintWriter out)8193 public void list(PrintWriter out) { 8194 list(out, 0); 8195 } 8196 8197 /** 8198 * Prints out a list, starting at the specified indentation, to 8199 * the specified print writer. 8200 * @param out the print writer to print to 8201 * @param indent the number of spaces to indent 8202 * @throws NullPointerException if {@code out} is {@code null} 8203 * @see java.io.PrintStream#println(java.lang.Object) 8204 * @since JDK1.1 8205 */ list(PrintWriter out, int indent)8206 public void list(PrintWriter out, int indent) { 8207 for (int i = 0 ; i < indent ; i++) { 8208 out.print(" "); 8209 } 8210 out.println(this); 8211 } 8212 8213 /* 8214 * Fetches the native container somewhere higher up in the component 8215 * tree that contains this component. 8216 */ getNativeContainer()8217 final Container getNativeContainer() { 8218 Container p = getContainer(); 8219 while (p != null && p.peer instanceof LightweightPeer) { 8220 p = p.getContainer(); 8221 } 8222 return p; 8223 } 8224 8225 /** 8226 * Adds a PropertyChangeListener to the listener list. The listener is 8227 * registered for all bound properties of this class, including the 8228 * following: 8229 * <ul> 8230 * <li>this Component's font ("font")</li> 8231 * <li>this Component's background color ("background")</li> 8232 * <li>this Component's foreground color ("foreground")</li> 8233 * <li>this Component's focusability ("focusable")</li> 8234 * <li>this Component's focus traversal keys enabled state 8235 * ("focusTraversalKeysEnabled")</li> 8236 * <li>this Component's Set of FORWARD_TRAVERSAL_KEYS 8237 * ("forwardFocusTraversalKeys")</li> 8238 * <li>this Component's Set of BACKWARD_TRAVERSAL_KEYS 8239 * ("backwardFocusTraversalKeys")</li> 8240 * <li>this Component's Set of UP_CYCLE_TRAVERSAL_KEYS 8241 * ("upCycleFocusTraversalKeys")</li> 8242 * <li>this Component's preferred size ("preferredSize")</li> 8243 * <li>this Component's minimum size ("minimumSize")</li> 8244 * <li>this Component's maximum size ("maximumSize")</li> 8245 * <li>this Component's name ("name")</li> 8246 * </ul> 8247 * Note that if this <code>Component</code> is inheriting a bound property, then no 8248 * event will be fired in response to a change in the inherited property. 8249 * <p> 8250 * If <code>listener</code> is <code>null</code>, 8251 * no exception is thrown and no action is performed. 8252 * 8253 * @param listener the property change listener to be added 8254 * 8255 * @see #removePropertyChangeListener 8256 * @see #getPropertyChangeListeners 8257 * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener) 8258 */ addPropertyChangeListener( PropertyChangeListener listener)8259 public void addPropertyChangeListener( 8260 PropertyChangeListener listener) { 8261 synchronized (getObjectLock()) { 8262 if (listener == null) { 8263 return; 8264 } 8265 if (changeSupport == null) { 8266 changeSupport = new PropertyChangeSupport(this); 8267 } 8268 changeSupport.addPropertyChangeListener(listener); 8269 } 8270 } 8271 8272 /** 8273 * Removes a PropertyChangeListener from the listener list. This method 8274 * should be used to remove PropertyChangeListeners that were registered 8275 * for all bound properties of this class. 8276 * <p> 8277 * If listener is null, no exception is thrown and no action is performed. 8278 * 8279 * @param listener the PropertyChangeListener to be removed 8280 * 8281 * @see #addPropertyChangeListener 8282 * @see #getPropertyChangeListeners 8283 * @see #removePropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener) 8284 */ removePropertyChangeListener( PropertyChangeListener listener)8285 public void removePropertyChangeListener( 8286 PropertyChangeListener listener) { 8287 synchronized (getObjectLock()) { 8288 if (listener == null || changeSupport == null) { 8289 return; 8290 } 8291 changeSupport.removePropertyChangeListener(listener); 8292 } 8293 } 8294 8295 /** 8296 * Returns an array of all the property change listeners 8297 * registered on this component. 8298 * 8299 * @return all of this component's <code>PropertyChangeListener</code>s 8300 * or an empty array if no property change 8301 * listeners are currently registered 8302 * 8303 * @see #addPropertyChangeListener 8304 * @see #removePropertyChangeListener 8305 * @see #getPropertyChangeListeners(java.lang.String) 8306 * @see java.beans.PropertyChangeSupport#getPropertyChangeListeners 8307 * @since 1.4 8308 */ getPropertyChangeListeners()8309 public PropertyChangeListener[] getPropertyChangeListeners() { 8310 synchronized (getObjectLock()) { 8311 if (changeSupport == null) { 8312 return new PropertyChangeListener[0]; 8313 } 8314 return changeSupport.getPropertyChangeListeners(); 8315 } 8316 } 8317 8318 /** 8319 * Adds a PropertyChangeListener to the listener list for a specific 8320 * property. The specified property may be user-defined, or one of the 8321 * following: 8322 * <ul> 8323 * <li>this Component's font ("font")</li> 8324 * <li>this Component's background color ("background")</li> 8325 * <li>this Component's foreground color ("foreground")</li> 8326 * <li>this Component's focusability ("focusable")</li> 8327 * <li>this Component's focus traversal keys enabled state 8328 * ("focusTraversalKeysEnabled")</li> 8329 * <li>this Component's Set of FORWARD_TRAVERSAL_KEYS 8330 * ("forwardFocusTraversalKeys")</li> 8331 * <li>this Component's Set of BACKWARD_TRAVERSAL_KEYS 8332 * ("backwardFocusTraversalKeys")</li> 8333 * <li>this Component's Set of UP_CYCLE_TRAVERSAL_KEYS 8334 * ("upCycleFocusTraversalKeys")</li> 8335 * </ul> 8336 * Note that if this <code>Component</code> is inheriting a bound property, then no 8337 * event will be fired in response to a change in the inherited property. 8338 * <p> 8339 * If <code>propertyName</code> or <code>listener</code> is <code>null</code>, 8340 * no exception is thrown and no action is taken. 8341 * 8342 * @param propertyName one of the property names listed above 8343 * @param listener the property change listener to be added 8344 * 8345 * @see #removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener) 8346 * @see #getPropertyChangeListeners(java.lang.String) 8347 * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener) 8348 */ addPropertyChangeListener( String propertyName, PropertyChangeListener listener)8349 public void addPropertyChangeListener( 8350 String propertyName, 8351 PropertyChangeListener listener) { 8352 synchronized (getObjectLock()) { 8353 if (listener == null) { 8354 return; 8355 } 8356 if (changeSupport == null) { 8357 changeSupport = new PropertyChangeSupport(this); 8358 } 8359 changeSupport.addPropertyChangeListener(propertyName, listener); 8360 } 8361 } 8362 8363 /** 8364 * Removes a <code>PropertyChangeListener</code> from the listener 8365 * list for a specific property. This method should be used to remove 8366 * <code>PropertyChangeListener</code>s 8367 * that were registered for a specific bound property. 8368 * <p> 8369 * If <code>propertyName</code> or <code>listener</code> is <code>null</code>, 8370 * no exception is thrown and no action is taken. 8371 * 8372 * @param propertyName a valid property name 8373 * @param listener the PropertyChangeListener to be removed 8374 * 8375 * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener) 8376 * @see #getPropertyChangeListeners(java.lang.String) 8377 * @see #removePropertyChangeListener(java.beans.PropertyChangeListener) 8378 */ removePropertyChangeListener( String propertyName, PropertyChangeListener listener)8379 public void removePropertyChangeListener( 8380 String propertyName, 8381 PropertyChangeListener listener) { 8382 synchronized (getObjectLock()) { 8383 if (listener == null || changeSupport == null) { 8384 return; 8385 } 8386 changeSupport.removePropertyChangeListener(propertyName, listener); 8387 } 8388 } 8389 8390 /** 8391 * Returns an array of all the listeners which have been associated 8392 * with the named property. 8393 * 8394 * @return all of the <code>PropertyChangeListener</code>s associated with 8395 * the named property; if no such listeners have been added or 8396 * if <code>propertyName</code> is <code>null</code>, an empty 8397 * array is returned 8398 * 8399 * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener) 8400 * @see #removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener) 8401 * @see #getPropertyChangeListeners 8402 * @since 1.4 8403 */ getPropertyChangeListeners( String propertyName)8404 public PropertyChangeListener[] getPropertyChangeListeners( 8405 String propertyName) { 8406 synchronized (getObjectLock()) { 8407 if (changeSupport == null) { 8408 return new PropertyChangeListener[0]; 8409 } 8410 return changeSupport.getPropertyChangeListeners(propertyName); 8411 } 8412 } 8413 8414 /** 8415 * Support for reporting bound property changes for Object properties. 8416 * This method can be called when a bound property has changed and it will 8417 * send the appropriate PropertyChangeEvent to any registered 8418 * PropertyChangeListeners. 8419 * 8420 * @param propertyName the property whose value has changed 8421 * @param oldValue the property's previous value 8422 * @param newValue the property's new value 8423 */ firePropertyChange(String propertyName, Object oldValue, Object newValue)8424 protected void firePropertyChange(String propertyName, 8425 Object oldValue, Object newValue) { 8426 PropertyChangeSupport changeSupport; 8427 synchronized (getObjectLock()) { 8428 changeSupport = this.changeSupport; 8429 } 8430 if (changeSupport == null || 8431 (oldValue != null && newValue != null && oldValue.equals(newValue))) { 8432 return; 8433 } 8434 changeSupport.firePropertyChange(propertyName, oldValue, newValue); 8435 } 8436 8437 /** 8438 * Support for reporting bound property changes for boolean properties. 8439 * This method can be called when a bound property has changed and it will 8440 * send the appropriate PropertyChangeEvent to any registered 8441 * PropertyChangeListeners. 8442 * 8443 * @param propertyName the property whose value has changed 8444 * @param oldValue the property's previous value 8445 * @param newValue the property's new value 8446 * @since 1.4 8447 */ firePropertyChange(String propertyName, boolean oldValue, boolean newValue)8448 protected void firePropertyChange(String propertyName, 8449 boolean oldValue, boolean newValue) { 8450 PropertyChangeSupport changeSupport = this.changeSupport; 8451 if (changeSupport == null || oldValue == newValue) { 8452 return; 8453 } 8454 changeSupport.firePropertyChange(propertyName, oldValue, newValue); 8455 } 8456 8457 /** 8458 * Support for reporting bound property changes for integer properties. 8459 * This method can be called when a bound property has changed and it will 8460 * send the appropriate PropertyChangeEvent to any registered 8461 * PropertyChangeListeners. 8462 * 8463 * @param propertyName the property whose value has changed 8464 * @param oldValue the property's previous value 8465 * @param newValue the property's new value 8466 * @since 1.4 8467 */ firePropertyChange(String propertyName, int oldValue, int newValue)8468 protected void firePropertyChange(String propertyName, 8469 int oldValue, int newValue) { 8470 PropertyChangeSupport changeSupport = this.changeSupport; 8471 if (changeSupport == null || oldValue == newValue) { 8472 return; 8473 } 8474 changeSupport.firePropertyChange(propertyName, oldValue, newValue); 8475 } 8476 8477 /** 8478 * Reports a bound property change. 8479 * 8480 * @param propertyName the programmatic name of the property 8481 * that was changed 8482 * @param oldValue the old value of the property (as a byte) 8483 * @param newValue the new value of the property (as a byte) 8484 * @see #firePropertyChange(java.lang.String, java.lang.Object, 8485 * java.lang.Object) 8486 * @since 1.5 8487 */ firePropertyChange(String propertyName, byte oldValue, byte newValue)8488 public void firePropertyChange(String propertyName, byte oldValue, byte newValue) { 8489 if (changeSupport == null || oldValue == newValue) { 8490 return; 8491 } 8492 firePropertyChange(propertyName, Byte.valueOf(oldValue), Byte.valueOf(newValue)); 8493 } 8494 8495 /** 8496 * Reports a bound property change. 8497 * 8498 * @param propertyName the programmatic name of the property 8499 * that was changed 8500 * @param oldValue the old value of the property (as a char) 8501 * @param newValue the new value of the property (as a char) 8502 * @see #firePropertyChange(java.lang.String, java.lang.Object, 8503 * java.lang.Object) 8504 * @since 1.5 8505 */ firePropertyChange(String propertyName, char oldValue, char newValue)8506 public void firePropertyChange(String propertyName, char oldValue, char newValue) { 8507 if (changeSupport == null || oldValue == newValue) { 8508 return; 8509 } 8510 firePropertyChange(propertyName, new Character(oldValue), new Character(newValue)); 8511 } 8512 8513 /** 8514 * Reports a bound property change. 8515 * 8516 * @param propertyName the programmatic name of the property 8517 * that was changed 8518 * @param oldValue the old value of the property (as a short) 8519 * @param newValue the old value of the property (as a short) 8520 * @see #firePropertyChange(java.lang.String, java.lang.Object, 8521 * java.lang.Object) 8522 * @since 1.5 8523 */ firePropertyChange(String propertyName, short oldValue, short newValue)8524 public void firePropertyChange(String propertyName, short oldValue, short newValue) { 8525 if (changeSupport == null || oldValue == newValue) { 8526 return; 8527 } 8528 firePropertyChange(propertyName, Short.valueOf(oldValue), Short.valueOf(newValue)); 8529 } 8530 8531 8532 /** 8533 * Reports a bound property change. 8534 * 8535 * @param propertyName the programmatic name of the property 8536 * that was changed 8537 * @param oldValue the old value of the property (as a long) 8538 * @param newValue the new value of the property (as a long) 8539 * @see #firePropertyChange(java.lang.String, java.lang.Object, 8540 * java.lang.Object) 8541 * @since 1.5 8542 */ firePropertyChange(String propertyName, long oldValue, long newValue)8543 public void firePropertyChange(String propertyName, long oldValue, long newValue) { 8544 if (changeSupport == null || oldValue == newValue) { 8545 return; 8546 } 8547 firePropertyChange(propertyName, Long.valueOf(oldValue), Long.valueOf(newValue)); 8548 } 8549 8550 /** 8551 * Reports a bound property change. 8552 * 8553 * @param propertyName the programmatic name of the property 8554 * that was changed 8555 * @param oldValue the old value of the property (as a float) 8556 * @param newValue the new value of the property (as a float) 8557 * @see #firePropertyChange(java.lang.String, java.lang.Object, 8558 * java.lang.Object) 8559 * @since 1.5 8560 */ firePropertyChange(String propertyName, float oldValue, float newValue)8561 public void firePropertyChange(String propertyName, float oldValue, float newValue) { 8562 if (changeSupport == null || oldValue == newValue) { 8563 return; 8564 } 8565 firePropertyChange(propertyName, Float.valueOf(oldValue), Float.valueOf(newValue)); 8566 } 8567 8568 /** 8569 * Reports a bound property change. 8570 * 8571 * @param propertyName the programmatic name of the property 8572 * that was changed 8573 * @param oldValue the old value of the property (as a double) 8574 * @param newValue the new value of the property (as a double) 8575 * @see #firePropertyChange(java.lang.String, java.lang.Object, 8576 * java.lang.Object) 8577 * @since 1.5 8578 */ firePropertyChange(String propertyName, double oldValue, double newValue)8579 public void firePropertyChange(String propertyName, double oldValue, double newValue) { 8580 if (changeSupport == null || oldValue == newValue) { 8581 return; 8582 } 8583 firePropertyChange(propertyName, Double.valueOf(oldValue), Double.valueOf(newValue)); 8584 } 8585 8586 8587 // Serialization support. 8588 8589 /** 8590 * Component Serialized Data Version. 8591 * 8592 * @serial 8593 */ 8594 private int componentSerializedDataVersion = 4; 8595 8596 /** 8597 * This hack is for Swing serialization. It will invoke 8598 * the Swing package private method <code>compWriteObjectNotify</code>. 8599 */ doSwingSerialization()8600 private void doSwingSerialization() { 8601 Package swingPackage = Package.getPackage("javax.swing"); 8602 // For Swing serialization to correctly work Swing needs to 8603 // be notified before Component does it's serialization. This 8604 // hack accomodates this. 8605 // 8606 // Swing classes MUST be loaded by the bootstrap class loader, 8607 // otherwise we don't consider them. 8608 for (Class<?> klass = Component.this.getClass(); klass != null; 8609 klass = klass.getSuperclass()) { 8610 if (klass.getPackage() == swingPackage && 8611 klass.getClassLoader() == null) { 8612 final Class<?> swingClass = klass; 8613 // Find the first override of the compWriteObjectNotify method 8614 Method[] methods = AccessController.doPrivileged( 8615 new PrivilegedAction<Method[]>() { 8616 public Method[] run() { 8617 return swingClass.getDeclaredMethods(); 8618 } 8619 }); 8620 for (int counter = methods.length - 1; counter >= 0; 8621 counter--) { 8622 final Method method = methods[counter]; 8623 if (method.getName().equals("compWriteObjectNotify")){ 8624 // We found it, use doPrivileged to make it accessible 8625 // to use. 8626 AccessController.doPrivileged(new PrivilegedAction<Void>() { 8627 public Void run() { 8628 method.setAccessible(true); 8629 return null; 8630 } 8631 }); 8632 // Invoke the method 8633 try { 8634 method.invoke(this, (Object[]) null); 8635 } catch (IllegalAccessException iae) { 8636 } catch (InvocationTargetException ite) { 8637 } 8638 // We're done, bail. 8639 return; 8640 } 8641 } 8642 } 8643 } 8644 } 8645 8646 /** 8647 * Writes default serializable fields to stream. Writes 8648 * a variety of serializable listeners as optional data. 8649 * The non-serializable listeners are detected and 8650 * no attempt is made to serialize them. 8651 * 8652 * @param s the <code>ObjectOutputStream</code> to write 8653 * @serialData <code>null</code> terminated sequence of 8654 * 0 or more pairs; the pair consists of a <code>String</code> 8655 * and an <code>Object</code>; the <code>String</code> indicates 8656 * the type of object and is one of the following (as of 1.4): 8657 * <code>componentListenerK</code> indicating an 8658 * <code>ComponentListener</code> object; 8659 * <code>focusListenerK</code> indicating an 8660 * <code>FocusListener</code> object; 8661 * <code>keyListenerK</code> indicating an 8662 * <code>KeyListener</code> object; 8663 * <code>mouseListenerK</code> indicating an 8664 * <code>MouseListener</code> object; 8665 * <code>mouseMotionListenerK</code> indicating an 8666 * <code>MouseMotionListener</code> object; 8667 * <code>inputMethodListenerK</code> indicating an 8668 * <code>InputMethodListener</code> object; 8669 * <code>hierarchyListenerK</code> indicating an 8670 * <code>HierarchyListener</code> object; 8671 * <code>hierarchyBoundsListenerK</code> indicating an 8672 * <code>HierarchyBoundsListener</code> object; 8673 * <code>mouseWheelListenerK</code> indicating an 8674 * <code>MouseWheelListener</code> object 8675 * @serialData an optional <code>ComponentOrientation</code> 8676 * (after <code>inputMethodListener</code>, as of 1.2) 8677 * 8678 * @see AWTEventMulticaster#save(java.io.ObjectOutputStream, java.lang.String, java.util.EventListener) 8679 * @see #componentListenerK 8680 * @see #focusListenerK 8681 * @see #keyListenerK 8682 * @see #mouseListenerK 8683 * @see #mouseMotionListenerK 8684 * @see #inputMethodListenerK 8685 * @see #hierarchyListenerK 8686 * @see #hierarchyBoundsListenerK 8687 * @see #mouseWheelListenerK 8688 * @see #readObject(ObjectInputStream) 8689 */ writeObject(ObjectOutputStream s)8690 private void writeObject(ObjectOutputStream s) 8691 throws IOException 8692 { 8693 doSwingSerialization(); 8694 8695 s.defaultWriteObject(); 8696 8697 AWTEventMulticaster.save(s, componentListenerK, componentListener); 8698 AWTEventMulticaster.save(s, focusListenerK, focusListener); 8699 AWTEventMulticaster.save(s, keyListenerK, keyListener); 8700 AWTEventMulticaster.save(s, mouseListenerK, mouseListener); 8701 AWTEventMulticaster.save(s, mouseMotionListenerK, mouseMotionListener); 8702 AWTEventMulticaster.save(s, inputMethodListenerK, inputMethodListener); 8703 8704 s.writeObject(null); 8705 s.writeObject(componentOrientation); 8706 8707 AWTEventMulticaster.save(s, hierarchyListenerK, hierarchyListener); 8708 AWTEventMulticaster.save(s, hierarchyBoundsListenerK, 8709 hierarchyBoundsListener); 8710 s.writeObject(null); 8711 8712 AWTEventMulticaster.save(s, mouseWheelListenerK, mouseWheelListener); 8713 s.writeObject(null); 8714 8715 } 8716 8717 /** 8718 * Reads the <code>ObjectInputStream</code> and if it isn't 8719 * <code>null</code> adds a listener to receive a variety 8720 * of events fired by the component. 8721 * Unrecognized keys or values will be ignored. 8722 * 8723 * @param s the <code>ObjectInputStream</code> to read 8724 * @see #writeObject(ObjectOutputStream) 8725 */ readObject(ObjectInputStream s)8726 private void readObject(ObjectInputStream s) 8727 throws ClassNotFoundException, IOException 8728 { 8729 objectLock = new Object(); 8730 8731 acc = AccessController.getContext(); 8732 8733 s.defaultReadObject(); 8734 8735 appContext = AppContext.getAppContext(); 8736 coalescingEnabled = checkCoalescing(); 8737 if (componentSerializedDataVersion < 4) { 8738 // These fields are non-transient and rely on default 8739 // serialization. However, the default values are insufficient, 8740 // so we need to set them explicitly for object data streams prior 8741 // to 1.4. 8742 focusable = true; 8743 isFocusTraversableOverridden = FOCUS_TRAVERSABLE_UNKNOWN; 8744 initializeFocusTraversalKeys(); 8745 focusTraversalKeysEnabled = true; 8746 } 8747 8748 Object keyOrNull; 8749 while(null != (keyOrNull = s.readObject())) { 8750 String key = ((String)keyOrNull).intern(); 8751 8752 if (componentListenerK == key) 8753 addComponentListener((ComponentListener)(s.readObject())); 8754 8755 else if (focusListenerK == key) 8756 addFocusListener((FocusListener)(s.readObject())); 8757 8758 else if (keyListenerK == key) 8759 addKeyListener((KeyListener)(s.readObject())); 8760 8761 else if (mouseListenerK == key) 8762 addMouseListener((MouseListener)(s.readObject())); 8763 8764 else if (mouseMotionListenerK == key) 8765 addMouseMotionListener((MouseMotionListener)(s.readObject())); 8766 8767 else if (inputMethodListenerK == key) 8768 addInputMethodListener((InputMethodListener)(s.readObject())); 8769 8770 else // skip value for unrecognized key 8771 s.readObject(); 8772 8773 } 8774 8775 // Read the component's orientation if it's present 8776 Object orient = null; 8777 8778 try { 8779 orient = s.readObject(); 8780 } catch (java.io.OptionalDataException e) { 8781 // JDK 1.1 instances will not have this optional data. 8782 // e.eof will be true to indicate that there is no more 8783 // data available for this object. 8784 // If e.eof is not true, throw the exception as it 8785 // might have been caused by reasons unrelated to 8786 // componentOrientation. 8787 8788 if (!e.eof) { 8789 throw (e); 8790 } 8791 } 8792 8793 if (orient != null) { 8794 componentOrientation = (ComponentOrientation)orient; 8795 } else { 8796 componentOrientation = ComponentOrientation.UNKNOWN; 8797 } 8798 8799 try { 8800 while(null != (keyOrNull = s.readObject())) { 8801 String key = ((String)keyOrNull).intern(); 8802 8803 if (hierarchyListenerK == key) { 8804 addHierarchyListener((HierarchyListener)(s.readObject())); 8805 } 8806 else if (hierarchyBoundsListenerK == key) { 8807 addHierarchyBoundsListener((HierarchyBoundsListener) 8808 (s.readObject())); 8809 } 8810 else { 8811 // skip value for unrecognized key 8812 s.readObject(); 8813 } 8814 } 8815 } catch (java.io.OptionalDataException e) { 8816 // JDK 1.1/1.2 instances will not have this optional data. 8817 // e.eof will be true to indicate that there is no more 8818 // data available for this object. 8819 // If e.eof is not true, throw the exception as it 8820 // might have been caused by reasons unrelated to 8821 // hierarchy and hierarchyBounds listeners. 8822 8823 if (!e.eof) { 8824 throw (e); 8825 } 8826 } 8827 8828 try { 8829 while (null != (keyOrNull = s.readObject())) { 8830 String key = ((String)keyOrNull).intern(); 8831 8832 if (mouseWheelListenerK == key) { 8833 addMouseWheelListener((MouseWheelListener)(s.readObject())); 8834 } 8835 else { 8836 // skip value for unrecognized key 8837 s.readObject(); 8838 } 8839 } 8840 } catch (java.io.OptionalDataException e) { 8841 // pre-1.3 instances will not have this optional data. 8842 // e.eof will be true to indicate that there is no more 8843 // data available for this object. 8844 // If e.eof is not true, throw the exception as it 8845 // might have been caused by reasons unrelated to 8846 // mouse wheel listeners 8847 8848 if (!e.eof) { 8849 throw (e); 8850 } 8851 } 8852 8853 if (popups != null) { 8854 int npopups = popups.size(); 8855 for (int i = 0 ; i < npopups ; i++) { 8856 PopupMenu popup = popups.elementAt(i); 8857 popup.parent = this; 8858 } 8859 } 8860 } 8861 8862 /** 8863 * Sets the language-sensitive orientation that is to be used to order 8864 * the elements or text within this component. Language-sensitive 8865 * <code>LayoutManager</code> and <code>Component</code> 8866 * subclasses will use this property to 8867 * determine how to lay out and draw components. 8868 * <p> 8869 * At construction time, a component's orientation is set to 8870 * <code>ComponentOrientation.UNKNOWN</code>, 8871 * indicating that it has not been specified 8872 * explicitly. The UNKNOWN orientation behaves the same as 8873 * <code>ComponentOrientation.LEFT_TO_RIGHT</code>. 8874 * <p> 8875 * To set the orientation of a single component, use this method. 8876 * To set the orientation of an entire component 8877 * hierarchy, use 8878 * {@link #applyComponentOrientation applyComponentOrientation}. 8879 * <p> 8880 * This method changes layout-related information, and therefore, 8881 * invalidates the component hierarchy. 8882 * 8883 * 8884 * @see ComponentOrientation 8885 * @see #invalidate 8886 * 8887 * @author Laura Werner, IBM 8888 * @beaninfo 8889 * bound: true 8890 */ setComponentOrientation(ComponentOrientation o)8891 public void setComponentOrientation(ComponentOrientation o) { 8892 ComponentOrientation oldValue = componentOrientation; 8893 componentOrientation = o; 8894 8895 // This is a bound property, so report the change to 8896 // any registered listeners. (Cheap if there are none.) 8897 firePropertyChange("componentOrientation", oldValue, o); 8898 8899 // This could change the preferred size of the Component. 8900 invalidateIfValid(); 8901 } 8902 8903 /** 8904 * Retrieves the language-sensitive orientation that is to be used to order 8905 * the elements or text within this component. <code>LayoutManager</code> 8906 * and <code>Component</code> 8907 * subclasses that wish to respect orientation should call this method to 8908 * get the component's orientation before performing layout or drawing. 8909 * 8910 * @see ComponentOrientation 8911 * 8912 * @author Laura Werner, IBM 8913 */ getComponentOrientation()8914 public ComponentOrientation getComponentOrientation() { 8915 return componentOrientation; 8916 } 8917 8918 /** 8919 * Sets the <code>ComponentOrientation</code> property of this component 8920 * and all components contained within it. 8921 * <p> 8922 * This method changes layout-related information, and therefore, 8923 * invalidates the component hierarchy. 8924 * 8925 * 8926 * @param orientation the new component orientation of this component and 8927 * the components contained within it. 8928 * @exception NullPointerException if <code>orientation</code> is null. 8929 * @see #setComponentOrientation 8930 * @see #getComponentOrientation 8931 * @see #invalidate 8932 * @since 1.4 8933 */ applyComponentOrientation(ComponentOrientation orientation)8934 public void applyComponentOrientation(ComponentOrientation orientation) { 8935 if (orientation == null) { 8936 throw new NullPointerException(); 8937 } 8938 setComponentOrientation(orientation); 8939 } 8940 canBeFocusOwner()8941 final boolean canBeFocusOwner() { 8942 // It is enabled, visible, focusable. 8943 if (isEnabled() && isDisplayable() && isVisible() && isFocusable()) { 8944 return true; 8945 } 8946 return false; 8947 } 8948 8949 /** 8950 * Checks that this component meets the prerequesites to be focus owner: 8951 * - it is enabled, visible, focusable 8952 * - it's parents are all enabled and showing 8953 * - top-level window is focusable 8954 * - if focus cycle root has DefaultFocusTraversalPolicy then it also checks that this policy accepts 8955 * this component as focus owner 8956 * @since 1.5 8957 */ canBeFocusOwnerRecursively()8958 final boolean canBeFocusOwnerRecursively() { 8959 // - it is enabled, visible, focusable 8960 if (!canBeFocusOwner()) { 8961 return false; 8962 } 8963 8964 // - it's parents are all enabled and showing 8965 synchronized(getTreeLock()) { 8966 if (parent != null) { 8967 return parent.canContainFocusOwner(this); 8968 } 8969 } 8970 return true; 8971 } 8972 8973 /** 8974 * Fix the location of the HW component in a LW container hierarchy. 8975 */ relocateComponent()8976 final void relocateComponent() { 8977 synchronized (getTreeLock()) { 8978 if (peer == null) { 8979 return; 8980 } 8981 int nativeX = x; 8982 int nativeY = y; 8983 for (Component cont = getContainer(); 8984 cont != null && cont.isLightweight(); 8985 cont = cont.getContainer()) 8986 { 8987 nativeX += cont.x; 8988 nativeY += cont.y; 8989 } 8990 peer.setBounds(nativeX, nativeY, width, height, 8991 ComponentPeer.SET_LOCATION); 8992 } 8993 } 8994 8995 /** 8996 * Returns the <code>Window</code> ancestor of the component. 8997 * @return Window ancestor of the component or component by itself if it is Window; 8998 * null, if component is not a part of window hierarchy 8999 */ getContainingWindow()9000 Window getContainingWindow() { 9001 return SunToolkit.getContainingWindow(this); 9002 } 9003 9004 /** 9005 * Initialize JNI field and method IDs 9006 */ initIDs()9007 private static native void initIDs(); 9008 9009 /* 9010 * --- Accessibility Support --- 9011 * 9012 * Component will contain all of the methods in interface Accessible, 9013 * though it won't actually implement the interface - that will be up 9014 * to the individual objects which extend Component. 9015 */ 9016 9017 /** 9018 * The {@code AccessibleContext} associated with this {@code Component}. 9019 */ 9020 protected AccessibleContext accessibleContext = null; 9021 9022 /** 9023 * Gets the <code>AccessibleContext</code> associated 9024 * with this <code>Component</code>. 9025 * The method implemented by this base 9026 * class returns null. Classes that extend <code>Component</code> 9027 * should implement this method to return the 9028 * <code>AccessibleContext</code> associated with the subclass. 9029 * 9030 * 9031 * @return the <code>AccessibleContext</code> of this 9032 * <code>Component</code> 9033 * @since 1.3 9034 */ getAccessibleContext()9035 public AccessibleContext getAccessibleContext() { 9036 return accessibleContext; 9037 } 9038 9039 /** 9040 * Inner class of Component used to provide default support for 9041 * accessibility. This class is not meant to be used directly by 9042 * application developers, but is instead meant only to be 9043 * subclassed by component developers. 9044 * <p> 9045 * The class used to obtain the accessible role for this object. 9046 * @since 1.3 9047 */ 9048 protected abstract class AccessibleAWTComponent extends AccessibleContext 9049 implements Serializable, AccessibleComponent { 9050 9051 private static final long serialVersionUID = 642321655757800191L; 9052 9053 /** 9054 * Though the class is abstract, this should be called by 9055 * all sub-classes. 9056 */ AccessibleAWTComponent()9057 protected AccessibleAWTComponent() { 9058 } 9059 9060 /** 9061 * Number of PropertyChangeListener objects registered. It's used 9062 * to add/remove ComponentListener and FocusListener to track 9063 * target Component's state. 9064 */ 9065 private volatile transient int propertyListenersCount = 0; 9066 9067 protected ComponentListener accessibleAWTComponentHandler = null; 9068 protected FocusListener accessibleAWTFocusHandler = null; 9069 9070 /** 9071 * Fire PropertyChange listener, if one is registered, 9072 * when shown/hidden.. 9073 * @since 1.3 9074 */ 9075 protected class AccessibleAWTComponentHandler implements ComponentListener { componentHidden(ComponentEvent e)9076 public void componentHidden(ComponentEvent e) { 9077 if (accessibleContext != null) { 9078 accessibleContext.firePropertyChange( 9079 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 9080 AccessibleState.VISIBLE, null); 9081 } 9082 } 9083 componentShown(ComponentEvent e)9084 public void componentShown(ComponentEvent e) { 9085 if (accessibleContext != null) { 9086 accessibleContext.firePropertyChange( 9087 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 9088 null, AccessibleState.VISIBLE); 9089 } 9090 } 9091 componentMoved(ComponentEvent e)9092 public void componentMoved(ComponentEvent e) { 9093 } 9094 componentResized(ComponentEvent e)9095 public void componentResized(ComponentEvent e) { 9096 } 9097 } // inner class AccessibleAWTComponentHandler 9098 9099 9100 /** 9101 * Fire PropertyChange listener, if one is registered, 9102 * when focus events happen 9103 * @since 1.3 9104 */ 9105 protected class AccessibleAWTFocusHandler implements FocusListener { focusGained(FocusEvent event)9106 public void focusGained(FocusEvent event) { 9107 if (accessibleContext != null) { 9108 accessibleContext.firePropertyChange( 9109 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 9110 null, AccessibleState.FOCUSED); 9111 } 9112 } focusLost(FocusEvent event)9113 public void focusLost(FocusEvent event) { 9114 if (accessibleContext != null) { 9115 accessibleContext.firePropertyChange( 9116 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 9117 AccessibleState.FOCUSED, null); 9118 } 9119 } 9120 } // inner class AccessibleAWTFocusHandler 9121 9122 9123 /** 9124 * Adds a <code>PropertyChangeListener</code> to the listener list. 9125 * 9126 * @param listener the property change listener to be added 9127 */ addPropertyChangeListener(PropertyChangeListener listener)9128 public void addPropertyChangeListener(PropertyChangeListener listener) { 9129 if (accessibleAWTComponentHandler == null) { 9130 accessibleAWTComponentHandler = new AccessibleAWTComponentHandler(); 9131 } 9132 if (accessibleAWTFocusHandler == null) { 9133 accessibleAWTFocusHandler = new AccessibleAWTFocusHandler(); 9134 } 9135 if (propertyListenersCount++ == 0) { 9136 Component.this.addComponentListener(accessibleAWTComponentHandler); 9137 Component.this.addFocusListener(accessibleAWTFocusHandler); 9138 } 9139 super.addPropertyChangeListener(listener); 9140 } 9141 9142 /** 9143 * Remove a PropertyChangeListener from the listener list. 9144 * This removes a PropertyChangeListener that was registered 9145 * for all properties. 9146 * 9147 * @param listener The PropertyChangeListener to be removed 9148 */ removePropertyChangeListener(PropertyChangeListener listener)9149 public void removePropertyChangeListener(PropertyChangeListener listener) { 9150 if (--propertyListenersCount == 0) { 9151 Component.this.removeComponentListener(accessibleAWTComponentHandler); 9152 Component.this.removeFocusListener(accessibleAWTFocusHandler); 9153 } 9154 super.removePropertyChangeListener(listener); 9155 } 9156 9157 // AccessibleContext methods 9158 // 9159 /** 9160 * Gets the accessible name of this object. This should almost never 9161 * return <code>java.awt.Component.getName()</code>, 9162 * as that generally isn't a localized name, 9163 * and doesn't have meaning for the user. If the 9164 * object is fundamentally a text object (e.g. a menu item), the 9165 * accessible name should be the text of the object (e.g. "save"). 9166 * If the object has a tooltip, the tooltip text may also be an 9167 * appropriate String to return. 9168 * 9169 * @return the localized name of the object -- can be 9170 * <code>null</code> if this 9171 * object does not have a name 9172 * @see javax.accessibility.AccessibleContext#setAccessibleName 9173 */ getAccessibleName()9174 public String getAccessibleName() { 9175 return accessibleName; 9176 } 9177 9178 /** 9179 * Gets the accessible description of this object. This should be 9180 * a concise, localized description of what this object is - what 9181 * is its meaning to the user. If the object has a tooltip, the 9182 * tooltip text may be an appropriate string to return, assuming 9183 * it contains a concise description of the object (instead of just 9184 * the name of the object - e.g. a "Save" icon on a toolbar that 9185 * had "save" as the tooltip text shouldn't return the tooltip 9186 * text as the description, but something like "Saves the current 9187 * text document" instead). 9188 * 9189 * @return the localized description of the object -- can be 9190 * <code>null</code> if this object does not have a description 9191 * @see javax.accessibility.AccessibleContext#setAccessibleDescription 9192 */ getAccessibleDescription()9193 public String getAccessibleDescription() { 9194 return accessibleDescription; 9195 } 9196 9197 /** 9198 * Gets the role of this object. 9199 * 9200 * @return an instance of <code>AccessibleRole</code> 9201 * describing the role of the object 9202 * @see javax.accessibility.AccessibleRole 9203 */ getAccessibleRole()9204 public AccessibleRole getAccessibleRole() { 9205 return AccessibleRole.AWT_COMPONENT; 9206 } 9207 9208 /** 9209 * Gets the state of this object. 9210 * 9211 * @return an instance of <code>AccessibleStateSet</code> 9212 * containing the current state set of the object 9213 * @see javax.accessibility.AccessibleState 9214 */ getAccessibleStateSet()9215 public AccessibleStateSet getAccessibleStateSet() { 9216 return Component.this.getAccessibleStateSet(); 9217 } 9218 9219 /** 9220 * Gets the <code>Accessible</code> parent of this object. 9221 * If the parent of this object implements <code>Accessible</code>, 9222 * this method should simply return <code>getParent</code>. 9223 * 9224 * @return the <code>Accessible</code> parent of this 9225 * object -- can be <code>null</code> if this 9226 * object does not have an <code>Accessible</code> parent 9227 */ getAccessibleParent()9228 public Accessible getAccessibleParent() { 9229 if (accessibleParent != null) { 9230 return accessibleParent; 9231 } else { 9232 Container parent = getParent(); 9233 if (parent instanceof Accessible) { 9234 return (Accessible) parent; 9235 } 9236 } 9237 return null; 9238 } 9239 9240 /** 9241 * Gets the index of this object in its accessible parent. 9242 * 9243 * @return the index of this object in its parent; or -1 if this 9244 * object does not have an accessible parent 9245 * @see #getAccessibleParent 9246 */ getAccessibleIndexInParent()9247 public int getAccessibleIndexInParent() { 9248 return Component.this.getAccessibleIndexInParent(); 9249 } 9250 9251 /** 9252 * Returns the number of accessible children in the object. If all 9253 * of the children of this object implement <code>Accessible</code>, 9254 * then this method should return the number of children of this object. 9255 * 9256 * @return the number of accessible children in the object 9257 */ getAccessibleChildrenCount()9258 public int getAccessibleChildrenCount() { 9259 return 0; // Components don't have children 9260 } 9261 9262 /** 9263 * Returns the nth <code>Accessible</code> child of the object. 9264 * 9265 * @param i zero-based index of child 9266 * @return the nth <code>Accessible</code> child of the object 9267 */ getAccessibleChild(int i)9268 public Accessible getAccessibleChild(int i) { 9269 return null; // Components don't have children 9270 } 9271 9272 /** 9273 * Returns the locale of this object. 9274 * 9275 * @return the locale of this object 9276 */ getLocale()9277 public Locale getLocale() { 9278 return Component.this.getLocale(); 9279 } 9280 9281 /** 9282 * Gets the <code>AccessibleComponent</code> associated 9283 * with this object if one exists. 9284 * Otherwise return <code>null</code>. 9285 * 9286 * @return the component 9287 */ getAccessibleComponent()9288 public AccessibleComponent getAccessibleComponent() { 9289 return this; 9290 } 9291 9292 9293 // AccessibleComponent methods 9294 // 9295 /** 9296 * Gets the background color of this object. 9297 * 9298 * @return the background color, if supported, of the object; 9299 * otherwise, <code>null</code> 9300 */ getBackground()9301 public Color getBackground() { 9302 return Component.this.getBackground(); 9303 } 9304 9305 /** 9306 * Sets the background color of this object. 9307 * (For transparency, see <code>isOpaque</code>.) 9308 * 9309 * @param c the new <code>Color</code> for the background 9310 * @see Component#isOpaque 9311 */ setBackground(Color c)9312 public void setBackground(Color c) { 9313 Component.this.setBackground(c); 9314 } 9315 9316 /** 9317 * Gets the foreground color of this object. 9318 * 9319 * @return the foreground color, if supported, of the object; 9320 * otherwise, <code>null</code> 9321 */ getForeground()9322 public Color getForeground() { 9323 return Component.this.getForeground(); 9324 } 9325 9326 /** 9327 * Sets the foreground color of this object. 9328 * 9329 * @param c the new <code>Color</code> for the foreground 9330 */ setForeground(Color c)9331 public void setForeground(Color c) { 9332 Component.this.setForeground(c); 9333 } 9334 9335 /** 9336 * Gets the <code>Cursor</code> of this object. 9337 * 9338 * @return the <code>Cursor</code>, if supported, 9339 * of the object; otherwise, <code>null</code> 9340 */ getCursor()9341 public Cursor getCursor() { 9342 return Component.this.getCursor(); 9343 } 9344 9345 /** 9346 * Sets the <code>Cursor</code> of this object. 9347 * <p> 9348 * The method may have no visual effect if the Java platform 9349 * implementation and/or the native system do not support 9350 * changing the mouse cursor shape. 9351 * @param cursor the new <code>Cursor</code> for the object 9352 */ setCursor(Cursor cursor)9353 public void setCursor(Cursor cursor) { 9354 Component.this.setCursor(cursor); 9355 } 9356 9357 /** 9358 * Gets the <code>Font</code> of this object. 9359 * 9360 * @return the <code>Font</code>, if supported, 9361 * for the object; otherwise, <code>null</code> 9362 */ getFont()9363 public Font getFont() { 9364 return Component.this.getFont(); 9365 } 9366 9367 /** 9368 * Sets the <code>Font</code> of this object. 9369 * 9370 * @param f the new <code>Font</code> for the object 9371 */ setFont(Font f)9372 public void setFont(Font f) { 9373 Component.this.setFont(f); 9374 } 9375 9376 /** 9377 * Gets the <code>FontMetrics</code> of this object. 9378 * 9379 * @param f the <code>Font</code> 9380 * @return the <code>FontMetrics</code>, if supported, 9381 * the object; otherwise, <code>null</code> 9382 * @see #getFont 9383 */ getFontMetrics(Font f)9384 public FontMetrics getFontMetrics(Font f) { 9385 if (f == null) { 9386 return null; 9387 } else { 9388 return Component.this.getFontMetrics(f); 9389 } 9390 } 9391 9392 /** 9393 * Determines if the object is enabled. 9394 * 9395 * @return true if object is enabled; otherwise, false 9396 */ isEnabled()9397 public boolean isEnabled() { 9398 return Component.this.isEnabled(); 9399 } 9400 9401 /** 9402 * Sets the enabled state of the object. 9403 * 9404 * @param b if true, enables this object; otherwise, disables it 9405 */ setEnabled(boolean b)9406 public void setEnabled(boolean b) { 9407 boolean old = Component.this.isEnabled(); 9408 Component.this.setEnabled(b); 9409 if (b != old) { 9410 if (accessibleContext != null) { 9411 if (b) { 9412 accessibleContext.firePropertyChange( 9413 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 9414 null, AccessibleState.ENABLED); 9415 } else { 9416 accessibleContext.firePropertyChange( 9417 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 9418 AccessibleState.ENABLED, null); 9419 } 9420 } 9421 } 9422 } 9423 9424 /** 9425 * Determines if the object is visible. Note: this means that the 9426 * object intends to be visible; however, it may not in fact be 9427 * showing on the screen because one of the objects that this object 9428 * is contained by is not visible. To determine if an object is 9429 * showing on the screen, use <code>isShowing</code>. 9430 * 9431 * @return true if object is visible; otherwise, false 9432 */ isVisible()9433 public boolean isVisible() { 9434 return Component.this.isVisible(); 9435 } 9436 9437 /** 9438 * Sets the visible state of the object. 9439 * 9440 * @param b if true, shows this object; otherwise, hides it 9441 */ setVisible(boolean b)9442 public void setVisible(boolean b) { 9443 boolean old = Component.this.isVisible(); 9444 Component.this.setVisible(b); 9445 if (b != old) { 9446 if (accessibleContext != null) { 9447 if (b) { 9448 accessibleContext.firePropertyChange( 9449 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 9450 null, AccessibleState.VISIBLE); 9451 } else { 9452 accessibleContext.firePropertyChange( 9453 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 9454 AccessibleState.VISIBLE, null); 9455 } 9456 } 9457 } 9458 } 9459 9460 /** 9461 * Determines if the object is showing. This is determined by checking 9462 * the visibility of the object and ancestors of the object. Note: 9463 * this will return true even if the object is obscured by another 9464 * (for example, it happens to be underneath a menu that was pulled 9465 * down). 9466 * 9467 * @return true if object is showing; otherwise, false 9468 */ isShowing()9469 public boolean isShowing() { 9470 return Component.this.isShowing(); 9471 } 9472 9473 /** 9474 * Checks whether the specified point is within this object's bounds, 9475 * where the point's x and y coordinates are defined to be relative to 9476 * the coordinate system of the object. 9477 * 9478 * @param p the <code>Point</code> relative to the 9479 * coordinate system of the object 9480 * @return true if object contains <code>Point</code>; otherwise false 9481 */ contains(Point p)9482 public boolean contains(Point p) { 9483 return Component.this.contains(p); 9484 } 9485 9486 /** 9487 * Returns the location of the object on the screen. 9488 * 9489 * @return location of object on screen -- can be 9490 * <code>null</code> if this object is not on the screen 9491 */ getLocationOnScreen()9492 public Point getLocationOnScreen() { 9493 synchronized (Component.this.getTreeLock()) { 9494 if (Component.this.isShowing()) { 9495 return Component.this.getLocationOnScreen(); 9496 } else { 9497 return null; 9498 } 9499 } 9500 } 9501 9502 /** 9503 * Gets the location of the object relative to the parent in the form 9504 * of a point specifying the object's top-left corner in the screen's 9505 * coordinate space. 9506 * 9507 * @return an instance of Point representing the top-left corner of 9508 * the object's bounds in the coordinate space of the screen; 9509 * <code>null</code> if this object or its parent are not on the screen 9510 */ getLocation()9511 public Point getLocation() { 9512 return Component.this.getLocation(); 9513 } 9514 9515 /** 9516 * Sets the location of the object relative to the parent. 9517 * @param p the coordinates of the object 9518 */ setLocation(Point p)9519 public void setLocation(Point p) { 9520 Component.this.setLocation(p); 9521 } 9522 9523 /** 9524 * Gets the bounds of this object in the form of a Rectangle object. 9525 * The bounds specify this object's width, height, and location 9526 * relative to its parent. 9527 * 9528 * @return a rectangle indicating this component's bounds; 9529 * <code>null</code> if this object is not on the screen 9530 */ getBounds()9531 public Rectangle getBounds() { 9532 return Component.this.getBounds(); 9533 } 9534 9535 /** 9536 * Sets the bounds of this object in the form of a 9537 * <code>Rectangle</code> object. 9538 * The bounds specify this object's width, height, and location 9539 * relative to its parent. 9540 * 9541 * @param r a rectangle indicating this component's bounds 9542 */ setBounds(Rectangle r)9543 public void setBounds(Rectangle r) { 9544 Component.this.setBounds(r); 9545 } 9546 9547 /** 9548 * Returns the size of this object in the form of a 9549 * <code>Dimension</code> object. The height field of the 9550 * <code>Dimension</code> object contains this objects's 9551 * height, and the width field of the <code>Dimension</code> 9552 * object contains this object's width. 9553 * 9554 * @return a <code>Dimension</code> object that indicates 9555 * the size of this component; <code>null</code> if 9556 * this object is not on the screen 9557 */ getSize()9558 public Dimension getSize() { 9559 return Component.this.getSize(); 9560 } 9561 9562 /** 9563 * Resizes this object so that it has width and height. 9564 * 9565 * @param d - the dimension specifying the new size of the object 9566 */ setSize(Dimension d)9567 public void setSize(Dimension d) { 9568 Component.this.setSize(d); 9569 } 9570 9571 /** 9572 * Returns the <code>Accessible</code> child, 9573 * if one exists, contained at the local 9574 * coordinate <code>Point</code>. Otherwise returns 9575 * <code>null</code>. 9576 * 9577 * @param p the point defining the top-left corner of 9578 * the <code>Accessible</code>, given in the 9579 * coordinate space of the object's parent 9580 * @return the <code>Accessible</code>, if it exists, 9581 * at the specified location; else <code>null</code> 9582 */ getAccessibleAt(Point p)9583 public Accessible getAccessibleAt(Point p) { 9584 return null; // Components don't have children 9585 } 9586 9587 /** 9588 * Returns whether this object can accept focus or not. 9589 * 9590 * @return true if object can accept focus; otherwise false 9591 */ isFocusTraversable()9592 public boolean isFocusTraversable() { 9593 return Component.this.isFocusTraversable(); 9594 } 9595 9596 /** 9597 * Requests focus for this object. 9598 */ requestFocus()9599 public void requestFocus() { 9600 Component.this.requestFocus(); 9601 } 9602 9603 /** 9604 * Adds the specified focus listener to receive focus events from this 9605 * component. 9606 * 9607 * @param l the focus listener 9608 */ addFocusListener(FocusListener l)9609 public void addFocusListener(FocusListener l) { 9610 Component.this.addFocusListener(l); 9611 } 9612 9613 /** 9614 * Removes the specified focus listener so it no longer receives focus 9615 * events from this component. 9616 * 9617 * @param l the focus listener 9618 */ removeFocusListener(FocusListener l)9619 public void removeFocusListener(FocusListener l) { 9620 Component.this.removeFocusListener(l); 9621 } 9622 9623 } // inner class AccessibleAWTComponent 9624 9625 9626 /** 9627 * Gets the index of this object in its accessible parent. 9628 * If this object does not have an accessible parent, returns 9629 * -1. 9630 * 9631 * @return the index of this object in its accessible parent 9632 */ getAccessibleIndexInParent()9633 int getAccessibleIndexInParent() { 9634 synchronized (getTreeLock()) { 9635 int index = -1; 9636 Container parent = this.getParent(); 9637 if (parent != null && parent instanceof Accessible) { 9638 Component ca[] = parent.getComponents(); 9639 for (int i = 0; i < ca.length; i++) { 9640 if (ca[i] instanceof Accessible) { 9641 index++; 9642 } 9643 if (this.equals(ca[i])) { 9644 return index; 9645 } 9646 } 9647 } 9648 return -1; 9649 } 9650 } 9651 9652 /** 9653 * Gets the current state set of this object. 9654 * 9655 * @return an instance of <code>AccessibleStateSet</code> 9656 * containing the current state set of the object 9657 * @see AccessibleState 9658 */ getAccessibleStateSet()9659 AccessibleStateSet getAccessibleStateSet() { 9660 synchronized (getTreeLock()) { 9661 AccessibleStateSet states = new AccessibleStateSet(); 9662 if (this.isEnabled()) { 9663 states.add(AccessibleState.ENABLED); 9664 } 9665 if (this.isFocusTraversable()) { 9666 states.add(AccessibleState.FOCUSABLE); 9667 } 9668 if (this.isVisible()) { 9669 states.add(AccessibleState.VISIBLE); 9670 } 9671 if (this.isShowing()) { 9672 states.add(AccessibleState.SHOWING); 9673 } 9674 if (this.isFocusOwner()) { 9675 states.add(AccessibleState.FOCUSED); 9676 } 9677 if (this instanceof Accessible) { 9678 AccessibleContext ac = ((Accessible) this).getAccessibleContext(); 9679 if (ac != null) { 9680 Accessible ap = ac.getAccessibleParent(); 9681 if (ap != null) { 9682 AccessibleContext pac = ap.getAccessibleContext(); 9683 if (pac != null) { 9684 AccessibleSelection as = pac.getAccessibleSelection(); 9685 if (as != null) { 9686 states.add(AccessibleState.SELECTABLE); 9687 int i = ac.getAccessibleIndexInParent(); 9688 if (i >= 0) { 9689 if (as.isAccessibleChildSelected(i)) { 9690 states.add(AccessibleState.SELECTED); 9691 } 9692 } 9693 } 9694 } 9695 } 9696 } 9697 } 9698 if (Component.isInstanceOf(this, "javax.swing.JComponent")) { 9699 if (((javax.swing.JComponent) this).isOpaque()) { 9700 states.add(AccessibleState.OPAQUE); 9701 } 9702 } 9703 return states; 9704 } 9705 } 9706 9707 /** 9708 * Checks that the given object is instance of the given class. 9709 * @param obj Object to be checked 9710 * @param className The name of the class. Must be fully-qualified class name. 9711 * @return true, if this object is instanceof given class, 9712 * false, otherwise, or if obj or className is null 9713 */ isInstanceOf(Object obj, String className)9714 static boolean isInstanceOf(Object obj, String className) { 9715 if (obj == null) return false; 9716 if (className == null) return false; 9717 9718 Class<?> cls = obj.getClass(); 9719 while (cls != null) { 9720 if (cls.getName().equals(className)) { 9721 return true; 9722 } 9723 cls = cls.getSuperclass(); 9724 } 9725 return false; 9726 } 9727 9728 9729 // ************************** MIXING CODE ******************************* 9730 9731 /** 9732 * Check whether we can trust the current bounds of the component. 9733 * The return value of false indicates that the container of the 9734 * component is invalid, and therefore needs to be layed out, which would 9735 * probably mean changing the bounds of its children. 9736 * Null-layout of the container or absence of the container mean 9737 * the bounds of the component are final and can be trusted. 9738 */ areBoundsValid()9739 final boolean areBoundsValid() { 9740 Container cont = getContainer(); 9741 return cont == null || cont.isValid() || cont.getLayout() == null; 9742 } 9743 9744 /** 9745 * Applies the shape to the component 9746 * @param shape Shape to be applied to the component 9747 */ applyCompoundShape(Region shape)9748 void applyCompoundShape(Region shape) { 9749 checkTreeLock(); 9750 9751 if (!areBoundsValid()) { 9752 if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) { 9753 mixingLog.fine("this = " + this + "; areBoundsValid = " + areBoundsValid()); 9754 } 9755 return; 9756 } 9757 9758 if (!isLightweight()) { 9759 ComponentPeer peer = getPeer(); 9760 if (peer != null) { 9761 // The Region class has some optimizations. That's why 9762 // we should manually check whether it's empty and 9763 // substitute the object ourselves. Otherwise we end up 9764 // with some incorrect Region object with loX being 9765 // greater than the hiX for instance. 9766 if (shape.isEmpty()) { 9767 shape = Region.EMPTY_REGION; 9768 } 9769 9770 9771 // Note: the shape is not really copied/cloned. We create 9772 // the Region object ourselves, so there's no any possibility 9773 // to modify the object outside of the mixing code. 9774 // Nullifying compoundShape means that the component has normal shape 9775 // (or has no shape at all). 9776 if (shape.equals(getNormalShape())) { 9777 if (this.compoundShape == null) { 9778 return; 9779 } 9780 this.compoundShape = null; 9781 peer.applyShape(null); 9782 } else { 9783 if (shape.equals(getAppliedShape())) { 9784 return; 9785 } 9786 this.compoundShape = shape; 9787 Point compAbsolute = getLocationOnWindow(); 9788 if (mixingLog.isLoggable(PlatformLogger.Level.FINER)) { 9789 mixingLog.fine("this = " + this + 9790 "; compAbsolute=" + compAbsolute + "; shape=" + shape); 9791 } 9792 peer.applyShape(shape.getTranslatedRegion(-compAbsolute.x, -compAbsolute.y)); 9793 } 9794 } 9795 } 9796 } 9797 9798 /** 9799 * Returns the shape previously set with applyCompoundShape(). 9800 * If the component is LW or no shape was applied yet, 9801 * the method returns the normal shape. 9802 */ getAppliedShape()9803 private Region getAppliedShape() { 9804 checkTreeLock(); 9805 //XXX: if we allow LW components to have a shape, this must be changed 9806 return (this.compoundShape == null || isLightweight()) ? getNormalShape() : this.compoundShape; 9807 } 9808 getLocationOnWindow()9809 Point getLocationOnWindow() { 9810 checkTreeLock(); 9811 Point curLocation = getLocation(); 9812 9813 for (Container parent = getContainer(); 9814 parent != null && !(parent instanceof Window); 9815 parent = parent.getContainer()) 9816 { 9817 curLocation.x += parent.getX(); 9818 curLocation.y += parent.getY(); 9819 } 9820 9821 return curLocation; 9822 } 9823 9824 /** 9825 * Returns the full shape of the component located in window coordinates 9826 */ getNormalShape()9827 final Region getNormalShape() { 9828 checkTreeLock(); 9829 //XXX: we may take into account a user-specified shape for this component 9830 Point compAbsolute = getLocationOnWindow(); 9831 return 9832 Region.getInstanceXYWH( 9833 compAbsolute.x, 9834 compAbsolute.y, 9835 getWidth(), 9836 getHeight() 9837 ); 9838 } 9839 9840 /** 9841 * Returns the "opaque shape" of the component. 9842 * 9843 * The opaque shape of a lightweight components is the actual shape that 9844 * needs to be cut off of the heavyweight components in order to mix this 9845 * lightweight component correctly with them. 9846 * 9847 * The method is overriden in the java.awt.Container to handle non-opaque 9848 * containers containing opaque children. 9849 * 9850 * See 6637655 for details. 9851 */ getOpaqueShape()9852 Region getOpaqueShape() { 9853 checkTreeLock(); 9854 if (mixingCutoutRegion != null) { 9855 return mixingCutoutRegion; 9856 } else { 9857 return getNormalShape(); 9858 } 9859 } 9860 getSiblingIndexAbove()9861 final int getSiblingIndexAbove() { 9862 checkTreeLock(); 9863 Container parent = getContainer(); 9864 if (parent == null) { 9865 return -1; 9866 } 9867 9868 int nextAbove = parent.getComponentZOrder(this) - 1; 9869 9870 return nextAbove < 0 ? -1 : nextAbove; 9871 } 9872 getHWPeerAboveMe()9873 final ComponentPeer getHWPeerAboveMe() { 9874 checkTreeLock(); 9875 9876 Container cont = getContainer(); 9877 int indexAbove = getSiblingIndexAbove(); 9878 9879 while (cont != null) { 9880 for (int i = indexAbove; i > -1; i--) { 9881 Component comp = cont.getComponent(i); 9882 if (comp != null && comp.isDisplayable() && !comp.isLightweight()) { 9883 return comp.getPeer(); 9884 } 9885 } 9886 // traversing the hierarchy up to the closest HW container; 9887 // further traversing may return a component that is not actually 9888 // a native sibling of this component and this kind of z-order 9889 // request may not be allowed by the underlying system (6852051). 9890 if (!cont.isLightweight()) { 9891 break; 9892 } 9893 9894 indexAbove = cont.getSiblingIndexAbove(); 9895 cont = cont.getContainer(); 9896 } 9897 9898 return null; 9899 } 9900 getSiblingIndexBelow()9901 final int getSiblingIndexBelow() { 9902 checkTreeLock(); 9903 Container parent = getContainer(); 9904 if (parent == null) { 9905 return -1; 9906 } 9907 9908 int nextBelow = parent.getComponentZOrder(this) + 1; 9909 9910 return nextBelow >= parent.getComponentCount() ? -1 : nextBelow; 9911 } 9912 isNonOpaqueForMixing()9913 final boolean isNonOpaqueForMixing() { 9914 return mixingCutoutRegion != null && 9915 mixingCutoutRegion.isEmpty(); 9916 } 9917 calculateCurrentShape()9918 private Region calculateCurrentShape() { 9919 checkTreeLock(); 9920 Region s = getNormalShape(); 9921 9922 if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) { 9923 mixingLog.fine("this = " + this + "; normalShape=" + s); 9924 } 9925 9926 if (getContainer() != null) { 9927 Component comp = this; 9928 Container cont = comp.getContainer(); 9929 9930 while (cont != null) { 9931 for (int index = comp.getSiblingIndexAbove(); index != -1; --index) { 9932 /* It is assumed that: 9933 * 9934 * getComponent(getContainer().getComponentZOrder(comp)) == comp 9935 * 9936 * The assumption has been made according to the current 9937 * implementation of the Container class. 9938 */ 9939 Component c = cont.getComponent(index); 9940 if (c.isLightweight() && c.isShowing()) { 9941 s = s.getDifference(c.getOpaqueShape()); 9942 } 9943 } 9944 9945 if (cont.isLightweight()) { 9946 s = s.getIntersection(cont.getNormalShape()); 9947 } else { 9948 break; 9949 } 9950 9951 comp = cont; 9952 cont = cont.getContainer(); 9953 } 9954 } 9955 9956 if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) { 9957 mixingLog.fine("currentShape=" + s); 9958 } 9959 9960 return s; 9961 } 9962 applyCurrentShape()9963 void applyCurrentShape() { 9964 checkTreeLock(); 9965 if (!areBoundsValid()) { 9966 if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) { 9967 mixingLog.fine("this = " + this + "; areBoundsValid = " + areBoundsValid()); 9968 } 9969 return; // Because applyCompoundShape() ignores such components anyway 9970 } 9971 if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) { 9972 mixingLog.fine("this = " + this); 9973 } 9974 applyCompoundShape(calculateCurrentShape()); 9975 } 9976 subtractAndApplyShape(Region s)9977 final void subtractAndApplyShape(Region s) { 9978 checkTreeLock(); 9979 9980 if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) { 9981 mixingLog.fine("this = " + this + "; s=" + s); 9982 } 9983 9984 applyCompoundShape(getAppliedShape().getDifference(s)); 9985 } 9986 applyCurrentShapeBelowMe()9987 private final void applyCurrentShapeBelowMe() { 9988 checkTreeLock(); 9989 Container parent = getContainer(); 9990 if (parent != null && parent.isShowing()) { 9991 // First, reapply shapes of my siblings 9992 parent.recursiveApplyCurrentShape(getSiblingIndexBelow()); 9993 9994 // Second, if my container is non-opaque, reapply shapes of siblings of my container 9995 Container parent2 = parent.getContainer(); 9996 while (!parent.isOpaque() && parent2 != null) { 9997 parent2.recursiveApplyCurrentShape(parent.getSiblingIndexBelow()); 9998 9999 parent = parent2; 10000 parent2 = parent.getContainer(); 10001 } 10002 } 10003 } 10004 subtractAndApplyShapeBelowMe()10005 final void subtractAndApplyShapeBelowMe() { 10006 checkTreeLock(); 10007 Container parent = getContainer(); 10008 if (parent != null && isShowing()) { 10009 Region opaqueShape = getOpaqueShape(); 10010 10011 // First, cut my siblings 10012 parent.recursiveSubtractAndApplyShape(opaqueShape, getSiblingIndexBelow()); 10013 10014 // Second, if my container is non-opaque, cut siblings of my container 10015 Container parent2 = parent.getContainer(); 10016 while (!parent.isOpaque() && parent2 != null) { 10017 parent2.recursiveSubtractAndApplyShape(opaqueShape, parent.getSiblingIndexBelow()); 10018 10019 parent = parent2; 10020 parent2 = parent.getContainer(); 10021 } 10022 } 10023 } 10024 mixOnShowing()10025 void mixOnShowing() { 10026 synchronized (getTreeLock()) { 10027 if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) { 10028 mixingLog.fine("this = " + this); 10029 } 10030 if (!isMixingNeeded()) { 10031 return; 10032 } 10033 if (isLightweight()) { 10034 subtractAndApplyShapeBelowMe(); 10035 } else { 10036 applyCurrentShape(); 10037 } 10038 } 10039 } 10040 mixOnHiding(boolean isLightweight)10041 void mixOnHiding(boolean isLightweight) { 10042 // We cannot be sure that the peer exists at this point, so we need the argument 10043 // to find out whether the hiding component is (well, actually was) a LW or a HW. 10044 synchronized (getTreeLock()) { 10045 if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) { 10046 mixingLog.fine("this = " + this + "; isLightweight = " + isLightweight); 10047 } 10048 if (!isMixingNeeded()) { 10049 return; 10050 } 10051 if (isLightweight) { 10052 applyCurrentShapeBelowMe(); 10053 } 10054 } 10055 } 10056 mixOnReshaping()10057 void mixOnReshaping() { 10058 synchronized (getTreeLock()) { 10059 if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) { 10060 mixingLog.fine("this = " + this); 10061 } 10062 if (!isMixingNeeded()) { 10063 return; 10064 } 10065 if (isLightweight()) { 10066 applyCurrentShapeBelowMe(); 10067 } else { 10068 applyCurrentShape(); 10069 } 10070 } 10071 } 10072 mixOnZOrderChanging(int oldZorder, int newZorder)10073 void mixOnZOrderChanging(int oldZorder, int newZorder) { 10074 synchronized (getTreeLock()) { 10075 boolean becameHigher = newZorder < oldZorder; 10076 Container parent = getContainer(); 10077 10078 if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) { 10079 mixingLog.fine("this = " + this + 10080 "; oldZorder=" + oldZorder + "; newZorder=" + newZorder + "; parent=" + parent); 10081 } 10082 if (!isMixingNeeded()) { 10083 return; 10084 } 10085 if (isLightweight()) { 10086 if (becameHigher) { 10087 if (parent != null && isShowing()) { 10088 parent.recursiveSubtractAndApplyShape(getOpaqueShape(), getSiblingIndexBelow(), oldZorder); 10089 } 10090 } else { 10091 if (parent != null) { 10092 parent.recursiveApplyCurrentShape(oldZorder, newZorder); 10093 } 10094 } 10095 } else { 10096 if (becameHigher) { 10097 applyCurrentShape(); 10098 } else { 10099 if (parent != null) { 10100 Region shape = getAppliedShape(); 10101 10102 for (int index = oldZorder; index < newZorder; index++) { 10103 Component c = parent.getComponent(index); 10104 if (c.isLightweight() && c.isShowing()) { 10105 shape = shape.getDifference(c.getOpaqueShape()); 10106 } 10107 } 10108 applyCompoundShape(shape); 10109 } 10110 } 10111 } 10112 } 10113 } 10114 10115 void mixOnValidating() { 10116 // This method gets overriden in the Container. Obviously, a plain 10117 // non-container components don't need to handle validation. 10118 } 10119 10120 final boolean isMixingNeeded() { 10121 if (SunToolkit.getSunAwtDisableMixing()) { 10122 if (mixingLog.isLoggable(PlatformLogger.Level.FINEST)) { 10123 mixingLog.finest("this = " + this + "; Mixing disabled via sun.awt.disableMixing"); 10124 } 10125 return false; 10126 } 10127 if (!areBoundsValid()) { 10128 if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) { 10129 mixingLog.fine("this = " + this + "; areBoundsValid = " + areBoundsValid()); 10130 } 10131 return false; 10132 } 10133 Window window = getContainingWindow(); 10134 if (window != null) { 10135 if (!window.hasHeavyweightDescendants() || !window.hasLightweightDescendants() || window.isDisposing()) { 10136 if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) { 10137 mixingLog.fine("containing window = " + window + 10138 "; has h/w descendants = " + window.hasHeavyweightDescendants() + 10139 "; has l/w descendants = " + window.hasLightweightDescendants() + 10140 "; disposing = " + window.isDisposing()); 10141 } 10142 return false; 10143 } 10144 } else { 10145 if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) { 10146 mixingLog.fine("this = " + this + "; containing window is null"); 10147 } 10148 return false; 10149 } 10150 return true; 10151 } 10152 10153 // ****************** END OF MIXING CODE ******************************** 10154 10155 // Note that the method is overriden in the Window class, 10156 // a window doesn't need to be updated in the Z-order. 10157 void updateZOrder() { 10158 peer.setZOrder(getHWPeerAboveMe()); 10159 } 10160 10161 } 10162