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

时间:2010-02-05 10:00:05

标签: java swing validation number-formatting jformattedtextfield

我正在使用NumberFormatterJFormattedTextField,但.getValue()未返回与用户看到的值相同的值。

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

在示例中,如果用户输入1234.487 getValue()将返回: 1234.487但会向用户显示1,234.49

另一个例子,使用NumberFormat.getCurrencyInstance();。用户输入1234.487getValue()将返回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());
    }
});

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

2 个答案:

答案 0 :(得分: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"));

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

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

答案 1 :(得分:3)

试试这个:

txt.setText(ftf.getFormatter().valueToString(ftf.getValue()));

您还必须处理java.text.ParseException方法抛出的valueToString

修改 格式化程序可以设置为完全禁止无效条目,这可能会有所帮助:

    ((DefaultFormatter)ftf.getFormatter()).setAllowsInvalid( false );