需要在Java程序中进行输入验证(Java 2 SE)

时间:2013-05-21 06:49:20

标签: java input

我制作了一个java程序,它应该在GUI框架中从用户那里获取输入,并以行和列的形式存储在.dat文件中。问题在于这个特定的代码,因为它没有给出期望的结果。用户应该只能使用keylistener输入20到30之间的数字。输入不应该接受超出此范围的任何数字,即19或31.Eclipse正在抛出错误'无效的字符常量'。有什么出路吗?

// input validation that restricts user to enter specific number range between 20 and 30

txDeposit.addKeyListener(new KeyAdapter() {
    public void keyTyped(KeyEvent ke) {
        char c = ke.getKeyChar();
        if(!(ke.getKeyChar() >= '20' && ke.getKeyChar() <= '30')) {
            getToolkit().beep();
            ke.consume();
        }
    }
});

3 个答案:

答案 0 :(得分:0)

KeyListener在这种情况下是不可靠的,因为您无法保证听众处理的顺序。该字段可能已经在您之前处理了关键事件...

相反,您应该使用DocumentFilter

检查here示例

更简单的解决方案就是使用JSpinner

文档过滤示例

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;

public class TestNumericFilter {

    public static void main(String[] args) {
        new TestNumericFilter();
    }

    public TestNumericFilter() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            JTextField field = new JTextField(3);
            ((AbstractDocument) field.getDocument()).setDocumentFilter(new IntFilter());
            setLayout(new GridBagLayout());
            add(field);
        }
    }

    public class IntFilter extends DocumentFilter {

        public void insertString(DocumentFilter.FilterBypass fb, int offset,
                String text, AttributeSet attr)
                throws BadLocationException {

            boolean valid = true;
            for (char c : text.toCharArray()) {
                if (!Character.isDigit(c)) {
                    valid = false;
                    break;
                }
            }

            if (valid) {

                int incoming = Integer.parseInt(text);
                int length = fb.getDocument().getLength();
                if (length == 0 && text.length() == 1) {
                    if (incoming >= 2 && incoming <= 3) {
                        super.insertString(fb, offset, text, attr);
                    } else {
                        Toolkit.getDefaultToolkit().beep();
                    }
                } else {
                    String value = fb.getDocument().getText(0, length) + text;
                    incoming = Integer.parseInt(value);
                    if (incoming >= 20 && incoming <= 30) {
                        super.insertString(fb, offset, text, attr);
                    } else {
                        Toolkit.getDefaultToolkit().beep();
                    }
                }
            }
        }

        public void replace(DocumentFilter.FilterBypass fb,
                int offset, int length, String string, AttributeSet attr) throws BadLocationException {
            if (length > 0) {
                fb.remove(offset, length);
            }
            insertString(fb, offset, string, attr);
        }
    }
}

答案 1 :(得分:0)

您的代码无法编译,因为`` is used to mark characters, not string. Character constant consist of one and only one character only. Therefore'20''无效。

现在,据我所知,您希望从20到30捕获数字 .2位数字由2位数字组成,因此您必须使验证更复杂:如果第一个字符是{ {1}}如果第一个字符2仅允许'3',则必须等待0到9之间的字符。

输入2个字符后,您必须重置状态并再次等待“2”或“3”。

我只是怀疑你真的想这样做。 据我了解你添加了文本字段的监听器,不是吗?在这种情况下,请不要检查当前输入的字符。检查文本字段的内容:

'0'

答案 2 :(得分:0)

您可以使用扩展JTextField的预制Java组件。它提供长度限制和正则表达式检查。您可以轻松地使用该组件并添加正则表达式来限制数量。

您可以选择并轻松地编辑代码(特别是insertString()方法)并添加自己的自定义检查。

您可以在https://subversivebytes.wordpress.com/2012/10/09/java-create-custom-regex-jtextfield/查看有关它的博文,代码已完整且可以免费复制/粘贴

这只是其中一个“为什么要重新发明轮子”的事情......