【问题标题】:GWT numberformat weird behaviourGWT numberformat 奇怪的行为
【发布时间】:2013-06-24 19:23:24
【问题描述】:

我有一个语言环境设置为 fr 的 GWT 项目。我有一个自定义文本字段,它使用数字格式来验证和格式化数字输入。

格式化工作正常,但输入验证不行。这是验证新值是否为有效百分比的方法的快照(这称为 onValueChanged):

    private void validateNumber(String newVal){
    logger.debug("value changed, newVal="+newVal+", current="+current);
    // Attempt to parse value
    double val=0;
    try{
        val=Double.parseDouble(newVal);
    }catch(NumberFormatException e){
        logger.warn("parsing failed",e);
        try{
            val=getFormatter().parse(newVal);
        }catch(NumberFormatException ex){
            logger.warn("parsing with nb format failed",ex);
            // on failure: restore previous value
            setValue(current,false);


            return;
        }
    }
      //some check on min and max value here
}

例如,如果程序将起始值设置为“0.2”,它将显示为 20,00%,因此使用了正确的小数分隔符。 现在:

  • 如果我输入 0,1,我会得到一个数字格式异常。
  • 如果我输入 0.1,它会显示为 10,00%
  • 如果我是 10%(在 '%' 之前没有空格),我会得到一个数字格式异常

您知道如何修改方法以将 0,1 和 10% 识别为有效输入吗?

【问题讨论】:

  • getFormatter() 返回的是什么?你为什么使用Double.parse,因为那是在寻找.而不是,,也就是说,它不是特定于语言环境的?
  • getFormatter() 正在返回一个 NumberFormat。最初我只使用 NumberFormat.parse 但有一些例外,我不记得确切的例外措辞,但它类似于“无法解析'0',因为这个数字没有正面或负面的词缀”添加 Double.parse在尝试 NumberFormat.parse 之前解决了这个问题。
  • 对,但是哪个数字格式?如果它是期望的格式,而不是 .你当然会有格式错误。您需要发布足够多的内容才能知道您在做什么,然后人们才能回答您的问题。
  • 在 GWT 中,NumberFormat 是基于加载模块时设置的区域设置。在我的情况下,它是一个 fr_FR(因此它应该期待一个',')
  • 好的,到目前为止一切都很好 - 现在,在您上面显示的代码中,您对百分比做了什么?它是您的测试用例的一部分,我可以解释第一个和第三个问题,但最后一个我不确定它应该如何理解它,也不知道为什么洛瑟案例会发出 % 数字。

标签: gwt internationalization number-formatting


【解决方案1】:

正如 Colin 所提到的,您肯定希望使用 GWT Number Format 对象而不是 Double 来解析和格式化,因此解析和格式化是特定于区域设置的。

下面是一些我可以找到的用于解析、验证和格式化百分比数字的代码 sn-ps。

但请注意,编辑过程在文本框值的外部硬编码了 % 单位,因此在编辑过程中不会在 20,45% 和 0.2045 之间进行转换,直接输入 20,45并如此形象化。我隐约记得在编辑过程中为这种转换而苦苦挣扎,但由于很久以前就忘记了细节。因此,如果它是您的问题和要求的关键部分,那么恐怕下面的示例可能价值有限。不管怎样,他们来了!

符号:

TextBox txt = new TextBox();
NumberFormat _formatFloat = NumberFormat.getFormat("#,##0.00");
NumberFormat _formatPercent = NumberFormat.getFormat("##0.00%");

将诸如“20,45”之类的文本条目解析为 20.45(而不是将“20,45%”解析为 0.2045):

txt.setText("20,45"); // French locale format example, % symbol hard-coded outside of text box.
try {
  float amount = (float) _formatFloat.parse(txt.getText());
} catch (NumberFormatException e) ...

解析和验证文本条目,例如“20,45”:

private class PercentEntryValueChangeHandler implements ValueChangeHandler<String>
{
  @Override
  public void onValueChange(ValueChangeEvent<String> event)
  {
    validatePercent((TextBox) event.getSource());
  }
};

private void validatePercent(final TextBox percentTextBox)
{
  try
  {
    if (!percentTextBox.getText().isEmpty())
    {
      final float val = (float) _formatFloat.parse(percentTextBox.getText());
      if (isValid(val))
        percentTextBox.setText(_formatFloat.format(val));
      else
      {
        percentTextBox.setFocus(true);
        percentTextBox.setText("");
        Window.alert("Please give me a valid value!");
      }
    }
  }
  catch (NumberFormatException e)
  {
    percentTextBox.setFocus(true);
    percentTextBox.setText("");
    Window.alert("Error: entry is not a valid number!");
  }
}

private boolean isValid(float val) { return 12.5 < val && val < 95.5; }

txt.addValueChangeHandler(new PercentEntryValueChangeHandler());

将 20.45 格式化为“20,45”:

float val = 20.45;
txt.setText(_formatFloat.format(val));

将0.2045格式化为“20,45%”(只读过程,文本框不可编辑,%设置在文本框内):

float val = 0.2045;
txt.setText(_formatPercent.format((double)(val))); // * 100 embedded inside format.

它并不花哨,可能远非完美,但它确实有效! 任何有关如何改进此实现的反馈都非常受欢迎和赞赏! 无论如何,我希望它有所帮助。

【讨论】:

  • 抱歉延迟显示一些代码,我没有忘记。我的电脑崩溃了,我在恢复过程中遇到了挑战。我希望能在明天或周三之前掌握我心中的例子。
  • 别担心,感谢您的帮助
  • 我想将 "20.45%" 解析为 0.2045 可能相当简单:预处理字符串,测试 % 符号的存在,然后删除 %,将字符串解析为我显示的常规数字,然后然后除以 100。但我还没有这样做,我的用例是在用户条目之外使用 % 硬编码。
【解决方案2】:

我设法通过将代码更改为以下内容来使其工作:

private void validateNumber(String newVal){
    double val=0;
    try{
        val=getFormatter().parse(newVal);
    }catch(NumberFormatException e){
        boolean ok=false;
        try{
            val=NumberFormat.getDecimalFormat().parse(newVal);
            ok=true;
        }catch(NumberFormatException e1){}
        if(!ok){
            try{
                val=Double.parseDouble(newVal);

            }catch(NumberFormatException ex){
                setValue(current,false);
                // inform user
                Window.alert(Proto2.errors.myTextField_NAN(newVal));
                return;
            }
        }
    }

【讨论】:

    猜你喜欢
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-08
    • 1970-01-01
    • 2011-06-22
    相关资源
    最近更新 更多