tags:

views:

39

answers:

2

Hi, I keep getting an SWTException that says "Invalid Thread Access" when I try and run my code. I read up and the problem seems to be having code which tries to access SWT objects from outside the UI thread. Specifically I have a table widget and I have added a selection listener. Here is the code for the selection listener.

rosterTable.addSelectionListener(new SelectionAdapter()

    {
        public void widgetSelected(final SelectionEvent event)
        {

              createChat(connection,event);


        }

            });

and here is the code for the createChat method:

public void createChat(final XMPPConnection connection,final SelectionEvent event)
{
    Display.getDefault().syncExec(new Runnable()        
    {
        public void run()
        {
            String s = event.item.toString();
            int length = event.item.toString().length();
            ClassView cv = new ClassView(connection,s.substring(11,length -1),null);
        }
    });

As you can see I've tried too synchronise the code which is outside the UI thread, with the UI thread by wrapping it in the syncExec method but I still get the exception when the table item is selected which leads me to believe I have put the syncExec part in the wrong place.

I also thought the problem may be coming from the fact that the ClassView object that is instantiated in the createChat method uses SWT widgets, but I am not sure.

Does anyone one know where the syncExec code should go?

Or if I am doing it completely wrong, how I can fix it?

Update:

I did what you said and unfortunately I'm still getting the exception, I did a bit of redesign on the code so it looks a little different now, I don't think it should make any difference but just in case here's the code for the listener again:

 rosterTable.addSelectionListener(new SelectionAdapter()

    {
        public void widgetSelected(final SelectionEvent event)
        {

           selectedUser = event.item.toString();
           System.out.println(selectedUser);
           rm.createChat(selectedUser);

        }






    });

and here's the code for the method which is in a different class now:

public void createChat(String item)
{
    int length = item.length();
    Chatter c = new Chatter(connection,item.substring(11,length-1));

}

Here's a stack trace for the exception:

org.eclipse.swt.SWTException: Invalid thread access
at org.eclipse.swt.SWT.error(SWT.java:3884)
at org.eclipse.swt.SWT.error(SWT.java:3799)
at org.eclipse.swt.SWT.error(SWT.java:3770)
at org.eclipse.swt.widgets.Display.checkDisplay(Display.java:721)
at org.eclipse.swt.widgets.Display.create(Display.java:783)
at org.eclipse.swt.graphics.Device.<init>(Device.java:135)
at org.eclipse.swt.widgets.Display.<init>(Display.java:454)
at org.eclipse.swt.widgets.Display.<init>(Display.java:445)
at instantmessengerplugin.ClassView.<init>(ClassView.java:33)
at instantmessengerplugin.Chatter.<init>(Chatter.java:20)
at instantmessengerplugin.RosterManager.createChat(RosterManager.java:48)
at instantmessengerplugin.RosterView$1.widgetSelected(RosterView.java:103)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:228)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1003)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3880)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3473)
at instantmessengerplugin.RosterView.<init>(RosterView.java:158)
at instantmessengerplugin.Connection.connect(Connection.java:110)
at instantmessengerplugin.Connection$1.widgetSelected(Connection.java:65)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:228)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1003)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3880)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3473)
at instantmessengerplugin.Connection.<init>(Connection.java:77)
at instantmessengerplugin.Connection.main(Connection.java:119)
A: 

You are calling syncExec() from within the UI Thread which is definitely a problem.

All SWT events are fired on the UIThread so when you call createChat() from within widgetSelected() you are already on the UIThread. Within createChat() you are then trying to block on the UIThread again which causes a problem.

Try taking out that call to syncExec() and report back on what is happening. Include a stack trace if you are still having the exception.

If you are creating a simple SWT program usually you don't have to worry about the UI Thread since most simple applications do work in response to events and so are processing business logic on the UI Thread. You have to start worrying about the UI Thread when you start spawning threads (or using things like java.util.concurrent that put work on threads for you behind the scenes) in order to make your ui more responsive.

rancidfishbreath
I have updated the question include the stack trace.
Joshy910
You showed the code for createChat() but according to the stacktrace the exception is actually occurring in the constructor of ClassView which is being called by the constructor in Chatter. Can you post some of the relevant code in those two classes? We'll get this tracked down yet.
rancidfishbreath
A: 

I fixed the problem. The exception was coming from the fact that in ClassView I was trying to create a instance of class SWT Display, when there was already another instance of it in existence. The platform only allows one to open at any one time.

I have altered the code so that only one display is used and the exception is gone.

Thank you for all your help.

Joshy910