KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > JTextField


1 /*
2  * @(#)JTextField.java 1.90 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 package javax.swing;
8
9 import java.awt.*;
10 import java.awt.event.*;
11 import java.beans.*;
12 import javax.swing.text.*;
13 import javax.swing.plaf.*;
14 import javax.swing.event.*;
15 import javax.accessibility.*;
16
17 import java.io.ObjectOutputStream JavaDoc;
18 import java.io.ObjectInputStream JavaDoc;
19 import java.io.IOException JavaDoc;
20 import java.io.Serializable JavaDoc;
21
22 /**
23  * <code>JTextField</code> is a lightweight component that allows the editing
24  * of a single line of text.
25  * For information on and examples of using text fields,
26  * see
27  * <a HREF="http://java.sun.com/docs/books/tutorial/uiswing/components/textfield.html">How to Use Text Fields</a>
28  * in <em>The Java Tutorial.</em>
29  *
30  * <p>
31  * <code>JTextField</code> is intended to be source-compatible
32  * with <code>java.awt.TextField</code> where it is reasonable to do so. This
33  * component has capabilities not found in the <code>java.awt.TextField</code>
34  * class. The superclass should be consulted for additional capabilities.
35  * <p>
36  * <code>JTextField</code> has a method to establish the string used as the
37  * command string for the action event that gets fired. The
38  * <code>java.awt.TextField</code> used the text of the field as the command
39  * string for the <code>ActionEvent</code>.
40  * <code>JTextField</code> will use the command
41  * string set with the <code>setActionCommand</code> method if not <code>null</code>,
42  * otherwise it will use the text of the field as a compatibility with
43  * <code>java.awt.TextField</code>.
44  * <p>
45  * The method <code>setEchoChar</code> and <code>getEchoChar</code>
46  * are not provided directly to avoid a new implementation of a
47  * pluggable look-and-feel inadvertently exposing password characters.
48  * To provide password-like services a separate class <code>JPasswordField</code>
49  * extends <code>JTextField</code> to provide this service with an independently
50  * pluggable look-and-feel.
51  * <p>
52  * The <code>java.awt.TextField</code> could be monitored for changes by adding
53  * a <code>TextListener</code> for <code>TextEvent</code>'s.
54  * In the <code>JTextComponent</code> based
55  * components, changes are broadcasted from the model via a
56  * <code>DocumentEvent</code> to <code>DocumentListeners</code>.
57  * The <code>DocumentEvent</code> gives
58  * the location of the change and the kind of change if desired.
59  * The code fragment might look something like:
60  * <pre><code>
61  * &nbsp; DocumentListener myListener = ??;
62  * &nbsp; JTextField myArea = ??;
63  * &nbsp; myArea.getDocument().addDocumentListener(myListener);
64  * </code></pre>
65  * <p>
66  * The horizontal alignment of <code>JTextField</code> can be set to be left
67  * justified, leading justified, centered, right justified or trailing justified.
68  * Right/trailing justification is useful if the required size
69  * of the field text is smaller than the size allocated to it.
70  * This is determined by the <code>setHorizontalAlignment</code>
71  * and <code>getHorizontalAlignment</code> methods. The default
72  * is to be leading justified.
73  * <p>
74  * How the text field consumes VK_ENTER events depends
75  * on whether the text field has any action listeners.
76  * If so, then VK_ENTER results in the listeners
77  * getting an ActionEvent,
78  * and the VK_ENTER event is consumed.
79  * This is compatible with how AWT text fields handle VK_ENTER events.
80  * If the text field has no action listeners, then as of v 1.3 the VK_ENTER
81  * event is not consumed. Instead, the bindings of ancestor components
82  * are processed, which enables the default button feature of
83  * JFC/Swing to work.
84  * <p>
85  * Customized fields can easily be created by extending the model and
86  * changing the default model provided. For example, the following piece
87  * of code will create a field that holds only upper case characters. It
88  * will work even if text is pasted into from the clipboard or it is altered via
89  * programmatic changes.
90  * <pre><code>
91
92 &nbsp;public class UpperCaseField extends JTextField {
93 &nbsp;
94 &nbsp; public UpperCaseField(int cols) {
95 &nbsp; super(cols);
96 &nbsp; }
97 &nbsp;
98 &nbsp; protected Document createDefaultModel() {
99 &nbsp; return new UpperCaseDocument();
100 &nbsp; }
101 &nbsp;
102 &nbsp; static class UpperCaseDocument extends PlainDocument {
103 &nbsp;
104 &nbsp; public void insertString(int offs, String str, AttributeSet a)
105 &nbsp; throws BadLocationException {
106 &nbsp;
107 &nbsp; if (str == null) {
108 &nbsp; return;
109 &nbsp; }
110 &nbsp; char[] upper = str.toCharArray();
111 &nbsp; for (int i = 0; i < upper.length; i++) {
112 &nbsp; upper[i] = Character.toUpperCase(upper[i]);
113 &nbsp; }
114 &nbsp; super.insertString(offs, new String(upper), a);
115 &nbsp; }
116 &nbsp; }
117 &nbsp;}
118
119  * </code></pre>
120  * <p>
121  * <strong>Warning:</strong>
122  * Serialized objects of this class will not be compatible with
123  * future Swing releases. The current serialization support is
124  * appropriate for short term storage or RMI between applications running
125  * the same version of Swing. As of 1.4, support for long term storage
126  * of all JavaBeans<sup><font size="-2">TM</font></sup>
127  * has been added to the <code>java.beans</code> package.
128  * Please see {@link java.beans.XMLEncoder}.
129  *
130  * @beaninfo
131  * attribute: isContainer false
132  * description: A component which allows for the editing of a single line of text.
133  *
134  * @author Timothy Prinzing
135  * @version 1.90 12/19/03
136  * @see #setActionCommand
137  * @see JPasswordField
138  * @see #addActionListener
139  */

140 public class JTextField extends JTextComponent implements SwingConstants JavaDoc {
141
142     /**
143      * Constructs a new <code>TextField</code>. A default model is created,
144      * the initial string is <code>null</code>,
145      * and the number of columns is set to 0.
146      */

147     public JTextField() {
148         this(null, null, 0);
149     }
150
151     /**
152      * Constructs a new <code>TextField</code> initialized with the
153      * specified text. A default model is created and the number of
154      * columns is 0.
155      *
156      * @param text the text to be displayed, or <code>null</code>
157      */

158     public JTextField(String JavaDoc text) {
159         this(null, text, 0);
160     }
161
162     /**
163      * Constructs a new empty <code>TextField</code> with the specified
164      * number of columns.
165      * A default model is created and the initial string is set to
166      * <code>null</code>.
167      *
168      * @param columns the number of columns to use to calculate
169      * the preferred width; if columns is set to zero, the
170      * preferred width will be whatever naturally results from
171      * the component implementation
172      */

173     public JTextField(int columns) {
174         this(null, null, columns);
175     }
176
177     /**
178      * Constructs a new <code>TextField</code> initialized with the
179      * specified text and columns. A default model is created.
180      *
181      * @param text the text to be displayed, or <code>null</code>
182      * @param columns the number of columns to use to calculate
183      * the preferred width; if columns is set to zero, the
184      * preferred width will be whatever naturally results from
185      * the component implementation
186      */

187     public JTextField(String JavaDoc text, int columns) {
188         this(null, text, columns);
189     }
190
191     /**
192      * Constructs a new <code>JTextField</code> that uses the given text
193      * storage model and the given number of columns.
194      * This is the constructor through which the other constructors feed.
195      * If the document is <code>null</code>, a default model is created.
196      *
197      * @param doc the text storage to use; if this is <code>null</code>,
198      * a default will be provided by calling the
199      * <code>createDefaultModel</code> method
200      * @param text the initial string to display, or <code>null</code>
201      * @param columns the number of columns to use to calculate
202      * the preferred width >= 0; if <code>columns</code>
203      * is set to zero, the preferred width will be whatever
204      * naturally results from the component implementation
205      * @exception IllegalArgumentException if <code>columns</code> < 0
206      */

207     public JTextField(Document doc, String JavaDoc text, int columns) {
208         if (columns < 0) {
209             throw new IllegalArgumentException JavaDoc("columns less than zero.");
210         }
211         visibility = new DefaultBoundedRangeModel JavaDoc();
212         visibility.addChangeListener(new ScrollRepainter());
213         this.columns = columns;
214         if (doc == null) {
215             doc = createDefaultModel();
216         }
217         setDocument(doc);
218         if (text != null) {
219             setText(text);
220         }
221     }
222
223     /**
224      * Gets the class ID for a UI.
225      *
226      * @return the string "TextFieldUI"
227      * @see JComponent#getUIClassID
228      * @see UIDefaults#getUI
229      */

230     public String JavaDoc getUIClassID() {
231         return uiClassID;
232     }
233
234     
235     /**
236      * Associates the editor with a text document.
237      * The currently registered factory is used to build a view for
238      * the document, which gets displayed by the editor after revalidation.
239      * A PropertyChange event ("document") is propagated to each listener.
240      *
241      * @param doc the document to display/edit
242      * @see #getDocument
243      * @beaninfo
244      * description: the text document model
245      * bound: true
246      * expert: true
247      */

248     public void setDocument(Document doc) {
249     if (doc != null) {
250         doc.putProperty("filterNewlines", Boolean.TRUE);
251     }
252     super.setDocument(doc);
253     }
254
255     /**
256      * Calls to <code>revalidate</code> that come from within the
257      * textfield itself will
258      * be handled by validating the textfield, unless the textfield
259      * is contained within a <code>JViewport</code>,
260      * in which case this returns false.
261      *
262      * @return if the parent of this textfield is a <code>JViewPort</code>
263      * return false, otherwise return true
264      *
265      * @see JComponent#revalidate
266      * @see JComponent#isValidateRoot
267      */

268     public boolean isValidateRoot() {
269     Component parent = getParent();
270     if (parent instanceof JViewport JavaDoc) {
271         return false;
272     }
273         return true;
274     }
275
276
277     /**
278      * Returns the horizontal alignment of the text.
279      * Valid keys are:
280      * <ul>
281      * <li><code>JTextField.LEFT</code>
282      * <li><code>JTextField.CENTER</code>
283      * <li><code>JTextField.RIGHT</code>
284      * <li><code>JTextField.LEADING</code>
285      * <li><code>JTextField.TRAILING</code>
286      * </ul>
287      *
288      * @return the horizontal alignment
289      */

290     public int getHorizontalAlignment() {
291         return horizontalAlignment;
292     }
293     
294     /**
295      * Sets the horizontal alignment of the text.
296      * Valid keys are:
297      * <ul>
298      * <li><code>JTextField.LEFT</code>
299      * <li><code>JTextField.CENTER</code>
300      * <li><code>JTextField.RIGHT</code>
301      * <li><code>JTextField.LEADING</code>
302      * <li><code>JTextField.TRAILING</code>
303      * </ul>
304      * <code>invalidate</code> and <code>repaint</code> are called when the
305      * alignment is set,
306      * and a <code>PropertyChange</code> event ("horizontalAlignment") is fired.
307      *
308      * @param alignment the alignment
309      * @exception IllegalArgumentException if <code>alignment</code>
310      * is not a valid key
311      * @beaninfo
312      * preferred: true
313      * bound: true
314      * description: Set the field alignment to LEFT, CENTER, RIGHT,
315      * LEADING (the default) or TRAILING
316      * enum: LEFT JTextField.LEFT CENTER JTextField.CENTER RIGHT JTextField.RIGHT
317      * LEADING JTextField.LEADING TRAILING JTextField.TRAILING
318      */

319      public void setHorizontalAlignment(int alignment) {
320         if (alignment == horizontalAlignment) return;
321         int oldValue = horizontalAlignment;
322         if ((alignment == LEFT) || (alignment == CENTER) ||
323         (alignment == RIGHT)|| (alignment == LEADING) ||
324         (alignment == TRAILING)) {
325             horizontalAlignment = alignment;
326         } else {
327             throw new IllegalArgumentException JavaDoc("horizontalAlignment");
328         }
329         firePropertyChange("horizontalAlignment", oldValue, horizontalAlignment);
330         invalidate();
331         repaint();
332     }
333
334     /**
335      * Creates the default implementation of the model
336      * to be used at construction if one isn't explicitly
337      * given. An instance of <code>PlainDocument</code> is returned.
338      *
339      * @return the default model implementation
340      */

341     protected Document createDefaultModel() {
342         return new PlainDocument();
343     }
344
345     /**
346      * Returns the number of columns in this <code>TextField</code>.
347      *
348      * @return the number of columns >= 0
349      */

350     public int getColumns() {
351         return columns;
352     }
353
354     /**
355      * Sets the number of columns in this <code>TextField</code>,
356      * and then invalidate the layout.
357      *
358      * @param columns the number of columns >= 0
359      * @exception IllegalArgumentException if <code>columns</code>
360      * is less than 0
361      * @beaninfo
362      * description: the number of columns preferred for display
363      */

364     public void setColumns(int columns) {
365         int oldVal = this.columns;
366         if (columns < 0) {
367             throw new IllegalArgumentException JavaDoc("columns less than zero.");
368         }
369         if (columns != oldVal) {
370             this.columns = columns;
371             invalidate();
372         }
373     }
374
375     /**
376      * Returns the column width.
377      * The meaning of what a column is can be considered a fairly weak
378      * notion for some fonts. This method is used to define the width
379      * of a column. By default this is defined to be the width of the
380      * character <em>m</em> for the font used. This method can be
381      * redefined to be some alternative amount
382      *
383      * @return the column width >= 1
384      */

385     protected int getColumnWidth() {
386         if (columnWidth == 0) {
387             FontMetrics metrics = getFontMetrics(getFont());
388             columnWidth = metrics.charWidth('m');
389         }
390         return columnWidth;
391     }
392
393     /**
394      * Returns the preferred size <code>Dimensions</code> needed for this
395      * <code>TextField</code>. If a non-zero number of columns has been
396      * set, the width is set to the columns multiplied by
397      * the column width.
398      *
399      * @return the dimension of this textfield
400      */

401     public Dimension getPreferredSize() {
402         Dimension size = super.getPreferredSize();
403         if (columns != 0) {
404             Insets insets = getInsets();
405             size.width = columns * getColumnWidth() +
406                 insets.left + insets.right;
407         }
408         return size;
409     }
410
411     /**
412      * Sets the current font. This removes cached row height and column
413      * width so the new font will be reflected.
414      * <code>revalidate</code> is called after setting the font.
415      *
416      * @param f the new font
417      */

418     public void setFont(Font f) {
419         super.setFont(f);
420         columnWidth = 0;
421     }
422
423     /**
424      * Adds the specified action listener to receive
425      * action events from this textfield.
426      *
427      * @param l the action listener to be added
428      */

429     public synchronized void addActionListener(ActionListener l) {
430         listenerList.add(ActionListener.class, l);
431     }
432
433     /**
434      * Removes the specified action listener so that it no longer
435      * receives action events from this textfield.
436      *
437      * @param l the action listener to be removed
438      */

439     public synchronized void removeActionListener(ActionListener l) {
440     if ((l != null) && (getAction() == l)) {
441         setAction(null);
442     } else {
443         listenerList.remove(ActionListener.class, l);
444     }
445     }
446
447     /**
448      * Returns an array of all the <code>ActionListener</code>s added
449      * to this JTextField with addActionListener().
450      *
451      * @return all of the <code>ActionListener</code>s added or an empty
452      * array if no listeners have been added
453      * @since 1.4
454      */

455     public synchronized ActionListener[] getActionListeners() {
456         return (ActionListener[])listenerList.getListeners(
457                 ActionListener.class);
458     }
459
460     /**
461      * Notifies all listeners that have registered interest for
462      * notification on this event type. The event instance
463      * is lazily created.
464      * The listener list is processed in last to
465      * first order.
466      * @see EventListenerList
467      */

468     protected void fireActionPerformed() {
469         // Guaranteed to return a non-null array
470
Object JavaDoc[] listeners = listenerList.getListenerList();
471         int modifiers = 0;
472         AWTEvent currentEvent = EventQueue.getCurrentEvent();
473         if (currentEvent instanceof InputEvent) {
474             modifiers = ((InputEvent)currentEvent).getModifiers();
475         } else if (currentEvent instanceof ActionEvent) {
476             modifiers = ((ActionEvent)currentEvent).getModifiers();
477         }
478         ActionEvent e =
479             new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
480                             (command != null) ? command : getText(),
481                             EventQueue.getMostRecentEventTime(), modifiers);
482                             
483         // Process the listeners last to first, notifying
484
// those that are interested in this event
485
for (int i = listeners.length-2; i>=0; i-=2) {
486             if (listeners[i]==ActionListener.class) {
487                 ((ActionListener)listeners[i+1]).actionPerformed(e);
488             }
489         }
490     }
491
492     /**
493      * Sets the command string used for action events.
494      *
495      * @param command the command string
496      */

497     public void setActionCommand(String JavaDoc command) {
498         this.command = command;
499     }
500
501     private Action JavaDoc action;
502     private PropertyChangeListener actionPropertyChangeListener;
503
504     /**
505      * Sets the <code>Action</code> for the <code>ActionEvent</code> source.
506      * The new <code>Action</code> replaces
507      * any previously set <code>Action</code> but does not affect
508      * <code>ActionListeners</code> independently
509      * added with <code>addActionListener</code>.
510      * If the <code>Action</code> is already a registered
511      * <code>ActionListener</code>
512      * for the <code>ActionEvent</code> source, it is not re-registered.
513      *
514      * A side-effect of setting the <code>Action</code> is that the
515      * <code>ActionEvent</code> source's properties
516      * are immediately set from the values in the <code>Action</code>
517      * (performed by the method <code>configurePropertiesFromAction</code>)
518      * and subsequently updated as the <code>Action</code>'s
519      * properties change (via a <code>PropertyChangeListener</code>
520      * created by the method <code>createActionPropertyChangeListener</code>.
521      *
522      * @param a the <code>Action</code> for the <code>JTextField</code>,
523      * or <code>null</code>
524      * @since 1.3
525      * @see Action
526      * @see #getAction
527      * @see #configurePropertiesFromAction
528      * @see #createActionPropertyChangeListener
529      * @beaninfo
530      * bound: true
531      * attribute: visualUpdate true
532      * description: the Action instance connected with this ActionEvent source
533      */

534     public void setAction(Action JavaDoc a) {
535     Action JavaDoc oldValue = getAction();
536     if (action==null || !action.equals(a)) {
537         action = a;
538         if (oldValue!=null) {
539         removeActionListener(oldValue);
540         oldValue.removePropertyChangeListener(actionPropertyChangeListener);
541         actionPropertyChangeListener = null;
542         }
543         configurePropertiesFromAction(action);
544         if (action!=null) {
545         // Don't add if it is already a listener
546
if (!isListener(ActionListener.class, action)) {
547             addActionListener(action);
548         }
549         // Reverse linkage:
550
actionPropertyChangeListener = createActionPropertyChangeListener(action);
551         action.addPropertyChangeListener(actionPropertyChangeListener);
552         }
553         firePropertyChange("action", oldValue, action);
554         revalidate();
555         repaint();
556     }
557     }
558
559     private boolean isListener(Class JavaDoc c, ActionListener a) {
560     boolean isListener = false;
561     Object JavaDoc[] listeners = listenerList.getListenerList();
562         for (int i = listeners.length-2; i>=0; i-=2) {
563             if (listeners[i]==c && listeners[i+1]==a) {
564             isListener=true;
565         }
566     }
567     return isListener;
568     }
569
570     /**
571      * Returns the currently set <code>Action</code> for this
572      * <code>ActionEvent</code> source, or <code>null</code>
573      * if no <code>Action</code> is set.
574      *
575      * @return the <code>Action</code> for this <code>ActionEvent</code> source,
576      * or <code>null</code>
577      * @since 1.3
578      * @see Action
579      * @see #setAction
580      */

581     public Action JavaDoc getAction() {
582     return action;
583     }
584
585     /**
586      * Factory method which sets the <code>ActionEvent</code>
587      * source's properties according to values from the
588      * <code>Action</code> instance. The properties
589      * which are set may differ for subclasses.
590      * By default, the properties which get set are
591      * <code>Enabled</code> and <code>ToolTipText</code>.
592      *
593      * @param a the <code>Action</code> from which to get the properties,
594      * or <code>null</code>
595      * @since 1.3
596      * @see Action
597      * @see #setAction
598      */

599     protected void configurePropertiesFromAction(Action JavaDoc a) {
600     setEnabled((a!=null?a.isEnabled():true));
601     setToolTipText((a!=null?(String JavaDoc)a.getValue(Action.SHORT_DESCRIPTION):null));
602     }
603
604     /**
605      * Factory method which creates the <code>PropertyChangeListener</code>
606      * used to update the <code>ActionEvent</code> source as
607      * properties change on its <code>Action</code> instance.
608      * Subclasses may override this in order to provide their own
609      * <code>PropertyChangeListener</code> if the set of
610      * properties which should be kept up to date differs from the
611      * default properties (Text, Enabled, ToolTipText).
612      *
613      * <p>
614      * Note that <code>PropertyChangeListeners</code> should avoid holding
615      * strong references to the <code>ActionEvent</code> source,
616      * as this may hinder garbage collection of the
617      * <code>ActionEvent</code> source and all components
618      * in its containment hierarchy.
619      *
620      * @param a the <code>Action</code> from which to get the properties,
621      * or <code>null</code>
622      * @since 1.3
623      * @see Action
624      * @see #setAction
625      */

626     protected PropertyChangeListener createActionPropertyChangeListener(Action JavaDoc a) {
627         return new AbstractActionPropertyChangeListener JavaDoc(this, a) {
628         public void propertyChange(PropertyChangeEvent e) {
629         String JavaDoc propertyName = e.getPropertyName();
630         JTextField JavaDoc textField = (JTextField JavaDoc)getTarget();
631         if (textField == null) { //WeakRef GC'ed in 1.2
632
Action JavaDoc action = (Action JavaDoc)e.getSource();
633             action.removePropertyChangeListener(this);
634         } else {
635             if (e.getPropertyName().equals(Action.SHORT_DESCRIPTION)) {
636             String JavaDoc text = (String JavaDoc) e.getNewValue();
637             textField.setToolTipText(text);
638             } else if (propertyName.equals("enabled")) {
639             Boolean JavaDoc enabledState = (Boolean JavaDoc) e.getNewValue();
640             textField.setEnabled(enabledState.booleanValue());
641             textField.repaint();
642             }
643         }
644         }
645     };
646     }
647
648     /**
649      * Fetches the command list for the editor. This is
650      * the list of commands supported by the plugged-in UI
651      * augmented by the collection of commands that the
652      * editor itself supports. These are useful for binding
653      * to events, such as in a keymap.
654      *
655      * @return the command list
656      */

657     public Action JavaDoc[] getActions() {
658         return TextAction.augmentList(super.getActions(), defaultActions);
659     }
660
661     /**
662      * Processes action events occurring on this textfield by
663      * dispatching them to any registered <code>ActionListener</code> objects.
664      * This is normally called by the controller registered with
665      * textfield.
666      */

667     public void postActionEvent() {
668         fireActionPerformed();
669     }
670
671     // --- Scrolling support -----------------------------------
672

673     /**
674      * Gets the visibility of the text field. This can
675      * be adjusted to change the location of the visible
676      * area if the size of the field is greater than
677      * the area that was allocated to the field.
678      *
679      * <p>
680      * The fields look-and-feel implementation manages
681      * the values of the minimum, maximum, and extent
682      * properties on the <code>BoundedRangeModel</code>.
683      *
684      * @return the visibility
685      * @see BoundedRangeModel
686      */

687     public BoundedRangeModel JavaDoc getHorizontalVisibility() {
688         return visibility;
689     }
690
691     /**
692      * Gets the scroll offset, in pixels.
693      *
694      * @return the offset >= 0
695      */

696     public int getScrollOffset() {
697         return visibility.getValue();
698     }
699
700     /**
701      * Sets the scroll offset, in pixels.
702      *
703      * @param scrollOffset the offset >= 0
704      */

705     public void setScrollOffset(int scrollOffset) {
706         visibility.setValue(scrollOffset);
707     }
708     
709     /**
710      * Scrolls the field left or right.
711      *
712      * @param r the region to scroll
713      */

714     public void scrollRectToVisible(Rectangle r) {
715         // convert to coordinate system of the bounded range
716
Insets i = getInsets();
717         int x0 = r.x + visibility.getValue() - i.left;
718         int x1 = x0 + r.width;
719         if (x0 < visibility.getValue()) {
720             // Scroll to the left
721
visibility.setValue(x0);
722         } else if(x1 > visibility.getValue() + visibility.getExtent()) {
723             // Scroll to the right
724
visibility.setValue(x1 - visibility.getExtent());
725         }
726     }
727
728     /**
729      * Returns true if the receiver has an <code>ActionListener</code>
730      * installed.
731      */

732     boolean hasActionListener() {
733         // Guaranteed to return a non-null array
734
Object JavaDoc[] listeners = listenerList.getListenerList();
735         // Process the listeners last to first, notifying
736
// those that are interested in this event
737
for (int i = listeners.length-2; i>=0; i-=2) {
738             if (listeners[i]==ActionListener.class) {
739                 return true;
740             }
741         }
742         return false;
743     }
744
745     // --- variables -------------------------------------------
746

747     /**
748      * Name of the action to send notification that the
749      * contents of the field have been accepted. Typically
750      * this is bound to a carriage-return.
751      */

752     public static final String JavaDoc notifyAction = "notify-field-accept";
753
754     private BoundedRangeModel JavaDoc visibility;
755     private int horizontalAlignment = LEADING;
756     private int columns;
757     private int columnWidth;
758     private String JavaDoc command;
759
760     private static final Action JavaDoc[] defaultActions = {
761         new NotifyAction()
762     };
763
764     /**
765      * @see #getUIClassID
766      * @see #readObject
767      */

768     private static final String JavaDoc uiClassID = "TextFieldUI";
769
770     // --- Action implementations -----------------------------------
771

772     // Note that JFormattedTextField.CommitAction extends this
773
static class NotifyAction extends TextAction {
774
775         NotifyAction() {
776             super(notifyAction);
777         }
778
779         public void actionPerformed(ActionEvent e) {
780             JTextComponent target = getFocusedComponent();
781             if (target instanceof JTextField JavaDoc) {
782                 JTextField JavaDoc field = (JTextField JavaDoc) target;
783                 field.postActionEvent();
784             }
785         }
786
787         public boolean isEnabled() {
788             JTextComponent target = getFocusedComponent();
789             if (target instanceof JTextField JavaDoc) {
790                 return ((JTextField JavaDoc)target).hasActionListener();
791             }
792             return false;
793         }
794     }
795
796     class ScrollRepainter implements ChangeListener, Serializable JavaDoc {
797
798         public void stateChanged(ChangeEvent e) {
799             repaint();
800         }
801
802     }
803
804
805     /**
806      * See <code>readObject</code> and <code>writeObject</code> in
807      * <code>JComponent</code> for more
808      * information about serialization in Swing.
809      */

810     private void writeObject(ObjectOutputStream JavaDoc s) throws IOException JavaDoc {
811         s.defaultWriteObject();
812         if (getUIClassID().equals(uiClassID)) {
813             byte count = JComponent.getWriteObjCounter(this);
814             JComponent.setWriteObjCounter(this, --count);
815             if (count == 0 && ui != null) {
816                 ui.installUI(this);
817             }
818         }
819     }
820
821
822     /**
823      * Returns a string representation of this <code>JTextField</code>.
824      * This method is intended to be used only for debugging purposes,
825      * and the content and format of the returned string may vary between
826      * implementations. The returned string may be empty but may not
827      * be <code>null</code>.
828      *
829      * @return a string representation of this <code>JTextField</code>
830      */

831     protected String JavaDoc paramString() {
832         String JavaDoc horizontalAlignmentString;
833         if (horizontalAlignment == LEFT) {
834         horizontalAlignmentString = "LEFT";
835     } else if (horizontalAlignment == CENTER) {
836         horizontalAlignmentString = "CENTER";
837     } else if (horizontalAlignment == RIGHT) {
838         horizontalAlignmentString = "RIGHT";
839     } else if (horizontalAlignment == LEADING) {
840         horizontalAlignmentString = "LEADING";
841     } else if (horizontalAlignment == TRAILING) {
842         horizontalAlignmentString = "TRAILING";
843     } else horizontalAlignmentString = "";
844         String JavaDoc commandString = (command != null ?
845                 command : "");
846
847         return super.paramString() +
848         ",columns=" + columns +
849         ",columnWidth=" + columnWidth +
850         ",command=" + commandString +
851         ",horizontalAlignment=" + horizontalAlignmentString;
852     }
853
854
855 /////////////////
856
// Accessibility support
857
////////////////
858

859
860     /**
861      * Gets the <code>AccessibleContext</code> associated with this
862      * <code>JTextField</code>. For <code>JTextFields</code>,
863      * the <code>AccessibleContext</code> takes the form of an
864      * <code>AccessibleJTextField</code>.
865      * A new <code>AccessibleJTextField</code> instance is created
866      * if necessary.
867      *
868      * @return an <code>AccessibleJTextField</code> that serves as the
869      * <code>AccessibleContext</code> of this <code>JTextField</code>
870      */

871     public AccessibleContext getAccessibleContext() {
872         if (accessibleContext == null) {
873             accessibleContext = new AccessibleJTextField();
874         }
875         return accessibleContext;
876     }
877
878     /**
879      * This class implements accessibility support for the
880      * <code>JTextField</code> class. It provides an implementation of the
881      * Java Accessibility API appropriate to text field user-interface
882      * elements.
883      * <p>
884      * <strong>Warning:</strong>
885      * Serialized objects of this class will not be compatible with
886      * future Swing releases. The current serialization support is
887      * appropriate for short term storage or RMI between applications running
888      * the same version of Swing. As of 1.4, support for long term storage
889      * of all JavaBeans<sup><font size="-2">TM</font></sup>
890      * has been added to the <code>java.beans</code> package.
891      * Please see {@link java.beans.XMLEncoder}.
892      */

893     protected class AccessibleJTextField extends AccessibleJTextComponent {
894
895         /**
896          * Gets the state set of this object.
897          *
898          * @return an instance of AccessibleStateSet describing the states
899          * of the object
900          * @see AccessibleState
901          */

902         public AccessibleStateSet getAccessibleStateSet() {
903             AccessibleStateSet states = super.getAccessibleStateSet();
904             states.add(AccessibleState.SINGLE_LINE);
905             return states;
906         }
907     }
908 }
909
Popular Tags