ソースプロパティの値が変更されたときにカスタムバインディングが更新されていない大規模アプリケーションでこの問題が発生しました。JavaFXのカスタムバインディングが機能しない
私はこの問題を再現するためにシンプルなクラスを書くことができましたが、なぜこれが起こるのか分かりません。
がimport javafx.beans.binding.BooleanBinding;
import javafx.beans.binding.ObjectBinding;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
public class TestingBindingsFx {
private final ObjectProperty<MyEvent> objectProperty = new SimpleObjectProperty<MyEvent>(this, "objectProperty");
private final BooleanProperty booleanProperty = new SimpleBooleanProperty(this, "booleanProperty");
private ObjectBinding<MyEvent> bindingObj;
private BooleanBinding bindingBool;
public TestingBindingsFx(ObjectProperty<String> selection) {
setupBindings(selection);
}
private void setupBindings(ObjectProperty<String> selection) {
bindingObj = createObjectBinding(selection);
bindingBool = createBooleanBinding(selection);
objectProperty.bind(bindingObj);
booleanProperty.bind(bindingBool);
}
private static ObjectBinding<MyEvent> createObjectBinding(ObjectProperty<String> selection) {
return new ObjectBinding<MyEvent>() {
{
super.bind(selection);
}
@Override
protected MyEvent computeValue() {
System.out.println("createObjectBinding called");
MyEvent ve = selection.get() == null ? MyEvent.EVENT1
: MyEvent.EVENT2;
return ve;
}
};
}
private static BooleanBinding createBooleanBinding(ObjectProperty<String> selection) {
return new BooleanBinding() {
{
super.bind(selection);
}
@Override
protected boolean computeValue() {
System.out.println("createBooleanBinding called");
return selection.get() == null ? true : false;
}
};
}
public static void main(String[] args) {
ObjClass objclass = new ObjClass();
System.out.println("Instantiating TestingBindingsFx...");
TestingBindingsFx fx = new TestingBindingsFx(objclass.selection);
objclass.selection.addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
System.out.println("changed " + oldValue + "->" + newValue);
}
});
System.out.println("Changing selection property values...");
objclass.selection.set("Test 1");
objclass.selection.set("Test 2");
}
enum MyEvent {
EVENT1,
EVENT2;
}
static class ObjClass {
public final ObjectProperty<String> selection = new SimpleObjectProperty<String>(this, "selection");
}
}
だから、これを実行した後、私は以下を参照してください:ここでは、問題を複製し、簡単なテストです
:私はのようなものを見ることが予想Instantiating TestingBindingsFx... createObjectBinding called createBooleanBinding called Changing selection property values... changed null->Test 1 createObjectBinding called createBooleanBinding called changed Test 1->Test 2 createObjectBinding called createBooleanBinding called
Instantiating TestingBindingsFx... createObjectBinding called createBooleanBinding called Changing selection property values... changed null->Test 1 changed Test 1->Test 2
ChangeListener
は期待通りに動作しています(検証のためにそこに置いてください)。これはselectionプロパティの値を変更するたびに呼び出されます。
しかし、カスタムバインディングは初めて初めて更新され、コードを見るとわかりません。理由はわかりません。最初は弱い参照に関連すると思っていましたが、バインディングオブジェクトをクラスレベル変数に変更しても変更はありませんでした。
私はここで何かが欠けているかもしれないと感じますが、このコードを見て2時間後、私はなぜそれが見えません。 私の実際のアプリケーションでは、カスタムバインディングの1つが実際にうまく動作するので、さらに奇妙です。
ビンゴ、それでした!私は単純なものが欠けていることを知っていました。私はcomputeValueに集中していましたので、バインディングの遅延の性質を完全に忘れていました。再計算を強制する必要はありません。遅延は完全にうまくいきます。ソースプロパティ値を変更した後、テストコードでターゲットプロパティを読み直すだけでは足りませんでした。迅速な答えをありがとう。 – mfc