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.TextFieldPeer;
  28 import java.awt.event.*;
  29 import java.util.EventListener;
  30 import java.io.ObjectOutputStream;
  31 import java.io.ObjectInputStream;
  32 import java.io.IOException;
  33 import javax.accessibility.*;
  34 
  35 
  36 /**
  37  * A <code>TextField</code> object is a text component
  38  * that allows for the editing of a single line of text.
  39  * <p>
  40  * For example, the following image depicts a frame with four
  41  * text fields of varying widths. Two of these text fields
  42  * display the predefined text <code>"Hello"</code>.
  43  * <p>
  44  * <img src="doc-files/TextField-1.gif" alt="The preceding text describes this image."
  45  * style="float:center; margin: 7px 10px;">
  46  * <p>
  47  * Here is the code that produces these four text fields:
  48  *
  49  * <hr><blockquote><pre>
  50  * TextField tf1, tf2, tf3, tf4;
  51  * // a blank text field
  52  * tf1 = new TextField();
  53  * // blank field of 20 columns
  54  * tf2 = new TextField("", 20);
  55  * // predefined text displayed
  56  * tf3 = new TextField("Hello!");
  57  * // predefined text in 30 columns
  58  * tf4 = new TextField("Hello", 30);
  59  * </pre></blockquote><hr>
  60  * <p>
  61  * Every time the user types a key in the text field, one or
  62  * more key events are sent to the text field.  A <code>KeyEvent</code>
  63  * may be one of three types: keyPressed, keyReleased, or keyTyped.
  64  * The properties of a key event indicate which of these types
  65  * it is, as well as additional information about the event,
  66  * such as what modifiers are applied to the key event and the
  67  * time at which the event occurred.
  68  * <p>
  69  * The key event is passed to every <code>KeyListener</code>
  70  * or <code>KeyAdapter</code> object which registered to receive such
  71  * events using the component's <code>addKeyListener</code> method.
  72  * (<code>KeyAdapter</code> objects implement the
  73  * <code>KeyListener</code> interface.)
  74  * <p>
  75  * It is also possible to fire an <code>ActionEvent</code>.
  76  * If action events are enabled for the text field, they may
  77  * be fired by pressing the <code>Return</code> key.
  78  * <p>
  79  * The <code>TextField</code> class's <code>processEvent</code>
  80  * method examines the action event and passes it along to
  81  * <code>processActionEvent</code>. The latter method redirects the
  82  * event to any <code>ActionListener</code> objects that have
  83  * registered to receive action events generated by this
  84  * text field.
  85  *
  86  * @author      Sami Shaio
  87  * @see         java.awt.event.KeyEvent
  88  * @see         java.awt.event.KeyAdapter
  89  * @see         java.awt.event.KeyListener
  90  * @see         java.awt.event.ActionEvent
  91  * @see         java.awt.Component#addKeyListener
  92  * @see         java.awt.TextField#processEvent
  93  * @see         java.awt.TextField#processActionEvent
  94  * @see         java.awt.TextField#addActionListener
  95  * @since       1.0
  96  */
  97 public class TextField extends TextComponent {
  98 
  99     /**
 100      * The number of columns in the text field.
 101      * A column is an approximate average character
 102      * width that is platform-dependent.
 103      * Guaranteed to be non-negative.
 104      *
 105      * @serial
 106      * @see #setColumns(int)
 107      * @see #getColumns()
 108      */
 109     int columns;
 110 
 111     /**
 112      * The echo character, which is used when
 113      * the user wishes to disguise the characters
 114      * typed into the text field.
 115      * The disguises are removed if echoChar = <code>0</code>.
 116      *
 117      * @serial
 118      * @see #getEchoChar()
 119      * @see #setEchoChar(char)
 120      * @see #echoCharIsSet()
 121      */
 122     char echoChar;
 123 
 124     transient ActionListener actionListener;
 125 
 126     private static final String base = "textfield";
 127     private static int nameCounter = 0;
 128 
 129     /*
 130      * JDK 1.1 serialVersionUID
 131      */
 132     private static final long serialVersionUID = -2966288784432217853L;
 133 
 134     /**
 135      * Initialize JNI field and method ids
 136      */
 137     private static native void initIDs();
 138 
 139     static {
 140         /* ensure that the necessary native libraries are loaded */
 141         Toolkit.loadLibraries();
 142         if (!GraphicsEnvironment.isHeadless()) {
 143             initIDs();
 144         }
 145     }
 146 
 147     /**
 148      * Constructs a new text field.
 149      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 150      * returns true.
 151      * @see java.awt.GraphicsEnvironment#isHeadless
 152      */
 153     public TextField() throws HeadlessException {
 154         this("", 0);
 155     }
 156 
 157     /**
 158      * Constructs a new text field initialized with the specified text.
 159      * @param      text       the text to be displayed. If
 160      *             <code>text</code> is <code>null</code>, the empty
 161      *             string <code>""</code> will be displayed.
 162      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 163      * returns true.
 164      * @see java.awt.GraphicsEnvironment#isHeadless
 165      */
 166     public TextField(String text) throws HeadlessException {
 167         this(text, (text != null) ? text.length() : 0);
 168     }
 169 
 170     /**
 171      * Constructs a new empty text field with the specified number
 172      * of columns.  A column is an approximate average character
 173      * width that is platform-dependent.
 174      * @param      columns     the number of columns.  If
 175      *             <code>columns</code> is less than <code>0</code>,
 176      *             <code>columns</code> is set to <code>0</code>.
 177      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 178      * returns true.
 179      * @see java.awt.GraphicsEnvironment#isHeadless
 180      */
 181     public TextField(int columns) throws HeadlessException {
 182         this("", columns);
 183     }
 184 
 185     /**
 186      * Constructs a new text field initialized with the specified text
 187      * to be displayed, and wide enough to hold the specified
 188      * number of columns. A column is an approximate average character
 189      * width that is platform-dependent.
 190      * @param      text       the text to be displayed. If
 191      *             <code>text</code> is <code>null</code>, the empty
 192      *             string <code>""</code> will be displayed.
 193      * @param      columns     the number of columns.  If
 194      *             <code>columns</code> is less than <code>0</code>,
 195      *             <code>columns</code> is set to <code>0</code>.
 196      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 197      * returns true.
 198      * @see java.awt.GraphicsEnvironment#isHeadless
 199      */
 200     public TextField(String text, int columns) throws HeadlessException {
 201         super(replaceEOL(text));
 202         this.columns = (columns >= 0) ? columns : 0;
 203     }
 204 
 205     /**
 206      * Construct a name for this component.  Called by getName() when the
 207      * name is null.
 208      */
 209     String constructComponentName() {
 210         synchronized (TextField.class) {
 211             return base + nameCounter++;
 212         }
 213     }
 214 
 215     /**
 216      * Creates the TextField's peer.  The peer allows us to modify the
 217      * appearance of the TextField without changing its functionality.
 218      */
 219     public void addNotify() {
 220         synchronized (getTreeLock()) {
 221             if (peer == null)
 222                 peer = getComponentFactory().createTextField(this);
 223             super.addNotify();
 224         }
 225     }
 226 
 227     /**
 228      * Gets the character that is to be used for echoing.
 229      * <p>
 230      * An echo character is useful for text fields where
 231      * user input should not be echoed to the screen, as in
 232      * the case of a text field for entering a password.
 233      * If <code>echoChar</code> = <code>0</code>, user
 234      * input is echoed to the screen unchanged.
 235      * <p>
 236      * A Java platform implementation may support only a limited,
 237      * non-empty set of echo characters. This function returns the
 238      * echo character originally requested via setEchoChar(). The echo
 239      * character actually used by the TextField implementation might be
 240      * different.
 241      * @return      the echo character for this text field.
 242      * @see         java.awt.TextField#echoCharIsSet
 243      * @see         java.awt.TextField#setEchoChar
 244      */
 245     public char getEchoChar() {
 246         return echoChar;
 247     }
 248 
 249     /**
 250      * Sets the echo character for this text field.
 251      * <p>
 252      * An echo character is useful for text fields where
 253      * user input should not be echoed to the screen, as in
 254      * the case of a text field for entering a password.
 255      * Setting <code>echoChar</code> = <code>0</code> allows
 256      * user input to be echoed to the screen again.
 257      * <p>
 258      * A Java platform implementation may support only a limited,
 259      * non-empty set of echo characters. Attempts to set an
 260      * unsupported echo character will cause the default echo
 261      * character to be used instead. Subsequent calls to getEchoChar()
 262      * will return the echo character originally requested. This might
 263      * or might not be identical to the echo character actually
 264      * used by the TextField implementation.
 265      * @param       c   the echo character for this text field.
 266      * @see         java.awt.TextField#echoCharIsSet
 267      * @see         java.awt.TextField#getEchoChar
 268      * @since       1.1
 269      */
 270     public void setEchoChar(char c) {
 271         setEchoCharacter(c);
 272     }
 273 
 274     /**
 275      * Sets the character to be echoed when protected input is displayed.
 276      *
 277      *  @param  c the echo character for this text field
 278      *
 279      * @deprecated As of JDK version 1.1,
 280      * replaced by <code>setEchoChar(char)</code>.
 281      */
 282     @Deprecated
 283     public synchronized void setEchoCharacter(char c) {
 284         if (echoChar != c) {
 285             echoChar = c;
 286             TextFieldPeer peer = (TextFieldPeer)this.peer;
 287             if (peer != null) {
 288                 peer.setEchoChar(c);
 289             }
 290         }
 291     }
 292 
 293     /**
 294      * Sets the text that is presented by this
 295      * text component to be the specified text.
 296      * @param       t   the new text.
 297      * @see         java.awt.TextComponent#getText
 298      */
 299     public void setText(String t) {
 300         super.setText(replaceEOL(t));
 301 
 302         // This could change the preferred size of the Component.
 303         invalidateIfValid();
 304     }
 305 
 306     /**
 307      * Replaces EOL characters from the text variable with a space character.
 308      * @param       text   the new text.
 309      * @return      Returns text after replacing EOL characters.
 310      */
 311     private static String replaceEOL(String text) {
 312         String[] strEOLs = {System.lineSeparator(), "\n"};
 313         for (String eol : strEOLs) {
 314             if (text.contains(eol)) {
 315                 text = text.replace(eol, " ");
 316             }
 317         }
 318         return text;
 319     }
 320 
 321 
 322     /**
 323      * Indicates whether or not this text field has a
 324      * character set for echoing.
 325      * <p>
 326      * An echo character is useful for text fields where
 327      * user input should not be echoed to the screen, as in
 328      * the case of a text field for entering a password.
 329      * @return     <code>true</code> if this text field has
 330      *                 a character set for echoing;
 331      *                 <code>false</code> otherwise.
 332      * @see        java.awt.TextField#setEchoChar
 333      * @see        java.awt.TextField#getEchoChar
 334      */
 335     public boolean echoCharIsSet() {
 336         return echoChar != 0;
 337     }
 338 
 339     /**
 340      * Gets the number of columns in this text field. A column is an
 341      * approximate average character width that is platform-dependent.
 342      * @return     the number of columns.
 343      * @see        java.awt.TextField#setColumns
 344      * @since      1.1
 345      */
 346     public int getColumns() {
 347         return columns;
 348     }
 349 
 350     /**
 351      * Sets the number of columns in this text field. A column is an
 352      * approximate average character width that is platform-dependent.
 353      * @param      columns   the number of columns.
 354      * @see        java.awt.TextField#getColumns
 355      * @exception  IllegalArgumentException   if the value
 356      *                 supplied for <code>columns</code>
 357      *                 is less than <code>0</code>.
 358      * @since      1.1
 359      */
 360     public void setColumns(int columns) {
 361         int oldVal;
 362         synchronized (this) {
 363             oldVal = this.columns;
 364             if (columns < 0) {
 365                 throw new IllegalArgumentException("columns less than zero.");
 366             }
 367             if (columns != oldVal) {
 368                 this.columns = columns;
 369             }
 370         }
 371 
 372         if (columns != oldVal) {
 373             invalidate();
 374         }
 375     }
 376 
 377     /**
 378      * Gets the preferred size of this text field
 379      * with the specified number of columns.
 380      * @param     columns the number of columns
 381      *                 in this text field.
 382      * @return    the preferred dimensions for
 383      *                 displaying this text field.
 384      * @since     1.1
 385      */
 386     public Dimension getPreferredSize(int columns) {
 387         return preferredSize(columns);
 388     }
 389 
 390     /**
 391      * Returns the preferred size for this text field
 392      * with the specified number of columns.
 393      *
 394      * @param  columns the number of columns
 395      * @return the preferred size for the text field
 396      *
 397      * @deprecated As of JDK version 1.1,
 398      * replaced by <code>getPreferredSize(int)</code>.
 399      */
 400     @Deprecated
 401     public Dimension preferredSize(int columns) {
 402         synchronized (getTreeLock()) {
 403             TextFieldPeer peer = (TextFieldPeer)this.peer;
 404             return (peer != null) ?
 405                        peer.getPreferredSize(columns) :
 406                        super.preferredSize();
 407         }
 408     }
 409 
 410     /**
 411      * Gets the preferred size of this text field.
 412      * @return     the preferred dimensions for
 413      *                         displaying this text field.
 414      * @since      1.1
 415      */
 416     public Dimension getPreferredSize() {
 417         return preferredSize();
 418     }
 419 
 420     /**
 421      * @deprecated As of JDK version 1.1,
 422      * replaced by <code>getPreferredSize()</code>.
 423      */
 424     @Deprecated
 425     public Dimension preferredSize() {
 426         synchronized (getTreeLock()) {
 427             return (columns > 0) ?
 428                        preferredSize(columns) :
 429                        super.preferredSize();
 430         }
 431     }
 432 
 433     /**
 434      * Gets the minimum dimensions for a text field with
 435      * the specified number of columns.
 436      * @param  columns the number of columns in
 437      *         this text field.
 438      * @return the minimum size for this text field
 439      * @since    1.1
 440      */
 441     public Dimension getMinimumSize(int columns) {
 442         return minimumSize(columns);
 443     }
 444 
 445     /**
 446      * Returns the minimum dimensions for a text field with
 447      * the specified number of columns.
 448      *
 449      * @param  columns the number of columns
 450      * @return the minimum size for this text field
 451      * @deprecated As of JDK version 1.1,
 452      * replaced by <code>getMinimumSize(int)</code>.
 453      */
 454     @Deprecated
 455     public Dimension minimumSize(int columns) {
 456         synchronized (getTreeLock()) {
 457             TextFieldPeer peer = (TextFieldPeer)this.peer;
 458             return (peer != null) ?
 459                        peer.getMinimumSize(columns) :
 460                        super.minimumSize();
 461         }
 462     }
 463 
 464     /**
 465      * Gets the minimum dimensions for this text field.
 466      * @return     the minimum dimensions for
 467      *                  displaying this text field.
 468      * @since      1.1
 469      */
 470     public Dimension getMinimumSize() {
 471         return minimumSize();
 472     }
 473 
 474     /**
 475      * @deprecated As of JDK version 1.1,
 476      * replaced by <code>getMinimumSize()</code>.
 477      */
 478     @Deprecated
 479     public Dimension minimumSize() {
 480         synchronized (getTreeLock()) {
 481             return (columns > 0) ?
 482                        minimumSize(columns) :
 483                        super.minimumSize();
 484         }
 485     }
 486 
 487     /**
 488      * Adds the specified action listener to receive
 489      * action events from this text field.
 490      * If l is null, no exception is thrown and no action is performed.
 491      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
 492      * >AWT Threading Issues</a> for details on AWT's threading model.
 493      *
 494      * @param      l the action listener.
 495      * @see        #removeActionListener
 496      * @see        #getActionListeners
 497      * @see        java.awt.event.ActionListener
 498      * @since      1.1
 499      */
 500     public synchronized void addActionListener(ActionListener l) {
 501         if (l == null) {
 502             return;
 503         }
 504         actionListener = AWTEventMulticaster.add(actionListener, l);
 505         newEventsOnly = true;
 506     }
 507 
 508     /**
 509      * Removes the specified action listener so that it no longer
 510      * receives action events from this text field.
 511      * If l is null, no exception is thrown and no action is performed.
 512      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
 513      * >AWT Threading Issues</a> for details on AWT's threading model.
 514      *
 515      * @param           l the action listener.
 516      * @see             #addActionListener
 517      * @see             #getActionListeners
 518      * @see             java.awt.event.ActionListener
 519      * @since           1.1
 520      */
 521     public synchronized void removeActionListener(ActionListener l) {
 522         if (l == null) {
 523             return;
 524         }
 525         actionListener = AWTEventMulticaster.remove(actionListener, l);
 526     }
 527 
 528     /**
 529      * Returns an array of all the action listeners
 530      * registered on this textfield.
 531      *
 532      * @return all of this textfield's <code>ActionListener</code>s
 533      *         or an empty array if no action
 534      *         listeners are currently registered
 535      *
 536      * @see #addActionListener
 537      * @see #removeActionListener
 538      * @see java.awt.event.ActionListener
 539      * @since 1.4
 540      */
 541     public synchronized ActionListener[] getActionListeners() {
 542         return getListeners(ActionListener.class);
 543     }
 544 
 545     /**
 546      * Returns an array of all the objects currently registered
 547      * as <code><em>Foo</em>Listener</code>s
 548      * upon this <code>TextField</code>.
 549      * <code><em>Foo</em>Listener</code>s are registered using the
 550      * <code>add<em>Foo</em>Listener</code> method.
 551      *
 552      * <p>
 553      * You can specify the <code>listenerType</code> argument
 554      * with a class literal, such as
 555      * <code><em>Foo</em>Listener.class</code>.
 556      * For example, you can query a
 557      * <code>TextField</code> <code>t</code>
 558      * for its action listeners with the following code:
 559      *
 560      * <pre>ActionListener[] als = (ActionListener[])(t.getListeners(ActionListener.class));</pre>
 561      *
 562      * If no such listeners exist, this method returns an empty array.
 563      *
 564      * @param listenerType the type of listeners requested; this parameter
 565      *          should specify an interface that descends from
 566      *          <code>java.util.EventListener</code>
 567      * @return an array of all objects registered as
 568      *          <code><em>Foo</em>Listener</code>s on this textfield,
 569      *          or an empty array if no such
 570      *          listeners have been added
 571      * @exception ClassCastException if <code>listenerType</code>
 572      *          doesn't specify a class or interface that implements
 573      *          <code>java.util.EventListener</code>
 574      *
 575      * @see #getActionListeners
 576      * @since 1.3
 577      */
 578     public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
 579         EventListener l = null;
 580         if  (listenerType == ActionListener.class) {
 581             l = actionListener;
 582         } else {
 583             return super.getListeners(listenerType);
 584         }
 585         return AWTEventMulticaster.getListeners(l, listenerType);
 586     }
 587 
 588     // REMIND: remove when filtering is done at lower level
 589     boolean eventEnabled(AWTEvent e) {
 590         if (e.id == ActionEvent.ACTION_PERFORMED) {
 591             if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0 ||
 592                 actionListener != null) {
 593                 return true;
 594             }
 595             return false;
 596         }
 597         return super.eventEnabled(e);
 598     }
 599 
 600     /**
 601      * Processes events on this text field. If the event
 602      * is an instance of <code>ActionEvent</code>,
 603      * it invokes the <code>processActionEvent</code>
 604      * method. Otherwise, it invokes <code>processEvent</code>
 605      * on the superclass.
 606      * <p>Note that if the event parameter is <code>null</code>
 607      * the behavior is unspecified and may result in an
 608      * exception.
 609      *
 610      * @param      e the event
 611      * @see        java.awt.event.ActionEvent
 612      * @see        java.awt.TextField#processActionEvent
 613      * @since      1.1
 614      */
 615     protected void processEvent(AWTEvent e) {
 616         if (e instanceof ActionEvent) {
 617             processActionEvent((ActionEvent)e);
 618             return;
 619         }
 620         super.processEvent(e);
 621     }
 622 
 623     /**
 624      * Processes action events occurring on this text field by
 625      * dispatching them to any registered
 626      * <code>ActionListener</code> objects.
 627      * <p>
 628      * This method is not called unless action events are
 629      * enabled for this component. Action events are enabled
 630      * when one of the following occurs:
 631      * <ul>
 632      * <li>An <code>ActionListener</code> object is registered
 633      * via <code>addActionListener</code>.
 634      * <li>Action events are enabled via <code>enableEvents</code>.
 635      * </ul>
 636      * <p>Note that if the event parameter is <code>null</code>
 637      * the behavior is unspecified and may result in an
 638      * exception.
 639      *
 640      * @param       e the action event
 641      * @see         java.awt.event.ActionListener
 642      * @see         java.awt.TextField#addActionListener
 643      * @see         java.awt.Component#enableEvents
 644      * @since       1.1
 645      */
 646     protected void processActionEvent(ActionEvent e) {
 647         ActionListener listener = actionListener;
 648         if (listener != null) {
 649             listener.actionPerformed(e);
 650         }
 651     }
 652 
 653     /**
 654      * Returns a string representing the state of this <code>TextField</code>.
 655      * This method is intended to be used only for debugging purposes, and the
 656      * content and format of the returned string may vary between
 657      * implementations. The returned string may be empty but may not be
 658      * <code>null</code>.
 659      *
 660      * @return      the parameter string of this text field
 661      */
 662     protected String paramString() {
 663         String str = super.paramString();
 664         if (echoChar != 0) {
 665             str += ",echo=" + echoChar;
 666         }
 667         return str;
 668     }
 669 
 670 
 671     /*
 672      * Serialization support.
 673      */
 674     /**
 675      * The textField Serialized Data Version.
 676      *
 677      * @serial
 678      */
 679     private int textFieldSerializedDataVersion = 1;
 680 
 681     /**
 682      * Writes default serializable fields to stream.  Writes
 683      * a list of serializable ActionListener(s) as optional data.
 684      * The non-serializable ActionListener(s) are detected and
 685      * no attempt is made to serialize them.
 686      *
 687      * @serialData Null terminated sequence of zero or more pairs.
 688      *             A pair consists of a String and Object.
 689      *             The String indicates the type of object and
 690      *             is one of the following :
 691      *             ActionListenerK indicating and ActionListener object.
 692      *
 693      * @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
 694      * @see java.awt.Component#actionListenerK
 695      */
 696     private void writeObject(ObjectOutputStream s)
 697       throws IOException
 698     {
 699         s.defaultWriteObject();
 700 
 701         AWTEventMulticaster.save(s, actionListenerK, actionListener);
 702         s.writeObject(null);
 703     }
 704 
 705     /**
 706      * Read the ObjectInputStream and if it isn't null,
 707      * add a listener to receive action events fired by the
 708      * TextField.  Unrecognized keys or values will be
 709      * ignored.
 710      *
 711      * @exception HeadlessException if
 712      * <code>GraphicsEnvironment.isHeadless()</code> returns
 713      * <code>true</code>
 714      * @see #removeActionListener(ActionListener)
 715      * @see #addActionListener(ActionListener)
 716      * @see java.awt.GraphicsEnvironment#isHeadless
 717      */
 718     private void readObject(ObjectInputStream s)
 719       throws ClassNotFoundException, IOException, HeadlessException
 720     {
 721         // HeadlessException will be thrown by TextComponent's readObject
 722         s.defaultReadObject();
 723         text = replaceEOL(text);
 724 
 725         // Make sure the state we just read in for columns has legal values
 726         if (columns < 0) {
 727             columns = 0;
 728         }
 729 
 730         // Read in listeners, if any
 731         Object keyOrNull;
 732         while(null != (keyOrNull = s.readObject())) {
 733             String key = ((String)keyOrNull).intern();
 734 
 735             if (actionListenerK == key) {
 736                 addActionListener((ActionListener)(s.readObject()));
 737             } else {
 738                 // skip value for unrecognized key
 739                 s.readObject();
 740             }
 741         }
 742     }
 743 
 744 
 745 /////////////////
 746 // Accessibility support
 747 ////////////////
 748 
 749 
 750     /**
 751      * Gets the AccessibleContext associated with this TextField.
 752      * For text fields, the AccessibleContext takes the form of an
 753      * AccessibleAWTTextField.
 754      * A new AccessibleAWTTextField instance is created if necessary.
 755      *
 756      * @return an AccessibleAWTTextField that serves as the
 757      *         AccessibleContext of this TextField
 758      * @since 1.3
 759      */
 760     public AccessibleContext getAccessibleContext() {
 761         if (accessibleContext == null) {
 762             accessibleContext = new AccessibleAWTTextField();
 763         }
 764         return accessibleContext;
 765     }
 766 
 767     /**
 768      * This class implements accessibility support for the
 769      * <code>TextField</code> class.  It provides an implementation of the
 770      * Java Accessibility API appropriate to text field user-interface elements.
 771      * @since 1.3
 772      */
 773     protected class AccessibleAWTTextField extends AccessibleAWTTextComponent
 774     {
 775         /*
 776          * JDK 1.3 serialVersionUID
 777          */
 778         private static final long serialVersionUID = 6219164359235943158L;
 779 
 780         /**
 781          * Gets the state set of this object.
 782          *
 783          * @return an instance of AccessibleStateSet describing the states
 784          * of the object
 785          * @see AccessibleState
 786          */
 787         public AccessibleStateSet getAccessibleStateSet() {
 788             AccessibleStateSet states = super.getAccessibleStateSet();
 789             states.add(AccessibleState.SINGLE_LINE);
 790             return states;
 791         }
 792     }
 793 
 794 }