1

I've created a kind of custom type on a JSF project using PrimeFaces. I'd use this type with PrimeFaces's inputNumber but I get the error:

NumberFormatException class java.lang.NumberFormatException java.lang.NumberFormatException at java.math.BigDecimal.(BigDecimal.java:550) at java.math.BigDecimal.(BigDecimal.java:383) at java.math.BigDecimal.(BigDecimal.java:806) at org.primefaces.component.inputnumber.InputNumberRenderer.formatForPlugin(InputNumberRenderer.java:292) at org.primefaces.component.inputnumber.InputNumberRenderer.encodeScript(InputNumberRenderer.java:231) at org.primefaces.component.inputnumber.InputNumberRenderer.encodeEnd(InputNumberRenderer.java:124)

In short, I've created a class MyCurrency that stores a double and extends ValueExpression, like the following:

public final class MyCurrency extends ValueExpression implements Comparable<MyCurrency>, Serializable {

private Double value;

    private MyCurrency(final Double value) {
        this.value = value;
    }

    public Double getValue() {
        return this.value;
    }

    public Long longValue() {
        return value.longValue();
    }

    @Override
    public int compareTo(final MyCurrency o) {
        return this.getValue().compareTo(o.getValue());
    }

    @Override
    public Object getValue(final ELContext context) {
        return new BigDecimal(this.value);
    }

    @Override
    public void setValue(final ELContext context, final Object value) {
        this.value = new Builder().withValue(value).build().value;
    }

    public static class Builder {

        private Double value;

        public Builder withValue(final Double value) {
            this.value = value;
            return this;
        }

        public Builder withValue(final Long value) {
            this.value = new Double(value);
            return this;
        }

        public Builder withValue(final Object value) {
            this.value = Double.parseDouble(value.toString());
            return this;
        }

        public MyCurrency build() {
            return new MyCurrency(this.value);
        }

    }
}

And in my bean I've a property with type MyCurrency.

When I use it with an inputNumber:

<p:inputNumber id="importoDa" value="#{myBean.myAmount}" />

I get the error [NumberFormatException].

Any help, please?

Alessandro
  • 4,382
  • 8
  • 36
  • 70
  • When `formatForPlugin(String valueToRender, InputNumber inputNumber, Object value)` is invoked while debuging, what is the content of the `valueToRender` variable? It must not contain a "," as decimal seperator [which is what you likely did](https://en.wikipedia.org/wiki/Decimal_separator#Countries_using_decimal_comma). And why do you extend `ValueExpression`? – Selaron Oct 28 '19 at 13:55
  • I cannot find the method `formatForPlugin`, I extend `ValueExpression` 'cause I suppose that PrimeFaces needs a `ValueExpression` to use it in EL. I'm trying to remove it just now... and it seems the is invoking the `toString()` to get its value. – Alessandro Oct 28 '19 at 14:04
  • 3
    `#{myBean.myAmount}` **is** a valueExpression already even if the field `myAmount` is simply of type String, Integer, Double, BigDecimal or whatever. You don't need to extend ValueExpression. – Selaron Oct 28 '19 at 14:08
  • @Selaron how can primefaces know which's the value attribute in the class `MyCurrency`? Thanks. – Alessandro Oct 28 '19 at 14:12
  • 2
    `#{myBean.myAmount.value}` is a valueexpression pointing to the field `value`. – Selaron Oct 28 '19 at 14:52
  • @Selaron That's the point! I wish I could bind directly to my custom object, but I can easily access to the inner object `value` and solve in this way. Thank you. – Alessandro Oct 28 '19 at 15:30
  • You can bind to your custom object, but that is all it should be, a custom object with a normal jsf converter https://stackoverflow.com/questions/8001079/how-create-a-custom-converter-in-jsf-2. Still no need to make it implememt ValueExpression – Kukeltje Oct 30 '19 at 09:35

1 Answers1

3

Not sure if it's a solution for what you are asking, but it seems that you are trying to format the input of your inputNumber as currency an compare it's value to another object. It might be easier to store only the double or BigDecimal value in your bean and format it in the view as currency. You can achieve this using the symbol and decimalPlaces properties of the <p:inputNumber> tag this way:

<p:inputNumber id="importoDa" value="#{myBean.myAmount}" symbol="$" decimalPlaces="2" />

Hope it helps :)

EleazarAG
  • 105
  • 1
  • 6