0001 /*
0002 * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
0003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004 *
0005 * This code is free software; you can redistribute it and/or modify it
0006 * under the terms of the GNU General Public License version 2 only, as
0007 * published by the Free Software Foundation. Sun designates this
0008 * particular file as subject to the "Classpath" exception as provided
0009 * by Sun in the LICENSE file that accompanied this code.
0010 *
0011 * This code is distributed in the hope that it will be useful, but WITHOUT
0012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014 * version 2 for more details (a copy is included in the LICENSE file that
0015 * accompanied this code).
0016 *
0017 * You should have received a copy of the GNU General Public License version
0018 * 2 along with this work; if not, write to the Free Software Foundation,
0019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020 *
0021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022 * CA 95054 USA or visit www.sun.com if you need additional information or
0023 * have any questions.
0024 */
0025
0026 package javax.swing;
0027
0028 import java.awt.Component;
0029 import java.awt.Font;
0030 import java.awt.Image;
0031 import java.awt.*;
0032 import java.text.*;
0033 import java.awt.geom.*;
0034
0035 import java.io.ObjectOutputStream;
0036 import java.io.ObjectInputStream;
0037 import java.io.IOException;
0038
0039 import javax.swing.plaf.LabelUI;
0040 import javax.accessibility.*;
0041 import javax.swing.text.*;
0042 import javax.swing.text.html.*;
0043 import javax.swing.plaf.basic.*;
0044 import java.util.*;
0045
0046 /**
0047 * A display area for a short text string or an image,
0048 * or both.
0049 * A label does not react to input events.
0050 * As a result, it cannot get the keyboard focus.
0051 * A label can, however, display a keyboard alternative
0052 * as a convenience for a nearby component
0053 * that has a keyboard alternative but can't display it.
0054 * <p>
0055 * A <code>JLabel</code> object can display
0056 * either text, an image, or both.
0057 * You can specify where in the label's display area
0058 * the label's contents are aligned
0059 * by setting the vertical and horizontal alignment.
0060 * By default, labels are vertically centered
0061 * in their display area.
0062 * Text-only labels are leading edge aligned, by default;
0063 * image-only labels are horizontally centered, by default.
0064 * <p>
0065 * You can also specify the position of the text
0066 * relative to the image.
0067 * By default, text is on the trailing edge of the image,
0068 * with the text and image vertically aligned.
0069 * <p>
0070 * A label's leading and trailing edge are determined from the value of its
0071 * {@link java.awt.ComponentOrientation} property. At present, the default
0072 * ComponentOrientation setting maps the leading edge to left and the trailing
0073 * edge to right.
0074 *
0075 * <p>
0076 * Finally, you can use the <code>setIconTextGap</code> method
0077 * to specify how many pixels
0078 * should appear between the text and the image.
0079 * The default is 4 pixels.
0080 * <p>
0081 * See <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/label.html">How to Use Labels</a>
0082 * in <em>The Java Tutorial</em>
0083 * for further documentation.
0084 * <p>
0085 * <strong>Warning:</strong> Swing is not thread safe. For more
0086 * information see <a
0087 * href="package-summary.html#threading">Swing's Threading
0088 * Policy</a>.
0089 * <p>
0090 * <strong>Warning:</strong>
0091 * Serialized objects of this class will not be compatible with
0092 * future Swing releases. The current serialization support is
0093 * appropriate for short term storage or RMI between applications running
0094 * the same version of Swing. As of 1.4, support for long term storage
0095 * of all JavaBeans<sup><font size="-2">TM</font></sup>
0096 * has been added to the <code>java.beans</code> package.
0097 * Please see {@link java.beans.XMLEncoder}.
0098 *
0099 * @beaninfo
0100 * attribute: isContainer false
0101 * description: A component that displays a short string and an icon.
0102 *
0103 * @version 1.131 05/05/07
0104 * @author Hans Muller
0105 */
0106 public class JLabel extends JComponent implements SwingConstants,
0107 Accessible {
0108 /**
0109 * @see #getUIClassID
0110 * @see #readObject
0111 */
0112 private static final String uiClassID = "LabelUI";
0113
0114 private int mnemonic = '\0';
0115 private int mnemonicIndex = -1;
0116
0117 private String text = ""; // "" rather than null, for BeanBox
0118 private Icon defaultIcon = null;
0119 private Icon disabledIcon = null;
0120 private boolean disabledIconSet = false;
0121
0122 private int verticalAlignment = CENTER;
0123 private int horizontalAlignment = LEADING;
0124 private int verticalTextPosition = CENTER;
0125 private int horizontalTextPosition = TRAILING;
0126 private int iconTextGap = 4;
0127
0128 protected Component labelFor = null;
0129
0130 /**
0131 * Client property key used to determine what label is labeling the
0132 * component. This is generally not used by labels, but is instead
0133 * used by components such as text areas that are being labeled by
0134 * labels. When the labelFor property of a label is set, it will
0135 * automatically set the LABELED_BY_PROPERTY of the component being
0136 * labelled.
0137 *
0138 * @see #setLabelFor
0139 */
0140 static final String LABELED_BY_PROPERTY = "labeledBy";
0141
0142 /**
0143 * Creates a <code>JLabel</code> instance with the specified
0144 * text, image, and horizontal alignment.
0145 * The label is centered vertically in its display area.
0146 * The text is on the trailing edge of the image.
0147 *
0148 * @param text The text to be displayed by the label.
0149 * @param icon The image to be displayed by the label.
0150 * @param horizontalAlignment One of the following constants
0151 * defined in <code>SwingConstants</code>:
0152 * <code>LEFT</code>,
0153 * <code>CENTER</code>,
0154 * <code>RIGHT</code>,
0155 * <code>LEADING</code> or
0156 * <code>TRAILING</code>.
0157 */
0158 public JLabel(String text, Icon icon, int horizontalAlignment) {
0159 setText(text);
0160 setIcon(icon);
0161 setHorizontalAlignment(horizontalAlignment);
0162 updateUI();
0163 setAlignmentX(LEFT_ALIGNMENT);
0164 }
0165
0166 /**
0167 * Creates a <code>JLabel</code> instance with the specified
0168 * text and horizontal alignment.
0169 * The label is centered vertically in its display area.
0170 *
0171 * @param text The text to be displayed by the label.
0172 * @param horizontalAlignment One of the following constants
0173 * defined in <code>SwingConstants</code>:
0174 * <code>LEFT</code>,
0175 * <code>CENTER</code>,
0176 * <code>RIGHT</code>,
0177 * <code>LEADING</code> or
0178 * <code>TRAILING</code>.
0179 */
0180 public JLabel(String text, int horizontalAlignment) {
0181 this (text, null, horizontalAlignment);
0182 }
0183
0184 /**
0185 * Creates a <code>JLabel</code> instance with the specified text.
0186 * The label is aligned against the leading edge of its display area,
0187 * and centered vertically.
0188 *
0189 * @param text The text to be displayed by the label.
0190 */
0191 public JLabel(String text) {
0192 this (text, null, LEADING);
0193 }
0194
0195 /**
0196 * Creates a <code>JLabel</code> instance with the specified
0197 * image and horizontal alignment.
0198 * The label is centered vertically in its display area.
0199 *
0200 * @param image The image to be displayed by the label.
0201 * @param horizontalAlignment One of the following constants
0202 * defined in <code>SwingConstants</code>:
0203 * <code>LEFT</code>,
0204 * <code>CENTER</code>,
0205 * <code>RIGHT</code>,
0206 * <code>LEADING</code> or
0207 * <code>TRAILING</code>.
0208 */
0209 public JLabel(Icon image, int horizontalAlignment) {
0210 this (null, image, horizontalAlignment);
0211 }
0212
0213 /**
0214 * Creates a <code>JLabel</code> instance with the specified image.
0215 * The label is centered vertically and horizontally
0216 * in its display area.
0217 *
0218 * @param image The image to be displayed by the label.
0219 */
0220 public JLabel(Icon image) {
0221 this (null, image, CENTER);
0222 }
0223
0224 /**
0225 * Creates a <code>JLabel</code> instance with
0226 * no image and with an empty string for the title.
0227 * The label is centered vertically
0228 * in its display area.
0229 * The label's contents, once set, will be displayed on the leading edge
0230 * of the label's display area.
0231 */
0232 public JLabel() {
0233 this ("", null, LEADING);
0234 }
0235
0236 /**
0237 * Returns the L&F object that renders this component.
0238 *
0239 * @return LabelUI object
0240 */
0241 public LabelUI getUI() {
0242 return (LabelUI) ui;
0243 }
0244
0245 /**
0246 * Sets the L&F object that renders this component.
0247 *
0248 * @param ui the LabelUI L&F object
0249 * @see UIDefaults#getUI
0250 * @beaninfo
0251 * bound: true
0252 * hidden: true
0253 * attribute: visualUpdate true
0254 * description: The UI object that implements the Component's LookAndFeel.
0255 */
0256 public void setUI(LabelUI ui) {
0257 super .setUI(ui);
0258 // disabled icon is generated by LF so it should be unset here
0259 if (!disabledIconSet && disabledIcon != null) {
0260 setDisabledIcon(null);
0261 }
0262 }
0263
0264 /**
0265 * Resets the UI property to a value from the current look and feel.
0266 *
0267 * @see JComponent#updateUI
0268 */
0269 public void updateUI() {
0270 setUI((LabelUI) UIManager.getUI(this ));
0271 }
0272
0273 /**
0274 * Returns a string that specifies the name of the l&f class
0275 * that renders this component.
0276 *
0277 * @return String "LabelUI"
0278 *
0279 * @see JComponent#getUIClassID
0280 * @see UIDefaults#getUI
0281 */
0282 public String getUIClassID() {
0283 return uiClassID;
0284 }
0285
0286 /**
0287 * Returns the text string that the label displays.
0288 *
0289 * @return a String
0290 * @see #setText
0291 */
0292 public String getText() {
0293 return text;
0294 }
0295
0296 /**
0297 * Defines the single line of text this component will display. If
0298 * the value of text is null or empty string, nothing is displayed.
0299 * <p>
0300 * The default value of this property is null.
0301 * <p>
0302 * This is a JavaBeans bound property.
0303 *
0304 * @see #setVerticalTextPosition
0305 * @see #setHorizontalTextPosition
0306 * @see #setIcon
0307 * @beaninfo
0308 * preferred: true
0309 * bound: true
0310 * attribute: visualUpdate true
0311 * description: Defines the single line of text this component will display.
0312 */
0313 public void setText(String text) {
0314
0315 String oldAccessibleName = null;
0316 if (accessibleContext != null) {
0317 oldAccessibleName = accessibleContext.getAccessibleName();
0318 }
0319
0320 String oldValue = this .text;
0321 this .text = text;
0322 firePropertyChange("text", oldValue, text);
0323
0324 setDisplayedMnemonicIndex(SwingUtilities
0325 .findDisplayedMnemonicIndex(text,
0326 getDisplayedMnemonic()));
0327
0328 if ((accessibleContext != null)
0329 && (accessibleContext.getAccessibleName() != oldAccessibleName)) {
0330 accessibleContext.firePropertyChange(
0331 AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
0332 oldAccessibleName, accessibleContext
0333 .getAccessibleName());
0334 }
0335 if (text == null || oldValue == null || !text.equals(oldValue)) {
0336 revalidate();
0337 repaint();
0338 }
0339 }
0340
0341 /**
0342 * Returns the graphic image (glyph, icon) that the label displays.
0343 *
0344 * @return an Icon
0345 * @see #setIcon
0346 */
0347 public Icon getIcon() {
0348 return defaultIcon;
0349 }
0350
0351 /**
0352 * Defines the icon this component will display. If
0353 * the value of icon is null, nothing is displayed.
0354 * <p>
0355 * The default value of this property is null.
0356 * <p>
0357 * This is a JavaBeans bound property.
0358 *
0359 * @see #setVerticalTextPosition
0360 * @see #setHorizontalTextPosition
0361 * @see #getIcon
0362 * @beaninfo
0363 * preferred: true
0364 * bound: true
0365 * attribute: visualUpdate true
0366 * description: The icon this component will display.
0367 */
0368 public void setIcon(Icon icon) {
0369 Icon oldValue = defaultIcon;
0370 defaultIcon = icon;
0371
0372 /* If the default icon has really changed and we had
0373 * generated the disabled icon for this component
0374 * (in other words, setDisabledIcon() was never called), then
0375 * clear the disabledIcon field.
0376 */
0377 if ((defaultIcon != oldValue) && !disabledIconSet) {
0378 disabledIcon = null;
0379 }
0380
0381 firePropertyChange("icon", oldValue, defaultIcon);
0382
0383 if ((accessibleContext != null) && (oldValue != defaultIcon)) {
0384 accessibleContext.firePropertyChange(
0385 AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
0386 oldValue, defaultIcon);
0387 }
0388
0389 /* If the default icon has changed and the new one is
0390 * a different size, then revalidate. Repaint if the
0391 * default icon has changed.
0392 */
0393 if (defaultIcon != oldValue) {
0394 if ((defaultIcon == null)
0395 || (oldValue == null)
0396 || (defaultIcon.getIconWidth() != oldValue
0397 .getIconWidth())
0398 || (defaultIcon.getIconHeight() != oldValue
0399 .getIconHeight())) {
0400 revalidate();
0401 }
0402 repaint();
0403 }
0404 }
0405
0406 /**
0407 * Returns the icon used by the label when it's disabled.
0408 * If no disabled icon has been set this will forward the call to
0409 * the look and feel to construct an appropriate disabled Icon.
0410 * <p>
0411 * Some look and feels might not render the disabled Icon, in which
0412 * case they will ignore this.
0413 *
0414 * @return the <code>disabledIcon</code> property
0415 * @see #setDisabledIcon
0416 * @see javax.swing.LookAndFeel#getDisabledIcon
0417 * @see ImageIcon
0418 */
0419 public Icon getDisabledIcon() {
0420 if (!disabledIconSet && disabledIcon == null
0421 && defaultIcon != null) {
0422 disabledIcon = UIManager.getLookAndFeel().getDisabledIcon(
0423 this , defaultIcon);
0424 if (disabledIcon != null) {
0425 firePropertyChange("disabledIcon", null, disabledIcon);
0426 }
0427 }
0428 return disabledIcon;
0429 }
0430
0431 /**
0432 * Set the icon to be displayed if this JLabel is "disabled"
0433 * (JLabel.setEnabled(false)).
0434 * <p>
0435 * The default value of this property is null.
0436 *
0437 * @param disabledIcon the Icon to display when the component is disabled
0438 * @see #getDisabledIcon
0439 * @see #setEnabled
0440 * @beaninfo
0441 * bound: true
0442 * attribute: visualUpdate true
0443 * description: The icon to display if the label is disabled.
0444 */
0445 public void setDisabledIcon(Icon disabledIcon) {
0446 Icon oldValue = this .disabledIcon;
0447 this .disabledIcon = disabledIcon;
0448 disabledIconSet = (disabledIcon != null);
0449 firePropertyChange("disabledIcon", oldValue, disabledIcon);
0450 if (disabledIcon != oldValue) {
0451 if (disabledIcon == null
0452 || oldValue == null
0453 || disabledIcon.getIconWidth() != oldValue
0454 .getIconWidth()
0455 || disabledIcon.getIconHeight() != oldValue
0456 .getIconHeight()) {
0457 revalidate();
0458 }
0459 if (!isEnabled()) {
0460 repaint();
0461 }
0462 }
0463 }
0464
0465 /**
0466 * Specify a keycode that indicates a mnemonic key.
0467 * This property is used when the label is part of a larger component.
0468 * If the labelFor property of the label is not null, the label will
0469 * call the requestFocus method of the component specified by the
0470 * labelFor property when the mnemonic is activated.
0471 *
0472 * @see #getLabelFor
0473 * @see #setLabelFor
0474 * @beaninfo
0475 * bound: true
0476 * attribute: visualUpdate true
0477 * description: The mnemonic keycode.
0478 */
0479 public void setDisplayedMnemonic(int key) {
0480 int oldKey = mnemonic;
0481 mnemonic = key;
0482 firePropertyChange("displayedMnemonic", oldKey, mnemonic);
0483
0484 setDisplayedMnemonicIndex(SwingUtilities
0485 .findDisplayedMnemonicIndex(getText(), mnemonic));
0486
0487 if (key != oldKey) {
0488 revalidate();
0489 repaint();
0490 }
0491 }
0492
0493 /**
0494 * Specifies the displayedMnemonic as a char value.
0495 *
0496 * @param aChar a char specifying the mnemonic to display
0497 * @see #setDisplayedMnemonic(int)
0498 */
0499 public void setDisplayedMnemonic(char aChar) {
0500 int vk = (int) aChar;
0501 if (vk >= 'a' && vk <= 'z')
0502 vk -= ('a' - 'A');
0503 setDisplayedMnemonic(vk);
0504 }
0505
0506 /**
0507 * Return the keycode that indicates a mnemonic key.
0508 * This property is used when the label is part of a larger component.
0509 * If the labelFor property of the label is not null, the label will
0510 * call the requestFocus method of the component specified by the
0511 * labelFor property when the mnemonic is activated.
0512 *
0513 * @return int value for the mnemonic key
0514 *
0515 * @see #getLabelFor
0516 * @see #setLabelFor
0517 */
0518 public int getDisplayedMnemonic() {
0519 return mnemonic;
0520 }
0521
0522 /**
0523 * Provides a hint to the look and feel as to which character in the
0524 * text should be decorated to represent the mnemonic. Not all look and
0525 * feels may support this. A value of -1 indicates either there is no
0526 * mnemonic, the mnemonic character is not contained in the string, or
0527 * the developer does not wish the mnemonic to be displayed.
0528 * <p>
0529 * The value of this is updated as the properties relating to the
0530 * mnemonic change (such as the mnemonic itself, the text...).
0531 * You should only ever have to call this if
0532 * you do not wish the default character to be underlined. For example, if
0533 * the text was 'Save As', with a mnemonic of 'a', and you wanted the 'A'
0534 * to be decorated, as 'Save <u>A</u>s', you would have to invoke
0535 * <code>setDisplayedMnemonicIndex(5)</code> after invoking
0536 * <code>setDisplayedMnemonic(KeyEvent.VK_A)</code>.
0537 *
0538 * @since 1.4
0539 * @param index Index into the String to underline
0540 * @exception IllegalArgumentException will be thrown if <code>index</code
0541 * is >= length of the text, or < -1
0542 *
0543 * @beaninfo
0544 * bound: true
0545 * attribute: visualUpdate true
0546 * description: the index into the String to draw the keyboard character
0547 * mnemonic at
0548 */
0549 public void setDisplayedMnemonicIndex(int index)
0550 throws IllegalArgumentException {
0551 int oldValue = mnemonicIndex;
0552 if (index == -1) {
0553 mnemonicIndex = -1;
0554 } else {
0555 String text = getText();
0556 int textLength = (text == null) ? 0 : text.length();
0557 if (index < -1 || index >= textLength) { // index out of range
0558 throw new IllegalArgumentException("index == " + index);
0559 }
0560 }
0561 mnemonicIndex = index;
0562 firePropertyChange("displayedMnemonicIndex", oldValue, index);
0563 if (index != oldValue) {
0564 revalidate();
0565 repaint();
0566 }
0567 }
0568
0569 /**
0570 * Returns the character, as an index, that the look and feel should
0571 * provide decoration for as representing the mnemonic character.
0572 *
0573 * @since 1.4
0574 * @return index representing mnemonic character
0575 * @see #setDisplayedMnemonicIndex
0576 */
0577 public int getDisplayedMnemonicIndex() {
0578 return mnemonicIndex;
0579 }
0580
0581 /**
0582 * Verify that key is a legal value for the horizontalAlignment properties.
0583 *
0584 * @param key the property value to check
0585 * @param message the IllegalArgumentException detail message
0586 * @exception IllegalArgumentException if key isn't LEFT, CENTER, RIGHT,
0587 * LEADING or TRAILING.
0588 * @see #setHorizontalTextPosition
0589 * @see #setHorizontalAlignment
0590 */
0591 protected int checkHorizontalKey(int key, String message) {
0592 if ((key == LEFT) || (key == CENTER) || (key == RIGHT)
0593 || (key == LEADING) || (key == TRAILING)) {
0594 return key;
0595 } else {
0596 throw new IllegalArgumentException(message);
0597 }
0598 }
0599
0600 /**
0601 * Verify that key is a legal value for the
0602 * verticalAlignment or verticalTextPosition properties.
0603 *
0604 * @param key the property value to check
0605 * @param message the IllegalArgumentException detail message
0606 * @exception IllegalArgumentException if key isn't TOP, CENTER, or BOTTOM.
0607 * @see #setVerticalAlignment
0608 * @see #setVerticalTextPosition
0609 */
0610 protected int checkVerticalKey(int key, String message) {
0611 if ((key == TOP) || (key == CENTER) || (key == BOTTOM)) {
0612 return key;
0613 } else {
0614 throw new IllegalArgumentException(message);
0615 }
0616 }
0617
0618 /**
0619 * Returns the amount of space between the text and the icon
0620 * displayed in this label.
0621 *
0622 * @return an int equal to the number of pixels between the text
0623 * and the icon.
0624 * @see #setIconTextGap
0625 */
0626 public int getIconTextGap() {
0627 return iconTextGap;
0628 }
0629
0630 /**
0631 * If both the icon and text properties are set, this property
0632 * defines the space between them.
0633 * <p>
0634 * The default value of this property is 4 pixels.
0635 * <p>
0636 * This is a JavaBeans bound property.
0637 *
0638 * @see #getIconTextGap
0639 * @beaninfo
0640 * bound: true
0641 * attribute: visualUpdate true
0642 * description: If both the icon and text properties are set, this
0643 * property defines the space between them.
0644 */
0645 public void setIconTextGap(int iconTextGap) {
0646 int oldValue = this .iconTextGap;
0647 this .iconTextGap = iconTextGap;
0648 firePropertyChange("iconTextGap", oldValue, iconTextGap);
0649 if (iconTextGap != oldValue) {
0650 revalidate();
0651 repaint();
0652 }
0653 }
0654
0655 /**
0656 * Returns the alignment of the label's contents along the Y axis.
0657 *
0658 * @return The value of the verticalAlignment property, one of the
0659 * following constants defined in <code>SwingConstants</code>:
0660 * <code>TOP</code>,
0661 * <code>CENTER</code>, or
0662 * <code>BOTTOM</code>.
0663 *
0664 * @see SwingConstants
0665 * @see #setVerticalAlignment
0666 */
0667 public int getVerticalAlignment() {
0668 return verticalAlignment;
0669 }
0670
0671 /**
0672 * Sets the alignment of the label's contents along the Y axis.
0673 * <p>
0674 * The default value of this property is CENTER.
0675 *
0676 * @param alignment One of the following constants
0677 * defined in <code>SwingConstants</code>:
0678 * <code>TOP</code>,
0679 * <code>CENTER</code> (the default), or
0680 * <code>BOTTOM</code>.
0681 *
0682 * @see SwingConstants
0683 * @see #getVerticalAlignment
0684 * @beaninfo
0685 * bound: true
0686 * enum: TOP SwingConstants.TOP
0687 * CENTER SwingConstants.CENTER
0688 * BOTTOM SwingConstants.BOTTOM
0689 * attribute: visualUpdate true
0690 * description: The alignment of the label's contents along the Y axis.
0691 */
0692 public void setVerticalAlignment(int alignment) {
0693 if (alignment == verticalAlignment)
0694 return;
0695 int oldValue = verticalAlignment;
0696 verticalAlignment = checkVerticalKey(alignment,
0697 "verticalAlignment");
0698 firePropertyChange("verticalAlignment", oldValue,
0699 verticalAlignment);
0700 repaint();
0701 }
0702
0703 /**
0704 * Returns the alignment of the label's contents along the X axis.
0705 *
0706 * @return The value of the horizontalAlignment property, one of the
0707 * following constants defined in <code>SwingConstants</code>:
0708 * <code>LEFT</code>,
0709 * <code>CENTER</code>,
0710 * <code>RIGHT</code>,
0711 * <code>LEADING</code> or
0712 * <code>TRAILING</code>.
0713 *
0714 * @see #setHorizontalAlignment
0715 * @see SwingConstants
0716 */
0717 public int getHorizontalAlignment() {
0718 return horizontalAlignment;
0719 }
0720
0721 /**
0722 * Sets the alignment of the label's contents along the X axis.
0723 * <p>
0724 * This is a JavaBeans bound property.
0725 *
0726 * @param alignment One of the following constants
0727 * defined in <code>SwingConstants</code>:
0728 * <code>LEFT</code>,
0729 * <code>CENTER</code> (the default for image-only labels),
0730 * <code>RIGHT</code>,
0731 * <code>LEADING</code> (the default for text-only labels) or
0732 * <code>TRAILING</code>.
0733 *
0734 * @see SwingConstants
0735 * @see #getHorizontalAlignment
0736 * @beaninfo
0737 * bound: true
0738 * enum: LEFT SwingConstants.LEFT
0739 * CENTER SwingConstants.CENTER
0740 * RIGHT SwingConstants.RIGHT
0741 * LEADING SwingConstants.LEADING
0742 * TRAILING SwingConstants.TRAILING
0743 * attribute: visualUpdate true
0744 * description: The alignment of the label's content along the X axis.
0745 */
0746 public void setHorizontalAlignment(int alignment) {
0747 if (alignment == horizontalAlignment)
0748 return;
0749 int oldValue = horizontalAlignment;
0750 horizontalAlignment = checkHorizontalKey(alignment,
0751 "horizontalAlignment");
0752 firePropertyChange("horizontalAlignment", oldValue,
0753 horizontalAlignment);
0754 repaint();
0755 }
0756
0757 /**
0758 * Returns the vertical position of the label's text,
0759 * relative to its image.
0760 *
0761 * @return One of the following constants
0762 * defined in <code>SwingConstants</code>:
0763 * <code>TOP</code>,
0764 * <code>CENTER</code>, or
0765 * <code>BOTTOM</code>.
0766 *
0767 * @see #setVerticalTextPosition
0768 * @see SwingConstants
0769 */
0770 public int getVerticalTextPosition() {
0771 return verticalTextPosition;
0772 }
0773
0774 /**
0775 * Sets the vertical position of the label's text,
0776 * relative to its image.
0777 * <p>
0778 * The default value of this property is CENTER.
0779 * <p>
0780 * This is a JavaBeans bound property.
0781 *
0782 * @param textPosition One of the following constants
0783 * defined in <code>SwingConstants</code>:
0784 * <code>TOP</code>,
0785 * <code>CENTER</code> (the default), or
0786 * <code>BOTTOM</code>.
0787 *
0788 * @see SwingConstants
0789 * @see #getVerticalTextPosition
0790 * @beaninfo
0791 * bound: true
0792 * enum: TOP SwingConstants.TOP
0793 * CENTER SwingConstants.CENTER
0794 * BOTTOM SwingConstants.BOTTOM
0795 * expert: true
0796 * attribute: visualUpdate true
0797 * description: The vertical position of the text relative to it's image.
0798 */
0799 public void setVerticalTextPosition(int textPosition) {
0800 if (textPosition == verticalTextPosition)
0801 return;
0802 int old = verticalTextPosition;
0803 verticalTextPosition = checkVerticalKey(textPosition,
0804 "verticalTextPosition");
0805 firePropertyChange("verticalTextPosition", old,
0806 verticalTextPosition);
0807 revalidate();
0808 repaint();
0809 }
0810
0811 /**
0812 * Returns the horizontal position of the label's text,
0813 * relative to its image.
0814 *
0815 * @return One of the following constants
0816 * defined in <code>SwingConstants</code>:
0817 * <code>LEFT</code>,
0818 * <code>CENTER</code>,
0819 * <code>RIGHT</code>,
0820 * <code>LEADING</code> or
0821 * <code>TRAILING</code>.
0822 *
0823 * @see SwingConstants
0824 */
0825 public int getHorizontalTextPosition() {
0826 return horizontalTextPosition;
0827 }
0828
0829 /**
0830 * Sets the horizontal position of the label's text,
0831 * relative to its image.
0832 *
0833 * @param textPosition One of the following constants
0834 * defined in <code>SwingConstants</code>:
0835 * <code>LEFT</code>,
0836 * <code>CENTER</code>,
0837 * <code>RIGHT</code>,
0838 * <code>LEADING</code>, or
0839 * <code>TRAILING</code> (the default).
0840 * @exception IllegalArgumentException
0841 *
0842 * @see SwingConstants
0843 * @beaninfo
0844 * expert: true
0845 * bound: true
0846 * enum: LEFT SwingConstants.LEFT
0847 * CENTER SwingConstants.CENTER
0848 * RIGHT SwingConstants.RIGHT
0849 * LEADING SwingConstants.LEADING
0850 * TRAILING SwingConstants.TRAILING
0851 * attribute: visualUpdate true
0852 * description: The horizontal position of the label's text,
0853 * relative to its image.
0854 */
0855 public void setHorizontalTextPosition(int textPosition) {
0856 int old = horizontalTextPosition;
0857 this .horizontalTextPosition = checkHorizontalKey(textPosition,
0858 "horizontalTextPosition");
0859 firePropertyChange("horizontalTextPosition", old,
0860 horizontalTextPosition);
0861 revalidate();
0862 repaint();
0863 }
0864
0865 /**
0866 * This is overridden to return false if the current Icon's Image is
0867 * not equal to the passed in Image <code>img</code>.
0868 *
0869 * @see java.awt.image.ImageObserver
0870 * @see java.awt.Component#imageUpdate(java.awt.Image, int, int, int, int, int)
0871 */
0872 public boolean imageUpdate(Image img, int infoflags, int x, int y,
0873 int w, int h) {
0874 // Don't use getDisabledIcon, will trigger creation of icon if icon
0875 // not set.
0876 if (!isShowing()
0877 || !SwingUtilities.doesIconReferenceImage(getIcon(),
0878 img)
0879 && !SwingUtilities.doesIconReferenceImage(disabledIcon,
0880 img)) {
0881
0882 return false;
0883 }
0884 return super .imageUpdate(img, infoflags, x, y, w, h);
0885 }
0886
0887 /**
0888 * See readObject() and writeObject() in JComponent for more
0889 * information about serialization in Swing.
0890 */
0891 private void writeObject(ObjectOutputStream s) throws IOException {
0892 s.defaultWriteObject();
0893 if (getUIClassID().equals(uiClassID)) {
0894 byte count = JComponent.getWriteObjCounter(this );
0895 JComponent.setWriteObjCounter(this , --count);
0896 if (count == 0 && ui != null) {
0897 ui.installUI(this );
0898 }
0899 }
0900 }
0901
0902 /**
0903 * Returns a string representation of this JLabel. This method
0904 * is intended to be used only for debugging purposes, and the
0905 * content and format of the returned string may vary between
0906 * implementations. The returned string may be empty but may not
0907 * be <code>null</code>.
0908 *
0909 * @return a string representation of this JLabel.
0910 */
0911 protected String paramString() {
0912 String textString = (text != null ? text : "");
0913 String defaultIconString = ((defaultIcon != null)
0914 && (defaultIcon != this ) ? defaultIcon.toString() : "");
0915 String disabledIconString = ((disabledIcon != null)
0916 && (disabledIcon != this ) ? disabledIcon.toString()
0917 : "");
0918 String labelForString = (labelFor != null ? labelFor.toString()
0919 : "");
0920 String verticalAlignmentString;
0921 if (verticalAlignment == TOP) {
0922 verticalAlignmentString = "TOP";
0923 } else if (verticalAlignment == CENTER) {
0924 verticalAlignmentString = "CENTER";
0925 } else if (verticalAlignment == BOTTOM) {
0926 verticalAlignmentString = "BOTTOM";
0927 } else
0928 verticalAlignmentString = "";
0929 String horizontalAlignmentString;
0930 if (horizontalAlignment == LEFT) {
0931 horizontalAlignmentString = "LEFT";
0932 } else if (horizontalAlignment == CENTER) {
0933 horizontalAlignmentString = "CENTER";
0934 } else if (horizontalAlignment == RIGHT) {
0935 horizontalAlignmentString = "RIGHT";
0936 } else if (horizontalAlignment == LEADING) {
0937 horizontalAlignmentString = "LEADING";
0938 } else if (horizontalAlignment == TRAILING) {
0939 horizontalAlignmentString = "TRAILING";
0940 } else
0941 horizontalAlignmentString = "";
0942 String verticalTextPositionString;
0943 if (verticalTextPosition == TOP) {
0944 verticalTextPositionString = "TOP";
0945 } else if (verticalTextPosition == CENTER) {
0946 verticalTextPositionString = "CENTER";
0947 } else if (verticalTextPosition == BOTTOM) {
0948 verticalTextPositionString = "BOTTOM";
0949 } else
0950 verticalTextPositionString = "";
0951 String horizontalTextPositionString;
0952 if (horizontalTextPosition == LEFT) {
0953 horizontalTextPositionString = "LEFT";
0954 } else if (horizontalTextPosition == CENTER) {
0955 horizontalTextPositionString = "CENTER";
0956 } else if (horizontalTextPosition == RIGHT) {
0957 horizontalTextPositionString = "RIGHT";
0958 } else if (horizontalTextPosition == LEADING) {
0959 horizontalTextPositionString = "LEADING";
0960 } else if (horizontalTextPosition == TRAILING) {
0961 horizontalTextPositionString = "TRAILING";
0962 } else
0963 horizontalTextPositionString = "";
0964
0965 return super .paramString() + ",defaultIcon="
0966 + defaultIconString + ",disabledIcon="
0967 + disabledIconString + ",horizontalAlignment="
0968 + horizontalAlignmentString
0969 + ",horizontalTextPosition="
0970 + horizontalTextPositionString + ",iconTextGap="
0971 + iconTextGap + ",labelFor=" + labelForString
0972 + ",text=" + textString + ",verticalAlignment="
0973 + verticalAlignmentString + ",verticalTextPosition="
0974 + verticalTextPositionString;
0975 }
0976
0977 /**
0978 * --- Accessibility Support ---
0979 */
0980
0981 /**
0982 * Get the component this is labelling.
0983 *
0984 * @return the Component this is labelling. Can be null if this
0985 * does not label a Component. If the displayedMnemonic
0986 * property is set and the labelFor property is also set, the label
0987 * will call the requestFocus method of the component specified by the
0988 * labelFor property when the mnemonic is activated.
0989 *
0990 * @see #getDisplayedMnemonic
0991 * @see #setDisplayedMnemonic
0992 */
0993 public Component getLabelFor() {
0994 return labelFor;
0995 }
0996
0997 /**
0998 * Set the component this is labelling. Can be null if this does not
0999 * label a Component. If the displayedMnemonic property is set
1000 * and the labelFor property is also set, the label will
1001 * call the requestFocus method of the component specified by the
1002 * labelFor property when the mnemonic is activated.
1003 *
1004 * @param c the Component this label is for, or null if the label is
1005 * not the label for a component
1006 *
1007 * @see #getDisplayedMnemonic
1008 * @see #setDisplayedMnemonic
1009 *
1010 * @beaninfo
1011 * bound: true
1012 * description: The component this is labelling.
1013 */
1014 public void setLabelFor(Component c) {
1015 Component oldC = labelFor;
1016 labelFor = c;
1017 firePropertyChange("labelFor", oldC, c);
1018
1019 if (oldC instanceof JComponent) {
1020 ((JComponent) oldC).putClientProperty(LABELED_BY_PROPERTY,
1021 null);
1022 }
1023 if (c instanceof JComponent) {
1024 ((JComponent) c).putClientProperty(LABELED_BY_PROPERTY,
1025 this );
1026 }
1027 }
1028
1029 /**
1030 * Get the AccessibleContext of this object
1031 *
1032 * @return the AccessibleContext of this object
1033 * @beaninfo
1034 * expert: true
1035 * description: The AccessibleContext associated with this Label.
1036 */
1037 public AccessibleContext getAccessibleContext() {
1038 if (accessibleContext == null) {
1039 accessibleContext = new AccessibleJLabel();
1040 }
1041 return accessibleContext;
1042 }
1043
1044 /**
1045 * The class used to obtain the accessible role for this object.
1046 * <p>
1047 * <strong>Warning:</strong>
1048 * Serialized objects of this class will not be compatible with
1049 * future Swing releases. The current serialization support is
1050 * appropriate for short term storage or RMI between applications running
1051 * the same version of Swing. As of 1.4, support for long term storage
1052 * of all JavaBeans<sup><font size="-2">TM</font></sup>
1053 * has been added to the <code>java.beans</code> package.
1054 * Please see {@link java.beans.XMLEncoder}.
1055 */
1056 protected class AccessibleJLabel extends AccessibleJComponent
1057 implements AccessibleText, AccessibleExtendedComponent {
1058
1059 /**
1060 * Get the accessible name of this object.
1061 *
1062 * @return the localized name of the object -- can be null if this
1063 * object does not have a name
1064 * @see AccessibleContext#setAccessibleName
1065 */
1066 public String getAccessibleName() {
1067 String name = accessibleName;
1068
1069 if (name == null) {
1070 name = (String) getClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY);
1071 }
1072 if (name == null) {
1073 name = JLabel.this .getText();
1074 }
1075 if (name == null) {
1076 name = super .getAccessibleName();
1077 }
1078 return name;
1079 }
1080
1081 /**
1082 * Get the role of this object.
1083 *
1084 * @return an instance of AccessibleRole describing the role of the
1085 * object
1086 * @see AccessibleRole
1087 */
1088 public AccessibleRole getAccessibleRole() {
1089 return AccessibleRole.LABEL;
1090 }
1091
1092 /**
1093 * Get the AccessibleIcons associated with this object if one
1094 * or more exist. Otherwise return null.
1095 * @since 1.3
1096 */
1097 public AccessibleIcon[] getAccessibleIcon() {
1098 Icon icon = getIcon();
1099 if (icon instanceof Accessible) {
1100 AccessibleContext ac = ((Accessible) icon)
1101 .getAccessibleContext();
1102 if (ac != null && ac instanceof AccessibleIcon) {
1103 return new AccessibleIcon[] { (AccessibleIcon) ac };
1104 }
1105 }
1106 return null;
1107 }
1108
1109 /**
1110 * Get the AccessibleRelationSet associated with this object if one
1111 * exists. Otherwise return null.
1112 * @see AccessibleRelation
1113 * @since 1.3
1114 */
1115 public AccessibleRelationSet getAccessibleRelationSet() {
1116 // Check where the AccessibleContext's relation
1117 // set already contains a LABEL_FOR relation.
1118 AccessibleRelationSet relationSet = super
1119 .getAccessibleRelationSet();
1120
1121 if (!relationSet.contains(AccessibleRelation.LABEL_FOR)) {
1122 Component c = JLabel.this .getLabelFor();
1123 if (c != null) {
1124 AccessibleRelation relation = new AccessibleRelation(
1125 AccessibleRelation.LABEL_FOR);
1126 relation.setTarget(c);
1127 relationSet.add(relation);
1128 }
1129 }
1130 return relationSet;
1131 }
1132
1133 /* AccessibleText ---------- */
1134
1135 public AccessibleText getAccessibleText() {
1136 View view = (View) JLabel.this .getClientProperty("html");
1137 if (view != null) {
1138 return this ;
1139 } else {
1140 return null;
1141 }
1142 }
1143
1144 /**
1145 * Given a point in local coordinates, return the zero-based index
1146 * of the character under that Point. If the point is invalid,
1147 * this method returns -1.
1148 *
1149 * @param p the Point in local coordinates
1150 * @return the zero-based index of the character under Point p; if
1151 * Point is invalid returns -1.
1152 * @since 1.3
1153 */
1154 public int getIndexAtPoint(Point p) {
1155 View view = (View) JLabel.this .getClientProperty("html");
1156 if (view != null) {
1157 Rectangle r = getTextRectangle();
1158 if (r == null) {
1159 return -1;
1160 }
1161 Rectangle2D.Float shape = new Rectangle2D.Float(r.x,
1162 r.y, r.width, r.height);
1163 Position.Bias bias[] = new Position.Bias[1];
1164 return view.viewToModel(p.x, p.y, shape, bias);
1165 } else {
1166 return -1;
1167 }
1168 }
1169
1170 /**
1171 * Determine the bounding box of the character at the given
1172 * index into the string. The bounds are returned in local
1173 * coordinates. If the index is invalid an empty rectangle is
1174 * returned.
1175 *
1176 * @param i the index into the String
1177 * @return the screen coordinates of the character's the bounding box,
1178 * if index is invalid returns an empty rectangle.
1179 * @since 1.3
1180 */
1181 public Rectangle getCharacterBounds(int i) {
1182 View view = (View) JLabel.this .getClientProperty("html");
1183 if (view != null) {
1184 Rectangle r = getTextRectangle();
1185 if (r == null) {
1186 return null;
1187 }
1188 Rectangle2D.Float shape = new Rectangle2D.Float(r.x,
1189 r.y, r.width, r.height);
1190 try {
1191 Shape charShape = view.modelToView(i, shape,
1192 Position.Bias.Forward);
1193 return charShape.getBounds();
1194 } catch (BadLocationException e) {
1195 return null;
1196 }
1197 } else {
1198 return null;
1199 }
1200 }
1201
1202 /**
1203 * Return the number of characters (valid indicies)
1204 *
1205 * @return the number of characters
1206 * @since 1.3
1207 */
1208 public int getCharCount() {
1209 View view = (View) JLabel.this .getClientProperty("html");
1210 if (view != null) {
1211 Document d = view.getDocument();
1212 if (d instanceof StyledDocument) {
1213 StyledDocument doc = (StyledDocument) d;
1214 return doc.getLength();
1215 }
1216 }
1217 return accessibleContext.getAccessibleName().length();
1218 }
1219
1220 /**
1221 * Return the zero-based offset of the caret.
1222 *
1223 * Note: That to the right of the caret will have the same index
1224 * value as the offset (the caret is between two characters).
1225 * @return the zero-based offset of the caret.
1226 * @since 1.3
1227 */
1228 public int getCaretPosition() {
1229 // There is no caret.
1230 return -1;
1231 }
1232
1233 /**
1234 * Returns the String at a given index.
1235 *
1236 * @param part the AccessibleText.CHARACTER, AccessibleText.WORD,
1237 * or AccessibleText.SENTENCE to retrieve
1238 * @param index an index within the text >= 0
1239 * @return the letter, word, or sentence,
1240 * null for an invalid index or part
1241 * @since 1.3
1242 */
1243 public String getAtIndex(int part, int index) {
1244 if (index < 0 || index >= getCharCount()) {
1245 return null;
1246 }
1247 switch (part) {
1248 case AccessibleText.CHARACTER:
1249 try {
1250 return getText(index, 1);
1251 } catch (BadLocationException e) {
1252 return null;
1253 }
1254 case AccessibleText.WORD:
1255 try {
1256 String s = getText(0, getCharCount());
1257 BreakIterator words = BreakIterator
1258 .getWordInstance(getLocale());
1259 words.setText(s);
1260 int end = words.following(index);
1261 return s.substring(words.previous(), end);
1262 } catch (BadLocationException e) {
1263 return null;
1264 }
1265 case AccessibleText.SENTENCE:
1266 try {
1267 String s = getText(0, getCharCount());
1268 BreakIterator sentence = BreakIterator
1269 .getSentenceInstance(getLocale());
1270 sentence.setText(s);
1271 int end = sentence.following(index);
1272 return s.substring(sentence.previous(), end);
1273 } catch (BadLocationException e) {
1274 return null;
1275 }
1276 default:
1277 return null;
1278 }
1279 }
1280
1281 /**
1282 * Returns the String after a given index.
1283 *
1284 * @param part the AccessibleText.CHARACTER, AccessibleText.WORD,
1285 * or AccessibleText.SENTENCE to retrieve
1286 * @param index an index within the text >= 0
1287 * @return the letter, word, or sentence, null for an invalid
1288 * index or part
1289 * @since 1.3
1290 */
1291 public String getAfterIndex(int part, int index) {
1292 if (index < 0 || index >= getCharCount()) {
1293 return null;
1294 }
1295 switch (part) {
1296 case AccessibleText.CHARACTER:
1297 if (index + 1 >= getCharCount()) {
1298 return null;
1299 }
1300 try {
1301 return getText(index + 1, 1);
1302 } catch (BadLocationException e) {
1303 return null;
1304 }
1305 case AccessibleText.WORD:
1306 try {
1307 String s = getText(0, getCharCount());
1308 BreakIterator words = BreakIterator
1309 .getWordInstance(getLocale());
1310 words.setText(s);
1311 int start = words.following(index);
1312 if (start == BreakIterator.DONE
1313 || start >= s.length()) {
1314 return null;
1315 }
1316 int end = words.following(start);
1317 if (end == BreakIterator.DONE || end >= s.length()) {
1318 return null;
1319 }
1320 return s.substring(start, end);
1321 } catch (BadLocationException e) {
1322 return null;
1323 }
1324 case AccessibleText.SENTENCE:
1325 try {
1326 String s = getText(0, getCharCount());
1327 BreakIterator sentence = BreakIterator
1328 .getSentenceInstance(getLocale());
1329 sentence.setText(s);
1330 int start = sentence.following(index);
1331 if (start == BreakIterator.DONE
1332 || start > s.length()) {
1333 return null;
1334 }
1335 int end = sentence.following(start);
1336 if (end == BreakIterator.DONE || end > s.length()) {
1337 return null;
1338 }
1339 return s.substring(start, end);
1340 } catch (BadLocationException e) {
1341 return null;
1342 }
1343 default:
1344 return null;
1345 }
1346 }
1347
1348 /**
1349 * Returns the String before a given index.
1350 *
1351 * @param part the AccessibleText.CHARACTER, AccessibleText.WORD,
1352 * or AccessibleText.SENTENCE to retrieve
1353 * @param index an index within the text >= 0
1354 * @return the letter, word, or sentence, null for an invalid index
1355 * or part
1356 * @since 1.3
1357 */
1358 public String getBeforeIndex(int part, int index) {
1359 if (index < 0 || index > getCharCount() - 1) {
1360 return null;
1361 }
1362 switch (part) {
1363 case AccessibleText.CHARACTER:
1364 if (index == 0) {
1365 return null;
1366 }
1367 try {
1368 return getText(index - 1, 1);
1369 } catch (BadLocationException e) {
1370 return null;
1371 }
1372 case AccessibleText.WORD:
1373 try {
1374 String s = getText(0, getCharCount());
1375 BreakIterator words = BreakIterator
1376 .getWordInstance(getLocale());
1377 words.setText(s);
1378 int end = words.following(index);
1379 end = words.previous();
1380 int start = words.previous();
1381 if (start == BreakIterator.DONE) {
1382 return null;
1383 }
1384 return s.substring(start, end);
1385 } catch (BadLocationException e) {
1386 return null;
1387 }
1388 case AccessibleText.SENTENCE:
1389 try {
1390 String s = getText(0, getCharCount());
1391 BreakIterator sentence = BreakIterator
1392 .getSentenceInstance(getLocale());
1393 sentence.setText(s);
1394 int end = sentence.following(index);
1395 end = sentence.previous();
1396 int start = sentence.previous();
1397 if (start == BreakIterator.DONE) {
1398 return null;
1399 }
1400 return s.substring(start, end);
1401 } catch (BadLocationException e) {
1402 return null;
1403 }
1404 default:
1405 return null;
1406 }
1407 }
1408
1409 /**
1410 * Return the AttributeSet for a given character at a given index
1411 *
1412 * @param i the zero-based index into the text
1413 * @return the AttributeSet of the character
1414 * @since 1.3
1415 */
1416 public AttributeSet getCharacterAttribute(int i) {
1417 View view = (View) JLabel.this .getClientProperty("html");
1418 if (view != null) {
1419 Document d = view.getDocument();
1420 if (d instanceof StyledDocument) {
1421 StyledDocument doc = (StyledDocument) d;
1422 Element elem = doc.getCharacterElement(i);
1423 if (elem != null) {
1424 return elem.getAttributes();
1425 }
1426 }
1427 }
1428 return null;
1429 }
1430
1431 /**
1432 * Returns the start offset within the selected text.
1433 * If there is no selection, but there is
1434 * a caret, the start and end offsets will be the same.
1435 *
1436 * @return the index into the text of the start of the selection
1437 * @since 1.3
1438 */
1439 public int getSelectionStart() {
1440 // Text cannot be selected.
1441 return -1;
1442 }
1443
1444 /**
1445 * Returns the end offset within the selected text.
1446 * If there is no selection, but there is
1447 * a caret, the start and end offsets will be the same.
1448 *
1449 * @return the index into teh text of the end of the selection
1450 * @since 1.3
1451 */
1452 public int getSelectionEnd() {
1453 // Text cannot be selected.
1454 return -1;
1455 }
1456
1457 /**
1458 * Returns the portion of the text that is selected.
1459 *
1460 * @return the String portion of the text that is selected
1461 * @since 1.3
1462 */
1463 public String getSelectedText() {
1464 // Text cannot be selected.
1465 return null;
1466 }
1467
1468 /*
1469 * Returns the text substring starting at the specified
1470 * offset with the specified length.
1471 */
1472 private String getText(int offset, int length)
1473 throws BadLocationException {
1474
1475 View view = (View) JLabel.this .getClientProperty("html");
1476 if (view != null) {
1477 Document d = view.getDocument();
1478 if (d instanceof StyledDocument) {
1479 StyledDocument doc = (StyledDocument) d;
1480 return doc.getText(offset, length);
1481 }
1482 }
1483 return null;
1484 }
1485
1486 /*
1487 * Returns the bounding rectangle for the component text.
1488 */
1489 private Rectangle getTextRectangle() {
1490
1491 String text = JLabel.this .getText();
1492 Icon icon = (JLabel.this .isEnabled()) ? JLabel.this
1493 .getIcon() : JLabel.this .getDisabledIcon();
1494
1495 if ((icon == null) && (text == null)) {
1496 return null;
1497 }
1498
1499 Rectangle paintIconR = new Rectangle();
1500 Rectangle paintTextR = new Rectangle();
1501 Rectangle paintViewR = new Rectangle();
1502 Insets paintViewInsets = new Insets(0, 0, 0, 0);
1503
1504 paintViewInsets = JLabel.this .getInsets(paintViewInsets);
1505 paintViewR.x = paintViewInsets.left;
1506 paintViewR.y = paintViewInsets.top;
1507 paintViewR.width = JLabel.this .getWidth()
1508 - (paintViewInsets.left + paintViewInsets.right);
1509 paintViewR.height = JLabel.this .getHeight()
1510 - (paintViewInsets.top + paintViewInsets.bottom);
1511
1512 String clippedText = SwingUtilities.layoutCompoundLabel(
1513 (JComponent) JLabel.this ,
1514 getFontMetrics(getFont()), text, icon, JLabel.this
1515 .getVerticalAlignment(), JLabel.this
1516 .getHorizontalAlignment(), JLabel.this
1517 .getVerticalTextPosition(), JLabel.this
1518 .getHorizontalTextPosition(), paintViewR,
1519 paintIconR, paintTextR, JLabel.this
1520 .getIconTextGap());
1521
1522 return paintTextR;
1523 }
1524
1525 // ----- AccessibleExtendedComponent
1526
1527 /**
1528 * Returns the AccessibleExtendedComponent
1529 *
1530 * @return the AccessibleExtendedComponent
1531 */
1532 AccessibleExtendedComponent getAccessibleExtendedComponent() {
1533 return this ;
1534 }
1535
1536 /**
1537 * Returns the tool tip text
1538 *
1539 * @return the tool tip text, if supported, of the object;
1540 * otherwise, null
1541 * @since 1.4
1542 */
1543 public String getToolTipText() {
1544 return JLabel.this .getToolTipText();
1545 }
1546
1547 /**
1548 * Returns the titled border text
1549 *
1550 * @return the titled border text, if supported, of the object;
1551 * otherwise, null
1552 * @since 1.4
1553 */
1554 public String getTitledBorderText() {
1555 return super .getTitledBorderText();
1556 }
1557
1558 /**
1559 * Returns key bindings associated with this object
1560 *
1561 * @return the key bindings, if supported, of the object;
1562 * otherwise, null
1563 * @see AccessibleKeyBinding
1564 * @since 1.4
1565 */
1566 public AccessibleKeyBinding getAccessibleKeyBinding() {
1567 int mnemonic = JLabel.this .getDisplayedMnemonic();
1568 if (mnemonic == 0) {
1569 return null;
1570 }
1571 return new LabelKeyBinding(mnemonic);
1572 }
1573
1574 class LabelKeyBinding implements AccessibleKeyBinding {
1575 int mnemonic;
1576
1577 LabelKeyBinding(int mnemonic) {
1578 this .mnemonic = mnemonic;
1579 }
1580
1581 /**
1582 * Returns the number of key bindings for this object
1583 *
1584 * @return the zero-based number of key bindings for this object
1585 */
1586 public int getAccessibleKeyBindingCount() {
1587 return 1;
1588 }
1589
1590 /**
1591 * Returns a key binding for this object. The value returned is an
1592 * java.lang.Object which must be cast to appropriate type depending
1593 * on the underlying implementation of the key. For example, if the
1594 * Object returned is a javax.swing.KeyStroke, the user of this
1595 * method should do the following:
1596 * <nf><code>
1597 * Component c = <get the component that has the key bindings>
1598 * AccessibleContext ac = c.getAccessibleContext();
1599 * AccessibleKeyBinding akb = ac.getAccessibleKeyBinding();
1600 * for (int i = 0; i < akb.getAccessibleKeyBindingCount(); i++) {
1601 * Object o = akb.getAccessibleKeyBinding(i);
1602 * if (o instanceof javax.swing.KeyStroke) {
1603 * javax.swing.KeyStroke keyStroke = (javax.swing.KeyStroke)o;
1604 * <do something with the key binding>
1605 * }
1606 * }
1607 * </code></nf>
1608 *
1609 * @param i zero-based index of the key bindings
1610 * @return a javax.lang.Object which specifies the key binding
1611 * @exception IllegalArgumentException if the index is
1612 * out of bounds
1613 * @see #getAccessibleKeyBindingCount
1614 */
1615 public java.lang.Object getAccessibleKeyBinding(int i) {
1616 if (i != 0) {
1617 throw new IllegalArgumentException();
1618 }
1619 return KeyStroke.getKeyStroke(mnemonic, 0);
1620 }
1621 }
1622
1623 } // AccessibleJComponent
1624 }
|