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