1 /*
   2  * Copyright (c) 1995, 2015, 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} 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       1.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      */
  77     public static final int RIGHT       = 2;
  78 
  79     /**
  80      * The text of this label.
  81      * This text can be modified by the program
  82      * but never by the user.
  83      *
  84      * @serial
  85      * @see #getText()
  86      * @see #setText(String)
  87      */
  88     String text;
  89 
  90     /**
  91      * The label's alignment.  The default alignment is set
  92      * to be left justified.
  93      *
  94      * @serial
  95      * @see #getAlignment()
  96      * @see #setAlignment(int)
  97      */
  98     int    alignment = LEFT;
  99 
 100     private static final String base = "label";
 101     private static int nameCounter = 0;
 102 
 103     /*
 104      * JDK 1.1 serialVersionUID
 105      */
 106      private static final long serialVersionUID = 3094126758329070636L;
 107 
 108     /**
 109      * Constructs an empty label.
 110      * The text of the label is the empty string {@code ""}.
 111      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 112      * returns true.
 113      * @see java.awt.GraphicsEnvironment#isHeadless
 114      */
 115     public Label() throws HeadlessException {
 116         this("", LEFT);
 117     }
 118 
 119     /**
 120      * Constructs a new label with the specified string of text,
 121      * left justified.
 122      * @param text the string that the label presents.
 123      *        A {@code null} value
 124      *        will be accepted without causing a NullPointerException
 125      *        to be thrown.
 126      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 127      * returns true.
 128      * @see java.awt.GraphicsEnvironment#isHeadless
 129      */
 130     public Label(String text) throws HeadlessException {
 131         this(text, LEFT);
 132     }
 133 
 134     /**
 135      * Constructs a new label that presents the specified string of
 136      * text with the specified alignment.
 137      * Possible values for {@code alignment} are {@code Label.LEFT},
 138      * {@code Label.RIGHT}, and {@code Label.CENTER}.
 139      * @param text the string that the label presents.
 140      *        A {@code null} value
 141      *        will be accepted without causing a NullPointerException
 142      *        to be thrown.
 143      * @param     alignment   the alignment value.
 144      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 145      * returns true.
 146      * @see java.awt.GraphicsEnvironment#isHeadless
 147      */
 148     public Label(String text, int alignment) throws HeadlessException {
 149         GraphicsEnvironment.checkHeadless();
 150         this.text = text;
 151         setAlignment(alignment);
 152     }
 153 
 154     /**
 155      * Read a label from an object input stream.
 156      * @exception HeadlessException if
 157      * {@code GraphicsEnvironment.isHeadless()} returns
 158      * {@code true}
 159      * @serial
 160      * @since 1.4
 161      * @see java.awt.GraphicsEnvironment#isHeadless
 162      */
 163     private void readObject(ObjectInputStream s)
 164         throws ClassNotFoundException, IOException, HeadlessException {
 165         GraphicsEnvironment.checkHeadless();
 166         s.defaultReadObject();
 167     }
 168 
 169     /**
 170      * Construct a name for this component.  Called by getName() when the
 171      * name is {@code null}.
 172      */
 173     String constructComponentName() {
 174         synchronized (Label.class) {
 175             return base + nameCounter++;
 176         }
 177     }
 178 
 179     /**
 180      * Creates the peer for this label.  The peer allows us to
 181      * modify the appearance of the label without changing its
 182      * functionality.
 183      */
 184     public void addNotify() {
 185         synchronized (getTreeLock()) {
 186             if (peer == null)
 187                 peer = getComponentFactory().createLabel(this);
 188             super.addNotify();
 189         }
 190     }
 191 
 192     /**
 193      * Gets the current alignment of this label. Possible values are
 194      * {@code Label.LEFT}, {@code Label.RIGHT}, and
 195      * {@code Label.CENTER}.
 196      * @return the alignment of this label
 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},
 206      * {@code Label.RIGHT}, and {@code Label.CENTER}.
 207      * @param      alignment    the alignment to be set.
 208      * @exception  IllegalArgumentException if an improper value for
 209      *                          {@code alignment} 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} if
 230      *             the text has been set to {@code null}.
 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} is {@code null}, it is
 241      *             treated for display purposes like an empty
 242      *             string {@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}.
 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}.
 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} 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         /**
 326          * Constructor for the accessible label.
 327          */
 328         public AccessibleAWTLabel() {
 329             super();
 330         }
 331 
 332         /**
 333          * Get the accessible name of this object.
 334          *
 335          * @return the localized name of the object -- can be null if this
 336          * object does not have a name
 337          * @see AccessibleContext#setAccessibleName
 338          */
 339         public String getAccessibleName() {
 340             if (accessibleName != null) {
 341                 return accessibleName;
 342             } else {
 343                 if (getText() == null) {
 344                     return super.getAccessibleName();
 345                 } else {
 346                     return getText();
 347                 }
 348             }
 349         }
 350 
 351         /**
 352          * Get the role of this object.
 353          *
 354          * @return an instance of AccessibleRole describing the role of the object
 355          * @see AccessibleRole
 356          */
 357         public AccessibleRole getAccessibleRole() {
 358             return AccessibleRole.LABEL;
 359         }
 360 
 361     } // inner class AccessibleAWTLabel
 362 
 363 }