mfc*_*mfc 2 java javafx javafx-8
我在较大规模的应用程序上遇到了此问题,其中,当source属性的值更改时,某些自定义绑定没有更新。
我设法编写了一个简单的类来复制此问题,但我真的不明白为什么会发生这种情况。这是一个复制该问题的快速测试:
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");
}
}
Run Code Online (Sandbox Code Playgroud)
因此,运行此命令后,我看到:
Run Code Online (Sandbox Code Playgroud)Instantiating TestingBindingsFx... createObjectBinding called createBooleanBinding called Changing selection property values... changed null->Test 1 changed Test 1->Test 2
当我期望看到类似的东西:
Run Code Online (Sandbox Code Playgroud)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工作正常(只需把它放在那里进行核查的目的),它的获取调用每次我改变选择属性的值时。
但是自定义绑定永远不会在第一次之后更新,而查看代码我就无法理解为什么。起初我以为它可能与弱引用有关,但是我什至将绑定对象变成了类级别的变量,但没有变化。
我觉得这里可能遗漏了一些关键的内容,但是在看了两个小时的代码之后,我什至不明白为什么。在我的实际应用程序中,这更奇怪了,因为其中一个自定义绑定实际上可以正常工作。
这是因为JavaFX非常懒惰。
如果依赖项无效,则将绑定设为无效,InvalidationListener并通知s潜在的更改。除非您添加ChangeListener或使用get来检索值,否则将computeValue永远不会使用该方法,因为“没有人想知道新值”。这样可以提高性能。
绑定属性是使用a来完成的,InvalidationListener并且这些属性也会被懒惰地刷新。
您可以例如向属性添加更改侦听器,以在每次绑定无效时强制重新计算值:
private void setupBindings(ObjectProperty<String> selection) {
bindingObj = createObjectBinding(selection);
bindingBool = createBooleanBinding(selection);
objectProperty.bind(bindingObj);
booleanProperty.bind(bindingBool);
objectProperty.addListener((a,b,c)-> {});
booleanProperty.addListener((a,b,c)-> {});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
993 次 |
| 最近记录: |