[英]Java - JFormattedTextField does not allow input on first attempt
[英]Java : Does Locale affect the Formatter for JFormattedTextField
我创建了JFormattedTextField的自定义组件(NumberFormattedTextField)。 这是我使用的格式化程序:
public static InternationalFormatter getDecimalIFormatter92() {
// For Buy & Sale Price
DecimalFormat numberFormat = (DecimalFormat) DecimalFormat.getNumberInstance();
numberFormat.setMaximumFractionDigits(2);
numberFormat.setMinimumFractionDigits(2);
numberFormat.setRoundingMode(RoundingMode.HALF_UP);
numberFormat.setGroupingUsed(false);
final InternationalFormatter formatter = new InternationalFormatter(numberFormat);
formatter.setAllowsInvalid(false);
formatter.setMinimum(0.00);
formatter.setMaximum(999999999.99);
return formatter;
}
当我创建NumberFormattedTextField的实例时:
public RelationsPanel(CashParent parent) {
try {
initComponents(); // startBalTxt = new NumberFormattedTextField();
Utility.logInfo("initComponents OVER");
myParent = parent;
nameTxt.setSizeLimit(20);
System.out.println("startBalTxt.setFormatter GOING FOR IT");
this.startBalTxt.setFormatter(Utility.getDecimalIFormatter82()); // Must be throwing here
System.out.println("startBalTxt.setFormatter DONE");
this.currentBalTxt.setFormatter(Utility.getDecimalIFormatter82());
} catch (Exception e) {
Utility.logInfo("Failed to Initialize : " + e.getMessage());
e.printStackTrace();
}
}
NumberFormattedTextField CLASS代码:
public class NumberFormattedTextField extends JFormattedTextField implements java.io.Serializable, DocumentListener, FocusListener {
private DecimalFormat numberFormat;
private InternationalFormatter formatter;
private double MAX_VALUE = 999999.99;
private final Map attributes = (Utility.getTextFont()).getAttributes();
/**
* Creates a NumberFormattedTextField with 6 Integer & 2 Fractional digits.
* Minimum is set to 0.00 and Max to 999999.99 without any grouping used.
*/
public NumberFormattedTextField() {
super();
createFormatter(); // Creates a default formatter, used if formatter is not set
this.setValue(0.00);
init();
}
private void createFormatter() {
// Create standard DecimalFormat
numberFormat = (DecimalFormat) DecimalFormat.getNumberInstance();
numberFormat.setMaximumFractionDigits(2);
numberFormat.setMinimumFractionDigits(2);
numberFormat.setRoundingMode(RoundingMode.HALF_UP);
numberFormat.setGroupingUsed(false);
formatter = new InternationalFormatter(numberFormat);
formatter.setAllowsInvalid(false);
formatter.setMinimum(0.00);
formatter.setMaximum(999999.99);
this.setFormatterFactory(new AbstractFormatterFactoryImpl());
}
private void init() {
setFont(Utility.getTextFont());
this.getDocument().addDocumentListener(this);
this.addFocusListener(this);
attributes.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
setFocusLostBehavior(PERSIST);
}
public void setFormatter(InternationalFormatter format) {
super.setFormatter(format);
System.out.println("Class of Format = " + format.getFormat().getClass());
if (format.getFormat() instanceof java.text.DecimalFormat)
numberFormat = (DecimalFormat)format.getFormat();
else
numberFormat = (DecimalFormat)(NumberFormat) format.getFormat();
formatter = format;
// AbstractFormatterFactoryImpl returns formatter straight away
this.setFormatterFactory(new AbstractFormatterFactoryImpl());
calculateMaxValue();
}
private void calculateMaxValue() {
try {
if (formatter.getMaximum() != null) {
//System.out.println(" MAX ALlowed = " + formatter.getMaximum());
String no = formatter.valueToString(formatter.getMaximum());
char seperator = java.text.DecimalFormatSymbols.getInstance().getGroupingSeparator();
no = no.replace(String.valueOf(seperator), "");
System.out.println("MAX Number to PArse = " + no);
MAX_VALUE = Double.parseDouble(no); // HERE ITS THROWING EXCEPTION
}
} catch (ParseException ex) {
Logger.getLogger(NumberFormattedTextField.class.getName()).log(Level.SEVERE, null, ex);
}
}
我的PC上的上述代码运行良好。 但是在客户端的PC上,它给出错误:无法初始化:对于输入字符串:“ 99999999,99”错误/我得到的日志:
startBalTxt.setFormatter GOING FOR IT
INFO: initComponents OVER
Class of Format = class java.text.DecimalFormat
MAX Number to PArse = 99999999,99
INFO: Failed to Initialize : For input string: "99999999,99"
java.lang.NumberFormatException: For input string: "99999999,99"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1241)
at java.lang.Double.parseDouble(Double.java:540)
at cashaccountingapp.components.NumberFormattedTextField.calculateMaxValue(NumberFormattedTextField.java:184)
Class of Format = class java.text.DecimalFormat
at cashaccountingapp.components.NumberFormattedTextField.setFormatter(NumberFormattedTextField.java:173)
at cashaccountingapp.data.RelationsPanel.<init>(RelationsPanel.java:35)
我们俩的语言环境不同。
发生此错误的原因可能是什么? 我的NumberFormattedTextField类中有其他语言环境或其他需要注意的地方。 我希望应用程序适应系统设置并相应显示。
如何解决这个问题?
很有可能是(不能完全确定,因为您没有显示初始设置并将错误仅破坏其消息;-)不同的语言环境是原因:一个以句点为小数点,另一个以逗号表示。 因此,如果用一个表示另一个数字的String初始化一个,则会发生冲突:逗号不解释为小数点分隔符,因此最大值太大而无法满足限制
得到了解决方案:
我专门得到Locale.US的DecimalFormatSymbols实例。 这有助于我使用适当的十进制分隔符以标准格式获取字符串。 从而能够将有效字符串解析为Double。 这是我更改的代码,如果有帮助的话:
private void calculateMaxValue() {
try {
if (formatter.getMaximum() != null) {
String no = formatter.valueToString(formatter.getMaximum());
// Get DecimalFormatSymbols instance of Locale.US
char seperator = java.text.DecimalFormatSymbols.getInstance(java.util.Locale.US).getGroupingSeparator();
no = no.replace(String.valueOf(seperator), "");
MAX_VALUE = Double.parseDouble(no);
}
} catch (ParseException ex) {
Utility.logs.log(Level.SEVERE, null, ex);
}
}
就是这样,不需要其他更改。
谢谢。
经过两个小时的谷歌搜索并进行了一些更改之后,我得到了一个更简单的解决方案,只接受点(。)作为JFormattedTextField
小数点分隔符:
JFormattedTextField txtTax = new javax.swing.JFormattedTextField();
txtTax.setFormatterFactory(new DefaultFormatterFactory(new NumberFormatter(new DecimalFormat("#,##0.00", new DecimalFormatSymbols(new Locale("us", "EN"))))));
此解决方案忽略系统locale(ec,ES)
并将组件设置为特定区域设置(us,EN)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.