Как синхронизировать код с потоком пользовательского интерфейса в Standard Widget Toolkit - PullRequest
1 голос
/ 02 августа 2010

Я продолжаю получать исключение SWTEx, которое говорит «Неверный доступ к потокам», когда я пытаюсь запустить свой код.Я прочитал, и проблема, кажется, имеет код, который пытается получить доступ к объектам SWT извне потока пользовательского интерфейса.В частности, у меня есть виджет таблицы, и я добавил слушатель выбора.Вот код для прослушивателя выбора.

rosterTable.addSelectionListener(new SelectionAdapter()

    {
        public void widgetSelected(final SelectionEvent event)
        {

              createChat(connection,event);


        }

            });

, а вот код для метода createChat:

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

Как вы видите, я тоже пытался синхронизировать код, которыйнаходится вне потока пользовательского интерфейса, с потоком пользовательского интерфейса, оборачивая его в метод syncExec, но я по-прежнему получаю исключение при выборе элемента таблицы, что наводит меня на мысль, что я поместил часть syncExec в неправильное место.

Я также думал, что проблема может быть в том, что объект ClassView, который создается в методе createChat, использует виджеты SWT, но я не уверен.

Кто-нибудь знает, гдекод syncExec должен идти?

Или, если я делаю это совершенно неправильно, как я могу это исправить?

Обновление:

Я сделал то, что вы сказали, и, к сожалению, я все еще получаю исключение,Я немного переделал код, так что теперь он выглядит немного иначе, я не думаю, что это должно иметь какое-либо значение, но на всякий случай вот код для слушателя снова:

 rosterTable.addSelectionListener(new SelectionAdapter()

    {
        public void widgetSelected(final SelectionEvent event)
        {

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

        }






    });

и воткод метода, который теперь находится в другом классе:

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

}

Вот трассировка стека для исключения:

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)

Ответы [ 2 ]

0 голосов
/ 04 августа 2010

Я исправил проблему. Исключение было связано с тем, что в ClassView я пытался создать экземпляр класса SWT Display, когда уже существовал другой его экземпляр. Платформа позволяет открывать только один раз.

Я изменил код так, чтобы использовался только один дисплей, а исключение пропало.

Спасибо за вашу помощь.

0 голосов
/ 02 августа 2010

Вы звоните syncExec() из потока пользовательского интерфейса, что, безусловно, является проблемой.

Все события SWT запускаются в UIThread, поэтому, когда вы вызываете createChat() из widgetSelected(), вы уже наUIThread.В пределах createChat() вы затем снова пытаетесь заблокировать UIThread, что вызывает проблему.

Попробуйте перевести этот вызов на syncExec() и сообщить о происходящем.Включите трассировку стека, если у вас все еще есть исключение.

Если вы создаете простую SWT-программу, обычно вам не нужно беспокоиться о потоке пользовательского интерфейса, поскольку большинство простых приложений работают в ответ на события и т. Д.обрабатывают бизнес-логику в потоке пользовательского интерфейса.Вам нужно начать беспокоиться о потоке пользовательского интерфейса, когда вы начнете создавать потоки (или использовать такие вещи, как java.util.concurrent, которые за кулисами работают для вас), чтобы сделать ваш пользовательский интерфейс более отзывчивым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...