2017-03-13 4 views
0

J'utilise Goyave EventBus dans Vaadin + projet de printemps et a commencé à avoir un problème avec l'affichage d'un événement de fil d'arrière-plan.Poster un événement de thread différent avec Guava EventBus

EventBus est instancié en classe wrapper. Les objets communiquent avec le bus d'événements en utilisant la méthode statique définie dans la classe d'interface utilisateur principale pour obtenir l'objet EventBus. C'est la même manière que celle proposée dans l'exemple de Vaadin Dashboard (DashboardEventBus).

public class MainUI extends UI implements ViewDisplay 
{ 
    private EventBusWrapper eventbus_ = new EventBusWrapper(); 

    public static EventBusWrapper GetEventBusWrapper() 
    { 
     return ((MainUI) getCurrent()).eventbus_; 
    } 
} 

Un problème apparaît dans les classes presenter/services où je crée une nouvelle classe de thread et démarre le thread. Inside Exécution exécutable de la méthode run Je crée un autre objet qui fait un travail. Il effectue une validation/vérification et crée d'autres classes auxiliaires.

public class DefaultSearch implements Search 
{ 
    private final Scraper scraper_; 
    ... 

    @Override 
    public void Search() 
    { 
     if(!scraper_.IsConfigured()) 
      return; 
     ... 
     scraper_.FindElements(); 
    } 
} 

Ensuite, à l'intérieur du corps FindElements de grattoir J'essaie de poster un événement en utilisant la méthode post statique définie dans EventBusWrapper.

public class HttpElementScraper extends WebScraper 
{ 
    ... 

     @Override 
     public Collection<Element> FindElements() 
     { 
      ... 
      Element elem = ... 
      Event.UserSearchElementFound e = new Event.UserSearchElementFound(elem); 
      EventBusWrapper.post(e); 

      return foundelements; 
     } 
    } 

A ce moment, la NullPointerException est levée et je ne peux pas résoudre moi-même et aider avec le problème.

Exception in thread "Thread-10" java.lang.NullPointerException 
    at com.project.MainUI.GetEventBusWrapper(MainUI.java:109) 
    at com.project.events.EventBusWrapper.register(EventBusWrapper.java:24) 
    at com.project.service.search.scraper.HttpElementScraper.FindElements(HttpElementScraper.java:92) 
    at com.project.service.search.DefaultSearch.Search(DefaultSearch.java:38) 
    at com.project.view.search.SearchResultsPresenter$UpdateContentComponentThread.run(SearchResultsPresenter.java:71) 

// J'ai omis des lignes de code et des annotations non importantes. La plupart des composants et services qui leur sont connectés sont UIscoped.

Répondre

2

Vaadin suppose que l'accès aux instances composant Vaadin (et connexes) est synchronisée correctement. Lorsque vous utilisez le cycle demande-réponse traditionnel à un seul thread pour accéder aux composants, il est automatiquement synchronisé.

Lorsque vous utilisez des fils externes, vous devez synchroniser code d'accès à vos composants Vaadin en utilisant UI.access(). Par exemple:

getUI().access(() -> label.setValue("Hello"));