GWT数字格式怪异行为

GWT数字格式怪异行为,gwt,internationalization,number-formatting,Gwt,Internationalization,Number Formatting,我有一个GWT项目,其语言环境设置为fr。我有一个自定义文本字段,它使用数字格式来验证和格式化数字输入 格式化工作正常,但输入验证无效。下面是验证新值是否为有效百分比(称为onValueChanged)的方法的快照: 例如,如果程序将起始值设置为“0.2”,它将显示为20,00%,因此使用正确的十进制分隔符。 现在: 如果我输入0,1,我会得到一个numberformat异常 如果输入0.1,则显示为10,00% 如果输入10%(在“%”之前没有空格),则会得到numberformat异常

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

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

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

  • 如果我输入0,1,我会得到一个numberformat异常
  • 如果输入0.1,则显示为10,00%
  • 如果输入10%(在“%”之前没有空格),则会得到numberformat异常

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

正如Colin提到的,您肯定希望使用GWT Number format对象(而不是双精度对象)进行解析和格式化,因此解析和格式化是特定于语言环境的

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

注意:但是,编辑过程在文本框值之外硬编码了%单位,因此在编辑过程中,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):

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

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

这不是花哨的,可能还远远不够完美,但它很管用! 我们非常欢迎并感谢任何关于如何改进此实施的反馈!
不管怎样,我希望它能有所帮助。

我将代码更改为以下内容,从而使其正常工作:

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;
            }
        }
    }

什么是
getFormatter()
返回的?为什么要使用
Double.parse
,因为它是在寻找
而不是
,即它不是特定于语言环境的?getFormatter()正在返回一个数字格式。最初我只使用NumberFormat.parse,但遇到了一些异常,我不记得确切的异常措辞,但类似于“无法解析'0',因为这个数字没有正反词缀”在尝试NumberFormat.parse之前添加Double.parse解决了这个问题。对,但哪种数字格式?如果它是一种预期的格式,而不是。当然,你会有格式错误。在人们回答你的问题之前,你需要发布足够多的帖子,以便能够知道你在做什么。在GWT中,NumberFormat基于加载模块时设置的区域设置。在我的例子中,它是一个fr_fr(因此它应该是一个“,”),好的,到目前为止还不错-现在,在你上面展示的代码中,你用百分比做了什么?这是您的测试用例的一部分,我可以解释第一个和第三个问题,但最后一个问题我不确定它应该如何理解,也不确定为什么lother用例会发出%number。很抱歉延迟显示一些代码,我没有忘记。我的电脑死机了,我经历了恢复的挑战。我希望在明天或周三之前掌握好我想要的示例。不用担心,我很感谢您的帮助。我想将“20.45%”解析为0.2045可能相当简单:预处理字符串,测试%symbol是否存在,然后删除%,将字符串解析为我显示的常规数字,然后除以100。但我还没有这样做,我的用例是在用户条目之外用%硬编码的。
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) ...
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());
float val = 20.45;
txt.setText(_formatFloat.format(val));
float val = 0.2045;
txt.setText(_formatPercent.format((double)(val))); // * 100 embedded inside format.
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;
            }
        }
    }