如何使用文本区域

原文: https://docs.oracle.com/javase/tutorial/uiswing/components/textarea.html

JTextArea 类提供显示多行文本的组件,并可选择允许用户编辑文本。如果您只需要从用户那里获得一行输入,则应使用文本字段。如果希望文本区域使用多种字体或其他样式显示其文本,则应使用编辑器窗格或文本窗格。如果显示的文本长度有限且用户从未编辑过,请使用标签

许多教程的示例使用不可编辑的文本区域来显示程序输出。下面是一个名为TextDemo的示例图片,它允许您使用文本字段(在顶部)键入文本,然后将键入的文本附加到文本区域(下面)。

A snapshot of TextDemo

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

Launches the TextDemo application

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

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

JTextArea构造器的两个参数分别是文本区域应显示的行数和列数的提示。在确定滚动窗格应该有多大时,包含文本区域的滚动窗格会注意这些提示。

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

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

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

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

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

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

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

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

  1. JTextArea textArea = new JTextArea(
  2. "This is an editable JTextArea. " +
  3. "A text area is a \"plain\" text component, " +
  4. "which means that although it can display text " +
  5. "in any font, all of the text is in the same font."
  6. );
  7. textArea.setFont(new Font("Serif", Font.ITALIC, 16));
  8. textArea.setLineWrap(true);
  9. textArea.setWrapStyleWord(true);

默认情况下,文本区域不会换行显示区域太长的行。相反,它对换行符之间的所有文本使用一行 - 如果文本区域在滚动窗格内 - 允许自己水平滚动。此示例通过调用setLineWrap方法打开换行,然后调用setWrapStyleWord方法指示文本区域应在字边界而不是字符边界处换行。

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

  1. JScrollPane areaScrollPane = new JScrollPane(textArea);
  2. areaScrollPane.setVerticalScrollBarPolicy(
  3. JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
  4. areaScrollPane.setPreferredSize(new Dimension(250, 250));

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

TextAreaDemo示例引入了一个具有特殊功能的可编辑文本区域 - 单词完成功能。当用户输入单词时,只要程序的词汇表包含以键入内容开头的单词,程序就会建议完成单词的提示。这是TextAreaDemo应用程序的图片。

A snapshot of TextAreaDemo

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

Launches the TextAreaDemo Application

您可以在 TextAreaDemo.java 中找到该程序的完整代码。

此示例使用默认滚动条策略为文本区域提供滚动容量。默认情况下,仅当显示区域完全填充文本且没有空间添加新单词时,才会显示垂直滚动条。您可以使用以下代码提供此类型的滚动窗格:

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

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

现在探讨如何实现单词完成功能。输入“Swing”或“special”之类的单词。只要输入“sw”,程序就会以浅蓝色突出显示可能的完成情况。按 Enter 键接受完成或继续键入。

以下代码将文档监听器添加到文本区域的文档中:

  1. textArea.getDocument().addDocumentListener(this);

当您开始键入单词时,insertUpdate方法会检查程序的词汇表是否包含键入的前缀。找到前缀的完成后,对invokeLater方法的调用将提交稍后更改文档的任务。请务必记住,您无法在文档事件通知中修改文档,否则您将获得异常。检查下面的代码。

  1. String prefix = content.substring(w + 1).toLowerCase();
  2. int n = Collections.binarySearch(words, prefix);
  3. if (n < 0 && -n <= words.size()) {
  4. String match = words.get(-n - 1);
  5. if (match.startsWith(prefix)) {
  6. // A completion is found
  7. String completion = match.substring(pos - w);
  8. // We cannot modify Document from within notification,
  9. // so we submit a task that does the change later
  10. SwingUtilities.invokeLater(
  11. new CompletionTask(completion, pos + 1));
  12. }
  13. } else {
  14. // Nothing found
  15. mode = Mode.INSERT;
  16. }

以粗体显示的代码说明了如何创建选择。插入符号首先设置为完整单词的结尾,然后移回到输入最后一个字符后的位置。 moveCaretPosition方法不仅将插入符移动到新位置,还选择两个位置之间的文本。使用以下代码实现完成任务:

  1. private class CompletionTask implements Runnable {
  2. String completion;
  3. int position;
  4. CompletionTask(String completion, int position) {
  5. this.completion = completion;
  6. this.position = position;
  7. }
  8. public void run() {
  9. textArea.insert(completion, position);
  10. textArea.setCaretPosition(position + completion.length());
  11. textArea.moveCaretPosition(position);
  12. mode = Mode.COMPLETION;
  13. }
  14. }

下表列出了常用的JTextArea构造器和方法。您可能调用的其他方法在JTextComponent中定义,并在文本组件 API 中列出。

您也可以在文本区域上调用它从其他祖先继承的方法,例如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 如何使用焦点子系统 使用包含文本区域的一些组件演示焦点的工作原理。