文档

Java™教程
隐藏目录
如何使用文本区域
教程:使用Swing创建GUI
课程:使用Swing组件
章节:如何使用各种组件

如何使用文本区域

JTextArea类提供了一个显示多行文本并允许用户编辑文本的组件。如果你只需要从用户获取一行输入,应该使用一个文本字段。如果你希望文本区域使用多种字体或其他样式显示其文本,应该使用编辑器窗格或文本窗格。如果显示的文本长度有限且用户永远不会编辑,可以使用一个标签

教程的许多示例使用不可编辑的文本区域来显示程序输出。这里有一个名为TextDemo的示例的图片,你可以使用文本字段(顶部)输入文本,然后将输入的文本追加到文本区域(下方)。

TextDemo的快照

点击“启动”按钮以使用Java™ Web Start运行TextDemo(下载JDK 7或更高版本)。或者,要自己编译和运行示例,请参考示例索引

启动TextDemo应用程序

你可以在TextDemo.java中找到此程序的完整代码。下面的代码创建并初始化了文本区域:

textArea = new JTextArea(5, 20);
JScrollPane scrollPane = new JScrollPane(textArea); 
textArea.setEditable(false);

JTextArea构造函数的两个参数分别是文本区域应该显示的行数和列数的提示。包含文本区域的滚动窗格在确定滚动窗格的大小时会考虑这些提示。

如果不创建滚动窗格,文本区域将不会自动滚动。前面代码片段中显示的JScrollPane构造函数设置了在滚动窗格中查看文本区域,并指定滚动窗格的滚动条在需要时可见。如果需要更多信息,请参阅如何使用滚动窗格

文本区域默认是可编辑的。代码setEditable(false)使文本区域不可编辑。它仍然可选择,用户可以从中复制数据,但用户无法直接更改文本区域的内容。

以下代码向文本区域添加文本。请注意,文本系统在内部使用'\n'字符表示换行;详细信息请参见DefaultEditorKit的API文档。

private final static String newline = "\n";
...
textArea.append(text + newline);

除非用户通过点击或拖动在文本区域中移动插入符(光标),否则文本区域会自动滚动以使追加的文本可见。您可以在调用append之后将插入符移动到文本区域的末尾,以强制文本区域滚动到底部:

textArea.setCaretPosition(textArea.getDocument().getLength());

自定义文本区域

您可以通过多种方式自定义文本区域。例如,尽管给定的文本区域只能以一种字体和颜色显示文本,但您可以设置它使用的字体和颜色。此自定义选项可在任何组件上执行。您还可以确定文本区域如何换行以及每个制表符的字符数。最后,您可以使用JTextArea类从JTextComponent类继承的方法来设置诸如插入符、拖动支持或颜色选择之类的属性。

以下代码取自TextSamplerDemo.java,演示了如何初始化一个可编辑的文本区域。该文本区域使用指定的斜体字体,并在单词之间换行。

JTextArea textArea = new JTextArea(
    "这是一个可编辑的JTextArea。" +
    "文本区域是一个“普通”文本组件," +
    "这意味着尽管它可以以任何字体显示文本," +
    "但所有文本都是相同字体的。"
);
textArea.setFont(new Font("Serif", Font.ITALIC, 16));
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);

默认情况下,文本区域不会自动换行显示过长的行。相反,它将一行用于所有换行字符之间的文本,并且如果文本区域位于滚动窗格中,则允许自身在水平方向上滚动。此示例通过调用setLineWrap方法打开换行,并调用setWrapStyleWord方法指示文本区域应在单词边界而不是字符边界处换行。

为了提供滚动功能,示例将文本区域放在滚动窗格中。

JScrollPane areaScrollPane = new JScrollPane(textArea);
areaScrollPane.setVerticalScrollBarPolicy(
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
areaScrollPane.setPreferredSize(new Dimension(250, 250));

你可能已经注意到在这个示例中使用的JTextArea构造函数没有指定行数或列数。相反,代码通过设置滚动窗格的首选大小来限制文本区域的大小。

另一个示例:TextAreaDemo

TextAreaDemo示例介绍了一个可编辑的文本区域,具有特殊功能-单词完成功能。当用户输入单词时,程序会根据已输入的内容来提示完整的单词,只要程序的词汇表中包含以已输入内容开头的单词。下面是TextAreaDemo应用程序的截图。

TextAreaDemo的快照

点击“启动”按钮以使用Java™ Web Start下载JDK 7或更高版本)运行TextAreaDemo。或者,要自己编译和运行示例,请参考示例索引

启动TextAreaDemo应用程序

你可以在TextAreaDemo.java中找到这个程序的完整代码。

这个示例为文本区域提供了默认的滚动条策略。默认情况下,只有当显示区域完全填满文本并没有空间附加新单词时,垂直滚动条才会出现。你可以使用以下代码提供这种类型的滚动窗格:

  textArea.setWrapStyleWord(true);
  jScrollPane1 = new JScrollPane(textArea);

如上所述,文本区域是可编辑的。你可以通过键入和粘贴文本,或者删除文本的某些部分或整个内容来操作文本区域。还可以尝试使用文本区域内的标准键绑定来编辑文本。

现在来探索单词完成功能是如何实现的。输入类似于“Swing”或“special”的单词。当你输入“sw”时,程序会显示一个可能的完成词“ing”,并用浅蓝色进行高亮显示。按Enter键接受完成词或继续输入。

下面的代码向文本区域的文档添加了一个文档监听器:

  textArea.getDocument().addDocumentListener(this);

当您开始输入一个单词时,insertUpdate方法会检查程序的词汇是否包含所输入的前缀。一旦找到前缀的补全项,就会调用invokeLater方法提交一个任务以稍后修改文档。重要的是要记住,您不能在文档事件通知中修改文档,否则会引发异常。请查看下面的代码。

String prefix = content.substring(w + 1).toLowerCase();
int n = Collections.binarySearch(words, prefix);
if (n < 0 && -n <= words.size()) {
    String match = words.get(-n - 1);
    if (match.startsWith(prefix)) {
        // 找到了补全项
        String completion = match.substring(pos - w);
        // 我们不能在通知中直接修改Document,
        // 所以我们提交一个稍后执行修改的任务
        SwingUtilities.invokeLater(
            new CompletionTask(completion, pos + 1));
    }
} else {
    // 未找到补全项
    mode = Mode.INSERT;
}

粗体显示的代码展示了如何创建选择。首先将插入符设置为完整单词的末尾,然后将其移动到最后一个字符输入之后的位置。moveCaretPosition方法不仅将插入符移动到新位置,还会选择两个位置之间的文本。补全任务的代码如下所示:

  private class CompletionTask implements Runnable {
        String completion;
        int position;
        
        CompletionTask(String completion, int position) {
            this.completion = completion;
            this.position = position;
        }
        
        public void run() {
            textArea.insert(completion, position);
            textArea.setCaretPosition(position + completion.length());
            textArea.moveCaretPosition(position);
            mode = Mode.COMPLETION;
        }
    }

文本区域 API

以下表格列出了常用的JTextArea构造函数和方法。您可能还会调用继承自其它祖先类的方法,例如setPreferredSizesetForegroundsetBackgroundsetFont等。请参阅JComponent 类中常用继承方法的表格。

使用文本区域的 API 包括以下几个类别:

设置或获取内容
方法或构造函数 目的
JTextArea()
JTextArea(String)
JTextArea(String, int, int)
JTextArea(int, int)
创建一个文本区域。当存在时,String 参数包含初始文本。int 参数分别指定所需的列宽和行高。
void setText(String)
String getText()
(在 JTextComponent 中定义)
设置或获取文本区域中显示的文本。
微调文本区域的外观
方法 目的
void setEditable(boolean)
boolean isEditable()
(定义在 JTextComponent 中)
设置或指示用户是否可以编辑文本区域中的文本。
void setColumns(int);
int getColumns()
设置或获取文本区域显示的列数。这只是用于计算区域的首选宽度的提示。
void setRows(int);
int getRows()
设置或获取文本区域显示的行数。这是用于计算区域的首选高度的提示。
int setTabSize(int) 设置一个制表符等于的字符数。
int setLineWrap(boolean) 设置是否将行包装到分配的宽度之内,如果行太长无法容纳。默认情况下,此属性为false,不会包装行。
int setWrapStyleWord(boolean) 设置是否可以在空格(单词边界)或任何字符处换行。默认情况下,此属性为false,行可以在任何字符处换行(如果打开了换行功能)。
实现文本区域功能
方法 目的
void selectAll()
(定义在JTextComponent中)
选择文本区域中的所有字符。
void append(String) 将指定的文本添加到文本区域的末尾。
void insert(String, int) 在指定位置插入指定的文本。
void replaceRange(String, int, int) 用指定的字符串替换指定位置之间的文本。
int getLineCount()
int getLineOfOffset(int)
int getLineStartOffset(int)
int getLineEndOffset(int)
用于查找行号或指定行的开始或结束位置的实用方法。

使用文本区域的示例

这个表格列出了使用文本区域的示例,并指向这些示例的描述位置。

示例 描述位置 备注
TextDemo 本节 一个将用户输入的文本追加到文本区域的应用程序。
TextAreaDemo 本节 一个带有单词自动完成功能的文本区域应用程序。
TextSamplerDemo 使用文本组件 使用每个Swing文本组件的示例。
HtmlDemo 在Swing组件中使用HTML 一个文本区域,允许用户输入HTML代码以在标签中显示。
BasicDnD DnD简介 演示了几个Swing组件的内置拖放功能,包括文本区域。
FocusConceptsDemo 使用焦点子系统 演示了焦点在几个包含文本区域的组件中的工作方式。

上一页: 如何使用表格
下一页: 如何使用文本字段