3

我讀過幾本關於Java的書。在他們所有人中至少有一章講授GUI編程。在所有這些,創建一個簡單的表格申請按照這樣的邏輯:應該從Event Dispatcher或主線程控制Swing GUI應用程序嗎?

MyFrame.java

public class MyFrame extends JFrame 
{ 
    JButton button1; 

    public MyFrame() 
    { 
     button1 = new JButton("Click here."); 
    } 
} 

FrameTest.java:

public class FrameTest 
{ 
    public static void main(String[] args) 
    { 
     MyFrame myFrame = new MyFrame(); 

     myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     myFrame.setSize(600, 600); 
     myFrame.setVisible(true); 
    } 
} 

基本上,只要子類JFrame的創建形式和將其他組件聲明爲實例變量並在構造函數中初始化這些組件。然後創建另一個測試類,在該類中實例化框架子類並調用其某些方法以使其可見。

但是在併發課程中,我瞭解到我們有一個主線程,它在我們創建的每個應用程序中運行main()。據我所知,當我們使用Swing來創建GUI應用程序時,我們有另一個線程(Event Dispatcher Thread)。所以如果我沒有弄錯,在每個基於Swing的GUI應用程序中至少有兩個線程。這使得每個GUI應用程序都是多線程的。在我讀過的一些文章和教程中,它指出Swing不支持多線程,因此所有GUI組件都應該僅在Event Dispatcher Thread中創建和修改,否則可能會出現線程干擾和內存不一致錯誤。

即使在維基百科(http://en.wikipedia.org/wiki/Swing_%28Java%29)的最簡單示例中,它也是通過invokeLater方法制作的。

那麼哪一個纔是真正的方法?我錯在哪裏?

+3

無論是否擴展'JFrame',關鍵是要在'EDT'上執行GUI任務。所有耗時或阻塞的活動(如網絡I/O)都應該在單獨的線程中運行(例如,通過'SwingWorker'委託)以避免GUI凍結。 – asgs 2013-03-13 20:17:20

回答

7

與任何UI/Swing組件交互必須在美國東部時間範圍內完成

當啓動一個應用程序,你應該確保你在美國東部時間內,然後再嘗試和創建/任何交互執行Swing組件。

簡單地說,你應該使用類似...

EventQueue.invokeLater(new Runnable() { 
    public void run() { 
     // Now in the event dispatching thread 
    } 
}); 

如果你需要運行長時間運行的任務或執行任何任務阻塞,你應該在一個單獨的線程中執行它。在大多數情況下,SwingWorker是一個不錯的選擇,因爲它提供了一些簡單的機制來將代碼重新同步到事件分派線程。

取讀通過

所以,簡單的答案是肯定的,所有基於Swing代碼應訪問/修改/從的情況下與之交互EDT

3

所以如果我沒有弄錯,在每個基於Swing的GUI應用程序中那裏 至少有兩個線程

是的。一個是主線程,另一個是EDT(Event Dispatch Thread)。

這使得每個GUI應用程序都是多線程的。

是的。但在這種情況下,另一個線程不會與GUI組件交互。

搖擺不支持多線程,因此所有的GUI組件 只應在事件調度線程 創建和修改,否則螺紋干涉和內存不一致的錯誤可能出現 。

是的,絕對正確。這意味着一次只有一個線程應該與給定的GUI組件交互。
與下列種的線程的擺動程序員特價:

  • Initial threads,即執行初始應用程序代碼的線程。
  • event dispatch thread,其中執行所有事件處理代碼。與Swing框架交互的大多數代碼也必須在此線程上執行。
  • Worker threads,也被稱爲後臺線程,執行耗時的後臺任務。

程序員並不需要提供明確創建 這些線程代碼:它們是由運行時或搖擺 框架提供。程序員的工作是利用這些線程來創建一個響應式,可維護的Swing程序 。

相關問題