【问题标题】:JavaFX Scheduling and Concurrency with TasksJavaFX 调度和并发任务
【发布时间】:2015-07-15 03:55:48
【问题描述】:

首先,我对 Java 和 JavaFX 编程还很陌生。

我想为我的程序制作一个调度按钮,该按钮将调用一个函数:setSchedule()

我希望该按钮设置一个循环任务,该任务将在两次调用之间的定义时间段内被调用。

我创建了一个名为CreateTask 的课程。我在CreateTask 中有一个返回Task<Void> 的函数,该函数称为getTask()

setSchedule 被调用时:

CreateTask createTask = new CreateTask();
Task task = createTask.getTask();

bar.progressProperty().bind(uploadTask.progressProperty());
programStatusText.textProperty().bind(uploadTask.messageProperty());

ScheduledThreadPoolExecutor sch = (ScheduledThreadPoolExecutor)Executors.newScheduledThreadPool(5);
sch.scheduleWithFixedDelay(task, 5, 5, TimeUnit.SECONDS);

我的程序非常适合一次执行。进度条加载,我的功能完成。问题是任务没有被再次调用。

我已经尝试研究为什么会发生这种情况,但到目前为止我还没有运气!

【问题讨论】:

标签: java javafx javafx-2 scheduled-tasks javafx-8


【解决方案1】:

来自Task docs

Task 是一次性类,不能重复使用。请参阅可重用 Worker 的服务。

【讨论】:

    【解决方案2】:

    对于 JavaFX,我通常使用 TimeLine 来执行计划任务。像这样的

    /**
     * Timeline to cycle background image after 10 seconds.
     */
    private Timeline timelineBackground = new Timeline();
    
    
    void backgroundTimer()
    {
        // initialise the Timeline cycle to indefinite duration
        timelineBackground.setCycleCount(Timeline.INDEFINITE);
        // add KeyFrame with a duration of 30 seconds, executing onFinished when the time expires
        timelineBackground.getKeyFrames().add(new KeyFrame(Duration.millis(30000), (actionEvent) ->
        {
            cycleBackground();
        }, null, null));
        // start the Timeline
        timelineBackground.play();
    }
    
    private void cycleBackground()
    {
        imageView.setImage(images[((imageIndex == images.length) ? (imageIndex = 0) : imageIndex++ )]);
    }
    

    编辑: 添加了 cycleBackground 方法的源代码,以表明在 JavaFX 主线程上执行时,teask 是并且应该是微不足道的,因为正如 Jewelsea 所指出的,这在我的原始帖子中并不清楚。还注意到我包含了以前的版本,它需要捕获我使用的最终版本不需要的异常。

    【讨论】:

    • 如果计划的工作发生得很快,这是一个很好的解决方案,如果计划的工作需要很长时间,这是一个糟糕的解决方案。例如,如果发生阻塞 I/O 调用,则不好,因为 UI 将在执行 I/O 时挂起。但是,如果发生的只是改变场景图中节点的属性,那很好,因为这可以很快发生并且不会挂起 UI。
    • 是的,但我假设在 OP 示例中使用进度条,他们想要更新进度条而不是做一些繁重的任务。如我的简单示例所示,虽然我应该包含 cycleBackground() 源以表明它所做的只是将背景更改为预加载图像数组中的新图像,因此根本不需要繁重的处理,只是一个简单的 UI 更新,我相信应该在JavaFX主线程中完成。
    猜你喜欢
    • 2012-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多