Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

How to make a JSpinner accept only digits

jduprezFeb 3 2011 — edited Feb 4 2011
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;
            }
        });
    }
}
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Mar 4 2011
Added on Feb 3 2011
4 comments
2,612 views