Java中的thread.sleep会让Swing用户界面也休眠吗?

4

我正在创建一个简单的测试应用程序,它每小时使用JFileChooser通过thread.sleep()在选择的目录/ s上运行检查。但是,当我选择目录并运行该方法时,ui面板变灰,并且swing位消失了。该线程似乎将UI以及其调用的方法一起置于睡眠状态。

if (option == JFileChooser.APPROVE_OPTION) {
    selectedDirectory = chooser.getSelectedFiles();
    try {
        while (true) {
            runCheck(selectedDirectory);
            Thread.sleep(1000*5);//1000 is 1 second
        }
    } catch (InterruptedException e1) {
        Thread.currentThread().interrupt();
        e1.printStackTrace();
    }               
} 

我正在寻找一种解决方法,以便我可以在UI中打印运行检查的结果。.setText(result)


也许是 SwingWorker?http://download.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html - sje397
2
考虑使用 Timer 和 TimerTask 来运行定时任务,这样会更加可靠。 - Andrew
1
@Andrew,实际上应该使用javax.swing.Timer而不是util包中的Timer。 - jjnguy
2
@jjnguy,我只是想指出,在一般情况下,在while循环中使用sleep不是一个好的使重复任务按时执行的方法,而且有更可靠的方法。但是在这种情况下,你是正确的。 :P - Andrew
3个回答

6

关于代码让UI休眠的问题,你是正确的。由于sleep被调用在事件分发线程(负责运行GUI的线程)上,UI停止处理事件并“进入睡眠状态”。

我认为你需要一个javax.swing.Timer

Timer t = new Timer(1000 * 5, new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        // do your reoccuring task
    }
});

这将使您的重复任务在EDT之外执行,因此不会使您的UI无响应。

2
请注意,Swing计时器的任务在事件分派线程中执行。这意味着任务可以安全地操作组件,但也意味着任务应该快速执行。 - unholysampler

1
如果您发布的代码在EventDispatchThread上运行,则Swing无法重新绘制GUI。您正在阻塞(睡眠)应该处理此操作的线程!

1

这是因为你正在主GUI线程中运行检查并使用无限循环。此检查是后台任务,应在其自己的线程中执行,以便GUI仍然可以接收和响应用户输入。

您还不需要编写自己的实现,Java有一个计时器对象。

编辑:还有一个Swing特定的计时器对象。这将使操作发生在GUI线程中,因此如果您的任务很长,它可能会导致GUI在操作发生时仍然被锁定(但在等待时不会)。


你链接的计时器是来自util包。当与Swing组件交互时,应该使用Swing的计时器。 - jjnguy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接