Java SWT无效的线程访问错误

Car*_*ven 27 java swt

到目前为止,我在Java中有一个简单的Java SWT应用程序,但奇怪的是当我在听到我自己的一个类触发的事件时尝试启动消息框/警告框时,我收到一条错误消息"无效的线程访问".

我的类事件被主类触发并听到,但它必须显示MessageBox时出现"无效线程访问"错误.我试图在一个函数中显示MessageBox,该函数包含将创建SWT GUI的所有其他代码.这是函数的样子:

public void createContents() {
    Shell shell = new Shell();
    //.....all the SWT GUI codes....
    MessageBox msg = new MessageBox(shell, SWT.OK);
    myClass.addEventListener(new MyClassEventClassListener() {
        @Override
        public void myClassEventHandler(MyClassEvent e) {
            msg.setText("Hello");
            msg.setMessage("Event fired!");
            int result = msg.open();
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

这些是课堂上的辅助功能.

<!-- language: lang-java -->
protected static Shell shell;
public static void main(String[] args) {
    MyClass new myClass = new MyClass();

    try {
        SWTApp window = new SWTApp();
        window.open();
    } catch (Exception e) {     
}

public void open() {
    Display display = Display.getDefault();
    createContents();
    shell.open();
    shell.layout();
    while (!shell.isDisposed()) {
        if (!display.readAndDispatch()) {
            display.sleep();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

错误堆栈跟踪如下:

Exception in thread "AWT-EventQueue-0" org.eclipse.swt.SWTException: Invalid thread access
    at org.eclipse.swt.SWT.error(SWT.java:4083)
    at org.eclipse.swt.SWT.error(SWT.java:3998)
    at org.eclipse.swt.SWT.error(SWT.java:3969)
    at org.eclipse.swt.widgets.Display.error(Display.java:1249)
    at org.eclipse.swt.widgets.Display.checkDevice(Display.java:755)
    at org.eclipse.swt.widgets.Display.getShells(Display.java:2171)
    at org.eclipse.swt.widgets.Display.setModalDialog(Display.java:4463)
    at org.eclipse.swt.widgets.MessageBox.open(MessageBox.java:200)
Run Code Online (Sandbox Code Playgroud)

任何帮助都会很棒.谢谢!

Jea*_*let 74

抛出它是因为您的侦听器代码是从SWT Display线程外部调用的.您在显示线程上运行代码如下:

Display.getDefault().syncExec(new Runnable() {
    public void run() {
        // ...
    }
});
Run Code Online (Sandbox Code Playgroud)

或者,异步:

Display.getDefault().asyncExec(new Runnable() {
    public void run() {
        // ...
    }
});
Run Code Online (Sandbox Code Playgroud)

  • 更正我的评论:“asyncExec”不会将其安排在不同的线程上(它将始终在显示线程上运行),但只会“稍后”执行,并且调用不会阻塞。 (3认同)