1. /*
  2. * @(#)TextArea.java 1.57 00/04/06
  3. *
  4. * Copyright 1995-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 java.awt;
  11. import java.awt.peer.TextAreaPeer;
  12. import java.io.ObjectOutputStream;
  13. import java.io.ObjectInputStream;
  14. import java.io.IOException;
  15. import javax.accessibility.*;
  16. /**
  17. * A <code>TextArea</code> object is a multi-line region
  18. * that displays text. It can be set to allow editing or
  19. * to be read-only.
  20. * <p>
  21. * The following image shows the appearance of a text area:
  22. * <p>
  23. * <img src="doc-files/TextArea-1.gif"
  24. * ALIGN=center HSPACE=10 VSPACE=7>
  25. * <p>
  26. * This text area could be created by the following line of code:
  27. * <p>
  28. * <hr><blockquote><pre>
  29. * new TextArea("Hello", 5, 40);
  30. * </pre></blockquote><hr>
  31. * <p>
  32. * @version 1.57, 04/06/00
  33. * @author Sami Shaio
  34. * @since JDK1.0
  35. */
  36. public class TextArea extends TextComponent {
  37. /**
  38. * The number of rows in the TextArea.
  39. * This parameter will determine the text area's height.
  40. * Guaranteed to be non-negative.
  41. *
  42. * @serial
  43. * @see getRows()
  44. * @see setRows()
  45. */
  46. int rows;
  47. /**
  48. * The number of columns in the TextArea.
  49. * A column is an approximate average character
  50. * width that is platform-dependent.
  51. * This parameter will determine the text area's width.
  52. * Guaranteed to be non-negative.
  53. *
  54. * @serial
  55. * @see getColumns()
  56. * @see setColumns()
  57. */
  58. int columns;
  59. private static final String base = "text";
  60. private static int nameCounter = 0;
  61. /**
  62. * Create and display both vertical and horizontal scrollbars.
  63. * @since JDK1.1
  64. */
  65. public static final int SCROLLBARS_BOTH = 0;
  66. /**
  67. * Create and display vertical scrollbar only.
  68. * @since JDK1.1
  69. */
  70. public static final int SCROLLBARS_VERTICAL_ONLY = 1;
  71. /**
  72. * Create and display horizontal scrollbar only.
  73. * @since JDK1.1
  74. */
  75. public static final int SCROLLBARS_HORIZONTAL_ONLY = 2;
  76. /**
  77. * Do not create or display any scrollbars for the text area.
  78. * @since JDK1.1
  79. */
  80. public static final int SCROLLBARS_NONE = 3;
  81. /**
  82. * Determines which scrollbars are created for the
  83. * text area. It can be one of four values :
  84. * <code>SCROLLBARS_BOTH</code> = both scrollbars.<BR>
  85. * <code>SCROLLBARS_HORIZONTAL_ONLY</code> = Horizontal bar only.<BR>
  86. * <code>SCROLLBARS_VERTICAL_ONLY</code> = Vertical bar only.<BR>
  87. * <code>SCROLLBARS_NONE</code> = No scrollbars.<BR>
  88. *
  89. * @serial
  90. * @see getScrollbarVisibility()
  91. */
  92. private int scrollbarVisibility;
  93. /*
  94. * JDK 1.1 serialVersionUID
  95. */
  96. private static final long serialVersionUID = 3692302836626095722L;
  97. /**
  98. * Initialize JNI field and method ids
  99. */
  100. private static native void initIDs();
  101. static {
  102. /* ensure that the necessary native libraries are loaded */
  103. Toolkit.loadLibraries();
  104. initIDs();
  105. }
  106. /**
  107. * Constructs a new text area.
  108. * This text area is created with scrollbar visibility equal to
  109. * {@link #SCROLLBARS_BOTH}, so both vertical and horizontal
  110. * scrollbars will be visible for this text area.
  111. */
  112. public TextArea() {
  113. this("", 0, 0, SCROLLBARS_BOTH);
  114. }
  115. /**
  116. * Constructs a new text area with the specified text.
  117. * This text area is created with scrollbar visibility equal to
  118. * {@link #SCROLLBARS_BOTH}, so both vertical and horizontal
  119. * scrollbars will be visible for this text area.
  120. * @param text the text to be displayed.
  121. */
  122. public TextArea(String text) {
  123. this(text, 0, 0, SCROLLBARS_BOTH);
  124. }
  125. /**
  126. * Constructs a new empty text area with the specified number of
  127. * rows and columns. A column is an approximate average character
  128. * width that is platform-dependent. The text area is created with
  129. * scrollbar visibility equal to {@link #SCROLLBARS_BOTH}, so both
  130. * vertical and horizontal scrollbars will be visible for this
  131. * text area.
  132. * @param rows the number of rows
  133. * @param columns the number of columns
  134. */
  135. public TextArea(int rows, int columns) {
  136. this("", rows, columns, SCROLLBARS_BOTH);
  137. }
  138. /**
  139. * Constructs a new text area with the specified text,
  140. * and with the specified number of rows and columns.
  141. * A column is an approximate average character
  142. * width that is platform-dependent. The text area is created with
  143. * scrollbar visibility equal to {@link #SCROLLBARS_BOTH}, so both
  144. * vertical and horizontal scrollbars will be visible for this
  145. * text area.
  146. * @param text the text to be displayed.
  147. * @param rows the number of rows.
  148. * @param columns the number of columns.
  149. */
  150. public TextArea(String text, int rows, int columns) {
  151. this(text, rows, columns, SCROLLBARS_BOTH);
  152. }
  153. /**
  154. * Constructs a new text area with the specified text,
  155. * and with the rows, columns, and scroll bar visibility
  156. * as specified.
  157. * <p>
  158. * The <code>TextArea</code> class defines several constants
  159. * that can be supplied as values for the
  160. * <code>scrollbars</code> argument:
  161. * <code>SCROLLBARS_BOTH</code>,
  162. * <code>SCROLLBARS_VERTICAL_ONLY</code>,
  163. * <code>SCROLLBARS_HORIZONTAL_ONLY</code>,
  164. * and <code>SCROLLBARS_NONE</code>. Any other value for the
  165. * <code>scrollbars</code> argument is invalid and will result in
  166. * this text area being created with scrollbar visibility equal to
  167. * the default value of {@link #SCROLLBARS_BOTH}.
  168. * @param text the text to be displayed. If
  169. * <code>text</code> is <code>null</code>, the empty
  170. * string <code>""</code> will be displayed.
  171. * @param rows the number of rows. If
  172. * <code>rows</code> is less than <code>0</code>,
  173. * <code>rows</code> is set to <code>0</code>.
  174. * @param columns the number of columns. If
  175. * <code>columns</code> is less than <code>0</code>,
  176. * <code>columns</code> is set to <code>0</code>.
  177. * @param scrollbars a constant that determines what
  178. * scrollbars are created to view the text area.
  179. * @since JDK1.1
  180. */
  181. public TextArea(String text, int rows, int columns, int scrollbars) {
  182. super(text);
  183. this.rows = (rows >= 0) ? rows : 0;
  184. this.columns = (columns >= 0) ? columns : 0;
  185. if ((scrollbars >= SCROLLBARS_BOTH) && (scrollbars <= SCROLLBARS_NONE)) {
  186. this.scrollbarVisibility = scrollbars;
  187. } else {
  188. this.scrollbarVisibility = SCROLLBARS_BOTH;
  189. }
  190. }
  191. /**
  192. * Construct a name for this component. Called by getName() when the
  193. * name is null.
  194. */
  195. String constructComponentName() {
  196. synchronized (getClass()) {
  197. return base + nameCounter++;
  198. }
  199. }
  200. /**
  201. * Creates the TextArea's peer. The peer allows us to modify
  202. * the appearance of the TextArea without changing any of its
  203. * functionality.
  204. */
  205. public void addNotify() {
  206. synchronized (getTreeLock()) {
  207. if (peer == null)
  208. peer = getToolkit().createTextArea(this);
  209. super.addNotify();
  210. }
  211. }
  212. /**
  213. * Inserts the specified text at the specified position
  214. * in this text area.
  215. * @param str the text to insert.
  216. * @param pos the position at which to insert.
  217. * @see java.awt.TextComponent#setText
  218. * @see java.awt.TextArea#replaceRange
  219. * @see java.awt.TextArea#append
  220. * @since JDK1.1
  221. */
  222. public void insert(String str, int pos) {
  223. insertText(str, pos);
  224. }
  225. /**
  226. * @deprecated As of JDK version 1.1,
  227. * replaced by <code>insert(String, int)</code>.
  228. */
  229. public synchronized void insertText(String str, int pos) {
  230. TextAreaPeer peer = (TextAreaPeer)this.peer;
  231. if (peer != null) {
  232. peer.insertText(str, pos);
  233. } else {
  234. text = text.substring(0, pos) + str + text.substring(pos);
  235. }
  236. }
  237. /**
  238. * Appends the given text to the text area's current text.
  239. * @param str the text to append.
  240. * @see java.awt.TextArea#insert
  241. */
  242. public void append(String str) {
  243. appendText(str);
  244. }
  245. /**
  246. * @deprecated As of JDK version 1.1,
  247. * replaced by <code>append(String)</code>.
  248. */
  249. public synchronized void appendText(String str) {
  250. if (peer != null) {
  251. insertText(str, getText().length());
  252. } else {
  253. text = text + str;
  254. }
  255. }
  256. /**
  257. * Replaces text between the indicated start and end positions
  258. * with the specified replacement text.
  259. * @param str the text to use as the replacement.
  260. * @param start the start position.
  261. * @param end the end position.
  262. * @see java.awt.TextArea#insert
  263. * @since JDK1.1
  264. */
  265. public void replaceRange(String str, int start, int end) {
  266. replaceText(str, start, end);
  267. }
  268. /**
  269. * @deprecated As of JDK version 1.1,
  270. * replaced by <code>replaceRange(String, int, int)</code>.
  271. */
  272. public synchronized void replaceText(String str, int start, int end) {
  273. TextAreaPeer peer = (TextAreaPeer)this.peer;
  274. if (peer != null) {
  275. peer.replaceText(str, start, end);
  276. } else {
  277. text = text.substring(0, start) + str + text.substring(end);
  278. }
  279. }
  280. /**
  281. * Gets the number of rows in the text area.
  282. * @return the number of rows in the text area.
  283. * @see java.awt.TextArea#setRows
  284. * @see java.awt.TextArea#getColumns
  285. * @since JDK1
  286. */
  287. public int getRows() {
  288. return rows;
  289. }
  290. /**
  291. * Sets the number of rows for this text area.
  292. * @param rows the number of rows.
  293. * @see java.awt.TextArea#getRows
  294. * @see java.awt.TextArea#setColumns
  295. * @exception IllegalArgumentException if the value
  296. * supplied for <code>rows</code>
  297. * is less than <code>0</code>.
  298. * @since JDK1.1
  299. */
  300. public void setRows(int rows) {
  301. int oldVal = this.rows;
  302. if (rows < 0) {
  303. throw new IllegalArgumentException("rows less than zero.");
  304. }
  305. if (rows != oldVal) {
  306. this.rows = rows;
  307. invalidate();
  308. }
  309. }
  310. /**
  311. * Gets the number of columns in this text area.
  312. * @return the number of columns in the text area.
  313. * @see java.awt.TextArea#setColumns
  314. * @see java.awt.TextArea#getRows
  315. */
  316. public int getColumns() {
  317. return columns;
  318. }
  319. /**
  320. * Sets the number of columns for this text area.
  321. * @param columns the number of columns.
  322. * @see java.awt.TextArea#getColumns
  323. * @see java.awt.TextArea#setRows
  324. * @exception IllegalArgumentException if the value
  325. * supplied for <code>columns</code>
  326. * is less than <code>0</code>.
  327. * @since JDK1.1
  328. */
  329. public void setColumns(int columns) {
  330. int oldVal = this.columns;
  331. if (columns < 0) {
  332. throw new IllegalArgumentException("columns less than zero.");
  333. }
  334. if (columns != oldVal) {
  335. this.columns = columns;
  336. invalidate();
  337. }
  338. }
  339. /**
  340. * Gets an enumerated value that indicates which scroll bars
  341. * the text area uses.
  342. * <p>
  343. * The <code>TextArea</code> class defines four integer constants
  344. * that are used to specify which scroll bars are available.
  345. * <code>TextArea</code> has one constructor that gives the
  346. * application discretion over scroll bars.
  347. * @return an integer that indicates which scroll bars are used.
  348. * @see java.awt.TextArea#SCROLLBARS_BOTH
  349. * @see java.awt.TextArea#SCROLLBARS_VERTICAL_ONLY
  350. * @see java.awt.TextArea#SCROLLBARS_HORIZONTAL_ONLY
  351. * @see java.awt.TextArea#SCROLLBARS_NONE
  352. * @see java.awt.TextArea#TextArea(java.lang.String, int, int, int)
  353. * @since JDK1.1
  354. */
  355. public int getScrollbarVisibility() {
  356. return scrollbarVisibility;
  357. }
  358. /**
  359. * Determines the preferred size of a text area with the specified
  360. * number of rows and columns.
  361. * @param rows the number of rows.
  362. * @param cols the number of columns.
  363. * @return the preferred dimensions required to display
  364. * the text area with the specified
  365. * number of rows and columns.
  366. * @see java.awt.Component#getPreferredSize
  367. * @since JDK1.1
  368. */
  369. public Dimension getPreferredSize(int rows, int columns) {
  370. return preferredSize(rows, columns);
  371. }
  372. /**
  373. * @deprecated As of JDK version 1.1,
  374. * replaced by <code>getPreferredSize(int, int)</code>.
  375. */
  376. public Dimension preferredSize(int rows, int columns) {
  377. synchronized (getTreeLock()) {
  378. TextAreaPeer peer = (TextAreaPeer)this.peer;
  379. return (peer != null) ?
  380. peer.preferredSize(rows, columns) :
  381. super.preferredSize();
  382. }
  383. }
  384. /**
  385. * Determines the preferred size of this text area.
  386. * @return the preferred dimensions needed for this text area.
  387. * @see java.awt.Component#getPreferredSize
  388. * @since JDK1.1
  389. */
  390. public Dimension getPreferredSize() {
  391. return preferredSize();
  392. }
  393. /**
  394. * @deprecated As of JDK version 1.1,
  395. * replaced by <code>getPreferredSize()</code>.
  396. */
  397. public Dimension preferredSize() {
  398. synchronized (getTreeLock()) {
  399. return ((rows > 0) && (columns > 0)) ?
  400. preferredSize(rows, columns) :
  401. super.preferredSize();
  402. }
  403. }
  404. /**
  405. * Determines the minimum size of a text area with the specified
  406. * number of rows and columns.
  407. * @param rows the number of rows.
  408. * @param cols the number of columns.
  409. * @return the minimum dimensions required to display
  410. * the text area with the specified
  411. * number of rows and columns.
  412. * @see java.awt.Component#getMinimumSize
  413. * @since JDK1.1
  414. */
  415. public Dimension getMinimumSize(int rows, int columns) {
  416. return minimumSize(rows, columns);
  417. }
  418. /**
  419. * @deprecated As of JDK version 1.1,
  420. * replaced by <code>getMinimumSize(int, int)</code>.
  421. */
  422. public Dimension minimumSize(int rows, int columns) {
  423. synchronized (getTreeLock()) {
  424. TextAreaPeer peer = (TextAreaPeer)this.peer;
  425. return (peer != null) ?
  426. peer.minimumSize(rows, columns) :
  427. super.minimumSize();
  428. }
  429. }
  430. /**
  431. * Determines the minimum size of this text area.
  432. * @return the preferred dimensions needed for this text area.
  433. * @see java.awt.Component#getPreferredSize
  434. * @since JDK1.1
  435. */
  436. public Dimension getMinimumSize() {
  437. return minimumSize();
  438. }
  439. /**
  440. * @deprecated As of JDK version 1.1,
  441. * replaced by <code>getMinimumSize()</code>.
  442. */
  443. public Dimension minimumSize() {
  444. synchronized (getTreeLock()) {
  445. return ((rows > 0) && (columns > 0)) ?
  446. minimumSize(rows, columns) :
  447. super.minimumSize();
  448. }
  449. }
  450. /**
  451. * Returns the parameter string representing the state of
  452. * this text area. This string is useful for debugging.
  453. * @return the parameter string of this text area.
  454. */
  455. protected String paramString() {
  456. String sbVisStr;
  457. switch (scrollbarVisibility) {
  458. case SCROLLBARS_BOTH:
  459. sbVisStr = "both";
  460. break;
  461. case SCROLLBARS_VERTICAL_ONLY:
  462. sbVisStr = "vertical-only";
  463. break;
  464. case SCROLLBARS_HORIZONTAL_ONLY:
  465. sbVisStr = "horizontal-only";
  466. break;
  467. case SCROLLBARS_NONE:
  468. sbVisStr = "none";
  469. break;
  470. default:
  471. sbVisStr = "invalid display policy";
  472. }
  473. return super.paramString() + ",rows=" + rows +
  474. ",columns=" + columns +
  475. ", scrollbarVisibility=" + sbVisStr;
  476. }
  477. /*
  478. * Serialization support.
  479. */
  480. /**
  481. * The textArea Serialized Data Version.
  482. *
  483. * @serial
  484. */
  485. private int textAreaSerializedDataVersion = 1;
  486. /**
  487. * Read the ObjectInputStream.
  488. */
  489. private void readObject(ObjectInputStream s)
  490. throws ClassNotFoundException, IOException
  491. {
  492. s.defaultReadObject();
  493. // Make sure the state we just read in for columns, rows,
  494. // and scrollbarVisibility has legal values
  495. if (columns < 0) {
  496. columns = 0;
  497. }
  498. if (rows < 0) {
  499. rows = 0;
  500. }
  501. if ((scrollbarVisibility < SCROLLBARS_BOTH) ||
  502. (scrollbarVisibility > SCROLLBARS_NONE)) {
  503. this.scrollbarVisibility = SCROLLBARS_BOTH;
  504. }
  505. }
  506. /////////////////
  507. // Accessibility support
  508. ////////////////
  509. /**
  510. * Gets the AccessibleContext associated with this TextArea.
  511. * For text areas, the AccessibleContext takes the form of an
  512. * AccessibleAWTTextArea.
  513. * A new AccessibleAWTTextArea instance is created if necessary.
  514. *
  515. * @return an AccessibleAWTTextArea that serves as the
  516. * AccessibleContext of this TextArea
  517. */
  518. public AccessibleContext getAccessibleContext() {
  519. if (accessibleContext == null) {
  520. accessibleContext = new AccessibleAWTTextArea();
  521. }
  522. return accessibleContext;
  523. }
  524. /**
  525. * This class implements accessibility support for the
  526. * <code>TextArea</code> class. It provides an implementation of the
  527. * Java Accessibility API appropriate to text area user-interface elements.
  528. */
  529. protected class AccessibleAWTTextArea extends AccessibleAWTTextComponent {
  530. /**
  531. * Gets the state set of this object.
  532. *
  533. * @return an instance of AccessibleStateSet describing the states
  534. * of the object
  535. * @see AccessibleStateSet
  536. */
  537. public AccessibleStateSet getAccessibleStateSet() {
  538. AccessibleStateSet states = super.getAccessibleStateSet();
  539. states.add(AccessibleState.MULTI_LINE);
  540. return states;
  541. }
  542. }
  543. }