我在更大規模的應用程序中遇到了此問題,其中某些自定義綁定在源屬性的值更改時未更新。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 changed Test 1->Test 2
當我期望看到像這樣:
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
ChangeListener
按預期工作(僅用於驗證目的),每次更改選擇屬性的值時都會調用它。
但是,自定義綁定永遠不會在第一次後更新,看着代碼,我不明白爲什麼。起初我認爲它可能與弱引用有關,但我甚至將綁定對象轉換爲類級變量,但沒有改變。
我覺得我可能會在這裏失去一些至關重要的東西,但在查看這段代碼2個小時後,我只是看不出爲什麼。 在我的實際應用程序中,它更加奇怪,因爲其中一個自定義綁定實際上可以正常工作。
賓果,就是這樣!我知道我錯過了一些簡單的東西,我非常專注於不被稱爲的computeValue,它完全忘記了綁定的懶惰性質。我不需要強制重新計算,懶惰是完全正常的,我只是簡單地缺少在更改源屬性值後重新讀取測試代碼中的目標屬性。感謝你及時的答覆。 – mfc