作为一名十年的Swing开发人员,我对JavaFX 2.0引入的功能感到非常兴奋,特别是丰富,流畅,高级的数据绑定工具。仅此设施值得学习新API的成本(自放弃FX脚本以来,这个成本要少得多)。它将对我的模型/视图同步代码的可读性和可维护性产生直接影响。
到目前为止,我在第一级和基本派生绑定方面取得了巨大成功,但我正在努力找出将一个值绑定到数据图中两个或更多个间接值的“JavaFX方式”。
如下面的代码示例所示,我正在尝试使用javafx.beans.binding.Bindings.select()
将Label的文本值与ComboBox中当前所选项的一个包含属性同步。这段代码是我想要做的更复杂的一个简单例子,所以我理解用较低级别的绑定API做这件事并不难。我想知道是否可以使用更高级别的流畅API,以及select(...)
方法是否实际跟踪间接属性的更改(即直接属性或所选子属性更改时更新属性)。 / p>
select(...)
上的文档和示例很少,所以我希望有这方面经验的人可以告诉我,如果我尝试按照设计使用API,或者是否有其他方法可以使用高级绑定API,做我想做的事。
这是演示代码。运行时,会有一个包含两个项目的ComboBox,然后是两个标签。第一个标签显示所选项目的toString()
版本。第二个标签尝试显示所选项目的一个属性,但仅显示null
。
import static javafx.beans.binding.Bindings.*;
import javafx.application.Application;
import javafx.beans.property.ReadOnlyStringProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
/** Testing cascading binding change triggers. */
public class SandboxTest extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
VBox root = new VBox(8);
root.setStyle("-fx-padding: 8;");
Scene s = new Scene(root);
stage.setWidth(200);
stage.setScene(s);
ComboBox<MoPoJo> list = new ComboBox<SandboxTest.MoPoJo>();
list.itemsProperty().set(FXCollections.observableArrayList(new MoPoJo("foo", "bar"), new MoPoJo("baz", "bat")));
Label direct = new Label();
direct.setTooltip(new Tooltip("Selected item to string"));
Label withSelect = new Label();
withSelect.setTooltip(new Tooltip("Second property of selected item"));
direct.textProperty().bind(convert(list.getSelectionModel().selectedItemProperty()));
withSelect.textProperty().bind(convert(select(list.getSelectionModel().selectedItemProperty(), "two")));
root.getChildren().addAll(list, direct, withSelect);
stage.show();
}
private static class MoPoJo {
private StringProperty _one = new SimpleStringProperty();
private StringProperty _two = new SimpleStringProperty();
private StringProperty _name = new SimpleStringProperty();
public MoPoJo(String o, String t) {
_one.set(o);
_two.set(t);
_name.bind(format("{ %s, %s }", oneProperty(), twoProperty()));
}
public StringProperty oneProperty() {
return _one;
}
public StringProperty twoProperty() {
return _two;
}
public ReadOnlyStringProperty nameProperty() {
return _name;
}
@Override
public String toString() {
return nameProperty().get();
}
}
}
答案 0 :(得分:2)
Bindings.select
无法访问私有类。使MoPoJo
成为公共类,您的代码将起作用。
public static class MoPoJo {
P.S:我相信这个事实值得在文档中提及,所以我在JavaFX javadoc上提交了http://javafx-jira.kenai.com/browse/RT-20640。