当前位置: 首页 > 面试题库 >

如何在JavaFX中排队任务?

公孙和怡
2023-03-14
问题内容

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

但是,当线程正在运行时(一个过程大约需要30秒才能完成),我可以检查任何单选按钮。为此,它创建另一个线程,并与其他正在进行的线程长时间输出。所以我的输出盒简直是一团糟!我正在查看
异步 任务,但不确定是否与此相关。

这是我需要的:如果任务正在运行,并且在运行时单击“提交”按钮,请等待上一个任务结束,然后再执行该任务。

这是我的代码的伪代码

class TestMain {

    //main

    public void main(String ... args)  {

        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 if(/*second checkbox was selected*/){
        //do these other fancy stuff
        Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    TestMain.m_status_update.setText("Test Completed!");

                }
            });
    }
}

请不要建议我在任务运行时禁用单选按钮,因为我想像链接列表一样对任务进行排队。


问题答案:

使用单线程执行程序运行任务:

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制作了一个GUI,有三个单选按钮,一旦用户单击提交并创建了另一个线程,并且根据检查了什么单选按钮,线程运行所需的输出并将结果输出到控制台。 但是当线程运行时(一个进程需要大约30秒才能完成),我可以检查任何放射性按钮。它创建另一个线程并与另一个正在进行的线程一起输出长时间。所以我的输出框只是一个乱七八糟的东西!我在看异步任务,但我不确定这是否与它有关。 以下是我需要的:如果一个任

  • 据我所知,RabbitMQ等消息代理促进了用不同语言/平台编写的不同应用程序之间的通信。因此,由于celery可以使用RabbitMQ作为消息代理,我相信我们可以将任务从任何应用程序排队到celery,即使生产者不是用Python编写的。 现在,我想知道如何通过RabbitMQ将用C编写的应用程序中的任务排队到芹菜。但我还没有找到这样的例子。 我发现的唯一与此相关的信息就是这个问题 其中,公认的答

  • 我目前正在开发一个Twilio排队系统,但我被困在如何让电话排队并连接到代理上。 我把所有的电话都排在队列中,我的理解是,我们需要呼叫出队列,下面是twilio网站上可用的示例响应。 但是,当有人打电话给twilio时,这可以作为对twilio的回应发送。 那么,特工应该拨打twilio号码吗?如果是这样的话,我们是否需要为这个案例保留一个内部号码,除了我们为来电提供的支持号码? 谢谢你,巴斯卡。

  • 我在Tomcat中部署了一个web应用程序。我有一套代码,它检查数据库中的某些数据,然后根据这些数据向用户发送邮件。有人能建议如何在Tomcat中安排这项工作吗。

  • 问题内容: 我需要安排任务以固定的时间间隔运行。如何在长间隔(例如每8个小时)的支持下执行此操作? 我目前正在使用。是否支持长时间间隔? 问题答案: 使用:

  • 问题内容: 我的build.xml中包含以下内容: 这主要完成了我想要的操作,只是(如评论所述)我 不 希望 该任务编译其中的文件(但我确实希望该任务下的 所有其他内容都编译)。 我是一个完整的ant n00b蚂蚁,该文档对我没有太大帮助。我在几个地方看到它说有各种各样的排除/排除元素/属性,但是我能想到的每一种变化都没有效果,或者导致诸如“ 等等 不支持’排除’属性”之类的错误。 问题答案: 几