1 /*
   2  * Copyright (c) 1995, 2014, Oracle and/or its affiliates. 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package java.awt;
  26 
  27 import java.awt.peer.LabelPeer;
  28 import java.io.IOException;
  29 import java.io.ObjectInputStream;
  30 import javax.accessibility.*;
  31 
  32 /**
  33  * A <code>Label</code> object is a component for placing text in a
  34  * container. A label displays a single line of read-only text.
  35  * The text can be changed by the application, but a user cannot edit it
  36  * directly.
  37  * <p>
  38  * For example, the code&nbsp;.&nbsp;.&nbsp;.
  39  *
  40  * <hr><blockquote><pre>
  41  * setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10));
  42  * add(new Label("Hi There!"));
  43  * add(new Label("Another Label"));
  44  * </pre></blockquote><hr>
  45  * <p>
  46  * produces the following labels:
  47  * <p>
  48  * <img src="doc-files/Label-1.gif" alt="Two labels: 'Hi There!' and 'Another label'"
  49  * style="float:center; margin: 7px 10px;">
  50  *
  51  * @author      Sami Shaio
  52  * @since       JDK1.0
  53  */
  54 public class Label extends Component implements Accessible {
  55 
  56     static {
  57         /* ensure that the necessary native libraries are loaded */
  58         Toolkit.loadLibraries();
  59         if (!GraphicsEnvironment.isHeadless()) {
  60             initIDs();
  61         }
  62     }
  63 
  64     /**
  65      * Indicates that the label should be left justified.
  66      */
  67     public static final int LEFT        = 0;
  68 
  69     /**
  70      * Indicates that the label should be centered.
  71      */
  72     public static final int CENTER      = 1;
  73 
  74     /**
  75      * Indicates that the label should be right justified.
  76      * @since   JDK1.0t.
  77      */
  78     public static final int RIGHT       = 2;
  79 
  80     /**
  81      * The text of this label.
  82      * This text can be modified by the program
  83      * but never by the user.
  84      *
  85      * @serial
  86      * @see #getText()
  87      * @see #setText(String)
  88      */
  89     String text;
  90 
  91     /**
  92      * The label's alignment.  The default alignment is set
  93      * to be left justified.
  94      *
  95      * @serial
  96      * @see #getAlignment()
  97      * @see #setAlignment(int)
  98      */
  99     int    alignment = LEFT;
 100 
 101     private static final String base = "label";
 102     private static int nameCounter = 0;
 103 
 104     /*
 105      * JDK 1.1 serialVersionUID
 106      */
 107      private static final long serialVersionUID = 3094126758329070636L;
 108 
 109     /**
 110      * Constructs an empty label.
 111      * The text of the label is the empty string <code>""</code>.
 112      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 113      * returns true.
 114      * @see java.awt.GraphicsEnvironment#isHeadless
 115      */
 116     public Label() throws HeadlessException {
 117         this("", LEFT);
 118     }
 119 
 120     /**
 121      * Constructs a new label with the specified string of text,
 122      * left justified.
 123      * @param text the string that the label presents.
 124      *        A <code>null</code> value
 125      *        will be accepted without causing a NullPointerException
 126      *        to be thrown.
 127      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 128      * returns true.
 129      * @see java.awt.GraphicsEnvironment#isHeadless
 130      */
 131     public Label(String text) throws HeadlessException {
 132         this(text, LEFT);
 133     }
 134 
 135     /**
 136      * Constructs a new label that presents the specified string of
 137      * text with the specified alignment.
 138      * Possible values for <code>alignment</code> are <code>Label.LEFT</code>,
 139      * <code>Label.RIGHT</code>, and <code>Label.CENTER</code>.
 140      * @param text the string that the label presents.
 141      *        A <code>null</code> value
 142      *        will be accepted without causing a NullPointerException
 143      *        to be thrown.
 144      * @param     alignment   the alignment value.
 145      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 146      * returns true.
 147      * @see java.awt.GraphicsEnvironment#isHeadless
 148      */
 149     public Label(String text, int alignment) throws HeadlessException {
 150         GraphicsEnvironment.checkHeadless();
 151         this.text = text;
 152         setAlignment(alignment);
 153     }
 154 
 155     /**
 156      * Read a label from an object input stream.
 157      * @exception HeadlessException if
 158      * <code>GraphicsEnvironment.isHeadless()</code> returns
 159      * <code>true</code>
 160      * @serial
 161      * @since 1.4
 162      * @see java.awt.GraphicsEnvironment#isHeadless
 163      */
 164     private void readObject(ObjectInputStream s)
 165         throws ClassNotFoundException, IOException, HeadlessException {
 166         GraphicsEnvironment.checkHeadless();
 167         s.defaultReadObject();
 168     }
 169 
 170     /**
 171      * Construct a name for this component.  Called by getName() when the
 172      * name is <code>null</code>.
 173      */
 174     String constructComponentName() {
 175         synchronized (Label.class) {
 176             return base + nameCounter++;
 177         }
 178     }
 179 
 180     /**
 181      * Creates the peer for this label.  The peer allows us to
 182      * modify the appearance of the label without changing its
 183      * functionality.
 184      */
 185     public void addNotify() {
 186         synchronized (getTreeLock()) {
 187             if (peer == null)
 188                 peer = getToolkit().createLabel(this);
 189             super.addNotify();
 190         }
 191     }
 192 
 193     /**
 194      * Gets the current alignment of this label. Possible values are
 195      * <code>Label.LEFT</code>, <code>Label.RIGHT</code>, and
 196      * <code>Label.CENTER</code>.
 197      * @see        java.awt.Label#setAlignment
 198      */
 199     public int getAlignment() {
 200         return alignment;
 201     }
 202 
 203     /**
 204      * Sets the alignment for this label to the specified alignment.
 205      * Possible values are <code>Label.LEFT</code>,
 206      * <code>Label.RIGHT</code>, and <code>Label.CENTER</code>.
 207      * @param      alignment    the alignment to be set.
 208      * @exception  IllegalArgumentException if an improper value for
 209      *                          <code>alignment</code> is given.
 210      * @see        java.awt.Label#getAlignment
 211      */
 212     public synchronized void setAlignment(int alignment) {
 213         switch (alignment) {
 214           case LEFT:
 215           case CENTER:
 216           case RIGHT:
 217             this.alignment = alignment;
 218             LabelPeer peer = (LabelPeer)this.peer;
 219             if (peer != null) {
 220                 peer.setAlignment(alignment);
 221             }
 222             return;
 223         }
 224         throw new IllegalArgumentException("improper alignment: " + alignment);
 225     }
 226 
 227     /**
 228      * Gets the text of this label.
 229      * @return     the text of this label, or <code>null</code> if
 230      *             the text has been set to <code>null</code>.
 231      * @see        java.awt.Label#setText
 232      */
 233     public String getText() {
 234         return text;
 235     }
 236 
 237     /**
 238      * Sets the text for this label to the specified text.
 239      * @param      text the text that this label displays. If
 240      *             <code>text</code> is <code>null</code>, it is
 241      *             treated for display purposes like an empty
 242      *             string <code>""</code>.
 243      * @see        java.awt.Label#getText
 244      */
 245     public void setText(String text) {
 246         boolean testvalid = false;
 247         synchronized (this) {
 248             if (text != this.text && (this.text == null ||
 249                                       !this.text.equals(text))) {
 250                 this.text = text;
 251                 LabelPeer peer = (LabelPeer)this.peer;
 252                 if (peer != null) {
 253                     peer.setText(text);
 254                 }
 255                 testvalid = true;
 256             }
 257         }
 258 
 259         // This could change the preferred size of the Component.
 260         if (testvalid) {
 261             invalidateIfValid();
 262         }
 263     }
 264 
 265     /**
 266      * Returns a string representing the state of this <code>Label</code>.
 267      * This method is intended to be used only for debugging purposes, and the
 268      * content and format of the returned string may vary between
 269      * implementations. The returned string may be empty but may not be
 270      * <code>null</code>.
 271      *
 272      * @return     the parameter string of this label
 273      */
 274     protected String paramString() {
 275         String align = "";
 276         switch (alignment) {
 277             case LEFT:   align = "left"; break;
 278             case CENTER: align = "center"; break;
 279             case RIGHT:  align = "right"; break;
 280         }
 281         return super.paramString() + ",align=" + align + ",text=" + text;
 282     }
 283 
 284     /**
 285      * Initialize JNI field and method IDs
 286      */
 287     private static native void initIDs();
 288 
 289 
 290 /////////////////
 291 // Accessibility support
 292 ////////////////
 293 
 294 
 295     /**
 296      * Gets the AccessibleContext associated with this Label.
 297      * For labels, the AccessibleContext takes the form of an
 298      * AccessibleAWTLabel.
 299      * A new AccessibleAWTLabel instance is created if necessary.
 300      *
 301      * @return an AccessibleAWTLabel that serves as the
 302      *         AccessibleContext of this Label
 303      * @since 1.3
 304      */
 305     public AccessibleContext getAccessibleContext() {
 306         if (accessibleContext == null) {
 307             accessibleContext = new AccessibleAWTLabel();
 308         }
 309         return accessibleContext;
 310     }
 311 
 312     /**
 313      * This class implements accessibility support for the
 314      * <code>Label</code> class.  It provides an implementation of the
 315      * Java Accessibility API appropriate to label user-interface elements.
 316      * @since 1.3
 317      */
 318     protected class AccessibleAWTLabel extends AccessibleAWTComponent
 319     {
 320         /*
 321          * JDK 1.3 serialVersionUID
 322          */
 323         private static final long serialVersionUID = -3568967560160480438L;
 324 
 325         public AccessibleAWTLabel() {
 326             super();
 327         }
 328 
 329         /**
 330          * Get the accessible name of this object.
 331          *
 332          * @return the localized name of the object -- can be null if this
 333          * object does not have a name
 334          * @see AccessibleContext#setAccessibleName
 335          */
 336         public String getAccessibleName() {
 337             if (accessibleName != null) {
 338                 return accessibleName;
 339             } else {
 340                 if (getText() == null) {
 341                     return super.getAccessibleName();
 342                 } else {
 343                     return getText();
 344                 }
 345             }
 346         }
 347 
 348         /**
 349          * Get the role of this object.
 350          *
 351          * @return an instance of AccessibleRole describing the role of the object
 352          * @see AccessibleRole
 353          */
 354         public AccessibleRole getAccessibleRole() {
 355             return AccessibleRole.LABEL;
 356         }
 357 
 358     } // inner class AccessibleAWTLabel
 359 
 360 }