47 import java.io.ObjectOutputStream; 48 import java.io.ObjectInputStream; 49 import java.io.IOException; 50 import java.io.ObjectInputValidation; 51 import java.io.InvalidObjectException; 52 import java.util.concurrent.atomic.AtomicBoolean; 53 54 import javax.swing.border.*; 55 import javax.swing.event.*; 56 import javax.swing.plaf.*; 57 import static javax.swing.ClientPropertyKey.*; 58 import javax.accessibility.*; 59 60 import sun.awt.AWTAccessor; 61 import sun.awt.SunToolkit; 62 import sun.swing.SwingUtilities2; 63 import sun.swing.UIClientPropertyKey; 64 65 /** 66 * The base class for all Swing components except top-level containers. 67 * To use a component that inherits from <code>JComponent</code>, 68 * you must place the component in a containment hierarchy 69 * whose root is a top-level Swing container. 70 * Top-level Swing containers -- 71 * such as <code>JFrame</code>, <code>JDialog</code>, 72 * and <code>JApplet</code> -- 73 * are specialized components 74 * that provide a place for other Swing components to paint themselves. 75 * For an explanation of containment hierarchies, see 76 * <a 77 href="http://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html">Swing Components and the Containment Hierarchy</a>, 78 * a section in <em>The Java Tutorial</em>. 79 * 80 * <p> 81 * The <code>JComponent</code> class provides: 82 * <ul> 83 * <li>The base class for both standard and custom components 84 * that use the Swing architecture. 85 * <li>A "pluggable look and feel" (L&F) that can be specified by the 86 * programmer or (optionally) selected by the user at runtime. 87 * The look and feel for each component is provided by a 88 * <em>UI delegate</em> -- an object that descends from 89 * {@link javax.swing.plaf.ComponentUI}. 90 * See <a 91 * href="http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html">How 92 * to Set the Look and Feel</a> 93 * in <em>The Java Tutorial</em> 94 * for more information. 95 * <li>Comprehensive keystroke handling. 96 * See the document <a 97 * href="http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html">How to Use Key Bindings</a>, 98 * an article in <em>The Java Tutorial</em>, 99 * for more information. 100 * <li>Support for tool tips -- 101 * short descriptions that pop up when the cursor lingers 102 * over a component. 103 * See <a 104 * href="http://docs.oracle.com/javase/tutorial/uiswing/components/tooltip.html">How 105 * to Use Tool Tips</a> 106 * in <em>The Java Tutorial</em> 107 * for more information. 108 * <li>Support for accessibility. 109 * <code>JComponent</code> contains all of the methods in the 110 * <code>Accessible</code> interface, 111 * but it doesn't actually implement the interface. That is the 112 * responsibility of the individual classes 113 * that extend <code>JComponent</code>. 114 * <li>Support for component-specific properties. 115 * With the {@link #putClientProperty} 116 * and {@link #getClientProperty} methods, 117 * you can associate name-object pairs 118 * with any object that descends from <code>JComponent</code>. 119 * <li>An infrastructure for painting 120 * that includes double buffering and support for borders. 121 * For more information see <a 122 * href="http://www.oracle.com/technetwork/java/painting-140037.html#swing">Painting</a> and 123 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/border.html">How 124 * to Use Borders</a>, 125 * both of which are sections in <em>The Java Tutorial</em>. 126 * </ul> 127 * For more information on these subjects, see the 128 * <a href="package-summary.html#package_description">Swing package description</a> 129 * and <em>The Java Tutorial</em> section 130 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/jcomponent.html">The JComponent Class</a>. 131 * <p> 132 * <code>JComponent</code> and its subclasses document default values 133 * for certain properties. For example, <code>JTable</code> documents the 134 * default row height as 16. Each <code>JComponent</code> subclass 135 * that has a <code>ComponentUI</code> will create the 136 * <code>ComponentUI</code> as part of its constructor. In order 137 * to provide a particular look and feel each 138 * <code>ComponentUI</code> may set properties back on the 139 * <code>JComponent</code> that created it. For example, a custom 140 * look and feel may require <code>JTable</code>s to have a row 141 * height of 24. The documented defaults are the value of a property 142 * BEFORE the <code>ComponentUI</code> has been installed. If you 143 * need a specific value for a particular property you should 144 * explicitly set it. 145 * <p> 146 * In release 1.4, the focus subsystem was rearchitected. 147 * For more information, see 148 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> 149 * How to Use the Focus Subsystem</a>, 150 * a section in <em>The Java Tutorial</em>. 151 * <p> 152 * <strong>Warning:</strong> Swing is not thread safe. For more 153 * information see <a 154 * href="package-summary.html#threading">Swing's Threading 155 * Policy</a>. 156 * <p> 157 * <strong>Warning:</strong> 158 * Serialized objects of this class will not be compatible with 159 * future Swing releases. The current serialization support is 160 * appropriate for short term storage or RMI between applications running 161 * the same version of Swing. As of 1.4, support for long term storage 162 * of all JavaBeans™ 163 * has been added to the <code>java.beans</code> package. 164 * Please see {@link java.beans.XMLEncoder}. 165 * 166 * @see KeyStroke 167 * @see Action 168 * @see #setBorder 169 * @see #registerKeyboardAction 170 * @see JOptionPane 171 * @see #setDebugGraphicsOptions 172 * @see #setToolTipText 173 * @see #setAutoscrolls 174 * 175 * @author Hans Muller 176 * @author Arnaud Weber 177 * @since 1.2 178 */ 179 @SuppressWarnings("serial") // Same-version serialization only 180 public abstract class JComponent extends Container implements Serializable, 181 TransferHandler.HasGetTransferHandler 182 { 183 /** 239 /** The look and feel delegate for this component. */ 240 protected transient ComponentUI ui; 241 /** A list of event listeners for this component. */ 242 protected EventListenerList listenerList = new EventListenerList(); 243 244 private transient ArrayTable clientProperties; 245 private VetoableChangeSupport vetoableChangeSupport; 246 /** 247 * Whether or not autoscroll has been enabled. 248 */ 249 private boolean autoscrolls; 250 private Border border; 251 private int flags; 252 253 /* Input verifier for this component */ 254 private InputVerifier inputVerifier = null; 255 256 private boolean verifyInputWhenFocusTarget = true; 257 258 /** 259 * Set in <code>_paintImmediately</code>. 260 * Will indicate the child that initiated the painting operation. 261 * If <code>paintingChild</code> is opaque, no need to paint 262 * any child components after <code>paintingChild</code>. 263 * Test used in <code>paintChildren</code>. 264 */ 265 transient Component paintingChild; 266 267 /** 268 * Constant used for <code>registerKeyboardAction</code> that 269 * means that the command should be invoked when 270 * the component has the focus. 271 */ 272 public static final int WHEN_FOCUSED = 0; 273 274 /** 275 * Constant used for <code>registerKeyboardAction</code> that 276 * means that the command should be invoked when the receiving 277 * component is an ancestor of the focused component or is 278 * itself the focused component. 279 */ 280 public static final int WHEN_ANCESTOR_OF_FOCUSED_COMPONENT = 1; 281 282 /** 283 * Constant used for <code>registerKeyboardAction</code> that 284 * means that the command should be invoked when 285 * the receiving component is in the window that has the focus 286 * or is itself the focused component. 287 */ 288 public static final int WHEN_IN_FOCUSED_WINDOW = 2; 289 290 /** 291 * Constant used by some of the APIs to mean that no condition is defined. 292 */ 293 public static final int UNDEFINED_CONDITION = -1; 294 295 /** 296 * The key used by <code>JComponent</code> to access keyboard bindings. 297 */ 298 private static final String KEYBOARD_BINDINGS_KEY = "_KeyboardBindings"; 299 300 /** 301 * An array of <code>KeyStroke</code>s used for 302 * <code>WHEN_IN_FOCUSED_WINDOW</code> are stashed 303 * in the client properties under this string. 304 */ 305 private static final String WHEN_IN_FOCUSED_WINDOW_BINDINGS = "_WhenInFocusedWindow"; 306 307 /** 308 * The comment to display when the cursor is over the component, 309 * also known as a "value tip", "flyover help", or "flyover label". 310 */ 311 public static final String TOOL_TIP_TEXT_KEY = "ToolTipText"; 312 313 private static final String NEXT_FOCUS = "nextFocus"; 314 315 /** 316 * <code>JPopupMenu</code> assigned to this component 317 * and all of its children 318 */ 319 private JPopupMenu popupMenu; 320 321 /** Private flags **/ 322 private static final int IS_DOUBLE_BUFFERED = 0; 323 private static final int ANCESTOR_USING_BUFFER = 1; 324 private static final int IS_PAINTING_TILE = 2; 325 private static final int IS_OPAQUE = 3; 326 private static final int KEY_EVENTS_ENABLED = 4; 327 private static final int FOCUS_INPUTMAP_CREATED = 5; 328 private static final int ANCESTOR_INPUTMAP_CREATED = 6; 329 private static final int WIF_INPUTMAP_CREATED = 7; 330 private static final int ACTIONMAP_CREATED = 8; 331 private static final int CREATED_DOUBLE_BUFFER = 9; 332 // bit 10 is free 333 private static final int IS_PRINTING = 11; 334 private static final int IS_PRINTING_ALL = 12; 335 private static final int IS_REPAINTING = 13; 336 /** Bits 14-21 are used to handle nested writeObject calls. **/ 340 private static final int RESERVED_3 = 17; 341 private static final int RESERVED_4 = 18; 342 private static final int RESERVED_5 = 19; 343 private static final int RESERVED_6 = 20; 344 private static final int WRITE_OBJ_COUNTER_LAST = 21; 345 346 private static final int REQUEST_FOCUS_DISABLED = 22; 347 private static final int INHERITS_POPUP_MENU = 23; 348 private static final int OPAQUE_SET = 24; 349 private static final int AUTOSCROLLS_SET = 25; 350 private static final int FOCUS_TRAVERSAL_KEYS_FORWARD_SET = 26; 351 private static final int FOCUS_TRAVERSAL_KEYS_BACKWARD_SET = 27; 352 353 private transient AtomicBoolean revalidateRunnableScheduled = new AtomicBoolean(false); 354 355 /** 356 * Temporary rectangles. 357 */ 358 private static java.util.List<Rectangle> tempRectangles = new java.util.ArrayList<Rectangle>(11); 359 360 /** Used for <code>WHEN_FOCUSED</code> bindings. */ 361 private InputMap focusInputMap; 362 /** Used for <code>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT</code> bindings. */ 363 private InputMap ancestorInputMap; 364 /** Used for <code>WHEN_IN_FOCUSED_KEY</code> bindings. */ 365 private ComponentInputMap windowInputMap; 366 367 /** ActionMap. */ 368 private ActionMap actionMap; 369 370 /** Key used to store the default locale in an AppContext **/ 371 private static final String defaultLocale = "JComponent.defaultLocale"; 372 373 private static Component componentObtainingGraphicsFrom; 374 private static Object componentObtainingGraphicsFromLock = new 375 StringBuilder("componentObtainingGraphicsFrom"); 376 377 /** 378 * AA text hints. 379 */ 380 private transient Object aaHint; 381 private transient Object lcdRenderingHint; 382 383 static Graphics safelyGetGraphics(Component c) { 384 return safelyGetGraphics(c, SwingUtilities.getRoot(c)); 397 if (!JComponent.isComponentObtainingGraphicsFrom(root)) { 398 JRootPane rootPane = ((RootPaneContainer)root).getRootPane(); 399 if (rootPane != null) { 400 rootPane.disableTrueDoubleBuffering(); 401 } 402 } 403 } 404 405 406 /** 407 * Returns true if {@code c} is the component the graphics is being 408 * requested of. This is intended for use when getGraphics is invoked. 409 */ 410 private static boolean isComponentObtainingGraphicsFrom(Component c) { 411 synchronized(componentObtainingGraphicsFromLock) { 412 return (componentObtainingGraphicsFrom == c); 413 } 414 } 415 416 /** 417 * Returns the Set of <code>KeyStroke</code>s to use if the component 418 * is managing focus for forward focus traversal. 419 */ 420 static Set<KeyStroke> getManagingFocusForwardTraversalKeys() { 421 synchronized(JComponent.class) { 422 if (managingFocusForwardTraversalKeys == null) { 423 managingFocusForwardTraversalKeys = new HashSet<KeyStroke>(1); 424 managingFocusForwardTraversalKeys.add( 425 KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 426 InputEvent.CTRL_MASK)); 427 } 428 } 429 return managingFocusForwardTraversalKeys; 430 } 431 432 /** 433 * Returns the Set of <code>KeyStroke</code>s to use if the component 434 * is managing focus for backward focus traversal. 435 */ 436 static Set<KeyStroke> getManagingFocusBackwardTraversalKeys() { 437 synchronized(JComponent.class) { 438 if (managingFocusBackwardTraversalKeys == null) { 439 managingFocusBackwardTraversalKeys = new HashSet<KeyStroke>(1); 440 managingFocusBackwardTraversalKeys.add( 441 KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 442 InputEvent.SHIFT_MASK | 443 InputEvent.CTRL_MASK)); 444 } 445 } 446 return managingFocusBackwardTraversalKeys; 447 } 448 449 private static Rectangle fetchRectangle() { 450 synchronized(tempRectangles) { 451 Rectangle rect; 452 int size = tempRectangles.size(); 453 if (size > 0) { 454 rect = tempRectangles.remove(size - 1); 455 } 456 else { 457 rect = new Rectangle(0, 0, 0, 0); 458 } 459 return rect; 460 } 461 } 462 463 private static void recycleRectangle(Rectangle rect) { 464 synchronized(tempRectangles) { 465 tempRectangles.add(rect); 466 } 467 } 468 469 /** 470 * Sets whether or not <code>getComponentPopupMenu</code> should delegate 471 * to the parent if this component does not have a <code>JPopupMenu</code> 472 * assigned to it. 473 * <p> 474 * The default value for this is false, but some <code>JComponent</code> 475 * subclasses that are implemented as a number of <code>JComponent</code>s 476 * may set this to true. 477 * <p> 478 * This is a bound property. 479 * 480 * @param value whether or not the JPopupMenu is inherited 481 * @see #setComponentPopupMenu 482 * @beaninfo 483 * bound: true 484 * description: Whether or not the JPopupMenu is inherited 485 * @since 1.5 486 */ 487 public void setInheritsPopupMenu(boolean value) { 488 boolean oldValue = getFlag(INHERITS_POPUP_MENU); 489 setFlag(INHERITS_POPUP_MENU, value); 490 firePropertyChange("inheritsPopupMenu", oldValue, value); 491 } 492 493 /** 494 * Returns true if the JPopupMenu should be inherited from the parent. 495 * 496 * @return true if the JPopupMenu should be inherited from the parent 497 * @see #setComponentPopupMenu 498 * @since 1.5 499 */ 500 public boolean getInheritsPopupMenu() { 501 return getFlag(INHERITS_POPUP_MENU); 502 } 503 504 /** 505 * Sets the <code>JPopupMenu</code> for this <code>JComponent</code>. 506 * The UI is responsible for registering bindings and adding the necessary 507 * listeners such that the <code>JPopupMenu</code> will be shown at 508 * the appropriate time. When the <code>JPopupMenu</code> is shown 509 * depends upon the look and feel: some may show it on a mouse event, 510 * some may enable a key binding. 511 * <p> 512 * If <code>popup</code> is null, and <code>getInheritsPopupMenu</code> 513 * returns true, then <code>getComponentPopupMenu</code> will be delegated 514 * to the parent. This provides for a way to make all child components 515 * inherit the popupmenu of the parent. 516 * <p> 517 * This is a bound property. 518 * 519 * @param popup - the popup that will be assigned to this component 520 * may be null 521 * @see #getComponentPopupMenu 522 * @beaninfo 523 * bound: true 524 * preferred: true 525 * description: Popup to show 526 * @since 1.5 527 */ 528 public void setComponentPopupMenu(JPopupMenu popup) { 529 if(popup != null) { 530 enableEvents(AWTEvent.MOUSE_EVENT_MASK); 531 } 532 JPopupMenu oldPopup = this.popupMenu; 533 this.popupMenu = popup; 534 firePropertyChange("componentPopupMenu", oldPopup, popup); 535 } 536 537 /** 538 * Returns <code>JPopupMenu</code> that assigned for this component. 539 * If this component does not have a <code>JPopupMenu</code> assigned 540 * to it and <code>getInheritsPopupMenu</code> is true, this 541 * will return <code>getParent().getComponentPopupMenu()</code> (assuming 542 * the parent is valid.) 543 * 544 * @return <code>JPopupMenu</code> assigned for this component 545 * or <code>null</code> if no popup assigned 546 * @see #setComponentPopupMenu 547 * @since 1.5 548 */ 549 public JPopupMenu getComponentPopupMenu() { 550 551 if(!getInheritsPopupMenu()) { 552 return popupMenu; 553 } 554 555 if(popupMenu == null) { 556 // Search parents for its popup 557 Container parent = getParent(); 558 while (parent != null) { 559 if(parent instanceof JComponent) { 560 return ((JComponent)parent).getComponentPopupMenu(); 561 } 562 if(parent instanceof Window || 563 parent instanceof Applet) { 564 // Reached toplevel, break and return null 565 break; 566 } 567 parent = parent.getParent(); 568 } 569 return null; 570 } 571 572 return popupMenu; 573 } 574 575 /** 576 * Default <code>JComponent</code> constructor. This constructor does 577 * very little initialization beyond calling the <code>Container</code> 578 * constructor. For example, the initial layout manager is 579 * <code>null</code>. It does, however, set the component's locale 580 * property to the value returned by 581 * <code>JComponent.getDefaultLocale</code>. 582 * 583 * @see #getDefaultLocale 584 */ 585 public JComponent() { 586 super(); 587 // We enable key events on all JComponents so that accessibility 588 // bindings will work everywhere. This is a partial fix to BugID 589 // 4282211. 590 enableEvents(AWTEvent.KEY_EVENT_MASK); 591 if (isManagingFocus()) { 592 LookAndFeel.installProperty(this, 593 "focusTraversalKeysForward", 594 getManagingFocusForwardTraversalKeys()); 595 LookAndFeel.installProperty(this, 596 "focusTraversalKeysBackward", 597 getManagingFocusBackwardTraversalKeys()); 598 } 599 600 super.setLocale( JComponent.getDefaultLocale() ); 601 } 602 603 604 /** 605 * Resets the UI property to a value from the current look and feel. 606 * <code>JComponent</code> subclasses must override this method 607 * like this: 608 * <pre> 609 * public void updateUI() { 610 * setUI((SliderUI)UIManager.getUI(this); 611 * } 612 * </pre> 613 * 614 * @see #setUI 615 * @see UIManager#getLookAndFeel 616 * @see UIManager#getUI 617 */ 618 public void updateUI() {} 619 620 /** 621 * Returns the look and feel delegate that renders this component. 622 * 623 * @return the {@code ComponentUI} object that renders this component 624 * @since 1.9 625 */ 626 public ComponentUI getUI() { 627 return ui; 628 } 629 630 /** 631 * Sets the look and feel delegate for this component. 632 * <code>JComponent</code> subclasses generally override this method 633 * to narrow the argument type. For example, in <code>JSlider</code>: 634 * <pre> 635 * public void setUI(SliderUI newUI) { 636 * super.setUI(newUI); 637 * } 638 * </pre> 639 * <p> 640 * Additionally <code>JComponent</code> subclasses must provide a 641 * <code>getUI</code> method that returns the correct type. For example: 642 * <pre> 643 * public SliderUI getUI() { 644 * return (SliderUI)ui; 645 * } 646 * </pre> 647 * 648 * @param newUI the new UI delegate 649 * @see #updateUI 650 * @see UIManager#getLookAndFeel 651 * @see UIManager#getUI 652 * @beaninfo 653 * bound: true 654 * hidden: true 655 * attribute: visualUpdate true 656 * description: The component's look and feel delegate. 657 */ 658 protected void setUI(ComponentUI newUI) { 659 /* We do not check that the UI instance is different 660 * before allowing the switch in order to enable the 661 * same UI instance *with different default settings* 689 if (ui != null) { 690 ui.uninstallUI(this); 691 //clean UIClientPropertyKeys from client properties 692 if (clientProperties != null) { 693 synchronized(clientProperties) { 694 Object[] clientPropertyKeys = 695 clientProperties.getKeys(null); 696 if (clientPropertyKeys != null) { 697 for (Object key : clientPropertyKeys) { 698 if (key instanceof UIClientPropertyKey) { 699 putClientProperty(key, null); 700 } 701 } 702 } 703 } 704 } 705 } 706 } 707 708 /** 709 * Returns the <code>UIDefaults</code> key used to 710 * look up the name of the <code>swing.plaf.ComponentUI</code> 711 * class that defines the look and feel 712 * for this component. Most applications will never need to 713 * call this method. Subclasses of <code>JComponent</code> that support 714 * pluggable look and feel should override this method to 715 * return a <code>UIDefaults</code> key that maps to the 716 * <code>ComponentUI</code> subclass that defines their look and feel. 717 * 718 * @return the <code>UIDefaults</code> key for a 719 * <code>ComponentUI</code> subclass 720 * @see UIDefaults#getUI 721 * @beaninfo 722 * expert: true 723 * description: UIClassID 724 */ 725 public String getUIClassID() { 726 return uiClassID; 727 } 728 729 730 /** 731 * Returns the graphics object used to paint this component. 732 * If <code>DebugGraphics</code> is turned on we create a new 733 * <code>DebugGraphics</code> object if necessary. 734 * Otherwise we just configure the 735 * specified graphics object's foreground and font. 736 * 737 * @param g the original <code>Graphics</code> object 738 * @return a <code>Graphics</code> object configured for this component 739 */ 740 protected Graphics getComponentGraphics(Graphics g) { 741 Graphics componentGraphics = g; 742 if (ui != null && DEBUG_GRAPHICS_LOADED) { 743 if ((DebugGraphics.debugComponentCount() != 0) && 744 (shouldDebugGraphics() != 0) && 745 !(g instanceof DebugGraphics)) { 746 componentGraphics = new DebugGraphics(g,this); 747 } 748 } 749 componentGraphics.setColor(getForeground()); 750 componentGraphics.setFont(getFont()); 751 752 return componentGraphics; 753 } 754 755 756 /** 757 * Calls the UI delegate's paint method, if the UI delegate 758 * is non-<code>null</code>. We pass the delegate a copy of the 759 * <code>Graphics</code> object to protect the rest of the 760 * paint code from irrevocable changes 761 * (for example, <code>Graphics.translate</code>). 762 * <p> 763 * If you override this in a subclass you should not make permanent 764 * changes to the passed in <code>Graphics</code>. For example, you 765 * should not alter the clip <code>Rectangle</code> or modify the 766 * transform. If you need to do these operations you may find it 767 * easier to create a new <code>Graphics</code> from the passed in 768 * <code>Graphics</code> and manipulate it. Further, if you do not 769 * invoker super's implementation you must honor the opaque property, 770 * that is 771 * if this component is opaque, you must completely fill in the background 772 * in a non-opaque color. If you do not honor the opaque property you 773 * will likely see visual artifacts. 774 * <p> 775 * The passed in <code>Graphics</code> object might 776 * have a transform other than the identify transform 777 * installed on it. In this case, you might get 778 * unexpected results if you cumulatively apply 779 * another transform. 780 * 781 * @param g the <code>Graphics</code> object to protect 782 * @see #paint 783 * @see ComponentUI 784 */ 785 protected void paintComponent(Graphics g) { 786 if (ui != null) { 787 Graphics scratchGraphics = (g == null) ? null : g.create(); 788 try { 789 ui.update(scratchGraphics, this); 790 } 791 finally { 792 scratchGraphics.dispose(); 793 } 794 } 795 } 796 797 /** 798 * Paints this component's children. 799 * If <code>shouldUseBuffer</code> is true, 800 * no component ancestor has a buffer and 801 * the component children can use a buffer if they have one. 802 * Otherwise, one ancestor has a buffer currently in use and children 803 * should not use a buffer to paint. 804 * @param g the <code>Graphics</code> context in which to paint 805 * @see #paint 806 * @see java.awt.Container#paint 807 */ 808 protected void paintChildren(Graphics g) { 809 Graphics sg = g; 810 811 synchronized(getTreeLock()) { 812 int i = getComponentCount() - 1; 813 if (i < 0) { 814 return; 815 } 816 // If we are only to paint to a specific child, determine 817 // its index. 818 if (paintingChild != null && 819 (paintingChild instanceof JComponent) && 820 paintingChild.isOpaque()) { 821 for (; i >= 0; i--) { 822 if (getComponent(i) == paintingChild){ 823 break; 824 } 924 cg.dispose(); 925 if(shouldSetFlagBack) { 926 ((JComponent)comp).setFlag( 927 ANCESTOR_USING_BUFFER,false); 928 ((JComponent)comp).setFlag( 929 IS_PAINTING_TILE,false); 930 } 931 } 932 } 933 } 934 935 } 936 recycleRectangle(tmpRect); 937 } 938 } 939 940 /** 941 * Paints the component's border. 942 * <p> 943 * If you override this in a subclass you should not make permanent 944 * changes to the passed in <code>Graphics</code>. For example, you 945 * should not alter the clip <code>Rectangle</code> or modify the 946 * transform. If you need to do these operations you may find it 947 * easier to create a new <code>Graphics</code> from the passed in 948 * <code>Graphics</code> and manipulate it. 949 * 950 * @param g the <code>Graphics</code> context in which to paint 951 * 952 * @see #paint 953 * @see #setBorder 954 */ 955 protected void paintBorder(Graphics g) { 956 Border border = getBorder(); 957 if (border != null) { 958 border.paintBorder(this, g, 0, 0, getWidth(), getHeight()); 959 } 960 } 961 962 963 /** 964 * Calls <code>paint</code>. Doesn't clear the background but see 965 * <code>ComponentUI.update</code>, which is called by 966 * <code>paintComponent</code>. 967 * 968 * @param g the <code>Graphics</code> context in which to paint 969 * @see #paint 970 * @see #paintComponent 971 * @see javax.swing.plaf.ComponentUI 972 */ 973 public void update(Graphics g) { 974 paint(g); 975 } 976 977 978 /** 979 * Invoked by Swing to draw components. 980 * Applications should not invoke <code>paint</code> directly, 981 * but should instead use the <code>repaint</code> method to 982 * schedule the component for redrawing. 983 * <p> 984 * This method actually delegates the work of painting to three 985 * protected methods: <code>paintComponent</code>, 986 * <code>paintBorder</code>, 987 * and <code>paintChildren</code>. They're called in the order 988 * listed to ensure that children appear on top of component itself. 989 * Generally speaking, the component and its children should not 990 * paint in the insets area allocated to the border. Subclasses can 991 * just override this method, as always. A subclass that just 992 * wants to specialize the UI (look and feel) delegate's 993 * <code>paint</code> method should just override 994 * <code>paintComponent</code>. 995 * 996 * @param g the <code>Graphics</code> context in which to paint 997 * @see #paintComponent 998 * @see #paintBorder 999 * @see #paintChildren 1000 * @see #getComponentGraphics 1001 * @see #repaint 1002 */ 1003 public void paint(Graphics g) { 1004 boolean shouldClearPaintFlags = false; 1005 1006 if ((getWidth() <= 0) || (getHeight() <= 0)) { 1007 return; 1008 } 1009 1010 Graphics componentGraphics = getComponentGraphics(g); 1011 Graphics co = componentGraphics.create(); 1012 try { 1013 RepaintManager repaintManager = RepaintManager.currentManager(this); 1014 Rectangle clipRect = co.getClipBounds(); 1015 int clipX; 1016 int clipY; 1126 Container parent; 1127 for(parent = getParent() ; parent != null ; parent = 1128 parent.getParent()) { 1129 if(parent instanceof JComponent) { 1130 jparent = (JComponent) parent; 1131 if(jparent.getFlag(ANCESTOR_USING_BUFFER)) 1132 setFlag(ANCESTOR_USING_BUFFER, true); 1133 if(jparent.getFlag(IS_PAINTING_TILE)) 1134 setFlag(IS_PAINTING_TILE, true); 1135 if(jparent.getFlag(IS_PRINTING)) 1136 setFlag(IS_PRINTING, true); 1137 if(jparent.getFlag(IS_PRINTING_ALL)) 1138 setFlag(IS_PRINTING_ALL, true); 1139 break; 1140 } 1141 } 1142 } 1143 1144 /** 1145 * Invoke this method to print the component. This method invokes 1146 * <code>print</code> on the component. 1147 * 1148 * @param g the <code>Graphics</code> context in which to paint 1149 * @see #print 1150 * @see #printComponent 1151 * @see #printBorder 1152 * @see #printChildren 1153 */ 1154 public void printAll(Graphics g) { 1155 setFlag(IS_PRINTING_ALL, true); 1156 try { 1157 print(g); 1158 } 1159 finally { 1160 setFlag(IS_PRINTING_ALL, false); 1161 } 1162 } 1163 1164 /** 1165 * Invoke this method to print the component to the specified 1166 * <code>Graphics</code>. This method will result in invocations 1167 * of <code>printComponent</code>, <code>printBorder</code> and 1168 * <code>printChildren</code>. It is recommended that you override 1169 * one of the previously mentioned methods rather than this one if 1170 * your intention is to customize the way printing looks. However, 1171 * it can be useful to override this method should you want to prepare 1172 * state before invoking the superclass behavior. As an example, 1173 * if you wanted to change the component's background color before 1174 * printing, you could do the following: 1175 * <pre> 1176 * public void print(Graphics g) { 1177 * Color orig = getBackground(); 1178 * setBackground(Color.WHITE); 1179 * 1180 * // wrap in try/finally so that we always restore the state 1181 * try { 1182 * super.print(g); 1183 * } finally { 1184 * setBackground(orig); 1185 * } 1186 * } 1187 * </pre> 1188 * <p> 1189 * Alternatively, or for components that delegate painting to other objects, 1190 * you can query during painting whether or not the component is in the 1191 * midst of a print operation. The <code>isPaintingForPrint</code> method provides 1192 * this ability and its return value will be changed by this method: to 1193 * <code>true</code> immediately before rendering and to <code>false</code> 1194 * immediately after. With each change a property change event is fired on 1195 * this component with the name <code>"paintingForPrint"</code>. 1196 * <p> 1197 * This method sets the component's state such that the double buffer 1198 * will not be used: painting will be done directly on the passed in 1199 * <code>Graphics</code>. 1200 * 1201 * @param g the <code>Graphics</code> context in which to paint 1202 * @see #printComponent 1203 * @see #printBorder 1204 * @see #printChildren 1205 * @see #isPaintingForPrint 1206 */ 1207 public void print(Graphics g) { 1208 setFlag(IS_PRINTING, true); 1209 firePropertyChange("paintingForPrint", false, true); 1210 try { 1211 paint(g); 1212 } 1213 finally { 1214 setFlag(IS_PRINTING, false); 1215 firePropertyChange("paintingForPrint", true, false); 1216 } 1217 } 1218 1219 /** 1220 * This is invoked during a printing operation. This is implemented to 1221 * invoke <code>paintComponent</code> on the component. Override this 1222 * if you wish to add special painting behavior when printing. 1223 * 1224 * @param g the <code>Graphics</code> context in which to paint 1225 * @see #print 1226 * @since 1.3 1227 */ 1228 protected void printComponent(Graphics g) { 1229 paintComponent(g); 1230 } 1231 1232 /** 1233 * Prints this component's children. This is implemented to invoke 1234 * <code>paintChildren</code> on the component. Override this if you 1235 * wish to print the children differently than painting. 1236 * 1237 * @param g the <code>Graphics</code> context in which to paint 1238 * @see #print 1239 * @since 1.3 1240 */ 1241 protected void printChildren(Graphics g) { 1242 paintChildren(g); 1243 } 1244 1245 /** 1246 * Prints the component's border. This is implemented to invoke 1247 * <code>paintBorder</code> on the component. Override this if you 1248 * wish to print the border differently that it is painted. 1249 * 1250 * @param g the <code>Graphics</code> context in which to paint 1251 * @see #print 1252 * @since 1.3 1253 */ 1254 protected void printBorder(Graphics g) { 1255 paintBorder(g); 1256 } 1257 1258 /** 1259 * Returns true if the component is currently painting a tile. 1260 * If this method returns true, paint will be called again for another 1261 * tile. This method returns false if you are not painting a tile or 1262 * if the last tile is painted. 1263 * Use this method to keep some state you might need between tiles. 1264 * 1265 * @return true if the component is currently painting a tile, 1266 * false otherwise 1267 */ 1268 public boolean isPaintingTile() { 1269 return getFlag(IS_PAINTING_TILE); 1270 } 1271 1272 /** 1273 * Returns <code>true</code> if the current painting operation on this 1274 * component is part of a <code>print</code> operation. This method is 1275 * useful when you want to customize what you print versus what you show 1276 * on the screen. 1277 * <p> 1278 * You can detect changes in the value of this property by listening for 1279 * property change events on this component with name 1280 * <code>"paintingForPrint"</code>. 1281 * <p> 1282 * Note: This method provides complimentary functionality to that provided 1283 * by other high level Swing printing APIs. However, it deals strictly with 1284 * painting and should not be confused as providing information on higher 1285 * level print processes. For example, a {@link javax.swing.JTable#print()} 1286 * operation doesn't necessarily result in a continuous rendering of the 1287 * full component, and the return value of this method can change multiple 1288 * times during that operation. It is even possible for the component to be 1289 * painted to the screen while the printing process is ongoing. In such a 1290 * case, the return value of this method is <code>true</code> when, and only 1291 * when, the table is being painted as part of the printing process. 1292 * 1293 * @return true if the current painting operation on this component 1294 * is part of a print operation 1295 * @see #print 1296 * @since 1.6 1297 */ 1298 public final boolean isPaintingForPrint() { 1299 return getFlag(IS_PRINTING); 1300 } 1301 1302 /** 1303 * In release 1.4, the focus subsystem was rearchitected. 1304 * For more information, see 1305 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> 1306 * How to Use the Focus Subsystem</a>, 1307 * a section in <em>The Java Tutorial</em>. 1308 * <p> 1309 * Changes this <code>JComponent</code>'s focus traversal keys to 1310 * CTRL+TAB and CTRL+SHIFT+TAB. Also prevents 1311 * <code>SortingFocusTraversalPolicy</code> from considering descendants 1312 * of this JComponent when computing a focus traversal cycle. 1313 * 1314 * @return false 1315 * @see java.awt.Component#setFocusTraversalKeys 1316 * @see SortingFocusTraversalPolicy 1317 * @deprecated As of 1.4, replaced by 1318 * <code>Component.setFocusTraversalKeys(int, Set)</code> and 1319 * <code>Container.setFocusCycleRoot(boolean)</code>. 1320 */ 1321 @Deprecated 1322 public boolean isManagingFocus() { 1323 return false; 1324 } 1325 1326 private void registerNextFocusableComponent() { 1327 registerNextFocusableComponent(getNextFocusableComponent()); 1328 } 1329 1330 private void registerNextFocusableComponent(Component 1331 nextFocusableComponent) { 1332 if (nextFocusableComponent == null) { 1333 return; 1334 } 1335 1336 Container nearestRoot = 1337 (isFocusCycleRoot()) ? this : getFocusCycleRootAncestor(); 1338 FocusTraversalPolicy policy = nearestRoot.getFocusTraversalPolicy(); 1339 if (!(policy instanceof LegacyGlueFocusTraversalPolicy)) { 1352 1353 Container nearestRoot = 1354 (isFocusCycleRoot()) ? this : getFocusCycleRootAncestor(); 1355 if (nearestRoot == null) { 1356 return; 1357 } 1358 FocusTraversalPolicy policy = nearestRoot.getFocusTraversalPolicy(); 1359 if (policy instanceof LegacyGlueFocusTraversalPolicy) { 1360 ((LegacyGlueFocusTraversalPolicy)policy). 1361 unsetNextFocusableComponent(this, nextFocusableComponent); 1362 } 1363 } 1364 1365 /** 1366 * In release 1.4, the focus subsystem was rearchitected. 1367 * For more information, see 1368 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> 1369 * How to Use the Focus Subsystem</a>, 1370 * a section in <em>The Java Tutorial</em>. 1371 * <p> 1372 * Overrides the default <code>FocusTraversalPolicy</code> for this 1373 * <code>JComponent</code>'s focus traversal cycle by unconditionally 1374 * setting the specified <code>Component</code> as the next 1375 * <code>Component</code> in the cycle, and this <code>JComponent</code> 1376 * as the specified <code>Component</code>'s previous 1377 * <code>Component</code> in the cycle. 1378 * 1379 * @param aComponent the <code>Component</code> that should follow this 1380 * <code>JComponent</code> in the focus traversal cycle 1381 * 1382 * @see #getNextFocusableComponent 1383 * @see java.awt.FocusTraversalPolicy 1384 * @deprecated As of 1.4, replaced by <code>FocusTraversalPolicy</code> 1385 */ 1386 @Deprecated 1387 public void setNextFocusableComponent(Component aComponent) { 1388 boolean displayable = isDisplayable(); 1389 if (displayable) { 1390 deregisterNextFocusableComponent(); 1391 } 1392 putClientProperty(NEXT_FOCUS, aComponent); 1393 if (displayable) { 1394 registerNextFocusableComponent(aComponent); 1395 } 1396 } 1397 1398 /** 1399 * In release 1.4, the focus subsystem was rearchitected. 1400 * For more information, see 1401 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> 1402 * How to Use the Focus Subsystem</a>, 1403 * a section in <em>The Java Tutorial</em>. 1404 * <p> 1405 * Returns the <code>Component</code> set by a prior call to 1406 * <code>setNextFocusableComponent(Component)</code> on this 1407 * <code>JComponent</code>. 1408 * 1409 * @return the <code>Component</code> that will follow this 1410 * <code>JComponent</code> in the focus traversal cycle, or 1411 * <code>null</code> if none has been explicitly specified 1412 * 1413 * @see #setNextFocusableComponent 1414 * @deprecated As of 1.4, replaced by <code>FocusTraversalPolicy</code>. 1415 */ 1416 @Deprecated 1417 public Component getNextFocusableComponent() { 1418 return (Component)getClientProperty(NEXT_FOCUS); 1419 } 1420 1421 /** 1422 * Provides a hint as to whether or not this <code>JComponent</code> 1423 * should get focus. This is only a hint, and it is up to consumers that 1424 * are requesting focus to honor this property. This is typically honored 1425 * for mouse operations, but not keyboard operations. For example, look 1426 * and feels could verify this property is true before requesting focus 1427 * during a mouse operation. This would often times be used if you did 1428 * not want a mouse press on a <code>JComponent</code> to steal focus, 1429 * but did want the <code>JComponent</code> to be traversable via the 1430 * keyboard. If you do not want this <code>JComponent</code> focusable at 1431 * all, use the <code>setFocusable</code> method instead. 1432 * <p> 1433 * Please see 1434 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> 1435 * How to Use the Focus Subsystem</a>, 1436 * a section in <em>The Java Tutorial</em>, 1437 * for more information. 1438 * 1439 * @param requestFocusEnabled indicates whether you want this 1440 * <code>JComponent</code> to be focusable or not 1441 * @see <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a> 1442 * @see java.awt.Component#setFocusable 1443 */ 1444 public void setRequestFocusEnabled(boolean requestFocusEnabled) { 1445 setFlag(REQUEST_FOCUS_DISABLED, !requestFocusEnabled); 1446 } 1447 1448 /** 1449 * Returns <code>true</code> if this <code>JComponent</code> should 1450 * get focus; otherwise returns <code>false</code>. 1451 * <p> 1452 * Please see 1453 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> 1454 * How to Use the Focus Subsystem</a>, 1455 * a section in <em>The Java Tutorial</em>, 1456 * for more information. 1457 * 1458 * @return <code>true</code> if this component should get focus, 1459 * otherwise returns <code>false</code> 1460 * @see #setRequestFocusEnabled 1461 * @see <a href="../../java/awt/doc-files/FocusSpec.html">Focus 1462 * Specification</a> 1463 * @see java.awt.Component#isFocusable 1464 */ 1465 public boolean isRequestFocusEnabled() { 1466 return !getFlag(REQUEST_FOCUS_DISABLED); 1467 } 1468 1469 /** 1470 * Requests that this <code>Component</code> gets the input focus. 1471 * Refer to {@link java.awt.Component#requestFocus() 1472 * Component.requestFocus()} for a complete description of 1473 * this method. 1474 * <p> 1475 * Note that the use of this method is discouraged because 1476 * its behavior is platform dependent. Instead we recommend the 1477 * use of {@link #requestFocusInWindow() requestFocusInWindow()}. 1478 * If you would like more information on focus, see 1479 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> 1480 * How to Use the Focus Subsystem</a>, 1481 * a section in <em>The Java Tutorial</em>. 1482 * 1483 * @see java.awt.Component#requestFocusInWindow() 1484 * @see java.awt.Component#requestFocusInWindow(boolean) 1485 * @since 1.4 1486 */ 1487 public void requestFocus() { 1488 super.requestFocus(); 1489 } 1490 1491 /** 1492 * Requests that this <code>Component</code> gets the input focus. 1493 * Refer to {@link java.awt.Component#requestFocus(boolean) 1494 * Component.requestFocus(boolean)} for a complete description of 1495 * this method. 1496 * <p> 1497 * Note that the use of this method is discouraged because 1498 * its behavior is platform dependent. Instead we recommend the 1499 * use of {@link #requestFocusInWindow(boolean) 1500 * requestFocusInWindow(boolean)}. 1501 * If you would like more information on focus, see 1502 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> 1503 * How to Use the Focus Subsystem</a>, 1504 * a section in <em>The Java Tutorial</em>. 1505 * 1506 * @param temporary boolean indicating if the focus change is temporary 1507 * @return <code>false</code> if the focus change request is guaranteed to 1508 * fail; <code>true</code> if it is likely to succeed 1509 * @see java.awt.Component#requestFocusInWindow() 1510 * @see java.awt.Component#requestFocusInWindow(boolean) 1511 * @since 1.4 1512 */ 1513 public boolean requestFocus(boolean temporary) { 1514 return super.requestFocus(temporary); 1515 } 1516 1517 /** 1518 * Requests that this <code>Component</code> gets the input focus. 1519 * Refer to {@link java.awt.Component#requestFocusInWindow() 1520 * Component.requestFocusInWindow()} for a complete description of 1521 * this method. 1522 * <p> 1523 * If you would like more information on focus, see 1524 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> 1525 * How to Use the Focus Subsystem</a>, 1526 * a section in <em>The Java Tutorial</em>. 1527 * 1528 * @return <code>false</code> if the focus change request is guaranteed to 1529 * fail; <code>true</code> if it is likely to succeed 1530 * @see java.awt.Component#requestFocusInWindow() 1531 * @see java.awt.Component#requestFocusInWindow(boolean) 1532 * @since 1.4 1533 */ 1534 public boolean requestFocusInWindow() { 1535 return super.requestFocusInWindow(); 1536 } 1537 1538 /** 1539 * Requests that this <code>Component</code> gets the input focus. 1540 * Refer to {@link java.awt.Component#requestFocusInWindow(boolean) 1541 * Component.requestFocusInWindow(boolean)} for a complete description of 1542 * this method. 1543 * <p> 1544 * If you would like more information on focus, see 1545 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> 1546 * How to Use the Focus Subsystem</a>, 1547 * a section in <em>The Java Tutorial</em>. 1548 * 1549 * @param temporary boolean indicating if the focus change is temporary 1550 * @return <code>false</code> if the focus change request is guaranteed to 1551 * fail; <code>true</code> if it is likely to succeed 1552 * @see java.awt.Component#requestFocusInWindow() 1553 * @see java.awt.Component#requestFocusInWindow(boolean) 1554 * @since 1.4 1555 */ 1556 protected boolean requestFocusInWindow(boolean temporary) { 1557 return super.requestFocusInWindow(temporary); 1558 } 1559 1560 /** 1561 * Requests that this Component get the input focus, and that this 1562 * Component's top-level ancestor become the focused Window. This component 1563 * must be displayable, visible, and focusable for the request to be 1564 * granted. 1565 * <p> 1566 * This method is intended for use by focus implementations. Client code 1567 * should not use this method; instead, it should use 1568 * <code>requestFocusInWindow()</code>. 1569 * 1570 * @see #requestFocusInWindow() 1571 */ 1572 public void grabFocus() { 1573 requestFocus(); 1574 } 1575 1576 /** 1577 * Sets the value to indicate whether input verifier for the 1578 * current focus owner will be called before this component requests 1579 * focus. The default is true. Set to false on components such as a 1580 * Cancel button or a scrollbar, which should activate even if the 1581 * input in the current focus owner is not "passed" by the input 1582 * verifier for that component. 1583 * 1584 * @param verifyInputWhenFocusTarget value for the 1585 * <code>verifyInputWhenFocusTarget</code> property 1586 * @see InputVerifier 1587 * @see #setInputVerifier 1588 * @see #getInputVerifier 1589 * @see #getVerifyInputWhenFocusTarget 1590 * 1591 * @since 1.3 1592 * @beaninfo 1593 * bound: true 1594 * description: Whether the Component verifies input before accepting 1595 * focus. 1596 */ 1597 public void setVerifyInputWhenFocusTarget(boolean 1598 verifyInputWhenFocusTarget) { 1599 boolean oldVerifyInputWhenFocusTarget = 1600 this.verifyInputWhenFocusTarget; 1601 this.verifyInputWhenFocusTarget = verifyInputWhenFocusTarget; 1602 firePropertyChange("verifyInputWhenFocusTarget", 1603 oldVerifyInputWhenFocusTarget, 1604 verifyInputWhenFocusTarget); 1605 } 1606 1607 /** 1608 * Returns the value that indicates whether the input verifier for the 1609 * current focus owner will be called before this component requests 1610 * focus. 1611 * 1612 * @return value of the <code>verifyInputWhenFocusTarget</code> property 1613 * 1614 * @see InputVerifier 1615 * @see #setInputVerifier 1616 * @see #getInputVerifier 1617 * @see #setVerifyInputWhenFocusTarget 1618 * 1619 * @since 1.3 1620 */ 1621 public boolean getVerifyInputWhenFocusTarget() { 1622 return verifyInputWhenFocusTarget; 1623 } 1624 1625 1626 /** 1627 * Gets the <code>FontMetrics</code> for the specified <code>Font</code>. 1628 * 1629 * @param font the font for which font metrics is to be 1630 * obtained 1631 * @return the font metrics for <code>font</code> 1632 * @throws NullPointerException if <code>font</code> is null 1633 * @since 1.5 1634 */ 1635 public FontMetrics getFontMetrics(Font font) { 1636 return SwingUtilities2.getFontMetrics(this, font); 1637 } 1638 1639 1640 /** 1641 * Sets the preferred size of this component. 1642 * If <code>preferredSize</code> is <code>null</code>, the UI will 1643 * be asked for the preferred size. 1644 * @beaninfo 1645 * preferred: true 1646 * bound: true 1647 * description: The preferred size of the component. 1648 */ 1649 public void setPreferredSize(Dimension preferredSize) { 1650 super.setPreferredSize(preferredSize); 1651 } 1652 1653 1654 /** 1655 * If the <code>preferredSize</code> has been set to a 1656 * non-<code>null</code> value just returns it. 1657 * If the UI delegate's <code>getPreferredSize</code> 1658 * method returns a non <code>null</code> value then return that; 1659 * otherwise defer to the component's layout manager. 1660 * 1661 * @return the value of the <code>preferredSize</code> property 1662 * @see #setPreferredSize 1663 * @see ComponentUI 1664 */ 1665 @Transient 1666 public Dimension getPreferredSize() { 1667 if (isPreferredSizeSet()) { 1668 return super.getPreferredSize(); 1669 } 1670 Dimension size = null; 1671 if (ui != null) { 1672 size = ui.getPreferredSize(this); 1673 } 1674 return (size != null) ? size : super.getPreferredSize(); 1675 } 1676 1677 1678 /** 1679 * Sets the maximum size of this component to a constant 1680 * value. Subsequent calls to <code>getMaximumSize</code> will always 1681 * return this value; the component's UI will not be asked 1682 * to compute it. Setting the maximum size to <code>null</code> 1683 * restores the default behavior. 1684 * 1685 * @param maximumSize a <code>Dimension</code> containing the 1686 * desired maximum allowable size 1687 * @see #getMaximumSize 1688 * @beaninfo 1689 * bound: true 1690 * description: The maximum size of the component. 1691 */ 1692 public void setMaximumSize(Dimension maximumSize) { 1693 super.setMaximumSize(maximumSize); 1694 } 1695 1696 1697 /** 1698 * If the maximum size has been set to a non-<code>null</code> value 1699 * just returns it. If the UI delegate's <code>getMaximumSize</code> 1700 * method returns a non-<code>null</code> value then return that; 1701 * otherwise defer to the component's layout manager. 1702 * 1703 * @return the value of the <code>maximumSize</code> property 1704 * @see #setMaximumSize 1705 * @see ComponentUI 1706 */ 1707 @Transient 1708 public Dimension getMaximumSize() { 1709 if (isMaximumSizeSet()) { 1710 return super.getMaximumSize(); 1711 } 1712 Dimension size = null; 1713 if (ui != null) { 1714 size = ui.getMaximumSize(this); 1715 } 1716 return (size != null) ? size : super.getMaximumSize(); 1717 } 1718 1719 1720 /** 1721 * Sets the minimum size of this component to a constant 1722 * value. Subsequent calls to <code>getMinimumSize</code> will always 1723 * return this value; the component's UI will not be asked 1724 * to compute it. Setting the minimum size to <code>null</code> 1725 * restores the default behavior. 1726 * 1727 * @param minimumSize the new minimum size of this component 1728 * @see #getMinimumSize 1729 * @beaninfo 1730 * bound: true 1731 * description: The minimum size of the component. 1732 */ 1733 public void setMinimumSize(Dimension minimumSize) { 1734 super.setMinimumSize(minimumSize); 1735 } 1736 1737 /** 1738 * If the minimum size has been set to a non-<code>null</code> value 1739 * just returns it. If the UI delegate's <code>getMinimumSize</code> 1740 * method returns a non-<code>null</code> value then return that; otherwise 1741 * defer to the component's layout manager. 1742 * 1743 * @return the value of the <code>minimumSize</code> property 1744 * @see #setMinimumSize 1745 * @see ComponentUI 1746 */ 1747 @Transient 1748 public Dimension getMinimumSize() { 1749 if (isMinimumSizeSet()) { 1750 return super.getMinimumSize(); 1751 } 1752 Dimension size = null; 1753 if (ui != null) { 1754 size = ui.getMinimumSize(this); 1755 } 1756 return (size != null) ? size : super.getMinimumSize(); 1757 } 1758 1759 /** 1760 * Gives the UI delegate an opportunity to define the precise 1761 * shape of this component for the sake of mouse processing. 1762 * 1763 * @return true if this component logically contains x,y 1764 * @see java.awt.Component#contains(int, int) 1765 * @see ComponentUI 1766 */ 1767 public boolean contains(int x, int y) { 1768 return (ui != null) ? ui.contains(this, x, y) : super.contains(x, y); 1769 } 1770 1771 /** 1772 * Sets the border of this component. The <code>Border</code> object is 1773 * responsible for defining the insets for the component 1774 * (overriding any insets set directly on the component) and 1775 * for optionally rendering any border decorations within the 1776 * bounds of those insets. Borders should be used (rather 1777 * than insets) for creating both decorative and non-decorative 1778 * (such as margins and padding) regions for a swing component. 1779 * Compound borders can be used to nest multiple borders within a 1780 * single component. 1781 * <p> 1782 * Although technically you can set the border on any object 1783 * that inherits from <code>JComponent</code>, the look and 1784 * feel implementation of many standard Swing components 1785 * doesn't work well with user-set borders. In general, 1786 * when you want to set a border on a standard Swing 1787 * component other than <code>JPanel</code> or <code>JLabel</code>, 1788 * we recommend that you put the component in a <code>JPanel</code> 1789 * and set the border on the <code>JPanel</code>. 1790 * <p> 1791 * This is a bound property. 1792 * 1793 * @param border the border to be rendered for this component 1794 * @see Border 1795 * @see CompoundBorder 1796 * @beaninfo 1797 * bound: true 1798 * preferred: true 1799 * attribute: visualUpdate true 1800 * description: The component's border. 1801 */ 1802 public void setBorder(Border border) { 1803 Border oldBorder = this.border; 1804 1805 this.border = border; 1806 firePropertyChange("border", oldBorder, border); 1807 if (border != oldBorder) { 1808 if (border == null || oldBorder == null || 1809 !(border.getBorderInsets(this).equals(oldBorder.getBorderInsets(this)))) { 1810 revalidate(); 1811 } 1812 repaint(); 1813 } 1814 } 1815 1816 /** 1817 * Returns the border of this component or <code>null</code> if no 1818 * border is currently set. 1819 * 1820 * @return the border object for this component 1821 * @see #setBorder 1822 */ 1823 public Border getBorder() { 1824 return border; 1825 } 1826 1827 /** 1828 * If a border has been set on this component, returns the 1829 * border's insets; otherwise calls <code>super.getInsets</code>. 1830 * 1831 * @return the value of the insets property 1832 * @see #setBorder 1833 */ 1834 public Insets getInsets() { 1835 if (border != null) { 1836 return border.getBorderInsets(this); 1837 } 1838 return super.getInsets(); 1839 } 1840 1841 /** 1842 * Returns an <code>Insets</code> object containing this component's inset 1843 * values. The passed-in <code>Insets</code> object will be reused 1844 * if possible. 1845 * Calling methods cannot assume that the same object will be returned, 1846 * however. All existing values within this object are overwritten. 1847 * If <code>insets</code> is null, this will allocate a new one. 1848 * 1849 * @param insets the <code>Insets</code> object, which can be reused 1850 * @return the <code>Insets</code> object 1851 * @see #getInsets 1852 * @beaninfo 1853 * expert: true 1854 */ 1855 public Insets getInsets(Insets insets) { 1856 if (insets == null) { 1857 insets = new Insets(0, 0, 0, 0); 1858 } 1859 if (border != null) { 1860 if (border instanceof AbstractBorder) { 1861 return ((AbstractBorder)border).getBorderInsets(this, insets); 1862 } else { 1863 // Can't reuse border insets because the Border interface 1864 // can't be enhanced. 1865 return border.getBorderInsets(this); 1866 } 1867 } else { 1868 // super.getInsets() always returns an Insets object with 1869 // all of its value zeroed. No need for a new object here. 1870 insets.left = insets.top = insets.right = insets.bottom = 0; 1871 return insets; 1872 } 1873 } 1874 1875 /** 1876 * Overrides <code>Container.getAlignmentY</code> to return 1877 * the vertical alignment. 1878 * 1879 * @return the value of the <code>alignmentY</code> property 1880 * @see #setAlignmentY 1881 * @see java.awt.Component#getAlignmentY 1882 */ 1883 public float getAlignmentY() { 1884 if (isAlignmentYSet) { 1885 return alignmentY; 1886 } 1887 return super.getAlignmentY(); 1888 } 1889 1890 /** 1891 * Sets the vertical alignment. 1892 * 1893 * @param alignmentY the new vertical alignment 1894 * @see #getAlignmentY 1895 * @beaninfo 1896 * description: The preferred vertical alignment of the component. 1897 */ 1898 public void setAlignmentY(float alignmentY) { 1899 this.alignmentY = validateAlignment(alignmentY); 1900 isAlignmentYSet = true; 1901 } 1902 1903 1904 /** 1905 * Overrides <code>Container.getAlignmentX</code> to return 1906 * the horizontal alignment. 1907 * 1908 * @return the value of the <code>alignmentX</code> property 1909 * @see #setAlignmentX 1910 * @see java.awt.Component#getAlignmentX 1911 */ 1912 public float getAlignmentX() { 1913 if (isAlignmentXSet) { 1914 return alignmentX; 1915 } 1916 return super.getAlignmentX(); 1917 } 1918 1919 /** 1920 * Sets the horizontal alignment. 1921 * 1922 * @param alignmentX the new horizontal alignment 1923 * @see #getAlignmentX 1924 * @beaninfo 1925 * description: The preferred horizontal alignment of the component. 1926 */ 1927 public void setAlignmentX(float alignmentX) { 1928 this.alignmentX = validateAlignment(alignmentX); 1936 /** 1937 * Sets the input verifier for this component. 1938 * 1939 * @param inputVerifier the new input verifier 1940 * @since 1.3 1941 * @see InputVerifier 1942 * @beaninfo 1943 * bound: true 1944 * description: The component's input verifier. 1945 */ 1946 public void setInputVerifier(InputVerifier inputVerifier) { 1947 InputVerifier oldInputVerifier = (InputVerifier)getClientProperty( 1948 JComponent_INPUT_VERIFIER); 1949 putClientProperty(JComponent_INPUT_VERIFIER, inputVerifier); 1950 firePropertyChange("inputVerifier", oldInputVerifier, inputVerifier); 1951 } 1952 1953 /** 1954 * Returns the input verifier for this component. 1955 * 1956 * @return the <code>inputVerifier</code> property 1957 * @since 1.3 1958 * @see InputVerifier 1959 */ 1960 public InputVerifier getInputVerifier() { 1961 return (InputVerifier)getClientProperty(JComponent_INPUT_VERIFIER); 1962 } 1963 1964 /** 1965 * Returns this component's graphics context, which lets you draw 1966 * on a component. Use this method to get a <code>Graphics</code> object and 1967 * then invoke operations on that object to draw on the component. 1968 * @return this components graphics context 1969 */ 1970 public Graphics getGraphics() { 1971 if (DEBUG_GRAPHICS_LOADED && shouldDebugGraphics() != 0) { 1972 DebugGraphics graphics = new DebugGraphics(super.getGraphics(), 1973 this); 1974 return graphics; 1975 } 1976 return super.getGraphics(); 1977 } 1978 1979 1980 /** Enables or disables diagnostic information about every graphics 1981 * operation performed within the component or one of its children. 1982 * 1983 * @param debugOptions determines how the component should display 1984 * the information; one of the following options: 1985 * <ul> 1986 * <li>DebugGraphics.LOG_OPTION - causes a text message to be printed. 1987 * <li>DebugGraphics.FLASH_OPTION - causes the drawing to flash several 1988 * times. 1989 * <li>DebugGraphics.BUFFERED_OPTION - creates an 1990 * <code>ExternalWindow</code> that displays the operations 1991 * performed on the View's offscreen buffer. 1992 * <li>DebugGraphics.NONE_OPTION disables debugging. 1993 * <li>A value of 0 causes no changes to the debugging options. 1994 * </ul> 1995 * <code>debugOptions</code> is bitwise OR'd into the current value 1996 * 1997 * @beaninfo 1998 * preferred: true 1999 * enum: NONE_OPTION DebugGraphics.NONE_OPTION 2000 * LOG_OPTION DebugGraphics.LOG_OPTION 2001 * FLASH_OPTION DebugGraphics.FLASH_OPTION 2002 * BUFFERED_OPTION DebugGraphics.BUFFERED_OPTION 2003 * description: Diagnostic options for graphics operations. 2004 */ 2005 public void setDebugGraphicsOptions(int debugOptions) { 2006 DebugGraphics.setDebugOptions(this, debugOptions); 2007 } 2008 2009 /** Returns the state of graphics debugging. 2010 * 2011 * @return a bitwise OR'd flag of zero or more of the following options: 2012 * <ul> 2013 * <li>DebugGraphics.LOG_OPTION - causes a text message to be printed. 2014 * <li>DebugGraphics.FLASH_OPTION - causes the drawing to flash several 2015 * times. 2016 * <li>DebugGraphics.BUFFERED_OPTION - creates an 2017 * <code>ExternalWindow</code> that displays the operations 2018 * performed on the View's offscreen buffer. 2019 * <li>DebugGraphics.NONE_OPTION disables debugging. 2020 * <li>A value of 0 causes no changes to the debugging options. 2021 * </ul> 2022 * @see #setDebugGraphicsOptions 2023 */ 2024 public int getDebugGraphicsOptions() { 2025 return DebugGraphics.getDebugOptions(this); 2026 } 2027 2028 2029 /** 2030 * Returns true if debug information is enabled for this 2031 * <code>JComponent</code> or one of its parents. 2032 */ 2033 int shouldDebugGraphics() { 2034 return DebugGraphics.shouldComponentDebug(this); 2035 } 2036 2037 /** 2038 * This method is now obsolete, please use a combination of 2039 * <code>getActionMap()</code> and <code>getInputMap()</code> for 2040 * similar behavior. For example, to bind the <code>KeyStroke</code> 2041 * <code>aKeyStroke</code> to the <code>Action</code> <code>anAction</code> 2042 * now use: 2043 * <pre> 2044 * component.getInputMap().put(aKeyStroke, aCommand); 2045 * component.getActionMap().put(aCommmand, anAction); 2046 * </pre> 2047 * The above assumes you want the binding to be applicable for 2048 * <code>WHEN_FOCUSED</code>. To register bindings for other focus 2049 * states use the <code>getInputMap</code> method that takes an integer. 2050 * <p> 2051 * Register a new keyboard action. 2052 * <code>anAction</code> will be invoked if a key event matching 2053 * <code>aKeyStroke</code> occurs and <code>aCondition</code> is verified. 2054 * The <code>KeyStroke</code> object defines a 2055 * particular combination of a keyboard key and one or more modifiers 2056 * (alt, shift, ctrl, meta). 2057 * <p> 2058 * The <code>aCommand</code> will be set in the delivered event if 2059 * specified. 2060 * <p> 2061 * The <code>aCondition</code> can be one of: 2062 * <blockquote> 2063 * <DL> 2064 * <DT>WHEN_FOCUSED 2065 * <DD>The action will be invoked only when the keystroke occurs 2066 * while the component has the focus. 2067 * <DT>WHEN_IN_FOCUSED_WINDOW 2068 * <DD>The action will be invoked when the keystroke occurs while 2069 * the component has the focus or if the component is in the 2070 * window that has the focus. Note that the component need not 2071 * be an immediate descendent of the window -- it can be 2072 * anywhere in the window's containment hierarchy. In other 2073 * words, whenever <em>any</em> component in the window has the focus, 2074 * the action registered with this component is invoked. 2075 * <DT>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT 2076 * <DD>The action will be invoked when the keystroke occurs while the 2077 * component has the focus or if the component is an ancestor of 2078 * the component that has the focus. 2079 * </DL> 2080 * </blockquote> 2081 * <p> 2082 * The combination of keystrokes and conditions lets you define high 2083 * level (semantic) action events for a specified keystroke+modifier 2084 * combination (using the KeyStroke class) and direct to a parent or 2085 * child of a component that has the focus, or to the component itself. 2086 * In other words, in any hierarchical structure of components, an 2087 * arbitrary key-combination can be immediately directed to the 2088 * appropriate component in the hierarchy, and cause a specific method 2089 * to be invoked (usually by way of adapter objects). 2090 * <p> 2091 * If an action has already been registered for the receiving 2092 * container, with the same charCode and the same modifiers, 2093 * <code>anAction</code> will replace the action. 2094 * 2095 * @param anAction the <code>Action</code> to be registered 2096 * @param aCommand the command to be set in the delivered event 2097 * @param aKeyStroke the <code>KeyStroke</code> to bind to the action 2098 * @param aCondition the condition that needs to be met, see above 2099 * @see KeyStroke 2100 */ 2101 public void registerKeyboardAction(ActionListener anAction,String aCommand,KeyStroke aKeyStroke,int aCondition) { 2102 2103 InputMap inputMap = getInputMap(aCondition, true); 2104 2105 if (inputMap != null) { 2106 ActionMap actionMap = getActionMap(true); 2107 ActionStandin action = new ActionStandin(anAction, aCommand); 2108 inputMap.put(aKeyStroke, action); 2109 if (actionMap != null) { 2110 actionMap.put(action, action); 2111 } 2112 } 2113 } 2114 2115 /** 2116 * Registers any bound <code>WHEN_IN_FOCUSED_WINDOW</code> actions with 2117 * the <code>KeyboardManager</code>. If <code>onlyIfNew</code> 2118 * is true only actions that haven't been registered are pushed 2119 * to the <code>KeyboardManager</code>; 2120 * otherwise all actions are pushed to the <code>KeyboardManager</code>. 2121 * 2122 * @param onlyIfNew if true, only actions that haven't been registered 2123 * are pushed to the <code>KeyboardManager</code> 2124 */ 2125 private void registerWithKeyboardManager(boolean onlyIfNew) { 2126 InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW, false); 2127 KeyStroke[] strokes; 2128 @SuppressWarnings("unchecked") 2129 Hashtable<KeyStroke, KeyStroke> registered = 2130 (Hashtable<KeyStroke, KeyStroke>)getClientProperty 2131 (WHEN_IN_FOCUSED_WINDOW_BINDINGS); 2132 2133 if (inputMap != null) { 2134 // Push any new KeyStrokes to the KeyboardManager. 2135 strokes = inputMap.allKeys(); 2136 if (strokes != null) { 2137 for (int counter = strokes.length - 1; counter >= 0; 2138 counter--) { 2139 if (!onlyIfNew || registered == null || 2140 registered.get(strokes[counter]) == null) { 2141 registerWithKeyboardManager(strokes[counter]); 2142 } 2143 if (registered != null) { 2159 } 2160 registered.clear(); 2161 } 2162 // Updated the registered Hashtable. 2163 if (strokes != null && strokes.length > 0) { 2164 if (registered == null) { 2165 registered = new Hashtable<KeyStroke, KeyStroke>(strokes.length); 2166 putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, registered); 2167 } 2168 for (int counter = strokes.length - 1; counter >= 0; counter--) { 2169 registered.put(strokes[counter], strokes[counter]); 2170 } 2171 } 2172 else { 2173 putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, null); 2174 } 2175 } 2176 2177 /** 2178 * Unregisters all the previously registered 2179 * <code>WHEN_IN_FOCUSED_WINDOW</code> <code>KeyStroke</code> bindings. 2180 */ 2181 private void unregisterWithKeyboardManager() { 2182 @SuppressWarnings("unchecked") 2183 Hashtable<KeyStroke, KeyStroke> registered = 2184 (Hashtable<KeyStroke, KeyStroke>)getClientProperty 2185 (WHEN_IN_FOCUSED_WINDOW_BINDINGS); 2186 2187 if (registered != null && registered.size() > 0) { 2188 Enumeration<KeyStroke> keys = registered.keys(); 2189 2190 while (keys.hasMoreElements()) { 2191 KeyStroke ks = keys.nextElement(); 2192 unregisterWithKeyboardManager(ks); 2193 } 2194 } 2195 putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, null); 2196 } 2197 2198 /** 2199 * Invoked from <code>ComponentInputMap</code> when its bindings change. 2200 * If <code>inputMap</code> is the current <code>windowInputMap</code> 2201 * (or a parent of the window <code>InputMap</code>) 2202 * the <code>KeyboardManager</code> is notified of the new bindings. 2203 * 2204 * @param inputMap the map containing the new bindings 2205 */ 2206 void componentInputMapChanged(ComponentInputMap inputMap) { 2207 InputMap km = getInputMap(WHEN_IN_FOCUSED_WINDOW, false); 2208 2209 while (km != inputMap && km != null) { 2210 km = km.getParent(); 2211 } 2212 if (km != null) { 2213 registerWithKeyboardManager(false); 2214 } 2215 } 2216 2217 private void registerWithKeyboardManager(KeyStroke aKeyStroke) { 2218 KeyboardManager.getCurrentManager().registerKeyStroke(aKeyStroke,this); 2219 } 2220 2221 private void unregisterWithKeyboardManager(KeyStroke aKeyStroke) { 2222 KeyboardManager.getCurrentManager().unregisterKeyStroke(aKeyStroke, 2223 this); 2224 } 2225 2226 /** 2227 * This method is now obsolete, please use a combination of 2228 * <code>getActionMap()</code> and <code>getInputMap()</code> for 2229 * similar behavior. 2230 * 2231 * @param anAction action to be registered to given keystroke and condition 2232 * @param aKeyStroke a {@code KeyStroke} 2233 * @param aCondition the condition to be associated with given keystroke 2234 * and action 2235 * @see #getActionMap 2236 * @see #getInputMap(int) 2237 */ 2238 public void registerKeyboardAction(ActionListener anAction,KeyStroke aKeyStroke,int aCondition) { 2239 registerKeyboardAction(anAction,null,aKeyStroke,aCondition); 2240 } 2241 2242 /** 2243 * This method is now obsolete. To unregister an existing binding 2244 * you can either remove the binding from the 2245 * <code>ActionMap/InputMap</code>, or place a dummy binding the 2246 * <code>InputMap</code>. Removing the binding from the 2247 * <code>InputMap</code> allows bindings in parent <code>InputMap</code>s 2248 * to be active, whereas putting a dummy binding in the 2249 * <code>InputMap</code> effectively disables 2250 * the binding from ever happening. 2251 * <p> 2252 * Unregisters a keyboard action. 2253 * This will remove the binding from the <code>ActionMap</code> 2254 * (if it exists) as well as the <code>InputMap</code>s. 2255 * 2256 * @param aKeyStroke the keystroke for which to unregister its 2257 * keyboard action 2258 */ 2259 public void unregisterKeyboardAction(KeyStroke aKeyStroke) { 2260 ActionMap am = getActionMap(false); 2261 for (int counter = 0; counter < 3; counter++) { 2262 InputMap km = getInputMap(counter, false); 2263 if (km != null) { 2264 Object actionID = km.get(aKeyStroke); 2265 2266 if (am != null && actionID != null) { 2267 am.remove(actionID); 2268 } 2269 km.remove(aKeyStroke); 2270 } 2271 } 2272 } 2273 2274 /** 2275 * Returns the <code>KeyStrokes</code> that will initiate 2276 * registered actions. 2277 * 2278 * @return an array of <code>KeyStroke</code> objects 2279 * @see #registerKeyboardAction 2280 */ 2281 public KeyStroke[] getRegisteredKeyStrokes() { 2282 int[] counts = new int[3]; 2283 KeyStroke[][] strokes = new KeyStroke[3][]; 2284 2285 for (int counter = 0; counter < 3; counter++) { 2286 InputMap km = getInputMap(counter, false); 2287 strokes[counter] = (km != null) ? km.allKeys() : null; 2288 counts[counter] = (strokes[counter] != null) ? 2289 strokes[counter].length : 0; 2290 } 2291 KeyStroke[] retValue = new KeyStroke[counts[0] + counts[1] + 2292 counts[2]]; 2293 for (int counter = 0, last = 0; counter < 3; counter++) { 2294 if (counts[counter] > 0) { 2295 System.arraycopy(strokes[counter], 0, retValue, last, 2296 counts[counter]); 2297 last += counts[counter]; 2298 } 2299 } 2300 return retValue; 2301 } 2302 2303 /** 2304 * Returns the condition that determines whether a registered action 2305 * occurs in response to the specified keystroke. 2306 * <p> 2307 * For Java 2 platform v1.3, a <code>KeyStroke</code> can be associated 2308 * with more than one condition. 2309 * For example, 'a' could be bound for the two 2310 * conditions <code>WHEN_FOCUSED</code> and 2311 * <code>WHEN_IN_FOCUSED_WINDOW</code> condition. 2312 * 2313 * @param aKeyStroke the keystroke for which to request an 2314 * action-keystroke condition 2315 * @return the action-keystroke condition 2316 */ 2317 public int getConditionForKeyStroke(KeyStroke aKeyStroke) { 2318 for (int counter = 0; counter < 3; counter++) { 2319 InputMap inputMap = getInputMap(counter, false); 2320 if (inputMap != null && inputMap.get(aKeyStroke) != null) { 2321 return counter; 2322 } 2323 } 2324 return UNDEFINED_CONDITION; 2325 } 2326 2327 /** 2328 * Returns the object that will perform the action registered for a 2329 * given keystroke. 2330 * 2331 * @param aKeyStroke the keystroke for which to return a listener 2332 * @return the <code>ActionListener</code> 2333 * object invoked when the keystroke occurs 2334 */ 2335 public ActionListener getActionForKeyStroke(KeyStroke aKeyStroke) { 2336 ActionMap am = getActionMap(false); 2337 2338 if (am == null) { 2339 return null; 2340 } 2341 for (int counter = 0; counter < 3; counter++) { 2342 InputMap inputMap = getInputMap(counter, false); 2343 if (inputMap != null) { 2344 Object actionBinding = inputMap.get(aKeyStroke); 2345 2346 if (actionBinding != null) { 2347 Action action = am.get(actionBinding); 2348 if (action instanceof ActionStandin) { 2349 return ((ActionStandin)action).actionListener; 2350 } 2351 return action; 2352 } 2353 } 2354 } 2355 return null; 2356 } 2357 2358 /** 2359 * Unregisters all the bindings in the first tier <code>InputMaps</code> 2360 * and <code>ActionMap</code>. This has the effect of removing any 2361 * local bindings, and allowing the bindings defined in parent 2362 * <code>InputMap/ActionMaps</code> 2363 * (the UI is usually defined in the second tier) to persist. 2364 */ 2365 public void resetKeyboardActions() { 2366 // Keys 2367 for (int counter = 0; counter < 3; counter++) { 2368 InputMap inputMap = getInputMap(counter, false); 2369 2370 if (inputMap != null) { 2371 inputMap.clear(); 2372 } 2373 } 2374 2375 // Actions 2376 ActionMap am = getActionMap(false); 2377 2378 if (am != null) { 2379 am.clear(); 2380 } 2381 } 2382 2383 /** 2384 * Sets the <code>InputMap</code> to use under the condition 2385 * <code>condition</code> to 2386 * <code>map</code>. A <code>null</code> value implies you 2387 * do not want any bindings to be used, even from the UI. This will 2388 * not reinstall the UI <code>InputMap</code> (if there was one). 2389 * <code>condition</code> has one of the following values: 2390 * <ul> 2391 * <li><code>WHEN_IN_FOCUSED_WINDOW</code> 2392 * <li><code>WHEN_FOCUSED</code> 2393 * <li><code>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT</code> 2394 * </ul> 2395 * If <code>condition</code> is <code>WHEN_IN_FOCUSED_WINDOW</code> 2396 * and <code>map</code> is not a <code>ComponentInputMap</code>, an 2397 * <code>IllegalArgumentException</code> will be thrown. 2398 * Similarly, if <code>condition</code> is not one of the values 2399 * listed, an <code>IllegalArgumentException</code> will be thrown. 2400 * 2401 * @param condition one of the values listed above 2402 * @param map the <code>InputMap</code> to use for the given condition 2403 * @exception IllegalArgumentException if <code>condition</code> is 2404 * <code>WHEN_IN_FOCUSED_WINDOW</code> and <code>map</code> 2405 * is not an instance of <code>ComponentInputMap</code>; or 2406 * if <code>condition</code> is not one of the legal values 2407 * specified above 2408 * @since 1.3 2409 */ 2410 public final void setInputMap(int condition, InputMap map) { 2411 switch (condition) { 2412 case WHEN_IN_FOCUSED_WINDOW: 2413 if (map != null && !(map instanceof ComponentInputMap)) { 2414 throw new IllegalArgumentException("WHEN_IN_FOCUSED_WINDOW InputMaps must be of type ComponentInputMap"); 2415 } 2416 windowInputMap = (ComponentInputMap)map; 2417 setFlag(WIF_INPUTMAP_CREATED, true); 2418 registerWithKeyboardManager(false); 2419 break; 2420 case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT: 2421 ancestorInputMap = map; 2422 setFlag(ANCESTOR_INPUTMAP_CREATED, true); 2423 break; 2424 case WHEN_FOCUSED: 2425 focusInputMap = map; 2426 setFlag(FOCUS_INPUTMAP_CREATED, true); 2427 break; 2428 default: 2429 throw new IllegalArgumentException("condition must be one of JComponent.WHEN_IN_FOCUSED_WINDOW, JComponent.WHEN_FOCUSED or JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT"); 2430 } 2431 } 2432 2433 /** 2434 * Returns the <code>InputMap</code> that is used during 2435 * <code>condition</code>. 2436 * 2437 * @param condition one of WHEN_IN_FOCUSED_WINDOW, WHEN_FOCUSED, 2438 * WHEN_ANCESTOR_OF_FOCUSED_COMPONENT 2439 * @return the <code>InputMap</code> for the specified 2440 * <code>condition</code> 2441 * @since 1.3 2442 */ 2443 public final InputMap getInputMap(int condition) { 2444 return getInputMap(condition, true); 2445 } 2446 2447 /** 2448 * Returns the <code>InputMap</code> that is used when the 2449 * component has focus. 2450 * This is convenience method for <code>getInputMap(WHEN_FOCUSED)</code>. 2451 * 2452 * @return the <code>InputMap</code> used when the component has focus 2453 * @since 1.3 2454 */ 2455 public final InputMap getInputMap() { 2456 return getInputMap(WHEN_FOCUSED, true); 2457 } 2458 2459 /** 2460 * Sets the <code>ActionMap</code> to <code>am</code>. This does not set 2461 * the parent of the <code>am</code> to be the <code>ActionMap</code> 2462 * from the UI (if there was one), it is up to the caller to have done this. 2463 * 2464 * @param am the new <code>ActionMap</code> 2465 * @since 1.3 2466 */ 2467 public final void setActionMap(ActionMap am) { 2468 actionMap = am; 2469 setFlag(ACTIONMAP_CREATED, true); 2470 } 2471 2472 /** 2473 * Returns the <code>ActionMap</code> used to determine what 2474 * <code>Action</code> to fire for particular <code>KeyStroke</code> 2475 * binding. The returned <code>ActionMap</code>, unless otherwise 2476 * set, will have the <code>ActionMap</code> from the UI set as the parent. 2477 * 2478 * @return the <code>ActionMap</code> containing the key/action bindings 2479 * @since 1.3 2480 */ 2481 public final ActionMap getActionMap() { 2482 return getActionMap(true); 2483 } 2484 2485 /** 2486 * Returns the <code>InputMap</code> to use for condition 2487 * <code>condition</code>. If the <code>InputMap</code> hasn't 2488 * been created, and <code>create</code> is 2489 * true, it will be created. 2490 * 2491 * @param condition one of the following values: 2492 * <ul> 2493 * <li>JComponent.FOCUS_INPUTMAP_CREATED 2494 * <li>JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT 2495 * <li>JComponent.WHEN_IN_FOCUSED_WINDOW 2496 * </ul> 2497 * @param create if true, create the <code>InputMap</code> if it 2498 * is not already created 2499 * @return the <code>InputMap</code> for the given <code>condition</code>; 2500 * if <code>create</code> is false and the <code>InputMap</code> 2501 * hasn't been created, returns <code>null</code> 2502 * @exception IllegalArgumentException if <code>condition</code> 2503 * is not one of the legal values listed above 2504 */ 2505 final InputMap getInputMap(int condition, boolean create) { 2506 switch (condition) { 2507 case WHEN_FOCUSED: 2508 if (getFlag(FOCUS_INPUTMAP_CREATED)) { 2509 return focusInputMap; 2510 } 2511 // Hasn't been created yet. 2512 if (create) { 2513 InputMap km = new InputMap(); 2514 setInputMap(condition, km); 2515 return km; 2516 } 2517 break; 2518 case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT: 2519 if (getFlag(ANCESTOR_INPUTMAP_CREATED)) { 2520 return ancestorInputMap; 2521 } 2522 // Hasn't been created yet. 2527 } 2528 break; 2529 case WHEN_IN_FOCUSED_WINDOW: 2530 if (getFlag(WIF_INPUTMAP_CREATED)) { 2531 return windowInputMap; 2532 } 2533 // Hasn't been created yet. 2534 if (create) { 2535 ComponentInputMap km = new ComponentInputMap(this); 2536 setInputMap(condition, km); 2537 return km; 2538 } 2539 break; 2540 default: 2541 throw new IllegalArgumentException("condition must be one of JComponent.WHEN_IN_FOCUSED_WINDOW, JComponent.WHEN_FOCUSED or JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT"); 2542 } 2543 return null; 2544 } 2545 2546 /** 2547 * Finds and returns the appropriate <code>ActionMap</code>. 2548 * 2549 * @param create if true, create the <code>ActionMap</code> if it 2550 * is not already created 2551 * @return the <code>ActionMap</code> for this component; if the 2552 * <code>create</code> flag is false and there is no 2553 * current <code>ActionMap</code>, returns <code>null</code> 2554 */ 2555 final ActionMap getActionMap(boolean create) { 2556 if (getFlag(ACTIONMAP_CREATED)) { 2557 return actionMap; 2558 } 2559 // Hasn't been created. 2560 if (create) { 2561 ActionMap am = new ActionMap(); 2562 setActionMap(am); 2563 return am; 2564 } 2565 return null; 2566 } 2567 2568 /** 2569 * Returns the baseline. The baseline is measured from the top of 2570 * the component. This method is primarily meant for 2571 * <code>LayoutManager</code>s to align components along their 2572 * baseline. A return value less than 0 indicates this component 2573 * does not have a reasonable baseline and that 2574 * <code>LayoutManager</code>s should not align this component on 2575 * its baseline. 2576 * <p> 2577 * This method calls into the <code>ComponentUI</code> method of the 2578 * same name. If this component does not have a <code>ComponentUI</code> 2579 * -1 will be returned. If a value >= 0 is 2580 * returned, then the component has a valid baseline for any 2581 * size >= the minimum size and <code>getBaselineResizeBehavior</code> 2582 * can be used to determine how the baseline changes with size. 2583 * 2584 * @throws IllegalArgumentException {@inheritDoc} 2585 * @see #getBaselineResizeBehavior 2586 * @see java.awt.FontMetrics 2587 * @since 1.6 2588 */ 2589 public int getBaseline(int width, int height) { 2590 // check size. 2591 super.getBaseline(width, height); 2592 if (ui != null) { 2593 return ui.getBaseline(this, width, height); 2594 } 2595 return -1; 2596 } 2597 2598 /** 2599 * Returns an enum indicating how the baseline of the component 2600 * changes as the size changes. This method is primarily meant for 2601 * layout managers and GUI builders. 2602 * <p> 2603 * This method calls into the <code>ComponentUI</code> method of 2604 * the same name. If this component does not have a 2605 * <code>ComponentUI</code> 2606 * <code>BaselineResizeBehavior.OTHER</code> will be 2607 * returned. Subclasses should 2608 * never return <code>null</code>; if the baseline can not be 2609 * calculated return <code>BaselineResizeBehavior.OTHER</code>. Callers 2610 * should first ask for the baseline using 2611 * <code>getBaseline</code> and if a value >= 0 is returned use 2612 * this method. It is acceptable for this method to return a 2613 * value other than <code>BaselineResizeBehavior.OTHER</code> even if 2614 * <code>getBaseline</code> returns a value less than 0. 2615 * 2616 * @see #getBaseline(int, int) 2617 * @since 1.6 2618 */ 2619 public BaselineResizeBehavior getBaselineResizeBehavior() { 2620 if (ui != null) { 2621 return ui.getBaselineResizeBehavior(this); 2622 } 2623 return BaselineResizeBehavior.OTHER; 2624 } 2625 2626 /** 2627 * In release 1.4, the focus subsystem was rearchitected. 2628 * For more information, see 2629 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> 2630 * How to Use the Focus Subsystem</a>, 2631 * a section in <em>The Java Tutorial</em>. 2632 * <p> 2633 * Requests focus on this <code>JComponent</code>'s 2634 * <code>FocusTraversalPolicy</code>'s default <code>Component</code>. 2635 * If this <code>JComponent</code> is a focus cycle root, then its 2636 * <code>FocusTraversalPolicy</code> is used. Otherwise, the 2637 * <code>FocusTraversalPolicy</code> of this <code>JComponent</code>'s 2638 * focus-cycle-root ancestor is used. 2639 * 2640 * @return true if this component can request to get the input focus, 2641 * false if it can not 2642 * @see java.awt.FocusTraversalPolicy#getDefaultComponent 2643 * @deprecated As of 1.4, replaced by 2644 * <code>FocusTraversalPolicy.getDefaultComponent(Container).requestFocus()</code> 2645 */ 2646 @Deprecated 2647 public boolean requestDefaultFocus() { 2648 Container nearestRoot = 2649 (isFocusCycleRoot()) ? this : getFocusCycleRootAncestor(); 2650 if (nearestRoot == null) { 2651 return false; 2652 } 2653 Component comp = nearestRoot.getFocusTraversalPolicy(). 2654 getDefaultComponent(nearestRoot); 2655 if (comp != null) { 2656 comp.requestFocus(); 2657 return true; 2658 } else { 2659 return false; 2660 } 2661 } 2662 2663 /** 2664 * Makes the component visible or invisible. 2665 * Overrides <code>Component.setVisible</code>. 2666 * 2667 * @param aFlag true to make the component visible; false to 2668 * make it invisible 2669 * 2670 * @beaninfo 2671 * attribute: visualUpdate true 2672 */ 2673 public void setVisible(boolean aFlag) { 2674 if (aFlag != isVisible()) { 2675 super.setVisible(aFlag); 2676 if (aFlag) { 2677 Container parent = getParent(); 2678 if (parent != null) { 2679 Rectangle r = getBounds(); 2680 parent.repaint(r.x, r.y, r.width, r.height); 2681 } 2682 revalidate(); 2683 } 2684 } 2685 } 2703 * @beaninfo 2704 * preferred: true 2705 * bound: true 2706 * attribute: visualUpdate true 2707 * description: The enabled state of the component. 2708 */ 2709 public void setEnabled(boolean enabled) { 2710 boolean oldEnabled = isEnabled(); 2711 super.setEnabled(enabled); 2712 firePropertyChange("enabled", oldEnabled, enabled); 2713 if (enabled != oldEnabled) { 2714 repaint(); 2715 } 2716 } 2717 2718 /** 2719 * Sets the foreground color of this component. It is up to the 2720 * look and feel to honor this property, some may choose to ignore 2721 * it. 2722 * 2723 * @param fg the desired foreground <code>Color</code> 2724 * @see java.awt.Component#getForeground 2725 * 2726 * @beaninfo 2727 * preferred: true 2728 * bound: true 2729 * attribute: visualUpdate true 2730 * description: The foreground color of the component. 2731 */ 2732 public void setForeground(Color fg) { 2733 Color oldFg = getForeground(); 2734 super.setForeground(fg); 2735 if ((oldFg != null) ? !oldFg.equals(fg) : ((fg != null) && !fg.equals(oldFg))) { 2736 // foreground already bound in AWT1.2 2737 repaint(); 2738 } 2739 } 2740 2741 /** 2742 * Sets the background color of this component. The background 2743 * color is used only if the component is opaque, and only 2744 * by subclasses of <code>JComponent</code> or 2745 * <code>ComponentUI</code> implementations. Direct subclasses of 2746 * <code>JComponent</code> must override 2747 * <code>paintComponent</code> to honor this property. 2748 * <p> 2749 * It is up to the look and feel to honor this property, some may 2750 * choose to ignore it. 2751 * 2752 * @param bg the desired background <code>Color</code> 2753 * @see java.awt.Component#getBackground 2754 * @see #setOpaque 2755 * 2756 * @beaninfo 2757 * preferred: true 2758 * bound: true 2759 * attribute: visualUpdate true 2760 * description: The background color of the component. 2761 */ 2762 public void setBackground(Color bg) { 2763 Color oldBg = getBackground(); 2764 super.setBackground(bg); 2765 if ((oldBg != null) ? !oldBg.equals(bg) : ((bg != null) && !bg.equals(oldBg))) { 2766 // background already bound in AWT1.2 2767 repaint(); 2768 } 2769 } 2770 2771 /** 2772 * Sets the font for this component. 2773 * 2774 * @param font the desired <code>Font</code> for this component 2775 * @see java.awt.Component#getFont 2776 * 2777 * @beaninfo 2778 * preferred: true 2779 * bound: true 2780 * attribute: visualUpdate true 2781 * description: The font for the component. 2782 */ 2783 public void setFont(Font font) { 2784 Font oldFont = getFont(); 2785 super.setFont(font); 2786 // font already bound in AWT1.2 2787 if (font != oldFont) { 2788 revalidate(); 2789 repaint(); 2790 } 2791 } 2792 2793 /** 2794 * Returns the default locale used to initialize each JComponent's 2795 * locale property upon creation. 2796 * 2797 * The default locale has "AppContext" scope so that applets (and 2798 * potentially multiple lightweight applications running in a single VM) 2799 * can have their own setting. An applet can safely alter its default 2800 * locale because it will have no affect on other applets (or the browser). 2801 * 2802 * @return the default <code>Locale</code>. 2803 * @see #setDefaultLocale 2804 * @see java.awt.Component#getLocale 2805 * @see #setLocale 2806 * @since 1.4 2807 */ 2808 public static Locale getDefaultLocale() { 2809 Locale l = (Locale) SwingUtilities.appContextGet(defaultLocale); 2810 if( l == null ) { 2811 //REMIND(bcb) choosing the default value is more complicated 2812 //than this. 2813 l = Locale.getDefault(); 2814 JComponent.setDefaultLocale( l ); 2815 } 2816 return l; 2817 } 2818 2819 2820 /** 2821 * Sets the default locale used to initialize each JComponent's locale 2822 * property upon creation. The initial value is the VM's default locale. 2823 * 2824 * The default locale has "AppContext" scope so that applets (and 2825 * potentially multiple lightweight applications running in a single VM) 2826 * can have their own setting. An applet can safely alter its default 2827 * locale because it will have no affect on other applets (or the browser). 2828 * 2829 * @param l the desired default <code>Locale</code> for new components. 2830 * @see #getDefaultLocale 2831 * @see java.awt.Component#getLocale 2832 * @see #setLocale 2833 * @since 1.4 2834 */ 2835 public static void setDefaultLocale( Locale l ) { 2836 SwingUtilities.appContextPut(defaultLocale, l); 2837 } 2838 2839 2840 /** 2841 * Processes any key events that the component itself 2842 * recognizes. This is called after the focus 2843 * manager and any interested listeners have been 2844 * given a chance to steal away the event. This 2845 * method is called only if the event has not 2846 * yet been consumed. This method is called prior 2847 * to the keyboard UI logic. 2848 * <p> 2849 * This method is implemented to do nothing. Subclasses would 2850 * normally override this method if they process some 2851 * key events themselves. If the event is processed, 2852 * it should be consumed. 2853 * 2854 * @param e the event to be processed 2855 */ 2856 protected void processComponentKeyEvent(KeyEvent e) { 2857 } 2858 2859 /** Overrides <code>processKeyEvent</code> to process events. **/ 2860 protected void processKeyEvent(KeyEvent e) { 2861 boolean result; 2862 boolean shouldProcessKey; 2863 2864 // This gives the key event listeners a crack at the event 2865 super.processKeyEvent(e); 2866 2867 // give the component itself a crack at the event 2868 if (! e.isConsumed()) { 2869 processComponentKeyEvent(e); 2870 } 2871 2872 shouldProcessKey = KeyboardState.shouldProcess(e); 2873 2874 if(e.isConsumed()) { 2875 return; 2876 } 2877 2878 if (shouldProcessKey && processKeyBindings(e, e.getID() == 2879 KeyEvent.KEY_PRESSED)) { 2880 e.consume(); 2881 } 2882 } 2883 2884 /** 2885 * Invoked to process the key bindings for <code>ks</code> as the result 2886 * of the <code>KeyEvent</code> <code>e</code>. This obtains 2887 * the appropriate <code>InputMap</code>, 2888 * gets the binding, gets the action from the <code>ActionMap</code>, 2889 * and then (if the action is found and the component 2890 * is enabled) invokes <code>notifyAction</code> to notify the action. 2891 * 2892 * @param ks the <code>KeyStroke</code> queried 2893 * @param e the <code>KeyEvent</code> 2894 * @param condition one of the following values: 2895 * <ul> 2896 * <li>JComponent.WHEN_FOCUSED 2897 * <li>JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT 2898 * <li>JComponent.WHEN_IN_FOCUSED_WINDOW 2899 * </ul> 2900 * @param pressed true if the key is pressed 2901 * @return true if there was a binding to an action, and the action 2902 * was enabled 2903 * 2904 * @since 1.3 2905 */ 2906 protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, 2907 int condition, boolean pressed) { 2908 InputMap map = getInputMap(condition, false); 2909 ActionMap am = getActionMap(false); 2910 2911 if(map != null && am != null && isEnabled()) { 2912 Object binding = map.get(ks); 2913 Action action = (binding == null) ? null : am.get(binding); 2914 if (action != null) { 2915 return SwingUtilities.notifyAction(action, ks, e, this, 2916 e.getModifiers()); 2917 } 2918 } 2919 return false; 2920 } 2921 2922 /** 2923 * This is invoked as the result of a <code>KeyEvent</code> 2924 * that was not consumed by the <code>FocusManager</code>, 2925 * <code>KeyListeners</code>, or the component. It will first try 2926 * <code>WHEN_FOCUSED</code> bindings, 2927 * then <code>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT</code> bindings, 2928 * and finally <code>WHEN_IN_FOCUSED_WINDOW</code> bindings. 2929 * 2930 * @param e the unconsumed <code>KeyEvent</code> 2931 * @param pressed true if the key is pressed 2932 * @return true if there is a key binding for <code>e</code> 2933 */ 2934 boolean processKeyBindings(KeyEvent e, boolean pressed) { 2935 if (!SwingUtilities.isValidKeyEventForKeyBindings(e)) { 2936 return false; 2937 } 2938 // Get the KeyStroke 2939 // There may be two keystrokes associated with a low-level key event; 2940 // in this case a keystroke made of an extended key code has a priority. 2941 KeyStroke ks; 2942 KeyStroke ksE = null; 2943 2944 if (e.getID() == KeyEvent.KEY_TYPED) { 2945 ks = KeyStroke.getKeyStroke(e.getKeyChar()); 2946 } 2947 else { 2948 ks = KeyStroke.getKeyStroke(e.getKeyCode(),e.getModifiers(), 2949 (pressed ? false:true)); 2950 if (e.getKeyCode() != e.getExtendedKeyCode()) { 2951 ksE = KeyStroke.getKeyStroke(e.getExtendedKeyCode(),e.getModifiers(), 2952 (pressed ? false:true)); 3008 e, pressed, container)) { 3009 return true; 3010 } 3011 if (container instanceof Popup.HeavyWeightWindow) { 3012 container = ((Window)container).getOwner(); 3013 } 3014 else { 3015 return false; 3016 } 3017 } 3018 } 3019 3020 /** 3021 * Registers the text to display in a tool tip. 3022 * The text displays when the cursor lingers over the component. 3023 * <p> 3024 * See <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/tooltip.html">How to Use Tool Tips</a> 3025 * in <em>The Java Tutorial</em> 3026 * for further documentation. 3027 * 3028 * @param text the string to display; if the text is <code>null</code>, 3029 * the tool tip is turned off for this component 3030 * @see #TOOL_TIP_TEXT_KEY 3031 * @beaninfo 3032 * preferred: true 3033 * description: The text to display in a tool tip. 3034 */ 3035 public void setToolTipText(String text) { 3036 String oldText = getToolTipText(); 3037 putClientProperty(TOOL_TIP_TEXT_KEY, text); 3038 ToolTipManager toolTipManager = ToolTipManager.sharedInstance(); 3039 if (text != null) { 3040 if (oldText == null) { 3041 toolTipManager.registerComponent(this); 3042 } 3043 } else { 3044 toolTipManager.unregisterComponent(this); 3045 } 3046 } 3047 3048 /** 3049 * Returns the tooltip string that has been set with 3050 * <code>setToolTipText</code>. 3051 * 3052 * @return the text of the tool tip 3053 * @see #TOOL_TIP_TEXT_KEY 3054 */ 3055 public String getToolTipText() { 3056 return (String)getClientProperty(TOOL_TIP_TEXT_KEY); 3057 } 3058 3059 3060 /** 3061 * Returns the string to be used as the tooltip for <i>event</i>. 3062 * By default this returns any string set using 3063 * <code>setToolTipText</code>. If a component provides 3064 * more extensive API to support differing tooltips at different locations, 3065 * this method should be overridden. 3066 * 3067 * @param event the {@code MouseEvent} that initiated the 3068 * {@code ToolTip} display 3069 * @return a string containing the tooltip 3070 */ 3071 public String getToolTipText(MouseEvent event) { 3072 return getToolTipText(); 3073 } 3074 3075 /** 3076 * Returns the tooltip location in this component's coordinate system. 3077 * If <code>null</code> is returned, Swing will choose a location. 3078 * The default implementation returns <code>null</code>. 3079 * 3080 * @param event the <code>MouseEvent</code> that caused the 3081 * <code>ToolTipManager</code> to show the tooltip 3082 * @return always returns <code>null</code> 3083 */ 3084 public Point getToolTipLocation(MouseEvent event) { 3085 return null; 3086 } 3087 3088 /** 3089 * Returns the preferred location to display the popup menu in this 3090 * component's coordinate system. It is up to the look and feel to 3091 * honor this property, some may choose to ignore it. 3092 * If {@code null}, the look and feel will choose a suitable location. 3093 * 3094 * @param event the {@code MouseEvent} that triggered the popup to be 3095 * shown, or {@code null} if the popup is not being shown as the 3096 * result of a mouse event 3097 * @return location to display the {@code JPopupMenu}, or {@code null} 3098 * @since 1.5 3099 */ 3100 public Point getPopupLocation(MouseEvent event) { 3101 return null; 3102 } 3103 3104 3105 /** 3106 * Returns the instance of <code>JToolTip</code> that should be used 3107 * to display the tooltip. 3108 * Components typically would not override this method, 3109 * but it can be used to 3110 * cause different tooltips to be displayed differently. 3111 * 3112 * @return the <code>JToolTip</code> used to display this toolTip 3113 */ 3114 public JToolTip createToolTip() { 3115 JToolTip tip = new JToolTip(); 3116 tip.setComponent(this); 3117 return tip; 3118 } 3119 3120 /** 3121 * Forwards the <code>scrollRectToVisible()</code> message to the 3122 * <code>JComponent</code>'s parent. Components that can service 3123 * the request, such as <code>JViewport</code>, 3124 * override this method and perform the scrolling. 3125 * 3126 * @param aRect the visible <code>Rectangle</code> 3127 * @see JViewport 3128 */ 3129 public void scrollRectToVisible(Rectangle aRect) { 3130 Container parent; 3131 int dx = getX(), dy = getY(); 3132 3133 for (parent = getParent(); 3134 !(parent == null) && 3135 !(parent instanceof JComponent) && 3136 !(parent instanceof CellRendererPane); 3137 parent = parent.getParent()) { 3138 Rectangle bounds = parent.getBounds(); 3139 3140 dx += bounds.x; 3141 dy += bounds.y; 3142 } 3143 3144 if (!(parent == null) && !(parent instanceof CellRendererPane)) { 3145 aRect.x += dx; 3146 aRect.y += dy; 3147 3148 ((JComponent)parent).scrollRectToVisible(aRect); 3149 aRect.x -= dx; 3150 aRect.y -= dy; 3151 } 3152 } 3153 3154 /** 3155 * Sets the <code>autoscrolls</code> property. 3156 * If <code>true</code> mouse dragged events will be 3157 * synthetically generated when the mouse is dragged 3158 * outside of the component's bounds and mouse motion 3159 * has paused (while the button continues to be held 3160 * down). The synthetic events make it appear that the 3161 * drag gesture has resumed in the direction established when 3162 * the component's boundary was crossed. Components that 3163 * support autoscrolling must handle <code>mouseDragged</code> 3164 * events by calling <code>scrollRectToVisible</code> with a 3165 * rectangle that contains the mouse event's location. All of 3166 * the Swing components that support item selection and are 3167 * typically displayed in a <code>JScrollPane</code> 3168 * (<code>JTable</code>, <code>JList</code>, <code>JTree</code>, 3169 * <code>JTextArea</code>, and <code>JEditorPane</code>) 3170 * already handle mouse dragged events in this way. To enable 3171 * autoscrolling in any other component, add a mouse motion 3172 * listener that calls <code>scrollRectToVisible</code>. 3173 * For example, given a <code>JPanel</code>, <code>myPanel</code>: 3174 * <pre> 3175 * MouseMotionListener doScrollRectToVisible = new MouseMotionAdapter() { 3176 * public void mouseDragged(MouseEvent e) { 3177 * Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1); 3178 * ((JPanel)e.getSource()).scrollRectToVisible(r); 3179 * } 3180 * }; 3181 * myPanel.addMouseMotionListener(doScrollRectToVisible); 3182 * </pre> 3183 * The default value of the <code>autoScrolls</code> 3184 * property is <code>false</code>. 3185 * 3186 * @param autoscrolls if true, synthetic mouse dragged events 3187 * are generated when the mouse is dragged outside of a component's 3188 * bounds and the mouse button continues to be held down; otherwise 3189 * false 3190 * @see #getAutoscrolls 3191 * @see JViewport 3192 * @see JScrollPane 3193 * 3194 * @beaninfo 3195 * expert: true 3196 * description: Determines if this component automatically scrolls its contents when dragged. 3197 */ 3198 public void setAutoscrolls(boolean autoscrolls) { 3199 setFlag(AUTOSCROLLS_SET, true); 3200 if (this.autoscrolls != autoscrolls) { 3201 this.autoscrolls = autoscrolls; 3202 if (autoscrolls) { 3203 enableEvents(AWTEvent.MOUSE_EVENT_MASK); 3204 enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK); 3205 } 3206 else { 3207 Autoscroller.stop(this); 3208 } 3209 } 3210 } 3211 3212 /** 3213 * Gets the <code>autoscrolls</code> property. 3214 * 3215 * @return the value of the <code>autoscrolls</code> property 3216 * @see JViewport 3217 * @see #setAutoscrolls 3218 */ 3219 public boolean getAutoscrolls() { 3220 return autoscrolls; 3221 } 3222 3223 /** 3224 * Sets the {@code TransferHandler}, which provides support for transfer 3225 * of data into and out of this component via cut/copy/paste and drag 3226 * and drop. This may be {@code null} if the component does not support 3227 * data transfer operations. 3228 * <p> 3229 * If the new {@code TransferHandler} is not {@code null}, this method 3230 * also installs a <b>new</b> {@code DropTarget} on the component to 3231 * activate drop handling through the {@code TransferHandler} and activate 3232 * any built-in support (such as calculating and displaying potential drop 3233 * locations). If you do not wish for this component to respond in any way 3234 * to drops, you can disable drop support entirely either by removing the 3235 * drop target ({@code setDropTarget(null)}) or by de-activating it 3252 * @param newHandler the new {@code TransferHandler} 3253 * 3254 * @see TransferHandler 3255 * @see #getTransferHandler 3256 * @since 1.4 3257 * @beaninfo 3258 * bound: true 3259 * hidden: true 3260 * description: Mechanism for transfer of data to and from the component 3261 */ 3262 public void setTransferHandler(TransferHandler newHandler) { 3263 TransferHandler oldHandler = (TransferHandler)getClientProperty( 3264 JComponent_TRANSFER_HANDLER); 3265 putClientProperty(JComponent_TRANSFER_HANDLER, newHandler); 3266 3267 SwingUtilities.installSwingDropTargetAsNecessary(this, newHandler); 3268 firePropertyChange("transferHandler", oldHandler, newHandler); 3269 } 3270 3271 /** 3272 * Gets the <code>transferHandler</code> property. 3273 * 3274 * @return the value of the <code>transferHandler</code> property 3275 * 3276 * @see TransferHandler 3277 * @see #setTransferHandler 3278 * @since 1.4 3279 */ 3280 public TransferHandler getTransferHandler() { 3281 return (TransferHandler)getClientProperty(JComponent_TRANSFER_HANDLER); 3282 } 3283 3284 /** 3285 * Calculates a custom drop location for this type of component, 3286 * representing where a drop at the given point should insert data. 3287 * <code>null</code> is returned if this component doesn't calculate 3288 * custom drop locations. In this case, <code>TransferHandler</code> 3289 * will provide a default <code>DropLocation</code> containing just 3290 * the point. 3291 * 3292 * @param p the point to calculate a drop location for 3293 * @return the drop location, or <code>null</code> 3294 */ 3295 TransferHandler.DropLocation dropLocationForPoint(Point p) { 3296 return null; 3297 } 3298 3299 /** 3300 * Called to set or clear the drop location during a DnD operation. 3301 * In some cases, the component may need to use its internal selection 3302 * temporarily to indicate the drop location. To help facilitate this, 3303 * this method returns and accepts as a parameter a state object. 3304 * This state object can be used to store, and later restore, the selection 3305 * state. Whatever this method returns will be passed back to it in 3306 * future calls, as the state parameter. If it wants the DnD system to 3307 * continue storing the same state, it must pass it back every time. 3308 * Here's how this is used: 3309 * <p> 3310 * Let's say that on the first call to this method the component decides 3311 * to save some state (because it is about to use the selection to show 3312 * a drop index). It can return a state object to the caller encapsulating 3313 * any saved selection state. On a second call, let's say the drop location 3314 * is being changed to something else. The component doesn't need to 3315 * restore anything yet, so it simply passes back the same state object 3316 * to have the DnD system continue storing it. Finally, let's say this 3317 * method is messaged with <code>null</code>. This means DnD 3318 * is finished with this component for now, meaning it should restore 3319 * state. At this point, it can use the state parameter to restore 3320 * said state, and of course return <code>null</code> since there's 3321 * no longer anything to store. 3322 * 3323 * @param location the drop location (as calculated by 3324 * <code>dropLocationForPoint</code>) or <code>null</code> 3325 * if there's no longer a valid drop location 3326 * @param state the state object saved earlier for this component, 3327 * or <code>null</code> 3328 * @param forDrop whether or not the method is being called because an 3329 * actual drop occurred 3330 * @return any saved state for this component, or <code>null</code> if none 3331 */ 3332 Object setDropLocation(TransferHandler.DropLocation location, 3333 Object state, 3334 boolean forDrop) { 3335 3336 return null; 3337 } 3338 3339 /** 3340 * Called to indicate to this component that DnD is done. 3341 * Needed by <code>JTree</code>. 3342 */ 3343 void dndDone() { 3344 } 3345 3346 /** 3347 * Processes mouse events occurring on this component by 3348 * dispatching them to any registered 3349 * <code>MouseListener</code> objects, refer to 3350 * {@link java.awt.Component#processMouseEvent(MouseEvent)} 3351 * for a complete description of this method. 3352 * 3353 * @param e the mouse event 3354 * @see java.awt.Component#processMouseEvent 3355 * @since 1.5 3356 */ 3357 protected void processMouseEvent(MouseEvent e) { 3358 if (autoscrolls && e.getID() == MouseEvent.MOUSE_RELEASED) { 3359 Autoscroller.stop(this); 3360 } 3361 super.processMouseEvent(e); 3362 } 3363 3364 /** 3365 * Processes mouse motion events, such as MouseEvent.MOUSE_DRAGGED. 3366 * 3367 * @param e the <code>MouseEvent</code> 3368 * @see MouseEvent 3369 */ 3370 protected void processMouseMotionEvent(MouseEvent e) { 3371 boolean dispatch = true; 3372 if (autoscrolls && e.getID() == MouseEvent.MOUSE_DRAGGED) { 3373 // We don't want to do the drags when the mouse moves if we're 3374 // autoscrolling. It makes it feel spastic. 3375 dispatch = !Autoscroller.isRunning(this); 3376 Autoscroller.processMouseDragged(e); 3377 } 3378 if (dispatch) { 3379 super.processMouseMotionEvent(e); 3380 } 3381 } 3382 3383 // Inner classes can't get at this method from a super class 3384 void superProcessMouseMotionEvent(MouseEvent e) { 3385 super.processMouseMotionEvent(e); 3386 } 3387 3388 /** 3389 * This is invoked by the <code>RepaintManager</code> if 3390 * <code>createImage</code> is called on the component. 3391 * 3392 * @param newValue true if the double buffer image was created from this component 3393 */ 3394 void setCreatedDoubleBuffer(boolean newValue) { 3395 setFlag(CREATED_DOUBLE_BUFFER, newValue); 3396 } 3397 3398 /** 3399 * Returns true if the <code>RepaintManager</code> 3400 * created the double buffer image from the component. 3401 * 3402 * @return true if this component had a double buffer image, false otherwise 3403 */ 3404 boolean getCreatedDoubleBuffer() { 3405 return getFlag(CREATED_DOUBLE_BUFFER); 3406 } 3407 3408 /** 3409 * <code>ActionStandin</code> is used as a standin for 3410 * <code>ActionListeners</code> that are 3411 * added via <code>registerKeyboardAction</code>. 3412 */ 3413 final class ActionStandin implements Action { 3414 private final ActionListener actionListener; 3415 private final String command; 3416 // This will be non-null if actionListener is an Action. 3417 private final Action action; 3418 3419 ActionStandin(ActionListener actionListener, String command) { 3420 this.actionListener = actionListener; 3421 if (actionListener instanceof Action) { 3422 this.action = (Action)actionListener; 3423 } 3424 else { 3425 this.action = null; 3426 } 3427 this.command = command; 3428 } 3429 3430 public Object getValue(String key) { 3431 if (key != null) { 3635 // we ensure that if the InputVerifier for 3636 // currentSource does a requestFocus, we don't 3637 // try and run the InputVerifier again. 3638 SwingUtilities.appContextPut( 3639 INPUT_VERIFIER_SOURCE_KEY, currentSource); 3640 } else { 3641 SwingUtilities.appContextRemove( 3642 INPUT_VERIFIER_SOURCE_KEY); 3643 } 3644 } 3645 } 3646 } 3647 }; 3648 3649 /* 3650 * --- Accessibility Support --- 3651 */ 3652 3653 /** 3654 * @deprecated As of JDK version 1.1, 3655 * replaced by <code>java.awt.Component.setEnabled(boolean)</code>. 3656 */ 3657 @Deprecated 3658 public void enable() { 3659 if (isEnabled() != true) { 3660 super.enable(); 3661 if (accessibleContext != null) { 3662 accessibleContext.firePropertyChange( 3663 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 3664 null, AccessibleState.ENABLED); 3665 } 3666 } 3667 } 3668 3669 /** 3670 * @deprecated As of JDK version 1.1, 3671 * replaced by <code>java.awt.Component.setEnabled(boolean)</code>. 3672 */ 3673 @Deprecated 3674 public void disable() { 3675 if (isEnabled() != false) { 3676 super.disable(); 3677 if (accessibleContext != null) { 3678 accessibleContext.firePropertyChange( 3679 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 3680 AccessibleState.ENABLED, null); 3681 } 3682 } 3683 } 3684 3685 /** 3686 * Inner class of JComponent used to provide default support for 3687 * accessibility. This class is not meant to be used directly by 3688 * application developers, but is instead meant only to be 3689 * subclassed by component developers. 3690 * <p> 3691 * <strong>Warning:</strong> 3692 * Serialized objects of this class will not be compatible with 3693 * future Swing releases. The current serialization support is 3694 * appropriate for short term storage or RMI between applications running 3695 * the same version of Swing. As of 1.4, support for long term storage 3696 * of all JavaBeans™ 3697 * has been added to the <code>java.beans</code> package. 3698 * Please see {@link java.beans.XMLEncoder}. 3699 */ 3700 @SuppressWarnings("serial") // Same-version serialization only 3701 public abstract class AccessibleJComponent extends AccessibleAWTContainer 3702 implements AccessibleExtendedComponent 3703 { 3704 /** 3705 * Though the class is abstract, this should be called by 3706 * all sub-classes. 3707 */ 3708 protected AccessibleJComponent() { 3709 super(); 3710 } 3711 3712 /** 3713 * Number of PropertyChangeListener objects registered. It's used 3714 * to add/remove ContainerListener and FocusListener to track 3715 * target JComponent's state 3716 */ 3717 private transient volatile int propertyListenersCount = 0; 4016 * @since 1.4 4017 */ 4018 public AccessibleKeyBinding getAccessibleKeyBinding(){ 4019 // Try to get the linked label's mnemonic if it exists 4020 Object o = getClientProperty(JLabel.LABELED_BY_PROPERTY); 4021 if (o instanceof Accessible){ 4022 AccessibleContext ac = ((Accessible) o).getAccessibleContext(); 4023 if (ac != null){ 4024 AccessibleComponent comp = ac.getAccessibleComponent(); 4025 if (! (comp instanceof AccessibleExtendedComponent)) 4026 return null; 4027 return ((AccessibleExtendedComponent)comp).getAccessibleKeyBinding(); 4028 } 4029 } 4030 return null; 4031 } 4032 } // inner class AccessibleJComponent 4033 4034 4035 /** 4036 * Returns an <code>ArrayTable</code> used for 4037 * key/value "client properties" for this component. If the 4038 * <code>clientProperties</code> table doesn't exist, an empty one 4039 * will be created. 4040 * 4041 * @return an ArrayTable 4042 * @see #putClientProperty 4043 * @see #getClientProperty 4044 */ 4045 private ArrayTable getClientProperties() { 4046 if (clientProperties == null) { 4047 clientProperties = new ArrayTable(); 4048 } 4049 return clientProperties; 4050 } 4051 4052 4053 /** 4054 * Returns the value of the property with the specified key. Only 4055 * properties added with <code>putClientProperty</code> will return 4056 * a non-<code>null</code> value. 4057 * 4058 * @param key the being queried 4059 * @return the value of this property or <code>null</code> 4060 * @see #putClientProperty 4061 */ 4062 public final Object getClientProperty(Object key) { 4063 if (key == RenderingHints.KEY_TEXT_ANTIALIASING) { 4064 return aaHint; 4065 } else if (key == RenderingHints.KEY_TEXT_LCD_CONTRAST) { 4066 return lcdRenderingHint; 4067 } 4068 if(clientProperties == null) { 4069 return null; 4070 } else { 4071 synchronized(clientProperties) { 4072 return clientProperties.get(key); 4073 } 4074 } 4075 } 4076 4077 /** 4078 * Adds an arbitrary key/value "client property" to this component. 4079 * <p> 4080 * The <code>get/putClientProperty</code> methods provide access to 4081 * a small per-instance hashtable. Callers can use get/putClientProperty 4082 * to annotate components that were created by another module. 4083 * For example, a 4084 * layout manager might store per child constraints this way. For example: 4085 * <pre> 4086 * componentA.putClientProperty("to the left of", componentB); 4087 * </pre> 4088 * If value is <code>null</code> this method will remove the property. 4089 * Changes to client properties are reported with 4090 * <code>PropertyChange</code> events. 4091 * The name of the property (for the sake of PropertyChange 4092 * events) is <code>key.toString()</code>. 4093 * <p> 4094 * The <code>clientProperty</code> dictionary is not intended to 4095 * support large 4096 * scale extensions to JComponent nor should be it considered an 4097 * alternative to subclassing when designing a new component. 4098 * 4099 * @param key the new client property key 4100 * @param value the new client property value; if <code>null</code> 4101 * this method will remove the property 4102 * @see #getClientProperty 4103 * @see #addPropertyChangeListener 4104 */ 4105 public final void putClientProperty(Object key, Object value) { 4106 if (key == RenderingHints.KEY_TEXT_ANTIALIASING) { 4107 aaHint = value; 4108 return; 4109 } else if (key == RenderingHints.KEY_TEXT_LCD_CONTRAST) { 4110 lcdRenderingHint = value; 4111 return; 4112 } 4113 if (value == null && clientProperties == null) { 4114 // Both the value and ArrayTable are null, implying we don't 4115 // have to do anything. 4116 return; 4117 } 4118 ArrayTable clientProperties = getClientProperties(); 4119 Object oldValue; 4120 synchronized(clientProperties) { 4226 * The methods and fields in this section will migrate to 4227 * java.awt.Component in the next JDK release. 4228 */ 4229 4230 /** 4231 * Returns true if this component is lightweight, that is, if it doesn't 4232 * have a native window system peer. 4233 * 4234 * @param c the {@code Component} to be checked 4235 * @return true if this component is lightweight 4236 */ 4237 public static boolean isLightweightComponent(Component c) { 4238 // TODO we cannot call c.isLightweight() because it is incorrectly 4239 // overriden in DelegateContainer on osx. 4240 return AWTAccessor.getComponentAccessor().isLightweight(c); 4241 } 4242 4243 4244 /** 4245 * @deprecated As of JDK 5, 4246 * replaced by <code>Component.setBounds(int, int, int, int)</code>. 4247 * <p> 4248 * Moves and resizes this component. 4249 * 4250 * @param x the new horizontal location 4251 * @param y the new vertical location 4252 * @param w the new width 4253 * @param h the new height 4254 * @see java.awt.Component#setBounds 4255 */ 4256 @Deprecated 4257 public void reshape(int x, int y, int w, int h) { 4258 super.reshape(x, y, w, h); 4259 } 4260 4261 4262 /** 4263 * Stores the bounds of this component into "return value" 4264 * <code>rv</code> and returns <code>rv</code>. 4265 * If <code>rv</code> is <code>null</code> a new <code>Rectangle</code> 4266 * is allocated. This version of <code>getBounds</code> is useful 4267 * if the caller wants to avoid allocating a new <code>Rectangle</code> 4268 * object on the heap. 4269 * 4270 * @param rv the return value, modified to the component's bounds 4271 * @return <code>rv</code>; if <code>rv</code> is <code>null</code> 4272 * return a newly created <code>Rectangle</code> with this 4273 * component's bounds 4274 */ 4275 public Rectangle getBounds(Rectangle rv) { 4276 if (rv == null) { 4277 return new Rectangle(getX(), getY(), getWidth(), getHeight()); 4278 } 4279 else { 4280 rv.setBounds(getX(), getY(), getWidth(), getHeight()); 4281 return rv; 4282 } 4283 } 4284 4285 4286 /** 4287 * Stores the width/height of this component into "return value" 4288 * <code>rv</code> and returns <code>rv</code>. 4289 * If <code>rv</code> is <code>null</code> a new <code>Dimension</code> 4290 * object is allocated. This version of <code>getSize</code> 4291 * is useful if the caller wants to avoid allocating a new 4292 * <code>Dimension</code> object on the heap. 4293 * 4294 * @param rv the return value, modified to the component's size 4295 * @return <code>rv</code> 4296 */ 4297 public Dimension getSize(Dimension rv) { 4298 if (rv == null) { 4299 return new Dimension(getWidth(), getHeight()); 4300 } 4301 else { 4302 rv.setSize(getWidth(), getHeight()); 4303 return rv; 4304 } 4305 } 4306 4307 4308 /** 4309 * Stores the x,y origin of this component into "return value" 4310 * <code>rv</code> and returns <code>rv</code>. 4311 * If <code>rv</code> is <code>null</code> a new <code>Point</code> 4312 * is allocated. This version of <code>getLocation</code> is useful 4313 * if the caller wants to avoid allocating a new <code>Point</code> 4314 * object on the heap. 4315 * 4316 * @param rv the return value, modified to the component's location 4317 * @return <code>rv</code> 4318 */ 4319 public Point getLocation(Point rv) { 4320 if (rv == null) { 4321 return new Point(getX(), getY()); 4322 } 4323 else { 4324 rv.setLocation(getX(), getY()); 4325 return rv; 4326 } 4327 } 4328 4329 4330 /** 4331 * Returns the current x coordinate of the component's origin. 4332 * This method is preferable to writing 4333 * <code>component.getBounds().x</code>, or 4334 * <code>component.getLocation().x</code> because it doesn't cause any 4335 * heap allocations. 4336 * 4337 * @return the current x coordinate of the component's origin 4338 */ 4339 public int getX() { return super.getX(); } 4340 4341 4342 /** 4343 * Returns the current y coordinate of the component's origin. 4344 * This method is preferable to writing 4345 * <code>component.getBounds().y</code>, or 4346 * <code>component.getLocation().y</code> because it doesn't cause any 4347 * heap allocations. 4348 * 4349 * @return the current y coordinate of the component's origin 4350 */ 4351 public int getY() { return super.getY(); } 4352 4353 4354 /** 4355 * Returns the current width of this component. 4356 * This method is preferable to writing 4357 * <code>component.getBounds().width</code>, or 4358 * <code>component.getSize().width</code> because it doesn't cause any 4359 * heap allocations. 4360 * 4361 * @return the current width of this component 4362 */ 4363 public int getWidth() { return super.getWidth(); } 4364 4365 4366 /** 4367 * Returns the current height of this component. 4368 * This method is preferable to writing 4369 * <code>component.getBounds().height</code>, or 4370 * <code>component.getSize().height</code> because it doesn't cause any 4371 * heap allocations. 4372 * 4373 * @return the current height of this component 4374 */ 4375 public int getHeight() { return super.getHeight(); } 4376 4377 /** 4378 * Returns true if this component is completely opaque. 4379 * <p> 4380 * An opaque component paints every pixel within its 4381 * rectangular bounds. A non-opaque component paints only a subset of 4382 * its pixels or none at all, allowing the pixels underneath it to 4383 * "show through". Therefore, a component that does not fully paint 4384 * its pixels provides a degree of transparency. 4385 * <p> 4386 * Subclasses that guarantee to always completely paint their contents 4387 * should override this method and return true. 4388 * 4389 * @return true if this component is completely opaque 4390 * @see #setOpaque 4391 */ 4392 public boolean isOpaque() { 4393 return getFlag(IS_OPAQUE); 4394 } 4395 4396 /** 4397 * If true the component paints every pixel within its bounds. 4398 * Otherwise, the component may not paint some or all of its 4399 * pixels, allowing the underlying pixels to show through. 4400 * <p> 4401 * The default value of this property is false for <code>JComponent</code>. 4402 * However, the default value for this property on most standard 4403 * <code>JComponent</code> subclasses (such as <code>JButton</code> and 4404 * <code>JTree</code>) is look-and-feel dependent. 4405 * 4406 * @param isOpaque true if this component should be opaque 4407 * @see #isOpaque 4408 * @beaninfo 4409 * bound: true 4410 * expert: true 4411 * description: The component's opacity 4412 */ 4413 public void setOpaque(boolean isOpaque) { 4414 boolean oldValue = getFlag(IS_OPAQUE); 4415 setFlag(IS_OPAQUE, isOpaque); 4416 setFlag(OPAQUE_SET, true); 4417 firePropertyChange("opaque", oldValue, isOpaque); 4418 } 4419 4420 4421 /** 4422 * If the specified rectangle is completely obscured by any of this 4423 * component's opaque children then returns true. Only direct children 4424 * are considered, more distant descendants are ignored. A 4425 * <code>JComponent</code> is opaque if 4426 * <code>JComponent.isOpaque()</code> returns true, other lightweight 4427 * components are always considered transparent, and heavyweight components 4428 * are always considered opaque. 4429 * 4430 * @param x x value of specified rectangle 4431 * @param y y value of specified rectangle 4432 * @param width width of specified rectangle 4433 * @param height height of specified rectangle 4434 * @return true if the specified rectangle is obscured by an opaque child 4435 */ 4436 boolean rectangleIsObscured(int x,int y,int width,int height) 4437 { 4438 int numChildren = getComponentCount(); 4439 4440 for(int i = 0; i < numChildren; i++) { 4441 Component child = getComponent(i); 4442 int cx, cy, cw, ch; 4443 4444 cx = child.getX(); 4445 cy = child.getY(); 4446 cw = child.getWidth(); 4451 4452 if(child instanceof JComponent) { 4453 // System.out.println("A) checking opaque: " + ((JComponent)child).isOpaque() + " " + child); 4454 // System.out.print("B) "); 4455 // Thread.dumpStack(); 4456 return child.isOpaque(); 4457 } else { 4458 /** Sometimes a heavy weight can have a bound larger than its peer size 4459 * so we should always draw under heavy weights 4460 */ 4461 return false; 4462 } 4463 } 4464 } 4465 4466 return false; 4467 } 4468 4469 4470 /** 4471 * Returns the <code>Component</code>'s "visible rect rectangle" - the 4472 * intersection of the visible rectangles for the component <code>c</code> 4473 * and all of its ancestors. The return value is stored in 4474 * <code>visibleRect</code>. 4475 * 4476 * @param c the component 4477 * @param visibleRect a <code>Rectangle</code> computed as the 4478 * intersection of all visible rectangles for the component 4479 * <code>c</code> and all of its ancestors -- this is the 4480 * return value for this method 4481 * @see #getVisibleRect 4482 */ 4483 static final void computeVisibleRect(Component c, Rectangle visibleRect) { 4484 Container p = c.getParent(); 4485 Rectangle bounds = c.getBounds(); 4486 4487 if (p == null || p instanceof Window || p instanceof Applet) { 4488 visibleRect.setBounds(0, 0, bounds.width, bounds.height); 4489 } else { 4490 computeVisibleRect(p, visibleRect); 4491 visibleRect.x -= bounds.x; 4492 visibleRect.y -= bounds.y; 4493 SwingUtilities.computeIntersection(0,0,bounds.width,bounds.height,visibleRect); 4494 } 4495 } 4496 4497 4498 /** 4499 * Returns the <code>Component</code>'s "visible rect rectangle" - the 4500 * intersection of the visible rectangles for this component 4501 * and all of its ancestors. The return value is stored in 4502 * <code>visibleRect</code>. 4503 * 4504 * @param visibleRect a <code>Rectangle</code> computed as the 4505 * intersection of all visible rectangles for this 4506 * component and all of its ancestors -- this is the return 4507 * value for this method 4508 * @see #getVisibleRect 4509 */ 4510 public void computeVisibleRect(Rectangle visibleRect) { 4511 computeVisibleRect(this, visibleRect); 4512 } 4513 4514 4515 /** 4516 * Returns the <code>Component</code>'s "visible rectangle" - the 4517 * intersection of this component's visible rectangle, 4518 * <code>new Rectangle(0, 0, getWidth(), getHeight())</code>, 4519 * and all of its ancestors' visible rectangles. 4520 * 4521 * @return the visible rectangle 4522 */ 4523 public Rectangle getVisibleRect() { 4524 Rectangle visibleRect = new Rectangle(); 4525 4526 computeVisibleRect(visibleRect); 4527 return visibleRect; 4528 } 4529 4530 /** 4531 * Support for reporting bound property changes for boolean properties. 4532 * This method can be called when a bound property has changed and it will 4533 * send the appropriate PropertyChangeEvent to any registered 4534 * PropertyChangeListeners. 4535 * 4536 * @param propertyName the property whose value has changed 4537 * @param oldValue the property's previous value 4538 * @param newValue the property's new value 4550 * PropertyChangeListeners. 4551 * 4552 * @param propertyName the property whose value has changed 4553 * @param oldValue the property's previous value 4554 * @param newValue the property's new value 4555 */ 4556 public void firePropertyChange(String propertyName, 4557 int oldValue, int newValue) { 4558 super.firePropertyChange(propertyName, oldValue, newValue); 4559 } 4560 4561 // XXX This method is implemented as a workaround to a JLS issue with ambiguous 4562 // methods. This should be removed once 4758654 is resolved. 4563 public void firePropertyChange(String propertyName, char oldValue, char newValue) { 4564 super.firePropertyChange(propertyName, oldValue, newValue); 4565 } 4566 4567 /** 4568 * Supports reporting constrained property changes. 4569 * This method can be called when a constrained property has changed 4570 * and it will send the appropriate <code>PropertyChangeEvent</code> 4571 * to any registered <code>VetoableChangeListeners</code>. 4572 * 4573 * @param propertyName the name of the property that was listened on 4574 * @param oldValue the old value of the property 4575 * @param newValue the new value of the property 4576 * @exception java.beans.PropertyVetoException when the attempt to set the 4577 * property is vetoed by the component 4578 */ 4579 protected void fireVetoableChange(String propertyName, Object oldValue, Object newValue) 4580 throws java.beans.PropertyVetoException 4581 { 4582 if (vetoableChangeSupport == null) { 4583 return; 4584 } 4585 vetoableChangeSupport.fireVetoableChange(propertyName, oldValue, newValue); 4586 } 4587 4588 4589 /** 4590 * Adds a <code>VetoableChangeListener</code> to the listener list. 4591 * The listener is registered for all properties. 4592 * 4593 * @param listener the <code>VetoableChangeListener</code> to be added 4594 */ 4595 public synchronized void addVetoableChangeListener(VetoableChangeListener listener) { 4596 if (vetoableChangeSupport == null) { 4597 vetoableChangeSupport = new java.beans.VetoableChangeSupport(this); 4598 } 4599 vetoableChangeSupport.addVetoableChangeListener(listener); 4600 } 4601 4602 4603 /** 4604 * Removes a <code>VetoableChangeListener</code> from the listener list. 4605 * This removes a <code>VetoableChangeListener</code> that was registered 4606 * for all properties. 4607 * 4608 * @param listener the <code>VetoableChangeListener</code> to be removed 4609 */ 4610 public synchronized void removeVetoableChangeListener(VetoableChangeListener listener) { 4611 if (vetoableChangeSupport == null) { 4612 return; 4613 } 4614 vetoableChangeSupport.removeVetoableChangeListener(listener); 4615 } 4616 4617 4618 /** 4619 * Returns an array of all the vetoable change listeners 4620 * registered on this component. 4621 * 4622 * @return all of the component's <code>VetoableChangeListener</code>s 4623 * or an empty 4624 * array if no vetoable change listeners are currently registered 4625 * 4626 * @see #addVetoableChangeListener 4627 * @see #removeVetoableChangeListener 4628 * 4629 * @since 1.4 4630 */ 4631 public synchronized VetoableChangeListener[] getVetoableChangeListeners() { 4632 if (vetoableChangeSupport == null) { 4633 return new VetoableChangeListener[0]; 4634 } 4635 return vetoableChangeSupport.getVetoableChangeListeners(); 4636 } 4637 4638 4639 /** 4640 * Returns the top-level ancestor of this component (either the 4641 * containing <code>Window</code> or <code>Applet</code>), 4642 * or <code>null</code> if this component has not 4643 * been added to any container. 4644 * 4645 * @return the top-level <code>Container</code> that this component is in, 4646 * or <code>null</code> if not in any container 4647 */ 4648 public Container getTopLevelAncestor() { 4649 for(Container p = this; p != null; p = p.getParent()) { 4650 if(p instanceof Window || p instanceof Applet) { 4651 return p; 4652 } 4653 } 4654 return null; 4655 } 4656 4657 private AncestorNotifier getAncestorNotifier() { 4658 return (AncestorNotifier) 4659 getClientProperty(JComponent_ANCESTOR_NOTIFIER); 4660 } 4661 4662 /** 4663 * Registers <code>listener</code> so that it will receive 4664 * <code>AncestorEvents</code> when it or any of its ancestors 4665 * move or are made visible or invisible. 4666 * Events are also sent when the component or its ancestors are added 4667 * or removed from the containment hierarchy. 4668 * 4669 * @param listener the <code>AncestorListener</code> to register 4670 * @see AncestorEvent 4671 */ 4672 public void addAncestorListener(AncestorListener listener) { 4673 AncestorNotifier ancestorNotifier = getAncestorNotifier(); 4674 if (ancestorNotifier == null) { 4675 ancestorNotifier = new AncestorNotifier(this); 4676 putClientProperty(JComponent_ANCESTOR_NOTIFIER, 4677 ancestorNotifier); 4678 } 4679 ancestorNotifier.addAncestorListener(listener); 4680 } 4681 4682 /** 4683 * Unregisters <code>listener</code> so that it will no longer receive 4684 * <code>AncestorEvents</code>. 4685 * 4686 * @param listener the <code>AncestorListener</code> to be removed 4687 * @see #addAncestorListener 4688 */ 4689 public void removeAncestorListener(AncestorListener listener) { 4690 AncestorNotifier ancestorNotifier = getAncestorNotifier(); 4691 if (ancestorNotifier == null) { 4692 return; 4693 } 4694 ancestorNotifier.removeAncestorListener(listener); 4695 if (ancestorNotifier.listenerList.getListenerList().length == 0) { 4696 ancestorNotifier.removeAllListeners(); 4697 putClientProperty(JComponent_ANCESTOR_NOTIFIER, null); 4698 } 4699 } 4700 4701 /** 4702 * Returns an array of all the ancestor listeners 4703 * registered on this component. 4704 * 4705 * @return all of the component's <code>AncestorListener</code>s 4706 * or an empty 4707 * array if no ancestor listeners are currently registered 4708 * 4709 * @see #addAncestorListener 4710 * @see #removeAncestorListener 4711 * 4712 * @since 1.4 4713 */ 4714 public AncestorListener[] getAncestorListeners() { 4715 AncestorNotifier ancestorNotifier = getAncestorNotifier(); 4716 if (ancestorNotifier == null) { 4717 return new AncestorListener[0]; 4718 } 4719 return ancestorNotifier.getAncestorListeners(); 4720 } 4721 4722 /** 4723 * Returns an array of all the objects currently registered 4724 * as <code><em>Foo</em>Listener</code>s 4725 * upon this <code>JComponent</code>. 4726 * <code><em>Foo</em>Listener</code>s are registered using the 4727 * <code>add<em>Foo</em>Listener</code> method. 4728 * 4729 * <p> 4730 * 4731 * You can specify the <code>listenerType</code> argument 4732 * with a class literal, 4733 * such as 4734 * <code><em>Foo</em>Listener.class</code>. 4735 * For example, you can query a 4736 * <code>JComponent</code> <code>c</code> 4737 * for its mouse listeners with the following code: 4738 * <pre>MouseListener[] mls = (MouseListener[])(c.getListeners(MouseListener.class));</pre> 4739 * If no such listeners exist, this method returns an empty array. 4740 * 4741 * @param listenerType the type of listeners requested; this parameter 4742 * should specify an interface that descends from 4743 * <code>java.util.EventListener</code> 4744 * @return an array of all objects registered as 4745 * <code><em>Foo</em>Listener</code>s on this component, 4746 * or an empty array if no such 4747 * listeners have been added 4748 * @exception ClassCastException if <code>listenerType</code> 4749 * doesn't specify a class or interface that implements 4750 * <code>java.util.EventListener</code> 4751 * 4752 * @since 1.3 4753 * 4754 * @see #getVetoableChangeListeners 4755 * @see #getAncestorListeners 4756 */ 4757 @SuppressWarnings("unchecked") // Casts to (T[]) 4758 public <T extends EventListener> T[] getListeners(Class<T> listenerType) { 4759 T[] result; 4760 if (listenerType == AncestorListener.class) { 4761 // AncestorListeners are handled by the AncestorNotifier 4762 result = (T[])getAncestorListeners(); 4763 } 4764 else if (listenerType == VetoableChangeListener.class) { 4765 // VetoableChangeListeners are handled by VetoableChangeSupport 4766 result = (T[])getVetoableChangeListeners(); 4767 } 4768 else if (listenerType == PropertyChangeListener.class) { 4769 // PropertyChangeListeners are handled by PropertyChangeSupport 4770 result = (T[])getPropertyChangeListeners(); 4771 } 4772 else { 4773 result = listenerList.getListeners(listenerType); 4774 } 4775 4776 if (result.length == 0) { 4777 return super.getListeners(listenerType); 4778 } 4779 return result; 4780 } 4781 4782 /** 4783 * Notifies this component that it now has a parent component. 4784 * When this method is invoked, the chain of parent components is 4785 * set up with <code>KeyboardAction</code> event listeners. 4786 * This method is called by the toolkit internally and should 4787 * not be called directly by programs. 4788 * 4789 * @see #registerKeyboardAction 4790 */ 4791 public void addNotify() { 4792 super.addNotify(); 4793 firePropertyChange("ancestor", null, getParent()); 4794 4795 registerWithKeyboardManager(false); 4796 registerNextFocusableComponent(); 4797 } 4798 4799 4800 /** 4801 * Notifies this component that it no longer has a parent component. 4802 * When this method is invoked, any <code>KeyboardAction</code>s 4803 * set up in the chain of parent components are removed. 4804 * This method is called by the toolkit internally and should 4805 * not be called directly by programs. 4806 * 4807 * @see #registerKeyboardAction 4808 */ 4809 public void removeNotify() { 4810 super.removeNotify(); 4811 // This isn't strictly correct. The event shouldn't be 4812 // fired until *after* the parent is set to null. But 4813 // we only get notified before that happens 4814 firePropertyChange("ancestor", getParent(), null); 4815 4816 unregisterWithKeyboardManager(); 4817 deregisterNextFocusableComponent(); 4818 4819 if (getCreatedDoubleBuffer()) { 4820 RepaintManager.currentManager(this).resetDoubleBuffer(); 4821 setCreatedDoubleBuffer(false); 4822 } 4834 * @param tm this parameter is not used 4835 * @param x the x value of the dirty region 4836 * @param y the y value of the dirty region 4837 * @param width the width of the dirty region 4838 * @param height the height of the dirty region 4839 * @see #isPaintingOrigin() 4840 * @see java.awt.Component#isShowing 4841 * @see RepaintManager#addDirtyRegion 4842 */ 4843 public void repaint(long tm, int x, int y, int width, int height) { 4844 RepaintManager.currentManager(SunToolkit.targetToAppContext(this)) 4845 .addDirtyRegion(this, x, y, width, height); 4846 } 4847 4848 4849 /** 4850 * Adds the specified region to the dirty region list if the component 4851 * is showing. The component will be repainted after all of the 4852 * currently pending events have been dispatched. 4853 * 4854 * @param r a <code>Rectangle</code> containing the dirty region 4855 * @see #isPaintingOrigin() 4856 * @see java.awt.Component#isShowing 4857 * @see RepaintManager#addDirtyRegion 4858 */ 4859 public void repaint(Rectangle r) { 4860 repaint(0,r.x,r.y,r.width,r.height); 4861 } 4862 4863 4864 /** 4865 * Supports deferred automatic layout. 4866 * <p> 4867 * Calls <code>invalidate</code> and then adds this component's 4868 * <code>validateRoot</code> to a list of components that need to be 4869 * validated. Validation will occur after all currently pending 4870 * events have been dispatched. In other words after this method 4871 * is called, the first validateRoot (if any) found when walking 4872 * up the containment hierarchy of this component will be validated. 4873 * By default, <code>JRootPane</code>, <code>JScrollPane</code>, 4874 * and <code>JTextField</code> return true 4875 * from <code>isValidateRoot</code>. 4876 * <p> 4877 * This method will automatically be called on this component 4878 * when a property value changes such that size, location, or 4879 * internal layout of this component has been affected. This automatic 4880 * updating differs from the AWT because programs generally no 4881 * longer need to invoke <code>validate</code> to get the contents of the 4882 * GUI to update. 4883 * 4884 * @see java.awt.Component#invalidate 4885 * @see java.awt.Container#validate 4886 * @see #isValidateRoot 4887 * @see RepaintManager#addInvalidComponent 4888 */ 4889 public void revalidate() { 4890 if (getParent() == null) { 4891 // Note: We don't bother invalidating here as once added 4892 // to a valid parent invalidate will be invoked (addImpl 4893 // invokes addNotify which will invoke invalidate on the 4894 // new Component). Also, if we do add a check to isValid 4895 // here it can potentially be called before the constructor 4896 // which was causing some people grief. 4897 return; 4898 } 4899 if (SunToolkit.isDispatchThreadForAppContext(this)) { 4900 invalidate(); 4901 RepaintManager.currentManager(this).addInvalidComponent(this); 4902 } 4903 else { 4904 // To avoid a flood of Runnables when constructing GUIs off 4905 // the EDT, a flag is maintained as to whether or not 4906 // a Runnable has been scheduled. 4907 if (revalidateRunnableScheduled.getAndSet(true)) { 4908 return; 4909 } 4910 SunToolkit.executeOnEventHandlerThread(this, () -> { 4911 revalidateRunnableScheduled.set(false); 4912 revalidate(); 4913 }); 4914 } 4915 } 4916 4917 /** 4918 * If this method returns true, <code>revalidate</code> calls by 4919 * descendants of this component will cause the entire tree 4920 * beginning with this root to be validated. 4921 * Returns false by default. <code>JScrollPane</code> overrides 4922 * this method and returns true. 4923 * 4924 * @return always returns false 4925 * @see #revalidate 4926 * @see java.awt.Component#invalidate 4927 * @see java.awt.Container#validate 4928 * @see java.awt.Container#isValidateRoot 4929 */ 4930 @Override 4931 public boolean isValidateRoot() { 4932 return false; 4933 } 4934 4935 4936 /** 4937 * Returns true if this component tiles its children -- that is, if 4938 * it can guarantee that the children will not overlap. The 4939 * repainting system is substantially more efficient in this 4940 * common case. <code>JComponent</code> subclasses that can't make this 4941 * guarantee, such as <code>JLayeredPane</code>, 4942 * should override this method to return false. 4943 * 4944 * @return always returns true 4945 */ 4946 public boolean isOptimizedDrawingEnabled() { 4947 return true; 4948 } 4949 4950 /** 4951 * Returns {@code true} if a paint triggered on a child component should cause 4952 * painting to originate from this Component, or one of its ancestors. 4953 * <p> 4954 * Calling {@link #repaint} or {@link #paintImmediately(int, int, int, int)} 4955 * on a Swing component will result in calling 4956 * the {@link JComponent#paintImmediately(int, int, int, int)} method of 4957 * the first ancestor which {@code isPaintingOrigin()} returns {@code true}, if there are any. 4958 * <p> 4959 * {@code JComponent} subclasses that need to be painted when any of their 4960 * children are repainted should override this method to return {@code true}. 4961 * 5010 y += c.getY(); 5011 c = parent; 5012 } else { 5013 break; 5014 } 5015 5016 if(!(c instanceof JComponent)) { 5017 break; 5018 } 5019 } 5020 if(c instanceof JComponent) { 5021 ((JComponent)c)._paintImmediately(x,y,w,h); 5022 } else { 5023 c.repaint(x,y,w,h); 5024 } 5025 } 5026 5027 /** 5028 * Paints the specified region now. 5029 * 5030 * @param r a <code>Rectangle</code> containing the region to be painted 5031 */ 5032 public void paintImmediately(Rectangle r) { 5033 paintImmediately(r.x,r.y,r.width,r.height); 5034 } 5035 5036 /** 5037 * Returns whether this component should be guaranteed to be on top. 5038 * For example, it would make no sense for <code>Menu</code>s to pop up 5039 * under another component, so they would always return true. 5040 * Most components will want to return false, hence that is the default. 5041 * 5042 * @return always returns false 5043 */ 5044 // package private 5045 boolean alwaysOnTop() { 5046 return false; 5047 } 5048 5049 void setPaintingChild(Component paintingChild) { 5050 this.paintingChild = paintingChild; 5051 } 5052 5053 void _paintImmediately(int x, int y, int w, int h) { 5054 Graphics g; 5055 Container c; 5056 Rectangle b; 5057 5058 int tmpX, tmpY, tmpWidth, tmpHeight; 5312 y >= siblingRect.y && (y + height) <= 5313 (siblingRect.y + siblingRect.height)) { 5314 recycleRectangle(tmpRect); 5315 return COMPLETELY_OBSCURED; 5316 } 5317 else if (retValue == NOT_OBSCURED && 5318 !((x + width <= siblingRect.x) || 5319 (y + height <= siblingRect.y) || 5320 (x >= siblingRect.x + siblingRect.width) || 5321 (y >= siblingRect.y + siblingRect.height))) { 5322 retValue = PARTIALLY_OBSCURED; 5323 } 5324 } 5325 recycleRectangle(tmpRect); 5326 return retValue; 5327 } 5328 5329 /** 5330 * Returns true, which implies that before checking if a child should 5331 * be painted it is first check that the child is not obscured by another 5332 * sibling. This is only checked if <code>isOptimizedDrawingEnabled</code> 5333 * returns false. 5334 * 5335 * @return always returns true 5336 */ 5337 boolean checkIfChildObscuredBySibling() { 5338 return true; 5339 } 5340 5341 5342 private void setFlag(int aFlag, boolean aValue) { 5343 if(aValue) { 5344 flags |= (1 << aFlag); 5345 } else { 5346 flags &= ~(1 << aFlag); 5347 } 5348 } 5349 private boolean getFlag(int aFlag) { 5350 int mask = (1 << aFlag); 5351 return ((flags & mask) == mask); 5352 } 5353 // These functions must be static so that they can be called from 5354 // subclasses inside the package, but whose inheritance hierarhcy includes 5355 // classes outside of the package below JComponent (e.g., JTextArea). 5356 static void setWriteObjCounter(JComponent comp, byte count) { 5357 comp.flags = (comp.flags & ~(0xFF << WRITE_OBJ_COUNTER_FIRST)) | 5358 (count << WRITE_OBJ_COUNTER_FIRST); 5359 } 5360 static byte getWriteObjCounter(JComponent comp) { 5361 return (byte)((comp.flags >> WRITE_OBJ_COUNTER_FIRST) & 0xFF); 5362 } 5363 5364 /** Buffering **/ 5365 5366 /** 5367 * Sets whether this component should use a buffer to paint. 5368 * If set to true, all the drawing from this component will be done 5369 * in an offscreen painting buffer. The offscreen painting buffer will 5370 * the be copied onto the screen. 5371 * If a <code>Component</code> is buffered and one of its ancestor 5372 * is also buffered, the ancestor buffer will be used. 5373 * 5374 * @param aFlag if true, set this component to be double buffered 5375 */ 5376 public void setDoubleBuffered(boolean aFlag) { 5377 setFlag(IS_DOUBLE_BUFFERED,aFlag); 5378 } 5379 5380 /** 5381 * Returns whether this component should use a buffer to paint. 5382 * 5383 * @return true if this component is double buffered, otherwise false 5384 */ 5385 public boolean isDoubleBuffered() { 5386 return getFlag(IS_DOUBLE_BUFFERED); 5387 } 5388 5389 /** 5390 * Returns the <code>JRootPane</code> ancestor for this component. 5391 * 5392 * @return the <code>JRootPane</code> that contains this component, 5393 * or <code>null</code> if no <code>JRootPane</code> is found 5394 */ 5395 public JRootPane getRootPane() { 5396 return SwingUtilities.getRootPane(this); 5397 } 5398 5399 5400 /** Serialization **/ 5401 5402 /** 5403 * This is called from Component by way of reflection. Do NOT change 5404 * the name unless you change the code in Component as well. 5405 */ 5406 void compWriteObjectNotify() { 5407 byte count = JComponent.getWriteObjCounter(this); 5408 JComponent.setWriteObjCounter(this, (byte)(count + 1)); 5409 if (count != 0) { 5410 return; 5411 } 5412 5413 uninstallUIAndProperties(); 5414 5415 /* JTableHeader is in a separate package, which prevents it from 5416 * being able to override this package-private method the way the 5417 * other components can. We don't want to make this method protected 5418 * because it would introduce public-api for a less-than-desirable 5419 * serialization scheme, so we compromise with this 'instanceof' hack 5420 * for now. 5421 */ 5422 if (getToolTipText() != null || 5423 this instanceof javax.swing.table.JTableHeader) { 5424 ToolTipManager.sharedInstance().unregisterComponent(JComponent.this); 5425 } 5426 } 5427 5428 /** 5429 * This object is the <code>ObjectInputStream</code> callback 5430 * that's called after a complete graph of objects (including at least 5431 * one <code>JComponent</code>) has been read. 5432 * It sets the UI property of each Swing component 5433 * that was read to the current default with <code>updateUI</code>. 5434 * <p> 5435 * As each component is read in we keep track of the current set of 5436 * root components here, in the roots vector. Note that there's only one 5437 * <code>ReadObjectCallback</code> per <code>ObjectInputStream</code>, 5438 * they're stored in the static <code>readObjectCallbacks</code> 5439 * hashtable. 5440 * 5441 * @see java.io.ObjectInputStream#registerValidation 5442 * @see SwingUtilities#updateComponentTreeUI 5443 */ 5444 private class ReadObjectCallback implements ObjectInputValidation 5445 { 5446 private final Vector<JComponent> roots = new Vector<JComponent>(1); 5447 private final ObjectInputStream inputStream; 5448 5449 ReadObjectCallback(ObjectInputStream s) throws Exception { 5450 inputStream = s; 5451 s.registerValidation(this, 0); 5452 } 5453 5454 /** 5455 * This is the method that's called after the entire graph 5456 * of objects has been read in. It initializes 5457 * the UI property of all of the copmonents with 5458 * <code>SwingUtilities.updateComponentTreeUI</code>. 5459 */ 5460 public void validateObject() throws InvalidObjectException { 5461 try { 5462 for (JComponent root : roots) { 5463 SwingUtilities.updateComponentTreeUI(root); 5464 } 5465 } 5466 finally { 5467 readObjectCallbacks.remove(inputStream); 5468 } 5469 } 5470 5471 /** 5472 * If <code>c</code> isn't a descendant of a component we've already 5473 * seen, then add it to the roots <code>Vector</code>. 5474 * 5475 * @param c the <code>JComponent</code> to add 5476 */ 5477 private void registerComponent(JComponent c) 5478 { 5479 /* If the Component c is a descendant of one of the 5480 * existing roots (or it IS an existing root), we're done. 5481 */ 5482 for (JComponent root : roots) { 5483 for(Component p = c; p != null; p = p.getParent()) { 5484 if (p == root) { 5485 return; 5486 } 5487 } 5488 } 5489 5490 /* Otherwise: if Component c is an ancestor of any of the 5491 * existing roots then remove them and add c (the "new root") 5492 * to the roots vector. 5493 */ 5494 for(int i = 0; i < roots.size(); i++) { 5495 JComponent root = roots.elementAt(i); 5496 for(Component p = root.getParent(); p != null; p = p.getParent()) { 5497 if (p == c) { 5498 roots.removeElementAt(i--); // !! 5499 break; 5500 } 5501 } 5502 } 5503 5504 roots.addElement(c); 5505 } 5506 } 5507 5508 5509 /** 5510 * We use the <code>ObjectInputStream</code> "registerValidation" 5511 * callback to update the UI for the entire tree of components 5512 * after they've all been read in. 5513 * 5514 * @param s the <code>ObjectInputStream</code> from which to read 5515 */ 5516 private void readObject(ObjectInputStream s) 5517 throws IOException, ClassNotFoundException 5518 { 5519 ObjectInputStream.GetField f = s.readFields(); 5520 5521 isAlignmentXSet = f.get("isAlignmentXSet", false); 5522 alignmentX = validateAlignment(f.get("alignmentX", 0f)); 5523 isAlignmentYSet = f.get("isAlignmentYSet", false); 5524 alignmentY = validateAlignment(f.get("alignmentY", 0f)); 5525 listenerList = (EventListenerList) f.get("listenerList", null); 5526 vetoableChangeSupport = (VetoableChangeSupport) f.get("vetoableChangeSupport", null); 5527 autoscrolls = f.get("autoscrolls", false); 5528 border = (Border) f.get("border", null); 5529 flags = f.get("flags", 0); 5530 inputVerifier = (InputVerifier) f.get("inputVerifier", null); 5531 verifyInputWhenFocusTarget = f.get("verifyInputWhenFocusTarget", false); 5532 popupMenu = (JPopupMenu) f.get("popupMenu", null); 5533 focusInputMap = (InputMap) f.get("focusInputMap", null); 5534 ancestorInputMap = (InputMap) f.get("ancestorInputMap", null); 5553 cb.registerComponent(this); 5554 5555 // Read back the client properties. 5556 int cpCount = s.readInt(); 5557 if (cpCount > 0) { 5558 clientProperties = new ArrayTable(); 5559 for (int counter = 0; counter < cpCount; counter++) { 5560 clientProperties.put(s.readObject(), 5561 s.readObject()); 5562 } 5563 } 5564 if (getToolTipText() != null) { 5565 ToolTipManager.sharedInstance().registerComponent(this); 5566 } 5567 setWriteObjCounter(this, (byte)0); 5568 revalidateRunnableScheduled = new AtomicBoolean(false); 5569 } 5570 5571 5572 /** 5573 * Before writing a <code>JComponent</code> to an 5574 * <code>ObjectOutputStream</code> we temporarily uninstall its UI. 5575 * This is tricky to do because we want to uninstall 5576 * the UI before any of the <code>JComponent</code>'s children 5577 * (or its <code>LayoutManager</code> etc.) are written, 5578 * and we don't want to restore the UI until the most derived 5579 * <code>JComponent</code> subclass has been stored. 5580 * 5581 * @param s the <code>ObjectOutputStream</code> in which to write 5582 */ 5583 private void writeObject(ObjectOutputStream s) throws IOException { 5584 s.defaultWriteObject(); 5585 if (getUIClassID().equals(uiClassID)) { 5586 byte count = JComponent.getWriteObjCounter(this); 5587 JComponent.setWriteObjCounter(this, --count); 5588 if (count == 0 && ui != null) { 5589 ui.installUI(this); 5590 } 5591 } 5592 ArrayTable.writeArrayTable(s, clientProperties); 5593 } 5594 5595 5596 /** 5597 * Returns a string representation of this <code>JComponent</code>. 5598 * This method 5599 * is intended to be used only for debugging purposes, and the 5600 * content and format of the returned string may vary between 5601 * implementations. The returned string may be empty but may not 5602 * be <code>null</code>. 5603 * 5604 * @return a string representation of this <code>JComponent</code> 5605 */ 5606 protected String paramString() { 5607 String preferredSizeString = (isPreferredSizeSet() ? 5608 getPreferredSize().toString() : ""); 5609 String minimumSizeString = (isMinimumSizeSet() ? 5610 getMinimumSize().toString() : ""); 5611 String maximumSizeString = (isMaximumSizeSet() ? 5612 getMaximumSize().toString() : ""); 5613 String borderString = (border == null ? "" 5614 : (border == this ? "this" : border.toString())); 5615 5616 return super.paramString() + 5617 ",alignmentX=" + alignmentX + 5618 ",alignmentY=" + alignmentY + 5619 ",border=" + borderString + 5620 ",flags=" + flags + // should beef this up a bit 5621 ",maximumSize=" + maximumSizeString + 5622 ",minimumSize=" + minimumSizeString + 5623 ",preferredSize=" + preferredSizeString; 5624 } | 47 import java.io.ObjectOutputStream; 48 import java.io.ObjectInputStream; 49 import java.io.IOException; 50 import java.io.ObjectInputValidation; 51 import java.io.InvalidObjectException; 52 import java.util.concurrent.atomic.AtomicBoolean; 53 54 import javax.swing.border.*; 55 import javax.swing.event.*; 56 import javax.swing.plaf.*; 57 import static javax.swing.ClientPropertyKey.*; 58 import javax.accessibility.*; 59 60 import sun.awt.AWTAccessor; 61 import sun.awt.SunToolkit; 62 import sun.swing.SwingUtilities2; 63 import sun.swing.UIClientPropertyKey; 64 65 /** 66 * The base class for all Swing components except top-level containers. 67 * To use a component that inherits from {@code JComponent}, 68 * you must place the component in a containment hierarchy 69 * whose root is a top-level Swing container. 70 * Top-level Swing containers -- 71 * such as {@code JFrame}, {@code JDialog}, 72 * and {@code JApplet} -- 73 * are specialized components 74 * that provide a place for other Swing components to paint themselves. 75 * For an explanation of containment hierarchies, see 76 * <a 77 href="http://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html">Swing Components and the Containment Hierarchy</a>, 78 * a section in <em>The Java Tutorial</em>. 79 * 80 * <p> 81 * The {@code JComponent} class provides: 82 * <ul> 83 * <li>The base class for both standard and custom components 84 * that use the Swing architecture. 85 * <li>A "pluggable look and feel" (L&F) that can be specified by the 86 * programmer or (optionally) selected by the user at runtime. 87 * The look and feel for each component is provided by a 88 * <em>UI delegate</em> -- an object that descends from 89 * {@link javax.swing.plaf.ComponentUI}. 90 * See <a 91 * href="http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html">How 92 * to Set the Look and Feel</a> 93 * in <em>The Java Tutorial</em> 94 * for more information. 95 * <li>Comprehensive keystroke handling. 96 * See the document <a 97 * href="http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html">How to Use Key Bindings</a>, 98 * an article in <em>The Java Tutorial</em>, 99 * for more information. 100 * <li>Support for tool tips -- 101 * short descriptions that pop up when the cursor lingers 102 * over a component. 103 * See <a 104 * href="http://docs.oracle.com/javase/tutorial/uiswing/components/tooltip.html">How 105 * to Use Tool Tips</a> 106 * in <em>The Java Tutorial</em> 107 * for more information. 108 * <li>Support for accessibility. 109 * {@code JComponent} contains all of the methods in the 110 * {@code Accessible} interface, 111 * but it doesn't actually implement the interface. That is the 112 * responsibility of the individual classes 113 * that extend {@code JComponent}. 114 * <li>Support for component-specific properties. 115 * With the {@link #putClientProperty} 116 * and {@link #getClientProperty} methods, 117 * you can associate name-object pairs 118 * with any object that descends from {@code JComponent}. 119 * <li>An infrastructure for painting 120 * that includes double buffering and support for borders. 121 * For more information see <a 122 * href="http://www.oracle.com/technetwork/java/painting-140037.html#swing">Painting</a> and 123 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/border.html">How 124 * to Use Borders</a>, 125 * both of which are sections in <em>The Java Tutorial</em>. 126 * </ul> 127 * For more information on these subjects, see the 128 * <a href="package-summary.html#package_description">Swing package description</a> 129 * and <em>The Java Tutorial</em> section 130 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/jcomponent.html">The JComponent Class</a>. 131 * <p> 132 * {@code JComponent} and its subclasses document default values 133 * for certain properties. For example, {@code JTable} documents the 134 * default row height as 16. Each {@code JComponent} subclass 135 * that has a {@code ComponentUI} will create the 136 * {@code ComponentUI} as part of its constructor. In order 137 * to provide a particular look and feel each 138 * {@code ComponentUI} may set properties back on the 139 * {@code JComponent} that created it. For example, a custom 140 * look and feel may require {@code JTable}s to have a row 141 * height of 24. The documented defaults are the value of a property 142 * BEFORE the {@code ComponentUI} has been installed. If you 143 * need a specific value for a particular property you should 144 * explicitly set it. 145 * <p> 146 * In release 1.4, the focus subsystem was rearchitected. 147 * For more information, see 148 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> 149 * How to Use the Focus Subsystem</a>, 150 * a section in <em>The Java Tutorial</em>. 151 * <p> 152 * <strong>Warning:</strong> Swing is not thread safe. For more 153 * information see <a 154 * href="package-summary.html#threading">Swing's Threading 155 * Policy</a>. 156 * <p> 157 * <strong>Warning:</strong> 158 * Serialized objects of this class will not be compatible with 159 * future Swing releases. The current serialization support is 160 * appropriate for short term storage or RMI between applications running 161 * the same version of Swing. As of 1.4, support for long term storage 162 * of all JavaBeans™ 163 * has been added to the {@code java.beans} package. 164 * Please see {@link java.beans.XMLEncoder}. 165 * 166 * @see KeyStroke 167 * @see Action 168 * @see #setBorder 169 * @see #registerKeyboardAction 170 * @see JOptionPane 171 * @see #setDebugGraphicsOptions 172 * @see #setToolTipText 173 * @see #setAutoscrolls 174 * 175 * @author Hans Muller 176 * @author Arnaud Weber 177 * @since 1.2 178 */ 179 @SuppressWarnings("serial") // Same-version serialization only 180 public abstract class JComponent extends Container implements Serializable, 181 TransferHandler.HasGetTransferHandler 182 { 183 /** 239 /** The look and feel delegate for this component. */ 240 protected transient ComponentUI ui; 241 /** A list of event listeners for this component. */ 242 protected EventListenerList listenerList = new EventListenerList(); 243 244 private transient ArrayTable clientProperties; 245 private VetoableChangeSupport vetoableChangeSupport; 246 /** 247 * Whether or not autoscroll has been enabled. 248 */ 249 private boolean autoscrolls; 250 private Border border; 251 private int flags; 252 253 /* Input verifier for this component */ 254 private InputVerifier inputVerifier = null; 255 256 private boolean verifyInputWhenFocusTarget = true; 257 258 /** 259 * Set in {@code _paintImmediately}. 260 * Will indicate the child that initiated the painting operation. 261 * If {@code paintingChild} is opaque, no need to paint 262 * any child components after {@code paintingChild}. 263 * Test used in {@code paintChildren}. 264 */ 265 transient Component paintingChild; 266 267 /** 268 * Constant used for {@code registerKeyboardAction} that 269 * means that the command should be invoked when 270 * the component has the focus. 271 */ 272 public static final int WHEN_FOCUSED = 0; 273 274 /** 275 * Constant used for {@code registerKeyboardAction} that 276 * means that the command should be invoked when the receiving 277 * component is an ancestor of the focused component or is 278 * itself the focused component. 279 */ 280 public static final int WHEN_ANCESTOR_OF_FOCUSED_COMPONENT = 1; 281 282 /** 283 * Constant used for {@code registerKeyboardAction} that 284 * means that the command should be invoked when 285 * the receiving component is in the window that has the focus 286 * or is itself the focused component. 287 */ 288 public static final int WHEN_IN_FOCUSED_WINDOW = 2; 289 290 /** 291 * Constant used by some of the APIs to mean that no condition is defined. 292 */ 293 public static final int UNDEFINED_CONDITION = -1; 294 295 /** 296 * The key used by {@code JComponent} to access keyboard bindings. 297 */ 298 private static final String KEYBOARD_BINDINGS_KEY = "_KeyboardBindings"; 299 300 /** 301 * An array of {@code KeyStroke}s used for 302 * {@code WHEN_IN_FOCUSED_WINDOW} are stashed 303 * in the client properties under this string. 304 */ 305 private static final String WHEN_IN_FOCUSED_WINDOW_BINDINGS = "_WhenInFocusedWindow"; 306 307 /** 308 * The comment to display when the cursor is over the component, 309 * also known as a "value tip", "flyover help", or "flyover label". 310 */ 311 public static final String TOOL_TIP_TEXT_KEY = "ToolTipText"; 312 313 private static final String NEXT_FOCUS = "nextFocus"; 314 315 /** 316 * {@code JPopupMenu} assigned to this component 317 * and all of its children 318 */ 319 private JPopupMenu popupMenu; 320 321 /** Private flags **/ 322 private static final int IS_DOUBLE_BUFFERED = 0; 323 private static final int ANCESTOR_USING_BUFFER = 1; 324 private static final int IS_PAINTING_TILE = 2; 325 private static final int IS_OPAQUE = 3; 326 private static final int KEY_EVENTS_ENABLED = 4; 327 private static final int FOCUS_INPUTMAP_CREATED = 5; 328 private static final int ANCESTOR_INPUTMAP_CREATED = 6; 329 private static final int WIF_INPUTMAP_CREATED = 7; 330 private static final int ACTIONMAP_CREATED = 8; 331 private static final int CREATED_DOUBLE_BUFFER = 9; 332 // bit 10 is free 333 private static final int IS_PRINTING = 11; 334 private static final int IS_PRINTING_ALL = 12; 335 private static final int IS_REPAINTING = 13; 336 /** Bits 14-21 are used to handle nested writeObject calls. **/ 340 private static final int RESERVED_3 = 17; 341 private static final int RESERVED_4 = 18; 342 private static final int RESERVED_5 = 19; 343 private static final int RESERVED_6 = 20; 344 private static final int WRITE_OBJ_COUNTER_LAST = 21; 345 346 private static final int REQUEST_FOCUS_DISABLED = 22; 347 private static final int INHERITS_POPUP_MENU = 23; 348 private static final int OPAQUE_SET = 24; 349 private static final int AUTOSCROLLS_SET = 25; 350 private static final int FOCUS_TRAVERSAL_KEYS_FORWARD_SET = 26; 351 private static final int FOCUS_TRAVERSAL_KEYS_BACKWARD_SET = 27; 352 353 private transient AtomicBoolean revalidateRunnableScheduled = new AtomicBoolean(false); 354 355 /** 356 * Temporary rectangles. 357 */ 358 private static java.util.List<Rectangle> tempRectangles = new java.util.ArrayList<Rectangle>(11); 359 360 /** Used for {@code WHEN_FOCUSED} bindings. */ 361 private InputMap focusInputMap; 362 /** Used for {@code WHEN_ANCESTOR_OF_FOCUSED_COMPONENT} bindings. */ 363 private InputMap ancestorInputMap; 364 /** Used for {@code WHEN_IN_FOCUSED_KEY} bindings. */ 365 private ComponentInputMap windowInputMap; 366 367 /** ActionMap. */ 368 private ActionMap actionMap; 369 370 /** Key used to store the default locale in an AppContext **/ 371 private static final String defaultLocale = "JComponent.defaultLocale"; 372 373 private static Component componentObtainingGraphicsFrom; 374 private static Object componentObtainingGraphicsFromLock = new 375 StringBuilder("componentObtainingGraphicsFrom"); 376 377 /** 378 * AA text hints. 379 */ 380 private transient Object aaHint; 381 private transient Object lcdRenderingHint; 382 383 static Graphics safelyGetGraphics(Component c) { 384 return safelyGetGraphics(c, SwingUtilities.getRoot(c)); 397 if (!JComponent.isComponentObtainingGraphicsFrom(root)) { 398 JRootPane rootPane = ((RootPaneContainer)root).getRootPane(); 399 if (rootPane != null) { 400 rootPane.disableTrueDoubleBuffering(); 401 } 402 } 403 } 404 405 406 /** 407 * Returns true if {@code c} is the component the graphics is being 408 * requested of. This is intended for use when getGraphics is invoked. 409 */ 410 private static boolean isComponentObtainingGraphicsFrom(Component c) { 411 synchronized(componentObtainingGraphicsFromLock) { 412 return (componentObtainingGraphicsFrom == c); 413 } 414 } 415 416 /** 417 * Returns the Set of {@code KeyStroke}s to use if the component 418 * is managing focus for forward focus traversal. 419 */ 420 static Set<KeyStroke> getManagingFocusForwardTraversalKeys() { 421 synchronized(JComponent.class) { 422 if (managingFocusForwardTraversalKeys == null) { 423 managingFocusForwardTraversalKeys = new HashSet<KeyStroke>(1); 424 managingFocusForwardTraversalKeys.add( 425 KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 426 InputEvent.CTRL_MASK)); 427 } 428 } 429 return managingFocusForwardTraversalKeys; 430 } 431 432 /** 433 * Returns the Set of {@code KeyStroke}s to use if the component 434 * is managing focus for backward focus traversal. 435 */ 436 static Set<KeyStroke> getManagingFocusBackwardTraversalKeys() { 437 synchronized(JComponent.class) { 438 if (managingFocusBackwardTraversalKeys == null) { 439 managingFocusBackwardTraversalKeys = new HashSet<KeyStroke>(1); 440 managingFocusBackwardTraversalKeys.add( 441 KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 442 InputEvent.SHIFT_MASK | 443 InputEvent.CTRL_MASK)); 444 } 445 } 446 return managingFocusBackwardTraversalKeys; 447 } 448 449 private static Rectangle fetchRectangle() { 450 synchronized(tempRectangles) { 451 Rectangle rect; 452 int size = tempRectangles.size(); 453 if (size > 0) { 454 rect = tempRectangles.remove(size - 1); 455 } 456 else { 457 rect = new Rectangle(0, 0, 0, 0); 458 } 459 return rect; 460 } 461 } 462 463 private static void recycleRectangle(Rectangle rect) { 464 synchronized(tempRectangles) { 465 tempRectangles.add(rect); 466 } 467 } 468 469 /** 470 * Sets whether or not {@code getComponentPopupMenu} should delegate 471 * to the parent if this component does not have a {@code JPopupMenu} 472 * assigned to it. 473 * <p> 474 * The default value for this is false, but some {@code JComponent} 475 * subclasses that are implemented as a number of {@code JComponent}s 476 * may set this to true. 477 * <p> 478 * This is a bound property. 479 * 480 * @param value whether or not the JPopupMenu is inherited 481 * @see #setComponentPopupMenu 482 * @beaninfo 483 * bound: true 484 * description: Whether or not the JPopupMenu is inherited 485 * @since 1.5 486 */ 487 public void setInheritsPopupMenu(boolean value) { 488 boolean oldValue = getFlag(INHERITS_POPUP_MENU); 489 setFlag(INHERITS_POPUP_MENU, value); 490 firePropertyChange("inheritsPopupMenu", oldValue, value); 491 } 492 493 /** 494 * Returns true if the JPopupMenu should be inherited from the parent. 495 * 496 * @return true if the JPopupMenu should be inherited from the parent 497 * @see #setComponentPopupMenu 498 * @since 1.5 499 */ 500 public boolean getInheritsPopupMenu() { 501 return getFlag(INHERITS_POPUP_MENU); 502 } 503 504 /** 505 * Sets the {@code JPopupMenu} for this {@code JComponent}. 506 * The UI is responsible for registering bindings and adding the necessary 507 * listeners such that the {@code JPopupMenu} will be shown at 508 * the appropriate time. When the {@code JPopupMenu} is shown 509 * depends upon the look and feel: some may show it on a mouse event, 510 * some may enable a key binding. 511 * <p> 512 * If {@code popup} is null, and {@code getInheritsPopupMenu} 513 * returns true, then {@code getComponentPopupMenu} will be delegated 514 * to the parent. This provides for a way to make all child components 515 * inherit the popupmenu of the parent. 516 * <p> 517 * This is a bound property. 518 * 519 * @param popup - the popup that will be assigned to this component 520 * may be null 521 * @see #getComponentPopupMenu 522 * @beaninfo 523 * bound: true 524 * preferred: true 525 * description: Popup to show 526 * @since 1.5 527 */ 528 public void setComponentPopupMenu(JPopupMenu popup) { 529 if(popup != null) { 530 enableEvents(AWTEvent.MOUSE_EVENT_MASK); 531 } 532 JPopupMenu oldPopup = this.popupMenu; 533 this.popupMenu = popup; 534 firePropertyChange("componentPopupMenu", oldPopup, popup); 535 } 536 537 /** 538 * Returns {@code JPopupMenu} that assigned for this component. 539 * If this component does not have a {@code JPopupMenu} assigned 540 * to it and {@code getInheritsPopupMenu} is true, this 541 * will return {@code getParent().getComponentPopupMenu()} (assuming 542 * the parent is valid.) 543 * 544 * @return {@code JPopupMenu} assigned for this component 545 * or {@code null} if no popup assigned 546 * @see #setComponentPopupMenu 547 * @since 1.5 548 */ 549 public JPopupMenu getComponentPopupMenu() { 550 551 if(!getInheritsPopupMenu()) { 552 return popupMenu; 553 } 554 555 if(popupMenu == null) { 556 // Search parents for its popup 557 Container parent = getParent(); 558 while (parent != null) { 559 if(parent instanceof JComponent) { 560 return ((JComponent)parent).getComponentPopupMenu(); 561 } 562 if(parent instanceof Window || 563 parent instanceof Applet) { 564 // Reached toplevel, break and return null 565 break; 566 } 567 parent = parent.getParent(); 568 } 569 return null; 570 } 571 572 return popupMenu; 573 } 574 575 /** 576 * Default {@code JComponent} constructor. This constructor does 577 * very little initialization beyond calling the {@code Container} 578 * constructor. For example, the initial layout manager is 579 * {@code null}. It does, however, set the component's locale 580 * property to the value returned by 581 * {@code JComponent.getDefaultLocale}. 582 * 583 * @see #getDefaultLocale 584 */ 585 public JComponent() { 586 super(); 587 // We enable key events on all JComponents so that accessibility 588 // bindings will work everywhere. This is a partial fix to BugID 589 // 4282211. 590 enableEvents(AWTEvent.KEY_EVENT_MASK); 591 if (isManagingFocus()) { 592 LookAndFeel.installProperty(this, 593 "focusTraversalKeysForward", 594 getManagingFocusForwardTraversalKeys()); 595 LookAndFeel.installProperty(this, 596 "focusTraversalKeysBackward", 597 getManagingFocusBackwardTraversalKeys()); 598 } 599 600 super.setLocale( JComponent.getDefaultLocale() ); 601 } 602 603 604 /** 605 * Resets the UI property to a value from the current look and feel. 606 * {@code JComponent} subclasses must override this method 607 * like this: 608 * <pre> 609 * public void updateUI() { 610 * setUI((SliderUI)UIManager.getUI(this); 611 * } 612 * </pre> 613 * 614 * @see #setUI 615 * @see UIManager#getLookAndFeel 616 * @see UIManager#getUI 617 */ 618 public void updateUI() {} 619 620 /** 621 * Returns the look and feel delegate that renders this component. 622 * 623 * @return the {@code ComponentUI} object that renders this component 624 * @since 1.9 625 */ 626 public ComponentUI getUI() { 627 return ui; 628 } 629 630 /** 631 * Sets the look and feel delegate for this component. 632 * {@code JComponent} subclasses generally override this method 633 * to narrow the argument type. For example, in {@code JSlider}: 634 * <pre> 635 * public void setUI(SliderUI newUI) { 636 * super.setUI(newUI); 637 * } 638 * </pre> 639 * <p> 640 * Additionally {@code JComponent} subclasses must provide a 641 * {@code getUI} method that returns the correct type. For example: 642 * <pre> 643 * public SliderUI getUI() { 644 * return (SliderUI)ui; 645 * } 646 * </pre> 647 * 648 * @param newUI the new UI delegate 649 * @see #updateUI 650 * @see UIManager#getLookAndFeel 651 * @see UIManager#getUI 652 * @beaninfo 653 * bound: true 654 * hidden: true 655 * attribute: visualUpdate true 656 * description: The component's look and feel delegate. 657 */ 658 protected void setUI(ComponentUI newUI) { 659 /* We do not check that the UI instance is different 660 * before allowing the switch in order to enable the 661 * same UI instance *with different default settings* 689 if (ui != null) { 690 ui.uninstallUI(this); 691 //clean UIClientPropertyKeys from client properties 692 if (clientProperties != null) { 693 synchronized(clientProperties) { 694 Object[] clientPropertyKeys = 695 clientProperties.getKeys(null); 696 if (clientPropertyKeys != null) { 697 for (Object key : clientPropertyKeys) { 698 if (key instanceof UIClientPropertyKey) { 699 putClientProperty(key, null); 700 } 701 } 702 } 703 } 704 } 705 } 706 } 707 708 /** 709 * Returns the {@code UIDefaults} key used to 710 * look up the name of the {@code swing.plaf.ComponentUI} 711 * class that defines the look and feel 712 * for this component. Most applications will never need to 713 * call this method. Subclasses of {@code JComponent} that support 714 * pluggable look and feel should override this method to 715 * return a {@code UIDefaults} key that maps to the 716 * {@code ComponentUI} subclass that defines their look and feel. 717 * 718 * @return the {@code UIDefaults} key for a 719 * {@code ComponentUI} subclass 720 * @see UIDefaults#getUI 721 * @beaninfo 722 * expert: true 723 * description: UIClassID 724 */ 725 public String getUIClassID() { 726 return uiClassID; 727 } 728 729 730 /** 731 * Returns the graphics object used to paint this component. 732 * If {@code DebugGraphics} is turned on we create a new 733 * {@code DebugGraphics} object if necessary. 734 * Otherwise we just configure the 735 * specified graphics object's foreground and font. 736 * 737 * @param g the original {@code Graphics} object 738 * @return a {@code Graphics} object configured for this component 739 */ 740 protected Graphics getComponentGraphics(Graphics g) { 741 Graphics componentGraphics = g; 742 if (ui != null && DEBUG_GRAPHICS_LOADED) { 743 if ((DebugGraphics.debugComponentCount() != 0) && 744 (shouldDebugGraphics() != 0) && 745 !(g instanceof DebugGraphics)) { 746 componentGraphics = new DebugGraphics(g,this); 747 } 748 } 749 componentGraphics.setColor(getForeground()); 750 componentGraphics.setFont(getFont()); 751 752 return componentGraphics; 753 } 754 755 756 /** 757 * Calls the UI delegate's paint method, if the UI delegate 758 * is non-{@code null}. We pass the delegate a copy of the 759 * {@code Graphics} object to protect the rest of the 760 * paint code from irrevocable changes 761 * (for example, {@code Graphics.translate}). 762 * <p> 763 * If you override this in a subclass you should not make permanent 764 * changes to the passed in {@code Graphics}. For example, you 765 * should not alter the clip {@code Rectangle} or modify the 766 * transform. If you need to do these operations you may find it 767 * easier to create a new {@code Graphics} from the passed in 768 * {@code Graphics} and manipulate it. Further, if you do not 769 * invoker super's implementation you must honor the opaque property, 770 * that is 771 * if this component is opaque, you must completely fill in the background 772 * in a non-opaque color. If you do not honor the opaque property you 773 * will likely see visual artifacts. 774 * <p> 775 * The passed in {@code Graphics} object might 776 * have a transform other than the identify transform 777 * installed on it. In this case, you might get 778 * unexpected results if you cumulatively apply 779 * another transform. 780 * 781 * @param g the {@code Graphics} object to protect 782 * @see #paint 783 * @see ComponentUI 784 */ 785 protected void paintComponent(Graphics g) { 786 if (ui != null) { 787 Graphics scratchGraphics = (g == null) ? null : g.create(); 788 try { 789 ui.update(scratchGraphics, this); 790 } 791 finally { 792 scratchGraphics.dispose(); 793 } 794 } 795 } 796 797 /** 798 * Paints this component's children. 799 * If {@code shouldUseBuffer} is true, 800 * no component ancestor has a buffer and 801 * the component children can use a buffer if they have one. 802 * Otherwise, one ancestor has a buffer currently in use and children 803 * should not use a buffer to paint. 804 * @param g the {@code Graphics} context in which to paint 805 * @see #paint 806 * @see java.awt.Container#paint 807 */ 808 protected void paintChildren(Graphics g) { 809 Graphics sg = g; 810 811 synchronized(getTreeLock()) { 812 int i = getComponentCount() - 1; 813 if (i < 0) { 814 return; 815 } 816 // If we are only to paint to a specific child, determine 817 // its index. 818 if (paintingChild != null && 819 (paintingChild instanceof JComponent) && 820 paintingChild.isOpaque()) { 821 for (; i >= 0; i--) { 822 if (getComponent(i) == paintingChild){ 823 break; 824 } 924 cg.dispose(); 925 if(shouldSetFlagBack) { 926 ((JComponent)comp).setFlag( 927 ANCESTOR_USING_BUFFER,false); 928 ((JComponent)comp).setFlag( 929 IS_PAINTING_TILE,false); 930 } 931 } 932 } 933 } 934 935 } 936 recycleRectangle(tmpRect); 937 } 938 } 939 940 /** 941 * Paints the component's border. 942 * <p> 943 * If you override this in a subclass you should not make permanent 944 * changes to the passed in {@code Graphics}. For example, you 945 * should not alter the clip {@code Rectangle} or modify the 946 * transform. If you need to do these operations you may find it 947 * easier to create a new {@code Graphics} from the passed in 948 * {@code Graphics} and manipulate it. 949 * 950 * @param g the {@code Graphics} context in which to paint 951 * 952 * @see #paint 953 * @see #setBorder 954 */ 955 protected void paintBorder(Graphics g) { 956 Border border = getBorder(); 957 if (border != null) { 958 border.paintBorder(this, g, 0, 0, getWidth(), getHeight()); 959 } 960 } 961 962 963 /** 964 * Calls {@code paint}. Doesn't clear the background but see 965 * {@code ComponentUI.update}, which is called by 966 * {@code paintComponent}. 967 * 968 * @param g the {@code Graphics} context in which to paint 969 * @see #paint 970 * @see #paintComponent 971 * @see javax.swing.plaf.ComponentUI 972 */ 973 public void update(Graphics g) { 974 paint(g); 975 } 976 977 978 /** 979 * Invoked by Swing to draw components. 980 * Applications should not invoke {@code paint} directly, 981 * but should instead use the {@code repaint} method to 982 * schedule the component for redrawing. 983 * <p> 984 * This method actually delegates the work of painting to three 985 * protected methods: {@code paintComponent}, 986 * {@code paintBorder}, 987 * and {@code paintChildren}. They're called in the order 988 * listed to ensure that children appear on top of component itself. 989 * Generally speaking, the component and its children should not 990 * paint in the insets area allocated to the border. Subclasses can 991 * just override this method, as always. A subclass that just 992 * wants to specialize the UI (look and feel) delegate's 993 * {@code paint} method should just override 994 * {@code paintComponent}. 995 * 996 * @param g the {@code Graphics} context in which to paint 997 * @see #paintComponent 998 * @see #paintBorder 999 * @see #paintChildren 1000 * @see #getComponentGraphics 1001 * @see #repaint 1002 */ 1003 public void paint(Graphics g) { 1004 boolean shouldClearPaintFlags = false; 1005 1006 if ((getWidth() <= 0) || (getHeight() <= 0)) { 1007 return; 1008 } 1009 1010 Graphics componentGraphics = getComponentGraphics(g); 1011 Graphics co = componentGraphics.create(); 1012 try { 1013 RepaintManager repaintManager = RepaintManager.currentManager(this); 1014 Rectangle clipRect = co.getClipBounds(); 1015 int clipX; 1016 int clipY; 1126 Container parent; 1127 for(parent = getParent() ; parent != null ; parent = 1128 parent.getParent()) { 1129 if(parent instanceof JComponent) { 1130 jparent = (JComponent) parent; 1131 if(jparent.getFlag(ANCESTOR_USING_BUFFER)) 1132 setFlag(ANCESTOR_USING_BUFFER, true); 1133 if(jparent.getFlag(IS_PAINTING_TILE)) 1134 setFlag(IS_PAINTING_TILE, true); 1135 if(jparent.getFlag(IS_PRINTING)) 1136 setFlag(IS_PRINTING, true); 1137 if(jparent.getFlag(IS_PRINTING_ALL)) 1138 setFlag(IS_PRINTING_ALL, true); 1139 break; 1140 } 1141 } 1142 } 1143 1144 /** 1145 * Invoke this method to print the component. This method invokes 1146 * {@code print} on the component. 1147 * 1148 * @param g the {@code Graphics} context in which to paint 1149 * @see #print 1150 * @see #printComponent 1151 * @see #printBorder 1152 * @see #printChildren 1153 */ 1154 public void printAll(Graphics g) { 1155 setFlag(IS_PRINTING_ALL, true); 1156 try { 1157 print(g); 1158 } 1159 finally { 1160 setFlag(IS_PRINTING_ALL, false); 1161 } 1162 } 1163 1164 /** 1165 * Invoke this method to print the component to the specified 1166 * {@code Graphics}. This method will result in invocations 1167 * of {@code printComponent}, {@code printBorder} and 1168 * {@code printChildren}. It is recommended that you override 1169 * one of the previously mentioned methods rather than this one if 1170 * your intention is to customize the way printing looks. However, 1171 * it can be useful to override this method should you want to prepare 1172 * state before invoking the superclass behavior. As an example, 1173 * if you wanted to change the component's background color before 1174 * printing, you could do the following: 1175 * <pre> 1176 * public void print(Graphics g) { 1177 * Color orig = getBackground(); 1178 * setBackground(Color.WHITE); 1179 * 1180 * // wrap in try/finally so that we always restore the state 1181 * try { 1182 * super.print(g); 1183 * } finally { 1184 * setBackground(orig); 1185 * } 1186 * } 1187 * </pre> 1188 * <p> 1189 * Alternatively, or for components that delegate painting to other objects, 1190 * you can query during painting whether or not the component is in the 1191 * midst of a print operation. The {@code isPaintingForPrint} method provides 1192 * this ability and its return value will be changed by this method: to 1193 * {@code true} immediately before rendering and to {@code false} 1194 * immediately after. With each change a property change event is fired on 1195 * this component with the name {@code "paintingForPrint"}. 1196 * <p> 1197 * This method sets the component's state such that the double buffer 1198 * will not be used: painting will be done directly on the passed in 1199 * {@code Graphics}. 1200 * 1201 * @param g the {@code Graphics} context in which to paint 1202 * @see #printComponent 1203 * @see #printBorder 1204 * @see #printChildren 1205 * @see #isPaintingForPrint 1206 */ 1207 public void print(Graphics g) { 1208 setFlag(IS_PRINTING, true); 1209 firePropertyChange("paintingForPrint", false, true); 1210 try { 1211 paint(g); 1212 } 1213 finally { 1214 setFlag(IS_PRINTING, false); 1215 firePropertyChange("paintingForPrint", true, false); 1216 } 1217 } 1218 1219 /** 1220 * This is invoked during a printing operation. This is implemented to 1221 * invoke {@code paintComponent} on the component. Override this 1222 * if you wish to add special painting behavior when printing. 1223 * 1224 * @param g the {@code Graphics} context in which to paint 1225 * @see #print 1226 * @since 1.3 1227 */ 1228 protected void printComponent(Graphics g) { 1229 paintComponent(g); 1230 } 1231 1232 /** 1233 * Prints this component's children. This is implemented to invoke 1234 * {@code paintChildren} on the component. Override this if you 1235 * wish to print the children differently than painting. 1236 * 1237 * @param g the {@code Graphics} context in which to paint 1238 * @see #print 1239 * @since 1.3 1240 */ 1241 protected void printChildren(Graphics g) { 1242 paintChildren(g); 1243 } 1244 1245 /** 1246 * Prints the component's border. This is implemented to invoke 1247 * {@code paintBorder} on the component. Override this if you 1248 * wish to print the border differently that it is painted. 1249 * 1250 * @param g the {@code Graphics} context in which to paint 1251 * @see #print 1252 * @since 1.3 1253 */ 1254 protected void printBorder(Graphics g) { 1255 paintBorder(g); 1256 } 1257 1258 /** 1259 * Returns true if the component is currently painting a tile. 1260 * If this method returns true, paint will be called again for another 1261 * tile. This method returns false if you are not painting a tile or 1262 * if the last tile is painted. 1263 * Use this method to keep some state you might need between tiles. 1264 * 1265 * @return true if the component is currently painting a tile, 1266 * false otherwise 1267 */ 1268 public boolean isPaintingTile() { 1269 return getFlag(IS_PAINTING_TILE); 1270 } 1271 1272 /** 1273 * Returns {@code true} if the current painting operation on this 1274 * component is part of a {@code print} operation. This method is 1275 * useful when you want to customize what you print versus what you show 1276 * on the screen. 1277 * <p> 1278 * You can detect changes in the value of this property by listening for 1279 * property change events on this component with name 1280 * {@code "paintingForPrint"}. 1281 * <p> 1282 * Note: This method provides complimentary functionality to that provided 1283 * by other high level Swing printing APIs. However, it deals strictly with 1284 * painting and should not be confused as providing information on higher 1285 * level print processes. For example, a {@link javax.swing.JTable#print()} 1286 * operation doesn't necessarily result in a continuous rendering of the 1287 * full component, and the return value of this method can change multiple 1288 * times during that operation. It is even possible for the component to be 1289 * painted to the screen while the printing process is ongoing. In such a 1290 * case, the return value of this method is {@code true} when, and only 1291 * when, the table is being painted as part of the printing process. 1292 * 1293 * @return true if the current painting operation on this component 1294 * is part of a print operation 1295 * @see #print 1296 * @since 1.6 1297 */ 1298 public final boolean isPaintingForPrint() { 1299 return getFlag(IS_PRINTING); 1300 } 1301 1302 /** 1303 * In release 1.4, the focus subsystem was rearchitected. 1304 * For more information, see 1305 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> 1306 * How to Use the Focus Subsystem</a>, 1307 * a section in <em>The Java Tutorial</em>. 1308 * <p> 1309 * Changes this {@code JComponent}'s focus traversal keys to 1310 * CTRL+TAB and CTRL+SHIFT+TAB. Also prevents 1311 * {@code SortingFocusTraversalPolicy} from considering descendants 1312 * of this JComponent when computing a focus traversal cycle. 1313 * 1314 * @return false 1315 * @see java.awt.Component#setFocusTraversalKeys 1316 * @see SortingFocusTraversalPolicy 1317 * @deprecated As of 1.4, replaced by 1318 * {@code Component.setFocusTraversalKeys(int, Set)} and 1319 * {@code Container.setFocusCycleRoot(boolean)}. 1320 */ 1321 @Deprecated 1322 public boolean isManagingFocus() { 1323 return false; 1324 } 1325 1326 private void registerNextFocusableComponent() { 1327 registerNextFocusableComponent(getNextFocusableComponent()); 1328 } 1329 1330 private void registerNextFocusableComponent(Component 1331 nextFocusableComponent) { 1332 if (nextFocusableComponent == null) { 1333 return; 1334 } 1335 1336 Container nearestRoot = 1337 (isFocusCycleRoot()) ? this : getFocusCycleRootAncestor(); 1338 FocusTraversalPolicy policy = nearestRoot.getFocusTraversalPolicy(); 1339 if (!(policy instanceof LegacyGlueFocusTraversalPolicy)) { 1352 1353 Container nearestRoot = 1354 (isFocusCycleRoot()) ? this : getFocusCycleRootAncestor(); 1355 if (nearestRoot == null) { 1356 return; 1357 } 1358 FocusTraversalPolicy policy = nearestRoot.getFocusTraversalPolicy(); 1359 if (policy instanceof LegacyGlueFocusTraversalPolicy) { 1360 ((LegacyGlueFocusTraversalPolicy)policy). 1361 unsetNextFocusableComponent(this, nextFocusableComponent); 1362 } 1363 } 1364 1365 /** 1366 * In release 1.4, the focus subsystem was rearchitected. 1367 * For more information, see 1368 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> 1369 * How to Use the Focus Subsystem</a>, 1370 * a section in <em>The Java Tutorial</em>. 1371 * <p> 1372 * Overrides the default {@code FocusTraversalPolicy} for this 1373 * {@code JComponent}'s focus traversal cycle by unconditionally 1374 * setting the specified {@code Component} as the next 1375 * {@code Component} in the cycle, and this {@code JComponent} 1376 * as the specified {@code Component}'s previous 1377 * {@code Component} in the cycle. 1378 * 1379 * @param aComponent the {@code Component} that should follow this 1380 * {@code JComponent} in the focus traversal cycle 1381 * 1382 * @see #getNextFocusableComponent 1383 * @see java.awt.FocusTraversalPolicy 1384 * @deprecated As of 1.4, replaced by {@code FocusTraversalPolicy} 1385 */ 1386 @Deprecated 1387 public void setNextFocusableComponent(Component aComponent) { 1388 boolean displayable = isDisplayable(); 1389 if (displayable) { 1390 deregisterNextFocusableComponent(); 1391 } 1392 putClientProperty(NEXT_FOCUS, aComponent); 1393 if (displayable) { 1394 registerNextFocusableComponent(aComponent); 1395 } 1396 } 1397 1398 /** 1399 * In release 1.4, the focus subsystem was rearchitected. 1400 * For more information, see 1401 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> 1402 * How to Use the Focus Subsystem</a>, 1403 * a section in <em>The Java Tutorial</em>. 1404 * <p> 1405 * Returns the {@code Component} set by a prior call to 1406 * {@code setNextFocusableComponent(Component)} on this 1407 * {@code JComponent}. 1408 * 1409 * @return the {@code Component} that will follow this 1410 * {@code JComponent} in the focus traversal cycle, or 1411 * {@code null} if none has been explicitly specified 1412 * 1413 * @see #setNextFocusableComponent 1414 * @deprecated As of 1.4, replaced by {@code FocusTraversalPolicy}. 1415 */ 1416 @Deprecated 1417 public Component getNextFocusableComponent() { 1418 return (Component)getClientProperty(NEXT_FOCUS); 1419 } 1420 1421 /** 1422 * Provides a hint as to whether or not this {@code JComponent} 1423 * should get focus. This is only a hint, and it is up to consumers that 1424 * are requesting focus to honor this property. This is typically honored 1425 * for mouse operations, but not keyboard operations. For example, look 1426 * and feels could verify this property is true before requesting focus 1427 * during a mouse operation. This would often times be used if you did 1428 * not want a mouse press on a {@code JComponent} to steal focus, 1429 * but did want the {@code JComponent} to be traversable via the 1430 * keyboard. If you do not want this {@code JComponent} focusable at 1431 * all, use the {@code setFocusable} method instead. 1432 * <p> 1433 * Please see 1434 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> 1435 * How to Use the Focus Subsystem</a>, 1436 * a section in <em>The Java Tutorial</em>, 1437 * for more information. 1438 * 1439 * @param requestFocusEnabled indicates whether you want this 1440 * {@code JComponent} to be focusable or not 1441 * @see <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a> 1442 * @see java.awt.Component#setFocusable 1443 */ 1444 public void setRequestFocusEnabled(boolean requestFocusEnabled) { 1445 setFlag(REQUEST_FOCUS_DISABLED, !requestFocusEnabled); 1446 } 1447 1448 /** 1449 * Returns {@code true} if this {@code JComponent} should 1450 * get focus; otherwise returns {@code false}. 1451 * <p> 1452 * Please see 1453 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> 1454 * How to Use the Focus Subsystem</a>, 1455 * a section in <em>The Java Tutorial</em>, 1456 * for more information. 1457 * 1458 * @return {@code true} if this component should get focus, 1459 * otherwise returns {@code false} 1460 * @see #setRequestFocusEnabled 1461 * @see <a href="../../java/awt/doc-files/FocusSpec.html">Focus 1462 * Specification</a> 1463 * @see java.awt.Component#isFocusable 1464 */ 1465 public boolean isRequestFocusEnabled() { 1466 return !getFlag(REQUEST_FOCUS_DISABLED); 1467 } 1468 1469 /** 1470 * Requests that this {@code Component} gets the input focus. 1471 * Refer to {@link java.awt.Component#requestFocus() 1472 * Component.requestFocus()} for a complete description of 1473 * this method. 1474 * <p> 1475 * Note that the use of this method is discouraged because 1476 * its behavior is platform dependent. Instead we recommend the 1477 * use of {@link #requestFocusInWindow() requestFocusInWindow()}. 1478 * If you would like more information on focus, see 1479 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> 1480 * How to Use the Focus Subsystem</a>, 1481 * a section in <em>The Java Tutorial</em>. 1482 * 1483 * @see java.awt.Component#requestFocusInWindow() 1484 * @see java.awt.Component#requestFocusInWindow(boolean) 1485 * @since 1.4 1486 */ 1487 public void requestFocus() { 1488 super.requestFocus(); 1489 } 1490 1491 /** 1492 * Requests that this {@code Component} gets the input focus. 1493 * Refer to {@link java.awt.Component#requestFocus(boolean) 1494 * Component.requestFocus(boolean)} for a complete description of 1495 * this method. 1496 * <p> 1497 * Note that the use of this method is discouraged because 1498 * its behavior is platform dependent. Instead we recommend the 1499 * use of {@link #requestFocusInWindow(boolean) 1500 * requestFocusInWindow(boolean)}. 1501 * If you would like more information on focus, see 1502 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> 1503 * How to Use the Focus Subsystem</a>, 1504 * a section in <em>The Java Tutorial</em>. 1505 * 1506 * @param temporary boolean indicating if the focus change is temporary 1507 * @return {@code false} if the focus change request is guaranteed to 1508 * fail; {@code true} if it is likely to succeed 1509 * @see java.awt.Component#requestFocusInWindow() 1510 * @see java.awt.Component#requestFocusInWindow(boolean) 1511 * @since 1.4 1512 */ 1513 public boolean requestFocus(boolean temporary) { 1514 return super.requestFocus(temporary); 1515 } 1516 1517 /** 1518 * Requests that this {@code Component} gets the input focus. 1519 * Refer to {@link java.awt.Component#requestFocusInWindow() 1520 * Component.requestFocusInWindow()} for a complete description of 1521 * this method. 1522 * <p> 1523 * If you would like more information on focus, see 1524 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> 1525 * How to Use the Focus Subsystem</a>, 1526 * a section in <em>The Java Tutorial</em>. 1527 * 1528 * @return {@code false} if the focus change request is guaranteed to 1529 * fail; {@code true} if it is likely to succeed 1530 * @see java.awt.Component#requestFocusInWindow() 1531 * @see java.awt.Component#requestFocusInWindow(boolean) 1532 * @since 1.4 1533 */ 1534 public boolean requestFocusInWindow() { 1535 return super.requestFocusInWindow(); 1536 } 1537 1538 /** 1539 * Requests that this {@code Component} gets the input focus. 1540 * Refer to {@link java.awt.Component#requestFocusInWindow(boolean) 1541 * Component.requestFocusInWindow(boolean)} for a complete description of 1542 * this method. 1543 * <p> 1544 * If you would like more information on focus, see 1545 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> 1546 * How to Use the Focus Subsystem</a>, 1547 * a section in <em>The Java Tutorial</em>. 1548 * 1549 * @param temporary boolean indicating if the focus change is temporary 1550 * @return {@code false} if the focus change request is guaranteed to 1551 * fail; {@code true} if it is likely to succeed 1552 * @see java.awt.Component#requestFocusInWindow() 1553 * @see java.awt.Component#requestFocusInWindow(boolean) 1554 * @since 1.4 1555 */ 1556 protected boolean requestFocusInWindow(boolean temporary) { 1557 return super.requestFocusInWindow(temporary); 1558 } 1559 1560 /** 1561 * Requests that this Component get the input focus, and that this 1562 * Component's top-level ancestor become the focused Window. This component 1563 * must be displayable, visible, and focusable for the request to be 1564 * granted. 1565 * <p> 1566 * This method is intended for use by focus implementations. Client code 1567 * should not use this method; instead, it should use 1568 * {@code requestFocusInWindow()}. 1569 * 1570 * @see #requestFocusInWindow() 1571 */ 1572 public void grabFocus() { 1573 requestFocus(); 1574 } 1575 1576 /** 1577 * Sets the value to indicate whether input verifier for the 1578 * current focus owner will be called before this component requests 1579 * focus. The default is true. Set to false on components such as a 1580 * Cancel button or a scrollbar, which should activate even if the 1581 * input in the current focus owner is not "passed" by the input 1582 * verifier for that component. 1583 * 1584 * @param verifyInputWhenFocusTarget value for the 1585 * {@code verifyInputWhenFocusTarget} property 1586 * @see InputVerifier 1587 * @see #setInputVerifier 1588 * @see #getInputVerifier 1589 * @see #getVerifyInputWhenFocusTarget 1590 * 1591 * @since 1.3 1592 * @beaninfo 1593 * bound: true 1594 * description: Whether the Component verifies input before accepting 1595 * focus. 1596 */ 1597 public void setVerifyInputWhenFocusTarget(boolean 1598 verifyInputWhenFocusTarget) { 1599 boolean oldVerifyInputWhenFocusTarget = 1600 this.verifyInputWhenFocusTarget; 1601 this.verifyInputWhenFocusTarget = verifyInputWhenFocusTarget; 1602 firePropertyChange("verifyInputWhenFocusTarget", 1603 oldVerifyInputWhenFocusTarget, 1604 verifyInputWhenFocusTarget); 1605 } 1606 1607 /** 1608 * Returns the value that indicates whether the input verifier for the 1609 * current focus owner will be called before this component requests 1610 * focus. 1611 * 1612 * @return value of the {@code verifyInputWhenFocusTarget} property 1613 * 1614 * @see InputVerifier 1615 * @see #setInputVerifier 1616 * @see #getInputVerifier 1617 * @see #setVerifyInputWhenFocusTarget 1618 * 1619 * @since 1.3 1620 */ 1621 public boolean getVerifyInputWhenFocusTarget() { 1622 return verifyInputWhenFocusTarget; 1623 } 1624 1625 1626 /** 1627 * Gets the {@code FontMetrics} for the specified {@code Font}. 1628 * 1629 * @param font the font for which font metrics is to be 1630 * obtained 1631 * @return the font metrics for {@code font} 1632 * @throws NullPointerException if {@code font} is null 1633 * @since 1.5 1634 */ 1635 public FontMetrics getFontMetrics(Font font) { 1636 return SwingUtilities2.getFontMetrics(this, font); 1637 } 1638 1639 1640 /** 1641 * Sets the preferred size of this component. 1642 * If {@code preferredSize} is {@code null}, the UI will 1643 * be asked for the preferred size. 1644 * @beaninfo 1645 * preferred: true 1646 * bound: true 1647 * description: The preferred size of the component. 1648 */ 1649 public void setPreferredSize(Dimension preferredSize) { 1650 super.setPreferredSize(preferredSize); 1651 } 1652 1653 1654 /** 1655 * If the {@code preferredSize} has been set to a 1656 * non-{@code null} value just returns it. 1657 * If the UI delegate's {@code getPreferredSize} 1658 * method returns a non {@code null} value then return that; 1659 * otherwise defer to the component's layout manager. 1660 * 1661 * @return the value of the {@code preferredSize} property 1662 * @see #setPreferredSize 1663 * @see ComponentUI 1664 */ 1665 @Transient 1666 public Dimension getPreferredSize() { 1667 if (isPreferredSizeSet()) { 1668 return super.getPreferredSize(); 1669 } 1670 Dimension size = null; 1671 if (ui != null) { 1672 size = ui.getPreferredSize(this); 1673 } 1674 return (size != null) ? size : super.getPreferredSize(); 1675 } 1676 1677 1678 /** 1679 * Sets the maximum size of this component to a constant 1680 * value. Subsequent calls to {@code getMaximumSize} will always 1681 * return this value; the component's UI will not be asked 1682 * to compute it. Setting the maximum size to {@code null} 1683 * restores the default behavior. 1684 * 1685 * @param maximumSize a {@code Dimension} containing the 1686 * desired maximum allowable size 1687 * @see #getMaximumSize 1688 * @beaninfo 1689 * bound: true 1690 * description: The maximum size of the component. 1691 */ 1692 public void setMaximumSize(Dimension maximumSize) { 1693 super.setMaximumSize(maximumSize); 1694 } 1695 1696 1697 /** 1698 * If the maximum size has been set to a non-{@code null} value 1699 * just returns it. If the UI delegate's {@code getMaximumSize} 1700 * method returns a non-{@code null} value then return that; 1701 * otherwise defer to the component's layout manager. 1702 * 1703 * @return the value of the {@code maximumSize} property 1704 * @see #setMaximumSize 1705 * @see ComponentUI 1706 */ 1707 @Transient 1708 public Dimension getMaximumSize() { 1709 if (isMaximumSizeSet()) { 1710 return super.getMaximumSize(); 1711 } 1712 Dimension size = null; 1713 if (ui != null) { 1714 size = ui.getMaximumSize(this); 1715 } 1716 return (size != null) ? size : super.getMaximumSize(); 1717 } 1718 1719 1720 /** 1721 * Sets the minimum size of this component to a constant 1722 * value. Subsequent calls to {@code getMinimumSize} will always 1723 * return this value; the component's UI will not be asked 1724 * to compute it. Setting the minimum size to {@code null} 1725 * restores the default behavior. 1726 * 1727 * @param minimumSize the new minimum size of this component 1728 * @see #getMinimumSize 1729 * @beaninfo 1730 * bound: true 1731 * description: The minimum size of the component. 1732 */ 1733 public void setMinimumSize(Dimension minimumSize) { 1734 super.setMinimumSize(minimumSize); 1735 } 1736 1737 /** 1738 * If the minimum size has been set to a non-{@code null} value 1739 * just returns it. If the UI delegate's {@code getMinimumSize} 1740 * method returns a non-{@code null} value then return that; otherwise 1741 * defer to the component's layout manager. 1742 * 1743 * @return the value of the {@code minimumSize} property 1744 * @see #setMinimumSize 1745 * @see ComponentUI 1746 */ 1747 @Transient 1748 public Dimension getMinimumSize() { 1749 if (isMinimumSizeSet()) { 1750 return super.getMinimumSize(); 1751 } 1752 Dimension size = null; 1753 if (ui != null) { 1754 size = ui.getMinimumSize(this); 1755 } 1756 return (size != null) ? size : super.getMinimumSize(); 1757 } 1758 1759 /** 1760 * Gives the UI delegate an opportunity to define the precise 1761 * shape of this component for the sake of mouse processing. 1762 * 1763 * @return true if this component logically contains x,y 1764 * @see java.awt.Component#contains(int, int) 1765 * @see ComponentUI 1766 */ 1767 public boolean contains(int x, int y) { 1768 return (ui != null) ? ui.contains(this, x, y) : super.contains(x, y); 1769 } 1770 1771 /** 1772 * Sets the border of this component. The {@code Border} object is 1773 * responsible for defining the insets for the component 1774 * (overriding any insets set directly on the component) and 1775 * for optionally rendering any border decorations within the 1776 * bounds of those insets. Borders should be used (rather 1777 * than insets) for creating both decorative and non-decorative 1778 * (such as margins and padding) regions for a swing component. 1779 * Compound borders can be used to nest multiple borders within a 1780 * single component. 1781 * <p> 1782 * Although technically you can set the border on any object 1783 * that inherits from {@code JComponent}, the look and 1784 * feel implementation of many standard Swing components 1785 * doesn't work well with user-set borders. In general, 1786 * when you want to set a border on a standard Swing 1787 * component other than {@code JPanel} or {@code JLabel}, 1788 * we recommend that you put the component in a {@code JPanel} 1789 * and set the border on the {@code JPanel}. 1790 * <p> 1791 * This is a bound property. 1792 * 1793 * @param border the border to be rendered for this component 1794 * @see Border 1795 * @see CompoundBorder 1796 * @beaninfo 1797 * bound: true 1798 * preferred: true 1799 * attribute: visualUpdate true 1800 * description: The component's border. 1801 */ 1802 public void setBorder(Border border) { 1803 Border oldBorder = this.border; 1804 1805 this.border = border; 1806 firePropertyChange("border", oldBorder, border); 1807 if (border != oldBorder) { 1808 if (border == null || oldBorder == null || 1809 !(border.getBorderInsets(this).equals(oldBorder.getBorderInsets(this)))) { 1810 revalidate(); 1811 } 1812 repaint(); 1813 } 1814 } 1815 1816 /** 1817 * Returns the border of this component or {@code null} if no 1818 * border is currently set. 1819 * 1820 * @return the border object for this component 1821 * @see #setBorder 1822 */ 1823 public Border getBorder() { 1824 return border; 1825 } 1826 1827 /** 1828 * If a border has been set on this component, returns the 1829 * border's insets; otherwise calls {@code super.getInsets}. 1830 * 1831 * @return the value of the insets property 1832 * @see #setBorder 1833 */ 1834 public Insets getInsets() { 1835 if (border != null) { 1836 return border.getBorderInsets(this); 1837 } 1838 return super.getInsets(); 1839 } 1840 1841 /** 1842 * Returns an {@code Insets} object containing this component's inset 1843 * values. The passed-in {@code Insets} object will be reused 1844 * if possible. 1845 * Calling methods cannot assume that the same object will be returned, 1846 * however. All existing values within this object are overwritten. 1847 * If {@code insets} is null, this will allocate a new one. 1848 * 1849 * @param insets the {@code Insets} object, which can be reused 1850 * @return the {@code Insets} object 1851 * @see #getInsets 1852 * @beaninfo 1853 * expert: true 1854 */ 1855 public Insets getInsets(Insets insets) { 1856 if (insets == null) { 1857 insets = new Insets(0, 0, 0, 0); 1858 } 1859 if (border != null) { 1860 if (border instanceof AbstractBorder) { 1861 return ((AbstractBorder)border).getBorderInsets(this, insets); 1862 } else { 1863 // Can't reuse border insets because the Border interface 1864 // can't be enhanced. 1865 return border.getBorderInsets(this); 1866 } 1867 } else { 1868 // super.getInsets() always returns an Insets object with 1869 // all of its value zeroed. No need for a new object here. 1870 insets.left = insets.top = insets.right = insets.bottom = 0; 1871 return insets; 1872 } 1873 } 1874 1875 /** 1876 * Overrides {@code Container.getAlignmentY} to return 1877 * the vertical alignment. 1878 * 1879 * @return the value of the {@code alignmentY} property 1880 * @see #setAlignmentY 1881 * @see java.awt.Component#getAlignmentY 1882 */ 1883 public float getAlignmentY() { 1884 if (isAlignmentYSet) { 1885 return alignmentY; 1886 } 1887 return super.getAlignmentY(); 1888 } 1889 1890 /** 1891 * Sets the vertical alignment. 1892 * 1893 * @param alignmentY the new vertical alignment 1894 * @see #getAlignmentY 1895 * @beaninfo 1896 * description: The preferred vertical alignment of the component. 1897 */ 1898 public void setAlignmentY(float alignmentY) { 1899 this.alignmentY = validateAlignment(alignmentY); 1900 isAlignmentYSet = true; 1901 } 1902 1903 1904 /** 1905 * Overrides {@code Container.getAlignmentX} to return 1906 * the horizontal alignment. 1907 * 1908 * @return the value of the {@code alignmentX} property 1909 * @see #setAlignmentX 1910 * @see java.awt.Component#getAlignmentX 1911 */ 1912 public float getAlignmentX() { 1913 if (isAlignmentXSet) { 1914 return alignmentX; 1915 } 1916 return super.getAlignmentX(); 1917 } 1918 1919 /** 1920 * Sets the horizontal alignment. 1921 * 1922 * @param alignmentX the new horizontal alignment 1923 * @see #getAlignmentX 1924 * @beaninfo 1925 * description: The preferred horizontal alignment of the component. 1926 */ 1927 public void setAlignmentX(float alignmentX) { 1928 this.alignmentX = validateAlignment(alignmentX); 1936 /** 1937 * Sets the input verifier for this component. 1938 * 1939 * @param inputVerifier the new input verifier 1940 * @since 1.3 1941 * @see InputVerifier 1942 * @beaninfo 1943 * bound: true 1944 * description: The component's input verifier. 1945 */ 1946 public void setInputVerifier(InputVerifier inputVerifier) { 1947 InputVerifier oldInputVerifier = (InputVerifier)getClientProperty( 1948 JComponent_INPUT_VERIFIER); 1949 putClientProperty(JComponent_INPUT_VERIFIER, inputVerifier); 1950 firePropertyChange("inputVerifier", oldInputVerifier, inputVerifier); 1951 } 1952 1953 /** 1954 * Returns the input verifier for this component. 1955 * 1956 * @return the {@code inputVerifier} property 1957 * @since 1.3 1958 * @see InputVerifier 1959 */ 1960 public InputVerifier getInputVerifier() { 1961 return (InputVerifier)getClientProperty(JComponent_INPUT_VERIFIER); 1962 } 1963 1964 /** 1965 * Returns this component's graphics context, which lets you draw 1966 * on a component. Use this method to get a {@code Graphics} object and 1967 * then invoke operations on that object to draw on the component. 1968 * @return this components graphics context 1969 */ 1970 public Graphics getGraphics() { 1971 if (DEBUG_GRAPHICS_LOADED && shouldDebugGraphics() != 0) { 1972 DebugGraphics graphics = new DebugGraphics(super.getGraphics(), 1973 this); 1974 return graphics; 1975 } 1976 return super.getGraphics(); 1977 } 1978 1979 1980 /** Enables or disables diagnostic information about every graphics 1981 * operation performed within the component or one of its children. 1982 * 1983 * @param debugOptions determines how the component should display 1984 * the information; one of the following options: 1985 * <ul> 1986 * <li>DebugGraphics.LOG_OPTION - causes a text message to be printed. 1987 * <li>DebugGraphics.FLASH_OPTION - causes the drawing to flash several 1988 * times. 1989 * <li>DebugGraphics.BUFFERED_OPTION - creates an 1990 * {@code ExternalWindow} that displays the operations 1991 * performed on the View's offscreen buffer. 1992 * <li>DebugGraphics.NONE_OPTION disables debugging. 1993 * <li>A value of 0 causes no changes to the debugging options. 1994 * </ul> 1995 * {@code debugOptions} is bitwise OR'd into the current value 1996 * 1997 * @beaninfo 1998 * preferred: true 1999 * enum: NONE_OPTION DebugGraphics.NONE_OPTION 2000 * LOG_OPTION DebugGraphics.LOG_OPTION 2001 * FLASH_OPTION DebugGraphics.FLASH_OPTION 2002 * BUFFERED_OPTION DebugGraphics.BUFFERED_OPTION 2003 * description: Diagnostic options for graphics operations. 2004 */ 2005 public void setDebugGraphicsOptions(int debugOptions) { 2006 DebugGraphics.setDebugOptions(this, debugOptions); 2007 } 2008 2009 /** Returns the state of graphics debugging. 2010 * 2011 * @return a bitwise OR'd flag of zero or more of the following options: 2012 * <ul> 2013 * <li>DebugGraphics.LOG_OPTION - causes a text message to be printed. 2014 * <li>DebugGraphics.FLASH_OPTION - causes the drawing to flash several 2015 * times. 2016 * <li>DebugGraphics.BUFFERED_OPTION - creates an 2017 * {@code ExternalWindow} that displays the operations 2018 * performed on the View's offscreen buffer. 2019 * <li>DebugGraphics.NONE_OPTION disables debugging. 2020 * <li>A value of 0 causes no changes to the debugging options. 2021 * </ul> 2022 * @see #setDebugGraphicsOptions 2023 */ 2024 public int getDebugGraphicsOptions() { 2025 return DebugGraphics.getDebugOptions(this); 2026 } 2027 2028 2029 /** 2030 * Returns true if debug information is enabled for this 2031 * {@code JComponent} or one of its parents. 2032 */ 2033 int shouldDebugGraphics() { 2034 return DebugGraphics.shouldComponentDebug(this); 2035 } 2036 2037 /** 2038 * This method is now obsolete, please use a combination of 2039 * {@code getActionMap()} and {@code getInputMap()} for 2040 * similar behavior. For example, to bind the {@code KeyStroke} 2041 * {@code aKeyStroke} to the {@code Action anAction} 2042 * now use: 2043 * <pre> 2044 * component.getInputMap().put(aKeyStroke, aCommand); 2045 * component.getActionMap().put(aCommmand, anAction); 2046 * </pre> 2047 * The above assumes you want the binding to be applicable for 2048 * {@code WHEN_FOCUSED}. To register bindings for other focus 2049 * states use the {@code getInputMap} method that takes an integer. 2050 * <p> 2051 * Register a new keyboard action. 2052 * {@code anAction} will be invoked if a key event matching 2053 * {@code aKeyStroke} occurs and {@code aCondition} is verified. 2054 * The {@code KeyStroke} object defines a 2055 * particular combination of a keyboard key and one or more modifiers 2056 * (alt, shift, ctrl, meta). 2057 * <p> 2058 * The {@code aCommand} will be set in the delivered event if 2059 * specified. 2060 * <p> 2061 * The {@code aCondition} can be one of: 2062 * <blockquote> 2063 * <DL> 2064 * <DT>WHEN_FOCUSED 2065 * <DD>The action will be invoked only when the keystroke occurs 2066 * while the component has the focus. 2067 * <DT>WHEN_IN_FOCUSED_WINDOW 2068 * <DD>The action will be invoked when the keystroke occurs while 2069 * the component has the focus or if the component is in the 2070 * window that has the focus. Note that the component need not 2071 * be an immediate descendent of the window -- it can be 2072 * anywhere in the window's containment hierarchy. In other 2073 * words, whenever <em>any</em> component in the window has the focus, 2074 * the action registered with this component is invoked. 2075 * <DT>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT 2076 * <DD>The action will be invoked when the keystroke occurs while the 2077 * component has the focus or if the component is an ancestor of 2078 * the component that has the focus. 2079 * </DL> 2080 * </blockquote> 2081 * <p> 2082 * The combination of keystrokes and conditions lets you define high 2083 * level (semantic) action events for a specified keystroke+modifier 2084 * combination (using the KeyStroke class) and direct to a parent or 2085 * child of a component that has the focus, or to the component itself. 2086 * In other words, in any hierarchical structure of components, an 2087 * arbitrary key-combination can be immediately directed to the 2088 * appropriate component in the hierarchy, and cause a specific method 2089 * to be invoked (usually by way of adapter objects). 2090 * <p> 2091 * If an action has already been registered for the receiving 2092 * container, with the same charCode and the same modifiers, 2093 * {@code anAction} will replace the action. 2094 * 2095 * @param anAction the {@code Action} to be registered 2096 * @param aCommand the command to be set in the delivered event 2097 * @param aKeyStroke the {@code KeyStroke} to bind to the action 2098 * @param aCondition the condition that needs to be met, see above 2099 * @see KeyStroke 2100 */ 2101 public void registerKeyboardAction(ActionListener anAction,String aCommand,KeyStroke aKeyStroke,int aCondition) { 2102 2103 InputMap inputMap = getInputMap(aCondition, true); 2104 2105 if (inputMap != null) { 2106 ActionMap actionMap = getActionMap(true); 2107 ActionStandin action = new ActionStandin(anAction, aCommand); 2108 inputMap.put(aKeyStroke, action); 2109 if (actionMap != null) { 2110 actionMap.put(action, action); 2111 } 2112 } 2113 } 2114 2115 /** 2116 * Registers any bound {@code WHEN_IN_FOCUSED_WINDOW} actions with 2117 * the {@code KeyboardManager}. If {@code onlyIfNew} 2118 * is true only actions that haven't been registered are pushed 2119 * to the {@code KeyboardManager}; 2120 * otherwise all actions are pushed to the {@code KeyboardManager}. 2121 * 2122 * @param onlyIfNew if true, only actions that haven't been registered 2123 * are pushed to the {@code KeyboardManager} 2124 */ 2125 private void registerWithKeyboardManager(boolean onlyIfNew) { 2126 InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW, false); 2127 KeyStroke[] strokes; 2128 @SuppressWarnings("unchecked") 2129 Hashtable<KeyStroke, KeyStroke> registered = 2130 (Hashtable<KeyStroke, KeyStroke>)getClientProperty 2131 (WHEN_IN_FOCUSED_WINDOW_BINDINGS); 2132 2133 if (inputMap != null) { 2134 // Push any new KeyStrokes to the KeyboardManager. 2135 strokes = inputMap.allKeys(); 2136 if (strokes != null) { 2137 for (int counter = strokes.length - 1; counter >= 0; 2138 counter--) { 2139 if (!onlyIfNew || registered == null || 2140 registered.get(strokes[counter]) == null) { 2141 registerWithKeyboardManager(strokes[counter]); 2142 } 2143 if (registered != null) { 2159 } 2160 registered.clear(); 2161 } 2162 // Updated the registered Hashtable. 2163 if (strokes != null && strokes.length > 0) { 2164 if (registered == null) { 2165 registered = new Hashtable<KeyStroke, KeyStroke>(strokes.length); 2166 putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, registered); 2167 } 2168 for (int counter = strokes.length - 1; counter >= 0; counter--) { 2169 registered.put(strokes[counter], strokes[counter]); 2170 } 2171 } 2172 else { 2173 putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, null); 2174 } 2175 } 2176 2177 /** 2178 * Unregisters all the previously registered 2179 * {@code WHEN_IN_FOCUSED_WINDOW KeyStroke} bindings. 2180 */ 2181 private void unregisterWithKeyboardManager() { 2182 @SuppressWarnings("unchecked") 2183 Hashtable<KeyStroke, KeyStroke> registered = 2184 (Hashtable<KeyStroke, KeyStroke>)getClientProperty 2185 (WHEN_IN_FOCUSED_WINDOW_BINDINGS); 2186 2187 if (registered != null && registered.size() > 0) { 2188 Enumeration<KeyStroke> keys = registered.keys(); 2189 2190 while (keys.hasMoreElements()) { 2191 KeyStroke ks = keys.nextElement(); 2192 unregisterWithKeyboardManager(ks); 2193 } 2194 } 2195 putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, null); 2196 } 2197 2198 /** 2199 * Invoked from {@code ComponentInputMap} when its bindings change. 2200 * If {@code inputMap} is the current {@code windowInputMap} 2201 * (or a parent of the window {@code InputMap}) 2202 * the {@code KeyboardManager} is notified of the new bindings. 2203 * 2204 * @param inputMap the map containing the new bindings 2205 */ 2206 void componentInputMapChanged(ComponentInputMap inputMap) { 2207 InputMap km = getInputMap(WHEN_IN_FOCUSED_WINDOW, false); 2208 2209 while (km != inputMap && km != null) { 2210 km = km.getParent(); 2211 } 2212 if (km != null) { 2213 registerWithKeyboardManager(false); 2214 } 2215 } 2216 2217 private void registerWithKeyboardManager(KeyStroke aKeyStroke) { 2218 KeyboardManager.getCurrentManager().registerKeyStroke(aKeyStroke,this); 2219 } 2220 2221 private void unregisterWithKeyboardManager(KeyStroke aKeyStroke) { 2222 KeyboardManager.getCurrentManager().unregisterKeyStroke(aKeyStroke, 2223 this); 2224 } 2225 2226 /** 2227 * This method is now obsolete, please use a combination of 2228 * {@code getActionMap()} and {@code getInputMap()} for 2229 * similar behavior. 2230 * 2231 * @param anAction action to be registered to given keystroke and condition 2232 * @param aKeyStroke a {@code KeyStroke} 2233 * @param aCondition the condition to be associated with given keystroke 2234 * and action 2235 * @see #getActionMap 2236 * @see #getInputMap(int) 2237 */ 2238 public void registerKeyboardAction(ActionListener anAction,KeyStroke aKeyStroke,int aCondition) { 2239 registerKeyboardAction(anAction,null,aKeyStroke,aCondition); 2240 } 2241 2242 /** 2243 * This method is now obsolete. To unregister an existing binding 2244 * you can either remove the binding from the 2245 * {@code ActionMap/InputMap}, or place a dummy binding the 2246 * {@code InputMap}. Removing the binding from the 2247 * {@code InputMap} allows bindings in parent {@code InputMap}s 2248 * to be active, whereas putting a dummy binding in the 2249 * {@code InputMap} effectively disables 2250 * the binding from ever happening. 2251 * <p> 2252 * Unregisters a keyboard action. 2253 * This will remove the binding from the {@code ActionMap} 2254 * (if it exists) as well as the {@code InputMap}s. 2255 * 2256 * @param aKeyStroke the keystroke for which to unregister its 2257 * keyboard action 2258 */ 2259 public void unregisterKeyboardAction(KeyStroke aKeyStroke) { 2260 ActionMap am = getActionMap(false); 2261 for (int counter = 0; counter < 3; counter++) { 2262 InputMap km = getInputMap(counter, false); 2263 if (km != null) { 2264 Object actionID = km.get(aKeyStroke); 2265 2266 if (am != null && actionID != null) { 2267 am.remove(actionID); 2268 } 2269 km.remove(aKeyStroke); 2270 } 2271 } 2272 } 2273 2274 /** 2275 * Returns the {@code KeyStrokes} that will initiate 2276 * registered actions. 2277 * 2278 * @return an array of {@code KeyStroke} objects 2279 * @see #registerKeyboardAction 2280 */ 2281 public KeyStroke[] getRegisteredKeyStrokes() { 2282 int[] counts = new int[3]; 2283 KeyStroke[][] strokes = new KeyStroke[3][]; 2284 2285 for (int counter = 0; counter < 3; counter++) { 2286 InputMap km = getInputMap(counter, false); 2287 strokes[counter] = (km != null) ? km.allKeys() : null; 2288 counts[counter] = (strokes[counter] != null) ? 2289 strokes[counter].length : 0; 2290 } 2291 KeyStroke[] retValue = new KeyStroke[counts[0] + counts[1] + 2292 counts[2]]; 2293 for (int counter = 0, last = 0; counter < 3; counter++) { 2294 if (counts[counter] > 0) { 2295 System.arraycopy(strokes[counter], 0, retValue, last, 2296 counts[counter]); 2297 last += counts[counter]; 2298 } 2299 } 2300 return retValue; 2301 } 2302 2303 /** 2304 * Returns the condition that determines whether a registered action 2305 * occurs in response to the specified keystroke. 2306 * <p> 2307 * For Java 2 platform v1.3, a {@code KeyStroke} can be associated 2308 * with more than one condition. 2309 * For example, 'a' could be bound for the two 2310 * conditions {@code WHEN_FOCUSED} and 2311 * {@code WHEN_IN_FOCUSED_WINDOW} condition. 2312 * 2313 * @param aKeyStroke the keystroke for which to request an 2314 * action-keystroke condition 2315 * @return the action-keystroke condition 2316 */ 2317 public int getConditionForKeyStroke(KeyStroke aKeyStroke) { 2318 for (int counter = 0; counter < 3; counter++) { 2319 InputMap inputMap = getInputMap(counter, false); 2320 if (inputMap != null && inputMap.get(aKeyStroke) != null) { 2321 return counter; 2322 } 2323 } 2324 return UNDEFINED_CONDITION; 2325 } 2326 2327 /** 2328 * Returns the object that will perform the action registered for a 2329 * given keystroke. 2330 * 2331 * @param aKeyStroke the keystroke for which to return a listener 2332 * @return the {@code ActionListener} 2333 * object invoked when the keystroke occurs 2334 */ 2335 public ActionListener getActionForKeyStroke(KeyStroke aKeyStroke) { 2336 ActionMap am = getActionMap(false); 2337 2338 if (am == null) { 2339 return null; 2340 } 2341 for (int counter = 0; counter < 3; counter++) { 2342 InputMap inputMap = getInputMap(counter, false); 2343 if (inputMap != null) { 2344 Object actionBinding = inputMap.get(aKeyStroke); 2345 2346 if (actionBinding != null) { 2347 Action action = am.get(actionBinding); 2348 if (action instanceof ActionStandin) { 2349 return ((ActionStandin)action).actionListener; 2350 } 2351 return action; 2352 } 2353 } 2354 } 2355 return null; 2356 } 2357 2358 /** 2359 * Unregisters all the bindings in the first tier {@code InputMaps} 2360 * and {@code ActionMap}. This has the effect of removing any 2361 * local bindings, and allowing the bindings defined in parent 2362 * {@code InputMap/ActionMaps} 2363 * (the UI is usually defined in the second tier) to persist. 2364 */ 2365 public void resetKeyboardActions() { 2366 // Keys 2367 for (int counter = 0; counter < 3; counter++) { 2368 InputMap inputMap = getInputMap(counter, false); 2369 2370 if (inputMap != null) { 2371 inputMap.clear(); 2372 } 2373 } 2374 2375 // Actions 2376 ActionMap am = getActionMap(false); 2377 2378 if (am != null) { 2379 am.clear(); 2380 } 2381 } 2382 2383 /** 2384 * Sets the {@code InputMap} to use under the condition 2385 * {@code condition} to 2386 * {@code map}. A {@code null} value implies you 2387 * do not want any bindings to be used, even from the UI. This will 2388 * not reinstall the UI {@code InputMap} (if there was one). 2389 * {@code condition} has one of the following values: 2390 * <ul> 2391 * <li>{@code WHEN_IN_FOCUSED_WINDOW} 2392 * <li>{@code WHEN_FOCUSED} 2393 * <li>{@code WHEN_ANCESTOR_OF_FOCUSED_COMPONENT} 2394 * </ul> 2395 * If {@code condition} is {@code WHEN_IN_FOCUSED_WINDOW} 2396 * and {@code map} is not a {@code ComponentInputMap}, an 2397 * {@code IllegalArgumentException} will be thrown. 2398 * Similarly, if {@code condition} is not one of the values 2399 * listed, an {@code IllegalArgumentException} will be thrown. 2400 * 2401 * @param condition one of the values listed above 2402 * @param map the {@code InputMap} to use for the given condition 2403 * @exception IllegalArgumentException if {@code condition} is 2404 * {@code WHEN_IN_FOCUSED_WINDOW} and {@code map} 2405 * is not an instance of {@code ComponentInputMap}; or 2406 * if {@code condition} is not one of the legal values 2407 * specified above 2408 * @since 1.3 2409 */ 2410 public final void setInputMap(int condition, InputMap map) { 2411 switch (condition) { 2412 case WHEN_IN_FOCUSED_WINDOW: 2413 if (map != null && !(map instanceof ComponentInputMap)) { 2414 throw new IllegalArgumentException("WHEN_IN_FOCUSED_WINDOW InputMaps must be of type ComponentInputMap"); 2415 } 2416 windowInputMap = (ComponentInputMap)map; 2417 setFlag(WIF_INPUTMAP_CREATED, true); 2418 registerWithKeyboardManager(false); 2419 break; 2420 case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT: 2421 ancestorInputMap = map; 2422 setFlag(ANCESTOR_INPUTMAP_CREATED, true); 2423 break; 2424 case WHEN_FOCUSED: 2425 focusInputMap = map; 2426 setFlag(FOCUS_INPUTMAP_CREATED, true); 2427 break; 2428 default: 2429 throw new IllegalArgumentException("condition must be one of JComponent.WHEN_IN_FOCUSED_WINDOW, JComponent.WHEN_FOCUSED or JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT"); 2430 } 2431 } 2432 2433 /** 2434 * Returns the {@code InputMap} that is used during 2435 * {@code condition}. 2436 * 2437 * @param condition one of WHEN_IN_FOCUSED_WINDOW, WHEN_FOCUSED, 2438 * WHEN_ANCESTOR_OF_FOCUSED_COMPONENT 2439 * @return the {@code InputMap} for the specified 2440 * {@code condition} 2441 * @since 1.3 2442 */ 2443 public final InputMap getInputMap(int condition) { 2444 return getInputMap(condition, true); 2445 } 2446 2447 /** 2448 * Returns the {@code InputMap} that is used when the 2449 * component has focus. 2450 * This is convenience method for {@code getInputMap(WHEN_FOCUSED)}. 2451 * 2452 * @return the {@code InputMap} used when the component has focus 2453 * @since 1.3 2454 */ 2455 public final InputMap getInputMap() { 2456 return getInputMap(WHEN_FOCUSED, true); 2457 } 2458 2459 /** 2460 * Sets the {@code ActionMap} to {@code am}. This does not set 2461 * the parent of the {@code am} to be the {@code ActionMap} 2462 * from the UI (if there was one), it is up to the caller to have done this. 2463 * 2464 * @param am the new {@code ActionMap} 2465 * @since 1.3 2466 */ 2467 public final void setActionMap(ActionMap am) { 2468 actionMap = am; 2469 setFlag(ACTIONMAP_CREATED, true); 2470 } 2471 2472 /** 2473 * Returns the {@code ActionMap} used to determine what 2474 * {@code Action} to fire for particular {@code KeyStroke} 2475 * binding. The returned {@code ActionMap}, unless otherwise 2476 * set, will have the {@code ActionMap} from the UI set as the parent. 2477 * 2478 * @return the {@code ActionMap} containing the key/action bindings 2479 * @since 1.3 2480 */ 2481 public final ActionMap getActionMap() { 2482 return getActionMap(true); 2483 } 2484 2485 /** 2486 * Returns the {@code InputMap} to use for condition 2487 * {@code condition}. If the {@code InputMap} hasn't 2488 * been created, and {@code create} is 2489 * true, it will be created. 2490 * 2491 * @param condition one of the following values: 2492 * <ul> 2493 * <li>JComponent.FOCUS_INPUTMAP_CREATED 2494 * <li>JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT 2495 * <li>JComponent.WHEN_IN_FOCUSED_WINDOW 2496 * </ul> 2497 * @param create if true, create the {@code InputMap} if it 2498 * is not already created 2499 * @return the {@code InputMap} for the given {@code condition}; 2500 * if {@code create} is false and the {@code InputMap} 2501 * hasn't been created, returns {@code null} 2502 * @exception IllegalArgumentException if {@code condition} 2503 * is not one of the legal values listed above 2504 */ 2505 final InputMap getInputMap(int condition, boolean create) { 2506 switch (condition) { 2507 case WHEN_FOCUSED: 2508 if (getFlag(FOCUS_INPUTMAP_CREATED)) { 2509 return focusInputMap; 2510 } 2511 // Hasn't been created yet. 2512 if (create) { 2513 InputMap km = new InputMap(); 2514 setInputMap(condition, km); 2515 return km; 2516 } 2517 break; 2518 case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT: 2519 if (getFlag(ANCESTOR_INPUTMAP_CREATED)) { 2520 return ancestorInputMap; 2521 } 2522 // Hasn't been created yet. 2527 } 2528 break; 2529 case WHEN_IN_FOCUSED_WINDOW: 2530 if (getFlag(WIF_INPUTMAP_CREATED)) { 2531 return windowInputMap; 2532 } 2533 // Hasn't been created yet. 2534 if (create) { 2535 ComponentInputMap km = new ComponentInputMap(this); 2536 setInputMap(condition, km); 2537 return km; 2538 } 2539 break; 2540 default: 2541 throw new IllegalArgumentException("condition must be one of JComponent.WHEN_IN_FOCUSED_WINDOW, JComponent.WHEN_FOCUSED or JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT"); 2542 } 2543 return null; 2544 } 2545 2546 /** 2547 * Finds and returns the appropriate {@code ActionMap}. 2548 * 2549 * @param create if true, create the {@code ActionMap} if it 2550 * is not already created 2551 * @return the {@code ActionMap} for this component; if the 2552 * {@code create} flag is false and there is no 2553 * current {@code ActionMap}, returns {@code null} 2554 */ 2555 final ActionMap getActionMap(boolean create) { 2556 if (getFlag(ACTIONMAP_CREATED)) { 2557 return actionMap; 2558 } 2559 // Hasn't been created. 2560 if (create) { 2561 ActionMap am = new ActionMap(); 2562 setActionMap(am); 2563 return am; 2564 } 2565 return null; 2566 } 2567 2568 /** 2569 * Returns the baseline. The baseline is measured from the top of 2570 * the component. This method is primarily meant for 2571 * {@code LayoutManager}s to align components along their 2572 * baseline. A return value less than 0 indicates this component 2573 * does not have a reasonable baseline and that 2574 * {@code LayoutManager}s should not align this component on 2575 * its baseline. 2576 * <p> 2577 * This method calls into the {@code ComponentUI} method of the 2578 * same name. If this component does not have a {@code ComponentUI} 2579 * -1 will be returned. If a value >= 0 is 2580 * returned, then the component has a valid baseline for any 2581 * size >= the minimum size and {@code getBaselineResizeBehavior} 2582 * can be used to determine how the baseline changes with size. 2583 * 2584 * @throws IllegalArgumentException {@inheritDoc} 2585 * @see #getBaselineResizeBehavior 2586 * @see java.awt.FontMetrics 2587 * @since 1.6 2588 */ 2589 public int getBaseline(int width, int height) { 2590 // check size. 2591 super.getBaseline(width, height); 2592 if (ui != null) { 2593 return ui.getBaseline(this, width, height); 2594 } 2595 return -1; 2596 } 2597 2598 /** 2599 * Returns an enum indicating how the baseline of the component 2600 * changes as the size changes. This method is primarily meant for 2601 * layout managers and GUI builders. 2602 * <p> 2603 * This method calls into the {@code ComponentUI} method of 2604 * the same name. If this component does not have a 2605 * {@code ComponentUI} 2606 * {@code BaselineResizeBehavior.OTHER} will be 2607 * returned. Subclasses should 2608 * never return {@code null}; if the baseline can not be 2609 * calculated return {@code BaselineResizeBehavior.OTHER}. Callers 2610 * should first ask for the baseline using 2611 * {@code getBaseline} and if a value >= 0 is returned use 2612 * this method. It is acceptable for this method to return a 2613 * value other than {@code BaselineResizeBehavior.OTHER} even if 2614 * {@code getBaseline} returns a value less than 0. 2615 * 2616 * @see #getBaseline(int, int) 2617 * @since 1.6 2618 */ 2619 public BaselineResizeBehavior getBaselineResizeBehavior() { 2620 if (ui != null) { 2621 return ui.getBaselineResizeBehavior(this); 2622 } 2623 return BaselineResizeBehavior.OTHER; 2624 } 2625 2626 /** 2627 * In release 1.4, the focus subsystem was rearchitected. 2628 * For more information, see 2629 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> 2630 * How to Use the Focus Subsystem</a>, 2631 * a section in <em>The Java Tutorial</em>. 2632 * <p> 2633 * Requests focus on this {@code JComponent}'s 2634 * {@code FocusTraversalPolicy}'s default {@code Component}. 2635 * If this {@code JComponent} is a focus cycle root, then its 2636 * {@code FocusTraversalPolicy} is used. Otherwise, the 2637 * {@code FocusTraversalPolicy} of this {@code JComponent}'s 2638 * focus-cycle-root ancestor is used. 2639 * 2640 * @return true if this component can request to get the input focus, 2641 * false if it can not 2642 * @see java.awt.FocusTraversalPolicy#getDefaultComponent 2643 * @deprecated As of 1.4, replaced by 2644 * {@code FocusTraversalPolicy.getDefaultComponent(Container).requestFocus()} 2645 */ 2646 @Deprecated 2647 public boolean requestDefaultFocus() { 2648 Container nearestRoot = 2649 (isFocusCycleRoot()) ? this : getFocusCycleRootAncestor(); 2650 if (nearestRoot == null) { 2651 return false; 2652 } 2653 Component comp = nearestRoot.getFocusTraversalPolicy(). 2654 getDefaultComponent(nearestRoot); 2655 if (comp != null) { 2656 comp.requestFocus(); 2657 return true; 2658 } else { 2659 return false; 2660 } 2661 } 2662 2663 /** 2664 * Makes the component visible or invisible. 2665 * Overrides {@code Component.setVisible}. 2666 * 2667 * @param aFlag true to make the component visible; false to 2668 * make it invisible 2669 * 2670 * @beaninfo 2671 * attribute: visualUpdate true 2672 */ 2673 public void setVisible(boolean aFlag) { 2674 if (aFlag != isVisible()) { 2675 super.setVisible(aFlag); 2676 if (aFlag) { 2677 Container parent = getParent(); 2678 if (parent != null) { 2679 Rectangle r = getBounds(); 2680 parent.repaint(r.x, r.y, r.width, r.height); 2681 } 2682 revalidate(); 2683 } 2684 } 2685 } 2703 * @beaninfo 2704 * preferred: true 2705 * bound: true 2706 * attribute: visualUpdate true 2707 * description: The enabled state of the component. 2708 */ 2709 public void setEnabled(boolean enabled) { 2710 boolean oldEnabled = isEnabled(); 2711 super.setEnabled(enabled); 2712 firePropertyChange("enabled", oldEnabled, enabled); 2713 if (enabled != oldEnabled) { 2714 repaint(); 2715 } 2716 } 2717 2718 /** 2719 * Sets the foreground color of this component. It is up to the 2720 * look and feel to honor this property, some may choose to ignore 2721 * it. 2722 * 2723 * @param fg the desired foreground {@code Color} 2724 * @see java.awt.Component#getForeground 2725 * 2726 * @beaninfo 2727 * preferred: true 2728 * bound: true 2729 * attribute: visualUpdate true 2730 * description: The foreground color of the component. 2731 */ 2732 public void setForeground(Color fg) { 2733 Color oldFg = getForeground(); 2734 super.setForeground(fg); 2735 if ((oldFg != null) ? !oldFg.equals(fg) : ((fg != null) && !fg.equals(oldFg))) { 2736 // foreground already bound in AWT1.2 2737 repaint(); 2738 } 2739 } 2740 2741 /** 2742 * Sets the background color of this component. The background 2743 * color is used only if the component is opaque, and only 2744 * by subclasses of {@code JComponent} or 2745 * {@code ComponentUI} implementations. Direct subclasses of 2746 * {@code JComponent} must override 2747 * {@code paintComponent} to honor this property. 2748 * <p> 2749 * It is up to the look and feel to honor this property, some may 2750 * choose to ignore it. 2751 * 2752 * @param bg the desired background {@code Color} 2753 * @see java.awt.Component#getBackground 2754 * @see #setOpaque 2755 * 2756 * @beaninfo 2757 * preferred: true 2758 * bound: true 2759 * attribute: visualUpdate true 2760 * description: The background color of the component. 2761 */ 2762 public void setBackground(Color bg) { 2763 Color oldBg = getBackground(); 2764 super.setBackground(bg); 2765 if ((oldBg != null) ? !oldBg.equals(bg) : ((bg != null) && !bg.equals(oldBg))) { 2766 // background already bound in AWT1.2 2767 repaint(); 2768 } 2769 } 2770 2771 /** 2772 * Sets the font for this component. 2773 * 2774 * @param font the desired {@code Font} for this component 2775 * @see java.awt.Component#getFont 2776 * 2777 * @beaninfo 2778 * preferred: true 2779 * bound: true 2780 * attribute: visualUpdate true 2781 * description: The font for the component. 2782 */ 2783 public void setFont(Font font) { 2784 Font oldFont = getFont(); 2785 super.setFont(font); 2786 // font already bound in AWT1.2 2787 if (font != oldFont) { 2788 revalidate(); 2789 repaint(); 2790 } 2791 } 2792 2793 /** 2794 * Returns the default locale used to initialize each JComponent's 2795 * locale property upon creation. 2796 * 2797 * The default locale has "AppContext" scope so that applets (and 2798 * potentially multiple lightweight applications running in a single VM) 2799 * can have their own setting. An applet can safely alter its default 2800 * locale because it will have no affect on other applets (or the browser). 2801 * 2802 * @return the default {@code Locale}. 2803 * @see #setDefaultLocale 2804 * @see java.awt.Component#getLocale 2805 * @see #setLocale 2806 * @since 1.4 2807 */ 2808 public static Locale getDefaultLocale() { 2809 Locale l = (Locale) SwingUtilities.appContextGet(defaultLocale); 2810 if( l == null ) { 2811 //REMIND(bcb) choosing the default value is more complicated 2812 //than this. 2813 l = Locale.getDefault(); 2814 JComponent.setDefaultLocale( l ); 2815 } 2816 return l; 2817 } 2818 2819 2820 /** 2821 * Sets the default locale used to initialize each JComponent's locale 2822 * property upon creation. The initial value is the VM's default locale. 2823 * 2824 * The default locale has "AppContext" scope so that applets (and 2825 * potentially multiple lightweight applications running in a single VM) 2826 * can have their own setting. An applet can safely alter its default 2827 * locale because it will have no affect on other applets (or the browser). 2828 * 2829 * @param l the desired default {@code Locale} for new components. 2830 * @see #getDefaultLocale 2831 * @see java.awt.Component#getLocale 2832 * @see #setLocale 2833 * @since 1.4 2834 */ 2835 public static void setDefaultLocale( Locale l ) { 2836 SwingUtilities.appContextPut(defaultLocale, l); 2837 } 2838 2839 2840 /** 2841 * Processes any key events that the component itself 2842 * recognizes. This is called after the focus 2843 * manager and any interested listeners have been 2844 * given a chance to steal away the event. This 2845 * method is called only if the event has not 2846 * yet been consumed. This method is called prior 2847 * to the keyboard UI logic. 2848 * <p> 2849 * This method is implemented to do nothing. Subclasses would 2850 * normally override this method if they process some 2851 * key events themselves. If the event is processed, 2852 * it should be consumed. 2853 * 2854 * @param e the event to be processed 2855 */ 2856 protected void processComponentKeyEvent(KeyEvent e) { 2857 } 2858 2859 /** Overrides {@code processKeyEvent} to process events. **/ 2860 protected void processKeyEvent(KeyEvent e) { 2861 boolean result; 2862 boolean shouldProcessKey; 2863 2864 // This gives the key event listeners a crack at the event 2865 super.processKeyEvent(e); 2866 2867 // give the component itself a crack at the event 2868 if (! e.isConsumed()) { 2869 processComponentKeyEvent(e); 2870 } 2871 2872 shouldProcessKey = KeyboardState.shouldProcess(e); 2873 2874 if(e.isConsumed()) { 2875 return; 2876 } 2877 2878 if (shouldProcessKey && processKeyBindings(e, e.getID() == 2879 KeyEvent.KEY_PRESSED)) { 2880 e.consume(); 2881 } 2882 } 2883 2884 /** 2885 * Invoked to process the key bindings for {@code ks} as the result 2886 * of the {@code KeyEvent e}. This obtains 2887 * the appropriate {@code InputMap}, 2888 * gets the binding, gets the action from the {@code ActionMap}, 2889 * and then (if the action is found and the component 2890 * is enabled) invokes {@code notifyAction} to notify the action. 2891 * 2892 * @param ks the {@code KeyStroke} queried 2893 * @param e the {@code KeyEvent} 2894 * @param condition one of the following values: 2895 * <ul> 2896 * <li>JComponent.WHEN_FOCUSED 2897 * <li>JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT 2898 * <li>JComponent.WHEN_IN_FOCUSED_WINDOW 2899 * </ul> 2900 * @param pressed true if the key is pressed 2901 * @return true if there was a binding to an action, and the action 2902 * was enabled 2903 * 2904 * @since 1.3 2905 */ 2906 protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, 2907 int condition, boolean pressed) { 2908 InputMap map = getInputMap(condition, false); 2909 ActionMap am = getActionMap(false); 2910 2911 if(map != null && am != null && isEnabled()) { 2912 Object binding = map.get(ks); 2913 Action action = (binding == null) ? null : am.get(binding); 2914 if (action != null) { 2915 return SwingUtilities.notifyAction(action, ks, e, this, 2916 e.getModifiers()); 2917 } 2918 } 2919 return false; 2920 } 2921 2922 /** 2923 * This is invoked as the result of a {@code KeyEvent} 2924 * that was not consumed by the {@code FocusManager}, 2925 * {@code KeyListeners}, or the component. It will first try 2926 * {@code WHEN_FOCUSED} bindings, 2927 * then {@code WHEN_ANCESTOR_OF_FOCUSED_COMPONENT} bindings, 2928 * and finally {@code WHEN_IN_FOCUSED_WINDOW} bindings. 2929 * 2930 * @param e the unconsumed {@code KeyEvent} 2931 * @param pressed true if the key is pressed 2932 * @return true if there is a key binding for {@code e} 2933 */ 2934 boolean processKeyBindings(KeyEvent e, boolean pressed) { 2935 if (!SwingUtilities.isValidKeyEventForKeyBindings(e)) { 2936 return false; 2937 } 2938 // Get the KeyStroke 2939 // There may be two keystrokes associated with a low-level key event; 2940 // in this case a keystroke made of an extended key code has a priority. 2941 KeyStroke ks; 2942 KeyStroke ksE = null; 2943 2944 if (e.getID() == KeyEvent.KEY_TYPED) { 2945 ks = KeyStroke.getKeyStroke(e.getKeyChar()); 2946 } 2947 else { 2948 ks = KeyStroke.getKeyStroke(e.getKeyCode(),e.getModifiers(), 2949 (pressed ? false:true)); 2950 if (e.getKeyCode() != e.getExtendedKeyCode()) { 2951 ksE = KeyStroke.getKeyStroke(e.getExtendedKeyCode(),e.getModifiers(), 2952 (pressed ? false:true)); 3008 e, pressed, container)) { 3009 return true; 3010 } 3011 if (container instanceof Popup.HeavyWeightWindow) { 3012 container = ((Window)container).getOwner(); 3013 } 3014 else { 3015 return false; 3016 } 3017 } 3018 } 3019 3020 /** 3021 * Registers the text to display in a tool tip. 3022 * The text displays when the cursor lingers over the component. 3023 * <p> 3024 * See <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/tooltip.html">How to Use Tool Tips</a> 3025 * in <em>The Java Tutorial</em> 3026 * for further documentation. 3027 * 3028 * @param text the string to display; if the text is {@code null}, 3029 * the tool tip is turned off for this component 3030 * @see #TOOL_TIP_TEXT_KEY 3031 * @beaninfo 3032 * preferred: true 3033 * description: The text to display in a tool tip. 3034 */ 3035 public void setToolTipText(String text) { 3036 String oldText = getToolTipText(); 3037 putClientProperty(TOOL_TIP_TEXT_KEY, text); 3038 ToolTipManager toolTipManager = ToolTipManager.sharedInstance(); 3039 if (text != null) { 3040 if (oldText == null) { 3041 toolTipManager.registerComponent(this); 3042 } 3043 } else { 3044 toolTipManager.unregisterComponent(this); 3045 } 3046 } 3047 3048 /** 3049 * Returns the tooltip string that has been set with 3050 * {@code setToolTipText}. 3051 * 3052 * @return the text of the tool tip 3053 * @see #TOOL_TIP_TEXT_KEY 3054 */ 3055 public String getToolTipText() { 3056 return (String)getClientProperty(TOOL_TIP_TEXT_KEY); 3057 } 3058 3059 3060 /** 3061 * Returns the string to be used as the tooltip for <i>event</i>. 3062 * By default this returns any string set using 3063 * {@code setToolTipText}. If a component provides 3064 * more extensive API to support differing tooltips at different locations, 3065 * this method should be overridden. 3066 * 3067 * @param event the {@code MouseEvent} that initiated the 3068 * {@code ToolTip} display 3069 * @return a string containing the tooltip 3070 */ 3071 public String getToolTipText(MouseEvent event) { 3072 return getToolTipText(); 3073 } 3074 3075 /** 3076 * Returns the tooltip location in this component's coordinate system. 3077 * If {@code null} is returned, Swing will choose a location. 3078 * The default implementation returns {@code null}. 3079 * 3080 * @param event the {@code MouseEvent} that caused the 3081 * {@code ToolTipManager} to show the tooltip 3082 * @return always returns {@code null} 3083 */ 3084 public Point getToolTipLocation(MouseEvent event) { 3085 return null; 3086 } 3087 3088 /** 3089 * Returns the preferred location to display the popup menu in this 3090 * component's coordinate system. It is up to the look and feel to 3091 * honor this property, some may choose to ignore it. 3092 * If {@code null}, the look and feel will choose a suitable location. 3093 * 3094 * @param event the {@code MouseEvent} that triggered the popup to be 3095 * shown, or {@code null} if the popup is not being shown as the 3096 * result of a mouse event 3097 * @return location to display the {@code JPopupMenu}, or {@code null} 3098 * @since 1.5 3099 */ 3100 public Point getPopupLocation(MouseEvent event) { 3101 return null; 3102 } 3103 3104 3105 /** 3106 * Returns the instance of {@code JToolTip} that should be used 3107 * to display the tooltip. 3108 * Components typically would not override this method, 3109 * but it can be used to 3110 * cause different tooltips to be displayed differently. 3111 * 3112 * @return the {@code JToolTip} used to display this toolTip 3113 */ 3114 public JToolTip createToolTip() { 3115 JToolTip tip = new JToolTip(); 3116 tip.setComponent(this); 3117 return tip; 3118 } 3119 3120 /** 3121 * Forwards the {@code scrollRectToVisible()} message to the 3122 * {@code JComponent}'s parent. Components that can service 3123 * the request, such as {@code JViewport}, 3124 * override this method and perform the scrolling. 3125 * 3126 * @param aRect the visible {@code Rectangle} 3127 * @see JViewport 3128 */ 3129 public void scrollRectToVisible(Rectangle aRect) { 3130 Container parent; 3131 int dx = getX(), dy = getY(); 3132 3133 for (parent = getParent(); 3134 !(parent == null) && 3135 !(parent instanceof JComponent) && 3136 !(parent instanceof CellRendererPane); 3137 parent = parent.getParent()) { 3138 Rectangle bounds = parent.getBounds(); 3139 3140 dx += bounds.x; 3141 dy += bounds.y; 3142 } 3143 3144 if (!(parent == null) && !(parent instanceof CellRendererPane)) { 3145 aRect.x += dx; 3146 aRect.y += dy; 3147 3148 ((JComponent)parent).scrollRectToVisible(aRect); 3149 aRect.x -= dx; 3150 aRect.y -= dy; 3151 } 3152 } 3153 3154 /** 3155 * Sets the {@code autoscrolls} property. 3156 * If {@code true} mouse dragged events will be 3157 * synthetically generated when the mouse is dragged 3158 * outside of the component's bounds and mouse motion 3159 * has paused (while the button continues to be held 3160 * down). The synthetic events make it appear that the 3161 * drag gesture has resumed in the direction established when 3162 * the component's boundary was crossed. Components that 3163 * support autoscrolling must handle {@code mouseDragged} 3164 * events by calling {@code scrollRectToVisible} with a 3165 * rectangle that contains the mouse event's location. All of 3166 * the Swing components that support item selection and are 3167 * typically displayed in a {@code JScrollPane} 3168 * ({@code JTable}, {@code JList}, {@code JTree}, 3169 * {@code JTextArea}, and {@code JEditorPane}) 3170 * already handle mouse dragged events in this way. To enable 3171 * autoscrolling in any other component, add a mouse motion 3172 * listener that calls {@code scrollRectToVisible}. 3173 * For example, given a {@code JPanel}, {@code myPanel}: 3174 * <pre> 3175 * MouseMotionListener doScrollRectToVisible = new MouseMotionAdapter() { 3176 * public void mouseDragged(MouseEvent e) { 3177 * Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1); 3178 * ((JPanel)e.getSource()).scrollRectToVisible(r); 3179 * } 3180 * }; 3181 * myPanel.addMouseMotionListener(doScrollRectToVisible); 3182 * </pre> 3183 * The default value of the {@code autoScrolls} 3184 * property is {@code false}. 3185 * 3186 * @param autoscrolls if true, synthetic mouse dragged events 3187 * are generated when the mouse is dragged outside of a component's 3188 * bounds and the mouse button continues to be held down; otherwise 3189 * false 3190 * @see #getAutoscrolls 3191 * @see JViewport 3192 * @see JScrollPane 3193 * 3194 * @beaninfo 3195 * expert: true 3196 * description: Determines if this component automatically scrolls its contents when dragged. 3197 */ 3198 public void setAutoscrolls(boolean autoscrolls) { 3199 setFlag(AUTOSCROLLS_SET, true); 3200 if (this.autoscrolls != autoscrolls) { 3201 this.autoscrolls = autoscrolls; 3202 if (autoscrolls) { 3203 enableEvents(AWTEvent.MOUSE_EVENT_MASK); 3204 enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK); 3205 } 3206 else { 3207 Autoscroller.stop(this); 3208 } 3209 } 3210 } 3211 3212 /** 3213 * Gets the {@code autoscrolls} property. 3214 * 3215 * @return the value of the {@code autoscrolls} property 3216 * @see JViewport 3217 * @see #setAutoscrolls 3218 */ 3219 public boolean getAutoscrolls() { 3220 return autoscrolls; 3221 } 3222 3223 /** 3224 * Sets the {@code TransferHandler}, which provides support for transfer 3225 * of data into and out of this component via cut/copy/paste and drag 3226 * and drop. This may be {@code null} if the component does not support 3227 * data transfer operations. 3228 * <p> 3229 * If the new {@code TransferHandler} is not {@code null}, this method 3230 * also installs a <b>new</b> {@code DropTarget} on the component to 3231 * activate drop handling through the {@code TransferHandler} and activate 3232 * any built-in support (such as calculating and displaying potential drop 3233 * locations). If you do not wish for this component to respond in any way 3234 * to drops, you can disable drop support entirely either by removing the 3235 * drop target ({@code setDropTarget(null)}) or by de-activating it 3252 * @param newHandler the new {@code TransferHandler} 3253 * 3254 * @see TransferHandler 3255 * @see #getTransferHandler 3256 * @since 1.4 3257 * @beaninfo 3258 * bound: true 3259 * hidden: true 3260 * description: Mechanism for transfer of data to and from the component 3261 */ 3262 public void setTransferHandler(TransferHandler newHandler) { 3263 TransferHandler oldHandler = (TransferHandler)getClientProperty( 3264 JComponent_TRANSFER_HANDLER); 3265 putClientProperty(JComponent_TRANSFER_HANDLER, newHandler); 3266 3267 SwingUtilities.installSwingDropTargetAsNecessary(this, newHandler); 3268 firePropertyChange("transferHandler", oldHandler, newHandler); 3269 } 3270 3271 /** 3272 * Gets the {@code transferHandler} property. 3273 * 3274 * @return the value of the {@code transferHandler} property 3275 * 3276 * @see TransferHandler 3277 * @see #setTransferHandler 3278 * @since 1.4 3279 */ 3280 public TransferHandler getTransferHandler() { 3281 return (TransferHandler)getClientProperty(JComponent_TRANSFER_HANDLER); 3282 } 3283 3284 /** 3285 * Calculates a custom drop location for this type of component, 3286 * representing where a drop at the given point should insert data. 3287 * {@code null} is returned if this component doesn't calculate 3288 * custom drop locations. In this case, {@code TransferHandler} 3289 * will provide a default {@code DropLocation} containing just 3290 * the point. 3291 * 3292 * @param p the point to calculate a drop location for 3293 * @return the drop location, or {@code null} 3294 */ 3295 TransferHandler.DropLocation dropLocationForPoint(Point p) { 3296 return null; 3297 } 3298 3299 /** 3300 * Called to set or clear the drop location during a DnD operation. 3301 * In some cases, the component may need to use its internal selection 3302 * temporarily to indicate the drop location. To help facilitate this, 3303 * this method returns and accepts as a parameter a state object. 3304 * This state object can be used to store, and later restore, the selection 3305 * state. Whatever this method returns will be passed back to it in 3306 * future calls, as the state parameter. If it wants the DnD system to 3307 * continue storing the same state, it must pass it back every time. 3308 * Here's how this is used: 3309 * <p> 3310 * Let's say that on the first call to this method the component decides 3311 * to save some state (because it is about to use the selection to show 3312 * a drop index). It can return a state object to the caller encapsulating 3313 * any saved selection state. On a second call, let's say the drop location 3314 * is being changed to something else. The component doesn't need to 3315 * restore anything yet, so it simply passes back the same state object 3316 * to have the DnD system continue storing it. Finally, let's say this 3317 * method is messaged with {@code null}. This means DnD 3318 * is finished with this component for now, meaning it should restore 3319 * state. At this point, it can use the state parameter to restore 3320 * said state, and of course return {@code null} since there's 3321 * no longer anything to store. 3322 * 3323 * @param location the drop location (as calculated by 3324 * {@code dropLocationForPoint}) or {@code null} 3325 * if there's no longer a valid drop location 3326 * @param state the state object saved earlier for this component, 3327 * or {@code null} 3328 * @param forDrop whether or not the method is being called because an 3329 * actual drop occurred 3330 * @return any saved state for this component, or {@code null} if none 3331 */ 3332 Object setDropLocation(TransferHandler.DropLocation location, 3333 Object state, 3334 boolean forDrop) { 3335 3336 return null; 3337 } 3338 3339 /** 3340 * Called to indicate to this component that DnD is done. 3341 * Needed by {@code JTree}. 3342 */ 3343 void dndDone() { 3344 } 3345 3346 /** 3347 * Processes mouse events occurring on this component by 3348 * dispatching them to any registered 3349 * {@code MouseListener} objects, refer to 3350 * {@link java.awt.Component#processMouseEvent(MouseEvent)} 3351 * for a complete description of this method. 3352 * 3353 * @param e the mouse event 3354 * @see java.awt.Component#processMouseEvent 3355 * @since 1.5 3356 */ 3357 protected void processMouseEvent(MouseEvent e) { 3358 if (autoscrolls && e.getID() == MouseEvent.MOUSE_RELEASED) { 3359 Autoscroller.stop(this); 3360 } 3361 super.processMouseEvent(e); 3362 } 3363 3364 /** 3365 * Processes mouse motion events, such as MouseEvent.MOUSE_DRAGGED. 3366 * 3367 * @param e the {@code MouseEvent} 3368 * @see MouseEvent 3369 */ 3370 protected void processMouseMotionEvent(MouseEvent e) { 3371 boolean dispatch = true; 3372 if (autoscrolls && e.getID() == MouseEvent.MOUSE_DRAGGED) { 3373 // We don't want to do the drags when the mouse moves if we're 3374 // autoscrolling. It makes it feel spastic. 3375 dispatch = !Autoscroller.isRunning(this); 3376 Autoscroller.processMouseDragged(e); 3377 } 3378 if (dispatch) { 3379 super.processMouseMotionEvent(e); 3380 } 3381 } 3382 3383 // Inner classes can't get at this method from a super class 3384 void superProcessMouseMotionEvent(MouseEvent e) { 3385 super.processMouseMotionEvent(e); 3386 } 3387 3388 /** 3389 * This is invoked by the {@code RepaintManager} if 3390 * {@code createImage} is called on the component. 3391 * 3392 * @param newValue true if the double buffer image was created from this component 3393 */ 3394 void setCreatedDoubleBuffer(boolean newValue) { 3395 setFlag(CREATED_DOUBLE_BUFFER, newValue); 3396 } 3397 3398 /** 3399 * Returns true if the {@code RepaintManager} 3400 * created the double buffer image from the component. 3401 * 3402 * @return true if this component had a double buffer image, false otherwise 3403 */ 3404 boolean getCreatedDoubleBuffer() { 3405 return getFlag(CREATED_DOUBLE_BUFFER); 3406 } 3407 3408 /** 3409 * {@code ActionStandin} is used as a standin for 3410 * {@code ActionListeners} that are 3411 * added via {@code registerKeyboardAction}. 3412 */ 3413 final class ActionStandin implements Action { 3414 private final ActionListener actionListener; 3415 private final String command; 3416 // This will be non-null if actionListener is an Action. 3417 private final Action action; 3418 3419 ActionStandin(ActionListener actionListener, String command) { 3420 this.actionListener = actionListener; 3421 if (actionListener instanceof Action) { 3422 this.action = (Action)actionListener; 3423 } 3424 else { 3425 this.action = null; 3426 } 3427 this.command = command; 3428 } 3429 3430 public Object getValue(String key) { 3431 if (key != null) { 3635 // we ensure that if the InputVerifier for 3636 // currentSource does a requestFocus, we don't 3637 // try and run the InputVerifier again. 3638 SwingUtilities.appContextPut( 3639 INPUT_VERIFIER_SOURCE_KEY, currentSource); 3640 } else { 3641 SwingUtilities.appContextRemove( 3642 INPUT_VERIFIER_SOURCE_KEY); 3643 } 3644 } 3645 } 3646 } 3647 }; 3648 3649 /* 3650 * --- Accessibility Support --- 3651 */ 3652 3653 /** 3654 * @deprecated As of JDK version 1.1, 3655 * replaced by {@code java.awt.Component.setEnabled(boolean)}. 3656 */ 3657 @Deprecated 3658 public void enable() { 3659 if (isEnabled() != true) { 3660 super.enable(); 3661 if (accessibleContext != null) { 3662 accessibleContext.firePropertyChange( 3663 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 3664 null, AccessibleState.ENABLED); 3665 } 3666 } 3667 } 3668 3669 /** 3670 * @deprecated As of JDK version 1.1, 3671 * replaced by {@code java.awt.Component.setEnabled(boolean)}. 3672 */ 3673 @Deprecated 3674 public void disable() { 3675 if (isEnabled() != false) { 3676 super.disable(); 3677 if (accessibleContext != null) { 3678 accessibleContext.firePropertyChange( 3679 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 3680 AccessibleState.ENABLED, null); 3681 } 3682 } 3683 } 3684 3685 /** 3686 * Inner class of JComponent used to provide default support for 3687 * accessibility. This class is not meant to be used directly by 3688 * application developers, but is instead meant only to be 3689 * subclassed by component developers. 3690 * <p> 3691 * <strong>Warning:</strong> 3692 * Serialized objects of this class will not be compatible with 3693 * future Swing releases. The current serialization support is 3694 * appropriate for short term storage or RMI between applications running 3695 * the same version of Swing. As of 1.4, support for long term storage 3696 * of all JavaBeans™ 3697 * has been added to the {@code java.beans} package. 3698 * Please see {@link java.beans.XMLEncoder}. 3699 */ 3700 @SuppressWarnings("serial") // Same-version serialization only 3701 public abstract class AccessibleJComponent extends AccessibleAWTContainer 3702 implements AccessibleExtendedComponent 3703 { 3704 /** 3705 * Though the class is abstract, this should be called by 3706 * all sub-classes. 3707 */ 3708 protected AccessibleJComponent() { 3709 super(); 3710 } 3711 3712 /** 3713 * Number of PropertyChangeListener objects registered. It's used 3714 * to add/remove ContainerListener and FocusListener to track 3715 * target JComponent's state 3716 */ 3717 private transient volatile int propertyListenersCount = 0; 4016 * @since 1.4 4017 */ 4018 public AccessibleKeyBinding getAccessibleKeyBinding(){ 4019 // Try to get the linked label's mnemonic if it exists 4020 Object o = getClientProperty(JLabel.LABELED_BY_PROPERTY); 4021 if (o instanceof Accessible){ 4022 AccessibleContext ac = ((Accessible) o).getAccessibleContext(); 4023 if (ac != null){ 4024 AccessibleComponent comp = ac.getAccessibleComponent(); 4025 if (! (comp instanceof AccessibleExtendedComponent)) 4026 return null; 4027 return ((AccessibleExtendedComponent)comp).getAccessibleKeyBinding(); 4028 } 4029 } 4030 return null; 4031 } 4032 } // inner class AccessibleJComponent 4033 4034 4035 /** 4036 * Returns an {@code ArrayTable} used for 4037 * key/value "client properties" for this component. If the 4038 * {@code clientProperties} table doesn't exist, an empty one 4039 * will be created. 4040 * 4041 * @return an ArrayTable 4042 * @see #putClientProperty 4043 * @see #getClientProperty 4044 */ 4045 private ArrayTable getClientProperties() { 4046 if (clientProperties == null) { 4047 clientProperties = new ArrayTable(); 4048 } 4049 return clientProperties; 4050 } 4051 4052 4053 /** 4054 * Returns the value of the property with the specified key. Only 4055 * properties added with {@code putClientProperty} will return 4056 * a non-{@code null} value. 4057 * 4058 * @param key the being queried 4059 * @return the value of this property or {@code null} 4060 * @see #putClientProperty 4061 */ 4062 public final Object getClientProperty(Object key) { 4063 if (key == RenderingHints.KEY_TEXT_ANTIALIASING) { 4064 return aaHint; 4065 } else if (key == RenderingHints.KEY_TEXT_LCD_CONTRAST) { 4066 return lcdRenderingHint; 4067 } 4068 if(clientProperties == null) { 4069 return null; 4070 } else { 4071 synchronized(clientProperties) { 4072 return clientProperties.get(key); 4073 } 4074 } 4075 } 4076 4077 /** 4078 * Adds an arbitrary key/value "client property" to this component. 4079 * <p> 4080 * The {@code get/putClientProperty} methods provide access to 4081 * a small per-instance hashtable. Callers can use get/putClientProperty 4082 * to annotate components that were created by another module. 4083 * For example, a 4084 * layout manager might store per child constraints this way. For example: 4085 * <pre> 4086 * componentA.putClientProperty("to the left of", componentB); 4087 * </pre> 4088 * If value is {@code null} this method will remove the property. 4089 * Changes to client properties are reported with 4090 * {@code PropertyChange} events. 4091 * The name of the property (for the sake of PropertyChange 4092 * events) is {@code key.toString()}. 4093 * <p> 4094 * The {@code clientProperty} dictionary is not intended to 4095 * support large 4096 * scale extensions to JComponent nor should be it considered an 4097 * alternative to subclassing when designing a new component. 4098 * 4099 * @param key the new client property key 4100 * @param value the new client property value; if {@code null} 4101 * this method will remove the property 4102 * @see #getClientProperty 4103 * @see #addPropertyChangeListener 4104 */ 4105 public final void putClientProperty(Object key, Object value) { 4106 if (key == RenderingHints.KEY_TEXT_ANTIALIASING) { 4107 aaHint = value; 4108 return; 4109 } else if (key == RenderingHints.KEY_TEXT_LCD_CONTRAST) { 4110 lcdRenderingHint = value; 4111 return; 4112 } 4113 if (value == null && clientProperties == null) { 4114 // Both the value and ArrayTable are null, implying we don't 4115 // have to do anything. 4116 return; 4117 } 4118 ArrayTable clientProperties = getClientProperties(); 4119 Object oldValue; 4120 synchronized(clientProperties) { 4226 * The methods and fields in this section will migrate to 4227 * java.awt.Component in the next JDK release. 4228 */ 4229 4230 /** 4231 * Returns true if this component is lightweight, that is, if it doesn't 4232 * have a native window system peer. 4233 * 4234 * @param c the {@code Component} to be checked 4235 * @return true if this component is lightweight 4236 */ 4237 public static boolean isLightweightComponent(Component c) { 4238 // TODO we cannot call c.isLightweight() because it is incorrectly 4239 // overriden in DelegateContainer on osx. 4240 return AWTAccessor.getComponentAccessor().isLightweight(c); 4241 } 4242 4243 4244 /** 4245 * @deprecated As of JDK 5, 4246 * replaced by {@code Component.setBounds(int, int, int, int)}. 4247 * <p> 4248 * Moves and resizes this component. 4249 * 4250 * @param x the new horizontal location 4251 * @param y the new vertical location 4252 * @param w the new width 4253 * @param h the new height 4254 * @see java.awt.Component#setBounds 4255 */ 4256 @Deprecated 4257 public void reshape(int x, int y, int w, int h) { 4258 super.reshape(x, y, w, h); 4259 } 4260 4261 4262 /** 4263 * Stores the bounds of this component into "return value" 4264 * {@code rv} and returns {@code rv}. 4265 * If {@code rv} is {@code null} a new {@code Rectangle} 4266 * is allocated. This version of {@code getBounds} is useful 4267 * if the caller wants to avoid allocating a new {@code Rectangle} 4268 * object on the heap. 4269 * 4270 * @param rv the return value, modified to the component's bounds 4271 * @return {@code rv}; if {@code rv} is {@code null} 4272 * return a newly created {@code Rectangle} with this 4273 * component's bounds 4274 */ 4275 public Rectangle getBounds(Rectangle rv) { 4276 if (rv == null) { 4277 return new Rectangle(getX(), getY(), getWidth(), getHeight()); 4278 } 4279 else { 4280 rv.setBounds(getX(), getY(), getWidth(), getHeight()); 4281 return rv; 4282 } 4283 } 4284 4285 4286 /** 4287 * Stores the width/height of this component into "return value" 4288 * {@code rv} and returns {@code rv}. 4289 * If {@code rv} is {@code null} a new {@code Dimension} 4290 * object is allocated. This version of {@code getSize} 4291 * is useful if the caller wants to avoid allocating a new 4292 * {@code Dimension} object on the heap. 4293 * 4294 * @param rv the return value, modified to the component's size 4295 * @return {@code rv} 4296 */ 4297 public Dimension getSize(Dimension rv) { 4298 if (rv == null) { 4299 return new Dimension(getWidth(), getHeight()); 4300 } 4301 else { 4302 rv.setSize(getWidth(), getHeight()); 4303 return rv; 4304 } 4305 } 4306 4307 4308 /** 4309 * Stores the x,y origin of this component into "return value" 4310 * {@code rv} and returns {@code rv}. 4311 * If {@code rv} is {@code null} a new {@code Point} 4312 * is allocated. This version of {@code getLocation} is useful 4313 * if the caller wants to avoid allocating a new {@code Point} 4314 * object on the heap. 4315 * 4316 * @param rv the return value, modified to the component's location 4317 * @return {@code rv} 4318 */ 4319 public Point getLocation(Point rv) { 4320 if (rv == null) { 4321 return new Point(getX(), getY()); 4322 } 4323 else { 4324 rv.setLocation(getX(), getY()); 4325 return rv; 4326 } 4327 } 4328 4329 4330 /** 4331 * Returns the current x coordinate of the component's origin. 4332 * This method is preferable to writing 4333 * {@code component.getBounds().x}, or 4334 * {@code component.getLocation().x} because it doesn't cause any 4335 * heap allocations. 4336 * 4337 * @return the current x coordinate of the component's origin 4338 */ 4339 public int getX() { return super.getX(); } 4340 4341 4342 /** 4343 * Returns the current y coordinate of the component's origin. 4344 * This method is preferable to writing 4345 * {@code component.getBounds().y}, or 4346 * {@code component.getLocation().y} because it doesn't cause any 4347 * heap allocations. 4348 * 4349 * @return the current y coordinate of the component's origin 4350 */ 4351 public int getY() { return super.getY(); } 4352 4353 4354 /** 4355 * Returns the current width of this component. 4356 * This method is preferable to writing 4357 * {@code component.getBounds().width}, or 4358 * {@code component.getSize().width} because it doesn't cause any 4359 * heap allocations. 4360 * 4361 * @return the current width of this component 4362 */ 4363 public int getWidth() { return super.getWidth(); } 4364 4365 4366 /** 4367 * Returns the current height of this component. 4368 * This method is preferable to writing 4369 * {@code component.getBounds().height}, or 4370 * {@code component.getSize().height} because it doesn't cause any 4371 * heap allocations. 4372 * 4373 * @return the current height of this component 4374 */ 4375 public int getHeight() { return super.getHeight(); } 4376 4377 /** 4378 * Returns true if this component is completely opaque. 4379 * <p> 4380 * An opaque component paints every pixel within its 4381 * rectangular bounds. A non-opaque component paints only a subset of 4382 * its pixels or none at all, allowing the pixels underneath it to 4383 * "show through". Therefore, a component that does not fully paint 4384 * its pixels provides a degree of transparency. 4385 * <p> 4386 * Subclasses that guarantee to always completely paint their contents 4387 * should override this method and return true. 4388 * 4389 * @return true if this component is completely opaque 4390 * @see #setOpaque 4391 */ 4392 public boolean isOpaque() { 4393 return getFlag(IS_OPAQUE); 4394 } 4395 4396 /** 4397 * If true the component paints every pixel within its bounds. 4398 * Otherwise, the component may not paint some or all of its 4399 * pixels, allowing the underlying pixels to show through. 4400 * <p> 4401 * The default value of this property is false for {@code JComponent}. 4402 * However, the default value for this property on most standard 4403 * {@code JComponent} subclasses (such as {@code JButton} and 4404 * {@code JTree}) is look-and-feel dependent. 4405 * 4406 * @param isOpaque true if this component should be opaque 4407 * @see #isOpaque 4408 * @beaninfo 4409 * bound: true 4410 * expert: true 4411 * description: The component's opacity 4412 */ 4413 public void setOpaque(boolean isOpaque) { 4414 boolean oldValue = getFlag(IS_OPAQUE); 4415 setFlag(IS_OPAQUE, isOpaque); 4416 setFlag(OPAQUE_SET, true); 4417 firePropertyChange("opaque", oldValue, isOpaque); 4418 } 4419 4420 4421 /** 4422 * If the specified rectangle is completely obscured by any of this 4423 * component's opaque children then returns true. Only direct children 4424 * are considered, more distant descendants are ignored. A 4425 * {@code JComponent} is opaque if 4426 * {@code JComponent.isOpaque()} returns true, other lightweight 4427 * components are always considered transparent, and heavyweight components 4428 * are always considered opaque. 4429 * 4430 * @param x x value of specified rectangle 4431 * @param y y value of specified rectangle 4432 * @param width width of specified rectangle 4433 * @param height height of specified rectangle 4434 * @return true if the specified rectangle is obscured by an opaque child 4435 */ 4436 boolean rectangleIsObscured(int x,int y,int width,int height) 4437 { 4438 int numChildren = getComponentCount(); 4439 4440 for(int i = 0; i < numChildren; i++) { 4441 Component child = getComponent(i); 4442 int cx, cy, cw, ch; 4443 4444 cx = child.getX(); 4445 cy = child.getY(); 4446 cw = child.getWidth(); 4451 4452 if(child instanceof JComponent) { 4453 // System.out.println("A) checking opaque: " + ((JComponent)child).isOpaque() + " " + child); 4454 // System.out.print("B) "); 4455 // Thread.dumpStack(); 4456 return child.isOpaque(); 4457 } else { 4458 /** Sometimes a heavy weight can have a bound larger than its peer size 4459 * so we should always draw under heavy weights 4460 */ 4461 return false; 4462 } 4463 } 4464 } 4465 4466 return false; 4467 } 4468 4469 4470 /** 4471 * Returns the {@code Component}'s "visible rect rectangle" - the 4472 * intersection of the visible rectangles for the component {@code c} 4473 * and all of its ancestors. The return value is stored in 4474 * {@code visibleRect}. 4475 * 4476 * @param c the component 4477 * @param visibleRect a {@code Rectangle} computed as the 4478 * intersection of all visible rectangles for the component 4479 * {@code c} and all of its ancestors -- this is the 4480 * return value for this method 4481 * @see #getVisibleRect 4482 */ 4483 static final void computeVisibleRect(Component c, Rectangle visibleRect) { 4484 Container p = c.getParent(); 4485 Rectangle bounds = c.getBounds(); 4486 4487 if (p == null || p instanceof Window || p instanceof Applet) { 4488 visibleRect.setBounds(0, 0, bounds.width, bounds.height); 4489 } else { 4490 computeVisibleRect(p, visibleRect); 4491 visibleRect.x -= bounds.x; 4492 visibleRect.y -= bounds.y; 4493 SwingUtilities.computeIntersection(0,0,bounds.width,bounds.height,visibleRect); 4494 } 4495 } 4496 4497 4498 /** 4499 * Returns the {@code Component}'s "visible rect rectangle" - the 4500 * intersection of the visible rectangles for this component 4501 * and all of its ancestors. The return value is stored in 4502 * {@code visibleRect}. 4503 * 4504 * @param visibleRect a {@code Rectangle} computed as the 4505 * intersection of all visible rectangles for this 4506 * component and all of its ancestors -- this is the return 4507 * value for this method 4508 * @see #getVisibleRect 4509 */ 4510 public void computeVisibleRect(Rectangle visibleRect) { 4511 computeVisibleRect(this, visibleRect); 4512 } 4513 4514 4515 /** 4516 * Returns the {@code Component}'s "visible rectangle" - the 4517 * intersection of this component's visible rectangle, 4518 * {@code new Rectangle(0, 0, getWidth(), getHeight())}, 4519 * and all of its ancestors' visible rectangles. 4520 * 4521 * @return the visible rectangle 4522 */ 4523 public Rectangle getVisibleRect() { 4524 Rectangle visibleRect = new Rectangle(); 4525 4526 computeVisibleRect(visibleRect); 4527 return visibleRect; 4528 } 4529 4530 /** 4531 * Support for reporting bound property changes for boolean properties. 4532 * This method can be called when a bound property has changed and it will 4533 * send the appropriate PropertyChangeEvent to any registered 4534 * PropertyChangeListeners. 4535 * 4536 * @param propertyName the property whose value has changed 4537 * @param oldValue the property's previous value 4538 * @param newValue the property's new value 4550 * PropertyChangeListeners. 4551 * 4552 * @param propertyName the property whose value has changed 4553 * @param oldValue the property's previous value 4554 * @param newValue the property's new value 4555 */ 4556 public void firePropertyChange(String propertyName, 4557 int oldValue, int newValue) { 4558 super.firePropertyChange(propertyName, oldValue, newValue); 4559 } 4560 4561 // XXX This method is implemented as a workaround to a JLS issue with ambiguous 4562 // methods. This should be removed once 4758654 is resolved. 4563 public void firePropertyChange(String propertyName, char oldValue, char newValue) { 4564 super.firePropertyChange(propertyName, oldValue, newValue); 4565 } 4566 4567 /** 4568 * Supports reporting constrained property changes. 4569 * This method can be called when a constrained property has changed 4570 * and it will send the appropriate {@code PropertyChangeEvent} 4571 * to any registered {@code VetoableChangeListeners}. 4572 * 4573 * @param propertyName the name of the property that was listened on 4574 * @param oldValue the old value of the property 4575 * @param newValue the new value of the property 4576 * @exception java.beans.PropertyVetoException when the attempt to set the 4577 * property is vetoed by the component 4578 */ 4579 protected void fireVetoableChange(String propertyName, Object oldValue, Object newValue) 4580 throws java.beans.PropertyVetoException 4581 { 4582 if (vetoableChangeSupport == null) { 4583 return; 4584 } 4585 vetoableChangeSupport.fireVetoableChange(propertyName, oldValue, newValue); 4586 } 4587 4588 4589 /** 4590 * Adds a {@code VetoableChangeListener} to the listener list. 4591 * The listener is registered for all properties. 4592 * 4593 * @param listener the {@code VetoableChangeListener} to be added 4594 */ 4595 public synchronized void addVetoableChangeListener(VetoableChangeListener listener) { 4596 if (vetoableChangeSupport == null) { 4597 vetoableChangeSupport = new java.beans.VetoableChangeSupport(this); 4598 } 4599 vetoableChangeSupport.addVetoableChangeListener(listener); 4600 } 4601 4602 4603 /** 4604 * Removes a {@code VetoableChangeListener} from the listener list. 4605 * This removes a {@code VetoableChangeListener} that was registered 4606 * for all properties. 4607 * 4608 * @param listener the {@code VetoableChangeListener} to be removed 4609 */ 4610 public synchronized void removeVetoableChangeListener(VetoableChangeListener listener) { 4611 if (vetoableChangeSupport == null) { 4612 return; 4613 } 4614 vetoableChangeSupport.removeVetoableChangeListener(listener); 4615 } 4616 4617 4618 /** 4619 * Returns an array of all the vetoable change listeners 4620 * registered on this component. 4621 * 4622 * @return all of the component's {@code VetoableChangeListener}s 4623 * or an empty 4624 * array if no vetoable change listeners are currently registered 4625 * 4626 * @see #addVetoableChangeListener 4627 * @see #removeVetoableChangeListener 4628 * 4629 * @since 1.4 4630 */ 4631 public synchronized VetoableChangeListener[] getVetoableChangeListeners() { 4632 if (vetoableChangeSupport == null) { 4633 return new VetoableChangeListener[0]; 4634 } 4635 return vetoableChangeSupport.getVetoableChangeListeners(); 4636 } 4637 4638 4639 /** 4640 * Returns the top-level ancestor of this component (either the 4641 * containing {@code Window} or {@code Applet}), 4642 * or {@code null} if this component has not 4643 * been added to any container. 4644 * 4645 * @return the top-level {@code Container} that this component is in, 4646 * or {@code null} if not in any container 4647 */ 4648 public Container getTopLevelAncestor() { 4649 for(Container p = this; p != null; p = p.getParent()) { 4650 if(p instanceof Window || p instanceof Applet) { 4651 return p; 4652 } 4653 } 4654 return null; 4655 } 4656 4657 private AncestorNotifier getAncestorNotifier() { 4658 return (AncestorNotifier) 4659 getClientProperty(JComponent_ANCESTOR_NOTIFIER); 4660 } 4661 4662 /** 4663 * Registers {@code listener} so that it will receive 4664 * {@code AncestorEvents} when it or any of its ancestors 4665 * move or are made visible or invisible. 4666 * Events are also sent when the component or its ancestors are added 4667 * or removed from the containment hierarchy. 4668 * 4669 * @param listener the {@code AncestorListener} to register 4670 * @see AncestorEvent 4671 */ 4672 public void addAncestorListener(AncestorListener listener) { 4673 AncestorNotifier ancestorNotifier = getAncestorNotifier(); 4674 if (ancestorNotifier == null) { 4675 ancestorNotifier = new AncestorNotifier(this); 4676 putClientProperty(JComponent_ANCESTOR_NOTIFIER, 4677 ancestorNotifier); 4678 } 4679 ancestorNotifier.addAncestorListener(listener); 4680 } 4681 4682 /** 4683 * Unregisters {@code listener} so that it will no longer receive 4684 * {@code AncestorEvents}. 4685 * 4686 * @param listener the {@code AncestorListener} to be removed 4687 * @see #addAncestorListener 4688 */ 4689 public void removeAncestorListener(AncestorListener listener) { 4690 AncestorNotifier ancestorNotifier = getAncestorNotifier(); 4691 if (ancestorNotifier == null) { 4692 return; 4693 } 4694 ancestorNotifier.removeAncestorListener(listener); 4695 if (ancestorNotifier.listenerList.getListenerList().length == 0) { 4696 ancestorNotifier.removeAllListeners(); 4697 putClientProperty(JComponent_ANCESTOR_NOTIFIER, null); 4698 } 4699 } 4700 4701 /** 4702 * Returns an array of all the ancestor listeners 4703 * registered on this component. 4704 * 4705 * @return all of the component's {@code AncestorListener}s 4706 * or an empty 4707 * array if no ancestor listeners are currently registered 4708 * 4709 * @see #addAncestorListener 4710 * @see #removeAncestorListener 4711 * 4712 * @since 1.4 4713 */ 4714 public AncestorListener[] getAncestorListeners() { 4715 AncestorNotifier ancestorNotifier = getAncestorNotifier(); 4716 if (ancestorNotifier == null) { 4717 return new AncestorListener[0]; 4718 } 4719 return ancestorNotifier.getAncestorListeners(); 4720 } 4721 4722 /** 4723 * Returns an array of all the objects currently registered 4724 * as <code><em>Foo</em>Listener</code>s 4725 * upon this {@code JComponent}. 4726 * <code><em>Foo</em>Listener</code>s are registered using the 4727 * <code>add<em>Foo</em>Listener</code> method. 4728 * 4729 * <p> 4730 * 4731 * You can specify the {@code listenerType} argument 4732 * with a class literal, 4733 * such as 4734 * <code><em>Foo</em>Listener.class</code>. 4735 * For example, you can query a 4736 * {@code JComponent c} 4737 * for its mouse listeners with the following code: 4738 * <pre>MouseListener[] mls = (MouseListener[])(c.getListeners(MouseListener.class));</pre> 4739 * If no such listeners exist, this method returns an empty array. 4740 * 4741 * @param listenerType the type of listeners requested; this parameter 4742 * should specify an interface that descends from 4743 * {@code java.util.EventListener} 4744 * @return an array of all objects registered as 4745 * <code><em>Foo</em>Listener</code>s on this component, 4746 * or an empty array if no such 4747 * listeners have been added 4748 * @exception ClassCastException if {@code listenerType} 4749 * doesn't specify a class or interface that implements 4750 * {@code java.util.EventListener} 4751 * 4752 * @since 1.3 4753 * 4754 * @see #getVetoableChangeListeners 4755 * @see #getAncestorListeners 4756 */ 4757 @SuppressWarnings("unchecked") // Casts to (T[]) 4758 public <T extends EventListener> T[] getListeners(Class<T> listenerType) { 4759 T[] result; 4760 if (listenerType == AncestorListener.class) { 4761 // AncestorListeners are handled by the AncestorNotifier 4762 result = (T[])getAncestorListeners(); 4763 } 4764 else if (listenerType == VetoableChangeListener.class) { 4765 // VetoableChangeListeners are handled by VetoableChangeSupport 4766 result = (T[])getVetoableChangeListeners(); 4767 } 4768 else if (listenerType == PropertyChangeListener.class) { 4769 // PropertyChangeListeners are handled by PropertyChangeSupport 4770 result = (T[])getPropertyChangeListeners(); 4771 } 4772 else { 4773 result = listenerList.getListeners(listenerType); 4774 } 4775 4776 if (result.length == 0) { 4777 return super.getListeners(listenerType); 4778 } 4779 return result; 4780 } 4781 4782 /** 4783 * Notifies this component that it now has a parent component. 4784 * When this method is invoked, the chain of parent components is 4785 * set up with {@code KeyboardAction} event listeners. 4786 * This method is called by the toolkit internally and should 4787 * not be called directly by programs. 4788 * 4789 * @see #registerKeyboardAction 4790 */ 4791 public void addNotify() { 4792 super.addNotify(); 4793 firePropertyChange("ancestor", null, getParent()); 4794 4795 registerWithKeyboardManager(false); 4796 registerNextFocusableComponent(); 4797 } 4798 4799 4800 /** 4801 * Notifies this component that it no longer has a parent component. 4802 * When this method is invoked, any {@code KeyboardAction}s 4803 * set up in the chain of parent components are removed. 4804 * This method is called by the toolkit internally and should 4805 * not be called directly by programs. 4806 * 4807 * @see #registerKeyboardAction 4808 */ 4809 public void removeNotify() { 4810 super.removeNotify(); 4811 // This isn't strictly correct. The event shouldn't be 4812 // fired until *after* the parent is set to null. But 4813 // we only get notified before that happens 4814 firePropertyChange("ancestor", getParent(), null); 4815 4816 unregisterWithKeyboardManager(); 4817 deregisterNextFocusableComponent(); 4818 4819 if (getCreatedDoubleBuffer()) { 4820 RepaintManager.currentManager(this).resetDoubleBuffer(); 4821 setCreatedDoubleBuffer(false); 4822 } 4834 * @param tm this parameter is not used 4835 * @param x the x value of the dirty region 4836 * @param y the y value of the dirty region 4837 * @param width the width of the dirty region 4838 * @param height the height of the dirty region 4839 * @see #isPaintingOrigin() 4840 * @see java.awt.Component#isShowing 4841 * @see RepaintManager#addDirtyRegion 4842 */ 4843 public void repaint(long tm, int x, int y, int width, int height) { 4844 RepaintManager.currentManager(SunToolkit.targetToAppContext(this)) 4845 .addDirtyRegion(this, x, y, width, height); 4846 } 4847 4848 4849 /** 4850 * Adds the specified region to the dirty region list if the component 4851 * is showing. The component will be repainted after all of the 4852 * currently pending events have been dispatched. 4853 * 4854 * @param r a {@code Rectangle} containing the dirty region 4855 * @see #isPaintingOrigin() 4856 * @see java.awt.Component#isShowing 4857 * @see RepaintManager#addDirtyRegion 4858 */ 4859 public void repaint(Rectangle r) { 4860 repaint(0,r.x,r.y,r.width,r.height); 4861 } 4862 4863 4864 /** 4865 * Supports deferred automatic layout. 4866 * <p> 4867 * Calls {@code invalidate} and then adds this component's 4868 * {@code validateRoot} to a list of components that need to be 4869 * validated. Validation will occur after all currently pending 4870 * events have been dispatched. In other words after this method 4871 * is called, the first validateRoot (if any) found when walking 4872 * up the containment hierarchy of this component will be validated. 4873 * By default, {@code JRootPane}, {@code JScrollPane}, 4874 * and {@code JTextField} return true 4875 * from {@code isValidateRoot}. 4876 * <p> 4877 * This method will automatically be called on this component 4878 * when a property value changes such that size, location, or 4879 * internal layout of this component has been affected. This automatic 4880 * updating differs from the AWT because programs generally no 4881 * longer need to invoke {@code validate} to get the contents of the 4882 * GUI to update. 4883 * 4884 * @see java.awt.Component#invalidate 4885 * @see java.awt.Container#validate 4886 * @see #isValidateRoot 4887 * @see RepaintManager#addInvalidComponent 4888 */ 4889 public void revalidate() { 4890 if (getParent() == null) { 4891 // Note: We don't bother invalidating here as once added 4892 // to a valid parent invalidate will be invoked (addImpl 4893 // invokes addNotify which will invoke invalidate on the 4894 // new Component). Also, if we do add a check to isValid 4895 // here it can potentially be called before the constructor 4896 // which was causing some people grief. 4897 return; 4898 } 4899 if (SunToolkit.isDispatchThreadForAppContext(this)) { 4900 invalidate(); 4901 RepaintManager.currentManager(this).addInvalidComponent(this); 4902 } 4903 else { 4904 // To avoid a flood of Runnables when constructing GUIs off 4905 // the EDT, a flag is maintained as to whether or not 4906 // a Runnable has been scheduled. 4907 if (revalidateRunnableScheduled.getAndSet(true)) { 4908 return; 4909 } 4910 SunToolkit.executeOnEventHandlerThread(this, () -> { 4911 revalidateRunnableScheduled.set(false); 4912 revalidate(); 4913 }); 4914 } 4915 } 4916 4917 /** 4918 * If this method returns true, {@code revalidate} calls by 4919 * descendants of this component will cause the entire tree 4920 * beginning with this root to be validated. 4921 * Returns false by default. {@code JScrollPane} overrides 4922 * this method and returns true. 4923 * 4924 * @return always returns false 4925 * @see #revalidate 4926 * @see java.awt.Component#invalidate 4927 * @see java.awt.Container#validate 4928 * @see java.awt.Container#isValidateRoot 4929 */ 4930 @Override 4931 public boolean isValidateRoot() { 4932 return false; 4933 } 4934 4935 4936 /** 4937 * Returns true if this component tiles its children -- that is, if 4938 * it can guarantee that the children will not overlap. The 4939 * repainting system is substantially more efficient in this 4940 * common case. {@code JComponent} subclasses that can't make this 4941 * guarantee, such as {@code JLayeredPane}, 4942 * should override this method to return false. 4943 * 4944 * @return always returns true 4945 */ 4946 public boolean isOptimizedDrawingEnabled() { 4947 return true; 4948 } 4949 4950 /** 4951 * Returns {@code true} if a paint triggered on a child component should cause 4952 * painting to originate from this Component, or one of its ancestors. 4953 * <p> 4954 * Calling {@link #repaint} or {@link #paintImmediately(int, int, int, int)} 4955 * on a Swing component will result in calling 4956 * the {@link JComponent#paintImmediately(int, int, int, int)} method of 4957 * the first ancestor which {@code isPaintingOrigin()} returns {@code true}, if there are any. 4958 * <p> 4959 * {@code JComponent} subclasses that need to be painted when any of their 4960 * children are repainted should override this method to return {@code true}. 4961 * 5010 y += c.getY(); 5011 c = parent; 5012 } else { 5013 break; 5014 } 5015 5016 if(!(c instanceof JComponent)) { 5017 break; 5018 } 5019 } 5020 if(c instanceof JComponent) { 5021 ((JComponent)c)._paintImmediately(x,y,w,h); 5022 } else { 5023 c.repaint(x,y,w,h); 5024 } 5025 } 5026 5027 /** 5028 * Paints the specified region now. 5029 * 5030 * @param r a {@code Rectangle} containing the region to be painted 5031 */ 5032 public void paintImmediately(Rectangle r) { 5033 paintImmediately(r.x,r.y,r.width,r.height); 5034 } 5035 5036 /** 5037 * Returns whether this component should be guaranteed to be on top. 5038 * For example, it would make no sense for {@code Menu}s to pop up 5039 * under another component, so they would always return true. 5040 * Most components will want to return false, hence that is the default. 5041 * 5042 * @return always returns false 5043 */ 5044 // package private 5045 boolean alwaysOnTop() { 5046 return false; 5047 } 5048 5049 void setPaintingChild(Component paintingChild) { 5050 this.paintingChild = paintingChild; 5051 } 5052 5053 void _paintImmediately(int x, int y, int w, int h) { 5054 Graphics g; 5055 Container c; 5056 Rectangle b; 5057 5058 int tmpX, tmpY, tmpWidth, tmpHeight; 5312 y >= siblingRect.y && (y + height) <= 5313 (siblingRect.y + siblingRect.height)) { 5314 recycleRectangle(tmpRect); 5315 return COMPLETELY_OBSCURED; 5316 } 5317 else if (retValue == NOT_OBSCURED && 5318 !((x + width <= siblingRect.x) || 5319 (y + height <= siblingRect.y) || 5320 (x >= siblingRect.x + siblingRect.width) || 5321 (y >= siblingRect.y + siblingRect.height))) { 5322 retValue = PARTIALLY_OBSCURED; 5323 } 5324 } 5325 recycleRectangle(tmpRect); 5326 return retValue; 5327 } 5328 5329 /** 5330 * Returns true, which implies that before checking if a child should 5331 * be painted it is first check that the child is not obscured by another 5332 * sibling. This is only checked if {@code isOptimizedDrawingEnabled} 5333 * returns false. 5334 * 5335 * @return always returns true 5336 */ 5337 boolean checkIfChildObscuredBySibling() { 5338 return true; 5339 } 5340 5341 5342 private void setFlag(int aFlag, boolean aValue) { 5343 if(aValue) { 5344 flags |= (1 << aFlag); 5345 } else { 5346 flags &= ~(1 << aFlag); 5347 } 5348 } 5349 private boolean getFlag(int aFlag) { 5350 int mask = (1 << aFlag); 5351 return ((flags & mask) == mask); 5352 } 5353 // These functions must be static so that they can be called from 5354 // subclasses inside the package, but whose inheritance hierarhcy includes 5355 // classes outside of the package below JComponent (e.g., JTextArea). 5356 static void setWriteObjCounter(JComponent comp, byte count) { 5357 comp.flags = (comp.flags & ~(0xFF << WRITE_OBJ_COUNTER_FIRST)) | 5358 (count << WRITE_OBJ_COUNTER_FIRST); 5359 } 5360 static byte getWriteObjCounter(JComponent comp) { 5361 return (byte)((comp.flags >> WRITE_OBJ_COUNTER_FIRST) & 0xFF); 5362 } 5363 5364 /** Buffering **/ 5365 5366 /** 5367 * Sets whether this component should use a buffer to paint. 5368 * If set to true, all the drawing from this component will be done 5369 * in an offscreen painting buffer. The offscreen painting buffer will 5370 * the be copied onto the screen. 5371 * If a {@code Component} is buffered and one of its ancestor 5372 * is also buffered, the ancestor buffer will be used. 5373 * 5374 * @param aFlag if true, set this component to be double buffered 5375 */ 5376 public void setDoubleBuffered(boolean aFlag) { 5377 setFlag(IS_DOUBLE_BUFFERED,aFlag); 5378 } 5379 5380 /** 5381 * Returns whether this component should use a buffer to paint. 5382 * 5383 * @return true if this component is double buffered, otherwise false 5384 */ 5385 public boolean isDoubleBuffered() { 5386 return getFlag(IS_DOUBLE_BUFFERED); 5387 } 5388 5389 /** 5390 * Returns the {@code JRootPane} ancestor for this component. 5391 * 5392 * @return the {@code JRootPane} that contains this component, 5393 * or {@code null} if no {@code JRootPane} is found 5394 */ 5395 public JRootPane getRootPane() { 5396 return SwingUtilities.getRootPane(this); 5397 } 5398 5399 5400 /** Serialization **/ 5401 5402 /** 5403 * This is called from Component by way of reflection. Do NOT change 5404 * the name unless you change the code in Component as well. 5405 */ 5406 void compWriteObjectNotify() { 5407 byte count = JComponent.getWriteObjCounter(this); 5408 JComponent.setWriteObjCounter(this, (byte)(count + 1)); 5409 if (count != 0) { 5410 return; 5411 } 5412 5413 uninstallUIAndProperties(); 5414 5415 /* JTableHeader is in a separate package, which prevents it from 5416 * being able to override this package-private method the way the 5417 * other components can. We don't want to make this method protected 5418 * because it would introduce public-api for a less-than-desirable 5419 * serialization scheme, so we compromise with this 'instanceof' hack 5420 * for now. 5421 */ 5422 if (getToolTipText() != null || 5423 this instanceof javax.swing.table.JTableHeader) { 5424 ToolTipManager.sharedInstance().unregisterComponent(JComponent.this); 5425 } 5426 } 5427 5428 /** 5429 * This object is the {@code ObjectInputStream} callback 5430 * that's called after a complete graph of objects (including at least 5431 * one {@code JComponent}) has been read. 5432 * It sets the UI property of each Swing component 5433 * that was read to the current default with {@code updateUI}. 5434 * <p> 5435 * As each component is read in we keep track of the current set of 5436 * root components here, in the roots vector. Note that there's only one 5437 * {@code ReadObjectCallback} per {@code ObjectInputStream}, 5438 * they're stored in the static {@code readObjectCallbacks} 5439 * hashtable. 5440 * 5441 * @see java.io.ObjectInputStream#registerValidation 5442 * @see SwingUtilities#updateComponentTreeUI 5443 */ 5444 private class ReadObjectCallback implements ObjectInputValidation 5445 { 5446 private final Vector<JComponent> roots = new Vector<JComponent>(1); 5447 private final ObjectInputStream inputStream; 5448 5449 ReadObjectCallback(ObjectInputStream s) throws Exception { 5450 inputStream = s; 5451 s.registerValidation(this, 0); 5452 } 5453 5454 /** 5455 * This is the method that's called after the entire graph 5456 * of objects has been read in. It initializes 5457 * the UI property of all of the copmonents with 5458 * {@code SwingUtilities.updateComponentTreeUI}. 5459 */ 5460 public void validateObject() throws InvalidObjectException { 5461 try { 5462 for (JComponent root : roots) { 5463 SwingUtilities.updateComponentTreeUI(root); 5464 } 5465 } 5466 finally { 5467 readObjectCallbacks.remove(inputStream); 5468 } 5469 } 5470 5471 /** 5472 * If {@code c} isn't a descendant of a component we've already 5473 * seen, then add it to the roots {@code Vector}. 5474 * 5475 * @param c the {@code JComponent} to add 5476 */ 5477 private void registerComponent(JComponent c) 5478 { 5479 /* If the Component c is a descendant of one of the 5480 * existing roots (or it IS an existing root), we're done. 5481 */ 5482 for (JComponent root : roots) { 5483 for(Component p = c; p != null; p = p.getParent()) { 5484 if (p == root) { 5485 return; 5486 } 5487 } 5488 } 5489 5490 /* Otherwise: if Component c is an ancestor of any of the 5491 * existing roots then remove them and add c (the "new root") 5492 * to the roots vector. 5493 */ 5494 for(int i = 0; i < roots.size(); i++) { 5495 JComponent root = roots.elementAt(i); 5496 for(Component p = root.getParent(); p != null; p = p.getParent()) { 5497 if (p == c) { 5498 roots.removeElementAt(i--); // !! 5499 break; 5500 } 5501 } 5502 } 5503 5504 roots.addElement(c); 5505 } 5506 } 5507 5508 5509 /** 5510 * We use the {@code ObjectInputStream} "registerValidation" 5511 * callback to update the UI for the entire tree of components 5512 * after they've all been read in. 5513 * 5514 * @param s the {@code ObjectInputStream} from which to read 5515 */ 5516 private void readObject(ObjectInputStream s) 5517 throws IOException, ClassNotFoundException 5518 { 5519 ObjectInputStream.GetField f = s.readFields(); 5520 5521 isAlignmentXSet = f.get("isAlignmentXSet", false); 5522 alignmentX = validateAlignment(f.get("alignmentX", 0f)); 5523 isAlignmentYSet = f.get("isAlignmentYSet", false); 5524 alignmentY = validateAlignment(f.get("alignmentY", 0f)); 5525 listenerList = (EventListenerList) f.get("listenerList", null); 5526 vetoableChangeSupport = (VetoableChangeSupport) f.get("vetoableChangeSupport", null); 5527 autoscrolls = f.get("autoscrolls", false); 5528 border = (Border) f.get("border", null); 5529 flags = f.get("flags", 0); 5530 inputVerifier = (InputVerifier) f.get("inputVerifier", null); 5531 verifyInputWhenFocusTarget = f.get("verifyInputWhenFocusTarget", false); 5532 popupMenu = (JPopupMenu) f.get("popupMenu", null); 5533 focusInputMap = (InputMap) f.get("focusInputMap", null); 5534 ancestorInputMap = (InputMap) f.get("ancestorInputMap", null); 5553 cb.registerComponent(this); 5554 5555 // Read back the client properties. 5556 int cpCount = s.readInt(); 5557 if (cpCount > 0) { 5558 clientProperties = new ArrayTable(); 5559 for (int counter = 0; counter < cpCount; counter++) { 5560 clientProperties.put(s.readObject(), 5561 s.readObject()); 5562 } 5563 } 5564 if (getToolTipText() != null) { 5565 ToolTipManager.sharedInstance().registerComponent(this); 5566 } 5567 setWriteObjCounter(this, (byte)0); 5568 revalidateRunnableScheduled = new AtomicBoolean(false); 5569 } 5570 5571 5572 /** 5573 * Before writing a {@code JComponent} to an 5574 * {@code ObjectOutputStream} we temporarily uninstall its UI. 5575 * This is tricky to do because we want to uninstall 5576 * the UI before any of the {@code JComponent}'s children 5577 * (or its {@code LayoutManager} etc.) are written, 5578 * and we don't want to restore the UI until the most derived 5579 * {@code JComponent} subclass has been stored. 5580 * 5581 * @param s the {@code ObjectOutputStream} in which to write 5582 */ 5583 private void writeObject(ObjectOutputStream s) throws IOException { 5584 s.defaultWriteObject(); 5585 if (getUIClassID().equals(uiClassID)) { 5586 byte count = JComponent.getWriteObjCounter(this); 5587 JComponent.setWriteObjCounter(this, --count); 5588 if (count == 0 && ui != null) { 5589 ui.installUI(this); 5590 } 5591 } 5592 ArrayTable.writeArrayTable(s, clientProperties); 5593 } 5594 5595 5596 /** 5597 * Returns a string representation of this {@code JComponent}. 5598 * This method 5599 * is intended to be used only for debugging purposes, and the 5600 * content and format of the returned string may vary between 5601 * implementations. The returned string may be empty but may not 5602 * be {@code null}. 5603 * 5604 * @return a string representation of this {@code JComponent} 5605 */ 5606 protected String paramString() { 5607 String preferredSizeString = (isPreferredSizeSet() ? 5608 getPreferredSize().toString() : ""); 5609 String minimumSizeString = (isMinimumSizeSet() ? 5610 getMinimumSize().toString() : ""); 5611 String maximumSizeString = (isMaximumSizeSet() ? 5612 getMaximumSize().toString() : ""); 5613 String borderString = (border == null ? "" 5614 : (border == this ? "this" : border.toString())); 5615 5616 return super.paramString() + 5617 ",alignmentX=" + alignmentX + 5618 ",alignmentY=" + alignmentY + 5619 ",border=" + borderString + 5620 ",flags=" + flags + // should beef this up a bit 5621 ",maximumSize=" + maximumSizeString + 5622 ",minimumSize=" + minimumSizeString + 5623 ",preferredSize=" + preferredSizeString; 5624 } |