The JavaTM Tutorial
Previous Page Lesson Contents Next Page Start of Tutorial > Start of Trail > Start of Lesson Search

Trail: Creating a GUI with JFC/Swing
Lesson: Writing Event Listeners

How to Write a Document Listener

A Swing text component uses a Document(in the API reference documentation) to hold and edit its text. Document events occur when the content of a document changes in any way. You attach a document listener to a text component's document, rather than to the text component itself.

The following applet demonstrates document events on two plain text components.

Click this figure to run the applet.
This is a picture of the applet's GUI. To run the applet, click the picture. The applet will appear in a new browser window.


Try this: 
  1. Type in the text field at the upper left of the applet or the text area beneath the text field.
    One document event is fired for each character typed.
  2. Delete text with the backspace key.
    One document event is fired for each backspace key typed.
  3. Select text and then delete it by typing backspace or by using a keyboard command such as CTRL-X (cut).
    One document event is fired for the entire deletion.
  4. Copy text from one text component into the other using keyboard commands such as CTRL-C (copy) and CTRL-V (paste).
    One document event is fired for the entire paste operation regardless of the length of the text pasted. If text is selected in the target text component before the paste command is issued, an additional document event is fired because the selected text is deleted first.

You can find the applet's code in DocumentEventDemo.java. Here is the applet's document event handling code:

public class DocumentEventDemo ... {
    ...//where initialization occurs:
    textField = new JTextField(20);
    textField.addActionListener(new MyTextActionListener());
    textField.getDocument().addDocumentListener(new MyDocumentListener());
    textField.getDocument().putProperty("name", "Text Field");

    textArea = new JTextArea();
    textArea.getDocument().addDocumentListener(new MyDocumentListener());
    textArea.getDocument().putProperty("name", "Text Area");
    ...
}

class MyDocumentListener implements DocumentListener {
    String newline = System.getProperty("line.separator");
 
    public void insertUpdate(DocumentEvent e) {
        updateLog(e, "inserted into");
    }
    public void removeUpdate(DocumentEvent e) {
        updateLog(e, "removed from");
    }
    public void changedUpdate(DocumentEvent e) {
        //Plain text components don't fire these events
    }

    public void updateLog(DocumentEvent e, String action) {
        Document doc = (Document)e.getDocument();
        int changeLength = e.getLength();
        displayArea.append(
            changeLength + " character" +
            ((changeLength == 1) ? " " : "s ") +
            action + doc.getProperty("name") + "." + newline +
            "  Text length = " + doc.getLength() + newline);
    }
}
Document listeners shouldn't modify the contents of the document; The change is already complete by the time the listener is notified of the change. Instead, write a custom document that overrides the insertString or remove methods, or both. See Listening for Changes on a Document(in the Creating a User Interface trail) for details.

The Document Event API

The DocumentListener interface contains these three methods:
void changedUpdate(DocumentEvent)
Called when the style of some of the text in the listened-to document changes. This sort of event is fired only from a StyledDocument -- a PlainDocument does not fire these events.

void insertUpdate(DocumentEvent)
Called when text is inserted into the listened-to document.

void removeUpdate(DocumentEvent)
Called when text is removed from the listened-to document.
Each document event method has a single parameter: an instance of a class that implements the DocumentEvent(in the API reference documentation) interface. Typically, the object passed into this method will be an instance of DefaultDocumentEvent(in the API reference documentation) which is defined in AbstractDocument.

To get the document that fired the event, you can use DocumentEvent's getDocument method. Note that as an interface, DocumentEvent does not inherit from EventObject. Thus, it does not inherit the getSource method.

In addition to getDocument, the DocumentEvent interface requires these methods:

int getLength()
Returns the length of the change.
int getOffset()
Returns the location within the document of the first character changed.
ElementChange getChange(Element)
Returns details about what elements in the document have changed and how. ElementChange(in the API reference documentation) is an interface defined within the DocumentEvent interface.
EventType getType()
Returns the type of change that occurred. EventType(in the API reference documentation) is a class defined within the DocumentEvent interface that enumerates the possible changes that can occur on a document: insert text, remove text, and change text style.

Examples that Use Document Listeners

The following table lists the examples that use document listeners.

Example Where Described Notes
DocumentEventDemo This section Reports all document events that occur on the documents for both a text field and a text area. One listener listens to both text components and uses a client property on the document to determine which component fired the event.
TextComponentDemo Listening for Changes on a Document(in the Creating a User Interface trail) Updates a change log every time text in the listened-to document changes. The document in this example supports styled text, so changedUpdate gets called in this example. Requires this additional source file: LimitedStyledDocument
TextFieldDemo Using a Document Listener on a Text Field(in the Creating a User Interface trail) Registers one document listener on three text fields. The listener computes a numeric value based on numeric values entered into the three text fields by the user.


Previous Page Lesson Contents Next Page Start of Tutorial > Start of Trail > Start of Lesson Search