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