Как использовать ObservableLists в JavaFX

Я пытаюсь использовать ObservableLists, чтобы помочь мне организовать структуру MVC в новом приложении, которое я создаю. У меня есть объект LineData, который содержит информацию, необходимую для рисования линии на экране, и я хочу поддерживать список LineData в бэкенде моей программы. Затем я хочу, чтобы соответствующие линии отображались на экране через интерфейс всякий раз, когда список LineData рисуется на сервере. Я считаю, что для этого мне нужен список во внешнем интерфейсе, привязанный к списку в бэкэнде, а затем мне нужен какой-то слушатель в этом списке, который инициирует преобразование новых данных в строки и нарисовано? Я просто запутался в том, как это сделать - любая помощь будет принята с благодарностью! Спасибо!


person Jeremy    schedule 22.02.2015    source источник


Ответы (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) { ... }

}
person James_D    schedule 22.02.2015