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

Save This Page
Home » openjdk-7 » javax » swing » [javadoc | source]