2012-11-07 38 views
2

我有一個具有表單的vaadin應用程序,並且我使用一個beanitem作爲數據源。 裏面的寶石,我有一個浮點值,默認爲0.0 .. 如果我輸入一個像123123123這樣的高值並提交(它保存到一個數據庫),當我嘗試編輯表單內的字段時,我得到1.23123123E9作爲值,爲什麼呢? 當我編輯我仍然傳遞的數據在它的beanitem,爲什麼不顯示我的值正確的文本框內?vaadin表單浮動字段

我知道如果我必須顯示我可以使用的值decimal format但這是在表單內,並且vaadin知道它是一個浮點數,所以它應該相應地處理它嗎? 或者我必須格式化它自己的表單字段工廠內?

PS:你如何設置窗體內的值的顯示模式?我讀過你可以實現bean內部字段的獲取,並讓它返回一個字符串,是否是正確的方法來做到這一點?

回答

6

其實Vaadin行爲正確,但它遵循幅度規則(已被約根德拉·辛格提到的),請看到一個example

enter image description here

也請檢查以下內容:

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 1: 12.0 
result 2: 1.2312312E8 

所以正確的解決方案(如我所見)如下所示:

  1. 定義您自己的Bean。沒有理由讓BeanItem包裝一個浮點值。
  2. 定義您的PropertyFormatter(example
  3. 重要的是要注意,一個不應該返回一個字符串,而不是正確的數據類型。它會影響編輯,驗證等

PropertyFormatter例如:

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

它可能看起來有點嚇人,但這是靈活性爲代價的。自定義Bean允許使用表格視圖,表單等,而不做任何重大更改。基本上,這是Vaadin UI背後的數據模型。

enter image description here

Chapter 9. Binding Components to Data

定製Bean的實例:

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

只需提供所有需要的見解:

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

會打印:

Property: 'name' value: Test 
Property: 'value' value: 12.0 
+0

這是一個很棒的洞察力,它幫助我完全理解我的問題。我已經使用了一個bean,並且這個bean裏面有了float。 – sokie

1

toString()內部調用toString(float)這是文件說什麼toString(float)

否則,結果是表示參數符號和幅度(絕對值)的字符串。如果符號是負數,結果的第一個字符是' - '('\ u002D');如果符號爲正,則結果中不會出現符號字符。至於數值m:

  • 如果m大於或等於10 -3但小於107,則其被表示爲m的整數部分,小數形式沒有前導零,隨後'' ('\ u002E'),後跟一個或多個小數位,代表m的小數部分。

  • 如果m小於10-3或大於或等於107,則設n爲唯一整數,使得10n≤m<10n+ 1;那麼令a爲m和10n的數學精確商,以便1≤a< 10.然後將幅度表示爲a的整數部分,作爲單個十進制數字,後跟'。'。 ('\ u002E'),後跟十進制數字,表示a的小數部分,後跟字母'E'('\ u0045'),後面跟着n表示十進制整數,如方法Integer所產生的。的toString(INT)。

要創建浮點值的本地化字符串表示,NumberFormat的使用子類。

希望這有助於你瞭解WHYHOW修復它,即使用DecimalFormat,你有你的領域工廠裏面提到,返回爲顯示目的字符串表示。

+0

問題出在表單裏,字段從數據源中獲取它們的值,那就是這個beanitem。爲什麼它在那裏顯示錯誤的值,以及可以做什麼?一個無意的用戶可以再次單擊提交,它會在表單右側提交一個錯誤的值? – sokie

+0

@sokie:是什麼讓你說價值是錯的?這聽起來像是顯示了正確的價值,而不是你想要的格式。 (說過了,'float'確實*是錯誤的數據類型,如果你打算使用9位數字......) –

+0

@JonSkeet我的意思是它顯示錯誤的方式,我道歉,不知道在哪裏鉤住一個toString覆蓋以更好地顯示浮點格式是更好的方法。一個自定義的浮動類可以覆蓋toString也許我希望在表單內部有東西。還有就像toString顯示的那樣,該號碼沒有數字,但它有點長,例如12345678.0。我明白了爲什麼它顯示錯誤,我想知道什麼是最好的行動在這裏 – sokie