2010-08-02 4 views
1

Je continue d'obtenir une exception SWTException qui indique "Accès aux threads non valide" lorsque j'essaie d'exécuter mon code. J'ai lu et le problème semble avoir du code qui essaie d'accéder aux objets SWT depuis l'extérieur du thread UI. Plus précisément, j'ai un widget de table et j'ai ajouté un écouteur de sélection. Voici le code pour l'écouteur de sélection.Comment synchroniser le code avec le fil d'interface utilisateur dans la boîte à outils Widget standard

rosterTable.addSelectionListener(new SelectionAdapter() 

    { 
     public void widgetSelected(final SelectionEvent event) 
     { 

       createChat(connection,event); 


     } 

      }); 

et voici le code pour la méthode 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); 
     } 
    }); 

Comme vous pouvez le voir, je l'ai essayé trop synchroniser le code qui est en dehors du thread d'interface utilisateur, avec le thread d'interface utilisateur en l'enveloppant dans la méthode syncExec mais je reçois toujours l'exception quand l'élément de la table est sélectionné ce qui me porte à croire que j'ai mis la partie syncExec au mauvais endroit.

Je pensais également que le problème venait peut-être du fait que l'objet ClassView instancié dans la méthode createChat utilise des widgets SWT, mais je ne suis pas sûr.

Est-ce que quelqu'un sait où le code syncExec devrait aller?

Ou si je le fais complètement faux, comment je peux le réparer?

Mise à jour:

Je l'ai fait ce que vous avez dit et, malheureusement, je reçois toujours l'exception, je l'ai fait un peu de refonte du code afin qu'il ressemble un peu différent maintenant, je ne pense pas qu'il devrait toute différence, mais juste au cas où est ici le code de l'auditeur à nouveau:

rosterTable.addSelectionListener(new SelectionAdapter() 

    { 
     public void widgetSelected(final SelectionEvent event) 
     { 

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

     } 






    }); 

et voici le code pour la méthode qui est dans une classe différente maintenant:

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

} 

Son e est une trace de pile pour l'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) 

Répondre

0

J'ai résolu le problème. L'exception provenait du fait que dans ClassView, j'essayais de créer une instance de la classe SWT Display, alors qu'il existait déjà une autre instance de celle-ci. La plate-forme permet seulement d'ouvrir à la fois.

J'ai modifié le code afin qu'un seul affichage soit utilisé et que l'exception disparaisse.

Merci pour votre aide.

0

Vous appelez syncExec() à partir de l'interface utilisateur fil est certainement un problème.

Tous les événements SWT sont déclenchés sur l'UIThread. Lorsque vous appelez createChat() depuis widgetSelected(), vous êtes déjà sur l'UIThread. Dans createChat() vous essayez ensuite de bloquer à nouveau sur l'UIThread ce qui provoque un problème. Essayez de passer cet appel au syncExec() et signalez ce qui se passe. Incluez une trace de pile si vous avez toujours l'exception. Si vous créez un programme SWT simple, vous n'avez généralement pas à vous soucier du thread UI car la plupart des applications simples fonctionnent en réponse aux événements et traitent donc la logique métier sur le thread UI. Vous devez commencer à vous soucier du thread d'interface utilisateur lorsque vous commencez à générer des threads (ou à utiliser des éléments tels que java.util.concurrent qui vous permettent de travailler en arrière-plan sur les threads) afin de rendre votre interface utilisateur plus réactive.

+0

J'ai mis à jour la question inclure la trace de la pile. – Joshy910

+0

Vous avez montré le code pour createChat() mais selon la pile, l'exception se produit réellement dans le constructeur de ClassView qui est appelé par le constructeur dans Chatter. Pouvez-vous poster une partie du code pertinent dans ces deux classes? Nous allons encore le retrouver. – rancidfishbreath

Questions connexes