/* * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.swing; import java.awt.Component; import java.awt.Font; import java.awt.Image; import java.awt.*; import java.text.*; import java.awt.geom.*; import java.beans.Transient; import java.io.ObjectOutputStream; import java.io.ObjectInputStream; import java.io.IOException; import javax.swing.plaf.LabelUI; import javax.accessibility.*; import javax.swing.text.*; import javax.swing.text.html.*; import javax.swing.plaf.basic.*; import java.util.*; /** * A display area for a short text string or an image, * or both. * A label does not react to input events. * As a result, it cannot get the keyboard focus. * A label can, however, display a keyboard alternative * as a convenience for a nearby component * that has a keyboard alternative but can't display it. *
* A JLabel
object can display
* either text, an image, or both.
* You can specify where in the label's display area
* the label's contents are aligned
* by setting the vertical and horizontal alignment.
* By default, labels are vertically centered
* in their display area.
* Text-only labels are leading edge aligned, by default;
* image-only labels are horizontally centered, by default.
*
* You can also specify the position of the text * relative to the image. * By default, text is on the trailing edge of the image, * with the text and image vertically aligned. *
* A label's leading and trailing edge are determined from the value of its * {@link java.awt.ComponentOrientation} property. At present, the default * ComponentOrientation setting maps the leading edge to left and the trailing * edge to right. * *
* Finally, you can use the setIconTextGap
method
* to specify how many pixels
* should appear between the text and the image.
* The default is 4 pixels.
*
* See How to Use Labels * in The Java Tutorial * for further documentation. *
* Warning: Swing is not thread safe. For more * information see Swing's Threading * Policy. *
* Warning:
* Serialized objects of this class will not be compatible with
* future Swing releases. The current serialization support is
* appropriate for short term storage or RMI between applications running
* the same version of Swing. As of 1.4, support for long term storage
* of all JavaBeansTM
* has been added to the java.beans
package.
* Please see {@link java.beans.XMLEncoder}.
*
* @beaninfo
* attribute: isContainer false
* description: A component that displays a short string and an icon.
*
* @author Hans Muller
*/
public class JLabel extends JComponent implements SwingConstants, Accessible
{
/**
* @see #getUIClassID
* @see #readObject
*/
private static final String uiClassID = "LabelUI";
private int mnemonic = '\0';
private int mnemonicIndex = -1;
private String text = ""; // "" rather than null, for BeanBox
private Icon defaultIcon = null;
private Icon disabledIcon = null;
private boolean disabledIconSet = false;
private int verticalAlignment = CENTER;
private int horizontalAlignment = LEADING;
private int verticalTextPosition = CENTER;
private int horizontalTextPosition = TRAILING;
private int iconTextGap = 4;
protected Component labelFor = null;
/**
* Client property key used to determine what label is labeling the
* component. This is generally not used by labels, but is instead
* used by components such as text areas that are being labeled by
* labels. When the labelFor property of a label is set, it will
* automatically set the LABELED_BY_PROPERTY of the component being
* labelled.
*
* @see #setLabelFor
*/
static final String LABELED_BY_PROPERTY = "labeledBy";
/**
* Creates a JLabel
instance with the specified
* text, image, and horizontal alignment.
* The label is centered vertically in its display area.
* The text is on the trailing edge of the image.
*
* @param text The text to be displayed by the label.
* @param icon The image to be displayed by the label.
* @param horizontalAlignment One of the following constants
* defined in SwingConstants
:
* LEFT
,
* CENTER
,
* RIGHT
,
* LEADING
or
* TRAILING
.
*/
public JLabel(String text, Icon icon, int horizontalAlignment) {
setText(text);
setIcon(icon);
setHorizontalAlignment(horizontalAlignment);
updateUI();
setAlignmentX(LEFT_ALIGNMENT);
}
/**
* Creates a JLabel
instance with the specified
* text and horizontal alignment.
* The label is centered vertically in its display area.
*
* @param text The text to be displayed by the label.
* @param horizontalAlignment One of the following constants
* defined in SwingConstants
:
* LEFT
,
* CENTER
,
* RIGHT
,
* LEADING
or
* TRAILING
.
*/
public JLabel(String text, int horizontalAlignment) {
this(text, null, horizontalAlignment);
}
/**
* Creates a JLabel
instance with the specified text.
* The label is aligned against the leading edge of its display area,
* and centered vertically.
*
* @param text The text to be displayed by the label.
*/
public JLabel(String text) {
this(text, null, LEADING);
}
/**
* Creates a JLabel
instance with the specified
* image and horizontal alignment.
* The label is centered vertically in its display area.
*
* @param image The image to be displayed by the label.
* @param horizontalAlignment One of the following constants
* defined in SwingConstants
:
* LEFT
,
* CENTER
,
* RIGHT
,
* LEADING
or
* TRAILING
.
*/
public JLabel(Icon image, int horizontalAlignment) {
this(null, image, horizontalAlignment);
}
/**
* Creates a JLabel
instance with the specified image.
* The label is centered vertically and horizontally
* in its display area.
*
* @param image The image to be displayed by the label.
*/
public JLabel(Icon image) {
this(null, image, CENTER);
}
/**
* Creates a JLabel
instance with
* no image and with an empty string for the title.
* The label is centered vertically
* in its display area.
* The label's contents, once set, will be displayed on the leading edge
* of the label's display area.
*/
public JLabel() {
this("", null, LEADING);
}
/**
* Returns the L&F object that renders this component.
*
* @return LabelUI object
*/
public LabelUI getUI() {
return (LabelUI)ui;
}
/**
* Sets the L&F object that renders this component.
*
* @param ui the LabelUI L&F object
* @see UIDefaults#getUI
* @beaninfo
* bound: true
* hidden: true
* attribute: visualUpdate true
* description: The UI object that implements the Component's LookAndFeel.
*/
public void setUI(LabelUI ui) {
super.setUI(ui);
// disabled icon is generated by LF so it should be unset here
if (!disabledIconSet && disabledIcon != null) {
setDisabledIcon(null);
}
}
/**
* Resets the UI property to a value from the current look and feel.
*
* @see JComponent#updateUI
*/
public void updateUI() {
setUI((LabelUI)UIManager.getUI(this));
}
/**
* Returns a string that specifies the name of the l&f class
* that renders this component.
*
* @return String "LabelUI"
*
* @see JComponent#getUIClassID
* @see UIDefaults#getUI
*/
public String getUIClassID() {
return uiClassID;
}
/**
* Returns the text string that the label displays.
*
* @return a String
* @see #setText
*/
public String getText() {
return text;
}
/**
* Defines the single line of text this component will display. If
* the value of text is null or empty string, nothing is displayed.
*
* The default value of this property is null. *
* This is a JavaBeans bound property. * * @see #setVerticalTextPosition * @see #setHorizontalTextPosition * @see #setIcon * @beaninfo * preferred: true * bound: true * attribute: visualUpdate true * description: Defines the single line of text this component will display. */ public void setText(String text) { String oldAccessibleName = null; if (accessibleContext != null) { oldAccessibleName = accessibleContext.getAccessibleName(); } String oldValue = this.text; this.text = text; firePropertyChange("text", oldValue, text); setDisplayedMnemonicIndex( SwingUtilities.findDisplayedMnemonicIndex( text, getDisplayedMnemonic())); if ((accessibleContext != null) && (accessibleContext.getAccessibleName() != oldAccessibleName)) { accessibleContext.firePropertyChange( AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY, oldAccessibleName, accessibleContext.getAccessibleName()); } if (text == null || oldValue == null || !text.equals(oldValue)) { revalidate(); repaint(); } } /** * Returns the graphic image (glyph, icon) that the label displays. * * @return an Icon * @see #setIcon */ public Icon getIcon() { return defaultIcon; } /** * Defines the icon this component will display. If * the value of icon is null, nothing is displayed. *
* The default value of this property is null. *
* This is a JavaBeans bound property. * * @see #setVerticalTextPosition * @see #setHorizontalTextPosition * @see #getIcon * @beaninfo * preferred: true * bound: true * attribute: visualUpdate true * description: The icon this component will display. */ public void setIcon(Icon icon) { Icon oldValue = defaultIcon; defaultIcon = icon; /* If the default icon has really changed and we had * generated the disabled icon for this component * (in other words, setDisabledIcon() was never called), then * clear the disabledIcon field. */ if ((defaultIcon != oldValue) && !disabledIconSet) { disabledIcon = null; } firePropertyChange("icon", oldValue, defaultIcon); if ((accessibleContext != null) && (oldValue != defaultIcon)) { accessibleContext.firePropertyChange( AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY, oldValue, defaultIcon); } /* If the default icon has changed and the new one is * a different size, then revalidate. Repaint if the * default icon has changed. */ if (defaultIcon != oldValue) { if ((defaultIcon == null) || (oldValue == null) || (defaultIcon.getIconWidth() != oldValue.getIconWidth()) || (defaultIcon.getIconHeight() != oldValue.getIconHeight())) { revalidate(); } repaint(); } } /** * Returns the icon used by the label when it's disabled. * If no disabled icon has been set this will forward the call to * the look and feel to construct an appropriate disabled Icon. *
* Some look and feels might not render the disabled Icon, in which
* case they will ignore this.
*
* @return the disabledIcon
property
* @see #setDisabledIcon
* @see javax.swing.LookAndFeel#getDisabledIcon
* @see ImageIcon
*/
@Transient
public Icon getDisabledIcon() {
if (!disabledIconSet && disabledIcon == null && defaultIcon != null) {
disabledIcon = UIManager.getLookAndFeel().getDisabledIcon(this, defaultIcon);
if (disabledIcon != null) {
firePropertyChange("disabledIcon", null, disabledIcon);
}
}
return disabledIcon;
}
/**
* Set the icon to be displayed if this JLabel is "disabled"
* (JLabel.setEnabled(false)).
*
* The default value of this property is null. * * @param disabledIcon the Icon to display when the component is disabled * @see #getDisabledIcon * @see #setEnabled * @beaninfo * bound: true * attribute: visualUpdate true * description: The icon to display if the label is disabled. */ public void setDisabledIcon(Icon disabledIcon) { Icon oldValue = this.disabledIcon; this.disabledIcon = disabledIcon; disabledIconSet = (disabledIcon != null); firePropertyChange("disabledIcon", oldValue, disabledIcon); if (disabledIcon != oldValue) { if (disabledIcon == null || oldValue == null || disabledIcon.getIconWidth() != oldValue.getIconWidth() || disabledIcon.getIconHeight() != oldValue.getIconHeight()) { revalidate(); } if (!isEnabled()) { repaint(); } } } /** * Specify a keycode that indicates a mnemonic key. * This property is used when the label is part of a larger component. * If the labelFor property of the label is not null, the label will * call the requestFocus method of the component specified by the * labelFor property when the mnemonic is activated. * * @see #getLabelFor * @see #setLabelFor * @beaninfo * bound: true * attribute: visualUpdate true * description: The mnemonic keycode. */ public void setDisplayedMnemonic(int key) { int oldKey = mnemonic; mnemonic = key; firePropertyChange("displayedMnemonic", oldKey, mnemonic); setDisplayedMnemonicIndex( SwingUtilities.findDisplayedMnemonicIndex(getText(), mnemonic)); if (key != oldKey) { revalidate(); repaint(); } } /** * Specifies the displayedMnemonic as a char value. * * @param aChar a char specifying the mnemonic to display * @see #setDisplayedMnemonic(int) */ public void setDisplayedMnemonic(char aChar) { int vk = java.awt.event.KeyEvent.getExtendedKeyCodeForChar(aChar); if (vk != java.awt.event.KeyEvent.VK_UNDEFINED) { setDisplayedMnemonic(vk); } } /** * Return the keycode that indicates a mnemonic key. * This property is used when the label is part of a larger component. * If the labelFor property of the label is not null, the label will * call the requestFocus method of the component specified by the * labelFor property when the mnemonic is activated. * * @return int value for the mnemonic key * * @see #getLabelFor * @see #setLabelFor */ public int getDisplayedMnemonic() { return mnemonic; } /** * Provides a hint to the look and feel as to which character in the * text should be decorated to represent the mnemonic. Not all look and * feels may support this. A value of -1 indicates either there is no * mnemonic, the mnemonic character is not contained in the string, or * the developer does not wish the mnemonic to be displayed. *
* The value of this is updated as the properties relating to the
* mnemonic change (such as the mnemonic itself, the text...).
* You should only ever have to call this if
* you do not wish the default character to be underlined. For example, if
* the text was 'Save As', with a mnemonic of 'a', and you wanted the 'A'
* to be decorated, as 'Save As', you would have to invoke
* setDisplayedMnemonicIndex(5)
after invoking
* setDisplayedMnemonic(KeyEvent.VK_A)
.
*
* @since 1.4
* @param index Index into the String to underline
* @exception IllegalArgumentException will be thrown if index
= length of the text, or < -1
*
* @beaninfo
* bound: true
* attribute: visualUpdate true
* description: the index into the String to draw the keyboard character
* mnemonic at
*/
public void setDisplayedMnemonicIndex(int index)
throws IllegalArgumentException {
int oldValue = mnemonicIndex;
if (index == -1) {
mnemonicIndex = -1;
} else {
String text = getText();
int textLength = (text == null) ? 0 : text.length();
if (index < -1 || index >= textLength) { // index out of range
throw new IllegalArgumentException("index == " + index);
}
}
mnemonicIndex = index;
firePropertyChange("displayedMnemonicIndex", oldValue, index);
if (index != oldValue) {
revalidate();
repaint();
}
}
/**
* Returns the character, as an index, that the look and feel should
* provide decoration for as representing the mnemonic character.
*
* @since 1.4
* @return index representing mnemonic character
* @see #setDisplayedMnemonicIndex
*/
public int getDisplayedMnemonicIndex() {
return mnemonicIndex;
}
/**
* Verify that key is a legal value for the horizontalAlignment properties.
*
* @param key the property value to check
* @param message the IllegalArgumentException detail message
* @exception IllegalArgumentException if key isn't LEFT, CENTER, RIGHT,
* LEADING or TRAILING.
* @see #setHorizontalTextPosition
* @see #setHorizontalAlignment
*/
protected int checkHorizontalKey(int key, String message) {
if ((key == LEFT) ||
(key == CENTER) ||
(key == RIGHT) ||
(key == LEADING) ||
(key == TRAILING)) {
return key;
}
else {
throw new IllegalArgumentException(message);
}
}
/**
* Verify that key is a legal value for the
* verticalAlignment or verticalTextPosition properties.
*
* @param key the property value to check
* @param message the IllegalArgumentException detail message
* @exception IllegalArgumentException if key isn't TOP, CENTER, or BOTTOM.
* @see #setVerticalAlignment
* @see #setVerticalTextPosition
*/
protected int checkVerticalKey(int key, String message) {
if ((key == TOP) || (key == CENTER) || (key == BOTTOM)) {
return key;
}
else {
throw new IllegalArgumentException(message);
}
}
/**
* Returns the amount of space between the text and the icon
* displayed in this label.
*
* @return an int equal to the number of pixels between the text
* and the icon.
* @see #setIconTextGap
*/
public int getIconTextGap() {
return iconTextGap;
}
/**
* If both the icon and text properties are set, this property
* defines the space between them.
*
* The default value of this property is 4 pixels. *
* This is a JavaBeans bound property.
*
* @see #getIconTextGap
* @beaninfo
* bound: true
* attribute: visualUpdate true
* description: If both the icon and text properties are set, this
* property defines the space between them.
*/
public void setIconTextGap(int iconTextGap) {
int oldValue = this.iconTextGap;
this.iconTextGap = iconTextGap;
firePropertyChange("iconTextGap", oldValue, iconTextGap);
if (iconTextGap != oldValue) {
revalidate();
repaint();
}
}
/**
* Returns the alignment of the label's contents along the Y axis.
*
* @return The value of the verticalAlignment property, one of the
* following constants defined in SwingConstants
:
* TOP
,
* CENTER
, or
* BOTTOM
.
*
* @see SwingConstants
* @see #setVerticalAlignment
*/
public int getVerticalAlignment() {
return verticalAlignment;
}
/**
* Sets the alignment of the label's contents along the Y axis.
*
* The default value of this property is CENTER.
*
* @param alignment One of the following constants
* defined in SwingConstants
:
* TOP
,
* CENTER
(the default), or
* BOTTOM
.
*
* @see SwingConstants
* @see #getVerticalAlignment
* @beaninfo
* bound: true
* enum: TOP SwingConstants.TOP
* CENTER SwingConstants.CENTER
* BOTTOM SwingConstants.BOTTOM
* attribute: visualUpdate true
* description: The alignment of the label's contents along the Y axis.
*/
public void setVerticalAlignment(int alignment) {
if (alignment == verticalAlignment) return;
int oldValue = verticalAlignment;
verticalAlignment = checkVerticalKey(alignment, "verticalAlignment");
firePropertyChange("verticalAlignment", oldValue, verticalAlignment);
repaint();
}
/**
* Returns the alignment of the label's contents along the X axis.
*
* @return The value of the horizontalAlignment property, one of the
* following constants defined in SwingConstants
:
* LEFT
,
* CENTER
,
* RIGHT
,
* LEADING
or
* TRAILING
.
*
* @see #setHorizontalAlignment
* @see SwingConstants
*/
public int getHorizontalAlignment() {
return horizontalAlignment;
}
/**
* Sets the alignment of the label's contents along the X axis.
*
* This is a JavaBeans bound property.
*
* @param alignment One of the following constants
* defined in SwingConstants
:
* LEFT
,
* CENTER
(the default for image-only labels),
* RIGHT
,
* LEADING
(the default for text-only labels) or
* TRAILING
.
*
* @see SwingConstants
* @see #getHorizontalAlignment
* @beaninfo
* bound: true
* enum: LEFT SwingConstants.LEFT
* CENTER SwingConstants.CENTER
* RIGHT SwingConstants.RIGHT
* LEADING SwingConstants.LEADING
* TRAILING SwingConstants.TRAILING
* attribute: visualUpdate true
* description: The alignment of the label's content along the X axis.
*/
public void setHorizontalAlignment(int alignment) {
if (alignment == horizontalAlignment) return;
int oldValue = horizontalAlignment;
horizontalAlignment = checkHorizontalKey(alignment,
"horizontalAlignment");
firePropertyChange("horizontalAlignment",
oldValue, horizontalAlignment);
repaint();
}
/**
* Returns the vertical position of the label's text,
* relative to its image.
*
* @return One of the following constants
* defined in SwingConstants
:
* TOP
,
* CENTER
, or
* BOTTOM
.
*
* @see #setVerticalTextPosition
* @see SwingConstants
*/
public int getVerticalTextPosition() {
return verticalTextPosition;
}
/**
* Sets the vertical position of the label's text,
* relative to its image.
*
* The default value of this property is CENTER. *
* This is a JavaBeans bound property.
*
* @param textPosition One of the following constants
* defined in SwingConstants
:
* TOP
,
* CENTER
(the default), or
* BOTTOM
.
*
* @see SwingConstants
* @see #getVerticalTextPosition
* @beaninfo
* bound: true
* enum: TOP SwingConstants.TOP
* CENTER SwingConstants.CENTER
* BOTTOM SwingConstants.BOTTOM
* expert: true
* attribute: visualUpdate true
* description: The vertical position of the text relative to it's image.
*/
public void setVerticalTextPosition(int textPosition) {
if (textPosition == verticalTextPosition) return;
int old = verticalTextPosition;
verticalTextPosition = checkVerticalKey(textPosition,
"verticalTextPosition");
firePropertyChange("verticalTextPosition", old, verticalTextPosition);
revalidate();
repaint();
}
/**
* Returns the horizontal position of the label's text,
* relative to its image.
*
* @return One of the following constants
* defined in SwingConstants
:
* LEFT
,
* CENTER
,
* RIGHT
,
* LEADING
or
* TRAILING
.
*
* @see SwingConstants
*/
public int getHorizontalTextPosition() {
return horizontalTextPosition;
}
/**
* Sets the horizontal position of the label's text,
* relative to its image.
*
* @param textPosition One of the following constants
* defined in SwingConstants
:
* LEFT
,
* CENTER
,
* RIGHT
,
* LEADING
, or
* TRAILING
(the default).
* @exception IllegalArgumentException
*
* @see SwingConstants
* @beaninfo
* expert: true
* bound: true
* enum: LEFT SwingConstants.LEFT
* CENTER SwingConstants.CENTER
* RIGHT SwingConstants.RIGHT
* LEADING SwingConstants.LEADING
* TRAILING SwingConstants.TRAILING
* attribute: visualUpdate true
* description: The horizontal position of the label's text,
* relative to its image.
*/
public void setHorizontalTextPosition(int textPosition) {
int old = horizontalTextPosition;
this.horizontalTextPosition = checkHorizontalKey(textPosition,
"horizontalTextPosition");
firePropertyChange("horizontalTextPosition",
old, horizontalTextPosition);
revalidate();
repaint();
}
/**
* This is overridden to return false if the current Icon's Image is
* not equal to the passed in Image img
.
*
* @see java.awt.image.ImageObserver
* @see java.awt.Component#imageUpdate(java.awt.Image, int, int, int, int, int)
*/
public boolean imageUpdate(Image img, int infoflags,
int x, int y, int w, int h) {
// Don't use getDisabledIcon, will trigger creation of icon if icon
// not set.
if (!isShowing() ||
!SwingUtilities.doesIconReferenceImage(getIcon(), img) &&
!SwingUtilities.doesIconReferenceImage(disabledIcon, img)) {
return false;
}
return super.imageUpdate(img, infoflags, x, y, w, h);
}
/**
* See readObject() and writeObject() in JComponent for more
* information about serialization in Swing.
*/
private void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
if (getUIClassID().equals(uiClassID)) {
byte count = JComponent.getWriteObjCounter(this);
JComponent.setWriteObjCounter(this, --count);
if (count == 0 && ui != null) {
ui.installUI(this);
}
}
}
/**
* Returns a string representation of this JLabel. This method
* is intended to be used only for debugging purposes, and the
* content and format of the returned string may vary between
* implementations. The returned string may be empty but may not
* be null
.
*
* @return a string representation of this JLabel.
*/
protected String paramString() {
String textString = (text != null ?
text : "");
String defaultIconString = ((defaultIcon != null)
&& (defaultIcon != this) ?
defaultIcon.toString() : "");
String disabledIconString = ((disabledIcon != null)
&& (disabledIcon != this) ?
disabledIcon.toString() : "");
String labelForString = (labelFor != null ?
labelFor.toString() : "");
String verticalAlignmentString;
if (verticalAlignment == TOP) {
verticalAlignmentString = "TOP";
} else if (verticalAlignment == CENTER) {
verticalAlignmentString = "CENTER";
} else if (verticalAlignment == BOTTOM) {
verticalAlignmentString = "BOTTOM";
} else verticalAlignmentString = "";
String horizontalAlignmentString;
if (horizontalAlignment == LEFT) {
horizontalAlignmentString = "LEFT";
} else if (horizontalAlignment == CENTER) {
horizontalAlignmentString = "CENTER";
} else if (horizontalAlignment == RIGHT) {
horizontalAlignmentString = "RIGHT";
} else if (horizontalAlignment == LEADING) {
horizontalAlignmentString = "LEADING";
} else if (horizontalAlignment == TRAILING) {
horizontalAlignmentString = "TRAILING";
} else horizontalAlignmentString = "";
String verticalTextPositionString;
if (verticalTextPosition == TOP) {
verticalTextPositionString = "TOP";
} else if (verticalTextPosition == CENTER) {
verticalTextPositionString = "CENTER";
} else if (verticalTextPosition == BOTTOM) {
verticalTextPositionString = "BOTTOM";
} else verticalTextPositionString = "";
String horizontalTextPositionString;
if (horizontalTextPosition == LEFT) {
horizontalTextPositionString = "LEFT";
} else if (horizontalTextPosition == CENTER) {
horizontalTextPositionString = "CENTER";
} else if (horizontalTextPosition == RIGHT) {
horizontalTextPositionString = "RIGHT";
} else if (horizontalTextPosition == LEADING) {
horizontalTextPositionString = "LEADING";
} else if (horizontalTextPosition == TRAILING) {
horizontalTextPositionString = "TRAILING";
} else horizontalTextPositionString = "";
return super.paramString() +
",defaultIcon=" + defaultIconString +
",disabledIcon=" + disabledIconString +
",horizontalAlignment=" + horizontalAlignmentString +
",horizontalTextPosition=" + horizontalTextPositionString +
",iconTextGap=" + iconTextGap +
",labelFor=" + labelForString +
",text=" + textString +
",verticalAlignment=" + verticalAlignmentString +
",verticalTextPosition=" + verticalTextPositionString;
}
/**
* --- Accessibility Support ---
*/
/**
* Get the component this is labelling.
*
* @return the Component this is labelling. Can be null if this
* does not label a Component. If the displayedMnemonic
* property is set and the labelFor property is also set, the label
* will call the requestFocus method of the component specified by the
* labelFor property when the mnemonic is activated.
*
* @see #getDisplayedMnemonic
* @see #setDisplayedMnemonic
*/
public Component getLabelFor() {
return labelFor;
}
/**
* Set the component this is labelling. Can be null if this does not
* label a Component. If the displayedMnemonic property is set
* and the labelFor property is also set, the label will
* call the requestFocus method of the component specified by the
* labelFor property when the mnemonic is activated.
*
* @param c the Component this label is for, or null if the label is
* not the label for a component
*
* @see #getDisplayedMnemonic
* @see #setDisplayedMnemonic
*
* @beaninfo
* bound: true
* description: The component this is labelling.
*/
public void setLabelFor(Component c) {
Component oldC = labelFor;
labelFor = c;
firePropertyChange("labelFor", oldC, c);
if (oldC instanceof JComponent) {
((JComponent)oldC).putClientProperty(LABELED_BY_PROPERTY, null);
}
if (c instanceof JComponent) {
((JComponent)c).putClientProperty(LABELED_BY_PROPERTY, this);
}
}
/**
* Get the AccessibleContext of this object
*
* @return the AccessibleContext of this object
* @beaninfo
* expert: true
* description: The AccessibleContext associated with this Label.
*/
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleJLabel();
}
return accessibleContext;
}
/**
* The class used to obtain the accessible role for this object.
*
* Warning:
* Serialized objects of this class will not be compatible with
* future Swing releases. The current serialization support is
* appropriate for short term storage or RMI between applications running
* the same version of Swing. As of 1.4, support for long term storage
* of all JavaBeansTM
* has been added to the java.beans
package.
* Please see {@link java.beans.XMLEncoder}.
*/
protected class AccessibleJLabel extends AccessibleJComponent
implements AccessibleText, AccessibleExtendedComponent {
/**
* Get the accessible name of this object.
*
* @return the localized name of the object -- can be null if this
* object does not have a name
* @see AccessibleContext#setAccessibleName
*/
public String getAccessibleName() {
String name = accessibleName;
if (name == null) {
name = (String)getClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY);
}
if (name == null) {
name = JLabel.this.getText();
}
if (name == null) {
name = super.getAccessibleName();
}
return name;
}
/**
* Get the role of this object.
*
* @return an instance of AccessibleRole describing the role of the
* object
* @see AccessibleRole
*/
public AccessibleRole getAccessibleRole() {
return AccessibleRole.LABEL;
}
/**
* Get the AccessibleIcons associated with this object if one
* or more exist. Otherwise return null.
* @since 1.3
*/
public AccessibleIcon [] getAccessibleIcon() {
Icon icon = getIcon();
if (icon instanceof Accessible) {
AccessibleContext ac =
((Accessible)icon).getAccessibleContext();
if (ac != null && ac instanceof AccessibleIcon) {
return new AccessibleIcon[] { (AccessibleIcon)ac };
}
}
return null;
}
/**
* Get the AccessibleRelationSet associated with this object if one
* exists. Otherwise return null.
* @see AccessibleRelation
* @since 1.3
*/
public AccessibleRelationSet getAccessibleRelationSet() {
// Check where the AccessibleContext's relation
// set already contains a LABEL_FOR relation.
AccessibleRelationSet relationSet
= super.getAccessibleRelationSet();
if (!relationSet.contains(AccessibleRelation.LABEL_FOR)) {
Component c = JLabel.this.getLabelFor();
if (c != null) {
AccessibleRelation relation
= new AccessibleRelation(AccessibleRelation.LABEL_FOR);
relation.setTarget(c);
relationSet.add(relation);
}
}
return relationSet;
}
/* AccessibleText ---------- */
public AccessibleText getAccessibleText() {
View view = (View)JLabel.this.getClientProperty("html");
if (view != null) {
return this;
} else {
return null;
}
}
/**
* Given a point in local coordinates, return the zero-based index
* of the character under that Point. If the point is invalid,
* this method returns -1.
*
* @param p the Point in local coordinates
* @return the zero-based index of the character under Point p; if
* Point is invalid returns -1.
* @since 1.3
*/
public int getIndexAtPoint(Point p) {
View view = (View) JLabel.this.getClientProperty("html");
if (view != null) {
Rectangle r = getTextRectangle();
if (r == null) {
return -1;
}
Rectangle2D.Float shape =
new Rectangle2D.Float(r.x, r.y, r.width, r.height);
Position.Bias bias[] = new Position.Bias[1];
return view.viewToModel(p.x, p.y, shape, bias);
} else {
return -1;
}
}
/**
* Determine the bounding box of the character at the given
* index into the string. The bounds are returned in local
* coordinates. If the index is invalid an empty rectangle is
* returned.
*
* @param i the index into the String
* @return the screen coordinates of the character's the bounding box,
* if index is invalid returns an empty rectangle.
* @since 1.3
*/
public Rectangle getCharacterBounds(int i) {
View view = (View) JLabel.this.getClientProperty("html");
if (view != null) {
Rectangle r = getTextRectangle();
if (r == null) {
return null;
}
Rectangle2D.Float shape =
new Rectangle2D.Float(r.x, r.y, r.width, r.height);
try {
Shape charShape =
view.modelToView(i, shape, Position.Bias.Forward);
return charShape.getBounds();
} catch (BadLocationException e) {
return null;
}
} else {
return null;
}
}
/**
* Return the number of characters (valid indicies)
*
* @return the number of characters
* @since 1.3
*/
public int getCharCount() {
View view = (View) JLabel.this.getClientProperty("html");
if (view != null) {
Document d = view.getDocument();
if (d instanceof StyledDocument) {
StyledDocument doc = (StyledDocument)d;
return doc.getLength();
}
}
return accessibleContext.getAccessibleName().length();
}
/**
* Return the zero-based offset of the caret.
*
* Note: That to the right of the caret will have the same index
* value as the offset (the caret is between two characters).
* @return the zero-based offset of the caret.
* @since 1.3
*/
public int getCaretPosition() {
// There is no caret.
return -1;
}
/**
* Returns the String at a given index.
*
* @param part the AccessibleText.CHARACTER, AccessibleText.WORD,
* or AccessibleText.SENTENCE to retrieve
* @param index an index within the text >= 0
* @return the letter, word, or sentence,
* null for an invalid index or part
* @since 1.3
*/
public String getAtIndex(int part, int index) {
if (index < 0 || index >= getCharCount()) {
return null;
}
switch (part) {
case AccessibleText.CHARACTER:
try {
return getText(index, 1);
} catch (BadLocationException e) {
return null;
}
case AccessibleText.WORD:
try {
String s = getText(0, getCharCount());
BreakIterator words = BreakIterator.getWordInstance(getLocale());
words.setText(s);
int end = words.following(index);
return s.substring(words.previous(), end);
} catch (BadLocationException e) {
return null;
}
case AccessibleText.SENTENCE:
try {
String s = getText(0, getCharCount());
BreakIterator sentence =
BreakIterator.getSentenceInstance(getLocale());
sentence.setText(s);
int end = sentence.following(index);
return s.substring(sentence.previous(), end);
} catch (BadLocationException e) {
return null;
}
default:
return null;
}
}
/**
* Returns the String after a given index.
*
* @param part the AccessibleText.CHARACTER, AccessibleText.WORD,
* or AccessibleText.SENTENCE to retrieve
* @param index an index within the text >= 0
* @return the letter, word, or sentence, null for an invalid
* index or part
* @since 1.3
*/
public String getAfterIndex(int part, int index) {
if (index < 0 || index >= getCharCount()) {
return null;
}
switch (part) {
case AccessibleText.CHARACTER:
if (index+1 >= getCharCount()) {
return null;
}
try {
return getText(index+1, 1);
} catch (BadLocationException e) {
return null;
}
case AccessibleText.WORD:
try {
String s = getText(0, getCharCount());
BreakIterator words = BreakIterator.getWordInstance(getLocale());
words.setText(s);
int start = words.following(index);
if (start == BreakIterator.DONE || start >= s.length()) {
return null;
}
int end = words.following(start);
if (end == BreakIterator.DONE || end >= s.length()) {
return null;
}
return s.substring(start, end);
} catch (BadLocationException e) {
return null;
}
case AccessibleText.SENTENCE:
try {
String s = getText(0, getCharCount());
BreakIterator sentence =
BreakIterator.getSentenceInstance(getLocale());
sentence.setText(s);
int start = sentence.following(index);
if (start == BreakIterator.DONE || start > s.length()) {
return null;
}
int end = sentence.following(start);
if (end == BreakIterator.DONE || end > s.length()) {
return null;
}
return s.substring(start, end);
} catch (BadLocationException e) {
return null;
}
default:
return null;
}
}
/**
* Returns the String before a given index.
*
* @param part the AccessibleText.CHARACTER, AccessibleText.WORD,
* or AccessibleText.SENTENCE to retrieve
* @param index an index within the text >= 0
* @return the letter, word, or sentence, null for an invalid index
* or part
* @since 1.3
*/
public String getBeforeIndex(int part, int index) {
if (index < 0 || index > getCharCount()-1) {
return null;
}
switch (part) {
case AccessibleText.CHARACTER:
if (index == 0) {
return null;
}
try {
return getText(index-1, 1);
} catch (BadLocationException e) {
return null;
}
case AccessibleText.WORD:
try {
String s = getText(0, getCharCount());
BreakIterator words = BreakIterator.getWordInstance(getLocale());
words.setText(s);
int end = words.following(index);
end = words.previous();
int start = words.previous();
if (start == BreakIterator.DONE) {
return null;
}
return s.substring(start, end);
} catch (BadLocationException e) {
return null;
}
case AccessibleText.SENTENCE:
try {
String s = getText(0, getCharCount());
BreakIterator sentence =
BreakIterator.getSentenceInstance(getLocale());
sentence.setText(s);
int end = sentence.following(index);
end = sentence.previous();
int start = sentence.previous();
if (start == BreakIterator.DONE) {
return null;
}
return s.substring(start, end);
} catch (BadLocationException e) {
return null;
}
default:
return null;
}
}
/**
* Return the AttributeSet for a given character at a given index
*
* @param i the zero-based index into the text
* @return the AttributeSet of the character
* @since 1.3
*/
public AttributeSet getCharacterAttribute(int i) {
View view = (View) JLabel.this.getClientProperty("html");
if (view != null) {
Document d = view.getDocument();
if (d instanceof StyledDocument) {
StyledDocument doc = (StyledDocument)d;
Element elem = doc.getCharacterElement(i);
if (elem != null) {
return elem.getAttributes();
}
}
}
return null;
}
/**
* Returns the start offset within the selected text.
* If there is no selection, but there is
* a caret, the start and end offsets will be the same.
*
* @return the index into the text of the start of the selection
* @since 1.3
*/
public int getSelectionStart() {
// Text cannot be selected.
return -1;
}
/**
* Returns the end offset within the selected text.
* If there is no selection, but there is
* a caret, the start and end offsets will be the same.
*
* @return the index into teh text of the end of the selection
* @since 1.3
*/
public int getSelectionEnd() {
// Text cannot be selected.
return -1;
}
/**
* Returns the portion of the text that is selected.
*
* @return the String portion of the text that is selected
* @since 1.3
*/
public String getSelectedText() {
// Text cannot be selected.
return null;
}
/*
* Returns the text substring starting at the specified
* offset with the specified length.
*/
private String getText(int offset, int length)
throws BadLocationException {
View view = (View) JLabel.this.getClientProperty("html");
if (view != null) {
Document d = view.getDocument();
if (d instanceof StyledDocument) {
StyledDocument doc = (StyledDocument)d;
return doc.getText(offset, length);
}
}
return null;
}
/*
* Returns the bounding rectangle for the component text.
*/
private Rectangle getTextRectangle() {
String text = JLabel.this.getText();
Icon icon = (JLabel.this.isEnabled()) ? JLabel.this.getIcon() : JLabel.this.getDisabledIcon();
if ((icon == null) && (text == null)) {
return null;
}
Rectangle paintIconR = new Rectangle();
Rectangle paintTextR = new Rectangle();
Rectangle paintViewR = new Rectangle();
Insets paintViewInsets = new Insets(0, 0, 0, 0);
paintViewInsets = JLabel.this.getInsets(paintViewInsets);
paintViewR.x = paintViewInsets.left;
paintViewR.y = paintViewInsets.top;
paintViewR.width = JLabel.this.getWidth() - (paintViewInsets.left + paintViewInsets.right);
paintViewR.height = JLabel.this.getHeight() - (paintViewInsets.top + paintViewInsets.bottom);
String clippedText = SwingUtilities.layoutCompoundLabel(
(JComponent)JLabel.this,
getFontMetrics(getFont()),
text,
icon,
JLabel.this.getVerticalAlignment(),
JLabel.this.getHorizontalAlignment(),
JLabel.this.getVerticalTextPosition(),
JLabel.this.getHorizontalTextPosition(),
paintViewR,
paintIconR,
paintTextR,
JLabel.this.getIconTextGap());
return paintTextR;
}
// ----- AccessibleExtendedComponent
/**
* Returns the AccessibleExtendedComponent
*
* @return the AccessibleExtendedComponent
*/
AccessibleExtendedComponent getAccessibleExtendedComponent() {
return this;
}
/**
* Returns the tool tip text
*
* @return the tool tip text, if supported, of the object;
* otherwise, null
* @since 1.4
*/
public String getToolTipText() {
return JLabel.this.getToolTipText();
}
/**
* Returns the titled border text
*
* @return the titled border text, if supported, of the object;
* otherwise, null
* @since 1.4
*/
public String getTitledBorderText() {
return super.getTitledBorderText();
}
/**
* Returns key bindings associated with this object
*
* @return the key bindings, if supported, of the object;
* otherwise, null
* @see AccessibleKeyBinding
* @since 1.4
*/
public AccessibleKeyBinding getAccessibleKeyBinding() {
int mnemonic = JLabel.this.getDisplayedMnemonic();
if (mnemonic == 0) {
return null;
}
return new LabelKeyBinding(mnemonic);
}
class LabelKeyBinding implements AccessibleKeyBinding {
int mnemonic;
LabelKeyBinding(int mnemonic) {
this.mnemonic = mnemonic;
}
/**
* Returns the number of key bindings for this object
*
* @return the zero-based number of key bindings for this object
*/
public int getAccessibleKeyBindingCount() {
return 1;
}
/**
* Returns a key binding for this object. The value returned is an
* java.lang.Object which must be cast to appropriate type depending
* on the underlying implementation of the key. For example, if the
* Object returned is a javax.swing.KeyStroke, the user of this
* method should do the following:
*
* Component c =