22.6 The DocumentFilter Class
DocumentFilter is a class that oversees calls to
insertString( ), remove( ), and
replace( ) on any subclass of
AbstractDocument. It can allow the edit to occur,
substitute another edit, or block it entirely. Because all of
Swing's Document classes inherit
from AbstractDocument, this means you can attach a
DocumentFilter to pretty much any Swing text
component. The Document interface does not define
a setDocumentFilter( ) method though, so you have
to cast the object returned by the getDocument( )
method to AbstractDocument before you can set the
DocumentFilter. DocumentFilter
was introduced in SDK 1.4.
Here's how DocumentFilter works.
AbstractDocument's
insertString( ), remove( ), and
replace( ) methods check for the existence of a
DocumentFilter. If there is one, they forward the
call to the like-named method of the
DocumentFilter object. But the
DocumentFilter methods are passed an extra
parameter called the FilterBypass. The
FilterBypass object has its own
insertString( ), remove( ), and
replace( ) methods, and these actually change the
Document's content.
It's important that
DocumentFilter methods call
FilterBypass methods because an endless calling
loop occurs if the Document methods are called.
The delegation to the DocumentFilter is
"bypassed" in
FilterBypass. FilterBypass also
provides a getDocument( ) method so the
DocumentFilter can examine the contents of the
Document before deciding whether to allow an edit.
22.6.1 Constructor
- public DocumentFilter( )
-
Instantiate a DocumentFilter that allows all edits
to occur.
22.6.1.1 Methods
DocumentFilter's methods allow
all edits to occur by default, so you override only the ones you want
to be more restrictive.
- public void insertString(DocumentFilter.FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException
- public void remove(DocumentFilter.FilterBypass fb, int offset, int length) throws BadLocationException
- public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attr) throws BadLocationException
22.6.1.2 DocumentFilter.FilterBypass methods
- public Document getDocument( )
- public void insertString(int offset, String text, AttributeSet attr) throws BadLocationException
- public void remove(int offset, int length) throws BadLocationException
- public void replace(int offset, int length, String text, AttributeSet attr) throws BadLocationException
Here's a simple example of a
DocumentFilter that doesn't allow
lowercase letters in the Document. All it does is
convert the input String to uppercase before
delegating to the FilterBypass.
// UpcaseFilter.java
// A simple DocumentFilter that maps lowercase letters to uppercase
import javax.swing.*;
import javax.swing.text.*;
public class UpcaseFilter extends DocumentFilter {
public void insertString(DocumentFilter.FilterBypass fb, int offset,
String text, AttributeSet attr) throws BadLocationException
{
fb.insertString(offset, text.toUpperCase( ), attr);
}
// No need to override remove( ); inherited version allows all removals.
public void replace(DocumentFilter.FilterBypass fb, int offset, int length,
String text, AttributeSet attr) throws BadLocationException
{
fb.replace(offset, length, text.toUpperCase( ), attr);
}
public static void main(String[] args) {
DocumentFilter dfilter = new UpcaseFilter( );
JTextArea jta = new JTextArea( );
JTextField jtf = new JTextField( );
((AbstractDocument)jta.getDocument( )).setDocumentFilter(dfilter);
((AbstractDocument)jtf.getDocument( )).setDocumentFilter(dfilter);
JFrame frame = new JFrame("UpcaseFilter");
frame.getContentPane( ).add(jta, java.awt.BorderLayout.CENTER);
frame.getContentPane( ).add(jtf, java.awt.BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(200, 120);
frame.setVisible(true);
}
}
Note that even though the text area and the text field each have
their own Document, they share the same
DocumentFilter instance. Unless your
DocumentFilter needs to store state information,
you can instantiate one DocumentFilter and attach
it to as many AbstractDocuments as you
like.
|