2

Я пытаюсь изучить тонкости Swing и много читал о теме Dispatch Event. Я понимаю, что для, однако борюсь со следующей концепции: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()); 
} 
} 

Я хочу, чтобы породить 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); 
} 
} 

Когда MenuItem получает щелкнул, это называется в контроллере:

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

Как gui является родительским контейнером для JOptionPane, и который был создан с помощью invokeLater, означает ли это, что вновь созданная JOptionPane была вызвана на EDT или вызывается за пределами EDT?

Извините, если это дубликат. Кажется, я не могу найти ответ на этот вопрос.

+0

Его зовут на EDT. –

+0

Спасибо. Итак, вызов для добавления JDialog в 'gui' за пределами потока будет рассмотрен в EDT, потому что именно здесь создан' gui'? – swshaun

+0

Это мое понимание этого. Если вы хотите отделить операцию, вы можете работать над одним из рабочих потоков. http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html –

ответ

2

Ваш вопрос поднимает два важных вопроса:

  • Качели GUI объекты должны быть построены и манипулируют только на event dispatch thread (EDT). Это example является типичным, используя EventQueue.invokeLater(). Обратите внимание, в частности, что метод actionPerformed() для Timer работает на EDT. Напротив, ваш GUITopLevel, кажется, создается в исходном потоке, а не в вашем Runnable.

  • Модальное диалоговое окно блокирует ввод пользователя из других окон того же приложения, но EDT продолжает работать. В поле example добавьте диалог к ​​методу run(), чтобы увидеть эффект.

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

Смотрите также это Q&A и это Q&A на MVC в Swing.

+2

[возможно больше идей здесь] (http://stackoverflow.com/questions/8169964/is-mvc-in-swing-thread-safe) – mKorbel

+0

Спасибо. Я использовал 'swingUtilities.isEventDispatchThread()', чтобы определить, что TopLevelFrame работает на EDT, и кажется, что он (возвращает true). – swshaun

Смежные вопросы