2011-12-26 39 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

相關問題