32

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!

ChrisH
  • 4,788
  • 26
  • 35
Carven
  • 14,988
  • 29
  • 118
  • 161

2 Answers2

82

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() {
        // ...
    }
});
Jean-Philippe Pellet
  • 59,296
  • 21
  • 173
  • 234
  • Thanks for the example! actually, would both do the same? It seems like both have no difference when I tried it. – Carven May 22 '11 at 12:19
  • 1
    @xEnOn `syncExec` blocks until the passed code is executed; `asyncExec` schedules it asynchronously on a different thread. – Jean-Philippe Pellet May 22 '11 at 18:56
  • @Jean-PhilippePellet Thanks for this! A follow-up question: How can I send parameters to the runnable, or is that possible? – Samuel Lampa Nov 19 '13 at 17:22
  • Define final variables in the outer scope, or subclass `Runnable`. – Jean-Philippe Pellet Nov 19 '13 at 17:55
  • 3
    Correction to my comment: `asyncExec` doesn't schedule it on a different thread (it will always run on the display thread), but will just execute “some time later” and the call won't be blocking. – Jean-Philippe Pellet Mar 17 '14 at 14:36
  • The `Display.getDefault()` javadoc says "Returns the default display. One is created <...> if it did not already exist.". What if I don't want to make my thread an UI one? What are drawbacks? We may just want to somehow access the existing `Display` of the running Eclipse's UI thread. – xmichael91 Dec 06 '16 at 09:43
  • The default display already is the existing UI thread if you're running in an SWT application. Unless you're writing an Eclipse plugin, you cannot access the UI thread of your IDE from your SWT app. – Jean-Philippe Pellet Dec 06 '16 at 11:02
6

Maybe this will help you:

FAQ Why do I get an invalid thread access exception? https://wiki.eclipse.org/FAQ_Why_do_I_get_an_invalid_thread_access_exception%3F

Sk8erPeter
  • 6,899
  • 9
  • 48
  • 67
Diogo
  • 548
  • 2
  • 8