带有掩码的 JFormattedTextField Formatter 抛出 NumberFormatException



我有一个使用以下掩码格式化程序的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 个字符组成的数值,那么您确实应该考虑使用应用于普通JTextFieldDocumentFilter

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

由于我不确定您如何使用修剪,因此建议您尝试以下代码行来删除空格: 如前所述,以下代码应该可以工作:

String playerBet=playerRaiseField.getText();
// if playerBet is not null
String playerBetWithoutSpaces=playerBet.trim();
Integer.parseInt(playerBetWithoutSpaces);

您的格式"####"只允许正好 4 位数字。对于可变长度,您必须编写一个自定义类。 下面是一个示例类。

使用您的代码实现了一些东西,并且只有在填写所有 4 个数字时才对我有用:

import javax.swing.*;
import javax.swing.text.*;
import java.awt.event.*;
import java.awt.*;
public class tes implements ActionListener
{
  public static JFormattedTextField playerRaiseField;
public static void main(String[] args) throws Exception{
JFrame j=new JFrame();
    j.setSize(400,400);
    j.setLayout(new GridLayout(2,1));
MaskFormatter maskForInput;
    maskForInput=new MaskFormatter("####"); // I have tried using stars (*) too.
    maskForInput.setValidCharacters("0123456789");
    playerRaiseField=new javax.swing.JFormattedTextField(maskForInput);
j.getContentPane().add(playerRaiseField);
JButton jb=new JButton("Print out the above value");
j.getContentPane().add(jb);
jb.addActionListener(new tes());
j.setVisible(true);
}
public void actionPerformed(ActionEvent e) throws Exception{
    System.out.println("""+Integer.parseInt(playerRaiseField.getText())+""");
}
}

Java 文档

1

public void setMask(String mask)
             throws ParseException

2 你说你得到 4 个空格。这意味着没有设置默认值,并且您没有使用无效字符。查找上述文档。

3 为了使其可扩展 (1-4),您必须确定输入的长度,然后使用 IF 通过适当的掩码运行它。您也可以使用默认值填充剩余的掩码,请参阅文档。

编辑:看到你在下面发布了更多代码。您不会对现有字符串执行 getText。您可以使用它从字段中获取输入。你必须以另一种方式做到这一点。

相关内容

  • 没有找到相关文章

最新更新