You really should avoid KeyListeners
, they are too limiting for what you are ultimately trying to achieve and you're only going to end up with a mutation exception as you try and change the fields document while the field is trying to change the document.
You really should be using a DocumentFilter, that's what it's design for.
((AbstractDocument)field.getDocument()).setDocumentFilter(new DocumentFilter() {
@Override
public void insertString(FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException {
StringBuilder sb = new StringBuilder(64);
for (char c : text.toCharArray()) {
if (Character.isDigit(c)) {
sb.append(c);
}
}
fb.insertString(offset, text, attr);
}
@Override
public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
StringBuilder sb = new StringBuilder(64);
for (char c : text.toCharArray()) {
if (Character.isDigit(c)) {
sb.append(c);
}
}
fb.replace(offset, length, sb.toString(), attrs);
}
});
This is a really basic example, there are plenty on SO.
Apart from avoiding mutation exceptions, the filter intercepts the update before it reaches the document/field, so the incoming changes won't be visible of the screen, you also capture any paste events or setText
calls.