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