Invalid Thread Access Error with Java SWT

Carven picture Carven · May 12, 2011 · Viewed 55k times · Source

I have a simple Java SWT app in Java so far but the weird thing is when I try to launch a messagebox/alert box upon listening to an event fired by one of my own classes, I get an error saying "Invalid thread access".

My class event is fired and heard by the main class but it is when it has to show the MessageBox that the "Invalid thread access" error appear. I am trying to show the MessageBox in a function that consist of all the other codes that will create the SWT GUIs. This is how the function looks like:

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();
        }
    });
}

These are the auxiliary functions together in the class.

<!-- 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();
        }
    }
}

The error stack trace is as follows:

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)

Any help will be great. Thanks!

Answer

Jean-Philippe Pellet picture Jean-Philippe Pellet · May 12, 2011

It is thrown because your listener code is called from outside the SWT Display thread. You run code on the display thread like this:

Display.getDefault().syncExec(new Runnable() {
    public void run() {
        // ...
    }
});

or, asynchronously:

Display.getDefault().asyncExec(new Runnable() {
    public void run() {
        // ...
    }
});