1 /*
2 * Copyright 1997-2008 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any 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://java.sun.com/docs/books/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<sup><font size="-2">TM</font></sup>
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 public class JLabel extends JComponent implements SwingConstants, Accessible
108 {
109 /**
110 * @see #getUIClassID
111 * @see #readObject
112 */
113 private static final String uiClassID = "LabelUI";
114
115 private int mnemonic = '\0';
116 private int mnemonicIndex = -1;
117
118 private String text = ""; // "" rather than null, for BeanBox
119 private Icon defaultIcon = null;
120 private Icon disabledIcon = null;
121 private boolean disabledIconSet = false;
122
123 private int verticalAlignment = CENTER;
124 private int horizontalAlignment = LEADING;
125 private int verticalTextPosition = CENTER;
126 private int horizontalTextPosition = TRAILING;
127 private int iconTextGap = 4;
128
129 protected Component labelFor = null;
130
131 /**
132 * Client property key used to determine what label is labeling the
133 * component. This is generally not used by labels, but is instead
134 * used by components such as text areas that are being labeled by
135 * labels. When the labelFor property of a label is set, it will
136 * automatically set the LABELED_BY_PROPERTY of the component being
137 * labelled.
138 *
139 * @see #setLabelFor
140 */
141 static final String LABELED_BY_PROPERTY = "labeledBy";
142
143 /**
144 * Creates a <code>JLabel</code> instance with the specified
145 * text, image, and horizontal alignment.
146 * The label is centered vertically in its display area.
147 * The text is on the trailing edge of the image.
148 *
149 * @param text The text to be displayed by the label.
150 * @param icon The image to be displayed by the label.
151 * @param horizontalAlignment One of the following constants
152 * defined in <code>SwingConstants</code>:
153 * <code>LEFT</code>,
154 * <code>CENTER</code>,
155 * <code>RIGHT</code>,
156 * <code>LEADING</code> or
157 * <code>TRAILING</code>.
158 */
159 public JLabel(String text, Icon icon, int horizontalAlignment) {
160 setText(text);
161 setIcon(icon);
162 setHorizontalAlignment(horizontalAlignment);
163 updateUI();
164 setAlignmentX(LEFT_ALIGNMENT);
165 }
166
167 /**
168 * Creates a <code>JLabel</code> instance with the specified
169 * text and horizontal alignment.
170 * The label is centered vertically in its display area.
171 *
172 * @param text The text to be displayed by the label.
173 * @param horizontalAlignment One of the following constants
174 * defined in <code>SwingConstants</code>:
175 * <code>LEFT</code>,
176 * <code>CENTER</code>,
177 * <code>RIGHT</code>,
178 * <code>LEADING</code> or
179 * <code>TRAILING</code>.
180 */
181 public JLabel(String text, int horizontalAlignment) {
182 this(text, null, horizontalAlignment);
183 }
184
185 /**
186 * Creates a <code>JLabel</code> instance with the specified text.
187 * The label is aligned against the leading edge of its display area,
188 * and centered vertically.
189 *
190 * @param text The text to be displayed by the label.
191 */
192 public JLabel(String text) {
193 this(text, null, LEADING);
194 }
195
196 /**
197 * Creates a <code>JLabel</code> instance with the specified
198 * image and horizontal alignment.
199 * The label is centered vertically in its display area.
200 *
201 * @param image The image to be displayed by the label.
202 * @param horizontalAlignment One of the following constants
203 * defined in <code>SwingConstants</code>:
204 * <code>LEFT</code>,
205 * <code>CENTER</code>,
206 * <code>RIGHT</code>,
207 * <code>LEADING</code> or
208 * <code>TRAILING</code>.
209 */
210 public JLabel(Icon image, int horizontalAlignment) {
211 this(null, image, horizontalAlignment);
212 }
213
214 /**
215 * Creates a <code>JLabel</code> instance with the specified image.
216 * The label is centered vertically and horizontally
217 * in its display area.
218 *
219 * @param image The image to be displayed by the label.
220 */
221 public JLabel(Icon image) {
222 this(null, image, CENTER);
223 }
224
225 /**
226 * Creates a <code>JLabel</code> instance with
227 * no image and with an empty string for the title.
228 * The label is centered vertically
229 * in its display area.
230 * The label's contents, once set, will be displayed on the leading edge
231 * of the label's display area.
232 */
233 public JLabel() {
234 this("", null, LEADING);
235 }
236
237
238 /**
239 * Returns the L&F object that renders this component.
240 *
241 * @return LabelUI object
242 */
243 public LabelUI getUI() {
244 return (LabelUI)ui;
245 }
246
247
248 /**
249 * Sets the L&F object that renders this component.
250 *
251 * @param ui the LabelUI L&F object
252 * @see UIDefaults#getUI
253 * @beaninfo
254 * bound: true
255 * hidden: true
256 * attribute: visualUpdate true
257 * description: The UI object that implements the Component's LookAndFeel.
258 */
259 public void setUI(LabelUI ui) {
260 super.setUI(ui);
261 // disabled icon is generated by LF so it should be unset here
262 if (!disabledIconSet && disabledIcon != null) {
263 setDisabledIcon(null);
264 }
265 }
266
267
268 /**
269 * Resets the UI property to a value from the current look and feel.
270 *
271 * @see JComponent#updateUI
272 */
273 public void updateUI() {
274 setUI((LabelUI)UIManager.getUI(this));
275 }
276
277
278 /**
279 * Returns a string that specifies the name of the l&f class
280 * that renders this component.
281 *
282 * @return String "LabelUI"
283 *
284 * @see JComponent#getUIClassID
285 * @see UIDefaults#getUI
286 */
287 public String getUIClassID() {
288 return uiClassID;
289 }
290
291
292 /**
293 * Returns the text string that the label displays.
294 *
295 * @return a String
296 * @see #setText
297 */
298 public String getText() {
299 return text;
300 }
301
302
303 /**
304 * Defines the single line of text this component will display. If
305 * the value of text is null or empty string, nothing is displayed.
306 * <p>
307 * The default value of this property is null.
308 * <p>
309 * This is a JavaBeans bound property.
310 *
311 * @see #setVerticalTextPosition
312 * @see #setHorizontalTextPosition
313 * @see #setIcon
314 * @beaninfo
315 * preferred: true
316 * bound: true
317 * attribute: visualUpdate true
318 * description: Defines the single line of text this component will display.
319 */
320 public void setText(String text) {
321
322 String oldAccessibleName = null;
323 if (accessibleContext != null) {
324 oldAccessibleName = accessibleContext.getAccessibleName();
325 }
326
327 String oldValue = this.text;
328 this.text = text;
329 firePropertyChange("text", oldValue, text);
330
331 setDisplayedMnemonicIndex(
332 SwingUtilities.findDisplayedMnemonicIndex(
333 text, getDisplayedMnemonic()));
334
335 if ((accessibleContext != null)
336 && (accessibleContext.getAccessibleName() != oldAccessibleName)) {
337 accessibleContext.firePropertyChange(
338 AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
339 oldAccessibleName,
340 accessibleContext.getAccessibleName());
341 }
342 if (text == null || oldValue == null || !text.equals(oldValue)) {
343 revalidate();
344 repaint();
345 }
346 }
347
348
349 /**
350 * Returns the graphic image (glyph, icon) that the label displays.
351 *
352 * @return an Icon
353 * @see #setIcon
354 */
355 public Icon getIcon() {
356 return defaultIcon;
357 }
358
359 /**
360 * Defines the icon this component will display. If
361 * the value of icon is null, nothing is displayed.
362 * <p>
363 * The default value of this property is null.
364 * <p>
365 * This is a JavaBeans bound property.
366 *
367 * @see #setVerticalTextPosition
368 * @see #setHorizontalTextPosition
369 * @see #getIcon
370 * @beaninfo
371 * preferred: true
372 * bound: true
373 * attribute: visualUpdate true
374 * description: The icon this component will display.
375 */
376 public void setIcon(Icon icon) {
377 Icon oldValue = defaultIcon;
378 defaultIcon = icon;
379
380 /* If the default icon has really changed and we had
381 * generated the disabled icon for this component
382 * (in other words, setDisabledIcon() was never called), then
383 * clear the disabledIcon field.
384 */
385 if ((defaultIcon != oldValue) && !disabledIconSet) {
386 disabledIcon = null;
387 }
388
389 firePropertyChange("icon", oldValue, defaultIcon);
390
391 if ((accessibleContext != null) && (oldValue != defaultIcon)) {
392 accessibleContext.firePropertyChange(
393 AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
394 oldValue, defaultIcon);
395 }
396
397 /* If the default icon has changed and the new one is
398 * a different size, then revalidate. Repaint if the
399 * default icon has changed.
400 */
401 if (defaultIcon != oldValue) {
402 if ((defaultIcon == null) ||
403 (oldValue == null) ||
404 (defaultIcon.getIconWidth() != oldValue.getIconWidth()) ||
405 (defaultIcon.getIconHeight() != oldValue.getIconHeight())) {
406 revalidate();
407 }
408 repaint();
409 }
410 }
411
412
413 /**
414 * Returns the icon used by the label when it's disabled.
415 * If no disabled icon has been set this will forward the call to
416 * the look and feel to construct an appropriate disabled Icon.
417 * <p>
418 * Some look and feels might not render the disabled Icon, in which
419 * case they will ignore this.
420 *
421 * @return the <code>disabledIcon</code> property
422 * @see #setDisabledIcon
423 * @see javax.swing.LookAndFeel#getDisabledIcon
424 * @see ImageIcon
425 */
426 @Transient
427 public Icon getDisabledIcon() {
428 if (!disabledIconSet && disabledIcon == null && defaultIcon != null) {
429 disabledIcon = UIManager.getLookAndFeel().getDisabledIcon(this, defaultIcon);
430 if (disabledIcon != null) {
431 firePropertyChange("disabledIcon", null, disabledIcon);
432 }
433 }
434 return disabledIcon;
435 }
436
437
438 /**
439 * Set the icon to be displayed if this JLabel is "disabled"
440 * (JLabel.setEnabled(false)).
441 * <p>
442 * The default value of this property is null.
443 *
444 * @param disabledIcon the Icon to display when the component is disabled
445 * @see #getDisabledIcon
446 * @see #setEnabled
447 * @beaninfo
448 * bound: true
449 * attribute: visualUpdate true
450 * description: The icon to display if the label is disabled.
451 */
452 public void setDisabledIcon(Icon disabledIcon) {
453 Icon oldValue = this.disabledIcon;
454 this.disabledIcon = disabledIcon;
455 disabledIconSet = (disabledIcon != null);
456 firePropertyChange("disabledIcon", oldValue, disabledIcon);
457 if (disabledIcon != oldValue) {
458 if (disabledIcon == null || oldValue == null ||
459 disabledIcon.getIconWidth() != oldValue.getIconWidth() ||
460 disabledIcon.getIconHeight() != oldValue.getIconHeight()) {
461 revalidate();
462 }
463 if (!isEnabled()) {
464 repaint();
465 }
466 }
467 }
468
469
470 /**
471 * Specify a keycode that indicates a mnemonic key.
472 * This property is used when the label is part of a larger component.
473 * If the labelFor property of the label is not null, the label will
474 * call the requestFocus method of the component specified by the
475 * labelFor property when the mnemonic is activated.
476 *
477 * @see #getLabelFor
478 * @see #setLabelFor
479 * @beaninfo
480 * bound: true
481 * attribute: visualUpdate true
482 * description: The mnemonic keycode.
483 */
484 public void setDisplayedMnemonic(int key) {
485 int oldKey = mnemonic;
486 mnemonic = key;
487 firePropertyChange("displayedMnemonic", oldKey, mnemonic);
488
489 setDisplayedMnemonicIndex(
490 SwingUtilities.findDisplayedMnemonicIndex(getText(), mnemonic));
491
492 if (key != oldKey) {
493 revalidate();
494 repaint();
495 }
496 }
497
498
499 /**
500 * Specifies the displayedMnemonic as a char value.
501 *
502 * @param aChar a char specifying the mnemonic to display
503 * @see #setDisplayedMnemonic(int)
504 */
505 public void setDisplayedMnemonic(char aChar) {
506 int vk = (int) aChar;
507 if(vk >= 'a' && vk <='z')
508 vk -= ('a' - 'A');
509 setDisplayedMnemonic(vk);
510 }
511
512
513 /**
514 * Return the keycode that indicates a mnemonic key.
515 * This property is used when the label is part of a larger component.
516 * If the labelFor property of the label is not null, the label will
517 * call the requestFocus method of the component specified by the
518 * labelFor property when the mnemonic is activated.
519 *
520 * @return int value for the mnemonic key
521 *
522 * @see #getLabelFor
523 * @see #setLabelFor
524 */
525 public int getDisplayedMnemonic() {
526 return mnemonic;
527 }
528
529 /**
530 * Provides a hint to the look and feel as to which character in the
531 * text should be decorated to represent the mnemonic. Not all look and
532 * feels may support this. A value of -1 indicates either there is no
533 * mnemonic, the mnemonic character is not contained in the string, or
534 * the developer does not wish the mnemonic to be displayed.
535 * <p>
536 * The value of this is updated as the properties relating to the
537 * mnemonic change (such as the mnemonic itself, the text...).
538 * You should only ever have to call this if
539 * you do not wish the default character to be underlined. For example, if
540 * the text was 'Save As', with a mnemonic of 'a', and you wanted the 'A'
541 * to be decorated, as 'Save <u>A</u>s', you would have to invoke
542 * <code>setDisplayedMnemonicIndex(5)</code> after invoking
543 * <code>setDisplayedMnemonic(KeyEvent.VK_A)</code>.
544 *
545 * @since 1.4
546 * @param index Index into the String to underline
547 * @exception IllegalArgumentException will be thrown if <code>index</code
548 * is >= length of the text, or < -1
549 *
550 * @beaninfo
551 * bound: true
552 * attribute: visualUpdate true
553 * description: the index into the String to draw the keyboard character
554 * mnemonic at
555 */
556 public void setDisplayedMnemonicIndex(int index)
557 throws IllegalArgumentException {
558 int oldValue = mnemonicIndex;
559 if (index == -1) {
560 mnemonicIndex = -1;
561 } else {
562 String text = getText();
563 int textLength = (text == null) ? 0 : text.length();
564 if (index < -1 || index >= textLength) { // index out of range
565 throw new IllegalArgumentException("index == " + index);
566 }
567 }
568 mnemonicIndex = index;
569 firePropertyChange("displayedMnemonicIndex", oldValue, index);
570 if (index != oldValue) {
571 revalidate();
572 repaint();
573 }
574 }
575
576 /**
577 * Returns the character, as an index, that the look and feel should
578 * provide decoration for as representing the mnemonic character.
579 *
580 * @since 1.4
581 * @return index representing mnemonic character
582 * @see #setDisplayedMnemonicIndex
583 */
584 public int getDisplayedMnemonicIndex() {
585 return mnemonicIndex;
586 }
587
588 /**
589 * Verify that key is a legal value for the horizontalAlignment properties.
590 *
591 * @param key the property value to check
592 * @param message the IllegalArgumentException detail message
593 * @exception IllegalArgumentException if key isn't LEFT, CENTER, RIGHT,
594 * LEADING or TRAILING.
595 * @see #setHorizontalTextPosition
596 * @see #setHorizontalAlignment
597 */
598 protected int checkHorizontalKey(int key, String message) {
599 if ((key == LEFT) ||
600 (key == CENTER) ||
601 (key == RIGHT) ||
602 (key == LEADING) ||
603 (key == TRAILING)) {
604 return key;
605 }
606 else {
607 throw new IllegalArgumentException(message);
608 }
609 }
610
611
612 /**
613 * Verify that key is a legal value for the
614 * verticalAlignment or verticalTextPosition properties.
615 *
616 * @param key the property value to check
617 * @param message the IllegalArgumentException detail message
618 * @exception IllegalArgumentException if key isn't TOP, CENTER, or BOTTOM.
619 * @see #setVerticalAlignment
620 * @see #setVerticalTextPosition
621 */
622 protected int checkVerticalKey(int key, String message) {
623 if ((key == TOP) || (key == CENTER) || (key == BOTTOM)) {
624 return key;
625 }
626 else {
627 throw new IllegalArgumentException(message);
628 }
629 }
630
631
632 /**
633 * Returns the amount of space between the text and the icon
634 * displayed in this label.
635 *
636 * @return an int equal to the number of pixels between the text
637 * and the icon.
638 * @see #setIconTextGap
639 */
640 public int getIconTextGap() {
641 return iconTextGap;
642 }
643
644
645 /**
646 * If both the icon and text properties are set, this property
647 * defines the space between them.
648 * <p>
649 * The default value of this property is 4 pixels.
650 * <p>
651 * This is a JavaBeans bound property.
652 *
653 * @see #getIconTextGap
654 * @beaninfo
655 * bound: true
656 * attribute: visualUpdate true
657 * description: If both the icon and text properties are set, this
658 * property defines the space between them.
659 */
660 public void setIconTextGap(int iconTextGap) {
661 int oldValue = this.iconTextGap;
662 this.iconTextGap = iconTextGap;
663 firePropertyChange("iconTextGap", oldValue, iconTextGap);
664 if (iconTextGap != oldValue) {
665 revalidate();
666 repaint();
667 }
668 }
669
670
671
672 /**
673 * Returns the alignment of the label's contents along the Y axis.
674 *
675 * @return The value of the verticalAlignment property, one of the
676 * following constants defined in <code>SwingConstants</code>:
677 * <code>TOP</code>,
678 * <code>CENTER</code>, or
679 * <code>BOTTOM</code>.
680 *
681 * @see SwingConstants
682 * @see #setVerticalAlignment
683 */
684 public int getVerticalAlignment() {
685 return verticalAlignment;
686 }
687
688
689 /**
690 * Sets the alignment of the label's contents along the Y axis.
691 * <p>
692 * The default value of this property is CENTER.
693 *
694 * @param alignment One of the following constants
695 * defined in <code>SwingConstants</code>:
696 * <code>TOP</code>,
697 * <code>CENTER</code> (the default), or
698 * <code>BOTTOM</code>.
699 *
700 * @see SwingConstants
701 * @see #getVerticalAlignment
702 * @beaninfo
703 * bound: true
704 * enum: TOP SwingConstants.TOP
705 * CENTER SwingConstants.CENTER
706 * BOTTOM SwingConstants.BOTTOM
707 * attribute: visualUpdate true
708 * description: The alignment of the label's contents along the Y axis.
709 */
710 public void setVerticalAlignment(int alignment) {
711 if (alignment == verticalAlignment) return;
712 int oldValue = verticalAlignment;
713 verticalAlignment = checkVerticalKey(alignment, "verticalAlignment");
714 firePropertyChange("verticalAlignment", oldValue, verticalAlignment);
715 repaint();
716 }
717
718
719 /**
720 * Returns the alignment of the label's contents along the X axis.
721 *
722 * @return The value of the horizontalAlignment property, one of the
723 * following constants defined in <code>SwingConstants</code>:
724 * <code>LEFT</code>,
725 * <code>CENTER</code>,
726 * <code>RIGHT</code>,
727 * <code>LEADING</code> or
728 * <code>TRAILING</code>.
729 *
730 * @see #setHorizontalAlignment
731 * @see SwingConstants
732 */
733 public int getHorizontalAlignment() {
734 return horizontalAlignment;
735 }
736
737 /**
738 * Sets the alignment of the label's contents along the X axis.
739 * <p>
740 * This is a JavaBeans bound property.
741 *
742 * @param alignment One of the following constants
743 * defined in <code>SwingConstants</code>:
744 * <code>LEFT</code>,
745 * <code>CENTER</code> (the default for image-only labels),
746 * <code>RIGHT</code>,
747 * <code>LEADING</code> (the default for text-only labels) or
748 * <code>TRAILING</code>.
749 *
750 * @see SwingConstants
751 * @see #getHorizontalAlignment
752 * @beaninfo
753 * bound: true
754 * enum: LEFT SwingConstants.LEFT
755 * CENTER SwingConstants.CENTER
756 * RIGHT SwingConstants.RIGHT
757 * LEADING SwingConstants.LEADING
758 * TRAILING SwingConstants.TRAILING
759 * attribute: visualUpdate true
760 * description: The alignment of the label's content along the X axis.
761 */
762 public void setHorizontalAlignment(int alignment) {
763 if (alignment == horizontalAlignment) return;
764 int oldValue = horizontalAlignment;
765 horizontalAlignment = checkHorizontalKey(alignment,
766 "horizontalAlignment");
767 firePropertyChange("horizontalAlignment",
768 oldValue, horizontalAlignment);
769 repaint();
770 }
771
772
773 /**
774 * Returns the vertical position of the label's text,
775 * relative to its image.
776 *
777 * @return One of the following constants
778 * defined in <code>SwingConstants</code>:
779 * <code>TOP</code>,
780 * <code>CENTER</code>, or
781 * <code>BOTTOM</code>.
782 *
783 * @see #setVerticalTextPosition
784 * @see SwingConstants
785 */
786 public int getVerticalTextPosition() {
787 return verticalTextPosition;
788 }
789
790
791 /**
792 * Sets the vertical position of the label's text,
793 * relative to its image.
794 * <p>
795 * The default value of this property is CENTER.
796 * <p>
797 * This is a JavaBeans bound property.
798 *
799 * @param textPosition One of the following constants
800 * defined in <code>SwingConstants</code>:
801 * <code>TOP</code>,
802 * <code>CENTER</code> (the default), or
803 * <code>BOTTOM</code>.
804 *
805 * @see SwingConstants
806 * @see #getVerticalTextPosition
807 * @beaninfo
808 * bound: true
809 * enum: TOP SwingConstants.TOP
810 * CENTER SwingConstants.CENTER
811 * BOTTOM SwingConstants.BOTTOM
812 * expert: true
813 * attribute: visualUpdate true
814 * description: The vertical position of the text relative to it's image.
815 */
816 public void setVerticalTextPosition(int textPosition) {
817 if (textPosition == verticalTextPosition) return;
818 int old = verticalTextPosition;
819 verticalTextPosition = checkVerticalKey(textPosition,
820 "verticalTextPosition");
821 firePropertyChange("verticalTextPosition", old, verticalTextPosition);
822 revalidate();
823 repaint();
824 }
825
826
827 /**
828 * Returns the horizontal position of the label's text,
829 * relative to its image.
830 *
831 * @return One of the following constants
832 * defined in <code>SwingConstants</code>:
833 * <code>LEFT</code>,
834 * <code>CENTER</code>,
835 * <code>RIGHT</code>,
836 * <code>LEADING</code> or
837 * <code>TRAILING</code>.
838 *
839 * @see SwingConstants
840 */
841 public int getHorizontalTextPosition() {
842 return horizontalTextPosition;
843 }
844
845
846 /**
847 * Sets the horizontal position of the label's text,
848 * relative to its image.
849 *
850 * @param textPosition One of the following constants
851 * defined in <code>SwingConstants</code>:
852 * <code>LEFT</code>,
853 * <code>CENTER</code>,
854 * <code>RIGHT</code>,
855 * <code>LEADING</code>, or
856 * <code>TRAILING</code> (the default).
857 * @exception IllegalArgumentException
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<sup><font size="-2">TM</font></sup>
1067 * has been added to the <code>java.beans</code> package.
1068 * Please see {@link java.beans.XMLEncoder}.
1069 */
1070 protected class AccessibleJLabel extends AccessibleJComponent
1071 implements AccessibleText, AccessibleExtendedComponent {
1072
1073 /**
1074 * Get the accessible name of this object.
1075 *
1076 * @return the localized name of the object -- can be null if this
1077 * object does not have a name
1078 * @see AccessibleContext#setAccessibleName
1079 */
1080 public String getAccessibleName() {
1081 String name = accessibleName;
1082
1083 if (name == null) {
1084 name = (String)getClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY);
1085 }
1086 if (name == null) {
1087 name = JLabel.this.getText();
1088 }
1089 if (name == null) {
1090 name = super.getAccessibleName();
1091 }
1092 return name;
1093 }
1094
1095 /**
1096 * Get the role of this object.
1097 *
1098 * @return an instance of AccessibleRole describing the role of the
1099 * object
1100 * @see AccessibleRole
1101 */
1102 public AccessibleRole getAccessibleRole() {
1103 return AccessibleRole.LABEL;
1104 }
1105
1106 /**
1107 * Get the AccessibleIcons associated with this object if one
1108 * or more exist. Otherwise return null.
1109 * @since 1.3
1110 */
1111 public AccessibleIcon [] getAccessibleIcon() {
1112 Icon icon = getIcon();
1113 if (icon instanceof Accessible) {
1114 AccessibleContext ac =
1115 ((Accessible)icon).getAccessibleContext();
1116 if (ac != null && ac instanceof AccessibleIcon) {
1117 return new AccessibleIcon[] { (AccessibleIcon)ac };
1118 }
1119 }
1120 return null;
1121 }
1122
1123 /**
1124 * Get the AccessibleRelationSet associated with this object if one
1125 * exists. Otherwise return null.
1126 * @see AccessibleRelation
1127 * @since 1.3
1128 */
1129 public AccessibleRelationSet getAccessibleRelationSet() {
1130 // Check where the AccessibleContext's relation
1131 // set already contains a LABEL_FOR relation.
1132 AccessibleRelationSet relationSet
1133 = super.getAccessibleRelationSet();
1134
1135 if (!relationSet.contains(AccessibleRelation.LABEL_FOR)) {
1136 Component c = JLabel.this.getLabelFor();
1137 if (c != null) {
1138 AccessibleRelation relation
1139 = new AccessibleRelation(AccessibleRelation.LABEL_FOR);
1140 relation.setTarget(c);
1141 relationSet.add(relation);
1142 }
1143 }
1144 return relationSet;
1145 }
1146
1147
1148 /* AccessibleText ---------- */
1149
1150 public AccessibleText getAccessibleText() {
1151 View view = (View)JLabel.this.getClientProperty("html");
1152 if (view != null) {
1153 return this;
1154 } else {
1155 return null;
1156 }
1157 }
1158
1159 /**
1160 * Given a point in local coordinates, return the zero-based index
1161 * of the character under that Point. If the point is invalid,
1162 * this method returns -1.
1163 *
1164 * @param p the Point in local coordinates
1165 * @return the zero-based index of the character under Point p; if
1166 * Point is invalid returns -1.
1167 * @since 1.3
1168 */
1169 public int getIndexAtPoint(Point p) {
1170 View view = (View) JLabel.this.getClientProperty("html");
1171 if (view != null) {
1172 Rectangle r = getTextRectangle();
1173 if (r == null) {
1174 return -1;
1175 }
1176 Rectangle2D.Float shape =
1177 new Rectangle2D.Float(r.x, r.y, r.width, r.height);
1178 Position.Bias bias[] = new Position.Bias[1];
1179 return view.viewToModel(p.x, p.y, shape, bias);
1180 } else {
1181 return -1;
1182 }
1183 }
1184
1185 /**
1186 * Determine the bounding box of the character at the given
1187 * index into the string. The bounds are returned in local
1188 * coordinates. If the index is invalid an empty rectangle is
1189 * returned.
1190 *
1191 * @param i the index into the String
1192 * @return the screen coordinates of the character's the bounding box,
1193 * if index is invalid returns an empty rectangle.
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 teh 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 }