I figure this must be a simple mistake in the code or a misunderstanding on my part, but I cannot get a DocumentFilter
to detect insertString
events. Below is a simple filter for upper case letters, but that is not as important as the fact that the insertString(..)
method never seems to be called!
Why is the insertString(..)
method of the DocumentFilter
not called?
The filter is applied to the JTextField
at the top. Every time insertString(..)
is called, it should append information to the JTextArea
in the CENTER
. At the moment, there is no action in the text field that causes text to be appended to the text area.
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.text.*;
public class FilterUpperCaseLetters {
private JComponent ui = null;
private final JTextField textField = new JTextField(25);
private final JTextArea textArea = new JTextArea(5, 20);
FilterUpperCaseLetters() {
initUI();
}
public void initUI() {
// The document filter that seems to do nothing.
DocumentFilter capsFilter = new DocumentFilter() {
@Override
public void insertString(
DocumentFilter.FilterBypass fb,
int offset,
String string,
AttributeSet attr) throws BadLocationException {
textArea.append("insertString! " + string + "\n");
if (!string.toUpperCase().equals(string)) {
textArea.append("Insert!\n");
super.insertString(fb, offset, string, attr);
} else {
textArea.append("DON'T insert!\n");
}
}
};
AbstractDocument abstractDocument
= (AbstractDocument) textField.getDocument();
abstractDocument.setDocumentFilter(capsFilter);
ui = new JPanel(new BorderLayout(4, 4));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
ui.add(textField, BorderLayout.PAGE_START);
ui.add(new JScrollPane(textArea), BorderLayout.CENTER);
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
FilterUpperCaseLetters o = new FilterUpperCaseLetters();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
DocumentFilter, as the name implies, is a filter for the Document mutation methods. When a Document containing a DocumentFilter is modified (either through insert or remove), it forwards the appropriate method invocation to the DocumentFilter. The default implementation allows the modification to occur.
When a Document containing a DocumentFilter is modified (either through insert or remove ), it forwards the appropriate method invocation to the DocumentFilter. The default implementation allows the modification to occur.
javax.swing.text Class DocumentFilter java.lang.Object javax.swing.text.DocumentFilter public class DocumentFilterextends Object DocumentFilter, as the name implies, is a filter for the Documentmutation methods.
By default, text related document mutation methods such as insertString, replaceand removein AbstractDocumentuse DocumentFilterwhen available, and Elementrelated mutation methods such as create, insertand removeElementin DefaultStyledDocumentdo not use DocumentFilter.
The text components use the replaceSelection(...)
method which will in turn invoke the replace(...)
method of the AbstractDocument
which will invoke the replace(...)
method of the DocumentFilter
.
The insertString(...)
method of the DocumentFilter
is only called when you use the Document.insertString(...)
method to directly update the Document
.
So in reality you need to override both methods to make sure the upper case conversion is done.
A simple example showing how to easily implement both methods:
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
public class UpperCaseFilter extends DocumentFilter
{
public void insertString(FilterBypass fb, int offs, String str, AttributeSet a)
throws BadLocationException
{
replace(fb, offs, 0, str, a);
}
public void replace(FilterBypass fb, final int offs, final int length, final String text, final AttributeSet a)
throws BadLocationException
{
if (text != null)
{
super.replace(fb, offs, length, text.toUpperCase(), a);
}
}
private static void createAndShowGUI()
{
JTextField textField = new JTextField(10);
AbstractDocument doc = (AbstractDocument) textField.getDocument();
doc.setDocumentFilter( new UpperCaseFilter() );
JFrame frame = new JFrame("Upper Case Filter");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout( new java.awt.GridBagLayout() );
frame.add( textField );
frame.setSize(220, 200);
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args) throws Exception
{
EventQueue.invokeLater( () -> createAndShowGUI() );
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With