java - 带有 maskFormatter 的 JFormattedTextField 会抛出 NumberFormatException

标签 java swing parsing input integer

我有一个使用以下掩码格式化程序的 JFormattedTextField:

    private MaskFormatter maskForInput;
    maskForInput=new MaskFormatter("####"); // I have tried using stars (*) too.
    maskForInput.setValidCharacters("0123456789");

    javax.swing.JFormattedTextField playerRaiseField=new javax.swing.JFormattedTextField(maskForInput);

这应该允许用户输入最多 4 位数字。但是,当我尝试 Integer.parseInt(playerRaiseField.getText()) 从此字段返回的 String 时,我总是可能收到 NumberFormatException由于用户输入中留有空格。 要清除此问题:

例如,如果用户输入 560 ,则后面会留下一个尾随空格,因此我正在读取的字符串是 560( ) 并且在尝试解析此 时String 转换为 int 会引发此异常。有什么解决方法吗?如何修改掩码格式化程序以接受 1 到 4 位数字,并且总是固定 4 位数字?

注意:奇怪的是,在返回的 String 上使用 trim() 仍然没有删除多余的空白字符...

最佳答案

有很多事情与您的期望不符......

首先,您似乎认为格式化字段可以包含任意数量的字符。这是不正确的(虽然您可以获取文本,但该字段仍处于其认为无效的状态)。格式化字段要求必须填充掩码的所有位置。

其次,您应该使用 JFormattedTextField#getValue 方法返回字段的值,而不是 getText

第三,返回的文本用掩码的占位符字符 (MaskFormatter#getPlaceholder) 填充,它可能是也可能不是空格,因此 String#trim 可能不会有帮助...

如果您希望用户只能输入可能由 0-n 个字符组成的数值,那么您确实应该考虑使用应用于普通 JTextField< 的 DocumentFilter/

public class TestField {

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

    public TestField() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

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

    public class NumericDocumentFilter extends DocumentFilter {

        private int maxChars;

        public NumericDocumentFilter(int maxChars) {
            this.maxChars = maxChars;
        }

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

            StringBuilder buffer = new StringBuilder(text);
            for (int i = buffer.length() - 1; i >= 0; i--) {
                char ch = buffer.charAt(i);
                if (!Character.isDigit(ch)) {
                    buffer.deleteCharAt(i);
                }
            }

            text = buffer.toString();
            if (fb.getDocument().getLength() + text.length() > maxChars) {
                int remaining = maxChars - fb.getDocument().getLength();
                text = text.substring(0, remaining);
            }

            if (text.length() > 0) {
                super.insertString(fb, offset, text, attr);
            }
        }

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

    public class TestPane extends JPanel {

        private JTextField field;

        public TestPane() {

            setLayout(new GridBagLayout());

            field = new JTextField(4);
            ((AbstractDocument) field.getDocument()).setDocumentFilter(new NumericDocumentFilter(4));
            add(field);
            field.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.println(field.getText());
                }
            });
        }
    }
}

关于java - 带有 maskFormatter 的 JFormattedTextField 会抛出 NumberFormatException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14450230/

相关文章:

Java指针或节点赋值理解错了吗?

java - 数据库-JTable交互

java - 在后台处理某些工作时显示带有动画 gif 的 JDialog

c# - XML 解析 - 读取简单的 XML 文件并检索值

java - 在 Guice 中使用通配符绑定(bind)泛型

java - 使用 UCanAccess 通过 JDBC 获取数据库名称

java - 数据库的 SQLiteConnection 对象被泄露!请修复您的应用程序

java - 如何在用户单击 JButton 时关闭 JFrame 窗口?

java - 使用 ANTLR 将非贪婪序列作为字符串获取

c++ - 编译器构造 : Handle references to unordered symbols