19.6 The JTextArea Class


The JTextArea class displays multiple lines of text in a single font and style. Its default behavior is not to wrap lines of text, but line-wrapping can be enabled on word or character boundaries. Figure 19-5 shows a JTextArea.

Figure 19-5. JTextArea
figs/swng2.1905.gif

Like all Swing JTextComponents (but unlike java.awt.TextArea), JTextArea lacks integrated scrollbars. Fortunately, it is easy to embed a JTextArea inside a JScrollPane for seamless scrolling. (JTextArea implements the Scrollable interface, so JScrollPane can be intelligent about scrolling it.)

JTextArea handles newlines in a cross-platform way. Line separators in text files can be newline (\n), carriage return (\r), or carriage return newline (\r\n), depending on the platform. Swing's text components remember which line separator was originally used, but always use a newline character to represent one in memory. So always use \n when working with the content of a text component. When writing the content back to disk (or to whatever destination you give the write( ) method), the text component translates newlines back to the remembered type. If there is no remembered type (because the content was created from scratch), newlines are translated to the value of the line.separator system property.

19.6.1 Properties

JTextArea defines properties shown in Table 19-6. AccessibleJTextArea is an inner class that extends JTextComponent.AccessibleJTextComponent.

Table 19-6. JTextArea properties

Property

Data type

get

is

set

Default value

accessibleContexto

AccessibleContext

·

   

AccessibleJTextArea

columns

int

·

 

·

0

fontb, o

Font

·

 

·

From superclass

lineCount

int

·

   

From document

lineWrapb

boolean

·

 

·

false

preferredScrollableViewportSizeo

Dimension

·

   

See comments below

preferredSizeb, o

Dimension

·

 

·

See comments below

rows

int

·

 

·

0

scrollableTracksViewportWidtho

boolean

·

   

See comments below

tabSizeb

int

·

 

·

8

UIClassIDo

String

·

   

"TextAreaUI"

wrapStyleWordb

boolean

·

 

·

false

bbound, ooverridden

See also properties from the javax.swing.text.JTextComponent class (Table 19-1).

The rows and columns properties specify the number of rows and columns to be displayed by the component. If they are nonzero, they determine the value of preferredScrollableViewportSize and the minimum dimensions for preferredSize, based on the size of font. For variable-width fonts, the width of each column is based on the width of the lowercase character m. The font property is listed here because setFont( ) has been overridden to revalidate the component, allowing it to resize based on the size of the new font.

By default, the preferredSize property makes the JTextArea just big enough to display all of the component's text, but not smaller in either dimension than the values defined in the rows and columns properties. The size of the text area changes dynamically as text is inserted or deleted. This is just what you want if you're using a JScrollPane, but it can be surprising under FlowLayout.[3] (The JTextArea resizes immediately on each keystroke without waiting for an external revalidation.)

[3] Or under any other layout manager that respects getPreferredSize( ).

lineCount provides access to the number of lines in the component's document. This has nothing to do with how much of the content is currently visible. What constitutes a "line" is document-dependent but is typically a sequence of characters that ends with a newline.

The lineWrap property indicates whether a line of text should wrap if it is too long for the allocated width of the component. If lineWrap is false, the ends of long lines are completely hidden from the user unless you're using a JScrollPane. The scrollableTracksViewportWidth property is true when line wrap is on, false otherwise.

The wrapStyleWord property determines where line wrapping occurs. If true, the component attempts to wrap only at word boundaries (see Figure 19-6). The default is false. (This property is ignored unless lineWrap is set to true.)

Figure 19-6. JTextArea with lineWrap and wrapStyleWord set to true
figs/swng2.1906.gif

The tabSize property specifies the number of columns that a tab character should expand to.

19.6.2 Events

JTextArea does not fire any new event types. It inherits event behavior from JTextComponent and fires property change events when the lineWrap, wrapStyleWord, or tabSize properties are changed.

19.6.3 Constructors

public JTextArea( )

Create a default text area.

public JTextArea(int rows, int columns)

Create a text area with the specified number of rows and columns.

public JTextArea(String text)

Create a text area displaying the specified text.

public JTextArea(String text, int rows, int columns)

Create a text area with the specified number of rows and columns displaying the given text.

public JTextArea(Document doc)

Create a text area that uses the specified Document.

public JTextArea(Document doc, String text, int rows, int columns)

Create a text area with the specified number of rows and columns that uses the specified Document. If text is null, the Document's current text is displayed. Otherwise, text replaces the Document's content and is displayed. All the other constructors invoke this one.

19.6.4 Text Manipulation Methods

The following convenience methods make it easy to modify the contents of the text area's document model:

public void append(String str)

Append the given text to the end of the document.

public void insert(String str, int pos)

Insert the specified text at the given position (offset from the beginning of the document). To insert text at the beginning of the document, use a position of 0.

public void replaceRange(String str, int start, int end)

Replace a section of the document beginning with the character at the start position and ending with the character at the end position with the given string. The string may be null, in which case a deletion is performed.

19.6.5 Line Transformation Methods

These methods can be used to find the character offset of a given line (see the distinction between line and row in Section 19.6.1) and vice-versa. Note that the first line of the document is line 0, the first character of the document is at offset 0, and that newlines count as characters in the document.

public int getLineStartOffset(int line) throws BadLocationException

Return the character offset (from the beginning of the document) that marks the beginning of the specified line number.

public int getLineEndOffset(int line) throws BadLocationException

Return the character offset (from the beginning of the document) that marks the end of the specified line number. This is actually the offset of the first character of the next line.

public int getLineOfOffset(int offset) throws BadLocationException

Return the line number that contains the given character offset (from the beginning of the document).

The following example shows how these three methods work:

// OffsetTest.java // import javax.swing.*; import javax.swing.text.*; public class OffsetTest {   public static void main(String[] args) {     JTextArea ta = new JTextArea( );     ta.setLineWrap(true);     ta.setWrapStyleWord(true);     JScrollPane scroll = new JScrollPane(ta);     // Add three lines of text to the JTextArea.     ta.append("The first line.\n");     ta.append("Line Two!\n");     ta.append("This is the 3rd line of this document.");     // Print some results.     try {       for (int n=0; n < ta.getLineCount( ); n+=1)         System.out.println("line " + n + " starts at " +             ta.getLineStartOffset(n) + ", ends at " + ta.getLineEndOffset(n));       System.out.println( );       int n = 0;       while (true) {         System.out.print("offset " + n + " is on ");         System.out.println("line " + ta.getLineOfOffset(n));         n += 13;       }     } catch (BadLocationException ex) { System.out.println(ex); }     // Layout     JFrame f = new JFrame( );     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     f.getContentPane( ).add(scroll, java.awt.BorderLayout.CENTER);     f.setSize(150, 150);     f.setVisible(true);   } }

When run, this little program produces the following output, along with the frame shown in Figure 19-7. Remember that newlines count as characters in the document.

line 0 starts at 0, ends at 16 line 1 starts at 16, ends at 26 line 2 starts at 26, ends at 65 offset 0 is on line 0 offset 13 is on line 0 offset 26 is on line 2 offset 39 is on line 2 offset 52 is on line 2 offset 65 is on javax.swing.text.BadLocationException: Can't translate offset to line
Figure 19-7. OffsetTest frame
figs/swng2.1907.gif

Notice that getLineEndOffset( ) returns an index of the character after the last character in the specified line. getLineOfOffset(65) throws a BadLocationException even though 65 is returned as the ending offset for line 2.

19.6.6 Understanding JTextArea Layout

Here are tips for laying out your JTextAreas:

Use a JScrollPane

Almost every JTextArea in a real-world application should be embedded in a JScrollPane. The exception might be a JTextArea set to be read-only via setEditable(false), in which it would be impossible for the user to enter text that is pushed past the JTextArea's allocated area. But even then, some of its content might be invisible to the user if the L&F installs a font larger than you expect. It's usually safe to use a JScrollPane because in most L&Fs, scrollbars don't show up unless they are needed. Installing a JScrollPane is as easy as replacing add(myTextArea) with add(new JScrollPane(myTextArea)) in your code. (JScrollPanes are described in Chapter 11.)

Give it size

The default size of a JTextArea is small, allowing only a handful of characters to be displayed. Typing some text into a small JTextArea causes scrollbars to appear, leaving even less space to display text. Or, if it's not in a JScrollPane, the JTextArea grows larger bit by bit as the user types. Neither of these is likely to be what you want, so be sure that your JTextArea is laid out with adequate size. There are three ways to do this. You can use a layout manager that ignores the preferredSize, such as GridLayout or (probably most popular) the center position of BorderLayout. You can specify nonzero values for rows and columns in the constructor (or by using setRows( ) and setColumns( )). Finally, you can specify an explicit size with setPreferredSize( ).



Java Swing
Graphic Java 2: Mastering the Jfc, By Geary, 3Rd Edition, Volume 2: Swing
ISBN: 0130796670
EAN: 2147483647
Year: 2001
Pages: 289
Authors: David Geary

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net