我修改了NumberFormatter
,使其具有货币实例(带有前缀)。当我写第一个号码时,这个应用程序已经为号码添加了前缀JFormattedTextField时空但是当我这样做的时候,插入符号的位置在第一个数字之前改变了,像这样输入图片描述
如何通过仅修改方法formato()
-返回NumberFormatter
-JFormattedTextField
的构造函数来修复此问题?
textFieldMonto = new javax.swing.JFormattedTextField(formato());
方法:
private NumberFormatter formato() {
DecimalFormat myFormatter = new DecimalFormat("'Gs. '###,##0;'Gs. '###,##0");
NumberFormatter numberFormatter = new NumberFormatter(myFormatter) {
// this change caret to the end in every focus gained
@Override
public void install(JFormattedTextField pField) {
super.install(pField);
pField.setCaretPosition(pField.getDocument().getLength());
}
// allow empty text on JFormattedTextField and dont allow negative numbers
@Override
public String valueToString(Object value) throws ParseException {
String result = super.valueToString(value);
if(super.valueToString(value).startsWith("-"))
result = result.replaceFirst("-", ""); // this block every negative number
if(value==null)
return "";
return result;
}
// allow empty text on JFormattedTextField and dont allow negative numbers
@Override
public Object stringToValue(String text) throws ParseException {
if (text.length() == 0 || text.equals("Gs. ")) // if is empty or only have the prefix, return null
return null;
text.replaceFirst("-", ""); // this block every negative number
if(!text.startsWith("Gs. ")) //if is empty, add the prefix "Gs. " to the number
text = "Gs. " + text;
return super.stringToValue(text);
}
};
numberFormatter.setAllowsInvalid(false); //this is the key!!
numberFormatter.setMaximum(new BigDecimal("999999999999"));// maximum number to put
numberFormatter.setCommitsOnValidEdit(true);// commit value on each keystroke instead of focus lost
return numberFormatter;
}
我不认为这个评论,在你的问题中的代码,是真的:
// this change caret to the end in every focus gained
方法install
不是每次JFormattedTextField
获得焦点时调用。根据我的测试,它只在创建JFormattedTextField
对象时被调用。
根据javadoc:
子类通常只需要在它们希望在
JFormattedTextField
上安装额外的侦听器时重写它。
因此,我建议在install
方法中为JFormattedTextField
的文档添加DocumentListener。
请注意,还有其他DocumentListener
是由Swing基础设施设置的,并且由于在存在多个DocumentListener
时无法保证执行顺序,因此在下面的代码中,实现使用invokeLater来确保我添加的侦听器是最后运行的。
这是我重写你的formato
方法。
唯一改变的是方法install
。
private NumberFormatter formato() {
DecimalFormat myFormatter = new DecimalFormat("'Gs. '###,##0;'Gs. '###,##0");
NumberFormatter numberFormatter = new NumberFormatter(myFormatter) {
// this change caret to the end in every focus gained
@Override
public void install(JFormattedTextField pField) {
super.install(pField);
pField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
EventQueue.invokeLater(() -> pField.setCaretPosition(pField.getDocument().getLength()));
}
@Override
public void removeUpdate(DocumentEvent e) {
EventQueue.invokeLater(() -> pField.setCaretPosition(pField.getDocument().getLength()));
}
@Override
public void changedUpdate(DocumentEvent e) {
// Do nothing.
}
});
}
// allow empty text on JFormattedTextField and don't allow negative numbers
@Override
public String valueToString(Object value) throws ParseException {
String result = super.valueToString(value);
if(super.valueToString(value).startsWith("-"))
result = result.replaceFirst("-", ""); // this block every negative number
if(value==null)
return "";
return result;
}
// allow empty text on JFormattedTextField and don't allow negative numbers
@Override
public Object stringToValue(String text) throws ParseException {
if (text.length() == 0 || text.equals("Gs. ")) // if is empty or only have the prefix, return null
return null;
text.replaceFirst("-", ""); // this block every negative number
if(!text.startsWith("Gs. ")) //if is empty, add the prefix "Gs. " to the number
text = "Gs. " + text;
return super.stringToValue(text);
}
};
numberFormatter.setAllowsInvalid(false); //this is the key!!
numberFormatter.setMaximum(new BigDecimal("999999999999"));// maximum number to put
numberFormatter.setCommitsOnValidEdit(true);// commit value on each keystroke instead of focus lost
return numberFormatter;
}