2

フォームのあるvaadinアプリケーションがあり、データソースとしてbeanitemを使用しています。Beanitem内には、デフォルトで0.0のfloat値があります。123123123のような高い値を入力してcommit(dbに保存)すると、フォーム内のそのフィールドを編集しようとすると、値として1.23123123E9が取得されます。なぜ?編集しても、データが含まれているBeanitemを渡しますが、テキストフィールド内に値が正しく表示されないのはなぜですか?

10進形式を使用できる値を表示する必要があるかどうかはわかっていますが、これはフォーム内にあり、vaadinはそれが浮動小数点数であることを認識しているため、それに応じて処理する必要がありますか?または、フォームフィールドファクトリ内で自分でフォーマットする必要がありますか?

PS:フォーム内の値の表示モードをどのように設定できますか?Bean内のフィールドの取得を実装し、文字列も返すようにすることができると読みましたが、それは正しい方法ですか?

4

2 に答える 2

6

実際、Vaadin は正しく動作しますが、マグニチュード ルールに従います (既に Yogendra Singh によって言及されています)例を参照してください

ここに画像の説明を入力

以下もご確認ください。

    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 を定義します。float 値をラップする BeanItem を持つ理由はありません。
  2. PropertyFormatter を定義します ()
  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 の背後にあるデータ モデルです。

ここに画像の説明を入力

第9章 データへのコンポーネントのバインド

カスタム 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
于 2012-11-12T12:36:22.537 に答える
1

toString()内部的にtoString(float)を呼び出しますtoString(float)

それ以外の場合、結果は引数の符号と大きさ (絶対値) を表す文字列になります。符号が負の場合、結果の最初の文字は '-' ('\u002D') です。符号が正の場合、符号文字は結果に表示されません。マグニチュード m については:

  • m が 10-3 以上で 107 未満の場合、m の整数部分として、先行ゼロなしの 10 進数形式で表され、その後に「.」が続きます。('\u002E') の後に、m の小数部を表す 1 つ以上の 10 進数が続きます。

  • m が 10-3 未満または 107 以上の場合、 ** n を 10n ≤ m < 10n+1 となる一意の整数とする。次に、a を m と 10n の数学的に正確な商とし、1 ≤ a < 10 とします。大きさは、a の整数部分として、単一の 10 進数として表され、その後に「.」が続きます。('\u002E')、その後に a の小数部を表す 10 進数、その後に文字 'E' ('\u0045') が続き、その後にメソッド Integer によって生成される 10 進整数としての n の表現が続きます。 toString(int)。

浮動小数点値のローカライズされた文字列表現を作成するには、NumberFormat のサブクラスを使用します。

WHYこれが理解しHOWて修正するのに役立つことを願っています。つまりDecimalFormat、フィールドファクトリ内で言及したように使用し、表示目的で文字列表現として返します。

于 2012-11-07T16:51:19.593 に答える