问题描述
我正在使用NumberFormatter
和JFormattedTextField
,但是.getValue()
返回的值与用户看到的值不同.
I'm using a NumberFormatter
and JFormattedTextField
, but the .getValue()
doesn't return the same value as the user is seeing.
我认为输入字符串是使用NumberFormats解析方法解析的,并且我从NumberFormat.getNumberInstance();
获取了带有实际语言环境的Numberformat.所以我认为我不容易扩展它并编写自己的解析方法?
I think the input-string is parsed using NumberFormats parse-method, and I get the Numberformat from NumberFormat.getNumberInstance();
with the actual Locale. So I don't think I easily can extend it and write my own parse-method?
在示例中,如果用户键入1234.487
getValue()
将返回:1234.487
,但用户将显示1,234.49
In example, if the user types 1234.487
the getValue()
will return:1234.487
but the user will be displayed 1,234.49
另一个示例,使用NumberFormat.getCurrencyInstance();
.用户键入1234.487
,getValue()
将返回1234.487
,但将显示$1,234.49
Another example, using NumberFormat.getCurrencyInstance();
. The user types 1234.487
and the getValue()
will return 1234.487
but the user will be displayed $1,234.49
相反,如果Formatter在不舍入的情况下无法格式化该值,我希望生成一个ParseException.如果用户键入4.35b6
,同样的事情,默认情况下,格式化程序将显示4.35
,值将为4.35
,但是我想要一个ParseException,因为用户键入了无效值.
Instead, I want an ParseException be generated if the Formatter can't format the value without rounding. Same thing if the user types 4.35b6
, by default the formatter will display 4.35
and the value will be 4.35
, but I want a ParseException, because the user typed in an invalid value.
这是我尝试过的代码:
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());
}
});
如何获得与用户看到的相同的值?
推荐答案
您应该扩展NumberFormatter
而不是NumberFormat
并覆盖stringToValue
,以便它验证在解析字符串时您是否获得了原始值:
You should extend NumberFormatter
rather than NumberFormat
and override stringToValue
so that it verifies that when the string is parsed you get back the original value:
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"));
如果舍入前后的值不匹配,此格式化程序将拒绝新文本.
This formatter will reject the new text if the values before and after rounding do not match.
注意:这将比较值,而不是字符串.它将容忍更改,例如删除分组字符("$1,000"
=> "$1000"
)和尾随零("$1.20"
=> "$1.2"
).基本上,如果NumberFormat
返回相同的值,则可以接受.但是NumberFormat
施加的任何限制仍然适用,例如您不得删除货币符号或插入前导空格等.
Note: this compares the values, not the strings. It will tolerate changes like removing grouping characters ("$1,000"
=> "$1000"
) and trailing zeros ("$1.20"
=> "$1.2"
). Basically if the NumberFormat
returns the same value then it is acceptable. But any restrictions imposed by the NumberFormat
still apply, e.g. you must not remove the currency symbol or insert leading spaces etc.
这篇关于如何获得与用户从JFormattedTextField看到的值相同的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!