如何在JavaFX中排队任务? [英] How to queue tasks in JavaFX?

查看:128
本文介绍了如何在JavaFX中排队任务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用JavaFX创建了一个GUI,并且有三个单选按钮,一旦用户单击提交并创建另一个线程,并且根据检查的单选按钮,线程运行所需的输出并将结果输出到控制台。

I have made a GUI using JavaFX, and there are three radio buttons and once the user clicks submit and another thread is created and depending on what radiobutton was checked, the thread runs the required output and outputs the result to the console.

但是当线程正在运行时(一个进程完成大约需要30秒),我可以检查任何单选按钮。它创建另一个线程,并与其他正在进行的线程输出长。所以我的输出框只是一个混乱的混乱!我正在查看异步任务,但我不确定这是否与之相关。

But while the thread is running (it takes around good 30 seconds for one process to complete) , I am able to check on any radiobutton. To it creates another thread and outputs long with the other ongoing thread. So my output box is just a jumble-wumble! I was looking at asynchronous task but I am not sure if that is something related to it.

这就是我需要的:如果一个任务正在运行,我在运行时点击提交按钮,等待上一个任务结束然后执行任务。

这是我的代码的伪代码

class TestMain{


main class{
launch(args);
}

declaring a new textfield with name m_status update here
once submit button is clicked {


create a new thread to run



}
}


 class ThreadBlahBlah implements Runnable{

if(first checkbox was selected){
//do these fancy stuff
Platform.runLater(new Runnable() {
@Override
    public void run() {
     TestMain.m_status_update.setText("Test Completed!") ;


}
else(second checkbox was selected){
//do these other fancy stuff
Platform.runLater(new Runnable() {
    @Override
    public void run() {
     TestMain.m_status_update.setText("Test Completed!") ;

}


}

请不要推荐我在任务运行时禁用单选按钮导致我想将我的任务排队,如链接列表。

Please do not recommend me to disable radio buttons while the task is running cause I want to queue my tasks like a linked list.

推荐答案

使用单线程执行者来运行y我们的任务:

Use a single-threaded executor to run your tasks:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.concurrent.Task;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class QueuedTaskExample extends Application {

    private AtomicInteger taskCount = new AtomicInteger(0);

    private ExecutorService exec = Executors.newSingleThreadExecutor(r -> {
        Thread t = new Thread(r);
        t.setDaemon(true); // allows app to exit if tasks are running
        return t ;
    });

    // Use the following if you want the tasks to run concurrently, instead of consecutively:

    // private ExecutorService exec = Executors.newCachedThreadPool(r -> {
    //     Thread t = new Thread(r);
    //     t.setDaemon(true);
    //     return t ;
    // });


    @Override
    public void start(Stage primaryStage) {

        // Just keep track of number of tasks pending/running for a status label:
        IntegerProperty pendingTasks = new SimpleIntegerProperty(0);

        Button startButton = new Button("Start");
        TextArea textArea = new TextArea();
        textArea.setEditable(true);
        startButton.setOnAction(event -> {
            Task<Void> task = createTask();
            // add text to text area if task's message changes:
            task.messageProperty().addListener((obs, oldMessage, newMessage) -> {
                textArea.appendText(newMessage);
                textArea.appendText("\n");
            });

            // for maintaining status label:
            pendingTasks.set(pendingTasks.get()+1);
            task.setOnSucceeded(taskEvent -> pendingTasks.set(pendingTasks.get()-1));

            // run task in single-thread executor (will queue if another task is running):
            exec.submit(task);
        });

        // layout etc
        HBox controls = new HBox(startButton);
        controls.setAlignment(Pos.CENTER);
        controls.setPadding(new Insets(10));

        Label statusLabel = new Label();
        statusLabel.textProperty().bind(Bindings.format("Pending/running tasks: %s", pendingTasks));

        BorderPane root = new BorderPane(textArea, statusLabel, null, controls, null);
        Scene scene = new Scene(root, 600, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    @Override
    public void stop() {
        exec.shutdownNow();
    }

    // Trivial task that counts slowly to 5, updating its message as it goes:
    private Task<Void> createTask() {
        final int taskNumber = taskCount.incrementAndGet();
        return new Task<Void>() {
            @Override 
            public Void call() throws Exception {
                for (int count=1; count<=5; count++) {
                    Thread.sleep(1000);
                    updateMessage("Task "+taskNumber+": Count "+count);
                }
                return null ;
            }
        };
    }

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

这篇关于如何在JavaFX中排队任务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆