1 /* 2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.swing; 27 28 import java.awt.Component; 29 import java.awt.Font; 30 import java.awt.Image; 31 import java.awt.*; 32 import java.text.*; 33 import java.awt.geom.*; 34 import java.beans.Transient; 35 36 import java.io.ObjectOutputStream; 37 import java.io.ObjectInputStream; 38 import java.io.IOException; 39 40 import javax.swing.plaf.LabelUI; 41 import javax.accessibility.*; 42 import javax.swing.text.*; 43 import javax.swing.text.html.*; 44 import javax.swing.plaf.basic.*; 45 import java.util.*; 46 47 48 /** 49 * A display area for a short text string or an image, 50 * or both. 51 * A label does not react to input events. 52 * As a result, it cannot get the keyboard focus. 53 * A label can, however, display a keyboard alternative 54 * as a convenience for a nearby component 55 * that has a keyboard alternative but can't display it. 56 * <p> 57 * A <code>JLabel</code> object can display 58 * either text, an image, or both. 59 * You can specify where in the label's display area 60 * the label's contents are aligned 61 * by setting the vertical and horizontal alignment. 62 * By default, labels are vertically centered 63 * in their display area. 64 * Text-only labels are leading edge aligned, by default; 65 * image-only labels are horizontally centered, by default. 66 * <p> 67 * You can also specify the position of the text 68 * relative to the image. 69 * By default, text is on the trailing edge of the image, 70 * with the text and image vertically aligned. 71 * <p> 72 * A label's leading and trailing edge are determined from the value of its 73 * {@link java.awt.ComponentOrientation} property. At present, the default 74 * ComponentOrientation setting maps the leading edge to left and the trailing 75 * edge to right. 76 * 77 * <p> 78 * Finally, you can use the <code>setIconTextGap</code> method 79 * to specify how many pixels 80 * should appear between the text and the image. 81 * The default is 4 pixels. 82 * <p> 83 * See <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/label.html">How to Use Labels</a> 84 * in <em>The Java Tutorial</em> 85 * for further documentation. 86 * <p> 87 * <strong>Warning:</strong> Swing is not thread safe. For more 88 * information see <a 89 * href="package-summary.html#threading">Swing's Threading 90 * Policy</a>. 91 * <p> 92 * <strong>Warning:</strong> 93 * Serialized objects of this class will not be compatible with 94 * future Swing releases. The current serialization support is 95 * appropriate for short term storage or RMI between applications running 96 * the same version of Swing. As of 1.4, support for long term storage 97 * of all JavaBeans™ 98 * has been added to the <code>java.beans</code> package. 99 * Please see {@link java.beans.XMLEncoder}. 100 * 101 * @beaninfo 102 * attribute: isContainer false 103 * description: A component that displays a short string and an icon. 104 * 105 * @author Hans Muller 106 */ 107 @SuppressWarnings("serial") 108 public class JLabel extends JComponent implements SwingConstants, Accessible 109 { 110 /** 111 * @see #getUIClassID 112 * @see #readObject 113 */ 114 private static final String uiClassID = "LabelUI"; 115 116 private int mnemonic = '\0'; 117 private int mnemonicIndex = -1; 118 119 private String text = ""; // "" rather than null, for BeanBox 120 private Icon defaultIcon = null; 121 private Icon disabledIcon = null; 122 private boolean disabledIconSet = false; 123 124 private int verticalAlignment = CENTER; 125 private int horizontalAlignment = LEADING; 126 private int verticalTextPosition = CENTER; 127 private int horizontalTextPosition = TRAILING; 128 private int iconTextGap = 4; 129 130 protected Component labelFor = null; 131 132 /** 133 * Client property key used to determine what label is labeling the 134 * component. This is generally not used by labels, but is instead 135 * used by components such as text areas that are being labeled by 136 * labels. When the labelFor property of a label is set, it will 137 * automatically set the LABELED_BY_PROPERTY of the component being 138 * labelled. 139 * 140 * @see #setLabelFor 141 */ 142 static final String LABELED_BY_PROPERTY = "labeledBy"; 143 144 /** 145 * Creates a <code>JLabel</code> instance with the specified 146 * text, image, and horizontal alignment. 147 * The label is centered vertically in its display area. 148 * The text is on the trailing edge of the image. 149 * 150 * @param text The text to be displayed by the label. 151 * @param icon The image to be displayed by the label. 152 * @param horizontalAlignment One of the following constants 153 * defined in <code>SwingConstants</code>: 154 * <code>LEFT</code>, 155 * <code>CENTER</code>, 156 * <code>RIGHT</code>, 157 * <code>LEADING</code> or 158 * <code>TRAILING</code>. 159 */ 160 public JLabel(String text, Icon icon, int horizontalAlignment) { 161 setText(text); 162 setIcon(icon); 163 setHorizontalAlignment(horizontalAlignment); 164 updateUI(); 165 setAlignmentX(LEFT_ALIGNMENT); 166 } 167 168 /** 169 * Creates a <code>JLabel</code> instance with the specified 170 * text and horizontal alignment. 171 * The label is centered vertically in its display area. 172 * 173 * @param text The text to be displayed by the label. 174 * @param horizontalAlignment One of the following constants 175 * defined in <code>SwingConstants</code>: 176 * <code>LEFT</code>, 177 * <code>CENTER</code>, 178 * <code>RIGHT</code>, 179 * <code>LEADING</code> or 180 * <code>TRAILING</code>. 181 */ 182 public JLabel(String text, int horizontalAlignment) { 183 this(text, null, horizontalAlignment); 184 } 185 186 /** 187 * Creates a <code>JLabel</code> instance with the specified text. 188 * The label is aligned against the leading edge of its display area, 189 * and centered vertically. 190 * 191 * @param text The text to be displayed by the label. 192 */ 193 public JLabel(String text) { 194 this(text, null, LEADING); 195 } 196 197 /** 198 * Creates a <code>JLabel</code> instance with the specified 199 * image and horizontal alignment. 200 * The label is centered vertically in its display area. 201 * 202 * @param image The image to be displayed by the label. 203 * @param horizontalAlignment One of the following constants 204 * defined in <code>SwingConstants</code>: 205 * <code>LEFT</code>, 206 * <code>CENTER</code>, 207 * <code>RIGHT</code>, 208 * <code>LEADING</code> or 209 * <code>TRAILING</code>. 210 */ 211 public JLabel(Icon image, int horizontalAlignment) { 212 this(null, image, horizontalAlignment); 213 } 214 215 /** 216 * Creates a <code>JLabel</code> instance with the specified image. 217 * The label is centered vertically and horizontally 218 * in its display area. 219 * 220 * @param image The image to be displayed by the label. 221 */ 222 public JLabel(Icon image) { 223 this(null, image, CENTER); 224 } 225 226 /** 227 * Creates a <code>JLabel</code> instance with 228 * no image and with an empty string for the title. 229 * The label is centered vertically 230 * in its display area. 231 * The label's contents, once set, will be displayed on the leading edge 232 * of the label's display area. 233 */ 234 public JLabel() { 235 this("", null, LEADING); 236 } 237 238 239 /** 240 * Returns the L&F object that renders this component. 241 * 242 * @return LabelUI object 243 */ 244 public LabelUI getUI() { 245 return (LabelUI)ui; 246 } 247 248 249 /** 250 * Sets the L&F object that renders this component. 251 * 252 * @param ui the LabelUI L&F object 253 * @see UIDefaults#getUI 254 * @beaninfo 255 * bound: true 256 * hidden: true 257 * attribute: visualUpdate true 258 * description: The UI object that implements the Component's LookAndFeel. 259 */ 260 public void setUI(LabelUI ui) { 261 super.setUI(ui); 262 // disabled icon is generated by LF so it should be unset here 263 if (!disabledIconSet && disabledIcon != null) { 264 setDisabledIcon(null); 265 } 266 } 267 268 269 /** 270 * Resets the UI property to a value from the current look and feel. 271 * 272 * @see JComponent#updateUI 273 */ 274 public void updateUI() { 275 setUI((LabelUI)UIManager.getUI(this)); 276 } 277 278 279 /** 280 * Returns a string that specifies the name of the l&f class 281 * that renders this component. 282 * 283 * @return String "LabelUI" 284 * 285 * @see JComponent#getUIClassID 286 * @see UIDefaults#getUI 287 */ 288 public String getUIClassID() { 289 return uiClassID; 290 } 291 292 293 /** 294 * Returns the text string that the label displays. 295 * 296 * @return a String 297 * @see #setText 298 */ 299 public String getText() { 300 return text; 301 } 302 303 304 /** 305 * Defines the single line of text this component will display. If 306 * the value of text is null or empty string, nothing is displayed. 307 * <p> 308 * The default value of this property is null. 309 * <p> 310 * This is a JavaBeans bound property. 311 * 312 * @see #setVerticalTextPosition 313 * @see #setHorizontalTextPosition 314 * @see #setIcon 315 * @beaninfo 316 * preferred: true 317 * bound: true 318 * attribute: visualUpdate true 319 * description: Defines the single line of text this component will display. 320 */ 321 public void setText(String text) { 322 323 String oldAccessibleName = null; 324 if (accessibleContext != null) { 325 oldAccessibleName = accessibleContext.getAccessibleName(); 326 } 327 328 String oldValue = this.text; 329 this.text = text; 330 firePropertyChange("text", oldValue, text); 331 332 setDisplayedMnemonicIndex( 333 SwingUtilities.findDisplayedMnemonicIndex( 334 text, getDisplayedMnemonic())); 335 336 if ((accessibleContext != null) 337 && (accessibleContext.getAccessibleName() != oldAccessibleName)) { 338 accessibleContext.firePropertyChange( 339 AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY, 340 oldAccessibleName, 341 accessibleContext.getAccessibleName()); 342 } 343 if (text == null || oldValue == null || !text.equals(oldValue)) { 344 revalidate(); 345 repaint(); 346 } 347 } 348 349 350 /** 351 * Returns the graphic image (glyph, icon) that the label displays. 352 * 353 * @return an Icon 354 * @see #setIcon 355 */ 356 public Icon getIcon() { 357 return defaultIcon; 358 } 359 360 /** 361 * Defines the icon this component will display. If 362 * the value of icon is null, nothing is displayed. 363 * <p> 364 * The default value of this property is null. 365 * <p> 366 * This is a JavaBeans bound property. 367 * 368 * @see #setVerticalTextPosition 369 * @see #setHorizontalTextPosition 370 * @see #getIcon 371 * @beaninfo 372 * preferred: true 373 * bound: true 374 * attribute: visualUpdate true 375 * description: The icon this component will display. 376 */ 377 public void setIcon(Icon icon) { 378 Icon oldValue = defaultIcon; 379 defaultIcon = icon; 380 381 /* If the default icon has really changed and we had 382 * generated the disabled icon for this component 383 * (in other words, setDisabledIcon() was never called), then 384 * clear the disabledIcon field. 385 */ 386 if ((defaultIcon != oldValue) && !disabledIconSet) { 387 disabledIcon = null; 388 } 389 390 firePropertyChange("icon", oldValue, defaultIcon); 391 392 if ((accessibleContext != null) && (oldValue != defaultIcon)) { 393 accessibleContext.firePropertyChange( 394 AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY, 395 oldValue, defaultIcon); 396 } 397 398 /* If the default icon has changed and the new one is 399 * a different size, then revalidate. Repaint if the 400 * default icon has changed. 401 */ 402 if (defaultIcon != oldValue) { 403 if ((defaultIcon == null) || 404 (oldValue == null) || 405 (defaultIcon.getIconWidth() != oldValue.getIconWidth()) || 406 (defaultIcon.getIconHeight() != oldValue.getIconHeight())) { 407 revalidate(); 408 } 409 repaint(); 410 } 411 } 412 413 414 /** 415 * Returns the icon used by the label when it's disabled. 416 * If no disabled icon has been set this will forward the call to 417 * the look and feel to construct an appropriate disabled Icon. 418 * <p> 419 * Some look and feels might not render the disabled Icon, in which 420 * case they will ignore this. 421 * 422 * @return the <code>disabledIcon</code> property 423 * @see #setDisabledIcon 424 * @see javax.swing.LookAndFeel#getDisabledIcon 425 * @see ImageIcon 426 */ 427 @Transient 428 public Icon getDisabledIcon() { 429 if (!disabledIconSet && disabledIcon == null && defaultIcon != null) { 430 disabledIcon = UIManager.getLookAndFeel().getDisabledIcon(this, defaultIcon); 431 if (disabledIcon != null) { 432 firePropertyChange("disabledIcon", null, disabledIcon); 433 } 434 } 435 return disabledIcon; 436 } 437 438 439 /** 440 * Set the icon to be displayed if this JLabel is "disabled" 441 * (JLabel.setEnabled(false)). 442 * <p> 443 * The default value of this property is null. 444 * 445 * @param disabledIcon the Icon to display when the component is disabled 446 * @see #getDisabledIcon 447 * @see #setEnabled 448 * @beaninfo 449 * bound: true 450 * attribute: visualUpdate true 451 * description: The icon to display if the label is disabled. 452 */ 453 public void setDisabledIcon(Icon disabledIcon) { 454 Icon oldValue = this.disabledIcon; 455 this.disabledIcon = disabledIcon; 456 disabledIconSet = (disabledIcon != null); 457 firePropertyChange("disabledIcon", oldValue, disabledIcon); 458 if (disabledIcon != oldValue) { 459 if (disabledIcon == null || oldValue == null || 460 disabledIcon.getIconWidth() != oldValue.getIconWidth() || 461 disabledIcon.getIconHeight() != oldValue.getIconHeight()) { 462 revalidate(); 463 } 464 if (!isEnabled()) { 465 repaint(); 466 } 467 } 468 } 469 470 471 /** 472 * Specify a keycode that indicates a mnemonic key. 473 * This property is used when the label is part of a larger component. 474 * If the labelFor property of the label is not null, the label will 475 * call the requestFocus method of the component specified by the 476 * labelFor property when the mnemonic is activated. 477 * 478 * @see #getLabelFor 479 * @see #setLabelFor 480 * @beaninfo 481 * bound: true 482 * attribute: visualUpdate true 483 * description: The mnemonic keycode. 484 */ 485 public void setDisplayedMnemonic(int key) { 486 int oldKey = mnemonic; 487 mnemonic = key; 488 firePropertyChange("displayedMnemonic", oldKey, mnemonic); 489 490 setDisplayedMnemonicIndex( 491 SwingUtilities.findDisplayedMnemonicIndex(getText(), mnemonic)); 492 493 if (key != oldKey) { 494 revalidate(); 495 repaint(); 496 } 497 } 498 499 500 /** 501 * Specifies the displayedMnemonic as a char value. 502 * 503 * @param aChar a char specifying the mnemonic to display 504 * @see #setDisplayedMnemonic(int) 505 */ 506 public void setDisplayedMnemonic(char aChar) { 507 int vk = java.awt.event.KeyEvent.getExtendedKeyCodeForChar(aChar); 508 if (vk != java.awt.event.KeyEvent.VK_UNDEFINED) { 509 setDisplayedMnemonic(vk); 510 } 511 } 512 513 514 /** 515 * Return the keycode that indicates a mnemonic key. 516 * This property is used when the label is part of a larger component. 517 * If the labelFor property of the label is not null, the label will 518 * call the requestFocus method of the component specified by the 519 * labelFor property when the mnemonic is activated. 520 * 521 * @return int value for the mnemonic key 522 * 523 * @see #getLabelFor 524 * @see #setLabelFor 525 */ 526 public int getDisplayedMnemonic() { 527 return mnemonic; 528 } 529 530 /** 531 * Provides a hint to the look and feel as to which character in the 532 * text should be decorated to represent the mnemonic. Not all look and 533 * feels may support this. A value of -1 indicates either there is no 534 * mnemonic, the mnemonic character is not contained in the string, or 535 * the developer does not wish the mnemonic to be displayed. 536 * <p> 537 * The value of this is updated as the properties relating to the 538 * mnemonic change (such as the mnemonic itself, the text...). 539 * You should only ever have to call this if 540 * you do not wish the default character to be underlined. For example, if 541 * the text was 'Save As', with a mnemonic of 'a', and you wanted the 'A' 542 * to be decorated, as 'Save <u>A</u>s', you would have to invoke 543 * <code>setDisplayedMnemonicIndex(5)</code> after invoking 544 * <code>setDisplayedMnemonic(KeyEvent.VK_A)</code>. 545 * 546 * @since 1.4 547 * @param index Index into the String to underline 548 * @exception IllegalArgumentException will be thrown if <code>index</code> 549 * is >= length of the text, or < -1 550 * 551 * @beaninfo 552 * bound: true 553 * attribute: visualUpdate true 554 * description: the index into the String to draw the keyboard character 555 * mnemonic at 556 */ 557 public void setDisplayedMnemonicIndex(int index) 558 throws IllegalArgumentException { 559 int oldValue = mnemonicIndex; 560 if (index == -1) { 561 mnemonicIndex = -1; 562 } else { 563 String text = getText(); 564 int textLength = (text == null) ? 0 : text.length(); 565 if (index < -1 || index >= textLength) { // index out of range 566 throw new IllegalArgumentException("index == " + index); 567 } 568 } 569 mnemonicIndex = index; 570 firePropertyChange("displayedMnemonicIndex", oldValue, index); 571 if (index != oldValue) { 572 revalidate(); 573 repaint(); 574 } 575 } 576 577 /** 578 * Returns the character, as an index, that the look and feel should 579 * provide decoration for as representing the mnemonic character. 580 * 581 * @since 1.4 582 * @return index representing mnemonic character 583 * @see #setDisplayedMnemonicIndex 584 */ 585 public int getDisplayedMnemonicIndex() { 586 return mnemonicIndex; 587 } 588 589 /** 590 * Verify that key is a legal value for the horizontalAlignment properties. 591 * 592 * @param key the property value to check 593 * @param message the IllegalArgumentException detail message 594 * @exception IllegalArgumentException if key isn't LEFT, CENTER, RIGHT, 595 * LEADING or TRAILING. 596 * @see #setHorizontalTextPosition 597 * @see #setHorizontalAlignment 598 */ 599 protected int checkHorizontalKey(int key, String message) { 600 if ((key == LEFT) || 601 (key == CENTER) || 602 (key == RIGHT) || 603 (key == LEADING) || 604 (key == TRAILING)) { 605 return key; 606 } 607 else { 608 throw new IllegalArgumentException(message); 609 } 610 } 611 612 613 /** 614 * Verify that key is a legal value for the 615 * verticalAlignment or verticalTextPosition properties. 616 * 617 * @param key the property value to check 618 * @param message the IllegalArgumentException detail message 619 * @exception IllegalArgumentException if key isn't TOP, CENTER, or BOTTOM. 620 * @see #setVerticalAlignment 621 * @see #setVerticalTextPosition 622 */ 623 protected int checkVerticalKey(int key, String message) { 624 if ((key == TOP) || (key == CENTER) || (key == BOTTOM)) { 625 return key; 626 } 627 else { 628 throw new IllegalArgumentException(message); 629 } 630 } 631 632 633 /** 634 * Returns the amount of space between the text and the icon 635 * displayed in this label. 636 * 637 * @return an int equal to the number of pixels between the text 638 * and the icon. 639 * @see #setIconTextGap 640 */ 641 public int getIconTextGap() { 642 return iconTextGap; 643 } 644 645 646 /** 647 * If both the icon and text properties are set, this property 648 * defines the space between them. 649 * <p> 650 * The default value of this property is 4 pixels. 651 * <p> 652 * This is a JavaBeans bound property. 653 * 654 * @see #getIconTextGap 655 * @beaninfo 656 * bound: true 657 * attribute: visualUpdate true 658 * description: If both the icon and text properties are set, this 659 * property defines the space between them. 660 */ 661 public void setIconTextGap(int iconTextGap) { 662 int oldValue = this.iconTextGap; 663 this.iconTextGap = iconTextGap; 664 firePropertyChange("iconTextGap", oldValue, iconTextGap); 665 if (iconTextGap != oldValue) { 666 revalidate(); 667 repaint(); 668 } 669 } 670 671 672 673 /** 674 * Returns the alignment of the label's contents along the Y axis. 675 * 676 * @return The value of the verticalAlignment property, one of the 677 * following constants defined in <code>SwingConstants</code>: 678 * <code>TOP</code>, 679 * <code>CENTER</code>, or 680 * <code>BOTTOM</code>. 681 * 682 * @see SwingConstants 683 * @see #setVerticalAlignment 684 */ 685 public int getVerticalAlignment() { 686 return verticalAlignment; 687 } 688 689 690 /** 691 * Sets the alignment of the label's contents along the Y axis. 692 * <p> 693 * The default value of this property is CENTER. 694 * 695 * @param alignment One of the following constants 696 * defined in <code>SwingConstants</code>: 697 * <code>TOP</code>, 698 * <code>CENTER</code> (the default), or 699 * <code>BOTTOM</code>. 700 * 701 * @see SwingConstants 702 * @see #getVerticalAlignment 703 * @beaninfo 704 * bound: true 705 * enum: TOP SwingConstants.TOP 706 * CENTER SwingConstants.CENTER 707 * BOTTOM SwingConstants.BOTTOM 708 * attribute: visualUpdate true 709 * description: The alignment of the label's contents along the Y axis. 710 */ 711 public void setVerticalAlignment(int alignment) { 712 if (alignment == verticalAlignment) return; 713 int oldValue = verticalAlignment; 714 verticalAlignment = checkVerticalKey(alignment, "verticalAlignment"); 715 firePropertyChange("verticalAlignment", oldValue, verticalAlignment); 716 repaint(); 717 } 718 719 720 /** 721 * Returns the alignment of the label's contents along the X axis. 722 * 723 * @return The value of the horizontalAlignment property, one of the 724 * following constants defined in <code>SwingConstants</code>: 725 * <code>LEFT</code>, 726 * <code>CENTER</code>, 727 * <code>RIGHT</code>, 728 * <code>LEADING</code> or 729 * <code>TRAILING</code>. 730 * 731 * @see #setHorizontalAlignment 732 * @see SwingConstants 733 */ 734 public int getHorizontalAlignment() { 735 return horizontalAlignment; 736 } 737 738 /** 739 * Sets the alignment of the label's contents along the X axis. 740 * <p> 741 * This is a JavaBeans bound property. 742 * 743 * @param alignment One of the following constants 744 * defined in <code>SwingConstants</code>: 745 * <code>LEFT</code>, 746 * <code>CENTER</code> (the default for image-only labels), 747 * <code>RIGHT</code>, 748 * <code>LEADING</code> (the default for text-only labels) or 749 * <code>TRAILING</code>. 750 * 751 * @see SwingConstants 752 * @see #getHorizontalAlignment 753 * @beaninfo 754 * bound: true 755 * enum: LEFT SwingConstants.LEFT 756 * CENTER SwingConstants.CENTER 757 * RIGHT SwingConstants.RIGHT 758 * LEADING SwingConstants.LEADING 759 * TRAILING SwingConstants.TRAILING 760 * attribute: visualUpdate true 761 * description: The alignment of the label's content along the X axis. 762 */ 763 public void setHorizontalAlignment(int alignment) { 764 if (alignment == horizontalAlignment) return; 765 int oldValue = horizontalAlignment; 766 horizontalAlignment = checkHorizontalKey(alignment, 767 "horizontalAlignment"); 768 firePropertyChange("horizontalAlignment", 769 oldValue, horizontalAlignment); 770 repaint(); 771 } 772 773 774 /** 775 * Returns the vertical position of the label's text, 776 * relative to its image. 777 * 778 * @return One of the following constants 779 * defined in <code>SwingConstants</code>: 780 * <code>TOP</code>, 781 * <code>CENTER</code>, or 782 * <code>BOTTOM</code>. 783 * 784 * @see #setVerticalTextPosition 785 * @see SwingConstants 786 */ 787 public int getVerticalTextPosition() { 788 return verticalTextPosition; 789 } 790 791 792 /** 793 * Sets the vertical position of the label's text, 794 * relative to its image. 795 * <p> 796 * The default value of this property is CENTER. 797 * <p> 798 * This is a JavaBeans bound property. 799 * 800 * @param textPosition One of the following constants 801 * defined in <code>SwingConstants</code>: 802 * <code>TOP</code>, 803 * <code>CENTER</code> (the default), or 804 * <code>BOTTOM</code>. 805 * 806 * @see SwingConstants 807 * @see #getVerticalTextPosition 808 * @beaninfo 809 * bound: true 810 * enum: TOP SwingConstants.TOP 811 * CENTER SwingConstants.CENTER 812 * BOTTOM SwingConstants.BOTTOM 813 * expert: true 814 * attribute: visualUpdate true 815 * description: The vertical position of the text relative to it's image. 816 */ 817 public void setVerticalTextPosition(int textPosition) { 818 if (textPosition == verticalTextPosition) return; 819 int old = verticalTextPosition; 820 verticalTextPosition = checkVerticalKey(textPosition, 821 "verticalTextPosition"); 822 firePropertyChange("verticalTextPosition", old, verticalTextPosition); 823 revalidate(); 824 repaint(); 825 } 826 827 828 /** 829 * Returns the horizontal position of the label's text, 830 * relative to its image. 831 * 832 * @return One of the following constants 833 * defined in <code>SwingConstants</code>: 834 * <code>LEFT</code>, 835 * <code>CENTER</code>, 836 * <code>RIGHT</code>, 837 * <code>LEADING</code> or 838 * <code>TRAILING</code>. 839 * 840 * @see SwingConstants 841 */ 842 public int getHorizontalTextPosition() { 843 return horizontalTextPosition; 844 } 845 846 847 /** 848 * Sets the horizontal position of the label's text, 849 * relative to its image. 850 * 851 * @param textPosition One of the following constants 852 * defined in <code>SwingConstants</code>: 853 * <code>LEFT</code>, 854 * <code>CENTER</code>, 855 * <code>RIGHT</code>, 856 * <code>LEADING</code>, or 857 * <code>TRAILING</code> (the default). 858 * 859 * @see SwingConstants 860 * @beaninfo 861 * expert: true 862 * bound: true 863 * enum: LEFT SwingConstants.LEFT 864 * CENTER SwingConstants.CENTER 865 * RIGHT SwingConstants.RIGHT 866 * LEADING SwingConstants.LEADING 867 * TRAILING SwingConstants.TRAILING 868 * attribute: visualUpdate true 869 * description: The horizontal position of the label's text, 870 * relative to its image. 871 */ 872 public void setHorizontalTextPosition(int textPosition) { 873 int old = horizontalTextPosition; 874 this.horizontalTextPosition = checkHorizontalKey(textPosition, 875 "horizontalTextPosition"); 876 firePropertyChange("horizontalTextPosition", 877 old, horizontalTextPosition); 878 revalidate(); 879 repaint(); 880 } 881 882 883 /** 884 * This is overridden to return false if the current Icon's Image is 885 * not equal to the passed in Image <code>img</code>. 886 * 887 * @see java.awt.image.ImageObserver 888 * @see java.awt.Component#imageUpdate(java.awt.Image, int, int, int, int, int) 889 */ 890 public boolean imageUpdate(Image img, int infoflags, 891 int x, int y, int w, int h) { 892 // Don't use getDisabledIcon, will trigger creation of icon if icon 893 // not set. 894 if (!isShowing() || 895 !SwingUtilities.doesIconReferenceImage(getIcon(), img) && 896 !SwingUtilities.doesIconReferenceImage(disabledIcon, img)) { 897 898 return false; 899 } 900 return super.imageUpdate(img, infoflags, x, y, w, h); 901 } 902 903 904 /** 905 * See readObject() and writeObject() in JComponent for more 906 * information about serialization in Swing. 907 */ 908 private void writeObject(ObjectOutputStream s) throws IOException { 909 s.defaultWriteObject(); 910 if (getUIClassID().equals(uiClassID)) { 911 byte count = JComponent.getWriteObjCounter(this); 912 JComponent.setWriteObjCounter(this, --count); 913 if (count == 0 && ui != null) { 914 ui.installUI(this); 915 } 916 } 917 } 918 919 920 /** 921 * Returns a string representation of this JLabel. This method 922 * is intended to be used only for debugging purposes, and the 923 * content and format of the returned string may vary between 924 * implementations. The returned string may be empty but may not 925 * be <code>null</code>. 926 * 927 * @return a string representation of this JLabel. 928 */ 929 protected String paramString() { 930 String textString = (text != null ? 931 text : ""); 932 String defaultIconString = ((defaultIcon != null) 933 && (defaultIcon != this) ? 934 defaultIcon.toString() : ""); 935 String disabledIconString = ((disabledIcon != null) 936 && (disabledIcon != this) ? 937 disabledIcon.toString() : ""); 938 String labelForString = (labelFor != null ? 939 labelFor.toString() : ""); 940 String verticalAlignmentString; 941 if (verticalAlignment == TOP) { 942 verticalAlignmentString = "TOP"; 943 } else if (verticalAlignment == CENTER) { 944 verticalAlignmentString = "CENTER"; 945 } else if (verticalAlignment == BOTTOM) { 946 verticalAlignmentString = "BOTTOM"; 947 } else verticalAlignmentString = ""; 948 String horizontalAlignmentString; 949 if (horizontalAlignment == LEFT) { 950 horizontalAlignmentString = "LEFT"; 951 } else if (horizontalAlignment == CENTER) { 952 horizontalAlignmentString = "CENTER"; 953 } else if (horizontalAlignment == RIGHT) { 954 horizontalAlignmentString = "RIGHT"; 955 } else if (horizontalAlignment == LEADING) { 956 horizontalAlignmentString = "LEADING"; 957 } else if (horizontalAlignment == TRAILING) { 958 horizontalAlignmentString = "TRAILING"; 959 } else horizontalAlignmentString = ""; 960 String verticalTextPositionString; 961 if (verticalTextPosition == TOP) { 962 verticalTextPositionString = "TOP"; 963 } else if (verticalTextPosition == CENTER) { 964 verticalTextPositionString = "CENTER"; 965 } else if (verticalTextPosition == BOTTOM) { 966 verticalTextPositionString = "BOTTOM"; 967 } else verticalTextPositionString = ""; 968 String horizontalTextPositionString; 969 if (horizontalTextPosition == LEFT) { 970 horizontalTextPositionString = "LEFT"; 971 } else if (horizontalTextPosition == CENTER) { 972 horizontalTextPositionString = "CENTER"; 973 } else if (horizontalTextPosition == RIGHT) { 974 horizontalTextPositionString = "RIGHT"; 975 } else if (horizontalTextPosition == LEADING) { 976 horizontalTextPositionString = "LEADING"; 977 } else if (horizontalTextPosition == TRAILING) { 978 horizontalTextPositionString = "TRAILING"; 979 } else horizontalTextPositionString = ""; 980 981 return super.paramString() + 982 ",defaultIcon=" + defaultIconString + 983 ",disabledIcon=" + disabledIconString + 984 ",horizontalAlignment=" + horizontalAlignmentString + 985 ",horizontalTextPosition=" + horizontalTextPositionString + 986 ",iconTextGap=" + iconTextGap + 987 ",labelFor=" + labelForString + 988 ",text=" + textString + 989 ",verticalAlignment=" + verticalAlignmentString + 990 ",verticalTextPosition=" + verticalTextPositionString; 991 } 992 993 /** 994 * --- Accessibility Support --- 995 */ 996 997 /** 998 * Get the component this is labelling. 999 * 1000 * @return the Component this is labelling. Can be null if this 1001 * does not label a Component. If the displayedMnemonic 1002 * property is set and the labelFor property is also set, the label 1003 * will call the requestFocus method of the component specified by the 1004 * labelFor property when the mnemonic is activated. 1005 * 1006 * @see #getDisplayedMnemonic 1007 * @see #setDisplayedMnemonic 1008 */ 1009 public Component getLabelFor() { 1010 return labelFor; 1011 } 1012 1013 /** 1014 * Set the component this is labelling. Can be null if this does not 1015 * label a Component. If the displayedMnemonic property is set 1016 * and the labelFor property is also set, the label will 1017 * call the requestFocus method of the component specified by the 1018 * labelFor property when the mnemonic is activated. 1019 * 1020 * @param c the Component this label is for, or null if the label is 1021 * not the label for a component 1022 * 1023 * @see #getDisplayedMnemonic 1024 * @see #setDisplayedMnemonic 1025 * 1026 * @beaninfo 1027 * bound: true 1028 * description: The component this is labelling. 1029 */ 1030 public void setLabelFor(Component c) { 1031 Component oldC = labelFor; 1032 labelFor = c; 1033 firePropertyChange("labelFor", oldC, c); 1034 1035 if (oldC instanceof JComponent) { 1036 ((JComponent)oldC).putClientProperty(LABELED_BY_PROPERTY, null); 1037 } 1038 if (c instanceof JComponent) { 1039 ((JComponent)c).putClientProperty(LABELED_BY_PROPERTY, this); 1040 } 1041 } 1042 1043 /** 1044 * Get the AccessibleContext of this object 1045 * 1046 * @return the AccessibleContext of this object 1047 * @beaninfo 1048 * expert: true 1049 * description: The AccessibleContext associated with this Label. 1050 */ 1051 public AccessibleContext getAccessibleContext() { 1052 if (accessibleContext == null) { 1053 accessibleContext = new AccessibleJLabel(); 1054 } 1055 return accessibleContext; 1056 } 1057 1058 /** 1059 * The class used to obtain the accessible role for this object. 1060 * <p> 1061 * <strong>Warning:</strong> 1062 * Serialized objects of this class will not be compatible with 1063 * future Swing releases. The current serialization support is 1064 * appropriate for short term storage or RMI between applications running 1065 * the same version of Swing. As of 1.4, support for long term storage 1066 * of all JavaBeans™ 1067 * has been added to the <code>java.beans</code> package. 1068 * Please see {@link java.beans.XMLEncoder}. 1069 */ 1070 @SuppressWarnings("serial") 1071 protected class AccessibleJLabel extends AccessibleJComponent 1072 implements AccessibleText, AccessibleExtendedComponent { 1073 1074 /** 1075 * Get the accessible name of this object. 1076 * 1077 * @return the localized name of the object -- can be null if this 1078 * object does not have a name 1079 * @see AccessibleContext#setAccessibleName 1080 */ 1081 public String getAccessibleName() { 1082 String name = accessibleName; 1083 1084 if (name == null) { 1085 name = (String)getClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY); 1086 } 1087 if (name == null) { 1088 name = JLabel.this.getText(); 1089 } 1090 if (name == null) { 1091 name = super.getAccessibleName(); 1092 } 1093 return name; 1094 } 1095 1096 /** 1097 * Get the role of this object. 1098 * 1099 * @return an instance of AccessibleRole describing the role of the 1100 * object 1101 * @see AccessibleRole 1102 */ 1103 public AccessibleRole getAccessibleRole() { 1104 return AccessibleRole.LABEL; 1105 } 1106 1107 /** 1108 * Get the AccessibleIcons associated with this object if one 1109 * or more exist. Otherwise return null. 1110 * @since 1.3 1111 */ 1112 public AccessibleIcon [] getAccessibleIcon() { 1113 Icon icon = getIcon(); 1114 if (icon instanceof Accessible) { 1115 AccessibleContext ac = 1116 ((Accessible)icon).getAccessibleContext(); 1117 if (ac != null && ac instanceof AccessibleIcon) { 1118 return new AccessibleIcon[] { (AccessibleIcon)ac }; 1119 } 1120 } 1121 return null; 1122 } 1123 1124 /** 1125 * Get the AccessibleRelationSet associated with this object if one 1126 * exists. Otherwise return null. 1127 * @see AccessibleRelation 1128 * @since 1.3 1129 */ 1130 public AccessibleRelationSet getAccessibleRelationSet() { 1131 // Check where the AccessibleContext's relation 1132 // set already contains a LABEL_FOR relation. 1133 AccessibleRelationSet relationSet 1134 = super.getAccessibleRelationSet(); 1135 1136 if (!relationSet.contains(AccessibleRelation.LABEL_FOR)) { 1137 Component c = JLabel.this.getLabelFor(); 1138 if (c != null) { 1139 AccessibleRelation relation 1140 = new AccessibleRelation(AccessibleRelation.LABEL_FOR); 1141 relation.setTarget(c); 1142 relationSet.add(relation); 1143 } 1144 } 1145 return relationSet; 1146 } 1147 1148 1149 /* AccessibleText ---------- */ 1150 1151 public AccessibleText getAccessibleText() { 1152 View view = (View)JLabel.this.getClientProperty("html"); 1153 if (view != null) { 1154 return this; 1155 } else { 1156 return null; 1157 } 1158 } 1159 1160 /** 1161 * Given a point in local coordinates, return the zero-based index 1162 * of the character under that Point. If the point is invalid, 1163 * this method returns -1. 1164 * 1165 * @param p the Point in local coordinates 1166 * @return the zero-based index of the character under Point p; if 1167 * Point is invalid returns -1. 1168 * @since 1.3 1169 */ 1170 public int getIndexAtPoint(Point p) { 1171 View view = (View) JLabel.this.getClientProperty("html"); 1172 if (view != null) { 1173 Rectangle r = getTextRectangle(); 1174 if (r == null) { 1175 return -1; 1176 } 1177 Rectangle2D.Float shape = 1178 new Rectangle2D.Float(r.x, r.y, r.width, r.height); 1179 Position.Bias bias[] = new Position.Bias[1]; 1180 return view.viewToModel(p.x, p.y, shape, bias); 1181 } else { 1182 return -1; 1183 } 1184 } 1185 1186 /** 1187 * Returns the bounding box of the character at the given 1188 * index in the string. The bounds are returned in local 1189 * coordinates. If the index is invalid, <code>null</code> is returned. 1190 * 1191 * @param i the index into the String 1192 * @return the screen coordinates of the character's bounding box. 1193 * If the index is invalid, <code>null</code> is returned. 1194 * @since 1.3 1195 */ 1196 public Rectangle getCharacterBounds(int i) { 1197 View view = (View) JLabel.this.getClientProperty("html"); 1198 if (view != null) { 1199 Rectangle r = getTextRectangle(); 1200 if (r == null) { 1201 return null; 1202 } 1203 Rectangle2D.Float shape = 1204 new Rectangle2D.Float(r.x, r.y, r.width, r.height); 1205 try { 1206 Shape charShape = 1207 view.modelToView(i, shape, Position.Bias.Forward); 1208 return charShape.getBounds(); 1209 } catch (BadLocationException e) { 1210 return null; 1211 } 1212 } else { 1213 return null; 1214 } 1215 } 1216 1217 /** 1218 * Return the number of characters (valid indicies) 1219 * 1220 * @return the number of characters 1221 * @since 1.3 1222 */ 1223 public int getCharCount() { 1224 View view = (View) JLabel.this.getClientProperty("html"); 1225 if (view != null) { 1226 Document d = view.getDocument(); 1227 if (d instanceof StyledDocument) { 1228 StyledDocument doc = (StyledDocument)d; 1229 return doc.getLength(); 1230 } 1231 } 1232 return accessibleContext.getAccessibleName().length(); 1233 } 1234 1235 /** 1236 * Return the zero-based offset of the caret. 1237 * 1238 * Note: That to the right of the caret will have the same index 1239 * value as the offset (the caret is between two characters). 1240 * @return the zero-based offset of the caret. 1241 * @since 1.3 1242 */ 1243 public int getCaretPosition() { 1244 // There is no caret. 1245 return -1; 1246 } 1247 1248 /** 1249 * Returns the String at a given index. 1250 * 1251 * @param part the AccessibleText.CHARACTER, AccessibleText.WORD, 1252 * or AccessibleText.SENTENCE to retrieve 1253 * @param index an index within the text >= 0 1254 * @return the letter, word, or sentence, 1255 * null for an invalid index or part 1256 * @since 1.3 1257 */ 1258 public String getAtIndex(int part, int index) { 1259 if (index < 0 || index >= getCharCount()) { 1260 return null; 1261 } 1262 switch (part) { 1263 case AccessibleText.CHARACTER: 1264 try { 1265 return getText(index, 1); 1266 } catch (BadLocationException e) { 1267 return null; 1268 } 1269 case AccessibleText.WORD: 1270 try { 1271 String s = getText(0, getCharCount()); 1272 BreakIterator words = BreakIterator.getWordInstance(getLocale()); 1273 words.setText(s); 1274 int end = words.following(index); 1275 return s.substring(words.previous(), end); 1276 } catch (BadLocationException e) { 1277 return null; 1278 } 1279 case AccessibleText.SENTENCE: 1280 try { 1281 String s = getText(0, getCharCount()); 1282 BreakIterator sentence = 1283 BreakIterator.getSentenceInstance(getLocale()); 1284 sentence.setText(s); 1285 int end = sentence.following(index); 1286 return s.substring(sentence.previous(), end); 1287 } catch (BadLocationException e) { 1288 return null; 1289 } 1290 default: 1291 return null; 1292 } 1293 } 1294 1295 /** 1296 * Returns the String after a given index. 1297 * 1298 * @param part the AccessibleText.CHARACTER, AccessibleText.WORD, 1299 * or AccessibleText.SENTENCE to retrieve 1300 * @param index an index within the text >= 0 1301 * @return the letter, word, or sentence, null for an invalid 1302 * index or part 1303 * @since 1.3 1304 */ 1305 public String getAfterIndex(int part, int index) { 1306 if (index < 0 || index >= getCharCount()) { 1307 return null; 1308 } 1309 switch (part) { 1310 case AccessibleText.CHARACTER: 1311 if (index+1 >= getCharCount()) { 1312 return null; 1313 } 1314 try { 1315 return getText(index+1, 1); 1316 } catch (BadLocationException e) { 1317 return null; 1318 } 1319 case AccessibleText.WORD: 1320 try { 1321 String s = getText(0, getCharCount()); 1322 BreakIterator words = BreakIterator.getWordInstance(getLocale()); 1323 words.setText(s); 1324 int start = words.following(index); 1325 if (start == BreakIterator.DONE || start >= s.length()) { 1326 return null; 1327 } 1328 int end = words.following(start); 1329 if (end == BreakIterator.DONE || end >= s.length()) { 1330 return null; 1331 } 1332 return s.substring(start, end); 1333 } catch (BadLocationException e) { 1334 return null; 1335 } 1336 case AccessibleText.SENTENCE: 1337 try { 1338 String s = getText(0, getCharCount()); 1339 BreakIterator sentence = 1340 BreakIterator.getSentenceInstance(getLocale()); 1341 sentence.setText(s); 1342 int start = sentence.following(index); 1343 if (start == BreakIterator.DONE || start > s.length()) { 1344 return null; 1345 } 1346 int end = sentence.following(start); 1347 if (end == BreakIterator.DONE || end > s.length()) { 1348 return null; 1349 } 1350 return s.substring(start, end); 1351 } catch (BadLocationException e) { 1352 return null; 1353 } 1354 default: 1355 return null; 1356 } 1357 } 1358 1359 /** 1360 * Returns the String before a given index. 1361 * 1362 * @param part the AccessibleText.CHARACTER, AccessibleText.WORD, 1363 * or AccessibleText.SENTENCE to retrieve 1364 * @param index an index within the text >= 0 1365 * @return the letter, word, or sentence, null for an invalid index 1366 * or part 1367 * @since 1.3 1368 */ 1369 public String getBeforeIndex(int part, int index) { 1370 if (index < 0 || index > getCharCount()-1) { 1371 return null; 1372 } 1373 switch (part) { 1374 case AccessibleText.CHARACTER: 1375 if (index == 0) { 1376 return null; 1377 } 1378 try { 1379 return getText(index-1, 1); 1380 } catch (BadLocationException e) { 1381 return null; 1382 } 1383 case AccessibleText.WORD: 1384 try { 1385 String s = getText(0, getCharCount()); 1386 BreakIterator words = BreakIterator.getWordInstance(getLocale()); 1387 words.setText(s); 1388 int end = words.following(index); 1389 end = words.previous(); 1390 int start = words.previous(); 1391 if (start == BreakIterator.DONE) { 1392 return null; 1393 } 1394 return s.substring(start, end); 1395 } catch (BadLocationException e) { 1396 return null; 1397 } 1398 case AccessibleText.SENTENCE: 1399 try { 1400 String s = getText(0, getCharCount()); 1401 BreakIterator sentence = 1402 BreakIterator.getSentenceInstance(getLocale()); 1403 sentence.setText(s); 1404 int end = sentence.following(index); 1405 end = sentence.previous(); 1406 int start = sentence.previous(); 1407 if (start == BreakIterator.DONE) { 1408 return null; 1409 } 1410 return s.substring(start, end); 1411 } catch (BadLocationException e) { 1412 return null; 1413 } 1414 default: 1415 return null; 1416 } 1417 } 1418 1419 /** 1420 * Return the AttributeSet for a given character at a given index 1421 * 1422 * @param i the zero-based index into the text 1423 * @return the AttributeSet of the character 1424 * @since 1.3 1425 */ 1426 public AttributeSet getCharacterAttribute(int i) { 1427 View view = (View) JLabel.this.getClientProperty("html"); 1428 if (view != null) { 1429 Document d = view.getDocument(); 1430 if (d instanceof StyledDocument) { 1431 StyledDocument doc = (StyledDocument)d; 1432 Element elem = doc.getCharacterElement(i); 1433 if (elem != null) { 1434 return elem.getAttributes(); 1435 } 1436 } 1437 } 1438 return null; 1439 } 1440 1441 /** 1442 * Returns the start offset within the selected text. 1443 * If there is no selection, but there is 1444 * a caret, the start and end offsets will be the same. 1445 * 1446 * @return the index into the text of the start of the selection 1447 * @since 1.3 1448 */ 1449 public int getSelectionStart() { 1450 // Text cannot be selected. 1451 return -1; 1452 } 1453 1454 /** 1455 * Returns the end offset within the selected text. 1456 * If there is no selection, but there is 1457 * a caret, the start and end offsets will be the same. 1458 * 1459 * @return the index into the text of the end of the selection 1460 * @since 1.3 1461 */ 1462 public int getSelectionEnd() { 1463 // Text cannot be selected. 1464 return -1; 1465 } 1466 1467 /** 1468 * Returns the portion of the text that is selected. 1469 * 1470 * @return the String portion of the text that is selected 1471 * @since 1.3 1472 */ 1473 public String getSelectedText() { 1474 // Text cannot be selected. 1475 return null; 1476 } 1477 1478 /* 1479 * Returns the text substring starting at the specified 1480 * offset with the specified length. 1481 */ 1482 private String getText(int offset, int length) 1483 throws BadLocationException { 1484 1485 View view = (View) JLabel.this.getClientProperty("html"); 1486 if (view != null) { 1487 Document d = view.getDocument(); 1488 if (d instanceof StyledDocument) { 1489 StyledDocument doc = (StyledDocument)d; 1490 return doc.getText(offset, length); 1491 } 1492 } 1493 return null; 1494 } 1495 1496 /* 1497 * Returns the bounding rectangle for the component text. 1498 */ 1499 private Rectangle getTextRectangle() { 1500 1501 String text = JLabel.this.getText(); 1502 Icon icon = (JLabel.this.isEnabled()) ? JLabel.this.getIcon() : JLabel.this.getDisabledIcon(); 1503 1504 if ((icon == null) && (text == null)) { 1505 return null; 1506 } 1507 1508 Rectangle paintIconR = new Rectangle(); 1509 Rectangle paintTextR = new Rectangle(); 1510 Rectangle paintViewR = new Rectangle(); 1511 Insets paintViewInsets = new Insets(0, 0, 0, 0); 1512 1513 paintViewInsets = JLabel.this.getInsets(paintViewInsets); 1514 paintViewR.x = paintViewInsets.left; 1515 paintViewR.y = paintViewInsets.top; 1516 paintViewR.width = JLabel.this.getWidth() - (paintViewInsets.left + paintViewInsets.right); 1517 paintViewR.height = JLabel.this.getHeight() - (paintViewInsets.top + paintViewInsets.bottom); 1518 1519 String clippedText = SwingUtilities.layoutCompoundLabel( 1520 (JComponent)JLabel.this, 1521 getFontMetrics(getFont()), 1522 text, 1523 icon, 1524 JLabel.this.getVerticalAlignment(), 1525 JLabel.this.getHorizontalAlignment(), 1526 JLabel.this.getVerticalTextPosition(), 1527 JLabel.this.getHorizontalTextPosition(), 1528 paintViewR, 1529 paintIconR, 1530 paintTextR, 1531 JLabel.this.getIconTextGap()); 1532 1533 return paintTextR; 1534 } 1535 1536 // ----- AccessibleExtendedComponent 1537 1538 /** 1539 * Returns the AccessibleExtendedComponent 1540 * 1541 * @return the AccessibleExtendedComponent 1542 */ 1543 AccessibleExtendedComponent getAccessibleExtendedComponent() { 1544 return this; 1545 } 1546 1547 /** 1548 * Returns the tool tip text 1549 * 1550 * @return the tool tip text, if supported, of the object; 1551 * otherwise, null 1552 * @since 1.4 1553 */ 1554 public String getToolTipText() { 1555 return JLabel.this.getToolTipText(); 1556 } 1557 1558 /** 1559 * Returns the titled border text 1560 * 1561 * @return the titled border text, if supported, of the object; 1562 * otherwise, null 1563 * @since 1.4 1564 */ 1565 public String getTitledBorderText() { 1566 return super.getTitledBorderText(); 1567 } 1568 1569 /** 1570 * Returns key bindings associated with this object 1571 * 1572 * @return the key bindings, if supported, of the object; 1573 * otherwise, null 1574 * @see AccessibleKeyBinding 1575 * @since 1.4 1576 */ 1577 public AccessibleKeyBinding getAccessibleKeyBinding() { 1578 int mnemonic = JLabel.this.getDisplayedMnemonic(); 1579 if (mnemonic == 0) { 1580 return null; 1581 } 1582 return new LabelKeyBinding(mnemonic); 1583 } 1584 1585 class LabelKeyBinding implements AccessibleKeyBinding { 1586 int mnemonic; 1587 1588 LabelKeyBinding(int mnemonic) { 1589 this.mnemonic = mnemonic; 1590 } 1591 1592 /** 1593 * Returns the number of key bindings for this object 1594 * 1595 * @return the zero-based number of key bindings for this object 1596 */ 1597 public int getAccessibleKeyBindingCount() { 1598 return 1; 1599 } 1600 1601 /** 1602 * Returns a key binding for this object. The value returned is an 1603 * java.lang.Object which must be cast to appropriate type depending 1604 * on the underlying implementation of the key. For example, if the 1605 * Object returned is a javax.swing.KeyStroke, the user of this 1606 * method should do the following: 1607 * <nf><code> 1608 * Component c = <get the component that has the key bindings> 1609 * AccessibleContext ac = c.getAccessibleContext(); 1610 * AccessibleKeyBinding akb = ac.getAccessibleKeyBinding(); 1611 * for (int i = 0; i < akb.getAccessibleKeyBindingCount(); i++) { 1612 * Object o = akb.getAccessibleKeyBinding(i); 1613 * if (o instanceof javax.swing.KeyStroke) { 1614 * javax.swing.KeyStroke keyStroke = (javax.swing.KeyStroke)o; 1615 * <do something with the key binding> 1616 * } 1617 * } 1618 * </code></nf> 1619 * 1620 * @param i zero-based index of the key bindings 1621 * @return a javax.lang.Object which specifies the key binding 1622 * @exception IllegalArgumentException if the index is 1623 * out of bounds 1624 * @see #getAccessibleKeyBindingCount 1625 */ 1626 public java.lang.Object getAccessibleKeyBinding(int i) { 1627 if (i != 0) { 1628 throw new IllegalArgumentException(); 1629 } 1630 return KeyStroke.getKeyStroke(mnemonic, 0); 1631 } 1632 } 1633 1634 } // AccessibleJComponent 1635 }