1. /*
  2. * @(#)JTextField.java 1.72 00/04/06
  3. *
  4. * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package javax.swing;
  11. import java.awt.*;
  12. import java.awt.event.*;
  13. import java.beans.*;
  14. import javax.swing.text.*;
  15. import javax.swing.plaf.*;
  16. import javax.swing.event.*;
  17. import javax.accessibility.*;
  18. import java.io.ObjectOutputStream;
  19. import java.io.ObjectInputStream;
  20. import java.io.IOException;
  21. /**
  22. * JTextField is a lightweight component that allows the editing
  23. * of a single line of text.
  24. * For information on and examples of using text fields,
  25. * see
  26. * <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/textfield.html">How to Use Text Fields</a>
  27. * in <em>The Java Tutorial.</em>
  28. *
  29. * <p>
  30. * JTextField is intended to be source-compatible
  31. * with java.awt.TextField where it is reasonable to do so. This
  32. * component has capabilities not found in the java.awt.TextField
  33. * class. The superclass should be consulted for additional capabilities.
  34. * <p>
  35. * JTextField has a method to establish the string used as the
  36. * command string for the action event that gets fired. The
  37. * java.awt.TextField used the text of the field as the command
  38. * string for the ActionEvent. JTextField will use the command
  39. * string set with the <code>setActionCommand</code> method if not null,
  40. * otherwise it will use the text of the field as a compatibility with
  41. * java.awt.TextField.
  42. * <p>
  43. * The method <code>setEchoChar</code> and <code>getEchoChar</code>
  44. * are not provided directly to avoid a new implementation of a
  45. * pluggable look-and-feel inadvertently exposing password characters.
  46. * To provide password-like services a separate class JPasswordField
  47. * extends JTextField to provide this service with an independently
  48. * pluggable look-and-feel.
  49. * <p>
  50. * The java.awt.TextField could be monitored for changes by adding
  51. * a TextListener for TextEvent's. In the JTextComponent based
  52. * components, changes are broadcasted from the model via a
  53. * DocumentEvent to DocumentListeners. The DocumentEvent gives
  54. * the location of the change and the kind of change if desired.
  55. * The code fragment might look something like:
  56. * <pre><code>
  57. *   DocumentListener myListener = ??;
  58. *   JTextField myArea = ??;
  59. *   myArea.getDocument().addDocumentListener(myListener);
  60. * </code></pre>
  61. * <p>
  62. * The horizontal alignment of JTextField can be set to be left
  63. * justified, leading justified, centered, right justified or trailing justified.
  64. * Right/trailing justification is useful if the required size
  65. * of the field text is smaller than the size allocated to it.
  66. * This is determined by the <code>setHorizontalAlignment</code>
  67. * and <code>getHorizontalAlignment</code> methods. The default
  68. * is to be leading justified.
  69. * <p>
  70. * For the keyboard keys used by this component in the standard Look and
  71. * Feel (L&F) renditions, see the
  72. * <a href="doc-files/Key-Index.html#JTextField">JTextField</a> key assignments.
  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.  public class UpperCaseField extends JTextField {
  92.  
  93.   public UpperCaseField(int cols) {
  94.   super(cols);
  95.   }
  96.  
  97.   protected Document createDefaultModel() {
  98.   return new UpperCaseDocument();
  99.   }
  100.  
  101.   static class UpperCaseDocument extends PlainDocument {
  102.  
  103.   public void insertString(int offs, String str, AttributeSet a)
  104.   throws BadLocationException {
  105.  
  106.   if (str == null) {
  107.   return;
  108.   }
  109.   char[] upper = str.toCharArray();
  110.   for (int i = 0; i < upper.length; i++) {
  111.   upper[i] = Character.toUpperCase(upper[i]);
  112.   }
  113.   super.insertString(offs, new String(upper), a);
  114.   }
  115.   }
  116.  }
  117. * </code></pre>
  118. * <p>
  119. * <strong>Warning:</strong>
  120. * Serialized objects of this class will not be compatible with
  121. * future Swing releases. The current serialization support is appropriate
  122. * for short term storage or RMI between applications running the same
  123. * version of Swing. A future release of Swing will provide support for
  124. * long term persistence.
  125. *
  126. * @beaninfo
  127. * attribute: isContainer false
  128. * description: A component which allows for the editing of a single line of text.
  129. *
  130. * @author Timothy Prinzing
  131. * @version 1.72 04/06/00
  132. * @see #setActionCommand
  133. * @see JPasswordField
  134. * @see #addActionListener
  135. */
  136. public class JTextField extends JTextComponent implements SwingConstants {
  137. /**
  138. * Constructs a new TextField. A default model is created, the initial
  139. * string is null, and the number of columns is set to 0.
  140. */
  141. public JTextField() {
  142. this(null, null, 0);
  143. }
  144. /**
  145. * Constructs a new TextField initialized with the specified text.
  146. * A default model is created and the number of columns is 0.
  147. *
  148. * @param text the text to be displayed, or null
  149. */
  150. public JTextField(String text) {
  151. this(null, text, 0);
  152. }
  153. /**
  154. * Constructs a new empty TextField with the specified number of columns.
  155. * A default model is created and the initial string is set to null.
  156. *
  157. * @param columns the number of columns to use to calculate
  158. * the preferred width. If columns is set to zero, the
  159. * preferred width will be whatever naturally results from
  160. * the component implementation.
  161. */
  162. public JTextField(int columns) {
  163. this(null, null, columns);
  164. }
  165. /**
  166. * Constructs a new TextField initialized with the specified text
  167. * and columns. A default model is created.
  168. *
  169. * @param text the text to be displayed, or null
  170. * @param columns the number of columns to use to calculate
  171. * the preferred width. If columns is set to zero, the
  172. * preferred width will be whatever naturally results from
  173. * the component implementation.
  174. */
  175. public JTextField(String text, int columns) {
  176. this(null, text, columns);
  177. }
  178. /**
  179. * Constructs a new JTextField that uses the given text storage
  180. * model and the given number of columns. This is the constructor
  181. * through which the other constructors feed. If the document is null,
  182. * a default model is created.
  183. *
  184. * @param doc the text storage to use. If this is null, a default
  185. * will be provided by calling the createDefaultModel method.
  186. * @param text the initial string to display, or null
  187. * @param columns the number of columns to use to calculate
  188. * the preferred width >= 0. If columns is set to zero, the
  189. * preferred width will be whatever naturally results from
  190. * the component implementation.
  191. * @exception IllegalArgumentException if columns < 0
  192. */
  193. public JTextField(Document doc, String text, int columns) {
  194. if (columns < 0) {
  195. throw new IllegalArgumentException("columns less than zero.");
  196. }
  197. visibility = new DefaultBoundedRangeModel();
  198. visibility.addChangeListener(new ScrollRepainter());
  199. this.columns = columns;
  200. if (doc == null) {
  201. doc = createDefaultModel();
  202. }
  203. setDocument(doc);
  204. if (text != null) {
  205. setText(text);
  206. }
  207. }
  208. /**
  209. * Gets the class ID for a UI.
  210. *
  211. * @return the ID ("TextFieldUI")
  212. * @see JComponent#getUIClassID
  213. * @see UIDefaults#getUI
  214. */
  215. public String getUIClassID() {
  216. return uiClassID;
  217. }
  218. /**
  219. * Calls to revalidate that come from within the textfield itself will
  220. * be handled by validating the textfield, unless the receiver
  221. * is contained within a JViewport, in which case this returns false.
  222. *
  223. * @see JComponent#revalidate
  224. * @see JComponent#isValidateRoot
  225. */
  226. public boolean isValidateRoot() {
  227. Component parent = getParent();
  228. if (parent instanceof JViewport) {
  229. return false;
  230. }
  231. return true;
  232. }
  233. /**
  234. * Returns the horizontal alignment of the text.
  235. * Valid keys: JTextField.LEFT, JTextField.CENTER, JTextField.RIGHT,
  236. * JTextField.LEADING and JTextField.TRAILING
  237. *
  238. * @return the alignment
  239. */
  240. public int getHorizontalAlignment() {
  241. return horizontalAlignment;
  242. }
  243. /**
  244. * Sets the horizontal alignment of the text.
  245. * Valid keys: JTextField.LEFT, JTextField.CENTER, JTextField.RIGHT,
  246. * JTextField.LEADING (the default) and JTextField.TRAILING.
  247. * invalidate() and repaint() are called when the alignment is set,
  248. * and a PropertyChange event ("horizontalAlignment") is fired.
  249. *
  250. * @param alignment the alignment
  251. * @exception IllegalArgumentException if the alignment
  252. * specified is not a valid key.
  253. * @beaninfo
  254. * preferred: true
  255. * bound: true
  256. * description: Set the field alignment to LEFT, CENTER, RIGHT,
  257. * LEADING (the default) or TRAILING
  258. * enum: LEFT JTextField.LEFT CENTER JTextField.CENTER RIGHT JTextField.RIGHT
  259. * LEADING JTextField.LEADING TRAILING JTextField.TRAILING
  260. */
  261. public void setHorizontalAlignment(int alignment) {
  262. if (alignment == horizontalAlignment) return;
  263. int oldValue = horizontalAlignment;
  264. if ((alignment == LEFT) || (alignment == CENTER) ||
  265. (alignment == RIGHT)|| (alignment == LEADING) ||
  266. (alignment == TRAILING)) {
  267. horizontalAlignment = alignment;
  268. } else {
  269. throw new IllegalArgumentException("horizontalAlignment");
  270. }
  271. firePropertyChange("horizontalAlignment", oldValue, horizontalAlignment);
  272. invalidate();
  273. repaint();
  274. }
  275. /**
  276. * Creates the default implementation of the model
  277. * to be used at construction if one isn't explicitly
  278. * given. An instance of PlainDocument is returned.
  279. *
  280. * @return the default model implementation
  281. */
  282. protected Document createDefaultModel() {
  283. return new PlainDocument();
  284. }
  285. /**
  286. * Returns the number of columns in this TextField.
  287. *
  288. * @return the number of columns >= 0
  289. */
  290. public int getColumns() {
  291. return columns;
  292. }
  293. /**
  294. * Sets the number of columns in this TextField, and then invalidate
  295. * the layout.
  296. *
  297. * @param columns the number of columns >= 0
  298. * @exception IllegalArgumentException if columns is less than 0
  299. * @beaninfo
  300. * description: the number of columns preferred for display
  301. */
  302. public void setColumns(int columns) {
  303. int oldVal = this.columns;
  304. if (columns < 0) {
  305. throw new IllegalArgumentException("columns less than zero.");
  306. }
  307. if (columns != oldVal) {
  308. this.columns = columns;
  309. invalidate();
  310. }
  311. }
  312. /**
  313. * Gets the column width.
  314. * The meaning of what a column is can be considered a fairly weak
  315. * notion for some fonts. This method is used to define the width
  316. * of a column. By default this is defined to be the width of the
  317. * character <em>m</em> for the font used. This method can be
  318. * redefined to be some alternative amount
  319. *
  320. * @return the column width >= 1
  321. */
  322. protected int getColumnWidth() {
  323. if (columnWidth == 0) {
  324. FontMetrics metrics = getFontMetrics(getFont());
  325. columnWidth = metrics.charWidth('m');
  326. }
  327. return columnWidth;
  328. }
  329. /**
  330. * Returns the preferred size Dimensions needed for this
  331. * TextField. If a non-zero number of columns has been
  332. * set, the width is set to the columns multiplied by
  333. * the column width.
  334. *
  335. * @return the dimensions
  336. */
  337. public Dimension getPreferredSize() {
  338. synchronized (getTreeLock()) {
  339. Dimension size = super.getPreferredSize();
  340. if (columns != 0) {
  341. size.width = columns * getColumnWidth();
  342. }
  343. return size;
  344. }
  345. }
  346. /**
  347. * Sets the current font. This removes cached row height and column
  348. * width so the new font will be reflected. revalidate() is called
  349. * after setting the font.
  350. *
  351. * @param f the new font
  352. */
  353. public void setFont(Font f) {
  354. super.setFont(f);
  355. columnWidth = 0;
  356. }
  357. /**
  358. * Adds the specified action listener to receive
  359. * action events from this textfield.
  360. *
  361. * @param l the action listener
  362. */
  363. public synchronized void addActionListener(ActionListener l) {
  364. listenerList.add(ActionListener.class, l);
  365. }
  366. /**
  367. * Removes the specified action listener so that it no longer
  368. * receives action events from this textfield.
  369. *
  370. * @param l the action listener
  371. */
  372. public synchronized void removeActionListener(ActionListener l) {
  373. if ((l != null) && (getAction() == l)) {
  374. setAction(null);
  375. } else {
  376. listenerList.remove(ActionListener.class, l);
  377. }
  378. }
  379. /**
  380. * Notifies all listeners that have registered interest for
  381. * notification on this event type. The event instance
  382. * is lazily created using the parameters passed into
  383. * the fire method. The listener list is processed in last to
  384. * first order.
  385. * @see EventListenerList
  386. */
  387. protected void fireActionPerformed() {
  388. // Guaranteed to return a non-null array
  389. Object[] listeners = listenerList.getListenerList();
  390. ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
  391. (command != null) ? command : getText());
  392. // Process the listeners last to first, notifying
  393. // those that are interested in this event
  394. for (int i = listeners.length-2; i>=0; i-=2) {
  395. if (listeners[i]==ActionListener.class) {
  396. ((ActionListener)listeners[i+1]).actionPerformed(e);
  397. }
  398. }
  399. }
  400. /**
  401. * Sets the command string used for action events.
  402. *
  403. * @param command the command string
  404. */
  405. public void setActionCommand(String command) {
  406. this.command = command;
  407. }
  408. private Action action;
  409. private PropertyChangeListener actionPropertyChangeListener;
  410. /**
  411. * Sets the Action for the ActionEvent source. The new Action replaces
  412. * any previously set Action but does not affect ActionListeners
  413. * independantly added with addActionListener(). If the Action is already
  414. * a registered ActionListener for the ActionEvent source, it is not re-registered.
  415. *
  416. * A side-effect of setting the Action is that the ActionEvent source's properties
  417. * are immediately set from the values in the Action (performed by the method
  418. * configurePropertiesFromAction()) and subsequently updated as the Action's
  419. * properties change (via a PropertyChangeListener created by the method
  420. * createActionPropertyChangeListener().
  421. *
  422. * @param a the Action for the JTextField, or null.
  423. * @since 1.3
  424. * @see Action
  425. * @see #getAction
  426. * @see #configurePropertiesFromAction
  427. * @see #createActionPropertyChangeListener
  428. * @beaninfo
  429. * bound: true
  430. * attribute: visualUpdate true
  431. * description: the Action instance connected with this ActionEvent source
  432. */
  433. public void setAction(Action a) {
  434. Action oldValue = getAction();
  435. if (action==null || !action.equals(a)) {
  436. action = a;
  437. if (oldValue!=null) {
  438. removeActionListener(oldValue);
  439. oldValue.removePropertyChangeListener(actionPropertyChangeListener);
  440. actionPropertyChangeListener = null;
  441. }
  442. configurePropertiesFromAction(action);
  443. if (action!=null) {
  444. // Don't add if it is already a listener
  445. if (!isListener(ActionListener.class, action)) {
  446. addActionListener(action);
  447. }
  448. // Reverse linkage:
  449. actionPropertyChangeListener = createActionPropertyChangeListener(action);
  450. action.addPropertyChangeListener(actionPropertyChangeListener);
  451. }
  452. firePropertyChange("action", oldValue, action);
  453. revalidate();
  454. repaint();
  455. }
  456. }
  457. private boolean isListener(Class c, ActionListener a) {
  458. boolean isListener = false;
  459. Object[] listeners = listenerList.getListenerList();
  460. for (int i = listeners.length-2; i>=0; i-=2) {
  461. if (listeners[i]==c && listeners[i+1]==a) {
  462. isListener=true;
  463. }
  464. }
  465. return isListener;
  466. }
  467. /**
  468. * Returns the currently set Action for this ActionEvent source,
  469. * or null if no Action is set.
  470. *
  471. * @return the Action for this ActionEvent source, or null.
  472. * @since 1.3
  473. * @see Action
  474. * @see #setAction
  475. */
  476. public Action getAction() {
  477. return action;
  478. }
  479. /**
  480. * Factory method which sets the ActionEvent source's properties
  481. * according to values from the Action instance. The properties
  482. * which are set may differ for subclasses.
  483. * By default, the properties which get set are
  484. * Enabled and ToolTipText.
  485. *
  486. * @param a the Action from which to get the properties, or null
  487. * @since 1.3
  488. * @see Action
  489. * @see #setAction
  490. */
  491. protected void configurePropertiesFromAction(Action a) {
  492. setEnabled((a!=null?a.isEnabled():true));
  493. setToolTipText((a!=null?(String)a.getValue(Action.SHORT_DESCRIPTION):null));
  494. }
  495. /**
  496. * Factory method which creates the PropertyChangeListener
  497. * used to update the ActionEvent source as properties change on
  498. * its Action instance. Subclasses may override this in order
  499. * to provide their own PropertyChangeListener if the set of
  500. * properties which should be kept up to date differs from the
  501. * default properties (Text, Enabled, ToolTipText).
  502. *
  503. * Note that PropertyChangeListeners should avoid holding
  504. * strong references to the ActionEvent source, as this may hinder
  505. * garbage collection of the ActionEvent source and all components
  506. * in its containment hierarchy.
  507. *
  508. * @since 1.3
  509. * @see Action
  510. * @see #setAction
  511. */
  512. protected PropertyChangeListener createActionPropertyChangeListener(Action a) {
  513. return new AbstractActionPropertyChangeListener(this, a) {
  514. public void propertyChange(PropertyChangeEvent e) {
  515. String propertyName = e.getPropertyName();
  516. JTextField textField = (JTextField)getTarget();
  517. if (textField == null) { //WeakRef GC'ed in 1.2
  518. Action action = (Action)e.getSource();
  519. action.removePropertyChangeListener(this);
  520. } else {
  521. if (e.getPropertyName().equals(Action.SHORT_DESCRIPTION)) {
  522. String text = (String) e.getNewValue();
  523. textField.setToolTipText(text);
  524. } else if (propertyName.equals("enabled")) {
  525. Boolean enabledState = (Boolean) e.getNewValue();
  526. textField.setEnabled(enabledState.booleanValue());
  527. textField.repaint();
  528. }
  529. }
  530. }
  531. };
  532. }
  533. /**
  534. * Fetches the command list for the editor. This is
  535. * the list of commands supported by the plugged-in UI
  536. * augmented by the collection of commands that the
  537. * editor itself supports. These are useful for binding
  538. * to events, such as in a keymap.
  539. *
  540. * @return the command list
  541. */
  542. public Action[] getActions() {
  543. return TextAction.augmentList(super.getActions(), defaultActions);
  544. }
  545. /**
  546. * Processes action events occurring on this textfield by
  547. * dispatching them to any registered ActionListener objects.
  548. * This is normally called by the controller registered with
  549. * textfield.
  550. */
  551. public void postActionEvent() {
  552. fireActionPerformed();
  553. }
  554. // --- Scrolling support -----------------------------------
  555. /**
  556. * Gets the visibility of the text field. This can
  557. * be adjusted to change the location of the visible
  558. * area if the size of the field is greater than
  559. * the area that was allocated to the field.
  560. *
  561. * The fields look-and-feel implementation manages
  562. * the values of the minimum, maximum, and extent
  563. * properties on the BoundedRangeModel.
  564. *
  565. * @return the visibility
  566. * @see BoundedRangeModel
  567. */
  568. public BoundedRangeModel getHorizontalVisibility() {
  569. return visibility;
  570. }
  571. /**
  572. * Gets the scroll offset.
  573. *
  574. * @return the offset >= 0
  575. */
  576. public int getScrollOffset() {
  577. return visibility.getValue();
  578. }
  579. /**
  580. * Sets the scroll offset.
  581. *
  582. * @param scrollOffset the offset >= 0
  583. */
  584. public void setScrollOffset(int scrollOffset) {
  585. visibility.setValue(scrollOffset);
  586. }
  587. /**
  588. * Scrolls the field left or right.
  589. *
  590. * @param r the region to scroll
  591. */
  592. public void scrollRectToVisible(Rectangle r) {
  593. // convert to coordinate system of the bounded range
  594. int x = r.x + visibility.getValue();
  595. if (x < visibility.getValue()) {
  596. // Scroll to the left
  597. visibility.setValue(x - 2);
  598. } else if(x > visibility.getValue() + visibility.getExtent()) {
  599. // Scroll to the right
  600. visibility.setValue(x - visibility.getExtent() + 2);
  601. }
  602. }
  603. /**
  604. * Returns true if the receiver has an ActionListener installed.
  605. */
  606. boolean hasActionListener() {
  607. // Guaranteed to return a non-null array
  608. Object[] listeners = listenerList.getListenerList();
  609. // Process the listeners last to first, notifying
  610. // those that are interested in this event
  611. for (int i = listeners.length-2; i>=0; i-=2) {
  612. if (listeners[i]==ActionListener.class) {
  613. return true;
  614. }
  615. }
  616. return false;
  617. }
  618. // --- variables -------------------------------------------
  619. /**
  620. * Name of the action to send notification that the
  621. * contents of the field have been accepted. Typically
  622. * this is bound to a carriage-return.
  623. */
  624. public static final String notifyAction = "notify-field-accept";
  625. private BoundedRangeModel visibility;
  626. private int horizontalAlignment = LEADING;
  627. private int columns;
  628. private int columnWidth;
  629. private String command;
  630. private static final Action[] defaultActions = {
  631. new NotifyAction()
  632. };
  633. /**
  634. * @see #getUIClassID
  635. * @see #readObject
  636. */
  637. private static final String uiClassID = "TextFieldUI";
  638. // --- Action implementations -----------------------------------
  639. static class NotifyAction extends TextAction {
  640. NotifyAction() {
  641. super(notifyAction);
  642. }
  643. public void actionPerformed(ActionEvent e) {
  644. JTextComponent target = getFocusedComponent();
  645. if (target instanceof JTextField) {
  646. JTextField field = (JTextField) target;
  647. field.postActionEvent();
  648. }
  649. }
  650. public boolean isEnabled() {
  651. JTextComponent target = getFocusedComponent();
  652. if (target instanceof JTextField) {
  653. return ((JTextField)target).hasActionListener();
  654. }
  655. return false;
  656. }
  657. }
  658. class ScrollRepainter implements ChangeListener {
  659. public void stateChanged(ChangeEvent e) {
  660. repaint();
  661. }
  662. }
  663. /**
  664. * See readObject() and writeObject() in JComponent for more
  665. * information about serialization in Swing.
  666. */
  667. private void writeObject(ObjectOutputStream s) throws IOException {
  668. s.defaultWriteObject();
  669. if ((ui != null) && (getUIClassID().equals(uiClassID))) {
  670. ui.installUI(this);
  671. }
  672. }
  673. /**
  674. * Returns a string representation of this JTextField. This method
  675. * is intended to be used only for debugging purposes, and the
  676. * content and format of the returned string may vary between
  677. * implementations. The returned string may be empty but may not
  678. * be <code>null</code>.
  679. *
  680. * @return a string representation of this JTextField.
  681. */
  682. protected String paramString() {
  683. String horizontalAlignmentString;
  684. if (horizontalAlignment == LEFT) {
  685. horizontalAlignmentString = "LEFT";
  686. } else if (horizontalAlignment == CENTER) {
  687. horizontalAlignmentString = "CENTER";
  688. } else if (horizontalAlignment == RIGHT) {
  689. horizontalAlignmentString = "RIGHT";
  690. } else if (horizontalAlignment == LEADING) {
  691. horizontalAlignmentString = "LEADING";
  692. } else if (horizontalAlignment == TRAILING) {
  693. horizontalAlignmentString = "TRAILING";
  694. } else horizontalAlignmentString = "";
  695. String commandString = (command != null ?
  696. command : "");
  697. return super.paramString() +
  698. ",columns=" + columns +
  699. ",columnWidth=" + columnWidth +
  700. ",command=" + commandString +
  701. ",horizontalAlignment=" + horizontalAlignmentString;
  702. }
  703. /////////////////
  704. // Accessibility support
  705. ////////////////
  706. /**
  707. * Gets the AccessibleContext associated with this JTextField.
  708. * For JTextFields, the AccessibleContext takes the form of an
  709. * AccessibleJTextField.
  710. * A new AccessibleJTextField instance is created if necessary.
  711. *
  712. * @return an AccessibleJTextField that serves as the
  713. * AccessibleContext of this JTextField
  714. */
  715. public AccessibleContext getAccessibleContext() {
  716. if (accessibleContext == null) {
  717. accessibleContext = new AccessibleJTextField();
  718. }
  719. return accessibleContext;
  720. }
  721. /**
  722. * This class implements accessibility support for the
  723. * <code>JTextField</code> class. It provides an implementation of the
  724. * Java Accessibility API appropriate to text field user-interface
  725. * elements.
  726. * <p>
  727. * <strong>Warning:</strong>
  728. * Serialized objects of this class will not be compatible with
  729. * future Swing releases. The current serialization support is appropriate
  730. * for short term storage or RMI between applications running the same
  731. * version of Swing. A future release of Swing will provide support for
  732. * long term persistence.
  733. */
  734. protected class AccessibleJTextField extends AccessibleJTextComponent {
  735. /**
  736. * Gets the state set of this object.
  737. *
  738. * @return an instance of AccessibleStateSet describing the states
  739. * of the object
  740. * @see AccessibleState
  741. */
  742. public AccessibleStateSet getAccessibleStateSet() {
  743. AccessibleStateSet states = super.getAccessibleStateSet();
  744. states.add(AccessibleState.SINGLE_LINE);
  745. return states;
  746. }
  747. }
  748. }