鉴于
我有一个模型类Model
,其中包含以下字段:
StringProperty stringProperty; ListProperty<String> listOfStringsProperty
我有一个视图类View extends VBox
,其中包含以下内容:
TextField stringTextField; TextFieldList stringsTextFieldList;
TextFieldList extends VBox
是我创建的一个自定义类,它使用nice +和 - 按钮处理多个TextFields
以添加和删除输入文本字段。
TextFieldList
类包含字段ObservableList<Node> inputTextFields
,我可以通过方法调用List<String> getData()
问题
我能够做到以下几点:
stringTextField.textProperty().bindBidirectional(model.getStringProperty());
为了将stringTextField
中View
的结果与stringProperty
中的Model
我需要做一些像
这样的事情stringsTextFieldList.listProperty().bindBidirectional(model.getListOfStringsProperty());
我该怎么做?
如果此设计不起作用,那么您如何建议我修复它?是否有内置类与TextFieldList
相同,而是extends Control
?
答案 0 :(得分:0)
你可以使用 Bindings.bindContent(List list1, ObservableList list2)
这是一个特殊的绑定,使列表与可观察列表保持同步。请记住,这不是双向的。
如果您想要双向性,则应使用失效侦听器或更改侦听器来检测更改并手动同步列表。您可能需要一些原始锁定机制来防止堆栈溢出。
答案 1 :(得分:0)
如果您决定自行控制,则应创建“手动绑定”,这意味着在输入ObservableList
中添加了ListChangeListener,然后您将处理Change示例:检查是否添加,删除或更新了新项目,并相应地维护TextField
s。这是可能的,但我的答案主要是提出一个现有的控件来重复使用,而不是创建自己的控件。
所以如果你不想重新发明轮子:
我不知道您的确切用例,但重用实际支持数据模型的控件可能是合理的,例如ListView。
在示例中,我将Model类修改为ObservableList<StringProperty>
而不是ListProperty<String>
(注意:列表中也可能只有String
个对象,我只是修改它以使绑定真正清楚)。我添加了ListView
并使用setCellFactory绘制TextField
作为列表中的元素,这些元素双向绑定到列表中的相应StringProperty
。我还添加了几个按钮来添加和删除元素,还添加了一个按钮来打印模型的当前内容。
示例:强>
Model.java
public class Model {
public ObservableList<StringProperty> listOfStringsProperty;
public Model(){
listOfStringsProperty = FXCollections.observableArrayList();
}
}
Main.java
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
Scene scene = new Scene(root,400,400);
Model m = new Model();
m.listOfStringsProperty.addAll(new SimpleStringProperty("First"),
new SimpleStringProperty("Second"),
new SimpleStringProperty("Third"));
ListView<StringProperty> lv = new ListView<StringProperty>();
lv.setCellFactory(new Callback<ListView<StringProperty>, ListCell<StringProperty>>() {
@Override
public ListCell<StringProperty> call(ListView<StringProperty> param) {
return new ListCell<StringProperty>(){
@Override
protected void updateItem(StringProperty item, boolean empty) {
super.updateItem(item, empty);
if(item == null){
setText(null);
setGraphic(null);
return;
}
TextField tf = new TextField();
tf.textProperty().bindBidirectional(item);
setGraphic(tf);
}
};
}
});
lv.setItems(m.listOfStringsProperty);
root.setCenter(lv);
// Control buttons
HBox hbox = new HBox();
Button buttonAdd = new Button("Add");
buttonAdd.setOnAction(e -> m.listOfStringsProperty.add(new SimpleStringProperty("")));
Button buttonRemove = new Button("Remove last");
buttonRemove.setOnAction(e -> m.listOfStringsProperty.remove(m.listOfStringsProperty.size()-1));
Button buttonPrintModel = new Button("Print model");
buttonPrintModel.setOnAction(e -> System.out.println(m.listOfStringsProperty.toString()));
hbox.getChildren().addAll(buttonAdd, buttonRemove, buttonPrintModel);
root.setBottom(hbox);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
这将生成以下窗口: