Javafx Link/Bind Treeview 项到 ObservableList
Javafx Link/Bind Treeview Items to ObservableList
我正在尝试找到一种简单的方法将下载类型的 TreeView 链接到相同类型的 ObservableList。
MainController.java
public class MainController {
private ObservableList<Download> downloads = FXCollections.observableArrayList();
@FXML private TreeView<Download> $TreeDownloads;
@FXML
public void initialize() {
$TreeDownloads.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
$TreeDownloads.setNodeOrientation(NodeOrientation.LEFT_TO_RIGHT);
$TreeDownloads.setShowRoot(false);
downloads.addListener(new ListChangeListener<Download>() {
@Override
public void onChanged(Change<? extends Download> c) {
if (c.wasAdded()) {
addDownloads(c.getAddedSubList());
}
if (c.wasRemoved()) {
//
}
}
});
downloads.add(new Download("3847"));
downloads.add(new Download("3567"));
downloads.add(new Download("2357"));
}
private void addDownloads(List<? extends Download> downloads) {
downloads.forEach(download -> {
TreeItem<Download> treeItem = new TreeItem<>(download);
$TreeDownloads.getRoot().getChildren().add(treeItem);
new Thread(download::start).start();
});
}
private void removeDownloads(List<? extends Download> downloads) {
// remove treeitems from the treeview that hold these downloads
}
}
Download.java
public class Download {
private DoubleProperty progress = new SimpleDoubleProperty(0D);
private StringProperty id = new SimpleStringProperty("");
public Download(String id) {
this.id.set(id);
}
public void start() {
while (progress.getValue() < 1) {
try {
Thread.sleep(1000);
progress.add(0.1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public String toString() {
return id.getValue();
}
}
如何通过 Object(Download) 机制实现 remove,以及是否有更简单的方法将 observablelist 的项目绑定到树视图?
仍然不完全确定确切的问题是什么,一切都很简单:
首先,您的列表更改侦听器实现不正确,它必须在访问其状态之前推进 subChanges(您 运行 您发布的代码,或者没有;)
downloads.addListener(new ListChangeListener<Download>() {
@Override
public void onChanged(Change<? extends Download> c) {
// this while was missing
while (c.next()) {
if (c.wasAdded()) {
addDownloads(c.getAddedSubList());
}
if (c.wasRemoved()) {
// accessing the list of removed elements is .. plain standard api
removeDownloads(c.getRemoved());
}
}
}
});
现在实现对应treeItem的移除:
private void removeDownloads(List<? extends Download> downloads) {
// remove treeitems from the treeview that hold these downloads
List<TreeItem<Download>> treeItemsToRemove = treeDownloads.getRoot().getChildren().stream()
.filter(treeItem -> downloads.contains(treeItem.getValue()))
.collect(Collectors.toList());
treeDownloads.getRoot().getChildren().removeAll(treeItemsToRemove);
}
旁白:
- java 命名约定对成员使用小写字母:treeDownloads(不是 $TreeDownloads)
- MCVE 中的 "verifiable" 意味着 运行 可以按原样使用:发布者应该是第一个验证这一点的人 ;) 你的不是因为监听器的不正确实现
- MCVE 中的 "minimal" 意味着省略所有不需要的东西:f.i。调用线程代码 - 这在您的第一个片段中特别令人分心,因为违反 fx 的线程规则是一个相当常见的错误
我正在尝试找到一种简单的方法将下载类型的 TreeView 链接到相同类型的 ObservableList。
MainController.java
public class MainController {
private ObservableList<Download> downloads = FXCollections.observableArrayList();
@FXML private TreeView<Download> $TreeDownloads;
@FXML
public void initialize() {
$TreeDownloads.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
$TreeDownloads.setNodeOrientation(NodeOrientation.LEFT_TO_RIGHT);
$TreeDownloads.setShowRoot(false);
downloads.addListener(new ListChangeListener<Download>() {
@Override
public void onChanged(Change<? extends Download> c) {
if (c.wasAdded()) {
addDownloads(c.getAddedSubList());
}
if (c.wasRemoved()) {
//
}
}
});
downloads.add(new Download("3847"));
downloads.add(new Download("3567"));
downloads.add(new Download("2357"));
}
private void addDownloads(List<? extends Download> downloads) {
downloads.forEach(download -> {
TreeItem<Download> treeItem = new TreeItem<>(download);
$TreeDownloads.getRoot().getChildren().add(treeItem);
new Thread(download::start).start();
});
}
private void removeDownloads(List<? extends Download> downloads) {
// remove treeitems from the treeview that hold these downloads
}
}
Download.java
public class Download {
private DoubleProperty progress = new SimpleDoubleProperty(0D);
private StringProperty id = new SimpleStringProperty("");
public Download(String id) {
this.id.set(id);
}
public void start() {
while (progress.getValue() < 1) {
try {
Thread.sleep(1000);
progress.add(0.1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public String toString() {
return id.getValue();
}
}
如何通过 Object(Download) 机制实现 remove,以及是否有更简单的方法将 observablelist 的项目绑定到树视图?
仍然不完全确定确切的问题是什么,一切都很简单:
首先,您的列表更改侦听器实现不正确,它必须在访问其状态之前推进 subChanges(您 运行 您发布的代码,或者没有;)
downloads.addListener(new ListChangeListener<Download>() {
@Override
public void onChanged(Change<? extends Download> c) {
// this while was missing
while (c.next()) {
if (c.wasAdded()) {
addDownloads(c.getAddedSubList());
}
if (c.wasRemoved()) {
// accessing the list of removed elements is .. plain standard api
removeDownloads(c.getRemoved());
}
}
}
});
现在实现对应treeItem的移除:
private void removeDownloads(List<? extends Download> downloads) {
// remove treeitems from the treeview that hold these downloads
List<TreeItem<Download>> treeItemsToRemove = treeDownloads.getRoot().getChildren().stream()
.filter(treeItem -> downloads.contains(treeItem.getValue()))
.collect(Collectors.toList());
treeDownloads.getRoot().getChildren().removeAll(treeItemsToRemove);
}
旁白:
- java 命名约定对成员使用小写字母:treeDownloads(不是 $TreeDownloads)
- MCVE 中的 "verifiable" 意味着 运行 可以按原样使用:发布者应该是第一个验证这一点的人 ;) 你的不是因为监听器的不正确实现
- MCVE 中的 "minimal" 意味着省略所有不需要的东西:f.i。调用线程代码 - 这在您的第一个片段中特别令人分心,因为违反 fx 的线程规则是一个相当常见的错误