2

我想了解Swing的複雜性,並且已經閱讀了關於事件調度線程的大量內容。我明白了什麼是對,但是我用下面的概念掙扎:Java EDT和產卵對話

我已經以正常的方式被援引一個JFrame:

public class Controller { 
GUITopLevel gui = new GUITopLevel(this); 

public void initiate() {   
    SwingUtilities.invokeLater(
      new Runnable() { 
       @Override 
       public void run() { 
        gui.init(); 
       } 
      } 
    ); 
} 

public void menuCatch(JMenuItem eventSource) { 
    JOptionPane.showMessageDialog(gui.topLevelFrame, eventSource.getActionCommand()); 
} 
} 

我想產卵從GUI JDialogs(代碼因而) :

public class GUITopLevel implements FrontOfHouse {  
JFrame topLevelFrame; 

Controller control; 

GUITopLevel(Controller c) { 
    control = c; 
} 

@Override 
public void GUI() {   
    // Create an action 
    MenuAction action = new MenuAction(control); 

    // Create the Frame 
    topLevelFrame = new JFrame(); 

    // Create the menu bar 
    JMenuBar menuBar = new JMenuBar(); 
    JMenu file = new JMenu("File"); 
    JMenu edit = new JMenu("Edit"); 

    JMenuItem file1 = new JMenuItem(); 
    JMenuItem file2 = new JMenuItem(); 
    JMenuItem file3 = new JMenuItem(); 

    JMenuItem edit1 = new JMenuItem(); 

    // Set the actions 
    file1.setAction(action); 
    file2.setAction(action); 
    file3.setAction(action); 
    edit1.setAction(action); 

    // Add the menu items 
    file.add(file1); 
    file.add(file2); 
    file.add(file3); 

    edit.add(edit1); 

    // Set the text 
    file1.setText("Import Diagrams"); 
    file2.setText("Settings"); 
    file3.setText("Exit"); 
    edit1.setText("Cut"); 
    // Add the menus together 
    menuBar.add(file); 
    menuBar.add(edit); 

    // Set size and add menu bar 
    topLevelFrame.setSize(600,400); 
    topLevelFrame.setJMenuBar(menuBar); 

    topLevelFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
} 

@Override 
public void init() { 
    GUI(); 
    //topLevelFrame.pack(); 
    topLevelFrame.setVisible(true); 
} 
} 

當一個菜單項被點擊,這就是所謂的控制器:

public void menuCatch(JMenuItem eventSource) { 
    JOptionPane.showMessageDialog(gui.topLevelFrame, eventSource.getActionCommand()); 
} 

由於gui是JOptionPane的父容器,並且已使用invokeLater創建,這是否意味着新生成的JOptionPane已在EDT上調用,或者它是否在EDT之外被調用?

道歉,如果這是重複的 - 我似乎無法找到這個問題的答案。

+0

它在EDT上被調用。 –

+0

謝謝。因此,在線程外的'gui'上添加一個JDialog的調用將在EDT上處理,因爲這是'gui'創建的地方? – swshaun

+0

這是我對它的理解。如果要分離操作,則可以在其中一個工作線程上工作。 http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html –

回答

2

你的問題提出了兩個關鍵問題:

  • 的Swing GUI對象應當建立並在event dispatch thread(EDT)操縱。這是example是典型的,使用EventQueue.invokeLater()。請特別注意TimeractionPerformed()方法在EDT上運行。相反,您的GUITopLevel似乎是在初始線程中實例化的,而不是在Runnable中實例化的。

  • 模式對話框將阻止來自同一應用程序的其他窗口的用戶輸入,但EDT繼續運行。在example中,向run()方法添加對話框以查看效果。也

    public void run() { 
        ... 
        f.setVisible(true); 
        JOptionPane.showMessageDialog(dt, TITLE); 
    } 
    

請參閱本Q&AQ&A對MVC中搖擺。

+2

[也許更多的想法](http://stackoverflow.com/questions/8169964/is-mvc-in-swing-thread-safe) – mKorbel

+0

謝謝。我使用'swingUtilities.isEventDispatchThread()'來確定TopLevelFrame在EDT上運行,看起來是(返回true)。 – swshaun