2010-02-02 51 views
1

作爲一個更大的應用程序的一部分,我正在編寫一個設置類,它收集並存儲用戶定義的設置。這個類是一個單例,並在應用程序啓動過程中被實例化。JFrame第一次實例化後無法工作?

爲了接受用戶輸入,兩個不同的GUI框架由內ConfigSettings.java insantiated,從一個公共靜態方法,selectSettings()。兩者都是JFrame的子類。下面是用於實例化文件選擇對話框的代碼:

private void selectFile() { 
    SelectFileGUI fileSelector = new SelectFileGUI(); 
    fileSelector.setVisible(true); 
    synchronized(this) { 
     try { 
      wait(); 
     } catch(Exception e) { 
      e.printStackTrace(); 
     } 
    } 
    fileSelector.dispose(); 
} 

當應用程序最初運行時,此工作正常。但是,稍後用戶可能會改變其選擇的設置,包括選擇新的源文件。這是通過再次調用selectSettings()完成的。

時遇到的問題是,任何後續嘗試實例化並顯示這些GUI組件又導致顯示一個新的JFrame,但具有灰色背景,也沒有按鈕或其它組件中。在調試時,我也無法直接創建SelectFileGUI的新實例。

什麼可能導致這種行爲?

+0

是否有任何GUI組件是靜態的?如果是這樣,那麼在第一個JFrame離開後它們可能會消失。顯然,它並沒有消失,但當JFrame離開時它們可能已經關閉,所以它們不再處於可顯示狀態。 – 2010-02-02 01:02:41

回答

2

我會檢查,看看是否你把它叫做第二次您正在使用的GUI線程或者從你自己的線程中調用一個。

在該方法的頂部,您可以測試它(AWT線程很容易通過名稱識別),並讓它拋出一個異常,以便開發人員不要在錯誤的線程中調用它 - 或者可以阻止它們線程並在工作線程中執行。

+0

非常感謝,你完全正確。通過關注線程我現在已經排序好了:) – deyur 2010-02-02 06:00:56

0

同意BillK:聽起來就像你第一次從美國東部時區以外撥打它(所以你的電話wait()不會阻止EDT),然後從美國東部時間第二次。見SwingUtilities.invokeAndWait()和/或Dialog.setModal()

1

我不知道是什麼原因造成這種行爲,但在你的代碼下面根本不可能是管理對話框(詳見下文)的正確方法:

fileSelector.setVisible(true); 
    synchronized(this) { 
     try { 
      wait(); 
     } catch(Exception e) { 
      e.printStackTrace(); 
     } 
    } 
    fileSelector.dispose(); 

你想對你的對話框是模態或不?

如果你想他們是模態的,那麼你只需做一個阻塞調用,當你調用JColorChooser.showDialog(...)方法和你的回報「值」是你的顏色/文件/什麼等。

如果你希望他們非模式,然後使用一個回調以獲取你的顏色/文件。在JColorChooser對話框的例子中,你可以調用createDialog(...)方法並使用ok/cancel監聽器作爲回調函數。

我建議你看看太陽的教程,例如在顏色選擇之一,來看看如何正確地顯示一個模式(或無模式)對話框:

http://java.sun.com/docs/books/tutorial/uiswing/components/colorchooser.html

再次, 同步(this){嘗試{等待()...}來管理一些簡單的事情,如文件選擇器/對話框不能正確。

0

這裏的共識是,你破壞了關於使用AWT的繪畫線程(事件指派線程)的規則。
幾件事情要注意:

  • 如果你的代碼試圖畫這幅畫線程之外的GUI組件,灰色的對話可能是EDT和應用程序正在使用油漆線程之間的死鎖的結果。
  • 如果確實遇到這種情況,您將會遇到無法按照描述創建新對話框的情況。
  • 但是,正如您所提到的,您在調試時遇到此問題,可能是因爲您已通過IDE暫停EDT。

看看this tutorial關於如何在客戶端應用程序中使用線程的一些指導。例如,爲了完全理解這個問題,很高興看到更多與代碼相關的代碼部分selectSettings()