任何人都可以用简单的语言向我解释这段代码:
SwingUtilities.invokeLater(
new Runnable(){
public void run(){
chatWindow.append(text);
}
});
}
拜托,任何人都可以给我一个详细解释。
答案 0 :(得分:5)
您正在创建Runnable
接口的匿名实现的实例,并将其传递给invokeLater
,这将把它放在队列中。另一个线程,Event Dispatch Thread,将Runnables弹出该队列并调用他们的run
方法。 (请注意,这确实是一个简单解释,并不与现实100%对应。)
就程序员感兴趣的效果而言,这会产生以下代码:
chatWindow.append(text);
不是在当前线程上执行,而是在事件调度线程(EDT)上执行。如果您尝试在当前线程上执行它,则会导致未定义的行为,因为Swing不是线程安全的,并且所有GUI操作都必须在上述EDT上进行。
答案 1 :(得分:1)
这简单地将任务添加到Java线程的任务队列中,该队列负责渲染&整个申请的活动。
注意:此线程称为 EDT (事件调度线程)。
答案 2 :(得分:0)
Runnable
是Java中的一个接口,表示定义run方法的类型。实现Runnable接口的类必须为其提供实现。 Thread是一个众所周知的Runnable。
来自docs:
导致doRun.run()在AWT事件上异步执行 调度线程。这将在所有挂起的AWT事件发生后发生 已被处理。应用程序线程时应使用此方法 需要更新GUI。在以下示例中,调用invokeLater 在事件分派上对Runnable对象doHelloWorld进行排队 线程然后打印一条消息。
如果从事件调度线程调用invokeLater - for 例如,从JButton的ActionListener - doRun.run()仍然会 被推迟到所有未决事件都被处理完毕。
答案 3 :(得分:0)
这是一种将一定数量的指令传递给AWT事件调度线程(EDT)的方法。这是必要的,因为从其他线程操作与AWT相关的东西(比如JFrame及其所有子代)是不好的做法。你最好把它交给EDT并让它在适当的时候处理它。
代码本身使用一个实现Runnable的匿名类,以便让您指定要在EDT上执行的内容。 Runnable接口要求您实现run()
方法。然后,EDT会在您想要的时候调用您的类对象run()
。
答案 4 :(得分:0)
基本上,只要消耗了所有AWT事件,它就会在内联run()
对象的Runnable
方法中启动代码。
答案 5 :(得分:0)
虽然这些链接上没有很好的答案和解释,但我仍然在添加一些细节:
Should we use EventQueue.invokeLater for any GUI update in a Java desktop application?
http://www.javamex.com/tutorials/threads/invokelater.shtml
Swing事件处理代码在称为事件调度线程(EDT)的特殊线程上运行。大多数调用Swing方法的代码也在这个线程上运行。这是必要的,因为大多数Swing对象方法都不是线程安全的。所有与GUI相关的任务,都应该对GUI进行任何更新,而绘制过程必须在EDT上进行,这涉及将请求包装在事件中并将其处理到EventQueue上。然后,事件将从一个接一个的队列中按顺序分派,即FIRST IN FIRST OUT。也就是说,如果事件A在事件B之前排队到EventQueue,那么事件B将不会在事件A之前被调度。
SwingUtilities类有两个有用的功能来帮助GUI渲染任务:
1)invokeLater(Runnable):使得doRun.run()在AWT事件派发线程(EDT)上异步执行。如上所述,这将在处理完所有挂起的AWT事件后发生。
2)invokeAndWait(Runnable):它具有与invokeLater相同的功能,但它与invokeLater的不同之处在于: - > invokeAndWait等待它给EDT的任务,在返回之前完成。 - >它阻塞(等待)当前(即,它通过同步锁来发送到WAIT状态,从而继续执行它来调用线程)。 - >一旦此函数发布的事件请求在EDT中调度并且此函数的调用者线程可以继续,它将释放锁。