2010-01-30 143 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代碼搜索」。

相關問題