我无法理解这个简单的代码:
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
有人可以解释一下它是如何运作的(简单来说因为我是新手)?此简短代码是此larger code的一部分。
更具体地说,我有以下问题:
我想再强调一次,我是一个新手,使用“特殊”和“技术”词语会产生更多问题。
如果您决定帮助我,请提前感谢您!
答案 0 :(得分:11)
我能给出的最短答案是:
Runnable
是Java中的一个接口,表示定义run
方法的类型。任何实现此接口的类都必须为run
提供实现。 Runnable
表示要由系统的其他部分执行的任务。 Thread
是众所周知的Runnable
。
如果您的代码看起来像new InterfaceName() { //implementation }
,则称为匿名类。匿名类的要点是创建一个实现接口类型的一次性类。这个类没有名字,因此我们再也不能引用它了。它只在这里使用。
在不了解Swing的情况下,看起来SwingUtilities.invokeLater()
接受Runnable
并且......好吧,我猜它稍后会调用它(稍后可能在JavaDocs中描述了多少)。但是,您在此处将run
定义为另一个方法调用的原因是SwingUtilities
内的某些代码将在此run
上调用Runnable
方法;事实上,它可能知道的任何Runnable
是它定义了一个带有签名public void run()
的方法,因为这是Runnable
接口中定义的唯一方法。
嗯,我想这毕竟不会太短。
答案 1 :(得分:6)
您正在定义三件事:
run
的方法
在此示例中,某些操作(createAndShowGUI()
)需要在Swing线程中运行。您不能在方法调用的中间“跳转”到另一个线程,因此您将一个对象(您创建的新实例)放在队列中。当Swing线程准备就绪时,它将从队列中删除该对象并调用run
方法,然后调用createAndShowGUI
。现在一切都在正确的线程中发生。
答案 2 :(得分:2)
虽然这就是Swing通常创建GUI的方式,但他们只是告诉你“就这样做,我们将在后面解释原因”。我猜他们是对的,因为细节有点复杂,对初学者没有帮助。但无论如何:
invokeLater
启动一个稍后将运行Runnable
类的线程。 runnable类是由finnw通过new Runnable { [..] }
临时创建的,并且必须根据public void run()
接口指定Runnable
方法。在这种情况下,它所做的就是执行createAndShowGUI
方法。
答案 3 :(得分:1)
此代码使一个函数(createAndShowGUI())在另一个线程中被调用。 如果您不知道线程是什么,请更好地阅读它,但无论如何,将其视为在执行其他代码的同时执行的代码。其他代码将是此Invoke()调用之后的行。 这在图形应用程序中非常常见,代码运行以更新图形,而其他代码响应用户操作。 这就是说我没有费心去阅读有关InvokeLater()的文档,并且在我的生活中没有写过太多的Java。正如'LumpN'所说 - '这就是Swing通常创建GUI的方式'。
怪物(对于新手)的事情是invokeLater()参数是以匿名方式定义的 - “在代码中”。这实际上是一件好事,因为这个类非常简单。所有其他答案都解释了这个匿名的事情。
所以: 1.是。 2.你问为什么,并要求不要获得太多的技术细节 - 但正如'yulkes'所说的那样 - 因为在Java中你不能将方法作为参数传递,所以你必须构建这个类,并且很好地构建它像这样。 3.根据我在第一段中总结的内容,您可以简要阅读文档(仅在Google上搜索功能名称),还可以了解“Google代码搜索”。
答案 4 :(得分:0)
当你调用invokeLater时,你传递一个Runnable类型的实例。 Runnable是一个只声明一个方法“public void run()”的接口。 你的短代码的第1行会发生什么,称为“匿名内部类” - 你正在创建一个Runnable实例,它只使用一次,你甚至没有命名它。
InvokeLater将收到你的Runnable,而inside会做类似
的事情public static void invokeLater(Runnable r) {
// Wait for the correct time to run this
r.run()
}
这意味着invokeLater将决定何时调用run方法,从而运行createAndShowGUI。
因为在Java中你无法将方法作为参数传递(但是),所以你不得不创建这个一次性使用的Runnable实例。