java - 多任务 JavaFX

标签 java multithreading javafx task

我现在一直在寻找如何创建多个任务并让它们一个接一个地运行。这是java代码:

public class Main extends Application {

    DropShadow shadow = new DropShadow();
    Button button = new Button("Start");
    Task<Integer> task;
    Task<Integer> task2;
    Label label1 = new Label("Status: NOT STARTED");
    ProgressBar bar = new ProgressBar(0);
    ProgressIndicator pi = new ProgressIndicator(0);
    Thread th = new Thread();

    public void start(Stage stage) {
        task = new Task<Integer>() {
            protected Integer call() throws Exception {
                int iterations;
                for (iterations = 0; iterations < 1001; iterations++) {
                    if (isCancelled()) {
                        updateMessage("Cancelled");
                        break;
                    }
                    updateProgress(iterations, 1001);
                    updateMessage("Test");

                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException interrupted) {
                        if (isCancelled()) {
                            //updateMessage("Cancelled");
                            break;
                        }
                    }
                }
                return iterations;
            }
        };

        task2 = new Task<Integer>() {
            protected Integer call() throws Exception {
                int iterations;
                for (iterations = 0; iterations < 1001; iterations++) {
                    if (isCancelled()) {
                        updateMessage("Cancelled");
                        break;
                    }
                    updateProgress(iterations, 1001);
                    updateMessage("Test");

                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException interrupted) {
                        if (isCancelled()) {
                            //updateMessage("Cancelled");
                            break;
                        }
                    }
                }
                return iterations;
            }
        };

    task.setOnSucceeded(new EventHandler<WorkerStateEvent>(){

        public void handle(WorkerStateEvent arg0) {
            label1.setText("Done");
            new Thread(task2).start();
        }
    });

        Group root = new Group();
        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.setTitle("Progress Controls");

        final Slider slider = new Slider();
        slider.setMin(0);
        slider.setMax(50);

        bar.progressProperty().bind(task.progressProperty());
        pi.progressProperty().bind(task.progressProperty());
        label1.textProperty().bind(task.messageProperty());

        button.addEventHandler(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
            public void handle(MouseEvent e) {
                button.setEffect(shadow);
                new Thread(task).start();

            }
        });

        button.addEventHandler(MouseEvent.MOUSE_RELEASED, new EventHandler <MouseEvent>() {
            public void handle(MouseEvent arg0) {
                button.setEffect(null);
            }
        });

        final HBox hb = new HBox();
        hb.setSpacing(5);
        hb.setAlignment(Pos.CENTER);
        hb.getChildren().addAll(bar, pi, button, label1);
        scene.setRoot(hb);
        stage.show();
    }
    public static void main(String[] args) {
        launch(args);
    }
}

基本上我想要有两个进度条和总共大约 5 个任务。一个进度条将显示当前正在运行的任务,另一个进度条将显示总体进度。一旦任务 1 完成,我希望它运行任务 2 并将进度条更新回零,同时增加另一个进度条。然而,一旦我为其他任务创建了一个新线程,GUI 中的任何内容都不会更新。

提前致谢。

编辑: 我已经修复了启动第二个任务的代码部分。但是,我有以下问题:

  1. 如何创建一个随着不同任务完成而更新的整体进度条?

  2. 启动每个新任务后,如何动态重置和更新每个单独任务的单个进度条?我是否必须为此创建各种 ProgressBar 对象?

最佳答案

您的解决方案有效。这是微不足道的,但我建议最好有一个任务 1 不知道任务 2 的解决方案。您可以通过以下方式执行此操作:

  1. 使用 onSucceeded 处理程序“重新绑定(bind)”进度条
  2. 使用单线程执行器并向其提交两个任务

对于“总体进度”,您可以创建一个代表总进度的 DoubleBinding。

public class Main extends Application {

    DropShadow shadow = new DropShadow();
    Button button = new Button("Start");
    Task<Integer> task;
    Task<Integer> task2;
    Label label1 = new Label("Status: NOT STARTED");
    ProgressBar bar = new ProgressBar(0);
    ProgressIndicator pi = new ProgressIndicator(0);
    Thread th = new Thread();

    public void start(Stage stage) {
        task = new Task<Integer>() {
            protected Integer call() throws Exception {
                int iterations;
                for (iterations = 0; iterations < 1001; iterations++) {
                    if (isCancelled()) {
                        updateMessage("Cancelled");
                        break;
                    }
                    updateProgress(iterations, 1001);
                    updateMessage("Test");

                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException interrupted) {
                        if (isCancelled()) {
                            //updateMessage("Cancelled");
                            break;
                        }
                    }
                }
                return iterations;
            }
        };

        task2 = new Task<Integer>() {
            protected Integer call() throws Exception {
                int iterations;
                for (iterations = 0; iterations < 1001; iterations++) {
                    if (isCancelled()) {
                        updateMessage("Cancelled");
                        break;
                    }
                    updateProgress(iterations, 1001);
                    updateMessage("Test");

                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException interrupted) {
                        if (isCancelled()) {
                            //updateMessage("Cancelled");
                            break;
                        }
                    }
                }
                return iterations;
            }
        };

    task.setOnSucceeded(new EventHandler<WorkerStateEvent>(){

        public void handle(WorkerStateEvent arg0) {
            label1.setText("Done");
            bar.progressProperty().unbind();
            bar.progressProperty().bind(task2.progressProperty());
        }
    });

    final int numTasks = 2 ;

    DoubleBinding totalProgress = Bindings.createDoubleBinding(new Callable<Double>() {
        @Override
        public Double call() {
            return ( Math.max(0, task1.getProgress())
                   + Math.max(0, task2.getProgress()) ) / numTasks ;
        },
        task1.progressProperty(), task2.progressProperty());

   pi.progressProperty().bind(totalProgress);

        Group root = new Group();
        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.setTitle("Progress Controls");

        final Slider slider = new Slider();
        slider.setMin(0);
        slider.setMax(50);

        bar.progressProperty().bind(task.progressProperty());
        //  pi.progressProperty().bind(task.progressProperty());
        label1.textProperty().bind(task.messageProperty());

        final ExecutorService exec = Executors.newSingleThreadExecutor();

        button.addEventHandler(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
            public void handle(MouseEvent e) {
                button.setEffect(shadow);
                exec.submit(task);
                exec.submit(task2);
            }
        });

        button.addEventHandler(MouseEvent.MOUSE_RELEASED, new EventHandler <MouseEvent>() {
            public void handle(MouseEvent arg0) {
                button.setEffect(null);
            }
        });

        final HBox hb = new HBox();
        hb.setSpacing(5);
        hb.setAlignment(Pos.CENTER);
        hb.getChildren().addAll(bar, pi, button, label1);
        scene.setRoot(hb);
        stage.show();
    }
    public static void main(String[] args) {
        launch(args);
    }
}

关于java - 多任务 JavaFX,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22971222/

相关文章:

python - 使用来自另一个 Python 进程的数据更新小部件,而不阻塞它

java - 在单独的 JVM 上执行新的 JavaFX 应用程序

user-interface - JavaFX:禁用 ToggleGroup 中的所有按钮

tomcat - Javafx-Rich-Client-Applications 持续集成的最佳方式是什么

java - Hibernate:没有 SQL 字符串的查询?

java - 如何从网页中提取文本内容?

java - 确定时间戳是否是精确的小时

java - 生产者/消费者模式与观察者模式的区别

java - 对变量应用条件 OR

c - 线程本地存储开销