【问题标题】:How to use ObservableLists in JavaFX如何在 JavaFX 中使用 ObservableLists
【发布时间】:2015-02-22 03:36:37
【问题描述】:
我正在尝试使用 ObservableLists 来帮助我在我正在构建的新应用程序中编排 MVC 框架。我有一个 LineData 对象,其中包含在屏幕上绘制线条所需的信息,我想在我的程序后端维护一个 LineData 列表。然后,每当在后端绘制 LineData 列表时,我希望通过前端在屏幕上绘制相应的线条。我相信要做到这一点,我需要在前端有一个列表绑定到后端列表,然后我需要在这个列表上有某种监听器,触发新数据变成行和画?我只是对如何做到这一点感到困惑——任何帮助将不胜感激!谢谢!
【问题讨论】:
标签:
model-view-controller
binding
javafx
observable
observablelist
【解决方案1】:
您可以“手动”执行此操作,向ObservableList<LineData> 注册一个侦听器,并根据需要从Pane 的子列表中添加或删除元素。所以像
public class Model {
// ...
public ObservableList<LineData> getLineData() { ... }
// ...
}
然后
public class MyController {
Model model ;
@FXML
private Pane pane ; // contains lines...
public void initialize() {
model.getLineData().addListener((ListChangeListener.Change change) -> {
while (change.next()) {
if (change.wasAdded()) {
change.getAddedSubList().stream()
.map(this::createLineForLineData)
.forEach(pane.getChildren()::add);
} else if (change.wasRemoved()) {
change.getRemoved().forEach(lineData ->
pane.getChildren().removeIf((Line line) -> lineMatchesLineData(line, lineData));
}
}
});
// ...
}
// ...
private Line createLineForLineData(LineData lineData) {
// create Line matching data in lineData and return it
}
private boolean lineMatchesLineData(Line line, LineData lineData) {
// return true if line's state matches data in lineData, false otherwise
}
}
请注意,EasyBind 框架为此具有内置功能:
public class MyController {
Model model ;
@FXML
private Pane pane ;
public void initialize() {
Bindings.bindContent(pane.getChildren(),
EasyBind.map(model.getLineData(), this::createLineForLineData));
// ...
}
private Line createLineForLineData(LineData lineData) { ... }
}