SwingUtilities中的invokeAndWait方法
请在SwingUtilities中解释invokeAndWait()方法。我无法理解这一点。 解释得非常清楚。 如果你尝试一个例子,这将是非常有帮助的。
编辑添加@ noob的问题的扩展:
什么不清楚这个 ?
这是一个修改的用法示例:
import javax.swing.SwingUtilities; public class InvokeAndWaitStuff { public static void main(String[] args) { final Runnable doHelloWorld = new Runnable() { public void run() { System.out.println("Hello World on " + Thread.currentThread()); } }; Thread appThread = new Thread() { public void run() { try { SwingUtilities.invokeAndWait(doHelloWorld); } catch (Exception e) { e.printStackTrace(); } System.out.println("Finished on " + Thread.currentThread()); } }; appThread.start(); } }
输出:
Hello World on Thread[AWT-EventQueue-0,6,main] Finished on Thread[Thread-0,5,main]
为什么这很重要?
导致doHelloWorld.run()在AWT事件派发线程上同步执行。 这个调用会阻塞,直到所有待处理的AWT事件都被处理,然后doHelloWorld.run()返回。 应用程序线程需要更新GUI时应使用此方法。
据我所知,这基本上是一个瓶颈,迫使GUI更新由单个线程同步执行,而不是由多个线程asynchronous执行,这可能是不安全的。
要理解invokeAndWait()
作用,首先需要了解Swing的事件/线程模型。
基本上, 以任何方式影响GUI的一切都必须发生在单个线程上 。 这是因为经验表明,multithreading的GUI是不可能正确的。
在Swing中,这个特殊的GUI线程被称为Event Dispatch Thread(或者EDT) 。 一旦显示Swing顶级组件,就会启动它,并且它基本上是一个工作线程,它具有一个接一个地执行的事件对象的FIFO队列。
当需要绘制或更新Swing GUI时,JRE会在EDT队列中放置一个事件。 导致侦听器被调用的用户操作以EDT队列上的事件开始。 和(这是重要的部分)你的程序所做的改变GUI的东西(比如注册监听器,添加/删除GUI组件或改变GUI显示的模型数据)必须放在EDT队列中,或者GUI可以得到损坏。
现在完成: invokeAndWait()
将您传递给它的Runnable
放到EDT事件队列中,等待EDT执行完成。 当非GUI线程需要做一些影响GUI的事情时,应该使用它,但是也需要等到实际完成之后才能继续。 如果你只是想做一些影响GUI的东西,但不关心什么时候完成,你应该改用invokeLater()
。
我在JTable中有类似的问题。 该程序在“scrollRectToVisible”方法的某个地方被阻止。 我已经通过将其包装在invokeLater调用中来取代该调用。 invokeAndWait没有解决我的块问题。
SwingUtilities.invokeLater(new Runnable() { @Override public void run() { table.scrollRectToVisible(r); } });
- 为什么Gson fromJson抛出一个JsonSyntaxException:期望某种types,但是是一些其他types?
- 你可以在Sun VM的Dalvik VM(Android的VM)上做什么?
- 什么是协变返回types?
- 如何在Jetty 9中访问实例化的WebSockets?
- 用Gson把JSON数组parsing成java.util.List
- Maven错误:无法find或加载主类org.codehaus.plexus.classworlds.launcher.Launcher
- Intellij IDEA。 隐藏.iml文件
- 检查一个string是否可以parsing为Long而没有try-catch?
- Java的createNewFile() – 它也会创build目录吗?