2016-01-14 24 views
1

我想開一個Eclipse WizardMessageDialog在一個新的線程,但不知何故,我總是得到這樣一個例外:使用這樣的代碼時打開Eclipse嚮導或者Eclipse MessageDialog新主題

Exception in thread "Thread-7" org.eclipse.swt.SWTException: Invalid thread access 
    at org.eclipse.swt.SWT.error(SWT.java:4491) 
    at org.eclipse.swt.SWT.error(SWT.java:4406) 
    at org.eclipse.swt.SWT.error(SWT.java:4377) 
    at org.eclipse.swt.widgets.Widget.error(Widget.java:482) 
    at org.eclipse.swt.widgets.Shell.<init>(Shell.java:266) 
    at org.eclipse.swt.widgets.Shell.<init>(Shell.java:362) 
    at org.eclipse.jface.window.Window.createShell(Window.java:486) 
    at org.eclipse.jface.window.Window.create(Window.java:429) 
    at org.eclipse.jface.dialogs.Dialog.create(Dialog.java:1096) 
    at org.eclipse.jface.window.Window.open(Window.java:792) 
    at org.eclipse.jface.dialogs.MessageDialog.open(MessageDialog.java:330) 
    at de.uka.ipd.sdq.beagle.gui.GuiController$DialogPolling.run(GuiController.java:126) 
    at java.lang.Thread.run(Thread.java:745) 

/** 
* Opens up the dialog displaying the actions "pause", "continue", and "abort" to the 
* user. These actions are regarding the analysis. 
*/ 
private void engageDialog() { 
    final String dialogTitle = "Beagle Analysis is Running"; 
    final String dialogMessage = "Beagle Analysis is running."; 
    final String[] buttonLabels = {"Abort", "Pause"}; 
    this.messageDialog = 
     new MessageDialog(this.shell, dialogTitle, null, dialogMessage, MessageDialog.INFORMATION, buttonLabels, 0); 
    new Thread(new DialogPolling()).start(); 
} 

private class DialogPolling implements Runnable { 

    @Override 
    public void run() { 
     final int buttonClick = GuiController.this.messageDialog.open(); // line 126 

     if (buttonClick == 0) { 
      System.out.println("User clicked 'Abort'."); 
     } 

     if (buttonClick == 1) { 
      System.out.println("User clicked 'Pause'."); 
     } 
    } 
} 

這是從GuiController和線126被標記。如果看不到行號,請向右滾動。

如何在新線程中打開向導或MessageDialog?

回答

0

必須在單個SWT UI線程中打開所有嚮導,對話框...。您可以在另一個線程中使用Display.syncExec調用來運行在UI線程中打開的對話框。

Display.getDefault().syncExec(runnable); 

Runnable可以調用對話框open和保存在某個地方的buttonClick值,你可以訪問時syncExec回報。

0

GUI系統通常設計爲單線程,因爲它幾乎不可能編寫多線程GUI系統。有許多用戶交互和太多事件。

這就是爲什麼GUI框架通常會創建他自己的專用線程,並且所有GUI活動都將在此線程中進行。例如Swing有它的AWT線程。如果在此線程中執行長時間運行操作,則會導致程序凍結(程序不會對用戶輸入做出反應)。如果你想避免這種情況,你必須在不同的線程中運行你的邏輯。但只有你的邏輯,而不是GUI操作!

有一些有用的類來解決這個問題 - 像SwingWorked,那就是設計在後臺線程中運行冗長GUI交互任務。