powered by Jive Software

Smack Api SWT- Thread Access Error

Hello. I keep getting an Invalid Thread access exception and I can’t figure out why.

I have looked at previous discussions on this subject and I have tried to sync the code in question with the UI thread but I don’t I am doing this in the right place.

I am trying to build an IM application using the smack api. Currently it connects to the server and logs in with my jabber account. It then displays my contacts, but the problem arises when I try to start a chat with one of the contacts. I think the code causing the problem is in the widget selection method for the table near the bottom.

I have indicated in the code where this is.

Can anyone help?

Josh.

public class RosterView {
        public Display display;
    public Shell shell;
        public RosterView(final XMPPConnection connection)
    {
        display = new Display();
        shell = new Shell(display);
        GridLayout gridLayout = new GridLayout();
        gridLayout.numColumns = 3;
        shell.setLayout(gridLayout);
                Label titlelabel = new Label(shell,SWT.NONE);
        titlelabel.setText("Roster");
        GridData data = new GridData();
        data.horizontalAlignment = GridData.FILL;
        data.horizontalSpan = 3;
        data.grabExcessHorizontalSpace = true;
        titlelabel.setLayoutData(data);
                final Table rosterTable = new Table(shell,SWT.BORDER);
        rosterTable.setLinesVisible(true);
        data = new GridData();
        data.horizontalAlignment = GridData.FILL;
        data.horizontalSpan = 3;
        data.grabExcessHorizontalSpace = true;
        rosterTable.setLayoutData(data);
                Button addButton = new Button(shell,SWT.PUSH);
        addButton.setText("Add");
        addButton.setToolTipText("Enter a contact and click here to add to your list");
        data = new GridData();
        data.horizontalAlignment = GridData.FILL;
        data.horizontalSpan = 1;
        addButton.setLayoutData(data);
                                final Text newContact  = new Text(shell,SWT.SINGLE);
        data = new GridData();
        data.horizontalAlignment = GridData.FILL;
        data.horizontalSpan = 2;
        newContact.setLayoutData(data);
                final Roster roster = connection.getRoster();
                getContacts(roster, rosterTable);
                        addButton.addSelectionListener(new SelectionAdapter(){
                        public void widgetSelected(SelectionEvent event)
            {
                if(newContact.getText().equals(""))
                {
                    return;
                }
               try {
                roster.createEntry(newContact.getText(), null, null);
                rosterTable.clearAll();                                    getContacts(roster,rosterTable);
                            } catch (XMPPException e) {
                                                            }
            }
                    });
                        roster.addRosterListener(new RosterListener(){
                        @Override
            public void entriesAdded(Collection<String> arg0) {
                rosterTable.clearAll();                                    getContacts(roster, rosterTable);
                            }             @Override
            public void entriesDeleted(Collection<String> arg0) {
               rosterTable.clearAll();                                   getContacts(roster, rosterTable);
                                        }                public void entriesUpdated(Collection<String> arg0) {
                   rosterTable.clearAll();                                            Roster roster = connection.getRoster();
                    getContacts(roster, rosterTable);
                            }             @Override
            public void presenceChanged(Presence arg0) {
                // TODO Auto-generated method stub
                            }
                    });
                        rosterTable.addSelectionListener(new SelectionAdapter()
                {
            public void widgetSelected(final SelectionEvent event)  // I think this is where the problem is.             {
                                Display.getDefault().asyncExec(new Runnable(){
                                public void run()
                {
                  createChat(connection,event);    Definition for this method can be found below,                      }
                                });
            }
        }
                                        );
                                        shell.pack();
        shell.open();
                while(!shell.isDisposed())
        {
            if(!display.readAndDispatch())display.sleep();
        }
        display.dispose();
        connection.disconnect();
        Connection c = new Connection();
        }
        public void getContacts(Roster roster, Table rosterTable)
    {
                if(roster == null)
    {
        return;
    }
    Collection<RosterEntry> contacts = roster.getEntries();
        for(RosterEntry entry : contacts)
    {
        TableItem item = new TableItem(rosterTable,SWT.NONE);
        item.setText(entry.getUser());
    }
                }
        public void createChat(XMPPConnection connection,SelectionEvent event)
    {
        int length = event.item.toString().length();
        ClassView cv = new ClassView(connection,event.item.toString().substring(11,length -1),null);
            }

Don’t know if this is still an issue, but IIRC the code in your selection listener should be run in the UI thread anyway so you are looking in the wrong place. It’s more likely the code in the RosterListener that needs the Display.asyncExec() as that is accessing the UI, and being a listener is most likely being called by Smack in another thread.