0

Here is the problem.

My main class implements SerialPortEventListener. After Serial event occurs, i have to check the String in a Text (i am using SWT API). Apparently, i can not reach text in a Text with Text.getText(), and get SWTException: Invalid thread access.

I tired to look here (Invalid Thread Access Error with Java SWT) and some other similar posts, but using this approach i get some other issues.

How can I access members of the UI to check their values?

Community
  • 1
  • 1
PauliusM
  • 171
  • 1
  • 11
  • well, i can't find how can i pass some variables to `Runnable` without making them `final` , also, i still need to return some objects from `Runnable`. – PauliusM May 15 '14 at 12:19
  • There's nothing you can do about it. If you interact with the UI, you need to do it using `(a)syncExec`... You *could* get the value before starting your new thread and save it in a field. This would, however, not guarantee that it's the value that's actually in the `Text` at the point of time when you read it. – Baz May 15 '14 at 12:24
  • ok… but… lets say i just received data through Serial Port, and I need to show it to the user. how can i pass this value to a `Runnable` since `SerialPortEventListener` is in another tread…? – PauliusM May 15 '14 at 12:32
  • Do you want to *get* or *set* the text? – Baz May 15 '14 at 12:33
  • actually - both. I need to get path for saving xml file and then update UI with the new value that was received from other device (via serial port). – PauliusM May 15 '14 at 12:40
  • "well, i can't find how can i pass some variables to Runnable without making them final" -> implement a runnable and pass the variables as parameters. if you really need to – Mirco May 15 '14 at 12:42
  • verbose-mode - can you give me a link with example? – PauliusM May 15 '14 at 12:44
  • Just create a new class implementing Runnable which takes the needed variables as constructor parameters and the add you logic in the inherited run method – Mirco May 15 '14 at 12:53
  • Verbose-mode: thanks to good advice. – PauliusM May 19 '14 at 07:30

1 Answers1

0

As already stated in the Exception Message: You are trying to access an UI-Element from a thread that differs from the Display-Thread.

I also stumbled across this several times when I was new to SWT.

You can avoid this issue by invoking the correct Thread, using:

        Display.getDefault().asyncExec(Runnable)

or

        Display.getDefault().syncExec(Runnable)

This way, you can define an anonymous runnable to access the needed information from your Text.

EDIT: Since you already knew about these methods on Display you now have to know how to return a value from that runnable, right? The solution to that depends on what you are going to do with these values. If its not a long-blocking operation, you could continue doing it inside the Display-Thread so you dont have to implement inter-thread-communication.

Otherwise you could use a Monitor-Object which your other thread waits on. If the Display-Thread (with the runnable) is then finished reading the Value of your Text, it can invoke notify on that Monitor (which can be any variable) so that your waiting Thread can continue.

EDIT2, since I can't comment:

MyRunnable runnable = new MyRunnable();
Display.getDefault().syncExec(runnable);

System.out.println(runnable.getText());


private class MyRunnable implements Runnable
{
    String myString;

    @Override
    public void run()
    {
       //Here you can also get the text from your Text-Object
        myString = "MyText";
    }

    String getText()
    {
        return myString;
    }
}
BenMorel
  • 34,448
  • 50
  • 182
  • 322
angrybobcat
  • 268
  • 1
  • 10