Merge from mainline.
[official-gcc.git] / libjava / classpath / javax / swing / JLabel.java
bloba993fb8f3e0d350793fa06294e9acbe1f3bfb2d2
1 /* JLabel.java --
2 Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package javax.swing;
41 import gnu.classpath.NotImplementedException;
43 import java.awt.Component;
44 import java.awt.Font;
45 import java.awt.Image;
46 import java.awt.Point;
47 import java.awt.Rectangle;
48 import java.awt.event.KeyEvent;
50 import javax.accessibility.Accessible;
51 import javax.accessibility.AccessibleContext;
52 import javax.accessibility.AccessibleExtendedComponent;
53 import javax.accessibility.AccessibleText;
54 import javax.swing.plaf.LabelUI;
55 import javax.swing.text.AttributeSet;
56 import javax.swing.text.SimpleAttributeSet;
58 /**
59 * A swing widget that displays a text message and/or an icon.
61 public class JLabel extends JComponent implements Accessible, SwingConstants
64 /**
65 * Accessibility support for JLabel.
67 protected class AccessibleJLabel
68 extends JComponent.AccessibleJComponent
69 implements AccessibleText, AccessibleExtendedComponent
71 /**
72 * Returns the selected text. This is null since JLabels
73 * are not selectable.
75 * @return <code>null</code> because JLabels cannot have selected text
77 public String getSelectedText()
79 // We return null here since JLabel's text is not selectable.
80 return null;
83 /**
84 * Returns the start index of the selected text.
86 * @return the start index of the selected text
88 public int getSelectionStart()
90 // JLabel don't have selected text, so we return -1 here.
91 return -1;
94 /**
95 * Returns the end index of the selected text.
97 * @return the end index of the selected text
99 public int getSelectionEnd()
101 // JLabel don't have selected text, so we return -1 here.
102 return -1;
106 * Returns an {@link AttributeSet} that reflects the text attributes of
107 * the specified character. We return an empty
108 * <code>AttributeSet</code> here, because JLabels don't support text
109 * attributes (at least not yet).
111 * @param index the index of the character
113 * @return an {@link AttributeSet} that reflects the text attributes of
114 * the specified character
116 public AttributeSet getCharacterAttribute(int index)
118 // FIXME: Return null here for simple labels, and query the HTML
119 // view for HTML labels.
120 return new SimpleAttributeSet();
124 * Returns the character, word or sentence at the specified index. The
125 * <code>part</code> parameter determines what is returned, the character,
126 * word or sentence after the index.
128 * @param part one of {@link AccessibleText#CHARACTER},
129 * {@link AccessibleText#WORD} or
130 * {@link AccessibleText#SENTENCE}, specifying what is returned
131 * @param index the index
133 * @return the character, word or sentence after <code>index</code>
135 public String getAtIndex(int part, int index)
137 String result = "";
138 int startIndex = -1;
139 int endIndex = -1;
140 switch(part)
142 case AccessibleText.CHARACTER:
143 result = String.valueOf(text.charAt(index));
144 break;
145 case AccessibleText.WORD:
146 startIndex = text.lastIndexOf(' ', index);
147 endIndex = text.indexOf(' ', startIndex + 1);
148 if (endIndex == -1)
149 endIndex = startIndex + 1;
150 result = text.substring(startIndex + 1, endIndex);
151 break;
152 case AccessibleText.SENTENCE:
153 default:
154 startIndex = text.lastIndexOf('.', index);
155 endIndex = text.indexOf('.', startIndex + 1);
156 if (endIndex == -1)
157 endIndex = startIndex + 1;
158 result = text.substring(startIndex + 1, endIndex);
159 break;
161 return result;
165 * Returns the character, word or sentence after the specified index. The
166 * <code>part</code> parameter determines what is returned, the character,
167 * word or sentence after the index.
169 * @param part one of {@link AccessibleText#CHARACTER},
170 * {@link AccessibleText#WORD} or
171 * {@link AccessibleText#SENTENCE}, specifying what is returned
172 * @param index the index
174 * @return the character, word or sentence after <code>index</code>
176 public String getAfterIndex(int part, int index)
178 String result = "";
179 int startIndex = -1;
180 int endIndex = -1;
181 switch(part)
183 case AccessibleText.CHARACTER:
184 result = String.valueOf(text.charAt(index + 1));
185 break;
186 case AccessibleText.WORD:
187 startIndex = text.indexOf(' ', index);
188 endIndex = text.indexOf(' ', startIndex + 1);
189 if (endIndex == -1)
190 endIndex = startIndex + 1;
191 result = text.substring(startIndex + 1, endIndex);
192 break;
193 case AccessibleText.SENTENCE:
194 default:
195 startIndex = text.indexOf('.', index);
196 endIndex = text.indexOf('.', startIndex + 1);
197 if (endIndex == -1)
198 endIndex = startIndex + 1;
199 result = text.substring(startIndex + 1, endIndex);
200 break;
202 return result;
206 * Returns the character, word or sentence before the specified index. The
207 * <code>part</code> parameter determines what is returned, the character,
208 * word or sentence before the index.
210 * @param part one of {@link AccessibleText#CHARACTER},
211 * {@link AccessibleText#WORD} or
212 * {@link AccessibleText#SENTENCE}, specifying what is returned
213 * @param index the index
215 * @return the character, word or sentence before <code>index</code>
217 public String getBeforeIndex(int part, int index)
219 String result = "";
220 int startIndex = -1;
221 int endIndex = -1;
222 switch(part)
224 case AccessibleText.CHARACTER:
225 result = String.valueOf(text.charAt(index - 1));
226 break;
227 case AccessibleText.WORD:
228 endIndex = text.lastIndexOf(' ', index);
229 if (endIndex == -1)
230 endIndex = 0;
231 startIndex = text.lastIndexOf(' ', endIndex - 1);
232 result = text.substring(startIndex + 1, endIndex);
233 break;
234 case AccessibleText.SENTENCE:
235 default:
236 endIndex = text.lastIndexOf('.', index);
237 if (endIndex == -1)
238 endIndex = 0;
239 startIndex = text.lastIndexOf('.', endIndex - 1);
240 result = text.substring(startIndex + 1, endIndex);
241 break;
243 return result;
247 * Returns the caret position. This method returns -1 because JLabel don't
248 * have a caret.
250 * @return the caret position
252 public int getCaretPosition()
254 return -1;
258 * Returns the number of characters that are displayed by the JLabel.
260 * @return the number of characters that are displayed by the JLabel
262 public int getCharCount()
264 // FIXME: Query HTML view for HTML labels.
265 return text.length();
269 * Returns the bounding box of the character at the specified index.
271 * @param index the index of the character that we return the
272 * bounds for
274 * @return the bounding box of the character at the specified index
276 public Rectangle getCharacterBounds(int index)
277 throws NotImplementedException
279 // FIXME: Implement this correctly.
280 return new Rectangle();
284 * Returns the index of the character that is located at the specified
285 * point.
287 * @param point the location that we lookup the character for
289 * @return the index of the character that is located at the specified
290 * point
292 public int getIndexAtPoint(Point point)
293 throws NotImplementedException
295 // FIXME: Implement this correctly.
296 return 0;
300 /** DOCUMENT ME! */
301 private static final long serialVersionUID = 5496508283662221534L;
303 static final String LABEL_PROPERTY = "labeledBy";
306 * The Component the label will give focus to when its mnemonic is
307 * activated.
309 protected Component labelFor;
311 /** The label's text. */
312 transient String text;
314 /** Where the label will be positioned horizontally. */
315 private transient int horizontalAlignment = LEADING;
317 /** Where the label text will be placed horizontally relative to the icon. */
318 private transient int horizontalTextPosition = TRAILING;
320 /** Where the label will be positioned vertically. */
321 private transient int verticalAlignment = CENTER;
323 /** Where the label text will be place vertically relative to the icon. */
324 private transient int verticalTextPosition = CENTER;
326 /** The icon painted when the label is enabled. */
327 private transient Icon icon;
329 /** The icon painted when the label is disabled. */
330 private transient Icon disabledIcon;
332 /** The label's mnemnonic key. */
333 private transient int displayedMnemonic = KeyEvent.VK_UNDEFINED;
335 /** The index of the menemonic character in the text. */
336 private transient int displayedMnemonicIndex = -1;
338 /** The gap between the icon and the text. */
339 private transient int iconTextGap = 4;
342 * Creates a new vertically centered, horizontally on the leading edge
343 * JLabel object with text and no icon.
345 public JLabel()
347 this("", null, LEADING);
351 * Creates a new vertically and horizontally centered
352 * JLabel object with no text and the given icon.
354 * @param image The icon to use with the label.
356 public JLabel(Icon image)
358 this("", image, CENTER);
362 * Creates a new vertically centered JLabel object with no text and the
363 * given icon and horizontal alignment. By default, the text is TRAILING
364 * the image.
366 * @param image The icon to use with the label.
367 * @param horizontalAlignment The horizontal alignment of the label.
369 public JLabel(Icon image, int horizontalAlignment)
371 this("", image, horizontalAlignment);
375 * Creates a new horizontally leading and vertically centered JLabel
376 * object with no icon and the given text.
378 * @param text The text to use with the label.
380 public JLabel(String text)
382 this(text, null, LEADING);
386 * Creates a new vertically centered JLabel object with no icon and the
387 * given text and horizontal alignment.
389 * @param text The text to use with the label.
390 * @param horizontalAlignment The horizontal alignment of the label.
392 public JLabel(String text, int horizontalAlignment)
394 this(text, null, horizontalAlignment);
398 * Creates a new vertically centered JLabel object with the given text,
399 * icon, and horizontal alignment.
401 * @param text The text to use with the label.
402 * @param icon The icon to use with the label.
403 * @param horizontalAlignment The horizontal alignment of the label.
405 public JLabel(String text, Icon icon, int horizontalAlignment)
407 this.text = text;
408 this.icon = icon;
409 this.horizontalAlignment = horizontalAlignment;
410 setAlignmentX(0.0F);
411 updateUI();
415 * This method returns the label's UI delegate.
417 * @return The label's UI delegate.
419 public LabelUI getUI()
421 return (LabelUI) ui;
425 * This method sets the label's UI delegate.
427 * @param ui The label's UI delegate.
429 public void setUI(LabelUI ui)
431 super.setUI(ui);
435 * This method resets the label's UI delegate to the default UI for the
436 * current look and feel.
438 public void updateUI()
440 setUI((LabelUI) UIManager.getUI(this));
444 * This method returns a name to identify which look and feel class will be
445 * the UI delegate for this label.
447 * @return The UIClass identifier. "LabelUI"
449 public String getUIClassID()
451 return "LabelUI";
455 * This method is used primarily for debugging purposes and returns a string
456 * that can be used to represent this label.
458 * @return A string to represent this label.
460 protected String paramString()
462 return super.paramString();
466 * This method returns the label text.
468 * @return The label text.
470 public String getText()
472 return text;
476 * This method changes the "text" property. The given text will be painted
477 * in the label.
479 * @param newText The label's text.
481 public void setText(String newText)
483 if (text != newText)
485 String oldText = text;
486 text = newText;
487 firePropertyChange("text", oldText, newText);
489 if (text != null && text.length() <= displayedMnemonicIndex)
490 setDisplayedMnemonicIndex(text.length() - 1);
491 revalidate();
492 repaint();
497 * This method returns the active icon. The active icon is painted when the
498 * label is enabled.
500 * @return The active icon.
502 public Icon getIcon()
504 return icon;
508 * This method changes the "icon" property. This icon (the active icon) will
509 * be the one displayed when the label is enabled.
511 * @param newIcon The active icon.
513 public void setIcon(Icon newIcon)
515 if (icon != newIcon)
517 Icon oldIcon = icon;
518 icon = newIcon;
519 firePropertyChange("icon", oldIcon, newIcon);
520 repaint();
525 * This method returns the disabled icon. The disabled icon is painted when
526 * the label is disabled. If the disabled icon is null and the active icon
527 * is an ImageIcon, this method returns a grayed version of the icon. The
528 * grayed version of the icon becomes the disabledIcon.
530 * @return The disabled icon.
532 public Icon getDisabledIcon()
534 if (disabledIcon == null && icon instanceof ImageIcon)
535 disabledIcon = new ImageIcon(GrayFilter.createDisabledImage(((ImageIcon) icon)
536 .getImage()));
538 return disabledIcon;
542 * This method changes the "disabledIcon" property. This icon (the disabled
543 * icon) will be the one displayed when the label is disabled.
545 * @param newIcon The disabled icon.
547 public void setDisabledIcon(Icon newIcon)
549 if (disabledIcon != newIcon)
551 Icon oldIcon = disabledIcon;
552 disabledIcon = newIcon;
553 firePropertyChange("disabledIcon", oldIcon, newIcon);
558 * This method sets the keycode that will be the label's mnemonic. If the
559 * label is used as a label for another component, the label will give
560 * focus to that component when the mnemonic is activated.
562 * @param mnemonic The keycode to use for the mnemonic.
564 public void setDisplayedMnemonic(int mnemonic)
566 if (displayedMnemonic != mnemonic)
568 firePropertyChange("displayedMnemonic",
569 displayedMnemonic, mnemonic);
570 displayedMnemonic = mnemonic;
572 if (text != null)
573 setDisplayedMnemonicIndex(text.toUpperCase().indexOf(mnemonic));
578 * This method sets the character that will be the mnemonic used. If the
579 * label is used as a label for another component, the label will give
580 * focus to that component when the mnemonic is activated.
582 * @param mnemonic The character to use for the mnemonic.
584 public void setDisplayedMnemonic(char mnemonic)
586 setDisplayedMnemonic((int) Character.toUpperCase(mnemonic));
590 * This method returns the keycode that is used for the label's mnemonic.
592 * @return The keycode that is used for the label's mnemonic.
594 public int getDisplayedMnemonic()
596 return (int) displayedMnemonic;
600 * This method sets which character in the text will be the underlined
601 * character. If the given index is -1, then this indicates that there is
602 * no mnemonic. If the index is less than -1 or if the index is equal to
603 * the length, this method will throw an IllegalArgumentException.
605 * @param newIndex The index of the character to underline.
607 * @throws IllegalArgumentException If index less than -1 or index equals
608 * length.
610 public void setDisplayedMnemonicIndex(int newIndex)
611 throws IllegalArgumentException
613 if (newIndex < -1 || (text != null && newIndex >= text.length()))
614 throw new IllegalArgumentException();
616 if (newIndex == -1
617 || text == null
618 || text.charAt(newIndex) != displayedMnemonic)
619 newIndex = -1;
621 if (newIndex != displayedMnemonicIndex)
623 int oldIndex = displayedMnemonicIndex;
624 displayedMnemonicIndex = newIndex;
625 firePropertyChange("displayedMnemonicIndex",
626 oldIndex, newIndex);
631 * This method returns which character in the text will be the underlined
632 * character.
634 * @return The index of the character that will be underlined.
636 public int getDisplayedMnemonicIndex()
638 return displayedMnemonicIndex;
642 * This method ensures that the key is valid as a horizontal alignment.
643 * Valid keys are: LEFT, CENTER, RIGHT, LEADING, TRAILING
645 * @param key The key to check.
646 * @param message The message of the exception to be thrown if the key is
647 * invalid.
649 * @return The key if it's valid.
651 * @throws IllegalArgumentException If the key is invalid.
653 protected int checkHorizontalKey(int key, String message)
655 if (key != LEFT && key != CENTER && key != RIGHT && key != LEADING
656 && key != TRAILING)
657 throw new IllegalArgumentException(message);
658 else
659 return key;
663 * This method ensures that the key is valid as a vertical alignment. Valid
664 * keys are: TOP, CENTER, and BOTTOM.
666 * @param key The key to check.
667 * @param message The message of the exception to be thrown if the key is
668 * invalid.
670 * @return The key if it's valid.
672 * @throws IllegalArgumentException If the key is invalid.
674 protected int checkVerticalKey(int key, String message)
676 if (key != TOP && key != BOTTOM && key != CENTER)
677 throw new IllegalArgumentException(message);
678 else
679 return key;
683 * This method returns the gap between the icon and the text.
685 * @return The gap between the icon and the text.
687 public int getIconTextGap()
689 return iconTextGap;
693 * This method changes the "iconTextGap" property. The iconTextGap
694 * determines how much space there is between the icon and the text.
696 * @param newGap The gap between the icon and the text.
698 public void setIconTextGap(int newGap)
700 if (iconTextGap != newGap)
702 firePropertyChange("iconTextGap", iconTextGap, newGap);
703 iconTextGap = newGap;
708 * This method returns the vertical alignment of the label.
710 * @return The vertical alignment of the label.
712 public int getVerticalAlignment()
714 return verticalAlignment;
718 * This method changes the "verticalAlignment" property of the label. The
719 * vertical alignment determines how where the label will be placed
720 * vertically. If the alignment is not valid, it will default to the
721 * center.
723 * @param alignment The vertical alignment of the label.
725 public void setVerticalAlignment(int alignment)
727 if (alignment == verticalAlignment)
728 return;
730 int oldAlignment = verticalAlignment;
731 verticalAlignment = checkVerticalKey(alignment, "verticalAlignment");
732 firePropertyChange("verticalAlignment", oldAlignment, verticalAlignment);
736 * This method returns the horziontal alignment of the label.
738 * @return The horizontal alignment of the label.
740 public int getHorizontalAlignment()
742 return horizontalAlignment;
746 * This method changes the "horizontalAlignment" property. The horizontal
747 * alignment determines where the label will be placed horizontally.
749 * @param alignment The horizontal alignment of the label.
751 public void setHorizontalAlignment(int alignment)
753 if (horizontalAlignment == alignment)
754 return;
756 int oldAlignment = horizontalAlignment;
757 horizontalAlignment = checkHorizontalKey(alignment, "horizontalAlignment");
758 firePropertyChange("horizontalAlignment", oldAlignment,
759 horizontalAlignment);
763 * This method returns the vertical text position of the label.
765 * @return The vertical text position of the label.
767 public int getVerticalTextPosition()
769 return verticalTextPosition;
773 * This method changes the "verticalTextPosition" property of the label. The
774 * vertical text position determines where the text will be placed
775 * vertically relative to the icon.
777 * @param textPosition The vertical text position.
779 public void setVerticalTextPosition(int textPosition)
781 if (textPosition != verticalTextPosition)
783 int oldPos = verticalTextPosition;
784 verticalTextPosition = checkVerticalKey(textPosition,
785 "verticalTextPosition");
786 firePropertyChange("verticalTextPosition", oldPos,
787 verticalTextPosition);
792 * This method returns the horizontal text position of the label.
794 * @return The horizontal text position.
796 public int getHorizontalTextPosition()
798 return horizontalTextPosition;
802 * This method changes the "horizontalTextPosition" property of the label.
803 * The horizontal text position determines where the text will be placed
804 * horizontally relative to the icon.
806 * @param textPosition The horizontal text position.
808 public void setHorizontalTextPosition(int textPosition)
810 if (textPosition != horizontalTextPosition)
812 int oldPos = horizontalTextPosition;
813 horizontalTextPosition = checkHorizontalKey(textPosition,
814 "horizontalTextPosition");
815 firePropertyChange("horizontalTextPosition", oldPos,
816 horizontalTextPosition);
821 * This method simply returns false if the current icon image (current icon
822 * will depend on whether the label is enabled) is not equal to the passed
823 * in image.
825 * @param img The image to check.
826 * @param infoflags The bitwise inclusive OR of ABORT, ALLBITS, ERROR,
827 * FRAMEBITS, HEIGHT, PROPERTIES, SOMEBITS, and WIDTH
828 * @param x The x position
829 * @param y The y position
830 * @param w The width
831 * @param h The height
833 * @return Whether the current icon image is equal to the image given.
835 public boolean imageUpdate(Image img, int infoflags, int x, int y, int w,
836 int h)
838 Icon currIcon = isEnabled() ? icon : disabledIcon;
840 // XXX: Is this the correct way to check for image equality?
841 if (currIcon != null && currIcon instanceof ImageIcon)
842 return (((ImageIcon) currIcon).getImage() == img);
844 return false;
848 * This method returns the component that the label gives focus to when the
849 * mnemonic is activated.
851 * @return The component that gets focus when the label's mnemonic is
852 * activated.
854 public Component getLabelFor()
856 return labelFor;
860 * This method changes the "labelFor" property. The component that the label
861 * is acting as a label for will request focus when the label's mnemonic
862 * is activated.
864 * @param c The component that gets focus when the label's mnemonic is
865 * activated.
867 public void setLabelFor(Component c)
869 if (c != labelFor)
871 // We put the label into the client properties for the labeled
872 // component so that it can be read by the AccessibleJComponent.
873 // The other option would be to reserve a default visible field
874 // in JComponent, but since this is relativly seldomly used, it
875 // would be unnecessary waste of memory to do so.
876 Component oldLabelFor = labelFor;
877 if (oldLabelFor instanceof JComponent)
879 ((JComponent) oldLabelFor).putClientProperty(LABEL_PROPERTY, null);
882 labelFor = c;
883 if (labelFor instanceof JComponent)
885 ((JComponent) labelFor).putClientProperty(LABEL_PROPERTY, this);
888 firePropertyChange("labelFor", oldLabelFor, labelFor);
893 * This method overrides setFont so that we can call for a repaint after the
894 * font is changed.
896 * @param f The font for this label.
898 public void setFont(Font f)
900 super.setFont(f);
901 repaint();
905 * DOCUMENT ME!
907 * @return The accessible context.
909 public AccessibleContext getAccessibleContext()
911 if (accessibleContext == null)
912 accessibleContext = new AccessibleJLabel();
913 return accessibleContext;