我正在尝试让我的GUI在最近的图形更新后等待2秒钟。这意味着在我使用之后:
boardLogo.repaint();
boardLogo.revalidate();
我希望GUI在进行进一步计算之前等待,然后再次绘制它们。
代码:
SwingUtilities.invokeLater(new Runnable() {
@SuppressWarnings("rawtypes")
@Override
public void run() {
SwingWorker swingWorkerExample = new SwingWorker(){
@Override
protected Object doInBackground() throws Exception {
return null;
}
protected void done(){
try {
Thread.sleep(2000); //wait 2 seconds.
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
swingWorkerExample.execute();
}
});
//.... more code here
boardLogo.repaint();
boardLogo.revalidate();
但是当我运行它时 - 首先执行最后两行,然后等待2秒......
老实说,我对线程和Java Swing的了解并不是最好的(特别是在理解swing工作者时,我试图从Oracle网站上读到),所以我很感激,如果答案是详细说明。
谢谢!
答案 0 :(得分:2)
当我运行它时 - 首先执行最后两行,然后等待2秒......我对Threads和Java Swing的了解并不是最好的。
你说,它执行最后两行。永远不要错过它是什么?
它是一个帖子。线程是在Java程序中执行代码的,并且每个执行的行都由某个线程执行。
当您的代码调用invokeLater()
时,它正在提交要由Swing的事件调度线程执行的任务(即一段代码)(EDT);当你的代码调用swingWorker.execute()
时,它正在提交一个由Swing的后台线程执行的任务。
在程序中拥有多个线程的重点是,他们可以同时执行不同的事情。
在你的情况下,你已经让EDT睡了两秒钟,同时,其他一些线程正在调用boardLogo.repaint();
和boardLogo.revalidate();
关于Swing和多线程,需要了解一些重要的事情:
所有的事件处理程序都将由EDT运行。
事件处理程序永远不应该执行任何超过一小时的事情,因为您的应用程序将无法响应任何其他事件(即,它将显示为"挂起& #34;)直到处理程序返回。
不允许其他线程与Swing的任何GUI组件进行交互。
invokeLater()
的一个重要用例是,后台线程中运行的代码如何与GUI组件通信。 invokeLater()提交将在EDT中运行的任务(即一段代码)。
SwingWorker的主要用例与此完全相反:它是如何在EDT中运行的事件处理程序启动将要采取的任务完成的时间不到一小部分。
您可以通过Swing Concurrency教程了解这些内容:https://docs.oracle.com/javase/tutorial/uiswing/concurrency/