2016-02-16 37 views
0

我目前正在使用Sencha GXT库的GWT项目。我目前正在尝试使用自定义货币格式创建CurrencyField。以下是我想要的自定义货币格式的一些示例:Sencha GXT输入字段的自定义货币格式

€ 123,45 
€ 98.765.432,10 
€ 400,00 

因此,正如您所看到的,我想要一个前缀euro-sign;货币符号和小数之间的空格;一千个分离器的点;和小数点的逗号(当然还有逗号后面的两个小数点)。

但是在GXT中,似乎无法创建自己的自定义格式。 我知道与普通java.text.NumberFormat我可以做这样的事情:但是

NumberFormat format = NumberFormat.getCurrencyInstance(); 
DecimalFormatSymbols formatSymbols = new DecimalFormatSymbols(); 
formatSymbols.setCurrencySymbol("€"); 
formatSymbols.setGroupingSeparator('.'); 
formatSymbols.setMonetaryDecimalSeparator(','); 
((DecimalFormat)format).setDecimalFormatSymbols(formatSymbols); 

在GXT,在com.google.gwt.i18n.client.NumberFormat必须用于NumberField<BigDecimal>setFormat - 方法。我知道一些定制可以与CurrencyData像这样使用:

private CurrencyData createCurrencyData() { 
    // CurrencyData docs: http://www.gwtproject.org/javadoc/latest/com/google/gwt/i18n/client/CurrencyData.html 
    return new CurrencyData() { 

    @Override 
    public String getCurrencySymbol() { 
     return "€"; 
    } 

    @Override 
    public String getSimpleCurrencySymbol() { 
     return "€"; 
    } 

    @Override 
    public String getPortableCurrencySymbol() { 
     return "€"; 
    } 

    @Override 
    public String getCurrencyCode() { 
     return "EUR"; // ISO4217 for this currency 
    } 

    @Override 
    public int getDefaultFractionDigits() { 
     return 2; // Amount of decimal positions 
    } 

    @Override 
    public boolean isSymbolPrefix() { 
     return true; // true to place currency symbol before the decimal 
    } 

    @Override 
    public boolean isSymbolPositionFixed() { 
     return true; // true to use the same currency symbol position regardless of locale (determined by the isSymbolPrefix-method) 
    } 

    @Override 
    public boolean isSpacingFixed() { 
     return true; // true to put a space between the currency symbol and the decimal 
    } 

    @Override 
    public boolean isSpaceForced() { 
     return true; // true to use the same spacing regardless of locale (determined by the isSpacingFixed-method) 
    } 

    @Override 
    public boolean isDeprecated() { 
     return false; 
    } 
    }; 
} 

我现在使用的是这样的:但是

NumberField<BigDecimal> currencyField = new NumberField<BigDecimal>(
    new NumberPropertyEditor.BigDecimalPropertyEditor()); 
currencyField.setFormat(NumberFormat.getCurrencyFormat(createCurrencyData())); 

两个问题:

  1. 它不完全定制我怎么想要它。它现在接受像这样的输入:€123,456.78;而不是€ 123.456,78(也,即使CurrencyData#isSpacingForced显然应该使用的货币符号和十进制之间的空间,它不会对NumberField工作..)
  2. 当我只需键入一个普通数字像400,它给出了一个错误,而不是自动格式化用户输入:400 does not have either positive or negative affixes is not a valid number

回答

0

变化,我们提出:

我们现在放置在荷兰的语言环境中我们.gwt.xml文件:

<extend-property name="locale" values="nl_NL"/> 
<set-property name="locale" value="nl_NL"/> 
<set-property-fallback name="locale" value="nl_NL"/> 

而且我们使用自定义格式是这样的:

final BigDecimalField currencyField = new BigDecimalField(); 
currencyField.setFormat(CustomNumberFormat.getCurrencyFormat()); 

随着CustomNumberFormat-class像这样:

import java.util.Map; 

import com.google.gwt.core.client.GWT; 
import com.google.gwt.i18n.client.CurrencyData; 
import com.google.gwt.i18n.client.CurrencyList; 
import com.google.gwt.i18n.client.NumberFormat; 
import com.google.gwt.i18n.client.constants.CurrencyCodeMapConstants; 

public class CustomNumberFormat extends NumberFormat { 

    private static CurrencyCodeMapConstants currencyCodeMapConstants = GWT.create(CurrencyCodeMapConstants.class); 
    private static char currencySymbol; 
    private static NumberFormat cachedCurrencyFormat; 

    /** 
    * Get the default currency format 
    * @return the default currency format 
    */ 
    public static NumberFormat getCurrencyFormat() { 
    if (cachedCurrencyFormat == null) { 
     cachedCurrencyFormat = getCurrencyFormat(CurrencyList.get().getDefault().getCurrencyCode()); 
    } 
    return cachedCurrencyFormat; 
    } 

    /** 
    * Get the currency format 
    * @param currencyCode the code to use 
    * @return the {@link NumberFormat} to use 
    */ 
    public static NumberFormat getCurrencyFormat(final String currencyCode) { 
    return new CustomNumberFormat(defaultNumberConstants.currencyPattern(), lookupCurrency(currencyCode), false, true); 
    } 

    /** 
    * Lookup the currency data 
    * @param currencyCode the currency code e.g. EUR 
    * @return the {@link CurrencyData} 
    */ 
    private static CurrencyData lookupCurrency(final String currencyCode) { 
    final CurrencyData currencyData = CurrencyList.get().lookup(currencyCode); 

    final Map<String, String> currencyMap = currencyCodeMapConstants.currencyMap(); 

    final String code = currencyData.getCurrencyCode(); 
    final String symbol = currencyMap.get(currencyCode); 
    final int fractionDigits = currencyData.getDefaultFractionDigits(); 
    final String portableSymbol = currencyData.getPortableCurrencySymbol(); 
    return toCurrencyData(code, symbol, fractionDigits, portableSymbol); 
    } 

    /** 
    * 
    * @param code the currency code e.g. EUR 
    * @param symbol the currency symbol e.g. the euro sign 
    * @param fractionDigits the number of fraction digits 
    * @param portableSymbol the portable symbol 
    * @return the {@link CurrencyData} to use 
    */ 
    public static native CurrencyData toCurrencyData(String code, String symbol, int fractionDigits, 
     String portableSymbol) /*-{ 
          //CHECKSTYLE:OFF 
          return [ code, symbol, fractionDigits, portableSymbol ]; 
          //CHECKSTYLE:ON 
          }-*/; 

    private boolean currencyFormat = false; 

    /** 
    * 
    * @param pattern the currency pattern 
    * @param cdata the {@link CurrencyData} 
    * @param userSuppliedPattern <code>true</code> if the pattern is supplied by the user 
    */ 
    protected CustomNumberFormat(final String pattern, final CurrencyData cdata, final boolean userSuppliedPattern, 
     final boolean currencyFormat) { 
    super(pattern, cdata, userSuppliedPattern); 
    this.currencyFormat = currencyFormat; 
    } 

    /* (non-Javadoc) 
    * @see com.google.gwt.i18n.client.NumberFormat#format(boolean, java.lang.StringBuilder, int) 
    */ 
    @Override 
    protected void format(final boolean isNegative, final StringBuilder digits, final int scale) { 
    super.format(isNegative, digits, scale); 
    if (this.currencyFormat) { 
     final char decimalSeparator = defaultNumberConstants.monetarySeparator().charAt(0); 
     if (digits.toString().endsWith(decimalSeparator + "00")) { 
     digits.delete(digits.length() - 3, digits.length()); 
     } 
     if (isNegative) { 
     digits.delete(digits.length() - 1, digits.length()); // Delete leading "-" 
     digits.insert(0, "- "); // Insert "- " at the front 
     } 
    } 
    } 

    /** 
    * Parse a String. The String does not start with the expected prefix so we add it first 
    * @param text the text to parse 
    * @param inOutPos an offset telling us 
    * @return the parsed value 
    * @throws NumberFormatException if the text cannot be parsed 
    */ 
    @Override 
    public double parse(final String text, final int[] inOutPos) throws NumberFormatException { 
    //add the positive prefix (euro-sign plus space) 
    final String temp = getPositivePrefix() + text; 
    //parse the adjusted string 
    final double val = super.parse(temp, inOutPos); 
    //now here is the tricky bit... during parsing the inOutPos offset was updated based on the modified String 
    //but a check is maded to see if the resulting offset is equal to the length of the String we have been passed 
    //so we need to update inOutPos by removing the length of the positive prefix 
    inOutPos[0] -= getPositivePrefix().length(); 
    return val; 
    } 
} 

现在我们得到了以下结果:

€ 123,45      when entering 123,45 
€ 98.765.432,10    when entering 98765432,1 
- € 400,00     when entering -400