2011-12-26 60 views
1

我已经创建了JFormattedTextField的自定义组件(NumberFormattedTextField)。这是我使用的格式化程序:Java:语言环境是否影响格式化程序的JFormattedTextField

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类代码:

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上提示错误: 无法初始化:对于输入字符串:“99999999,99” ERROR /日志,我得到:

 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类中注意的其他内容。我希望应用能够调整系统设置并相应地显示。

如何解决问题?

+0

kleapatra是正确的。 MAX_VALUE = Double.parseDouble(no); calculateMaxValue()中的行引发异常。在代码中也添加了异常。该字符串有一个有效值而不是“。”。它有“,”十进制分隔符,这也是由于语言环境。所以我想现在的观点应该是“如何将字符串解析为这种语言环境的双倍”。任何想法,建议... – Tvd 2011-12-27 06:01:17

回答

1

得到了解决:

我特别获取了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); 
    } 
} 

就是这样,要求没有其他变化。

谢谢。

+0

更好的问题+1 – mKorbel 2011-12-27 08:00:31

4

最有可能(不能完全确定,因为您不显示初始设置并将错误仅限于其消息;-)不同的Locale是原因:一个以小数点为周期,另一个以小数点为周期有逗号。所以,如果你初始化一个与代表其他的数字的字符串,就会发生冲突:逗号不被解释为一个小数点,所以max是太大,无法限制

+0

“初始设置” - 我认为你指的是NumberFormattedTextField的初始化。添加了该类的构造函数和更多代码。我同意你的小数点分隔符。如何处理这与不同的语言环境?这可以用于setMaximum(999999999.99);也行。对于代表数字的字符串,我使用DecimalSymbols进行分隔符 - 所以这不会为我提供缺省语言环境的分隔符吗? – Tvd 2011-12-27 05:23:08

+0

是的你是对的。MAX_VALUE = Double.parseDouble(no); calculateMaxValue()中的行引发异常。在代码中也添加了异常。该字符串具有一个有效值而不是“。”。它有“,”十进制分隔符,这也是由于语言环境。所以我想现在的观点应该是“如何将字符串解析为这种语言环境的双倍”。任何想法,建议... – Tvd 2011-12-27 06:00:02

0

2小时谷歌搜索,并做一些改变后,我得到一个简单的解决方案,只接受点作为小数点分隔符的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),并设置组件一个特定的区域(我们,EN)

+0

感谢您的努力。在我的解决方案中,我使用DecimalFormatsymbols和US Locale来设置我的格式化程序。 – Tvd 2012-01-13 06:05:08