KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > JLabel


1 /*
2  * @(#)JLabel.java 1.116 04/04/02
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.swing;
9
10 import java.awt.Component JavaDoc;
11 import java.awt.Font JavaDoc;
12 import java.awt.Image JavaDoc;
13 import java.awt.*;
14 import java.text.*;
15 import java.awt.geom.*;
16
17 import java.io.ObjectOutputStream JavaDoc;
18 import java.io.ObjectInputStream JavaDoc;
19 import java.io.IOException JavaDoc;
20
21 import javax.swing.plaf.LabelUI JavaDoc;
22 import javax.accessibility.*;
23 import javax.swing.text.*;
24 import javax.swing.text.html.*;
25 import javax.swing.plaf.basic.*;
26 import java.util.*;
27
28
29 /**
30  * A display area for a short text string or an image,
31  * or both.
32  * A label does not react to input events.
33  * As a result, it cannot get the keyboard focus.
34  * A label can, however, display a keyboard alternative
35  * as a convenience for a nearby component
36  * that has a keyboard alternative but can't display it.
37  * <p>
38  * A <code>JLabel</code> object can display
39  * either text, an image, or both.
40  * You can specify where in the label's display area
41  * the label's contents are aligned
42  * by setting the vertical and horizontal alignment.
43  * By default, labels are vertically centered
44  * in their display area.
45  * Text-only labels are leading edge aligned, by default;
46  * image-only labels are horizontally centered, by default.
47  * <p>
48  * You can also specify the position of the text
49  * relative to the image.
50  * By default, text is on the trailing edge of the image,
51  * with the text and image vertically aligned.
52  * <p>
53  * A label's leading and trailing edge are determined from the value of its
54  * {@link java.awt.ComponentOrientation} property. At present, the default
55  * ComponentOrientation setting maps the leading edge to left and the trailing
56  * edge to right.
57  *
58  * <p>
59  * Finally, you can use the <code>setIconTextGap</code> method
60  * to specify how many pixels
61  * should appear between the text and the image.
62  * The default is 4 pixels.
63  * <p>
64  * See <a HREF="http://java.sun.com/docs/books/tutorial/uiswing/components/label.html">How to Use Labels</a>
65  * in <em>The Java Tutorial</em>
66  * for further documentation.
67  * <p>
68  * <strong>Warning:</strong>
69  * Serialized objects of this class will not be compatible with
70  * future Swing releases. The current serialization support is
71  * appropriate for short term storage or RMI between applications running
72  * the same version of Swing. As of 1.4, support for long term storage
73  * of all JavaBeans<sup><font size="-2">TM</font></sup>
74  * has been added to the <code>java.beans</code> package.
75  * Please see {@link java.beans.XMLEncoder}.
76  *
77  * @beaninfo
78  * attribute: isContainer false
79  * description: A component that displays a short string and an icon.
80  *
81  * @version 1.116 04/02/04
82  * @author Hans Muller
83  */

84 public class JLabel extends JComponent JavaDoc implements SwingConstants JavaDoc, Accessible
85 {
86     /**
87      * @see #getUIClassID
88      * @see #readObject
89      */

90     private static final String JavaDoc uiClassID = "LabelUI";
91
92     private int mnemonic = '\0';
93     private int mnemonicIndex = -1;
94
95     private String JavaDoc text = ""; // "" rather than null, for BeanBox
96
private Icon JavaDoc defaultIcon = null;
97     private Icon JavaDoc disabledIcon = null;
98     private boolean disabledIconSet = false;
99             
100     private int verticalAlignment = CENTER;
101     private int horizontalAlignment = LEADING;
102     private int verticalTextPosition = CENTER;
103     private int horizontalTextPosition = TRAILING;
104     private int iconTextGap = 4;
105
106     protected Component JavaDoc labelFor = null;
107
108     /**
109      * Client property key used to determine what label is labeling the
110      * component. This is generally not used by labels, but is instead
111      * used by components such as text areas that are being labeled by
112      * labels. When the labelFor property of a label is set, it will
113      * automatically set the LABELED_BY_PROPERTY of the component being
114      * labelled.
115      *
116      * @see #setLabelFor
117      */

118     static final String JavaDoc LABELED_BY_PROPERTY = "labeledBy";
119
120     /**
121      * Creates a <code>JLabel</code> instance with the specified
122      * text, image, and horizontal alignment.
123      * The label is centered vertically in its display area.
124      * The text is on the trailing edge of the image.
125      *
126      * @param text The text to be displayed by the label.
127      * @param icon The image to be displayed by the label.
128      * @param horizontalAlignment One of the following constants
129      * defined in <code>SwingConstants</code>:
130      * <code>LEFT</code>,
131      * <code>CENTER</code>,
132      * <code>RIGHT</code>,
133      * <code>LEADING</code> or
134      * <code>TRAILING</code>.
135      */

136     public JLabel(String JavaDoc text, Icon JavaDoc icon, int horizontalAlignment) {
137         setText(text);
138         setIcon(icon);
139         setHorizontalAlignment(horizontalAlignment);
140         updateUI();
141         setAlignmentX(LEFT_ALIGNMENT);
142     }
143             
144     /**
145      * Creates a <code>JLabel</code> instance with the specified
146      * text and horizontal alignment.
147      * The label is centered vertically in its display area.
148      *
149      * @param text The text 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 JavaDoc text, int horizontalAlignment) {
159         this(text, null, horizontalAlignment);
160     }
161
162     /**
163      * Creates a <code>JLabel</code> instance with the specified text.
164      * The label is aligned against the leading edge of its display area,
165      * and centered vertically.
166      *
167      * @param text The text to be displayed by the label.
168      */

169     public JLabel(String JavaDoc text) {
170         this(text, null, LEADING);
171     }
172
173     /**
174      * Creates a <code>JLabel</code> instance with the specified
175      * image and horizontal alignment.
176      * The label is centered vertically in its display area.
177      *
178      * @param image The image to be displayed by the label.
179      * @param horizontalAlignment One of the following constants
180      * defined in <code>SwingConstants</code>:
181      * <code>LEFT</code>,
182      * <code>CENTER</code>,
183      * <code>RIGHT</code>,
184      * <code>LEADING</code> or
185      * <code>TRAILING</code>.
186      */

187     public JLabel(Icon JavaDoc image, int horizontalAlignment) {
188         this(null, image, horizontalAlignment);
189     }
190
191     /**
192      * Creates a <code>JLabel</code> instance with the specified image.
193      * The label is centered vertically and horizontally
194      * in its display area.
195      *
196      * @param image The image to be displayed by the label.
197      */

198     public JLabel(Icon JavaDoc image) {
199         this(null, image, CENTER);
200     }
201
202     /**
203      * Creates a <code>JLabel</code> instance with
204      * no image and with an empty string for the title.
205      * The label is centered vertically
206      * in its display area.
207      * The label's contents, once set, will be displayed on the leading edge
208      * of the label's display area.
209      */

210     public JLabel() {
211         this("", null, LEADING);
212     }
213
214
215     /**
216      * Returns the L&F object that renders this component.
217      *
218      * @return LabelUI object
219      */

220     public LabelUI JavaDoc getUI() {
221         return (LabelUI JavaDoc)ui;
222     }
223
224
225     /**
226      * Sets the L&F object that renders this component.
227      *
228      * @param ui the LabelUI L&F object
229      * @see UIDefaults#getUI
230      * @beaninfo
231      * bound: true
232      * hidden: true
233      * attribute: visualUpdate true
234      * description: The UI object that implements the Component's LookAndFeel.
235      */

236     public void setUI(LabelUI JavaDoc ui) {
237         super.setUI(ui);
238         // disabled icon is generated by LF so it should be unset here
239
if (!disabledIconSet && disabledIcon != null) {
240             setDisabledIcon(null);
241         }
242     }
243
244
245     /**
246      * Resets the UI property to a value from the current look and feel.
247      *
248      * @see JComponent#updateUI
249      */

250     public void updateUI() {
251         setUI((LabelUI JavaDoc)UIManager.getUI(this));
252     }
253
254
255     /**
256      * Returns a string that specifies the name of the l&f class
257      * that renders this component.
258      *
259      * @return String "LabelUI"
260      *
261      * @see JComponent#getUIClassID
262      * @see UIDefaults#getUI
263      */

264     public String JavaDoc getUIClassID() {
265         return uiClassID;
266     }
267
268
269     /**
270      * Returns the text string that the label displays.
271      *
272      * @return a String
273      * @see #setText
274      */

275     public String JavaDoc getText() {
276         return text;
277     }
278
279
280     /**
281      * Defines the single line of text this component will display. If
282      * the value of text is null or empty string, nothing is displayed.
283      * <p>
284      * The default value of this property is null.
285      * <p>
286      * This is a JavaBeans bound property.
287      *
288      * @see #setVerticalTextPosition
289      * @see #setHorizontalTextPosition
290      * @see #setIcon
291      * @beaninfo
292      * preferred: true
293      * bound: true
294      * attribute: visualUpdate true
295      * description: Defines the single line of text this component will display.
296      */

297     public void setText(String JavaDoc text) {
298
299         String JavaDoc oldAccessibleName = null;
300         if (accessibleContext != null) {
301             oldAccessibleName = accessibleContext.getAccessibleName();
302         }
303
304         String JavaDoc oldValue = this.text;
305         this.text = text;
306         firePropertyChange("text", oldValue, text);
307
308         setDisplayedMnemonicIndex(
309                       SwingUtilities.findDisplayedMnemonicIndex(
310                                           text, getDisplayedMnemonic()));
311
312         if ((accessibleContext != null)
313             && (accessibleContext.getAccessibleName() != oldAccessibleName)) {
314                 accessibleContext.firePropertyChange(
315                         AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
316                         oldAccessibleName,
317                         accessibleContext.getAccessibleName());
318         }
319         if (text == null || oldValue == null || !text.equals(oldValue)) {
320             revalidate();
321             repaint();
322         }
323     }
324
325     
326     /**
327      * Returns the graphic image (glyph, icon) that the label displays.
328      *
329      * @return an Icon
330      * @see #setIcon
331      */

332     public Icon JavaDoc getIcon() {
333         return defaultIcon;
334     }
335
336     /**
337      * Defines the icon this component will display. If
338      * the value of icon is null, nothing is displayed.
339      * <p>
340      * The default value of this property is null.
341      * <p>
342      * This is a JavaBeans bound property.
343      *
344      * @see #setVerticalTextPosition
345      * @see #setHorizontalTextPosition
346      * @see #getIcon
347      * @beaninfo
348      * preferred: true
349      * bound: true
350      * attribute: visualUpdate true
351      * description: The icon this component will display.
352      */

353     public void setIcon(Icon JavaDoc icon) {
354         Icon JavaDoc oldValue = defaultIcon;
355         defaultIcon = icon;
356
357         /* If the default icon has really changed and we had
358          * generated the disabled icon for this component
359          * (in other words, setDisabledIcon() was never called), then
360          * clear the disabledIcon field.
361          */

362         if ((defaultIcon != oldValue) && !disabledIconSet) {
363             disabledIcon = null;
364         }
365
366         firePropertyChange("icon", oldValue, defaultIcon);
367
368         if ((accessibleContext != null) && (oldValue != defaultIcon)) {
369                 accessibleContext.firePropertyChange(
370                         AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
371                         oldValue, defaultIcon);
372         }
373
374         /* If the default icon has changed and the new one is
375          * a different size, then revalidate. Repaint if the
376          * default icon has changed.
377          */

378         if (defaultIcon != oldValue) {
379             if ((defaultIcon == null) ||
380                 (oldValue == null) ||
381                 (defaultIcon.getIconWidth() != oldValue.getIconWidth()) ||
382                 (defaultIcon.getIconHeight() != oldValue.getIconHeight())) {
383                 revalidate();
384             }
385             repaint();
386         }
387     }
388
389     
390     /**
391      * Returns the icon used by the label when it's disabled.
392      * If no disabled icon has been set this will forward the call to
393      * the look and feel to construct an appropriate disabled Icon.
394      * <p>
395      * Some look and feels might not render the disabled Icon, in which
396      * case they will ignore this.
397      *
398      * @return the <code>disabledIcon</code> property
399      * @see #setDisabledIcon
400      * @see javax.swing.LookAndFeel#getDisabledIcon
401      * @see ImageIcon
402      */

403     public Icon JavaDoc getDisabledIcon() {
404         if (!disabledIconSet && disabledIcon == null && defaultIcon != null) {
405             disabledIcon = UIManager.getLookAndFeel().getDisabledIcon(this, defaultIcon);
406             if (disabledIcon != null) {
407                 firePropertyChange("disabledIcon", null, disabledIcon);
408             }
409         }
410         return disabledIcon;
411     }
412
413     
414     /**
415      * Set the icon to be displayed if this JLabel is "disabled"
416      * (JLabel.setEnabled(false)).
417      * <p>
418      * The default value of this property is null.
419      *
420      * @param disabledIcon the Icon to display when the component is disabled
421      * @see #getDisabledIcon
422      * @see #setEnabled
423      * @beaninfo
424      * bound: true
425      * attribute: visualUpdate true
426      * description: The icon to display if the label is disabled.
427      */

428     public void setDisabledIcon(Icon JavaDoc disabledIcon) {
429         Icon JavaDoc oldValue = this.disabledIcon;
430         this.disabledIcon = disabledIcon;
431         disabledIconSet = (disabledIcon != null);
432         firePropertyChange("disabledIcon", oldValue, disabledIcon);
433         if (disabledIcon != oldValue) {
434             if (disabledIcon == null || oldValue == null ||
435                 disabledIcon.getIconWidth() != oldValue.getIconWidth() ||
436                 disabledIcon.getIconHeight() != oldValue.getIconHeight()) {
437                 revalidate();
438             }
439             if (!isEnabled()) {
440                 repaint();
441             }
442         }
443     }
444
445
446     /**
447      * Specify a keycode that indicates a mnemonic key.
448      * This property is used when the label is part of a larger component.
449      * If the labelFor property of the label is not null, the label will
450      * call the requestFocus method of the component specified by the
451      * labelFor property when the mnemonic is activated.
452      *
453      * @see #getLabelFor
454      * @see #setLabelFor
455      * @beaninfo
456      * bound: true
457      * attribute: visualUpdate true
458      * description: The mnemonic keycode.
459      */

460     public void setDisplayedMnemonic(int key) {
461         int oldKey = mnemonic;
462         mnemonic = key;
463         firePropertyChange("displayedMnemonic", oldKey, mnemonic);
464
465         setDisplayedMnemonicIndex(
466             SwingUtilities.findDisplayedMnemonicIndex(getText(), mnemonic));
467
468         if (key != oldKey) {
469             revalidate();
470             repaint();
471         }
472     }
473
474
475     /**
476      * Specifies the displayedMnemonic as a char value.
477      *
478      * @param aChar a char specifying the mnemonic to display
479      * @see #setDisplayedMnemonic(int)
480      */

481     public void setDisplayedMnemonic(char aChar) {
482         int vk = (int) aChar;
483         if(vk >= 'a' && vk <='z')
484             vk -= ('a' - 'A');
485         setDisplayedMnemonic(vk);
486     }
487
488
489     /**
490      * Return the keycode that indicates a mnemonic key.
491      * This property is used when the label is part of a larger component.
492      * If the labelFor property of the label is not null, the label will
493      * call the requestFocus method of the component specified by the
494      * labelFor property when the mnemonic is activated.
495      *
496      * @return int value for the mnemonic key
497      *
498      * @see #getLabelFor
499      * @see #setLabelFor
500      */

501     public int getDisplayedMnemonic() {
502         return mnemonic;
503     }
504
505     /**
506      * Provides a hint to the look and feel as to which character in the
507      * text should be decorated to represent the mnemonic. Not all look and
508      * feels may support this. A value of -1 indicates either there is no
509      * mnemonic, the mnemonic character is not contained in the string, or
510      * the developer does not wish the mnemonic to be displayed.
511      * <p>
512      * The value of this is updated as the properties relating to the
513      * mnemonic change (such as the mnemonic itself, the text...).
514      * You should only ever have to call this if
515      * you do not wish the default character to be underlined. For example, if
516      * the text was 'Save As', with a mnemonic of 'a', and you wanted the 'A'
517      * to be decorated, as 'Save <u>A</u>s', you would have to invoke
518      * <code>setDisplayedMnemonicIndex(5)</code> after invoking
519      * <code>setMnemonic(KeyEvent.VK_A)</code>.
520      *
521      * @since 1.4
522      * @param index Index into the String to underline
523      * @exception IllegalArgumentException will be thrown if <code>index</code
524      * is >= length of the text, or < -1
525      *
526      * @beaninfo
527      * bound: true
528      * attribute: visualUpdate true
529      * description: the index into the String to draw the keyboard character
530      * mnemonic at
531      */

532     public void setDisplayedMnemonicIndex(int index)
533                                              throws IllegalArgumentException JavaDoc {
534         int oldValue = mnemonicIndex;
535         if (index == -1) {
536             mnemonicIndex = -1;
537         } else {
538             String JavaDoc text = getText();
539             int textLength = (text == null) ? 0 : text.length();
540             if (index < -1 || index >= textLength) { // index out of range
541
throw new IllegalArgumentException JavaDoc("index == " + index);
542             }
543         }
544         mnemonicIndex = index;
545         firePropertyChange("displayedMnemonicIndex", oldValue, index);
546         if (index != oldValue) {
547             revalidate();
548             repaint();
549         }
550     }
551
552     /**
553      * Returns the character, as an index, that the look and feel should
554      * provide decoration for as representing the mnemonic character.
555      *
556      * @since 1.4
557      * @return index representing mnemonic character
558      * @see #setDisplayedMnemonicIndex
559      */

560     public int getDisplayedMnemonicIndex() {
561         return mnemonicIndex;
562     }
563
564     /**
565      * Verify that key is a legal value for the horizontalAlignment properties.
566      *
567      * @param key the property value to check
568      * @param message the IllegalArgumentException detail message
569      * @exception IllegalArgumentException if key isn't LEFT, CENTER, RIGHT,
570      * LEADING or TRAILING.
571      * @see #setHorizontalTextPosition
572      * @see #setHorizontalAlignment
573      */

574     protected int checkHorizontalKey(int key, String JavaDoc message) {
575         if ((key == LEFT) ||
576             (key == CENTER) ||
577             (key == RIGHT) ||
578             (key == LEADING) ||
579             (key == TRAILING)) {
580             return key;
581         }
582         else {
583             throw new IllegalArgumentException JavaDoc(message);
584         }
585     }
586
587
588     /**
589      * Verify that key is a legal value for the
590      * verticalAlignment or verticalTextPosition properties.
591      *
592      * @param key the property value to check
593      * @param message the IllegalArgumentException detail message
594      * @exception IllegalArgumentException if key isn't TOP, CENTER, or BOTTOM.
595      * @see #setVerticalAlignment
596      * @see #setVerticalTextPosition
597      */

598     protected int checkVerticalKey(int key, String JavaDoc message) {
599         if ((key == TOP) || (key == CENTER) || (key == BOTTOM)) {
600             return key;
601         }
602         else {
603             throw new IllegalArgumentException JavaDoc(message);
604         }
605     }
606
607
608     /**
609      * Returns the amount of space between the text and the icon
610      * displayed in this label.
611      *
612      * @return an int equal to the number of pixels between the text
613      * and the icon.
614      * @see #setIconTextGap
615      */

616     public int getIconTextGap() {
617         return iconTextGap;
618     }
619
620
621     /**
622      * If both the icon and text properties are set, this property
623      * defines the space between them.
624      * <p>
625      * The default value of this property is 4 pixels.
626      * <p>
627      * This is a JavaBeans bound property.
628      *
629      * @see #getIconTextGap
630      * @beaninfo
631      * bound: true
632      * attribute: visualUpdate true
633      * description: If both the icon and text properties are set, this
634      * property defines the space between them.
635      */

636     public void setIconTextGap(int iconTextGap) {
637         int oldValue = this.iconTextGap;
638         this.iconTextGap = iconTextGap;
639         firePropertyChange("iconTextGap", oldValue, iconTextGap);
640         if (iconTextGap != oldValue) {
641             revalidate();
642             repaint();
643         }
644     }
645
646
647
648     /**
649      * Returns the alignment of the label's contents along the Y axis.
650      *
651      * @return The value of the verticalAlignment property, one of the
652      * following constants defined in <code>SwingConstants</code>:
653      * <code>TOP</code>,
654      * <code>CENTER</code>, or
655      * <code>BOTTOM</code>.
656      *
657      * @see SwingConstants
658      * @see #setVerticalAlignment
659      */

660     public int getVerticalAlignment() {
661         return verticalAlignment;
662     }
663
664
665     /**
666      * Sets the alignment of the label's contents along the Y axis.
667      * <p>
668      * The default value of this property is CENTER.
669      *
670      * @param alignment One of the following constants
671      * defined in <code>SwingConstants</code>:
672      * <code>TOP</code>,
673      * <code>CENTER</code> (the default), or
674      * <code>BOTTOM</code>.
675      *
676      * @see SwingConstants
677      * @see #getVerticalAlignment
678      * @beaninfo
679      * bound: true
680      * enum: TOP SwingConstants.TOP
681      * CENTER SwingConstants.CENTER
682      * BOTTOM SwingConstants.BOTTOM
683      * attribute: visualUpdate true
684      * description: The alignment of the label's contents along the Y axis.
685      */

686     public void setVerticalAlignment(int alignment) {
687         if (alignment == verticalAlignment) return;
688         int oldValue = verticalAlignment;
689         verticalAlignment = checkVerticalKey(alignment, "verticalAlignment");
690         firePropertyChange("verticalAlignment", oldValue, verticalAlignment);
691         repaint();
692     }
693
694
695     /**
696      * Returns the alignment of the label's contents along the X axis.
697      *
698      * @return The value of the horizontalAlignment property, one of the
699      * following constants defined in <code>SwingConstants</code>:
700      * <code>LEFT</code>,
701      * <code>CENTER</code>,
702      * <code>RIGHT</code>,
703      * <code>LEADING</code> or
704      * <code>TRAILING</code>.
705      *
706      * @see #setHorizontalAlignment
707      * @see SwingConstants
708      */

709     public int getHorizontalAlignment() {
710         return horizontalAlignment;
711     }
712
713     /**
714      * Sets the alignment of the label's contents along the X axis.
715      * <p>
716      * This is a JavaBeans bound property.
717      *
718      * @param alignment One of the following constants
719      * defined in <code>SwingConstants</code>:
720      * <code>LEFT</code>,
721      * <code>CENTER</code> (the default for image-only labels),
722      * <code>RIGHT</code>,
723      * <code>LEADING</code> (the default for text-only labels) or
724      * <code>TRAILING</code>.
725      *
726      * @see SwingConstants
727      * @see #getHorizontalAlignment
728      * @beaninfo
729      * bound: true
730      * enum: LEFT SwingConstants.LEFT
731      * CENTER SwingConstants.CENTER
732      * RIGHT SwingConstants.RIGHT
733      * LEADING SwingConstants.LEADING
734      * TRAILING SwingConstants.TRAILING
735      * attribute: visualUpdate true
736      * description: The alignment of the label's content along the X axis.
737      */

738     public void setHorizontalAlignment(int alignment) {
739         if (alignment == horizontalAlignment) return;
740         int oldValue = horizontalAlignment;
741         horizontalAlignment = checkHorizontalKey(alignment,
742                                                  "horizontalAlignment");
743         firePropertyChange("horizontalAlignment",
744                            oldValue, horizontalAlignment);
745         repaint();
746     }
747
748
749     /**
750      * Returns the vertical position of the label's text,
751      * relative to its image.
752      *
753      * @return One of the following constants
754      * defined in <code>SwingConstants</code>:
755      * <code>TOP</code>,
756      * <code>CENTER</code>, or
757      * <code>BOTTOM</code>.
758      *
759      * @see #setVerticalTextPosition
760      * @see SwingConstants
761      */

762     public int getVerticalTextPosition() {
763         return verticalTextPosition;
764     }
765
766
767     /**
768      * Sets the vertical position of the label's text,
769      * relative to its image.
770      * <p>
771      * The default value of this property is CENTER.
772      * <p>
773      * This is a JavaBeans bound property.
774      *
775      * @param textPosition One of the following constants
776      * defined in <code>SwingConstants</code>:
777      * <code>TOP</code>,
778      * <code>CENTER</code> (the default), or
779      * <code>BOTTOM</code>.
780      *
781      * @see SwingConstants
782      * @see #getVerticalTextPosition
783      * @beaninfo
784      * bound: true
785      * enum: TOP SwingConstants.TOP
786      * CENTER SwingConstants.CENTER
787      * BOTTOM SwingConstants.BOTTOM
788      * expert: true
789      * attribute: visualUpdate true
790      * description: The vertical position of the text relative to it's image.
791      */

792     public void setVerticalTextPosition(int textPosition) {
793         if (textPosition == verticalTextPosition) return;
794         int old = verticalTextPosition;
795         verticalTextPosition = checkVerticalKey(textPosition,
796                                                 "verticalTextPosition");
797         firePropertyChange("verticalTextPosition", old, verticalTextPosition);
798         repaint();
799     }
800
801
802     /**
803      * Returns the horizontal position of the label's text,
804      * relative to its image.
805      *
806      * @return One of the following constants
807      * defined in <code>SwingConstants</code>:
808      * <code>LEFT</code>,
809      * <code>CENTER</code>,
810      * <code>RIGHT</code>,
811      * <code>LEADING</code> or
812      * <code>TRAILING</code>.
813      *
814      * @see SwingConstants
815      */

816     public int getHorizontalTextPosition() {
817         return horizontalTextPosition;
818     }
819
820
821     /**
822      * Sets the horizontal position of the label's text,
823      * relative to its image.
824      *
825      * @param textPosition One of the following constants
826      * defined in <code>SwingConstants</code>:
827      * <code>LEFT</code>,
828      * <code>CENTER</code>,
829      * <code>RIGHT</code>,
830      * <code>LEADING</code>, or
831      * <code>TRAILING</code> (the default).
832      * @exception IllegalArgumentException
833      *
834      * @see SwingConstants
835      * @beaninfo
836      * expert: true
837      * bound: true
838      * enum: LEFT SwingConstants.LEFT
839      * CENTER SwingConstants.CENTER
840      * RIGHT SwingConstants.RIGHT
841      * LEADING SwingConstants.LEADING
842      * TRAILING SwingConstants.TRAILING
843      * attribute: visualUpdate true
844      * description: The horizontal position of the label's text,
845      * relative to its image.
846      */

847     public void setHorizontalTextPosition(int textPosition) {
848         int old = horizontalTextPosition;
849         this.horizontalTextPosition = checkHorizontalKey(textPosition,
850                                                 "horizontalTextPosition");
851         firePropertyChange("horizontalTextPosition",
852                            old, horizontalTextPosition);
853         repaint();
854     }
855
856
857     /**
858      * This is overridden to return false if the current Icon's Image is
859      * not equal to the passed in Image <code>img</code>.
860      *
861      * @see java.awt.image.ImageObserver
862      * @see java.awt.Component#imageUpdate(java.awt.Image, int, int, int, int, int)
863      */

864     public boolean imageUpdate(Image JavaDoc img, int infoflags,
865                    int x, int y, int w, int h) {
866         // Don't use getDisabledIcon, will trigger creation of icon if icon
867
// not set.
868
if (!isShowing() ||
869             !SwingUtilities.doesIconReferenceImage(getIcon(), img) &&
870             !SwingUtilities.doesIconReferenceImage(disabledIcon, img)) {
871
872         return false;
873     }
874     return super.imageUpdate(img, infoflags, x, y, w, h);
875     }
876
877
878     /**
879      * See readObject() and writeObject() in JComponent for more
880      * information about serialization in Swing.
881      */

882     private void writeObject(ObjectOutputStream JavaDoc s) throws IOException JavaDoc {
883         s.defaultWriteObject();
884         if (getUIClassID().equals(uiClassID)) {
885             byte count = JComponent.getWriteObjCounter(this);
886             JComponent.setWriteObjCounter(this, --count);
887             if (count == 0 && ui != null) {
888                 ui.installUI(this);
889             }
890         }
891     }
892
893
894     /**
895      * Returns a string representation of this JLabel. This method
896      * is intended to be used only for debugging purposes, and the
897      * content and format of the returned string may vary between
898      * implementations. The returned string may be empty but may not
899      * be <code>null</code>.
900      *
901      * @return a string representation of this JLabel.
902      */

903     protected String JavaDoc paramString() {
904     String JavaDoc textString = (text != null ?
905                  text : "");
906     String JavaDoc defaultIconString = ((defaultIcon != null)
907                     && (defaultIcon != this) ?
908                     defaultIcon.toString() : "");
909     String JavaDoc disabledIconString = ((disabledIcon != null)
910                      && (disabledIcon != this) ?
911                      disabledIcon.toString() : "");
912     String JavaDoc labelForString = (labelFor != null ?
913                  labelFor.toString() : "");
914         String JavaDoc verticalAlignmentString;
915         if (verticalAlignment == TOP) {
916             verticalAlignmentString = "TOP";
917         } else if (verticalAlignment == CENTER) {
918             verticalAlignmentString = "CENTER";
919         } else if (verticalAlignment == BOTTOM) {
920             verticalAlignmentString = "BOTTOM";
921         } else verticalAlignmentString = "";
922         String JavaDoc horizontalAlignmentString;
923         if (horizontalAlignment == LEFT) {
924             horizontalAlignmentString = "LEFT";
925         } else if (horizontalAlignment == CENTER) {
926             horizontalAlignmentString = "CENTER";
927         } else if (horizontalAlignment == RIGHT) {
928             horizontalAlignmentString = "RIGHT";
929         } else if (horizontalAlignment == LEADING) {
930             horizontalAlignmentString = "LEADING";
931         } else if (horizontalAlignment == TRAILING) {
932             horizontalAlignmentString = "TRAILING";
933         } else horizontalAlignmentString = "";
934         String JavaDoc verticalTextPositionString;
935         if (verticalTextPosition == TOP) {
936             verticalTextPositionString = "TOP";
937         } else if (verticalTextPosition == CENTER) {
938             verticalTextPositionString = "CENTER";
939         } else if (verticalTextPosition == BOTTOM) {
940             verticalTextPositionString = "BOTTOM";
941         } else verticalTextPositionString = "";
942         String JavaDoc horizontalTextPositionString;
943         if (horizontalTextPosition == LEFT) {
944             horizontalTextPositionString = "LEFT";
945         } else if (horizontalTextPosition == CENTER) {
946             horizontalTextPositionString = "CENTER";
947         } else if (horizontalTextPosition == RIGHT) {
948             horizontalTextPositionString = "RIGHT";
949         } else if (horizontalTextPosition == LEADING) {
950             horizontalTextPositionString = "LEADING";
951         } else if (horizontalTextPosition == TRAILING) {
952             horizontalTextPositionString = "TRAILING";
953         } else horizontalTextPositionString = "";
954
955     return super.paramString() +
956     ",defaultIcon=" + defaultIconString +
957     ",disabledIcon=" + disabledIconString +
958     ",horizontalAlignment=" + horizontalAlignmentString +
959     ",horizontalTextPosition=" + horizontalTextPositionString +
960     ",iconTextGap=" + iconTextGap +
961     ",labelFor=" + labelForString +
962     ",text=" + textString +
963     ",verticalAlignment=" + verticalAlignmentString +
964     ",verticalTextPosition=" + verticalTextPositionString;
965     }
966
967     /**
968      * --- Accessibility Support ---
969      */

970
971     /**
972      * Get the component this is labelling.
973      *
974      * @return the Component this is labelling. Can be null if this
975      * does not label a Component. If the displayedMnemonic
976      * property is set and the labelFor property is also set, the label
977      * will call the requestFocus method of the component specified by the
978      * labelFor property when the mnemonic is activated.
979      *
980      * @see #getDisplayedMnemonic
981      * @see #setDisplayedMnemonic
982      */

983     public Component JavaDoc getLabelFor() {
984         return labelFor;
985     }
986
987     /**
988      * Set the component this is labelling. Can be null if this does not
989      * label a Component. If the displayedMnemonic property is set
990      * and the labelFor property is also set, the label will
991      * call the requestFocus method of the component specified by the
992      * labelFor property when the mnemonic is activated.
993      *
994      * @param c the Component this label is for, or null if the label is
995      * not the label for a component
996      *
997      * @