Reputation: 1986
I have a vaadin application that has a form,and i use a beanitem as a data source. Inside the beanitem i have a float value that defaults to 0.0.. If i enter a high value like 123123123 and commit(it saves to a db),when i try to edit that field inside the form i get 1.23123123E9 as a value,why? When i edit i still pass the beanitem with the data in it,why doesn't it show my value correctly inside the textfield?
I know if i must display the value i can use decimal format but this is inside the form,and vaadin knows it is a float,so it should handle it accordingly right? Or must i format it inside the form field factory myself?
PS:How can you set a display mode for the values inside the form?I have read you could implement the get of the field inside the bean and have it return a string too,is that the right way to do it?
Upvotes: 2
Views: 3157
Reputation: 17895
Actually Vaadin behaves correctly, but it follows the magnitude rules (already mentioned by Yogendra Singh) please see an example
Please also check the following:
float value1 = 12.0f;
float value2 = 123123123;
BeanItem<Float> item1 = new BeanItem<Float>(value1);
BeanItem<Float> item2 = new BeanItem<Float>(value2);
System.out.println(" result 1: " + item1.getBean());
System.out.println(" result 2: " + item2.getBean());
Result:
result 1: 12.0
result 2: 1.2312312E8
So the correct solution (as I can see it) looks like the following:
PropertyFormatter example:
/** Integer formatter that accepts empty values. */
public class LenientIntegerFormatter extends PropertyFormatter {
public LenientIntegerFormatter(Property propertyDataSource) {
setPropertyDataSource(propertyDataSource);
}
@Override
public Object parse(String formattedValue) throws Exception {
if ("".equals(formattedValue))
return null;
else
return Integer.valueOf(formattedValue);
}
@Override
public String format(Object value) {
if (value == null)
return "";
return ((Integer) value).toString();
}
@Override
public Class<?> getType() {
return String.class;
}
}
It may look a little bit scary, but this is the cost of flexibility. Custom Bean allows to use table view, forms, etc without any significant changes. Basically, this is the data model behind Vaadin UI.
Chapter 9. Binding Components to Data
Custom Bean example:
public class Bean implements Serializable {
String name;
float value;
public Bean(String name, float newValue) {
this.name = name;
this.value = newValue;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getValue() {
return value;
}
public void setValue(float newValue) {
this.value = newValue;
}
}
Just to provide all required insights:
Bean bean = new Bean("Test", value1);
BeanItem<Bean> beanItem = new BeanItem<Bean>(bean);
for(Object propertyId: beanItem.getItemPropertyIds()) {
System.out.println(" Property: '" + propertyId +
"' value: " + beanItem.getItemProperty(propertyId));
}
Will print:
Property: 'name' value: Test
Property: 'value' value: 12.0
Upvotes: 6
Reputation: 34367
toString()
internally calls toString(float) This is what the documentation says for toString(float)
Otherwise, the result is a string that represents the sign and magnitude (absolute value) of the argument. If the sign is negative, the first character of the result is '-' ('\u002D'); if the sign is positive, no sign character appears in the result. As for the magnitude m:
If m is greater than or equal to 10-3 but less than 107, then it is represented as the integer part of m, in decimal form with no leading zeroes, followed by '.' ('\u002E'), followed by one or more decimal digits representing the fractional part of m.
If m is less than 10-3 or greater than or equal to 107, ** Let n be the unique integer such that 10n ≤ m < 10n+1; then let a be the mathematically exact quotient of m and 10n so that 1 ≤ a < 10. The magnitude is then represented as the integer part of a, as a single decimal digit, followed by '.' ('\u002E'), followed by decimal digits representing the fractional part of a, followed by the letter 'E' ('\u0045'), followed by a representation of n as a decimal integer, as produced by the method Integer.toString(int).
To create localized string representations of a floating-point value, use subclasses of NumberFormat.
Hope this helps you understand WHY
and HOW
to fix it i.e. use DecimalFormat
as you have mentioned inside your field factory and return as string representation for display purpose.
Upvotes: 1