【问题标题】:Allow textfield to input only number [Java]允许文本字段仅输入数字 [Java]
【发布时间】:2015-09-17 07:54:49
【问题描述】:

我知道这个问题已经被问过很多次,但我仍然无法得到我真正需要的答案。希望这一次,有人可以帮助我,我提前感谢你。 :)

这就是我在程序中想要的,我希望用户限制只能输入数字。每当他们输入字母和其他内容时,都会有提示信息。我可以这样做,有一个关于字母和其他字符的提示信息,但输入的值仍然存在,我希望它被清除。

请看我的代码。

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

}    

虽然我清除了我的文本字段,但我输入的字符仍然出现。 任何帮助将非常感激。谢谢! :)

【问题讨论】:

标签: java jtextfield


【解决方案1】:

您需要创建 DocumentFilter 类的子类,并使用正则表达式来匹配每个插入的字符串/字符是否为数字并执行相应的操作。

以下是此工作的完整工作示例代码。感谢@camickr 指出使用 DocumentFilter 比扩展 JTextField 以实现相同结果的旧方法更新。

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

【讨论】:

  • 较新的方法是使用DocumentFilter 而不是创建自定义文档。 DocumentFilter 可以添加到任何AbstractDocument
  • @camickr 哦,这对我来说是新的,谢谢。我会试试的。确实,我很久以前就使用自定义的jtextfield :)
  • 例如,请参阅Implementing a Document Filter。示例过滤器可用于 JTextField、JTextArea 或 JTextPane。不需要不同的类来扩展不同的文档。
  • 更新了使用 DocumentFilter 的答案。您知道它与旧方法非常相似,只是您只是子类 1 类而不是子类 2 类。
  • 感谢@george_h 和camickr。即使我尝试粘贴文本,我也尝试过并且效果很好。
【解决方案2】:

在代码中添加evt.consume()行如下:

 JOptionPane.showMessageDialog(this, "Number only!","Invalid Input",JOptionPane.ERROR_MESSAGE);
 txtQty1.setText(" ");
 evt.consume(); //consume the key type event

详情http://docs.oracle.com/javase/7/docs/api/java/awt/event/InputEvent.html#consume()


要禁用在txtQty1 文本字段中粘贴错误的输入,您可以使用caretUpdate 事件,如下所示:

注意:如果您使用 Netbeans GUI 表单,只需创建 caretUpdate 事件。

private void txtQty1CaretUpdate(javax.swing.event.CaretEvent evt) {                                    

    String text = txtQty1.getText();
    if(text != null) {
        if(!text.matches("[0-9]*")) {
            txtQty1.setText(" ");                
        }
    }

} 

【讨论】:

  • 嗨@developerbhuwan,非常感谢。我有我需要的东西。 :)
  • @nhix,不要使用 KeyListener。这不是解决问题的方法。例如,尝试将一串无效文本粘贴到文本字段中。您的修改将无效。
  • @camickr 谢谢!我试过了,你是对的。我应该使用什么事件?
  • @camickr 对不起,我忽略了。谢谢! :)
  • 同意它提供了很好的答案,它永远不会被黑客攻击。正确的安全和“摇摆不定”的方式如下(Document or DocumentFilter)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 2015-06-09
  • 2018-05-27
  • 1970-01-01
  • 2012-01-22
相关资源
最近更新 更多