1

我正在阅读多个帖子,但我无法找到我的问题的明确答案。

我有一个应用程序(主框架),它有一个开始和一个停止按钮,只有一个 jTextArea。当用户按下“开始”按钮时,SwingWorker 类被实例化并运行(execute())一个任务。该任务是连接到数据库并进行一些检查。对于每次检查,它都会正确更新 jTextArea 并且一切都很好。当按下停止按钮时,我将 isCancelled() 设置为 true,因此后台进程停止(我在 SwingWorker 内部进行了适当的检查以停止执行等)。

我想要做的是当用户按下“开始”时,SwingWorker 开始执行,休眠几分钟,然后重新运行相同的任务。当按下“停止”按钮时,一切都停止了。

我怎样才能做到这一点?我知道 SwingWorker 后台进程应该运行一次。这样做的其他方法是什么?请注意,我选择 SwingWorker 的原因是我想在后台进程运行时更新 jTextArea。

先感谢您。

4

2 回答 2

5

您可以运行 SwingWorker 一次且仅一次,无一例外。可能的解决方案包括:

  • 每次需要时创建一个新的 SwingWorker 对象,运行它,完成后停止并丢弃它。
  • 在程序运行期间运行一个 SwingWorker,在按下 stop 时不要取消它,而是暂停它(如何取决于我们不知道的代码的非 Swing 部分),并在何时唤醒它播放被按下。状态设计模式可以很好地解决这个问题。

关于你的说法,

我想要做的是当用户按下“开始”时,SwingWorker 开始执行,休眠几分钟,然后重新运行相同的任务。当按下“停止”按钮时,一切都停止了。

考虑在 SwingWorker 内部为此使用 ScheduledExecutorService。ScheduledExecutorService 创建一个ScheduledFuture<V>可以在需要时取消的。


编辑
您的评论和我的回复:

ScheduledExecutorService 不会导致后台进程运行多次吗?

不会。后台进程将运行一次。ScheduledExecutorService 创建的 Futures 也将被创建,然后在它们的预定时间运行。

例如,当延迟小于上一次迭代运行的时间时会发生什么?

将创建多个期货并将同时开始运行。

我是否应该在 doInBackground() 中使用 Thread.Sleep() 进行 while 循环?

根据我们对您当前项目的了解,很难判断。是的,这可能会起作用,但是对于更复杂的需求,不,您会想要使用 ScheduledExecutorService。

于 2013-09-09T21:25:48.037 回答
0

我通常在 swingworker 内部使用一个循环,工作正常。

全局变量

private boolean monitor = true;

摇摆工人班

private class MonitorQueue extends SwingWorker<Void, Void> {

    @Override
    protected Void doInBackground() throws Exception {
        while (monitor) {
            System.out.println("monitor");
            Thread.sleep(Constants.SECOND * 5);
        }
        return null;
    }
}

我所拥有的另一个好处是,我没有停止或暂停 SwingWorker 本身,而是设置了 monitor = false。这将使 SwingWorker 在停止之前完成所有任务。

于 2013-11-16T05:29:18.617 回答