我知道Java和C#,但属性绑定我只知道C#MVVM。我试图理解JavaFX中的属性绑定,使用属性值的自定义getter和setter(就像在C#中一样)。
我创建了以下类:
public class ViewModel {
private StringProperty name;
public ViewModel() {
name = new SimpleStringProperty();
}
public final String getName() {
return name.get();
}
public final void setName(String name) {
this.name.set(name);
}
public StringProperty getNameProperty() {
return name;
}
}
public class Controller implements Initializable {
@FXML
private TextField nameField;
private final ViewModel viewModel;
public Controller() {
viewModel = new ViewModel();
}
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
Bindings.bindBidirectional(nameField.textProperty(),
viewModel.getNameProperty());
}
}
我的印象是,如果我遵循推荐的JavaBean/JavaFX命名约定,那么绑定系统将足够聪明地使用反射(?)并为该属性使用自定义getter/setter。但是我的视图模型getter/setter从来没有使用过。
name = new SimpleStringProperty() {
@Override public void set(String value) {
// do something...
super.set(value);
}
};
在C#中,这很简单,我只是在setter中设置一个谓词。我可以通过设置其他属性来推动表单/向导的进程。
public String Property {
get { return _property; }
set {
if(SomePredicate(value)) {
_property = value;
_nextButtonCommand.canExecute() = true;
// notify...
}
}
}
public class ViewModel {
private StringProperty name;
public ViewModel() {
// parameters are owning bean, property name, and initial value,
// and are optional for the property convention
name = new SimpleStringProperty(this, "name", "");
}
public final String getName() {
return name.get();
}
public final void setName(String name) {
this.name.set(name);
}
// Note this method name:
public final StringProperty nameProperty() {
return name;
}
}
public class ViewModel {
private StringProperty name = new SimpleStringProperty(this, "name");
// usual JavaFX Property methods...
}
Predicate<String> predicate = ... ;
BooleanBinding canExecute = Bindings.createBooleanBinding(() ->
predicate.test(viewModel.getName()),
viewModel.nameProperty());
Button nextButton = new Button("Next");
nextButton.disableProperty().bind(canExecute.not());
ObjectProperty<Predicate<String>> predicate = new SimpleObjectProperty<>(s -> true);
BooleanBinding canExecute = Bindings.createBooleanBinding(() ->
predicate.get().test(viewModel.getName()),
predicate, viewModel.nameProperty());
通知
可以用属性注册InvalidationListener
或ChangeListener
。AddListener(InvalidationListener)
方法继承自Observable
,并指示上次观察到的值可能不再有效。这允许“惰性计算”可观察项,只在请求新值时计算新值。AddListener(ChangeListener)
方法继承自ObservableValue
,后者(如其名称所示)是显式包装值的可观察性。注册ChangeListener
会强制快速计算,因为监听器会收到新值的通知。虽然API为高性能实现提供了大量的灵活性,但对于我的口味来说,它的粒度有点太细了。
因此,在您的测试应用程序中,您可以
viewModel.nameProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> obs, String oldValue, String newValue) {
System.out.println("Name changed from "+oldValue+" to "+newValue);
}
});
viewModel.nameProperty().addListener((obs, oldName, newName) ->
System.out.println("Name changed from "+oldValue+" to "+newValue));
IntegerProperty x = new SimpleIntegerProperty(2);
IntegerProperty y = new SimpleIntegerProperty(3);
ObservableNumberValue sum = x.add(y);
sum.addListener(obs -> System.out.println("Invalidated")); // invalidation listener
x.set(3);
y.set(5);
sum.addListener((obs, oldSum, newSum) -> System.out.println("Changed"));
主要内容:绑定选项,双向绑定,高级别绑定,低级别绑定,UI控件和域模型之间的绑定JavaFX绑定同步两个值:当依赖变量更改时,其他变量更改。 要将属性绑定到另一个属性,请调用bind()方法,该方法在一个方向绑定值。 例如,当属性A绑定到属性B时,属性B的更改将更新属性A,但不可以反过来。 绑定选项 JavaFX提供了许多绑定选项,以便在域对象和GUI控件中的属性之间进行同步。 我们可以在JavaFX的Properties API中使用以下三种绑定策略: Java Bean上
下面是我的代码:
我在JavaFX的小游戏中工作。我有一个管理音乐的实用类:
我有一个和一个,在hBox中有三个,一个包含文本,另一个包含表中两列的总和。我想为HBox设置一个动态的间距,使两个标签正好在它们所属的表中的两列下方对齐。是否有可能将的间距绑定到列的位置。我也接受任何其他将标签固定在相应列下方的解决方案。下面是一个显示我想要的图像:
我有一个函数,有一系列约束。当然,这些约束必须出现在使用的函数的签名中,所以我试图将约束包装在类型同义词。例如, 会成为 如果所有类型都公开,这将非常有效。但是,我使用函数依赖来生成约束列表中的一些类型,这些类型不会出现在的签名中。例如: GHC不接受,因为在LHS上没有绑定。我也不能使用,因为不在