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