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