Search code examples
javajtextfield

Allow textfield to input only number [Java]


I know this has been asked and answered many times but I still can't get the answer that I really need. Hopefully this time, somebody can help me and I thank you in advance. :)

This is what I want in my program, I want user to limit to input only numbers. Whenever they input letters and others there will be a prompt message. I can do that, there is a prompt message for letters and other char but the inputted value still remain, I want it to be cleared.

Please see my code.

private void txtQty1KeyTyped(java.awt.event.KeyEvent evt) {                                 
    txtQty1.addKeyListener(new KeyAdapter() {});
    char char_input = evt.getKeyChar();
    if (((char_input < '0') || (char_input > '9')) && (char_input != '\b'))
    {
        JOptionPane.showMessageDialog(this, "Number only!","Invalid Input",JOptionPane.ERROR_MESSAGE);
        txtQty1.setText(" ");
    }

}    

Though I clear my textfield, the character that I input still appears. Any help would be much appreciated. Thank you! :)


Solution

  • You need to create a subclass of DocumentFilter class and use a regular expression to match each inserted string/character if they are digits or not and perform actions accordingly.

    Below is a fully working sample code of this working. Thanks to @camickr for pointing out using DocumentFilter is more up-to-date than the old way of extending JTextField to achieve the same result.

    import java.awt.BorderLayout;
    import java.util.regex.Pattern;
    
    import javax.swing.JFrame;
    import javax.swing.JTextField;
    import javax.swing.text.AbstractDocument;
    import javax.swing.text.AttributeSet;
    import javax.swing.text.BadLocationException;
    import javax.swing.text.DocumentFilter;
    
    public class TestDocumentFilter {
    
        public static void main(String... args) {
            new TestDocumentFilter();
        }
    
        public TestDocumentFilter() {
            JTextField textField = new JTextField(10);
            ((AbstractDocument) textField.getDocument()).setDocumentFilter(new CustomDocumentFilter());
    
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().setLayout(new BorderLayout(5, 5));
            frame.getContentPane().add(textField, BorderLayout.NORTH);
            frame.setSize(400, 200);
            frame.setVisible(true);
        }
    
        private class CustomDocumentFilter extends DocumentFilter {
    
            private Pattern regexCheck = Pattern.compile("[0-9]+");
    
            @Override
            public void insertString(FilterBypass fb, int offs, String str, AttributeSet a) throws BadLocationException {
                if (str == null) {
                    return;
                }
    
                if (regexCheck.matcher(str).matches()) {
                    super.insertString(fb, offs, str, a);
                }
            }
    
            @Override
            public void replace(FilterBypass fb, int offset, int length, String str, AttributeSet attrs)
                    throws BadLocationException {
                if (str == null) {
                    return;
                }
    
                if (regexCheck.matcher(str).matches()) {
                    fb.replace(offset, length, str, attrs);
                }
            }
        }
    }