1 /* 2 * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package java.awt; 26 27 import java.awt.peer.TextFieldPeer; 28 import java.awt.event.*; 29 import java.util.EventListener; 30 import java.io.ObjectOutputStream; 31 import java.io.ObjectInputStream; 32 import java.io.IOException; 33 import javax.accessibility.*; 34 35 36 /** 37 * A {@code TextField} object is a text component 38 * that allows for the editing of a single line of text. 39 * If input text contains new line character, then 40 * {@code TextField} replaces it by space character. 41 * <p> 42 * For example, the following image depicts a frame with four 43 * text fields of varying widths. Two of these text fields 44 * display the predefined text {@code "Hello"}. 45 * <p> 46 * <img src="doc-files/TextField-1.gif" alt="The preceding text describes this image." 47 * style="float:center; margin: 7px 10px;"> 48 * <p> 49 * Here is the code that produces these four text fields: 50 * 51 * <hr><blockquote><pre> 52 * TextField tf1, tf2, tf3, tf4; 53 * // a blank text field 54 * tf1 = new TextField(); 55 * // blank field of 20 columns 56 * tf2 = new TextField("", 20); 57 * // predefined text displayed 58 * tf3 = new TextField("Hello!"); 59 * // predefined text in 30 columns 60 * tf4 = new TextField("Hello", 30); 61 * </pre></blockquote><hr> 62 * <p> 63 * Every time the user types a key in the text field, one or 64 * more key events are sent to the text field. A {@code KeyEvent} 65 * may be one of three types: keyPressed, keyReleased, or keyTyped. 66 * The properties of a key event indicate which of these types 67 * it is, as well as additional information about the event, 68 * such as what modifiers are applied to the key event and the 69 * time at which the event occurred. 70 * <p> 71 * The key event is passed to every {@code KeyListener} 72 * or {@code KeyAdapter} object which registered to receive such 73 * events using the component's {@code addKeyListener} method. 74 * ({@code KeyAdapter} objects implement the 75 * {@code KeyListener} interface.) 76 * <p> 77 * It is also possible to fire an {@code ActionEvent}. 78 * If action events are enabled for the text field, they may 79 * be fired by pressing the {@code Return} key. 80 * <p> 81 * The {@code TextField} class's {@code processEvent} 82 * method examines the action event and passes it along to 83 * {@code processActionEvent}. The latter method redirects the 84 * event to any {@code ActionListener} objects that have 85 * registered to receive action events generated by this 86 * text field. 87 * 88 * @author Sami Shaio 89 * @see java.awt.event.KeyEvent 90 * @see java.awt.event.KeyAdapter 91 * @see java.awt.event.KeyListener 92 * @see java.awt.event.ActionEvent 93 * @see java.awt.Component#addKeyListener 94 * @see java.awt.TextField#processEvent 95 * @see java.awt.TextField#processActionEvent 96 * @see java.awt.TextField#addActionListener 97 * @since 1.0 98 */ 99 public class TextField extends TextComponent { 100 101 /** 102 * The number of columns in the text field. 103 * A column is an approximate average character 104 * width that is platform-dependent. 105 * Guaranteed to be non-negative. 106 * 107 * @serial 108 * @see #setColumns(int) 109 * @see #getColumns() 110 */ 111 int columns; 112 113 /** 114 * The echo character, which is used when 115 * the user wishes to disguise the characters 116 * typed into the text field. 117 * The disguises are removed if echoChar = {@code 0}. 118 * 119 * @serial 120 * @see #getEchoChar() 121 * @see #setEchoChar(char) 122 * @see #echoCharIsSet() 123 */ 124 char echoChar; 125 126 transient ActionListener actionListener; 127 128 private static final String base = "textfield"; 129 private static int nameCounter = 0; 130 131 /* 132 * JDK 1.1 serialVersionUID 133 */ 134 private static final long serialVersionUID = -2966288784432217853L; 135 136 /** 137 * Initialize JNI field and method ids 138 */ 139 private static native void initIDs(); 140 141 static { 142 /* ensure that the necessary native libraries are loaded */ 143 Toolkit.loadLibraries(); 144 if (!GraphicsEnvironment.isHeadless()) { 145 initIDs(); 146 } 147 } 148 149 /** 150 * Constructs a new text field. 151 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 152 * returns true. 153 * @see java.awt.GraphicsEnvironment#isHeadless 154 */ 155 public TextField() throws HeadlessException { 156 this("", 0); 157 } 158 159 /** 160 * Constructs a new text field initialized with the specified text. 161 * @param text the text to be displayed. If 162 * {@code text} is {@code null}, the empty 163 * string {@code ""} will be displayed. 164 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 165 * returns true. 166 * @see java.awt.GraphicsEnvironment#isHeadless 167 */ 168 public TextField(String text) throws HeadlessException { 169 this(text, (text != null) ? text.length() : 0); 170 } 171 172 /** 173 * Constructs a new empty text field with the specified number 174 * of columns. A column is an approximate average character 175 * width that is platform-dependent. 176 * @param columns the number of columns. If 177 * {@code columns} is less than {@code 0}, 178 * {@code columns} is set to {@code 0}. 179 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 180 * returns true. 181 * @see java.awt.GraphicsEnvironment#isHeadless 182 */ 183 public TextField(int columns) throws HeadlessException { 184 this("", columns); 185 } 186 187 /** 188 * Constructs a new text field initialized with the specified text 189 * to be displayed, and wide enough to hold the specified 190 * number of columns. A column is an approximate average character 191 * width that is platform-dependent. 192 * @param text the text to be displayed. If 193 * {@code text} is {@code null}, the empty 194 * string {@code ""} will be displayed. 195 * @param columns the number of columns. If 196 * {@code columns} is less than {@code 0}, 197 * {@code columns} is set to {@code 0}. 198 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 199 * returns true. 200 * @see java.awt.GraphicsEnvironment#isHeadless 201 */ 202 public TextField(String text, int columns) throws HeadlessException { 203 super(replaceEOL(text)); 204 this.columns = (columns >= 0) ? columns : 0; 205 } 206 207 /** 208 * Construct a name for this component. Called by getName() when the 209 * name is null. 210 */ 211 String constructComponentName() { 212 synchronized (TextField.class) { 213 return base + nameCounter++; 214 } 215 } 216 217 /** 218 * Creates the TextField's peer. The peer allows us to modify the 219 * appearance of the TextField without changing its functionality. 220 */ 221 public void addNotify() { 222 synchronized (getTreeLock()) { 223 if (peer == null) 224 peer = getComponentFactory().createTextField(this); 225 super.addNotify(); 226 } 227 } 228 229 /** 230 * Gets the character that is to be used for echoing. 231 * <p> 232 * An echo character is useful for text fields where 233 * user input should not be echoed to the screen, as in 234 * the case of a text field for entering a password. 235 * If {@code echoChar} = {@code 0}, user 236 * input is echoed to the screen unchanged. 237 * <p> 238 * A Java platform implementation may support only a limited, 239 * non-empty set of echo characters. This function returns the 240 * echo character originally requested via setEchoChar(). The echo 241 * character actually used by the TextField implementation might be 242 * different. 243 * @return the echo character for this text field. 244 * @see java.awt.TextField#echoCharIsSet 245 * @see java.awt.TextField#setEchoChar 246 */ 247 public char getEchoChar() { 248 return echoChar; 249 } 250 251 /** 252 * Sets the echo character for this text field. 253 * <p> 254 * An echo character is useful for text fields where 255 * user input should not be echoed to the screen, as in 256 * the case of a text field for entering a password. 257 * Setting {@code echoChar} = {@code 0} allows 258 * user input to be echoed to the screen again. 259 * <p> 260 * A Java platform implementation may support only a limited, 261 * non-empty set of echo characters. Attempts to set an 262 * unsupported echo character will cause the default echo 263 * character to be used instead. Subsequent calls to getEchoChar() 264 * will return the echo character originally requested. This might 265 * or might not be identical to the echo character actually 266 * used by the TextField implementation. 267 * @param c the echo character for this text field. 268 * @see java.awt.TextField#echoCharIsSet 269 * @see java.awt.TextField#getEchoChar 270 * @since 1.1 271 */ 272 public void setEchoChar(char c) { 273 setEchoCharacter(c); 274 } 275 276 /** 277 * Sets the character to be echoed when protected input is displayed. 278 * 279 * @param c the echo character for this text field 280 * 281 * @deprecated As of JDK version 1.1, 282 * replaced by {@code setEchoChar(char)}. 283 */ 284 @Deprecated 285 public synchronized void setEchoCharacter(char c) { 286 if (echoChar != c) { 287 echoChar = c; 288 TextFieldPeer peer = (TextFieldPeer)this.peer; 289 if (peer != null) { 290 peer.setEchoChar(c); 291 } 292 } 293 } 294 295 /** 296 * Sets the text that is presented by this 297 * text component to be the specified text. 298 * @param t the new text. 299 * @see java.awt.TextComponent#getText 300 */ 301 public void setText(String t) { 302 super.setText(replaceEOL(t)); 303 304 // This could change the preferred size of the Component. 305 invalidateIfValid(); 306 } 307 308 /** 309 * Replaces EOL characters from the text variable with a space character. 310 * @param text the new text. 311 * @return Returns text after replacing EOL characters. 312 */ 313 private static String replaceEOL(String text) { 314 if (text == null) { 315 return text; 316 } 317 String[] strEOLs = {System.lineSeparator(), "\n"}; 318 for (String eol : strEOLs) { 319 if (text.contains(eol)) { 320 text = text.replace(eol, " "); 321 } 322 } 323 return text; 324 } 325 326 327 /** 328 * Indicates whether or not this text field has a 329 * character set for echoing. 330 * <p> 331 * An echo character is useful for text fields where 332 * user input should not be echoed to the screen, as in 333 * the case of a text field for entering a password. 334 * @return {@code true} if this text field has 335 * a character set for echoing; 336 * {@code false} otherwise. 337 * @see java.awt.TextField#setEchoChar 338 * @see java.awt.TextField#getEchoChar 339 */ 340 public boolean echoCharIsSet() { 341 return echoChar != 0; 342 } 343 344 /** 345 * Gets the number of columns in this text field. A column is an 346 * approximate average character width that is platform-dependent. 347 * @return the number of columns. 348 * @see java.awt.TextField#setColumns 349 * @since 1.1 350 */ 351 public int getColumns() { 352 return columns; 353 } 354 355 /** 356 * Sets the number of columns in this text field. A column is an 357 * approximate average character width that is platform-dependent. 358 * @param columns the number of columns. 359 * @see java.awt.TextField#getColumns 360 * @exception IllegalArgumentException if the value 361 * supplied for {@code columns} 362 * is less than {@code 0}. 363 * @since 1.1 364 */ 365 public void setColumns(int columns) { 366 int oldVal; 367 synchronized (this) { 368 oldVal = this.columns; 369 if (columns < 0) { 370 throw new IllegalArgumentException("columns less than zero."); 371 } 372 if (columns != oldVal) { 373 this.columns = columns; 374 } 375 } 376 377 if (columns != oldVal) { 378 invalidate(); 379 } 380 } 381 382 /** 383 * Gets the preferred size of this text field 384 * with the specified number of columns. 385 * @param columns the number of columns 386 * in this text field. 387 * @return the preferred dimensions for 388 * displaying this text field. 389 * @since 1.1 390 */ 391 public Dimension getPreferredSize(int columns) { 392 return preferredSize(columns); 393 } 394 395 /** 396 * Returns the preferred size for this text field 397 * with the specified number of columns. 398 * 399 * @param columns the number of columns 400 * @return the preferred size for the text field 401 * 402 * @deprecated As of JDK version 1.1, 403 * replaced by {@code getPreferredSize(int)}. 404 */ 405 @Deprecated 406 public Dimension preferredSize(int columns) { 407 synchronized (getTreeLock()) { 408 TextFieldPeer peer = (TextFieldPeer)this.peer; 409 return (peer != null) ? 410 peer.getPreferredSize(columns) : 411 super.preferredSize(); 412 } 413 } 414 415 /** 416 * Gets the preferred size of this text field. 417 * @return the preferred dimensions for 418 * displaying this text field. 419 * @since 1.1 420 */ 421 public Dimension getPreferredSize() { 422 return preferredSize(); 423 } 424 425 /** 426 * @deprecated As of JDK version 1.1, 427 * replaced by {@code getPreferredSize()}. 428 */ 429 @Deprecated 430 public Dimension preferredSize() { 431 synchronized (getTreeLock()) { 432 return (columns > 0) ? 433 preferredSize(columns) : 434 super.preferredSize(); 435 } 436 } 437 438 /** 439 * Gets the minimum dimensions for a text field with 440 * the specified number of columns. 441 * @param columns the number of columns in 442 * this text field. 443 * @return the minimum size for this text field 444 * @since 1.1 445 */ 446 public Dimension getMinimumSize(int columns) { 447 return minimumSize(columns); 448 } 449 450 /** 451 * Returns the minimum dimensions for a text field with 452 * the specified number of columns. 453 * 454 * @param columns the number of columns 455 * @return the minimum size for this text field 456 * @deprecated As of JDK version 1.1, 457 * replaced by {@code getMinimumSize(int)}. 458 */ 459 @Deprecated 460 public Dimension minimumSize(int columns) { 461 synchronized (getTreeLock()) { 462 TextFieldPeer peer = (TextFieldPeer)this.peer; 463 return (peer != null) ? 464 peer.getMinimumSize(columns) : 465 super.minimumSize(); 466 } 467 } 468 469 /** 470 * Gets the minimum dimensions for this text field. 471 * @return the minimum dimensions for 472 * displaying this text field. 473 * @since 1.1 474 */ 475 public Dimension getMinimumSize() { 476 return minimumSize(); 477 } 478 479 /** 480 * @deprecated As of JDK version 1.1, 481 * replaced by {@code getMinimumSize()}. 482 */ 483 @Deprecated 484 public Dimension minimumSize() { 485 synchronized (getTreeLock()) { 486 return (columns > 0) ? 487 minimumSize(columns) : 488 super.minimumSize(); 489 } 490 } 491 492 /** 493 * Adds the specified action listener to receive 494 * action events from this text field. 495 * If l is null, no exception is thrown and no action is performed. 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 #removeActionListener 501 * @see #getActionListeners 502 * @see java.awt.event.ActionListener 503 * @since 1.1 504 */ 505 public synchronized void addActionListener(ActionListener l) { 506 if (l == null) { 507 return; 508 } 509 actionListener = AWTEventMulticaster.add(actionListener, l); 510 newEventsOnly = true; 511 } 512 513 /** 514 * Removes the specified action listener so that it no longer 515 * receives action events from this text field. 516 * If l is null, no exception is thrown and no action is performed. 517 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 518 * >AWT Threading Issues</a> for details on AWT's threading model. 519 * 520 * @param l the action listener. 521 * @see #addActionListener 522 * @see #getActionListeners 523 * @see java.awt.event.ActionListener 524 * @since 1.1 525 */ 526 public synchronized void removeActionListener(ActionListener l) { 527 if (l == null) { 528 return; 529 } 530 actionListener = AWTEventMulticaster.remove(actionListener, l); 531 } 532 533 /** 534 * Returns an array of all the action listeners 535 * registered on this textfield. 536 * 537 * @return all of this textfield's {@code ActionListener}s 538 * or an empty array if no action 539 * listeners are currently registered 540 * 541 * @see #addActionListener 542 * @see #removeActionListener 543 * @see java.awt.event.ActionListener 544 * @since 1.4 545 */ 546 public synchronized ActionListener[] getActionListeners() { 547 return getListeners(ActionListener.class); 548 } 549 550 /** 551 * Returns an array of all the objects currently registered 552 * as <code><em>Foo</em>Listener</code>s 553 * upon this {@code TextField}. 554 * <code><em>Foo</em>Listener</code>s are registered using the 555 * <code>add<em>Foo</em>Listener</code> method. 556 * 557 * <p> 558 * You can specify the {@code listenerType} argument 559 * with a class literal, such as 560 * <code><em>Foo</em>Listener.class</code>. 561 * For example, you can query a 562 * {@code TextField t} 563 * for its action listeners with the following code: 564 * 565 * <pre>ActionListener[] als = (ActionListener[])(t.getListeners(ActionListener.class));</pre> 566 * 567 * If no such listeners exist, this method returns an empty array. 568 * 569 * @param listenerType the type of listeners requested; this parameter 570 * should specify an interface that descends from 571 * {@code java.util.EventListener} 572 * @return an array of all objects registered as 573 * <code><em>Foo</em>Listener</code>s on this textfield, 574 * or an empty array if no such 575 * listeners have been added 576 * @exception ClassCastException if {@code listenerType} 577 * doesn't specify a class or interface that implements 578 * {@code java.util.EventListener} 579 * 580 * @see #getActionListeners 581 * @since 1.3 582 */ 583 public <T extends EventListener> T[] getListeners(Class<T> listenerType) { 584 EventListener l = null; 585 if (listenerType == ActionListener.class) { 586 l = actionListener; 587 } else { 588 return super.getListeners(listenerType); 589 } 590 return AWTEventMulticaster.getListeners(l, listenerType); 591 } 592 593 // REMIND: remove when filtering is done at lower level 594 boolean eventEnabled(AWTEvent e) { 595 if (e.id == ActionEvent.ACTION_PERFORMED) { 596 if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0 || 597 actionListener != null) { 598 return true; 599 } 600 return false; 601 } 602 return super.eventEnabled(e); 603 } 604 605 /** 606 * Processes events on this text field. If the event 607 * is an instance of {@code ActionEvent}, 608 * it invokes the {@code processActionEvent} 609 * method. Otherwise, it invokes {@code processEvent} 610 * on the superclass. 611 * <p>Note that if the event parameter is {@code null} 612 * the behavior is unspecified and may result in an 613 * exception. 614 * 615 * @param e the event 616 * @see java.awt.event.ActionEvent 617 * @see java.awt.TextField#processActionEvent 618 * @since 1.1 619 */ 620 protected void processEvent(AWTEvent e) { 621 if (e instanceof ActionEvent) { 622 processActionEvent((ActionEvent)e); 623 return; 624 } 625 super.processEvent(e); 626 } 627 628 /** 629 * Processes action events occurring on this text field by 630 * dispatching them to any registered 631 * {@code ActionListener} objects. 632 * <p> 633 * This method is not called unless action events are 634 * enabled for this component. Action events are enabled 635 * when one of the following occurs: 636 * <ul> 637 * <li>An {@code ActionListener} object is registered 638 * via {@code addActionListener}. 639 * <li>Action events are enabled via {@code enableEvents}. 640 * </ul> 641 * <p>Note that if the event parameter is {@code null} 642 * the behavior is unspecified and may result in an 643 * exception. 644 * 645 * @param e the action event 646 * @see java.awt.event.ActionListener 647 * @see java.awt.TextField#addActionListener 648 * @see java.awt.Component#enableEvents 649 * @since 1.1 650 */ 651 protected void processActionEvent(ActionEvent e) { 652 ActionListener listener = actionListener; 653 if (listener != null) { 654 listener.actionPerformed(e); 655 } 656 } 657 658 /** 659 * Returns a string representing the state of this {@code TextField}. 660 * This method is intended to be used only for debugging purposes, and the 661 * content and format of the returned string may vary between 662 * implementations. The returned string may be empty but may not be 663 * {@code null}. 664 * 665 * @return the parameter string of this text field 666 */ 667 protected String paramString() { 668 String str = super.paramString(); 669 if (echoChar != 0) { 670 str += ",echo=" + echoChar; 671 } 672 return str; 673 } 674 675 676 /* 677 * Serialization support. 678 */ 679 /** 680 * The textField Serialized Data Version. 681 * 682 * @serial 683 */ 684 private int textFieldSerializedDataVersion = 1; 685 686 /** 687 * Writes default serializable fields to stream. Writes 688 * a list of serializable ActionListener(s) as optional data. 689 * The non-serializable ActionListener(s) are detected and 690 * no attempt is made to serialize them. 691 * 692 * @serialData Null terminated sequence of zero or more pairs. 693 * A pair consists of a String and Object. 694 * The String indicates the type of object and 695 * is one of the following : 696 * ActionListenerK indicating and ActionListener object. 697 * 698 * @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener) 699 * @see java.awt.Component#actionListenerK 700 */ 701 private void writeObject(ObjectOutputStream s) 702 throws IOException 703 { 704 s.defaultWriteObject(); 705 706 AWTEventMulticaster.save(s, actionListenerK, actionListener); 707 s.writeObject(null); 708 } 709 710 /** 711 * Read the ObjectInputStream and if it isn't null, 712 * add a listener to receive action events fired by the 713 * TextField. Unrecognized keys or values will be 714 * ignored. 715 * 716 * @exception HeadlessException if 717 * {@code GraphicsEnvironment.isHeadless()} returns 718 * {@code true} 719 * @see #removeActionListener(ActionListener) 720 * @see #addActionListener(ActionListener) 721 * @see java.awt.GraphicsEnvironment#isHeadless 722 */ 723 private void readObject(ObjectInputStream s) 724 throws ClassNotFoundException, IOException, HeadlessException 725 { 726 // HeadlessException will be thrown by TextComponent's readObject 727 s.defaultReadObject(); 728 text = replaceEOL(text); 729 730 // Make sure the state we just read in for columns has legal values 731 if (columns < 0) { 732 columns = 0; 733 } 734 735 // Read in listeners, if any 736 Object keyOrNull; 737 while(null != (keyOrNull = s.readObject())) { 738 String key = ((String)keyOrNull).intern(); 739 740 if (actionListenerK == key) { 741 addActionListener((ActionListener)(s.readObject())); 742 } else { 743 // skip value for unrecognized key 744 s.readObject(); 745 } 746 } 747 } 748 749 750 ///////////////// 751 // Accessibility support 752 //////////////// 753 754 755 /** 756 * Gets the AccessibleContext associated with this TextField. 757 * For text fields, the AccessibleContext takes the form of an 758 * AccessibleAWTTextField. 759 * A new AccessibleAWTTextField instance is created if necessary. 760 * 761 * @return an AccessibleAWTTextField that serves as the 762 * AccessibleContext of this TextField 763 * @since 1.3 764 */ 765 public AccessibleContext getAccessibleContext() { 766 if (accessibleContext == null) { 767 accessibleContext = new AccessibleAWTTextField(); 768 } 769 return accessibleContext; 770 } 771 772 /** 773 * This class implements accessibility support for the 774 * {@code TextField} class. It provides an implementation of the 775 * Java Accessibility API appropriate to text field user-interface elements. 776 * @since 1.3 777 */ 778 protected class AccessibleAWTTextField extends AccessibleAWTTextComponent 779 { 780 /* 781 * JDK 1.3 serialVersionUID 782 */ 783 private static final long serialVersionUID = 6219164359235943158L; 784 785 /** 786 * Gets the state set of this object. 787 * 788 * @return an instance of AccessibleStateSet describing the states 789 * of the object 790 * @see AccessibleState 791 */ 792 public AccessibleStateSet getAccessibleStateSet() { 793 AccessibleStateSet states = super.getAccessibleStateSet(); 794 states.add(AccessibleState.SINGLE_LINE); 795 return states; 796 } 797 } 798 799 }