2011-03-30 66 views
6

我有一個簡單的groovy腳本,它的主執行線程需要向用戶顯示一些對話框。JOptionPane.showMessageDialog和swing.utils.invokeAndWait的(event-dispatch)線程安全用法是什麼?

我的揮杆知識是有限的和生鏽的,但我記得有關需要小心保持圖形用戶界面的東西在事件調度線程(EDT)的知識。

如果我只是從我的主線調用靜態JOptionPane.showMessageDialog方法,我是否認爲這會違反在GUI上保留GUI東西的正確做法?

我是否應該使用swing.utils.invokeAndWait方法,如下面的示例代碼所示?


void showHelloThereDialog() 
     throws Exception { 
    Runnable showModalDialog = new 
     Runnable() { 
     public void run() { 
      JOptionPane.showMessageDialog(
       myMainFrame, "Hello There"); 
     } 
    }; 
    SwingUtilities.invokeAndWait 
     (showModalDialog); 
} 

現在上面並沒有做任何事情來比從後invokeAndWait完成可用消息對話框以外的東西做的值。

大概事實上,groovy'閉包'實現Runnable將使得代碼比上面更簡單。

是否需要invokeAndWait?如果是這樣的話,請給出一個正確實現的例子,用groovy來得到類似confirmDialog的結果?

+0

如果您正在編寫Swing代碼並使用Groovy,則應該查看Griffon。 – 2011-03-31 08:36:30

+1

@Don感謝您的建議,我知道Griffon,這絕對有趣。另一方面,它比我現在需要的重量要重,而且我也希望在依靠這麼多的「魔術」之前,更好地理解螺栓和螺栓。我真正意識到的唯一文檔是MEAP「Griffon in Action」http://www.manning.com/almiray/。你知道它是否有用(或者其他來源是否有用)? – 2011-03-31 12:24:01

回答

4

看看groovy.swing.SwingBuilder,它封裝invokeAndWait和invokeLater的。你的例子可以被寫爲:

import groovy.swing.SwingBuilder 
import javax.swing.* 
import java.awt.* 

def swing = new SwingBuilder() 
def myMainFrame = new Frame() 

swing.edt { 
    JOptionPane.showMessageDialog(
     myMainFrame, "Hello There"); 
} 
5

這應該在EDT上,所以invokeAndWait或invokeLater是必需的。您可以知道,因爲JOptionPane.showMessageDialog的代碼最終創建並修改了Swing組件。從Java 6開始,Sun說所有對Swing組件的操作(無論它們是否已經實現)都必須在EDT上完成。

http://download.oracle.com/javase/6/docs/api/javax/swing/package-summary.html

http://www.velocityreviews.com/forums/t707173-why-does-jdk-1-6-recommend-creating-swing-components-on-the-edt.html

8

JOptionPane到的showXXXDialog之一(A呼叫)BLOCKING,直到用戶選擇OK /取消/等。通常情況下,您不要在事件調度線程(EDT)上放置這樣慢的阻塞例程,因爲每個其他GUI組件都會凍結。所以,沒有把它放在EDT上的直覺是好的,但它也是錯誤的。原因如其他人所述,該方法創建GUI組件,並且這應該始終在EDT上完成。但是阻塞呢?你會注意到,即使你在EDT上運行它,它也能正常工作。原因在源代碼中找到。 JOptionPane類創建一個對話框對象,然後調用show()後跟dispose(),其中第一個是阻塞線程。如果你讀了註釋(或javadoc的),你會看到,它說,這對方法:

如果對話框是形式上的,不可見,這個調用不會 返回,直到對話框被隱藏叫隱藏或處置。允許顯示來自事件調度線程 的模態對話框的 ,因爲該工具包將確保另一個事件泵運行,而調用此方法的 被阻止。

因此,在EDT上運行JOptionPane是絕對安全的,儘管它阻塞了它。顯然,將Dialog的show()方法從EDT調出是安全的,但JOptionPane也是如此,因爲它的方法是創建GUI組件,添加偵聽器,在模態時訪問其他容器並阻止對它們的輸入等等。您不希望全部這是因爲它不是線程安全的並且可能存在問題。無可否認,在美國東部時間使用JOptionPane時我從來沒有遇到過問題,所以機會似乎很低,但他們肯定是可能的。爲對話框的容器傳入一個空值,並且只給這些字段的參數賦予不可變對象(如String s)將顯着減少(甚至可能消除據我所知)事件發生的可能性,因爲所有相關的GUI組件都是在不可見的情況下在同一個線程中創建和訪問。但是,你應該安全並將其放在EDT上。撥打SwingUtilities.invokeAndWait()並不難。

+0

+1,有很好的理由和詳盡的答案 – 2012-10-25 12:05:07

相關問題