38 |
package javax.swing; |
package javax.swing; |
39 |
|
|
40 |
import java.awt.Dimension; |
import java.awt.Dimension; |
41 |
|
import javax.swing.text.BadLocationException; |
42 |
import javax.swing.text.Document; |
import javax.swing.text.Document; |
43 |
import javax.swing.text.JTextComponent; |
import javax.swing.text.JTextComponent; |
44 |
import javax.swing.text.PlainDocument; |
import javax.swing.text.PlainDocument; |
45 |
|
|
46 |
|
/** |
47 |
|
* The <code>JTextArea</code> component provides a multi-line area for displaying |
48 |
|
* and editing plain text. The component is designed to act as a lightweight |
49 |
|
* replacement for the heavyweight <code>java.awt.TextArea</code> component, |
50 |
|
* which provides similar functionality using native widgets. |
51 |
|
* <p> |
52 |
|
* |
53 |
|
* This component has additional functionality to the AWT class. It follows |
54 |
|
* the same design pattern as seen in other text components, such as |
55 |
|
* <code>JTextField</code>, <code>JTextPane</code> and <code>JEditorPane</code>, |
56 |
|
* and embodied in <code>JTextComponent</code>. These classes separate the text |
57 |
|
* (the model) from its appearance within the onscreen component (the view). The |
58 |
|
* text is held within a <code>javax.swing.text.Document</code> object, which can |
59 |
|
* also maintain relevant style information where necessary. As a result, it is the |
60 |
|
* document that should be monitored for textual changes, via |
61 |
|
* <code>DocumentEvent</code>s delivered to registered |
62 |
|
* <code>DocumentListener</code>s, rather than this component. |
63 |
|
* <p> |
64 |
|
* |
65 |
|
* Unlike <code>java.awt.TextArea</code>, <code>JTextArea</code> does not |
66 |
|
* handle scrolling. Instead, this functionality is delegated to a |
67 |
|
* <code>JScrollPane</code>, which can contain the text area and handle |
68 |
|
* scrolling when required. Likewise, the word wrapping functionality |
69 |
|
* of the AWT component is converted to a property of this component |
70 |
|
* and the <code>rows</code> and <code>columns</code> properties |
71 |
|
* are used in calculating the preferred size of the scroll pane's |
72 |
|
* view port. |
73 |
|
* |
74 |
|
* @author Michael Koch <konqueror@gmx.de> |
75 |
|
* @author Andrew John Hughes <gnu_andrew@member.fsf.org> |
76 |
|
* @see java.awt.TextArea |
77 |
|
* @see javax.swing.JTextComponent |
78 |
|
* @see javax.swing.JTextField |
79 |
|
* @see javax.swing.JTextPane |
80 |
|
* @see javax.swing.JEditorPane |
81 |
|
* @see javax.swing.text.Document |
82 |
|
* @see javax.swing.text.DocumentEvent |
83 |
|
* @see javax.swing.text.DocumentListener |
84 |
|
*/ |
85 |
|
|
86 |
public class JTextArea extends JTextComponent |
public class JTextArea extends JTextComponent |
87 |
{ |
{ |
88 |
|
/** |
89 |
|
* Compatible with Sun's JDK |
90 |
|
*/ |
91 |
private static final long serialVersionUID = -6141680179310439825L; |
private static final long serialVersionUID = -6141680179310439825L; |
92 |
|
|
93 |
|
/** |
94 |
|
* The number of rows used by the component. |
95 |
|
*/ |
96 |
private int rows; |
private int rows; |
97 |
|
|
98 |
|
/** |
99 |
|
* The number of columns used by the component. |
100 |
|
*/ |
101 |
private int columns; |
private int columns; |
102 |
|
|
103 |
|
/** |
104 |
|
* Whether line wrapping is enabled or not. |
105 |
|
*/ |
106 |
private boolean wrapping; |
private boolean wrapping; |
107 |
|
|
108 |
|
/** |
109 |
|
* The number of characters equal to a tab within the text. |
110 |
|
*/ |
111 |
private int tabSize = 8; |
private int tabSize = 8; |
112 |
|
|
113 |
/** |
/** |
184 |
} |
} |
185 |
|
|
186 |
/** |
/** |
187 |
* Appends some text. |
* Appends the supplied text to the current contents |
188 |
|
* of the document model. |
189 |
* |
* |
190 |
* @param toAppend the text to append |
* @param toAppend the text to append |
191 |
*/ |
*/ |
192 |
public void append(String toAppend) |
public void append(String toAppend) |
193 |
{ |
{ |
194 |
setText(getText() + toAppend); |
try |
195 |
|
{ |
196 |
|
getDocument().insertString(getText().length(), toAppend, null); |
197 |
|
} |
198 |
|
catch (BadLocationException exception) |
199 |
|
{ |
200 |
|
/* This shouldn't happen in theory -- but, if it does... */ |
201 |
|
throw new RuntimeException("Unexpected exception occurred.", exception); |
202 |
|
} |
203 |
} |
} |
204 |
|
|
205 |
/** |
/** |
212 |
return new PlainDocument(); |
return new PlainDocument(); |
213 |
} |
} |
214 |
|
|
215 |
|
/** |
216 |
|
* Returns true if the width of this component should be forced |
217 |
|
* to match the width of a surrounding view port. When line wrapping |
218 |
|
* is turned on, this method returns true. |
219 |
|
* |
220 |
|
* @return true if lines are wrapped. |
221 |
|
*/ |
222 |
public boolean getScrollableTracksViewportWidth() |
public boolean getScrollableTracksViewportWidth() |
223 |
{ |
{ |
224 |
return wrapping ? true : super.getScrollableTracksViewportWidth(); |
return wrapping ? true : super.getScrollableTracksViewportWidth(); |
285 |
} |
} |
286 |
|
|
287 |
/** |
/** |
288 |
* Checks whethet line wrapping is enabled. |
* Checks whether line wrapping is enabled. |
289 |
* |
* |
290 |
* @return true if line wrapping is enabled, false otherwise |
* @return true if line wrapping is enabled, false otherwise |
291 |
*/ |
*/ |
309 |
firePropertyChange("lineWrap", oldValue, wrapping); |
firePropertyChange("lineWrap", oldValue, wrapping); |
310 |
} |
} |
311 |
|
|
312 |
|
/** |
313 |
|
* Returns the number of characters used for a tab. |
314 |
|
* This defaults to 8. |
315 |
|
* |
316 |
|
* @return the current number of spaces used for a tab. |
317 |
|
*/ |
318 |
public int getTabSize() |
public int getTabSize() |
319 |
{ |
{ |
320 |
return tabSize; |
return tabSize; |
321 |
} |
} |
322 |
|
|
323 |
|
/** |
324 |
|
* Sets the number of characters used for a tab to the |
325 |
|
* supplied value. If a change to the tab size property |
326 |
|
* occurs (i.e. newSize != tabSize), a property change event |
327 |
|
* is fired. |
328 |
|
* |
329 |
|
* @param newSize The new number of characters to use for a tab. |
330 |
|
*/ |
331 |
public void setTabSize(int newSize) |
public void setTabSize(int newSize) |
332 |
{ |
{ |
333 |
if (tabSize == newSize) |
if (tabSize == newSize) |
337 |
tabSize = newSize; |
tabSize = newSize; |
338 |
firePropertyChange("tabSize", oldValue, tabSize); |
firePropertyChange("tabSize", oldValue, tabSize); |
339 |
} |
} |
340 |
|
|
341 |
|
/** |
342 |
|
* Inserts the supplied text at the specified position. Nothing |
343 |
|
* happens in the case that the model or the supplied string is null |
344 |
|
* or of zero length. |
345 |
|
* |
346 |
|
* @param string The string of text to insert. |
347 |
|
* @param position The position at which to insert the supplied text. |
348 |
|
* @throws IllegalArgumentException if the position is < 0 or greater |
349 |
|
* than the length of the current text. |
350 |
|
*/ |
351 |
|
public void insert(String string, int position) |
352 |
|
{ |
353 |
|
Document document; |
354 |
|
|
355 |
|
/* Retrieve the document model */ |
356 |
|
document = getDocument(); |
357 |
|
/* Check the model and string for validity */ |
358 |
|
if (document == null || string == null || string.length() == 0) |
359 |
|
{ |
360 |
|
return; /* Do nothing */ |
361 |
|
} |
362 |
|
/* Insert the text into the model */ |
363 |
|
try |
364 |
|
{ |
365 |
|
document.insertString(position, string, null); |
366 |
|
} |
367 |
|
catch (BadLocationException exception) |
368 |
|
{ |
369 |
|
throw new IllegalArgumentException("The supplied position, " + |
370 |
|
position + ", was invalid."); |
371 |
|
} |
372 |
|
} |
373 |
|
|
374 |
} |
} |