Documentation

The Java™ Tutorials
Hide TOC
Text Component FeaturesText组件特征
Trail: Creating a GUI With Swing
Lesson: Using Swing Components
Section: Using Text Components

Text Component Features文本组件特征

The JTextComponent class is the foundation for Swing text components. JTextComponent类是Swing文本组件的基础。This class provides the following customizable features for all of its descendants:此类为其所有子类提供了以下可自定义功能:

See the example called TextComponentDemo to explore these capabilities. 请参阅名为TextComponentDemo的示例来探索这些功能。Although the TextComponentDemo example contains a customized instance of JTextPane, the capabilities discussed in this section are inherited by all JTextComponent subclasses.尽管TextComponentDemo示例包含JTextPane的自定义实例,但本节中讨论的功能由所有JTextComponent子类继承。

A snapshot of TextComponentDemo, which contains a customized text pane and a standard text area

The upper text component is the customized text pane. 上部文本组件是自定义文本窗格。The lower text component is an instance of JTextArea, which serves as a log that reports all changes made to the contents of the text pane. 下部文本组件是JTextArea的一个实例,它用作报告对文本窗格内容所做的所有更改的日志。The status line at the bottom of the window reports either the location of the selection or the position of the caret, depending on whether text is selected.窗口底部的状态行报告选择的位置或插入符号的位置,具体取决于是否选择了文本。


Try this: 
  1. Click the Launch button to run TextComponentDemo using Java™ Web Start (download JDK 7 or later). 单击启动按钮,使用Java™Web启动运行TextComponentDemo(下载JDK 7或更高版本)。Alternatively, to compile and run the example yourself, consult the example index.或者,要自己编译和运行示例,请参考示例索引Launches the TextComponentDemo Application
  2. Use the mouse to select text and place the cursor in the text pane. 使用鼠标选择文本并将光标放在文本窗格中。Information about the selection and cursor is displayed at the bottom of the window.有关选择和光标的信息显示在窗口底部。
  3. Enter text by typing on the keyboard. 在键盘上键入文本。You can move the caret around using the arrow keys on the keyboard or the four emacs key bindings: Ctrl-B (backward one character), Ctrl-F (forward one character), Ctrl-N (down one line), and Ctrl-P (up one line).您可以使用键盘上的箭头键或四个emacs键绑定来移动插入符号:Ctrl-B(向后一个字符)、Ctrl-F(向前一个字符),Ctrl-N(向下一行)和Ctrl-P(向上一行)。
  4. Open the Edit menu, and use its menu items to edit text in the text pane. 打开“编辑”菜单,并使用其菜单项编辑文本窗格中的文本。Make a selection in the text area at the bottom of the window. 在窗口底部的文本区域中进行选择。Because the text area is not editable, only some of the Edit menu's commands, like copy-to-clipboard, work. 由于文本区域不可编辑,因此只有“编辑”菜单的一些命令(如“复制到剪贴板”)有效。It is important to note though, that the menu operates on both text components.但需要注意的是,菜单在两个文本组件上都可以操作。
  5. Use the items in the Style menu to apply different styles to the text in the text pane.使用“样式”菜单中的项目将不同样式应用于文本窗格中的文本。

Using the TextComponentDemo example as a reference point, this section covers the following topics:使用TextComponentDemo示例作为参考点,本节涵盖以下主题:

Associating Text Actions With Menus and Buttons将文本操作与菜单和按钮关联

All Swing text components support standard editing commands such as cut, copy, paste, and insert characters. 所有Swing文本组件都支持标准编辑命令,如剪切、复制、粘贴和插入字符。Each editing command is represented and implemented by an Action object. 每个编辑命令由Action对象表示和实现。(To learn more about actions see How to Use Actions.) (要了解有关操作的更多信息,请参阅如何使用操作。)Actions allow you to associate a command with a GUI component, such as a menu item or button, and therefore build a GUI around a text component.操作允许您将命令与GUI组件(如菜单项或按钮)相关联,从而围绕文本组件构建GUI。

You can invoke the getActions method on any text component to receive an array containing all actions supported by this component. 您可以在任何文本组件上调用getActions方法,以接收包含该组件支持的所有操作的数组。It is also possible to load the array of actions into a HashMap so your program can retrieve an action by name. 还可以将动作数组加载到HashMap中,以便程序可以按名称检索动作。Here is the code from the TextComponentDemo example that takes the actions from the text pane and loads them into a HashMap.下面是TextComponentDemo示例中的代码,它从文本窗格中获取操作并将其加载到HashMap中。

private HashMap<Object, Action> createActionTable(JTextComponent textComponent) {
        HashMap<Object, Action> actions = new HashMap<Object, Action>();
        Action[] actionsArray = textComponent.getActions();
        for (int i = 0; i < actionsArray.length; i++) {
            Action a = actionsArray[i];
            actions.put(a.getValue(Action.NAME), a);
        }
        return actions;
    }

Here is the method for retrieving an action by its name from the hash map:下面是从哈希映射中按名称检索操作的方法:

private Action getActionByName(String name) {
    return actions.get(name);
}

You can use both methods verbatim in your programs.您可以在程序中逐字使用这两种方法。

The following code shows how the cut menu item is created and associated with the action of removing text from the text component.下面的代码显示了如何创建剪切菜单项,并将其与从文本组件中删除文本的操作相关联。

protected JMenu createEditMenu() {
    JMenu menu = new JMenu("Edit");
    ...
    menu.add(getActionByName(DefaultEditorKit.cutAction));
    ...

This code gets the action by name using the handy method shown previously. 此代码使用前面显示的方便方法按名称获取操作。It then adds the action to the menu. 然后将动作添加到菜单中。That is all you need to do. The menu and the action take care of everything else. 这就是你需要做的一切。菜单和动作会处理其他一切。Note that the name of the action comes from DefaultEditorKit. 请注意,操作的名称来自DefaultEditorKitThis kit provides actions for basic text editing and is the superclass for all the editor kits provided by Swing. 该工具包提供基本文本编辑操作,是Swing提供的所有编辑器工具包的超类。So its capabilities are available to all text components unless they are overridden by a customization.因此,它的功能可用于所有文本组件,除非它们被自定义覆盖。

For efficiency, text components share actions. 为了提高效率,文本组件共享操作。The Action object returned by getActionByName(DefaultEditorKit.cutAction) is shared by the uneditable JTextArea at the bottom of the window. getActionByName(DefaultEditorKit.cutAction)返回的Action对象由窗口底部的不可编辑的JTextArea共享。This sharing characteristic has two important ramifications:这种共享特性有两个重要的分支:

Here is the code that creates the Style menu and puts the Bold menu item in it:下面是创建样式菜单并将粗体菜单项放入其中的代码:

protected JMenu createStyleMenu() {
    JMenu menu = new JMenu("Style");
 
    Action action = new StyledEditorKit.BoldAction();
    action.putValue(Action.NAME, "Bold");
    menu.add(action);
    ...

The StyledEditorKit provides Action subclasses to implement editing commands for styled text. StyledEditorKit提供了Action子类来实现样式文本的编辑命令。You will note that instead of getting the action from the editor kit, this code creates an instance of the BoldAction class. 您将注意到,这段代码不是从编辑器工具包中获取动作,而是创建了BoldAction类的实例。Thus, this action is not shared with any other text component, and changing its name will not affect any other text component.因此,此操作不会与任何其他文本组件共享,更改其名称不会影响任何其他文本部件。

Associating Text Actions With Key Strokes将文本动作与按键笔划关联

In addition to associating an action with a GUI component, you can also associate an action with a key stroke by using a text component's input map. 除了将动作与GUI组件相关联外,还可以通过使用文本组件的输入映射将动作与按键笔划相关联。Input maps are described in How to Use Key Bindings.如何使用键绑定中描述了输入映射。

The text pane in the TextComponentDemo example supports four key bindings not provided by default.TextComponentDemo示例中的文本窗格支持默认情况下未提供的四个键绑定。

The following code adds the Ctrl-B key binding to the text pane. 下面的代码将Ctrl-B键绑定添加到文本窗格。The code for adding the other three bindings listed above is similar.添加上面列出的其他三个绑定的代码类似。

InputMap inputMap = textPane.getInputMap();

KeyStroke key = KeyStroke.getKeyStroke(KeyEvent.VK_B,
                                       Event.CTRL_MASK);
inputMap.put(key, DefaultEditorKit.backwardAction);

First, the code obtains the text component's input map. 首先,代码获得文本组件的输入映射。Next, it finds a KeyStroke object representing the Ctrl-B key sequence. 接下来,它找到一个表示Ctrl-B键序列的KeyStroke对象。Finally, the code binds the key stroke to the Action that moves the cursor backward.最后,代码将键划绑定到向后移动光标的Action

Implementing Undo and Redo实现撤销和重做

Implementing undo and redo has two parts:实现撤销和重做有两部分:

Part 1: Remembering Undoable Edits第1部分:记住可撤消编辑
To support undo and redo, a text component must remember each edit that occurs, the order of edits, and what is needed to undo each edit. 为了支持撤消和重做,文本组件必须记住发生的每个编辑、编辑顺序以及撤消每个编辑所需的内容。The example program uses an instance of the UndoManager class to manage its list of undoable edits. 示例程序使用UndoManager类的实例来管理其可撤消编辑列表。The undo manager is created where the member variables are declared:撤销管理器是在声明成员变量的位置创建的:

protected UndoManager undo = new UndoManager();

Now, let us look at how the program discovers undoable edits and adds them to the undo manager.现在,让我们看看程序如何发现可撤消的编辑并将其添加到撤消管理器。

A document notifies interested listeners whenever an undoable edit occurs on the document content. 每当文档内容发生可撤消的编辑时,文档都会通知感兴趣的侦听器。An important step in implementing undo and redo is to register an undoable edit listener on the document of the text component. 实现撤销和重做的一个重要步骤是在文本组件的文档上注册一个可撤销的编辑侦听器。The following code adds an instance of MyUndoableEditListener to the text pane's document:以下代码将MyUndoableEditListener的实例添加到文本窗格的文档中:

doc.addUndoableEditListener(new MyUndoableEditListener());

The undoable edit listener used in our example adds the edit to the undo manager's list:本例中使用的可撤消编辑侦听器将该编辑添加到撤消管理器的列表中:

protected class MyUndoableEditListener
          implements UndoableEditListener {
    public void undoableEditHappened(UndoableEditEvent e) {
        //Remember the edit and update the menus
        undo.addEdit(e.getEdit());
        undoAction.updateUndoState();
        redoAction.updateRedoState();
    }
}

Note that this method updates two objects: undoAction and redoAction. 请注意,此方法更新两个对象:undoActionredoActionThese are the action objects attached to the Undo and Redo menu items, respectively. 这些是分别附加到“撤消”和“重做”菜单项的操作对象。The next step shows you how to create the menu items and how to implement the two actions. 下一步将向您展示如何创建菜单项以及如何实现这两个操作。For general information about undoable edit listeners and undoable edit events, see How to Write an Undoable Edit Listener.有关可撤消编辑侦听器和可撤消编辑事件的常规信息,请参阅如何编写可撤消编辑监听器


Note: 

By default, each undoable edit undoes a single character entry. 默认情况下,每个可撤消编辑都会撤消单个字符条目。It is possible with some effort to group edits so that a series of key strokes is combined into one undoable edit. 可以对编辑进行分组,以便将一系列按键组合成一个可撤消的编辑。Grouping edits in this manner would require you to define a class that intercepts undoable edit events from the document, combining them if appropriate and forwarding the results to your undoable edit listener.以这种方式对编辑进行分组将需要您定义一个类,该类从文档中截取可撤消的编辑事件,并在适当的情况下将它们组合起来,然后将结果转发给可撤消编辑侦听器。


Part 2: Implementing the Undo and Redo Commands第2部分:实现撤销和重做命令
The first step in implementing undo and redo is to create the actions to put in the Edit menu.实现撤消和重做的第一步是创建要放在编辑菜单中的操作。

JMenu menu = new JMenu("Edit");

//Undo and redo are actions of our own creation
undoAction = new UndoAction();
menu.add(undoAction);

redoAction = new RedoAction();
menu.add(redoAction);
...

The undo and redo actions are implemented by custom AbstractAction subclasses: UndoAction and RedoAction, respectively. 撤消和重做操作分别由自定义AbstractAction子类UndoActionRedoAction实现。These classes are inner classes of the example's primary class.这些类是示例主类的内部类。

When the user invokes the undo command, the actionPerformed method of the UndoAction class is called:当用户调用undo命令时,将调用UndoAction类的actionPerformed方法:

public void actionPerformed(ActionEvent e) {
    try {
        undo.undo();
    } catch (CannotUndoException ex) {
        System.out.println("Unable to undo: " + ex);
        ex.printStackTrace();
    }
    updateUndoState();
    redoAction.updateRedoState();
}

This method calls the undo manager's undo method and updates the menu items to reflect the new undo/redo state.此方法调用undo管理器的撤消方法,并更新菜单项以反映新的撤消/重做状态。

Similarly, when the user invokes the redo command, the actionPerformed method of the RedoAction class is called:类似地,当用户调用redo命令时,将调用RedoAction类的actionPerformed方法:

public void actionPerformed(ActionEvent e) {
    try {
        undo.redo();
    } catch (CannotRedoException ex) {
        System.out.println("Unable to redo: " + ex);
        ex.printStackTrace();
    }
    updateRedoState();
    undoAction.updateUndoState();
}

This method is similar to undo, except that it calls the undo manager's redo method.此方法类似于撤销,只是它调用撤销管理器的redo方法。

Much of the code in the UndoAction and RedoAction classes is dedicated to enabling and disabling the actions as appropriate of the current state, and changing the names of the menu items to reflect the edit to be undone or redone.UndoActionRedoAction类中的大部分代码用于根据当前状态启用和禁用操作,并更改菜单项的名称以反映要撤消或重做的编辑。


Note: 

The implementation of undo and redo in the TextComponentDemo example was taken from the NotePad demo that comes with the JDK software. TextComponentDemo示例中撤销和重做的实现取自JDK软件附带的NotePad演示。Many programmers will also be able to copy this implementation of undo/redo without modification.许多程序员也将能够复制撤销/重做的这种实现,而无需修改。


Concepts: About Documents概念:关于文档

Like other Swing components, a text component separates its data (known as the model) from its view of the data. 与其他Swing组件一样,文本组件将其数据(称为模型)与其数据视图分离。If you are not yet familiar with the model-view split used by Swing components, refer to Using Models.如果您还不熟悉Swing组件使用的模型视图拆分,请参阅使用模型

A text component's model is known as a document and is an instance of a class that implements the Document interface. 文本组件的模型称为文档,是实现Document接口的类的实例。A document provides the following services for a text component:文档为文本组件提供以下服务:

The Swing text package contains a subinterface of Document, StyledDocument, that adds support for marking up the text with styles. Swing文本包包含一个名为StyledDocument的文档子接口,它增加了对使用样式标记文本的支持。One JTextComponent subclass, JTextPane, requires that its document be a StyledDocument rather than merely a Document.JTextComponent的一个子类JTextPane要求其文档是StyledDocument,而不仅仅是Document

The javax.swing.text package provides the following hierarchy of document classes, which implement specialized documents for the various JTextComponent subclasses:javax.swing.text包提供了以下文档类的层次结构,这些类为各种JTextComponent子类实现了专门的文档:

The hierarchy of document classes that javax.swing.text provides.

A PlainDocument is the default document for text fields, password fields, and text areas. PlainDocument是文本字段、密码字段和文本区域的默认文档。PlainDocument provides a basic container for text where all the text is displayed in the same font. 提供文本的基本容器,其中所有文本都以相同字体显示。Even though an editor pane is a styled text component, it uses an instance of PlainDocument by default. 尽管编辑器窗格是一个样式化的文本组件,但默认情况下它使用一个PlainDocument实例。The default document for a standard JTextPane is an instance of DefaultStyledDocument — a container for styled text in no particular format. 标准JTextPane的默认文档是DefaultStyledDocument—没有特定格式的样式文本的容器。However, the document instance used by any particular editor pane or text pane depends on the type of content bound to it. 但是,任何特定编辑器窗格或文本窗格使用的文档实例取决于绑定到它的内容类型。If you use the setPage method to load text into an editor pane or text pane, the document instance used by the pane might change. 如果使用setPage方法将文本加载到编辑器窗格或文本窗格中,则窗格使用的文档实例可能会更改。Refer to How to Use Editor Panes and Text Panes for details.有关详细信息,请参阅如何使用编辑器窗格和文本窗格

Although you can set the document of a text component, it is usually easier to allow it to set automatically, and if necessary, use a document filter to change how the text component's data is set. 虽然可以设置文本组件的文档,但通常更容易自动设置,如果需要,可以使用文档筛选器更改文本组件的数据设置方式。You can implement certain customizations either by installing a document filter or by replacing a text component's document with one of your own. 您可以通过安装文档筛选器或用自己的文档替换文本组件的文档来实现某些自定义。For example, the text pane in the TextComponentDemo example has a document filter that limits the number of characters the text pane can contain.例如,TextComponentDemo示例中的文本窗格具有一个文档筛选器,该筛选器限制文本窗格可以包含的字符数。

Implementing a Document Filter实现文档筛选器

To implement a document filter, create a subclass of DocumentFilter and then attach it to a document using the setDocumentFilter method defined in the AbstractDocument class. 要实现文档筛选器,请创建DocumentFilter的子类,然后使用AbstractDocument类中定义的setDocumentFilter方法将其附加到文档。Although it is possible to have documents that do not descend from AbstractDocument, by default Swing text components use AbstractDocument subclasses for their documents.虽然可以有不从AbstractDocument派生的文档,但默认情况下,Swing文本组件使用AbstractDocument子类作为其文档。

The TextComponentDemo application has a document filter, DocumentSizeFilter, that limits the number of characters that the text pane can contain. TextComponentDemo应用程序有一个文档筛选器DocumentSizeFilter,用于限制文本窗格可以包含的字符数。Here is the code that creates the filter and attaches it to the text pane's document:下面是创建筛选器并将其附加到文本窗格文档的代码:

...//Where member variables are declared:
JTextPane textPane;
AbstractDocument doc;
static final int MAX_CHARACTERS = 300;
...
textPane = new JTextPane();
...
StyledDocument styledDoc = textPane.getStyledDocument();
if (styledDoc instanceof AbstractDocument) {
    doc = (AbstractDocument)styledDoc;
    doc.setDocumentFilter(new DocumentSizeFilter(MAX_CHARACTERS));
}

To limit the characters allowed in the document, DocumentSizeFilter overrides the DocumentFilter class's insertString method, which is called each time that text is inserted into the document. 为了限制文档中允许的字符,DocumentSizeFilter重写DocumentFilter类的insertString方法,每次将文本插入文档时都会调用该方法。It also overrides the replace method, which is most likely to be called when the user pastes in new text. 它还重写了replace方法,当用户粘贴新文本时最有可能调用该方法。In general, text insertion can result when the user types or pastes in new text, or when the setText method is called. 通常,当用户键入或粘贴新文本时,或者调用setText方法时,可能会导致文本插入。Here is the DocumentSizeFilter class's implementation of the insertString method:下面是DocumentSizeFilter类对insertString方法的实现:

public void insertString(FilterBypass fb, int offs,
                         String str, AttributeSet a)
    throws BadLocationException {

    if ((fb.getDocument().getLength() + str.length()) <= maxCharacters)
        super.insertString(fb, offs, str, a);
    else
        Toolkit.getDefaultToolkit().beep();
}

The code for replace is similar. replace的代码类似。The FilterBypass parameter to the methods defined by the DocumentFilter class is simply an object that enables the document to be updated in a thread-safe way.DocumentFilter类定义的方法的FilterBypass参数只是一个对象,它允许以线程安全的方式更新文档。

Because the preceding document filter is concerned with additions to the document's data, it only overrides the insertString and replace methods. 由于前面的文档筛选器涉及对文档数据的添加,因此它仅重写insertString方法和replace方法。Most document filters would override DocumentFilter's remove method as well.大多数文档筛选器也会覆盖DocumentFilterremove方法。

Listening for Changes on a Document侦听文档上的更改

You can register two different types of listeners on a document: document listeners and undoable edit listeners. 您可以在文档上注册两种不同类型的侦听器:文档侦听器和可撤消编辑侦听器。This subsection describes document listeners. 本小节描述文档侦听器。For information about undoable edit listeners, refer to Implementing Undo and Redo.有关可撤消编辑侦听器的信息,请参阅实现撤消和重做

A document notifies registered document listeners of changes to the document. 文档将文档的更改通知已注册的文档侦听器。Use a document listener to create a reaction when text is inserted or removed from a document, or when the text style changes.在文档中插入或删除文本时,或在文本样式更改时,使用文档侦听器创建反应。

The TextComponentDemo program uses a document listener to update the change log whenever a change is made to the text pane. TextComponentDemo程序使用文档监听器在对文本窗格进行更改时更新更改日志。The following line of code registers an instance of the MyDocumentListener class as a listener on the text pane's document:以下代码行将MyDocumentListener类的实例注册为文本窗格文档上的侦听器:

doc.addDocumentListener(new MyDocumentListener());

Here is the implementation of the MyDocumentListener class:下面是MyDocumentListener类的实现:

protected class MyDocumentListener implements DocumentListener {
    public void insertUpdate(DocumentEvent e) {
        displayEditInfo(e);
    }
    public void removeUpdate(DocumentEvent e) {
        displayEditInfo(e);
    }
    public void changedUpdate(DocumentEvent e) {
        displayEditInfo(e);
    }
    private void displayEditInfo(DocumentEvent e) {
            Document document = (Document)e.getDocument();
            int changeLength = e.getLength();
            changeLog.append(e.getType().toString() + ": "
                + changeLength + " character"
                + ((changeLength == 1) ? ". " : "s. ")
                + " Text length = " + document.getLength()
                + "." + newline);
    }
}

The listener implements three methods for handling three different types of document events: insertion, removal, and style changes. 监听器实现了三种方法来处理三种不同类型的文档事件:插入、删除和样式更改。StyledDocument instances can fire all three types of events. 实例可以触发所有三种类型的事件。PlainDocument instances fire events only for insertion and removal. 实例仅为插入和删除触发事件。For general information about document listeners and document events, see How to Write a Document Listener.有关文档侦听器和文档事件的一般信息,请参阅如何编写文档侦听器

Remember that the document filter for this text pane limits the number of characters allowed in the document. 请记住,此文本窗格的文档筛选器限制了文档中允许的字符数。If you try to add more text than the document filter allows, the document filter blocks the change and the listener's insertUpdate method is not called. 如果尝试添加超出文档筛选器允许的文本,文档筛选器将阻止更改,并且不会调用侦听器的insertUpdate方法。Document listeners are notified of changes only if the change has already occurred.只有在更改已经发生时,才会通知文档侦听器更改。

You may want to change the document's text within a document listener. 您可能希望在文档侦听器中更改文档的文本。However, you should never modify the contents of a text component from within a document listener.但是,您不应该从文档侦听器中修改文本组件的内容。 If you do, the program will likely deadlock. 如果这样做,程序可能会死锁。Instead, you can use a formatted text field or provide a document filter.相反,您可以使用格式化文本字段或提供文档筛选器。

Listening for Caret and Selection Changes侦听插入符号和选择更改

The TextComponentDemo program uses a caret listener to display the current position of the caret or, if text is selected, the extent of the selection.TextComponentDemo程序使用插入符号侦听器来显示插入符号的当前位置,如果选择了文本,则显示选择范围。

The caret listener class in this example is a JLabel subclass. 本例中的插入符号侦听器类是JLabel子类。Here is the code that creates the caret listener label and makes it a caret listener of the text pane:下面是创建插入符号侦听器标签并使其成为文本窗格的插入符号侦听程序的代码:

//Create the status area
CaretListenerLabel caretListenerLabel = new CaretListenerLabel(
                                                "Caret Status");
...
textPane.addCaretListener(caretListenerLabel);

A caret listener must implement one method, caretUpdate, which is called each time the caret moves or the selection changes. 插入符号侦听器必须实现一个方法caretUpdate,每次插入符号移动或选择更改时都会调用该方法。Here is the CaretListenerLabel implementation of caretUpdate:

public void caretUpdate(CaretEvent e) {
    //Get the location in the text
    int dot = e.getDot();
    int mark = e.getMark();
    if (dot == mark) {  // no selection
        try {
            Rectangle caretCoords = textPane.modelToView(dot);
            //Convert it to view coordinates
            setText("caret: text position: " + dot +
                    ", view location = [" +
                    caretCoords.x + ", " + caretCoords.y + "]" +
                    newline);
        } catch (BadLocationException ble) {
            setText("caret: text position: " + dot + newline);
        }
     } else if (dot < mark) {
        setText("selection from: " + dot + " to " + mark + newline);
     } else {
        setText("selection from: " + mark + " to " + dot + newline);
     }
}

As you can see, this listener updates its text label to reflect the current state of the caret or selection. 如您所见,此侦听器更新其文本标签以反映插入符号或所选内容的当前状态。The listener gets the information to display from the caret event object. 侦听器从插入符号事件对象获取要显示的信息。For general information about caret listeners and caret events, see How to Write a Caret Listener.有关插入符号侦听器和插入符号事件的一般信息,请参阅如何编写插入符号侦听程序

As with document listeners, a caret listener is passive. 与文档侦听器一样,插入符号侦听器是被动的。It reacts to changes in the caret or in the selection, but does not change the caret or the selection itself. 它对插入符号或所选内容的更改作出反应,但不更改插入符号或选择内容本身。If you want to change the caret or selection, use a navigation filter or a custom caret.如果要更改插入符号或选择,请使用导航筛选器或自定义插入符号。

Implementing a navigation filter is similar to implementing a document filter. 实现导航筛选器类似于实现文档筛选器。First, write a subclass of NavigationFilter. 首先,编写NavigationFilter的子类。Then attach an instance of the subclass to a text component with the setNavigationFilter method.然后使用setNavigationFilter方法将子类的实例附加到文本组件。

You might create a custom caret to customize the appearance of a caret. 您可以创建自定义插入符号以自定义插入符号的外观。To create a custom caret, write a class that implements the Caret interface — perhaps by extending the DefaultCaret class. 要创建自定义插入符号,请编写一个实现Caret接口的类—也许通过扩展DefaultCaret类。Then provide an instance of your class as an argument to the setCaret method on a text component.然后提供类的实例作为文本组件上setCaret方法的参数。

Concepts: About Editor Kits概念:关于编辑器工具包

Text components use an EditorKit to tie the various pieces of the text component together. 文本组件使用EditorKit将文本组件的各个部分连接在一起。The editor kit provides the view factory, document, caret, and actions. 编辑器工具包提供了视图工厂、文档、插入符号和操作。An editor kit also reads and writes documents of a particular format. 编辑器套件还读取和写入特定格式的文档。Although all text components use editor kits, some components hide theirs. 虽然所有文本组件都使用编辑器工具包,但有些组件隐藏了它们的编辑器工具包。You cannot set or get the editor kit used by a text field or text area. 无法设置或获取文本字段或文本区域使用的编辑器套件。Editor panes and text panes provide the getEditorKit method to get the current editor kit and the setEditorKit method to change it.编辑器窗格和文本窗格提供getEditorKit方法来获取当前编辑器工具包,并提供setEditorIt方法来更改它。

For all components, the JTextComponent class provides the API for you to indirectly invoke or customize some editor kit capabilities. 对于所有组件,JTextComponent类提供了API,供您间接调用或自定义某些编辑器工具包功能。For example, JTextComponent provides the read and write methods, which invoke the editor kit's read and write methods. 例如,JTextComponent提供read方法和write方法,这些方法调用编辑器工具包的读写方法。JTextComponent also provides a method, getActions, which returns all of the actions supported by a component.还提供了一个方法getActions,该方法返回组件支持的所有操作。

The Swing text package provides the following editor kits:Swing文本包提供了以下编辑器工具包:

DefaultEditorKit
Reads and writes plain text, and provides a basic set of editing commands. 读取和写入纯文本,并提供一组基本的编辑命令。Details about how the text system treats newlines can be found in the DefaultEditorKit API documentation. 有关文本系统如何处理换行符的详细信息,请参阅DefaultEditorKit API文档。Briefly, the '\n' character is used internally, but the document or platform line separators are used when writing files. 简而言之,“\n”字符在内部使用,但在写入文件时使用文档或平台行分隔符。All the other editor kits are descendants of the DefaultEditorKit class.所有其他编辑器工具包都是DefaultEditorKit类的后代。
StyledEditorKit
Reads and writes styled text, and provides a minimal set of actions for styled text. 读取和写入样式化文本,并为样式化文本提供最小的操作集。This class is a subclass of DefaultEditorKit and is the editor kit used by JTextPane by default.该类是DefaultEditorKit的子类,默认情况下是JTextPane使用的编辑器工具包。
HTMLEditorKit
Reads, writes, and edits HTML. 读取、写入和编辑HTML。This is a subclass of StyledEditorKit.这是StyledEditorKit的一个子类。

Each of the editor kits listed above has been registered with the JEditorPane class and associated with the text format that the kit reads, writes, and edits. 上面列出的每个编辑器工具包都已在JEditorPane类中注册,并与工具包读取、写入和编辑的文本格式相关联。When a file is loaded into an editor pane, the pane checks the format of the file against its registered kits. 当文件加载到编辑器窗格中时,该窗格将根据其注册的工具包检查文件的格式。If a registered kit is found that supports that file format, the pane uses the kit to read the file, display, and edit it. 如果找到支持该文件格式的注册工具包,则窗格将使用该工具包读取、显示和编辑该文件。Thus, the editor pane effectively transforms itself into an editor for that text format. 因此,编辑器窗格有效地将自身转换为该文本格式的编辑器。You can extend JEditorPane to support your own text format by creating an editor kit for it, and then using JEditorPane's registerEditorKitForContentType to associate your kit with your text format.您可以扩展JEditorPane以支持自己的文本格式,方法是为其创建一个编辑器套件,然后使用JEditorPaneregisterEditorKitForContentType将套件与文本格式相关联。


Previous page: Using Text Components
Next page: The Text Component API