2010-01-30 142 views
7

我很难理解这个简单的代码:任何人都可以解释我这个javax swing方法吗?

javax.swing.SwingUtilities.invokeLater(new Runnable() { 
    public void run() { 
     createAndShowGUI(); 
    } 
}); 

可有人请给我解释一下它是如何工作(简单地说,因为我是新手)?此短代码是此larger code的一部分。

更具体地讲,我有以下问题:

  1. 是否“公共无效的run”定义一个新的方法?如果是这种情况,为什么它在另一种方法中定义(请参阅“较大的代码”以供参考)?
  2. 如果“public void run”定义了一个新方法,那么定义只包含一行代码的方法(createAndShowGUI)的原因是什么?
  3. “invokeLater”是做什么的?这对我来说实际上是最复杂的问题。

我想再强调一次,我是一个新手,使用“特殊”和“技术”的话会产生更多的问题。

如果您决定帮助我,请提前致谢!

回答

6

这是一个anonymous inner class

您正在定义三件事情:

  • 一类新的
  • 的方法,其类中调用run
  • 该类

的新实例在这个例子中的一些操作( createAndShowGUI())需要在Swing线程中运行。您不能在方法调用过程中“跳入”另一个线程,因此您将一个对象(您创建的新实例)放入队列中。当Swing线程准备就绪时,它将从队列中移除该对象并调用您的run方法,该方法又调用createAndShowGUI。现在一切都发生在正确的线程中。

+0

它不是“Swing线程”。 AWT事件调度线程(EDT)根本不依赖于Swing。 'java.awt.EventQueue.invokeLater'更有意义。 – 2010-01-30 19:06:17

+0

('SwingUtilities.invokeLater'仅用于与Java 1.1兼容(1998年被Java2版本1.2取代)。 – 2010-01-30 19:08:26

+0

'SwingUtilities。invokeLater'和'EventQueue.invokeLater'都在1.2中引入。它们在1.3中变得相当。两者都不被弃用。而AWT-Swing的区别与初学者问题并不相关,所以是的,EDT可以称为“Swing线程”。 – finnw 2010-01-31 02:58:14

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接口中定义的唯一方法。

好吧,我想这不算太短。

+5

On invokeLater:Swing是一个单线程GUI工具包。有一个称为事件调度线程(EDT)的特殊线程,专门用于显示和更新Swing组件。 invokeLater是一个帮助器方法,用于确保以某种方式修改GUI的任何代码在这个特殊的EDT上运行时才会这样做。 invokeLater方法将在事件派发线程的未来某个时刻在“run”方法中调用代码。我会假定createAndShowGUI方法将创建,初始化和显示组件,因此它只能在EDT上运行。 – Ash 2010-01-30 13:41:16

+0

谢谢,很好的解释。 – danben 2010-01-30 13:55:42

0

当你调用invokeLater时,你传递给它一个Runnable类型的实例。 Runnable是一个只声明一个方法“public void run()”的接口。 短代码的第1行发生了什么,称为“Annonymous Inner Class” - 您正在创建一个只能使用一次的Runnable实例,甚至没有命名它。

的invokeLater将在收到您的Runnable,而且里面会做这样的事情

public static void invokeLater(Runnable r) { 
    // Wait for the correct time to run this 
    r.run() 
} 

这意味着invokeLater的将决定何时调用run方法,从而运行createAndShowGUI。

因为在Java中,您不能将方法作为参数传递(尚未),所以您不得不创建这个一次性使用的Runnable实例。

+0

您可以使用'java.reflect.Method',然后使用'myMethod.invoke()'传递方法,但这会给匿名类带来更多混乱。 – 11684 2012-08-22 16:05:46

2

虽然这是Swing通常创建GUI的方式,但他们所做的只是告诉你“只是这样做,我们将在后面解释”。我想他们是对的,因为细节对于初学者来说有点复杂和没有帮助。但无论如何:

invokeLater启动一个线程,稍后将运行Runnable类。可运行类由finnw通过new Runnable { [..] }提到,并且必须根据Runnable接口指定public void run()方法。在这种情况下,它所做的只是执行createAndShowGUI方法。

1

此代码使得函数(createAndShowGUI())在另一个线程中被调用。 如果您不知道线程是什么,请更好地阅读它,但无论如何,请将其视为执行其他代码的同时执行的代码。其他代码将是Invoke()调用后的行。 这在图形应用程序中非常常见,代码运行时会更新图形,而其他代码则会响应用户操作。 这就是说我没有仔细阅读关于InvokeLater()的文档,并且在我的生活中没有写太多的Java。正如'LumpN'所说 - '这就是Swing通常创建GUI的方式。

weirder(对于新手)的事情是invokeLater()参数是以匿名的方式定义的 - '在代码中'。这实际上是一件很好的事情,因为这个班级非常简单。所有其他答案已经解释了这个匿名的事情。

so: 1.yes。 2.你问为什么,并要求不要获得太多的技术细节 - 但正如'yulkes'所说 - 因为在Java中你不能将方法作为参数传递,所以你必须创建这个类,并且它很好地构建它这个。 3.通过我在第一段中总结的内容,您可以简要阅读文档(仅在Google上搜索功能名称),也可以了解“Google代码搜索”。

相关问题