How to allow introducing only digits in jTextField?
Asked Answered
P

5

12

I have tried to use the example shown here but java showing error message of

"AttributeSet cannot be resolved to a type"

That is why I am trying to use another method of allowing only digits:

txtUsername.addKeyListener(new MyKeyListener());

public class MyKeyListener extends KeyAdapter{
  public void keyPressed(KeyEvent ke){
      System.out.println("Key pressed code = "+ke.getKeyCode());
      if (ke.getKeyCode()>=48 && ke.getKeyCode()<=57)
              return true;
      else
              return false;
  }
} 

But of course it is not working because keyPressed method is void. So, what to do in order to print only digits in textfield?

Pleistocene answered 28/2, 2012 at 6:20 Comment(2)
#5663151Bemba
@Pleistocene never use KeyListener for JTextComponents, use DocumentListener and for filtering DocumentFilter, a few good examples for Digits on this forum, your linked post is most safiest way how to do itCote
E
25

Here check this code snippet, that's how you allow only digits in JTextField, by using DocumentFilter, as the most effeciive way :

import java.awt.*;
import javax.swing.*;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
import javax.swing.text.DocumentFilter.FilterBypass;

public class InputInteger
{
    private JTextField tField;
    private MyDocumentFilter documentFilter;

    private void displayGUI()
    {
        JFrame frame = new JFrame("Input Integer Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel();
        contentPane.setBorder(
            BorderFactory.createEmptyBorder(5, 5, 5, 5));
        tField = new JTextField(10);
        ((AbstractDocument)tField.getDocument()).setDocumentFilter(
                new MyDocumentFilter());        
        contentPane.add(tField); 

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args)
    {
        Runnable runnable = new Runnable()
        {
            @Override
            public void run()
            {
                new InputInteger().displayGUI();
            }
        };
        EventQueue.invokeLater(runnable);
    }
}

class MyDocumentFilter extends DocumentFilter
{   
    @Override
    public void insertString(DocumentFilter.FilterBypass fp
            , int offset, String string, AttributeSet aset)
                                throws BadLocationException
    {
        int len = string.length();
        boolean isValidInteger = true;

        for (int i = 0; i < len; i++)
        {
            if (!Character.isDigit(string.charAt(i)))
            {
                isValidInteger = false;
                break;
            }
        }
        if (isValidInteger)
            super.insertString(fp, offset, string, aset);
        else
            Toolkit.getDefaultToolkit().beep();
    }

    @Override
    public void replace(DocumentFilter.FilterBypass fp, int offset
                    , int length, String string, AttributeSet aset)
                                        throws BadLocationException
    {
        int len = string.length();
        boolean isValidInteger = true;

        for (int i = 0; i < len; i++)
        {
            if (!Character.isDigit(string.charAt(i)))
            {
                isValidInteger = false;
                break;
            }
        }
        if (isValidInteger)
            super.replace(fp, offset, length, string, aset);
        else
            Toolkit.getDefaultToolkit().beep();
    }
}

Or one can simply use this approach, as given by @Carlos Heuberger

@Override
public void insertString(FilterBypass fb, int off
                    , String str, AttributeSet attr) 
                            throws BadLocationException 
{
    // remove non-digits
    fb.insertString(off, str.replaceAll("\\D++", ""), attr);
} 
@Override
public void replace(FilterBypass fb, int off
        , int len, String str, AttributeSet attr) 
                        throws BadLocationException 
{
    // remove non-digits
    fb.replace(off, len, str.replaceAll("\\D++", ""), attr);
}
Easement answered 28/2, 2012 at 7:43 Comment(7)
hehehe strange, but for DocumentFilter +1Cote
@Cote : Thankyou, I just answered to someone in the wrong thread, how to do that with DocumentFilter, just learned there is no need for JFormattedField for this, since what results one wants is something not desirable with JFormattedField, in some cases, so did that with normal JTextField. :-)Easement
@mKorbel: Please note that there is a bug in your code. If I paste a string like "a2" into that JTextField, then it puts the given string into the JTextField without a problem, as only the very last character is validated.Declination
@LajosArpad : Thankyou very much for pointing out, the BUG. I hope this time, the bug has been removed :-) KEEP SMILING :-)Easement
sounds like lot of effort where in more modern languages such as Android, a simpe textField.SetValidation(TextField.Numeric) or similar does the trick. pretty poor Swing doesnt have thisSnead
In your version, you are calling DocumentFilter's insertString, while Carlos's version calls the FilterBypass's insertString. What's the difference?Robinrobina
@StevensMiller: 'DocumentFilter.FilterBypass' is a nested class inside 'DocumentFilter'. As far as I know, I kept that to Swing, how to circumvent that, in their implementation by calling the base class's method, though in the latter's case, it seems that authority has been taken by the programmer itself.Easement
B
10

I'd suggest using a JFormattedTextField, Here is how : How to Use Formatted Text Fields

Bridgeman answered 28/2, 2012 at 6:27 Comment(1)
DocumentFilter is another way ... +1Cote
S
1

This is what I use to consume non-numbers

textField.addKeyListener(new KeyAdapter() {
        public void keyTyped(KeyEvent e) {
            char c = e.getKeyChar();
            if (((c < '0') || (c > '9')) && (c != KeyEvent.VK_BACK_SPACE)) {
                e.consume(); // consume non-numbers
            }
        }
    });
Stunning answered 10/6, 2017 at 4:28 Comment(2)
Floating numbers are not accepted. Also characters can be inserted using copy pase.Cathepsin
User asked for only digits. You're right about the copy paste.Stunning
O
1

My version which rejects unwanted characters completely(I tried):

        val2 = new JTextField();
        val2.addKeyListener(new KeyAdapter() {
        @Override
        public void keyTyped(KeyEvent e) {

            try {

                char input = e.getKeyChar(); //checks each key pressed
                // in other words it prevents input of any character other than 0-9 or .

                try {
                    int i = Integer.parseInt(val2.getText());
                    valid1.setText(""); //valid1 is a label for the message

                } catch (Exception e2) {
                    // TODO: handle exception
                    valid1.setText("Invalid Number!");
                }

                if((!Character.isDigit(input)) && !(input == '.')) { //numbers accept "."
                    e.consume();
                    // event won't be sent for any further event listeners
                    try {
                        int i = Integer.parseInt(val2.getText()); // checks if the string can be converted to int
                        double i1 = Double.parseDouble(val2.getText()); // checks if string can be converted to double
                        valid1.setText("");

                    } catch (Exception e2) {
                        // TODO: handle exception
                        // if it is not in a valid format.. it will generate error message
                        valid1.setText("Invalid Number!");
                    }


                }
                else {
                    // if format and characters are fine... no output
                    valid1.setText("");
                }


            }
            catch (Exception e2) {
                // TODO: handle exception
                // for unexpected errors
                valid1.setText("Error");
            }

        }

    });

    // auto generated for design of the textfield
    val2.setColumns(10);
    val2.setBounds(236, 11, 126, 43);
    panel.add(val2);
Odilia answered 23/10, 2019 at 9:0 Comment(0)
D
0

Try this:

public void replace(DocumentFilter.FilterBypass fb, int offset,
     int length, String text, AttributeSet attrs)throws BadLocationException { 

    if(fb.getDocument().getLength() + text.length() > 10) {
        return;
    }
    fb.insertString(offset, text, attrs);
}

instead of:

public void replace(DocumentFilter.FilterBypass fp, int offset
                , int length, String string, AttributeSet aset)
                                    throws BadLocationException
{
    int len = string.length();
    boolean isValidInteger = true;

    for (int i = 0; i < len; i++)
    {
        if (!Character.isDigit(string.charAt(i)))
        {
            isValidInteger = false;
            break;
        }
    }
    if (isValidInteger)
        super.replace(fp, offset, length, string, aset);
    else
        Toolkit.getDefaultToolkit().beep();
}
Dagney answered 10/6, 2017 at 4:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.