你能让 TextField<BigDecimal> 同时接受 , 和 .作为小数分隔符?

Posted

技术标签:

【中文标题】你能让 TextField<BigDecimal> 同时接受 , 和 .作为小数分隔符?【英文标题】:Can you make a TextField<BigDecimal> accept both , and . as decimal separator? 【发布时间】:2011-07-11 09:27:22 【问题描述】:

在 Wicket 应用程序中,我有一个十进制数字文本字段:

 TextField<BigDecimal> f = 
     new TextField<BigDecimal>("f", new PropertyModel<BigDecimal>(model, "share"));

我希望它始终接受两者。 (点)和 ,(逗号)作为小数分隔符(不管浏览器的区域设置)。

对于 显示 值,使用会话的语言环境 [在我们的例子中强制为“fi”(-> 逗号)],但这里我对字段 接受作为输入。

我的问题是,我是否必须将字段更改为TextField&lt;String&gt;,并手动转换为域对象的类型(BigDecimal)?或者有什么方法可以使用TextField&lt;BigDecimal&gt;(例如允许使用 Wicket 的 MinimumValidator 或 RangeValidator),并且仍然接受两个小数分隔符?

【问题讨论】:

我现在没有文档,但您可以在应用程序类中全局注册转换器。因此,您可以为 BigDecimal 注册自己的 Converter 实现并在其中接受这两种变体 @bert,谢谢!阅读 Wicket in Action(第 163 页),这可能确实是解决此问题的最佳方法……也可以考虑将其写为答案。 请注意:在某些语言环境中,两个字符可以出现在同一个数字中,即. 用于对千位进行分组,, 作为小数分隔符。如果您想要一个通用数字解析器,请确保您的代码可以处理像 32.519.100,28 这样的数字。 @biziclop:是的,好点。 (在我们的例子中,我们不需要一个通用的解决方案,所以我们可以使用一些更简单的方法,比如我发布的答案。) 【参考方案1】:

感谢@bert 的评论和Wicket in Action 一书,我找到了一种行之有效的方法。在 Application 类中为 BigDecimals 指定一个自定义转换器:

@Override
protected IConverterLocator newConverterLocator() 
    ConverterLocator converterLocator = new ConverterLocator();
    converterLocator.set(BigDecimal.class, new CustomBigDecimalConverter());
    return converterLocator;

在自定义转换器中,convertToObject 需要被覆盖。 NB:这足以满足我们的需求;考虑您的要求并根据需要进行调整!

public class CustomBigDecimalConverter extends BigDecimalConverter 

    @Override
    public BigDecimal convertToObject(String value, Locale locale) 
        // NB: this isn't universal & your mileage problably varies!
        // (Specifically, this breaks if '.' is used as thousands separator)
        if ("fi".equals(locale.getLanguage())) 
            value = value.replace('.', ',');
        
        return super.convertToObject(value, locale);
    

编辑:离题,但我也想记录一下。我们需要我们的应用程序支持小数点后 4 位,而我们的自定义 BigDecimal 转换器也很好地解决了这个问题。

  @Override
    public String convertToString(Object value, Locale locale) 
        NumberFormat fmt = getNumberFormat(locale);
        fmt.setMaximumFractionDigits(4); // By default this is 3.
        return fmt.format(value);
    

在此自定义之后,像 2.0005 这样的十进制数字将显示为 2.0005 而不是 2。

【讨论】:

以上是关于你能让 TextField<BigDecimal> 同时接受 , 和 .作为小数分隔符?的主要内容,如果未能解决你的问题,请参考以下文章

你能让 SwiftUI 从右到左以外的不同方向打开视图吗?

你能让 html 文件在 url 中不显示“.html”吗? [复制]

你能让node js发送一个数组而不是一个字符串吗

你能让 dplyr::mutate 和 dplyr::lag 默认 = 自己的输入值吗?

你能让 Flash URLRequest /web 服务在 IE 中的代理后面工作吗?

面试官你能让我想想吗?我忘记了!