Hello,
I am trying to modify a JSpinner in a relatively simple UI, so as to edit an integer number.
Currently, the user can type anything in the spinner's textfield, and although that latter's model translates invalid edits as 0, the spec says only digits should be accepted.
From earlier reading on this forum, I tried to hack the spinner to get its (normally innards) editor, then tried to use a DocumentFilter, and accept the edits only if they contain only digits. Still, the user is able to type non-digits there. The spinner will revert the invalid edits when the focus moves to another component, that's all, but my boss doesn't even want to see the non-digits.
Eventually, I tried using a maskFormatter, and an InputVerifier, and neither worked :o(
Can anyone help me write a
private JSpinner makeDigitsOnlySpinner() method?
Thanks in advance.
J.
Here is an SSCCE of the DocumentFilter attempt.
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.DocumentFilter;
public class TestDigitsOnlySpinner {
public static void main(String... args) {
SwingUtilities.invokeLater((Runnable) new Runnable() {
public void run() {
JFrame frame = new JFrame("enter digit");
JSpinner jspinner = makeDigitsOnlySpinnerUsingDocumentFilter();
frame.getContentPane().add(jspinner, BorderLayout.CENTER);
frame.getContentPane().add(new JButton("just another widget"), BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
private JSpinner makeDigitsOnlySpinner_BasicAttempt() {
JSpinner spinner = new JSpinner(new SpinnerNumberModel());
return spinner;
}
private JSpinner makeDigitsOnlySpinnerUsingDocumentFilter() {
JSpinner spinner = new JSpinner(new SpinnerNumberModel());
JSpinner.NumberEditor jsEditor =
(JSpinner.NumberEditor)spinner.getEditor();
Document jsDoc = jsEditor.getTextField().getDocument();
if (jsDoc instanceof AbstractDocument) {
AbstractDocument doc = (AbstractDocument)jsDoc;
doc.setDocumentFilter(new DocumentFilter() {
@Override
public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException {
if (stringContainsOnlyDigits(string)) {
super.insertString(fb, offset, string, attr);
}
}
@Override
public void remove(FilterBypass fb, int offset, int length) throws BadLocationException {
super.remove(fb, offset, length);
}
@Override
public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
if (stringContainsOnlyDigits(text)) {
super.replace(fb, offset, length, text, attrs);
}
}
private boolean stringContainsOnlyDigits(String text) {
for (int i = 0; i<text.length(); i++) {
if (!Character.isDigit(text.charAt(i))) {
return false;
}
}
return true;
}
});
}
return spinner;
}
});
}
}