Как разрешить ввод только цифр в jTextField?

Я попытался использовать пример, показанный здесь, но java показывает сообщение об ошибке

"AttributeSet не может быть преобразован в тип"

Вот почему я пытаюсь использовать другой метод разрешения только цифр:

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;
  }
} 

Но, конечно, это не работает, потому что метод keyPressed - это void. Итак, что же сделать, чтобы в текстовом поле печатались только цифры?


person Bakhtiyor    schedule 28.02.2012    source источник
comment
stackoverflow.com/questions/5662651/   -  person Jwalin Shah    schedule 28.02.2012
comment
@Bakhtiyor никогда не используйте KeyListener для JTextComponents, используйте DocumentListener и для фильтрации DocumentFilter, несколько хороших примеров для Digits на этом форуме, ваш связанный пост - самый безопасный способ, как это сделать   -  person mKorbel    schedule 28.02.2012


Ответы (5)


Здесь проверьте этот фрагмент кода, вот как вы разрешаете только цифры в JTextField, используя DocumentFilter, как наиболее эффективный способ:

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();
    }
}

Или можно просто использовать этот подход, указанный @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);
}
person nIcE cOw    schedule 28.02.2012
comment
хехехе странно, но за DocumentFilter +1 - person mKorbel; 28.02.2012
comment
@mKorbel: Спасибо, я только что ответил кому-то не в той ветке, как это сделать с помощью DocumentFilter, только что узнал, что для этого не нужен JFormattedField, поскольку желаемые результаты в JFormattedField в некоторых случаях нежелательны, поэтому сделал это с обычным JTextField. :-) - person nIcE cOw; 28.02.2012
comment
@mKorbel: обратите внимание, что в вашем коде есть ошибка. Если я вставлю строку типа a2 в этот JTextField, то она поместит данную строку в JTextField без проблем, поскольку проверяется только самый последний символ. - person Lajos Arpad; 04.07.2013
comment
@LajosArpad: Большое спасибо за указание на ОШИБКУ. Надеюсь, на этот раз ошибка устранена :-) ПРОДОЛЖАЙТЕ УЛЫБАТЬСЯ :-) - person nIcE cOw; 04.07.2013
comment
звучит как много усилий, когда в более современных языках, таких как Android, простое textField.SetValidation(TextField.Numeric) или подобное делает свое дело. довольно бедный Swing не имеет этого - person Jonathan; 21.05.2014
comment
В вашей версии вы вызываете метод insertString DocumentFilter, а версия Карлоса вызывает метод insertString фильтра FilterBypass. Какая разница? - person Stevens Miller; 02.06.2014
comment
@StevensMiller: «DocumentFilter.FilterBypass» — это вложенный класс внутри «DocumentFilter». Насколько я знаю, я сохранил это для Swing, как обойти это в их реализации, вызвав метод базового класса, хотя в последнем случае кажется, что полномочия были взяты самим программистом. - person nIcE cOw; 02.06.2014

Я бы предложил использовать JFormattedTextField. Вот как: Как использовать форматированные текстовые поля

person COD3BOY    schedule 28.02.2012
comment
DocumentFilter - это еще один способ ... +1 - person mKorbel; 28.02.2012

Это то, что я использую, чтобы потреблять не числа

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
            }
        }
    });
person Alde    schedule 10.06.2017
comment
Плавающие числа не принимаются. Также символы могут быть вставлены с помощью копирования. - person Bu Saeed; 05.12.2019
comment
Пользователь запросил только цифры. Вы правы насчет копипаст. - person Alde; 02.01.2020

Моя версия, которая полностью отбрасывает нежелательные символы (я пробовал):

        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);
person Baboolull Yougesh    schedule 23.10.2019

Попробуй это:

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);
}

вместо:

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();
}
person Khan Usama    schedule 10.06.2017