2016-08-08 3 views
0

Je suis incapable de mettre à jour mon interface utilisateur même après avoir enveloppé tout le code SWT dans "Display.getDefault().asyncExec".Display.getDefault(). AsyncExec donne InvocationTargetException

Supposons que j'ai un écouteur qui s'appelle en cliquant sur un bouton.

Listener enterlisner = new Listener() { 
    @Override 
     public void handleEvent(Event event) 
     { 
      Display.getDefault().asyncExec(new Runnable() 
      { 
       public void run() 
       { 
        try 
        { 
         if((event.keyCode == SWT.CR || event.keyCode == 13 || event.type == SWT.Selection) && btnAdd.isEnabled()) 
         { 
          new ProgressMonitorDialog(shell).run(true, true, new IRunnableWithProgress() 
          { 
           @Override 
           public void run(final IProgressMonitor monitor) throws InvocationTargetException, 
             InterruptedException 
           { 

              // method1() 

              // method2() {method2.1() , method2.2()} 

              // method3() {method3.1() , method3.2()} 

              // .... 

              // ... 

              // method10 

           } 
          }); 
         } 
        } 
        catch (InvocationTargetException | InterruptedException e) 
        { 
         e.printStackTrace(); 
        } 
       } 
      }); 
     } 
}; 

Quelqu'un pourrait-il s'il vous plaît se référer et penser link me faire savoir où je me trompe?

Comment bifurquer un morceau de méthodes qui s'exécute dans un thread d'arrière-plan?

+0

Vous devez nous montrer un exemple minimal de votre code et le message exact que vous obtenez. –

+0

Bonjour Greg. Vous pouvez cliquer sur le lien ci-dessus où j'ai écrit le code entier –

+0

Il y a trop de code là et il ne dit pas clairement ce qu'est le InvocationTargetException. Nous avons besoin d'un [mcve]. Mais entourer tout dans asyncExec est presque certainement faux. –

Répondre

2

Envelopper le code entier dans asyncExec lorsque vous êtes déjà dans le thread d'interface utilisateur n'obtient pratiquement rien (sauf pour certaines utilisations très spécialisées).

Vous devez regarder votre code et identifier chaque élément qui s'exécute dans un fil d'arrière-plan. Tout accès aux opérations d'interface utilisateur dans ces lieux doit utiliser un appel asyncExec (ou syncExec) à ce stade.

Le code IRunnableWithProgress que vous transmettez à ProgressMonitorDialog s'exécute dans un fil d'arrière-plan. Ainsi, chaque fois que vous accédez à un objet IU dans le code IRunnableWithProgress, vous devez utiliser un appel séparé asyncExec ou syncExec.

donc quelque chose comme:

Listener enterlisner = new Listener() { 
    @Override 
    public void handleEvent(Event event) 
    { 
    if ((event.keyCode == SWT.CR || event.keyCode == 13 || event.type == SWT.Selection) && btnAdd.isEnabled()) 
    { 
     new ProgressMonitorDialog(shell).run(true, true, new IRunnableWithProgress() 
     { 
      @Override 
      public void run(final IProgressMonitor monitor) throws IvocationTargetException, InterruptedException 
      { 
       ... code not using UI 

       Display.getDefault().asyncExec(... code using UI ....); 

       ... more code not using UI 

       Display.getDefault().asyncExec(... more code using UI ....); 
      } 
     } 
    } 
    } 
+0

Mais que faire si j'ai un mélange de code qui met à jour l'interface utilisateur et ne met pas à jour l'interface utilisateur? Devra-t-il être enveloppé dans plusieurs méthodes asyncExec()? –

+0

Oui, plusieurs appels asyncExec ou syncExec. Édité l'exemple pour montrer ce –

+0

en gardant Display.getDefault(). AsyncExec() de "new ProgressMonitorDialog (shell)" montre la progression en mouvement mais en gardant à l'intérieur de ProgressMonitorDialog() ne montre pas –