這是我非常簡單的例子。 (下......)從TextField更新TreeView項目
做些什麼: TreeView控件填充了三個人,當TreeItem選擇文本字段將與選定人員的名稱來填充。如果用戶改變了名字並且失去了文本框的焦點(或者按下了回車鍵),它將改變人物的名字和「更新」TreeView項目的顯示文字。
我的問題是這一行:
selectedItem.valueProperty().set(new Person(selectedPerson.getName(), selectedPerson.getAge()));
只是由於該行我能刷新樹視圖。沒有這個,我只能在例如調整窗口大小(或摺疊根項目的擴展)。
我認爲這個解決方案是非常愚蠢的,必須有一個辦法如何把它更好的代碼。我無法每次創建Person的新實例,這對我來說是不可接受的。
我也試圖火樹視圖的事件,但這種方法與重點弄亂了,它也是一個愚蠢的解決方案了。 我也發現了這樣的解決方案:
treeView.getRoot().getChildren().set(treeView.getSelectionModel().getSelectedIndex(), new TreeItem<MainAppTF.Person>(updatedPerson));
這是不好解決了。除非我玩bind()unbind(),但也許在Binding中有一些我不熟悉的東西,但綁定是一種「實時/即時」的改變然而。 (我喜歡聽衆)
我的主要目標是,片刻後有權「承諾」我的焦點變化或關鍵事件的變化和更新的TreeView。
PS:我要成爲真正的例子,非常感謝。
public class MainAppTF extends Application {
private TreeView<Person> treeView;
private final TreeItem<Person> rootNode = new TreeItem<Person>(new Person("Root", 0));
private TextField textField;
@Override
public void start(Stage stage) {
VBox box = new VBox();
Scene scene = new Scene(box, 400, 400);
treeView = new TreeView<Person>(rootNode);
treeView.setShowRoot(false);
rootNode.setExpanded(true);
List<TreeItem<Person>> list = new ArrayList<>();
list.add(new TreeItem<Person>(new Person("Adam", 20)));
list.add(new TreeItem<Person>(new Person("Eva", 19)));
list.add(new TreeItem<Person>(new Person("Carl", 30)));
rootNode.getChildren().setAll(list);
textField = new TextField("");
attachListeners();
box.getChildren().add(treeView);
box.getChildren().add(textField);
VBox.setMargin(treeView, new Insets(10));
VBox.setMargin(textField, new Insets(10));
stage.setScene(scene);
stage.show();
}
private void attachListeners() {
treeView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<TreeItem<Person>>() {
@Override
public void changed(ObservableValue<? extends TreeItem<Person>> observable, TreeItem<Person> oldValue, TreeItem<Person> newValue) {
textField.setText(newValue.getValue().getName());
}
});
textField.focusedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
if (!newValue) {
updateTreeViewItem();
}
}
});
textField.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
updateTreeViewItem();
}
});
}
private void updateTreeViewItem() {
TreeItem<Person> selectedItem = treeView.getSelectionModel().getSelectedItem();
Person selectedPerson = selectedItem.getValue();
selectedPerson.nameProperty().set(textField.getText());
// FIXME This is silly! There must be another way!
selectedItem.valueProperty().set(new Person(selectedPerson.getName(), selectedPerson.getAge()));
}
public static void main(String[] args) {
Application.launch(args);
}
private class Person {
private StringProperty name;
private int age;
public Person() {
this(null, 0);
}
public Person(String name, int age) {
this.name = new SimpleStringProperty(name);
this.age = age;
}
public StringProperty nameProperty() {
return name;
}
public String getName() {
return name.getValue();
}
public void setName(String name) {
this.name.setValue(name);
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return getName() + " - " + getAge();
}
}
}
【相關問題(HTTP://計算器。 com/q/30556259/203657),它基本上是以自定義的TreeItem實現開始的(@James_D概述的選項之一) – kleopatra