2013-07-11 3 views
6

javafxプロパティの値を特定の範囲内に保つ最良の方法は何ですか?javafxプロパティにはどの値が決まりますか?

から

例1(またはJavaFXのプロパティで包まれた値をフィルタしないように何らかの理由を、既存の、この悪い習慣ですか?):IntegerProperty
例2の負の値を避ける:内IntegerPropertyの値を保ちますリストの境界

最初のアイデア: - オーバーライドIntegerPropertyBase.set(int)。安全です?実際にはsetValue(int)set(int)しか呼び出しませんが、この実装が1日変わった場合、値セットの制御が失われます。

第2のアイデア: - オーバーライドIntegerPropertyBase.invalidate()。しかし、この時点ですでに価値が設定されていました。

IllegalArgumentException(またはラップされた値が配列のインデックスである場合はArrayIndexOutOfBoundsException)を投げた方がjavafxプロパティに適しているでしょうか、範囲外の値を拒否した方がよいでしょうか?たぶん、このような

class BoundedIntegerProperty extends IntegerPropertyBase { 
     (...) 
     int oldValue = defaultValueInBounds; 
     boolean settingOldValue = false; 
     public void invalidated() { 
      if(!settingOldValue){ 
       if(outOfBounds(get())){ 
        settingOldValue = true; 
        set(oldValue); 
       } else { 
        oldValue = get(); 
       } 
      } else 
       settingOldValue = false; 
     } 
    } 

のみ(無効化で例外を投げる)範囲外の値については、範囲外のプロパティの値を保持することができます。

値をフィルタリングするために提供されるjavafxプロパティで何かを見落としましたか?両方のあなたの例では

(必要であれば、...私はこのテキストの可能性の悪い英語を向上助けてください)

+1

プロパティを設定する前に入力を検証する方が簡単かもしれません。テキストフィールド、DB結果、またはデータをファイルから検証します。私はこれを扱う良い方法が見当たりません。実際に#set()を呼び出して例外をスローしたいですか? –

+0

あなたは本当です。たとえば、このリストにアクセスできないリストのインデックスを設定するのは意味がありません。しかし、私はリストにアクセスする場合、インデックスのプロパティのためのセッターは、リスト自体にある可能性があり、プロパティは読み取り専用です。リストでは、インデックスが境界外の場合、インデックスの設定者は例外をスローすることがあります。 –

答えて

2

、例えば(論理デフォルト値があるように思えた。それが正であることが必要だ場合負の数は0に変わります)。もしあなたがそれをうまく書いていると仮定すると(値が無効な場合のデフォルトは何ですか?)、私はあなたの最初のアプローチが正しい方向にあるように思えます。

あなたの代わりにIntegerPropertyBaseを選んだいくつかの理由がありますしない限り、私はあなたが拡張しているクラス(などSimpleIntegerPropertyのような具象クラスで始まるお勧めします。

を私はその後set(int)方法とsetValue(Number)法、ラッピングの両方を上書きします。あなたのロジックで親:

/** 
    * Explanation that values under 0 are set to 0 
    */ 
    @Override 
    public void set(int value){ 
     super.set(value > 0 ? value : 0); 
    } 

    /** 
    * Explanation that values under 0 are set to 0 
    */ 
    @Override 
    public void setValue(Number value){ 
     super.setValue(value.intValue() > 0 ? value : 0); 
    } 

が論理既定値ではない(またはあなただけの無効な値を拒否したい)場合があるかもしれません、その場合には、それは少し難しくなります - あなたが実際にしたいと思いますこのようなメソッドシグネチャを使用すると、c値が変更された場合Allerのは知っている:

public boolean set(int value) 

そのためには、あなたはかなりの数のクラス戻らなければならないでしょう - 自分で構造を無効/バックReadOnlyIntegerPropertyにすべての方法を、設定を実装します。

私は、無効な入力を処理するために例外を使用することを躊躇します。それは例外の正当な使用ですが、私の恐れは例外が検証のために頼られるということです。例外は非常にリソース集中型であり、修正が必要なものがあればヒットする必要があります。だからあなたの意図と、あなたのクラスを使って正しいことをする(そして送信する前に検証する)人がどれほど信頼できるかについてです。

+0

もちろん:入力が違法である可能性がある場合は、入力が不正であるかどうかを調べるブール関数が必要です。これはJavafxのプロパティには含まれていません。 –

1

私は今あなたがより良く撮影していることを理解していると思います。ユーザー入力の検証を実行しようとしています。

あなたはユーザー検証をやっている、それに近づくには、2つの方法が本当にあります:

  1. 検証し、直ちに変更が行われ、フォーカスが入力エリアを離れるとき フィードバック
  2. 検証を提供した後

プロパティリスナーを使用することになります。これは、あなたが扱っているプロパティリスナーの問題です。あなたが確認しているプロパティに直接聞いてよ最初のケースでは

TextField field = new TextField(); 
    field.textProperty().addListener(new ChangeListener<String>(){ 
     @Override 
     public void changed(ObservableValue<? extends String> value, 
       String oldValue, String newValue) { 
       //Do your validation or revert the value 
     }}); 

第2のケースでは、あなたはfocusedプロパティに耳を傾けるだろう、とフォーカスが失われたとき(あなたを検証します)必要に応じて値を戻すために、このリスナーの最後の検証値を維持することができます。

TextField field = new TextField(); 
    field.focusedProperty().addListener(new ChangeListener<Boolean>(){ 
     String lastValidatedValue = ""; 
     @Override 
     public void changed(ObservableValue<? extends Boolean> value, 
       Boolean oldValue, Boolean newValue) { 
      if(newValue == false && oldValue == true){ 
       //Do your validation and set `lastValidatedValue` if valid 
      } 
     }}); 

注: を私はあなただけのシステムCのためにフェールセーフに入れたかったと仮定しました。 UIを更新する。私はそれが有用な情報を提供すると信じて私の前の答えを残します。

+0

検証がfalseを返し、プロパティを 'oldValue'に戻すと、検証は古い値を「new」として再開します。 'oldValue'のバリデーションがfalseを返す場合(検証リスナーが追加される前にPropertyに含まれる値かもしれません)、ループに入ります。この場合、古い値に戻す前に 'oldValue'を検証する方が安全です。 –

関連する問題