我想在一个新线程中打开一个Eclipse Wizard
或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 :(得分:0)
所有向导,对话框,......必须在单个SWT UI线程中打开。您可以在另一个线程中使用Display.syncExec
调用来在UI线程中运行打开的对话框。
Display.getDefault().syncExec(runnable);
您的Runnable
可以调用对话框open
并将buttonClick
值保存在syncExec
返回时您可以访问的位置。
答案 1 :(得分:0)
GUI系统通常设计为单线程,因为它几乎不可能编写多线程GUI系统。有许多用户交互和太多事件。
这就是为什么GUI框架通常会创建自己的专用线程,并且所有GUI活动都在此线程中。例如,Swing有自己的AWT线程。如果在该线程中执行长时间运行操作,则会导致程序冻结(程序不会对用户输入做出反应)。如果要避免这种情况,必须在不同的线程中运行逻辑。但只有你的逻辑,而不是GUI动作!
有一些有用的类可以解决这个问题 - 例如 SwingWorked ,它设计用于在后台线程中运行冗长的GUI交互任务。