1 /* TextField.java -- A one line text entry field
2    Copyright (C) 1999, 2002, 2004, 2006,  Free Software Foundation, Inc.
3 
4 This file is part of GNU Classpath.
5 
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20 
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25 
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37 
38 
39 package java.awt;
40 
41 import java.awt.event.ActionEvent;
42 import java.awt.event.ActionListener;
43 import java.awt.peer.ComponentPeer;
44 import java.awt.peer.TextFieldPeer;
45 import java.util.EventListener;
46 
47 import javax.accessibility.AccessibleContext;
48 import javax.accessibility.AccessibleStateSet;
49 
50 /**
51  * This class implements a single line text entry field widget
52  *
53  * @author Aaron M. Renn (arenn@urbanophile.com)
54  */
55 public class TextField extends TextComponent
56 {
57 
58   /**
59    * The number used to generate the name returned by getName.
60    */
61   private static transient long next_textfield_number;
62 
63 
64   private static final long serialVersionUID = -2966288784432217853L;
65 
66 
67   /**
68    * @serial The number of columns in the text entry field.
69    */
70   private int columns;
71 
72   /**
73    * @serial The character that is echoed when doing protected input
74    */
75   private char echoChar;
76 
77   // List of registered ActionListener's for this object.
78   private ActionListener action_listeners;
79 
80   /**
81    * Initializes a new instance of <code>TextField</code> that is empty
82    * and has one column.
83    *
84    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
85    */
TextField()86   public TextField()
87   {
88     this("", 0);
89   }
90 
91   /**
92    * Initializes a new instance of <code>TextField</code> containing
93    * the specified text.  The number of columns will be equal to the
94    * length of the text string.
95    *
96    * @param text The text to display in the field.
97    *
98    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
99    */
TextField(String text)100   public TextField(String text)
101   {
102     this(text, (text == null) ? 0 : text.length());
103   }
104 
105   /**
106    * Initializes a new instance of <code>TextField</code> that is empty
107    * and has the specified number of columns.
108    *
109    * @param columns The number of columns in the text field.
110    *
111    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
112    */
TextField(int columns)113   public TextField(int columns)
114   {
115     this("", columns);
116   }
117 
118   /**
119    * Initializes a new instance of <code>TextField</code> with the
120    * specified text and number of columns.
121    *
122    * @param text The text to display in the field.
123    * @param columns The number of columns in the field.
124    *
125    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
126    */
TextField(String text, int columns)127   public TextField(String text, int columns)
128   {
129     super(text);
130 
131     if (columns < 0)
132       this.columns = 0;
133     else
134       this.columns = columns;
135 
136     if (GraphicsEnvironment.isHeadless())
137       throw new HeadlessException ();
138   }
139 
140   /**
141    * Returns the number of columns in the field.
142    *
143    * @return The number of columns in the field.
144    */
getColumns()145   public int getColumns()
146   {
147     return(columns);
148   }
149 
150   /**
151    * Sets the number of columns in this field to the specified value.
152    *
153    * @param columns The new number of columns in the field.
154    *
155    * @exception IllegalArgumentException If columns is less than zero.
156    */
setColumns(int columns)157   public synchronized void setColumns(int columns)
158   {
159     if (columns < 0)
160       throw new IllegalArgumentException("Value is less than zero: " +
161                                          columns);
162 
163     this.columns = columns;
164     // FIXME: How to we communicate this to our peer?
165   }
166 
167   /**
168    * Returns the character that is echoed to the screen when a text
169    * field is protected (such as when a password is being entered).
170    *
171    * @return The echo character for this text field.
172    */
getEchoChar()173   public char getEchoChar()
174   {
175     return(echoChar);
176   }
177 
178   /**
179    * Sets the character that is echoed when protected input such as
180    * a password is displayed.
181    *
182    * @param echoChar The new echo character.
183    */
setEchoChar(char echoChar)184   public void setEchoChar(char echoChar)
185   {
186     setEchoCharacter(echoChar);
187   }
188 
189   /**
190    * Sets the character that is echoed when protected input such as
191    * a password is displayed.
192    *
193    * @param echoChar The new echo character.
194    *
195    * @deprecated This method is deprecated in favor of
196    * <code>setEchoChar()</code>
197    */
setEchoCharacter(char echoChar)198   public void setEchoCharacter(char echoChar)
199   {
200     this.echoChar = echoChar;
201 
202     TextFieldPeer peer = (TextFieldPeer) getPeer ();
203     if (peer != null)
204       peer.setEchoChar (echoChar);
205   }
206 
207   /**
208    * Tests whether or not this text field has an echo character set
209    * so that characters the user type are not echoed to the screen.
210    *
211    * @return <code>true</code> if an echo character is set,
212    * <code>false</code> otherwise.
213    */
echoCharIsSet()214   public boolean echoCharIsSet()
215   {
216     if (echoChar == '\u0000')
217       return(false);
218     else
219       return(true);
220   }
221 
222   /**
223    * Returns the minimum size for this text field.
224    *
225    * @return The minimum size for this text field.
226    */
getMinimumSize()227   public Dimension getMinimumSize()
228   {
229     return getMinimumSize (getColumns ());
230   }
231 
232   /**
233    * Returns the minimum size of a text field with the specified number
234    * of columns.
235    *
236    * @param columns The number of columns to get the minimum size for.
237    */
getMinimumSize(int columns)238   public Dimension getMinimumSize(int columns)
239   {
240     return minimumSize(columns);
241   }
242 
243   /**
244    * Returns the minimum size for this text field.
245    *
246    * @return The minimum size for this text field.
247    *
248    * @deprecated This method is deprecated in favor of
249    * <code>getMinimumSize()</code>.
250    */
minimumSize()251   public Dimension minimumSize()
252   {
253     return minimumSize(getColumns ());
254   }
255 
256   /**
257    * Returns the minimum size of a text field with the specified number
258    * of columns.
259    *
260    * @param columns The number of columns to get the minimum size for.
261    *
262    * @deprecated This method is deprecated in favor of
263    * <code>getMinimumSize(int)</code>.
264    */
minimumSize(int columns)265   public Dimension minimumSize(int columns)
266   {
267     if (isMinimumSizeSet())
268       return new Dimension(minSize);
269 
270     TextFieldPeer peer = (TextFieldPeer) getPeer ();
271     if (peer == null)
272       return new Dimension(getWidth(), getHeight());
273 
274     return peer.getMinimumSize (columns);
275   }
276 
277   /**
278    * Returns the preferred size for this text field.
279    *
280    * @return The preferred size for this text field.
281    */
getPreferredSize()282   public Dimension getPreferredSize()
283   {
284     return getPreferredSize(getColumns ());
285   }
286 
287   /**
288    * Returns the preferred size of a text field with the specified number
289    * of columns.
290    *
291    * @param columns The number of columns to get the preferred size for.
292    */
getPreferredSize(int columns)293   public Dimension getPreferredSize(int columns)
294   {
295     return preferredSize(columns);
296   }
297 
298   /**
299    * Returns the preferred size for this text field.
300    *
301    * @return The preferred size for this text field.
302    *
303    * @deprecated This method is deprecated in favor of
304    * <code>getPreferredSize()</code>.
305    */
preferredSize()306   public Dimension preferredSize()
307   {
308     return preferredSize(getColumns ());
309   }
310 
311   /**
312    * Returns the preferred size of a text field with the specified number
313    * of columns.
314    *
315    * @param columns The number of columns to get the preferred size for.
316    *
317    * @deprecated This method is deprecated in favor of
318    * <code>getPreferredSize(int)</code>.
319    */
preferredSize(int columns)320   public Dimension preferredSize(int columns)
321   {
322     if (isPreferredSizeSet())
323       return new Dimension(prefSize);
324 
325     TextFieldPeer peer = (TextFieldPeer) getPeer ();
326     if (peer == null)
327       return new Dimension (getWidth(), getHeight());
328 
329     return peer.getPreferredSize (columns);
330   }
331 
332   /**
333    * Notifies this object that it should create its native peer.
334    */
addNotify()335   public void addNotify()
336   {
337     if (getPeer() != null)
338       return;
339 
340     setPeer((ComponentPeer)getToolkit().createTextField(this));
341     super.addNotify();
342   }
343 
344   /**
345    * Addes a new listener to the list of action listeners for this
346    * object.
347    *
348    * @param listener The listener to add to the list.
349    */
addActionListener(ActionListener listener)350   public synchronized void addActionListener(ActionListener listener)
351   {
352     action_listeners = AWTEventMulticaster.add(action_listeners, listener);
353 
354     enableEvents(AWTEvent.ACTION_EVENT_MASK);
355   }
356 
357   /**
358    * Removes the specified listener from the list of action listeners
359    * for this object.
360    *
361    * @param listener The listener to remove from the list.
362    */
removeActionListener(ActionListener listener)363   public synchronized void removeActionListener(ActionListener listener)
364   {
365     action_listeners = AWTEventMulticaster.remove(action_listeners, listener);
366   }
367 
368   /**
369    * Processes the specified event.  If the event is an instance of
370    * <code>ActionEvent</code> then <code>processActionEvent()</code> is
371    * called to process it, otherwise the event is sent to the
372    * superclass.
373    *
374    * @param event The event to process.
375    */
processEvent(AWTEvent event)376   protected void processEvent(AWTEvent event)
377   {
378     if (event instanceof ActionEvent)
379       processActionEvent((ActionEvent)event);
380     else
381       super.processEvent(event);
382   }
383 
384   /**
385    * Processes an action event by calling any registered listeners.
386    * Note to subclasses: This method is not called unless action events
387    * are enabled on this object.  This will be true if any listeners
388    * are registered, or if action events were specifically enabled
389    * using <code>enableEvents()</code>.
390    *
391    * @param event The event to process.
392    */
processActionEvent(ActionEvent event)393   protected void processActionEvent(ActionEvent event)
394   {
395     if (action_listeners != null)
396       action_listeners.actionPerformed(event);
397   }
398 
dispatchEventImpl(AWTEvent e)399   void dispatchEventImpl(AWTEvent e)
400   {
401     if (e.id <= ActionEvent.ACTION_LAST
402         && e.id >= ActionEvent.ACTION_FIRST
403         && (action_listeners != null
404             || (eventMask & AWTEvent.ACTION_EVENT_MASK) != 0))
405       processEvent(e);
406     else
407       super.dispatchEventImpl(e);
408   }
409 
410  /**
411   * Returns a debug string for this object.
412   *
413   * @return A debug string for this object.
414   */
paramString()415   protected String paramString()
416   {
417     return(getClass().getName() + "(columns=" + getColumns() + ",echoChar=" +
418            getEchoChar());
419   }
420 
421   /**
422    * Returns an array of all the objects currently registered as FooListeners
423    * upon this <code>TextField</code>. FooListeners are registered using the
424    * addFooListener method.
425    *
426    * @exception ClassCastException If listenerType doesn't specify a class or
427    * interface that implements java.util.EventListener.
428    *
429    * @since 1.3
430    */
getListeners(Class<T> listenerType)431   public <T extends EventListener> T[] getListeners (Class<T> listenerType)
432   {
433     if (listenerType == ActionListener.class)
434       return AWTEventMulticaster.getListeners (action_listeners, listenerType);
435 
436     return super.getListeners (listenerType);
437   }
438 
439   /**
440    * Return all ActionListeners register to this <code>TextField</code> object
441    * as an array.
442    *
443    * @since 1.4
444    */
getActionListeners()445   public ActionListener[] getActionListeners ()
446   {
447     return (ActionListener[]) getListeners (ActionListener.class);
448   }
449 
450   /**
451    * Generate a unique name for this <code>TextField</code>.
452    *
453    * @return A unique name for this <code>TextField</code>.
454    */
generateName()455   String generateName()
456   {
457     return "textfield" + getUniqueLong();
458   }
459 
getUniqueLong()460   private static synchronized long getUniqueLong()
461   {
462     return next_textfield_number++;
463   }
464 
465   protected class AccessibleAWTTextField extends AccessibleAWTTextComponent
466   {
467     private static final long serialVersionUID = 6219164359235943158L;
468 
AccessibleAWTTextField()469     protected AccessibleAWTTextField()
470     {
471     }
472 
getAccessibleStateSet()473     public AccessibleStateSet getAccessibleStateSet()
474     {
475       return super.getAccessibleStateSet();
476     }
477   }
478 
getAccessibleContext()479   public AccessibleContext getAccessibleContext()
480   {
481     return new AccessibleAWTTextField();
482   }
483 
484 }
485