如何获得用户从JFormattedTextField看到的相同值?

Jon*_*nas 3 java validation swing number-formatting jformattedtextfield

我使用的是NumberFormatter和JFormattedTextField,但.getValue()不会返回相同的值,用户看到的.

我认为输入字符串是使用NumberFormats parse-method解析的,我从NumberFormat.getNumberInstance();实际的Locale中获取Numberformat .所以我认为我不能轻易扩展它并编写自己的解析方法?

在例如,如果用户键入1234.487 的getValue()将返回: 1234.487但用户将显示1,234.49

另一个例子,使用NumberFormat.getCurrencyInstance();.用户类型1234.487和getValue()将返回1234.487但将显示用户$1,234.49

相反,如果Formatter无法在不进行舍入的情况下格式化值,则需要生成ParseException.同样的事情,如果用户键入4.35b6,默认情况下格式化程序将显示4.35,值将是4.35,但我想要一个ParseException,因为用户输入了无效值.

这是我尝试过的代码:

NumberFormat nf = NumberFormat.getNumberInstance();
nf.setMaximumFractionDigits(2);
nf.setMinimumFractionDigits(2);
final JFormattedTextField ftf = new JFormattedTextField(nf);
ftf.setValue(new BigDecimal("1234.50"));

// Print the value from ftf
final JTextField txt = new JTextField(12);
txt.addFocusListener(new FocusAdapter() {
    public void focusGained(FocusEvent e) {
        txt.setText(ftf.getValue().toString());
    }
});
Run Code Online (Sandbox Code Playgroud)

如何获得与用户看到的相同的价值?

fin*_*nnw 6

你应该扩展NumberFormatter而不是NumberFormat覆盖,stringToValue以便它验证当解析字符串时你得到原始值:

class StrictNumberFormatter extends javax.swing.text.NumberFormatter {
    @Override
    public Object stringToValue(String text) throws ParseException {
        Object parsedValue = super.stringToValue(text);
        String expectedText = super.valueToString(parsedValue);
        if (! super.stringToValue(expectedText).equals(parsedValue)) {
            throw new ParseException("Rounding occurred", 0);
        }
        return parsedValue;
    }

    public StrictNumberFormatter(NumberFormat nf) {
        super(nf);
    }
}

NumberFormat nf = NumberFormat.getNumberInstance();
nf.setMaximumFractionDigits(2);
nf.setMinimumFractionDigits(2);
JFormattedTextField.AbstractFormatter formatter = new StrictNumberFormatter(nf);
final JFormattedTextField ftf = new JFormattedTextField(formatter);
ftf.setValue(new BigDecimal("1234.50"));
Run Code Online (Sandbox Code Playgroud)

如果舍入前后的值不匹配,则此格式化程序将拒绝新文本.

注意:这会比较值,而不是字符串.它将容忍更改,如删除分组字符("$1,000"=> "$1000")和尾随零("$1.20"=> "$1.2").基本上,如果NumberFormat返回相同的值,那么它是可以接受的.但是NumberFormat仍然适用的任何限制,例如,您不得删除货币符号或插入前导空格等.