View Javadoc
1   /*
2    * Copyright (c) 1995, 2013, 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       JDK1.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(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 = getToolkit().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       JDK1.1
269      */
270     public void setEchoChar(char c) {
271         setEchoCharacter(c);
272     }
273 
274     /**
275      * @deprecated As of JDK version 1.1,
276      * replaced by <code>setEchoChar(char)</code>.
277      */
278     @Deprecated
279     public synchronized void setEchoCharacter(char c) {
280         if (echoChar != c) {
281             echoChar = c;
282             TextFieldPeer peer = (TextFieldPeer)this.peer;
283             if (peer != null) {
284                 peer.setEchoChar(c);
285             }
286         }
287     }
288 
289     /**
290      * Sets the text that is presented by this
291      * text component to be the specified text.
292      * @param       t   the new text.
293      * @see         java.awt.TextComponent#getText
294      */
295     public void setText(String t) {
296         super.setText(t);
297 
298         // This could change the preferred size of the Component.
299         invalidateIfValid();
300     }
301 
302     /**
303      * Indicates whether or not this text field has a
304      * character set for echoing.
305      * <p>
306      * An echo character is useful for text fields where
307      * user input should not be echoed to the screen, as in
308      * the case of a text field for entering a password.
309      * @return     <code>true</code> if this text field has
310      *                 a character set for echoing;
311      *                 <code>false</code> otherwise.
312      * @see        java.awt.TextField#setEchoChar
313      * @see        java.awt.TextField#getEchoChar
314      */
315     public boolean echoCharIsSet() {
316         return echoChar != 0;
317     }
318 
319     /**
320      * Gets the number of columns in this text field. A column is an
321      * approximate average character width that is platform-dependent.
322      * @return     the number of columns.
323      * @see        java.awt.TextField#setColumns
324      * @since      JDK1.1
325      */
326     public int getColumns() {
327         return columns;
328     }
329 
330     /**
331      * Sets the number of columns in this text field. A column is an
332      * approximate average character width that is platform-dependent.
333      * @param      columns   the number of columns.
334      * @see        java.awt.TextField#getColumns
335      * @exception  IllegalArgumentException   if the value
336      *                 supplied for <code>columns</code>
337      *                 is less than <code>0</code>.
338      * @since      JDK1.1
339      */
340     public void setColumns(int columns) {
341         int oldVal;
342         synchronized (this) {
343             oldVal = this.columns;
344             if (columns < 0) {
345                 throw new IllegalArgumentException("columns less than zero.");
346             }
347             if (columns != oldVal) {
348                 this.columns = columns;
349             }
350         }
351 
352         if (columns != oldVal) {
353             invalidate();
354         }
355     }
356 
357     /**
358      * Gets the preferred size of this text field
359      * with the specified number of columns.
360      * @param     columns the number of columns
361      *                 in this text field.
362      * @return    the preferred dimensions for
363      *                 displaying this text field.
364      * @since     JDK1.1
365      */
366     public Dimension getPreferredSize(int columns) {
367         return preferredSize(columns);
368     }
369 
370     /**
371      * @deprecated As of JDK version 1.1,
372      * replaced by <code>getPreferredSize(int)</code>.
373      */
374     @Deprecated
375     public Dimension preferredSize(int columns) {
376         synchronized (getTreeLock()) {
377             TextFieldPeer peer = (TextFieldPeer)this.peer;
378             return (peer != null) ?
379                        peer.getPreferredSize(columns) :
380                        super.preferredSize();
381         }
382     }
383 
384     /**
385      * Gets the preferred size of this text field.
386      * @return     the preferred dimensions for
387      *                         displaying this text field.
388      * @since      JDK1.1
389      */
390     public Dimension getPreferredSize() {
391         return preferredSize();
392     }
393 
394     /**
395      * @deprecated As of JDK version 1.1,
396      * replaced by <code>getPreferredSize()</code>.
397      */
398     @Deprecated
399     public Dimension preferredSize() {
400         synchronized (getTreeLock()) {
401             return (columns > 0) ?
402                        preferredSize(columns) :
403                        super.preferredSize();
404         }
405     }
406 
407     /**
408      * Gets the minimum dimensions for a text field with
409      * the specified number of columns.
410      * @param    columns   the number of columns in
411      *                          this text field.
412      * @since    JDK1.1
413      */
414     public Dimension getMinimumSize(int columns) {
415         return minimumSize(columns);
416     }
417 
418     /**
419      * @deprecated As of JDK version 1.1,
420      * replaced by <code>getMinimumSize(int)</code>.
421      */
422     @Deprecated
423     public Dimension minimumSize(int columns) {
424         synchronized (getTreeLock()) {
425             TextFieldPeer peer = (TextFieldPeer)this.peer;
426             return (peer != null) ?
427                        peer.getMinimumSize(columns) :
428                        super.minimumSize();
429         }
430     }
431 
432     /**
433      * Gets the minimum dimensions for this text field.
434      * @return     the minimum dimensions for
435      *                  displaying this text field.
436      * @since      JDK1.1
437      */
438     public Dimension getMinimumSize() {
439         return minimumSize();
440     }
441 
442     /**
443      * @deprecated As of JDK version 1.1,
444      * replaced by <code>getMinimumSize()</code>.
445      */
446     @Deprecated
447     public Dimension minimumSize() {
448         synchronized (getTreeLock()) {
449             return (columns > 0) ?
450                        minimumSize(columns) :
451                        super.minimumSize();
452         }
453     }
454 
455     /**
456      * Adds the specified action listener to receive
457      * action events from this text field.
458      * If l is null, no exception is thrown and no action is performed.
459      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
460      * >AWT Threading Issues</a> for details on AWT's threading model.
461      *
462      * @param      l the action listener.
463      * @see        #removeActionListener
464      * @see        #getActionListeners
465      * @see        java.awt.event.ActionListener
466      * @since      JDK1.1
467      */
468     public synchronized void addActionListener(ActionListener l) {
469         if (l == null) {
470             return;
471         }
472         actionListener = AWTEventMulticaster.add(actionListener, l);
473         newEventsOnly = true;
474     }
475 
476     /**
477      * Removes the specified action listener so that it no longer
478      * receives action events from this text field.
479      * If l is null, no exception is thrown and no action is performed.
480      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
481      * >AWT Threading Issues</a> for details on AWT's threading model.
482      *
483      * @param           l the action listener.
484      * @see             #addActionListener
485      * @see             #getActionListeners
486      * @see             java.awt.event.ActionListener
487      * @since           JDK1.1
488      */
489     public synchronized void removeActionListener(ActionListener l) {
490         if (l == null) {
491             return;
492         }
493         actionListener = AWTEventMulticaster.remove(actionListener, l);
494     }
495 
496     /**
497      * Returns an array of all the action listeners
498      * registered on this textfield.
499      *
500      * @return all of this textfield's <code>ActionListener</code>s
501      *         or an empty array if no action
502      *         listeners are currently registered
503      *
504      * @see #addActionListener
505      * @see #removeActionListener
506      * @see java.awt.event.ActionListener
507      * @since 1.4
508      */
509     public synchronized ActionListener[] getActionListeners() {
510         return getListeners(ActionListener.class);
511     }
512 
513     /**
514      * Returns an array of all the objects currently registered
515      * as <code><em>Foo</em>Listener</code>s
516      * upon this <code>TextField</code>.
517      * <code><em>Foo</em>Listener</code>s are registered using the
518      * <code>add<em>Foo</em>Listener</code> method.
519      *
520      * <p>
521      * You can specify the <code>listenerType</code> argument
522      * with a class literal, such as
523      * <code><em>Foo</em>Listener.class</code>.
524      * For example, you can query a
525      * <code>TextField</code> <code>t</code>
526      * for its action listeners with the following code:
527      *
528      * <pre>ActionListener[] als = (ActionListener[])(t.getListeners(ActionListener.class));</pre>
529      *
530      * If no such listeners exist, this method returns an empty array.
531      *
532      * @param listenerType the type of listeners requested; this parameter
533      *          should specify an interface that descends from
534      *          <code>java.util.EventListener</code>
535      * @return an array of all objects registered as
536      *          <code><em>Foo</em>Listener</code>s on this textfield,
537      *          or an empty array if no such
538      *          listeners have been added
539      * @exception ClassCastException if <code>listenerType</code>
540      *          doesn't specify a class or interface that implements
541      *          <code>java.util.EventListener</code>
542      *
543      * @see #getActionListeners
544      * @since 1.3
545      */
546     public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
547         EventListener l = null;
548         if  (listenerType == ActionListener.class) {
549             l = actionListener;
550         } else {
551             return super.getListeners(listenerType);
552         }
553         return AWTEventMulticaster.getListeners(l, listenerType);
554     }
555 
556     // REMIND: remove when filtering is done at lower level
557     boolean eventEnabled(AWTEvent e) {
558         if (e.id == ActionEvent.ACTION_PERFORMED) {
559             if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0 ||
560                 actionListener != null) {
561                 return true;
562             }
563             return false;
564         }
565         return super.eventEnabled(e);
566     }
567 
568     /**
569      * Processes events on this text field. If the event
570      * is an instance of <code>ActionEvent</code>,
571      * it invokes the <code>processActionEvent</code>
572      * method. Otherwise, it invokes <code>processEvent</code>
573      * on the superclass.
574      * <p>Note that if the event parameter is <code>null</code>
575      * the behavior is unspecified and may result in an
576      * exception.
577      *
578      * @param      e the event
579      * @see        java.awt.event.ActionEvent
580      * @see        java.awt.TextField#processActionEvent
581      * @since      JDK1.1
582      */
583     protected void processEvent(AWTEvent e) {
584         if (e instanceof ActionEvent) {
585             processActionEvent((ActionEvent)e);
586             return;
587         }
588         super.processEvent(e);
589     }
590 
591     /**
592      * Processes action events occurring on this text field by
593      * dispatching them to any registered
594      * <code>ActionListener</code> objects.
595      * <p>
596      * This method is not called unless action events are
597      * enabled for this component. Action events are enabled
598      * when one of the following occurs:
599      * <ul>
600      * <li>An <code>ActionListener</code> object is registered
601      * via <code>addActionListener</code>.
602      * <li>Action events are enabled via <code>enableEvents</code>.
603      * </ul>
604      * <p>Note that if the event parameter is <code>null</code>
605      * the behavior is unspecified and may result in an
606      * exception.
607      *
608      * @param       e the action event
609      * @see         java.awt.event.ActionListener
610      * @see         java.awt.TextField#addActionListener
611      * @see         java.awt.Component#enableEvents
612      * @since       JDK1.1
613      */
614     protected void processActionEvent(ActionEvent e) {
615         ActionListener listener = actionListener;
616         if (listener != null) {
617             listener.actionPerformed(e);
618         }
619     }
620 
621     /**
622      * Returns a string representing the state of this <code>TextField</code>.
623      * This method is intended to be used only for debugging purposes, and the
624      * content and format of the returned string may vary between
625      * implementations. The returned string may be empty but may not be
626      * <code>null</code>.
627      *
628      * @return      the parameter string of this text field
629      */
630     protected String paramString() {
631         String str = super.paramString();
632         if (echoChar != 0) {
633             str += ",echo=" + echoChar;
634         }
635         return str;
636     }
637 
638 
639     /*
640      * Serialization support.
641      */
642     /**
643      * The textField Serialized Data Version.
644      *
645      * @serial
646      */
647     private int textFieldSerializedDataVersion = 1;
648 
649     /**
650      * Writes default serializable fields to stream.  Writes
651      * a list of serializable ActionListener(s) as optional data.
652      * The non-serializable ActionListener(s) are detected and
653      * no attempt is made to serialize them.
654      *
655      * @serialData Null terminated sequence of zero or more pairs.
656      *             A pair consists of a String and Object.
657      *             The String indicates the type of object and
658      *             is one of the following :
659      *             ActionListenerK indicating and ActionListener object.
660      *
661      * @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
662      * @see java.awt.Component#actionListenerK
663      */
664     private void writeObject(ObjectOutputStream s)
665       throws IOException
666     {
667         s.defaultWriteObject();
668 
669         AWTEventMulticaster.save(s, actionListenerK, actionListener);
670         s.writeObject(null);
671     }
672 
673     /**
674      * Read the ObjectInputStream and if it isn't null,
675      * add a listener to receive action events fired by the
676      * TextField.  Unrecognized keys or values will be
677      * ignored.
678      *
679      * @exception HeadlessException if
680      * <code>GraphicsEnvironment.isHeadless()</code> returns
681      * <code>true</code>
682      * @see #removeActionListener(ActionListener)
683      * @see #addActionListener(ActionListener)
684      * @see java.awt.GraphicsEnvironment#isHeadless
685      */
686     private void readObject(ObjectInputStream s)
687       throws ClassNotFoundException, IOException, HeadlessException
688     {
689         // HeadlessException will be thrown by TextComponent's readObject
690         s.defaultReadObject();
691 
692         // Make sure the state we just read in for columns has legal values
693         if (columns < 0) {
694             columns = 0;
695         }
696 
697         // Read in listeners, if any
698         Object keyOrNull;
699         while(null != (keyOrNull = s.readObject())) {
700             String key = ((String)keyOrNull).intern();
701 
702             if (actionListenerK == key) {
703                 addActionListener((ActionListener)(s.readObject()));
704             } else {
705                 // skip value for unrecognized key
706                 s.readObject();
707             }
708         }
709     }
710 
711 
712 /////////////////
713 // Accessibility support
714 ////////////////
715 
716 
717     /**
718      * Gets the AccessibleContext associated with this TextField.
719      * For text fields, the AccessibleContext takes the form of an
720      * AccessibleAWTTextField.
721      * A new AccessibleAWTTextField instance is created if necessary.
722      *
723      * @return an AccessibleAWTTextField that serves as the
724      *         AccessibleContext of this TextField
725      * @since 1.3
726      */
727     public AccessibleContext getAccessibleContext() {
728         if (accessibleContext == null) {
729             accessibleContext = new AccessibleAWTTextField();
730         }
731         return accessibleContext;
732     }
733 
734     /**
735      * This class implements accessibility support for the
736      * <code>TextField</code> class.  It provides an implementation of the
737      * Java Accessibility API appropriate to text field user-interface elements.
738      * @since 1.3
739      */
740     protected class AccessibleAWTTextField extends AccessibleAWTTextComponent
741     {
742         /*
743          * JDK 1.3 serialVersionUID
744          */
745         private static final long serialVersionUID = 6219164359235943158L;
746 
747         /**
748          * Gets the state set of this object.
749          *
750          * @return an instance of AccessibleStateSet describing the states
751          * of the object
752          * @see AccessibleState
753          */
754         public AccessibleStateSet getAccessibleStateSet() {
755             AccessibleStateSet states = super.getAccessibleStateSet();
756             states.add(AccessibleState.SINGLE_LINE);
757             return states;
758         }
759     }
760 
761 }