用于连续返回ArrayLists的JavaFX并发任务设计模式

时间:2016-07-27 10:51:33

标签: java javafx concurrency task

我正在学习如何在JavaFX中使用Task。我试图找出Task的设计模式,以便不断更新应用程序线程使用的ArrayList

以下是我到目前为止的代码。它有效,但我想确保我遵循最佳做法。这是一个合适的设计模式吗?如果没有,你能建议一个更好的方法吗?

最终,我的目标是使用长时间运行Canvas生成的像素数据更新Task,但希望首先在简单的案例中获得设计模式。

import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.stage.Stage;
import java.util.List;

interface Updateable {
    public void update(List<Integer> data);
}

public class TaskExample extends Application implements Updateable {

    private ListView<Integer> list_view = new ListView<>();

    public void update(List<Integer> data) {
        list_view.getItems().clear();
        list_view.getItems().addAll(data);  
    }

    @Override
    public void start(Stage primaryStage) throws Exception {

        MyTask task = new MyTask(this);

        Thread thread = new Thread(task);
        thread.setDaemon(true);     
        thread.start();

        primaryStage.setScene(new Scene(list_view));
        primaryStage.show();    

    }

    public static void main(String[] args) {
        launch(args);
    }
}

class MyTask extends Task<Void> {

    private ObservableList<Integer> data = FXCollections.observableArrayList();
    private Updateable ui;

    public MyTask(Updateable ui) {
        this.ui = ui;
        addListener();      
    }

    @Override
    protected Void call() throws InterruptedException {
        for (int i=0; i<10; i++) {
            Thread.sleep(1000);
            data.add(i);
        }
        return null;
    }

    private void addListener() {
        data.addListener((ListChangeListener.Change<? extends Integer> c) -> {
            Platform.runLater(() -> {
                ui.update(data);
            });
        });
    };

}

更新

根据@ James_D的评论更新了MyTask

class MyTask extends Task<Void> {

    private ObservableList<Integer> data = FXCollections.observableArrayList();
    private Updateable ui;

    public MyTask(Updateable ui) {
        this.ui = ui;
        addListener();      
    }

    @Override
    protected Void call() throws InterruptedException {
        for (int i=0; i<10; i++) {
            Thread.sleep(1000);
            final int j = i;
            Platform.runLater(() -> {
                data.add(j);
            });
        }
        return null;
    }

    private void addListener() {
        data.addListener((ListChangeListener.Change<? extends Integer> c) -> {
            ui.update(data);
        });
    };

}

0 个答案:

没有答案