如何在JavaFX中使用ObservableLists

时间:2015-02-22 03:36:37

标签: model-view-controller binding javafx observable observablelist

我正在尝试使用ObservableLists来帮助我在我正在构建的新应用程序中编排MVC框架。我有一个LineData对象,其中包含在屏幕上绘制一条线所需的信息,我想在程序的后端维护一个LineData列表。然后,每当在后端绘制LineData列表时,我希望通过前端在屏幕上绘制相应的行。我相信要做到这一点,我需要在前端有一个列表绑定到后端的列表,然后我需要在这个列表上有一些侦听器,触发新数据转换成行和画?我只是对如何做到这一点很困惑 - 任何帮助都将不胜感激!谢谢!

1 个答案:

答案 0 :(得分:0)

您可以“手动”执行此操作,使用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) { ... }

}