Prise en charge de l'accès concurrent au plan de travail

Nous avons vu que la structure de l'interface utilisateur JFace permet la prise en charge standard de l'affichage de la progression des tâches dans une boîte de dialogue (pour plus d'informations, reportez-vous à la sectionOpérations longues). Dans la section Infrastructure d'accès concurrent, nous avons étudié la prise en charge de l'exécution de la plate-forme pour l'accès concurrent et les opérations longues. A présent, nous allons observer comment l'interface utilisateur de la plate-forme améliore cette infrastructure dans le package org.eclipse.ui.progress. Ce package met à disposition l'interface utilisateur pour afficher la progression des tâches dans le plan de travail et définit la prise en charge complémentaire pour les tâches qui s'exécutent sur l'unité d'exécution de l'interface utilisateur.

Avant de présenter les nouvelles API, commençons par passer en revue quelques concepts. Il convient tout d'abord d'opérer une distinction entre les différents types d'opérations en tâche de fond :


Dans un environnement dans lequel plusieurs éléments peuvent se produire en même temps, l'utilisateur doit :

Ensuite, nous allons découvrir en détail l'utilisation des nouvelles API.

Service de progression

Le service de progression du plan de travail (IProgressService) est l'interface principale pour la prise en charge de la progression dans le plan de travail. Ce service est disponible à partir du plan de travail et est utilisé pour afficher la progression pour les opérations en tâche de fond et les opérations qui sont exécutées au niveau de l'unité d'exécution de l'interface utilisateur. L'objectif principal de cette classe est de proposer un point unique pour exécuter des opérations, supprimer la nécessité, pour les développeurs de plug-ins, de déterminer le plug-in à utiliser pour afficher la progression dans une situation donnée. Un autre avantage est que la boîte de dialogue de progression affichée avec ces méthodes permet une prise en charge appropriée pour indiquer le blocage d'une opération par une autre opération et donner à l'utilisateur le moyen de contrôler la résolution du conflit. Lorsque cela est possible, les opérations longues doivent être exécutées à l'aide de IProgressService#busyCursorWhile:


   IProgressService progressService = PlatformUI.getWorkbench().getProgressService();
   progressService.busyCursorWhile(new IRunnableWithProgress(){
      public void run(IProgressMonitor monitor) {
         // Pour effectuer un travail qui n'est pas associé à l'interface utilisateur
      }
   });

Cette méthode utilise à l'origine un curseur indiquant l'état d'occupation et le remplace par une boîte de dialogue de progression si l'opération dure au-delà d'une durée seuil spécifiée. L'avantage de cette méthode par rapport à une boîte de dialogue de progression est que si l'opération est courte, la boîte de dialogue de progression ne s'affiche pas. Si l'opération doit mettre à jour l'interface utilisateur, vous pouvez toujours transmettre Display.asyncExec ou Display.syncExec pour exécuter le code qui modifie l'interface utilisateur. Si une opération doit être exécutée dans son intégralité au niveau de l'unité d'exécution de l'interface utilisateur, vous devez appeler IProgressService#runInUI. Là encore, l'avantage de cette méthode est qu'elle affiche une boîte de dialogue de progression si l'opération est bloquée et donne le contrôle à l'utilisateur.


   progressService.runInUI(
      PlatformUI.getWorkbench().getProgressService(),
      new IRunnableWithProgress() {
         public void run(IProgressMonitor monitor) {
            // Pour effectuer un travail associé à l'interface utilisateur
         }
      },
      Platform.getWorkspace().getRoot());
 

Le troisième paramètre peut prendre la valeur null ou il peut s'agir d'une règle de planification pour l'opération. En pareil cas, nous spécifions la racine du plan de travail qui va, pour l'essentiel, verrouiller l'espace de travail lorsque l'opération de l'interface utilisateur est exécutée.

Vous pouvez également enregistrer une icône d'une famille de tâches dans le service de progression afin que la vue de progression puisse affiche l'icône en regard de la tâche en cours d'exécution. Voici un exemple d'association d'une icône à la création automatique :


   IProgressService service = PlatformUI.getWorkbench().getProgressService();
   ImageDescriptor newImage = IDEInternalWorkbenchImages.getImageDescriptor(
      IDEInternalWorkbenchImages.IMG_ETOOL_BUILD_EXEC);
   service.registerIconForFamily(newImage, ResourcesPlugin.FAMILY_MANUAL_BUILD);
   service.registerIconForFamily(newImage, ResourcesPlugin.FAMILY_AUTO_BUILD);

Affichage indiquant qu'une partie est occupée

IWorkbenchSiteProgressService ajoute une API pour planifier les tâches qui modifient l'apparence d'une partie du plan de travail lorsque la tâche est en cours d'exécution. Si le plug-in exécute des opérations en tâche de fond qui affectent l'état d'une partie, vous pouvez planifier la tâche via la partie et l'utilisateur est averti que la partie est occupée. Voici un exemple :


   IWorkbenchSiteProgressService siteService =
      (IWorkbenchSiteProgressService)view.getSite().getAdapter(IWorkbenchSiteProgressService.class);
   siteService.schedule(job, 0 /* now */, true /* use half-busy cursor in part */);

Propriétés de progression pour les tâches

Il existe un ensemble de propriétés prédéfinies dans IProgressConstants, qui peuvent être utilisées pour contrôler l'affichage d'une tâche dans la vue de progression. Ces propriétés peuvent être utilisées pour indiquer à la vue de progression de conserver (IProgressConstants#KEEP_PROPERTY) la tâche dans la vue une fois qu'elle est terminée, ou de ne conserver (IProgressConstants#KEEPONE_PROPERTY) qu'une tâche à la fois dans la vue. Vous pouvez également associer une action (IProgressConstants#ACTION_PROPERTY) à une tâche. Lorsqu'une tâche possède une action associée, la vue de progression affiche un lien hypertexte afin que l'utilisateur puisse exécuter l'action. Vous pouvez également savoir si une tâche utilisateur est actuellement affichée dans une boîte de dialogue de progression (IProgressConstants#PROPERTY_IN_DIALOG). Une indication dans la partie inférieure droite de la ligne de statut signale lorsqu'une action est disponible. Voici un exemple qui utilise ces propriétés :


   Job job = new Job("Do Work") {
      public IStatus run(IProgressMonitor monitor) {
         // Pour réaliser un travail et ne conserver que la tâche terminée dans la vue de progression si
         // elle n'est pas exécutée dans la boîte de dialogue de progression
         Boolean inDialog = (Boolean)getProperty(IProgressConstants.PROPERTY_IN_DIALOG);
         if(!inDialog.booleanValue())
            setProperty(IProgressConstants.KEEP_PROPERTY, Boolean.TRUE);
      }
   };
   job.setProperty(IProgressConstants.ICON_PROPERTY, Plugin.getImageDescriptor(WORK_IMAGE));
   IAction gotoAction = new Action("Results") {
      public void run() {
         // Pour afficher les résultats
      }
   };
   job.setProperty(IProgressConstants.ACTION_PROPERTY, gotoAction);
   job.setUser(true);
   job.schedule();

Tâches du plan de travail

Lorsque cela est possible, les opérations longues doivent être réalisées en dehors de l'unité d'exécution de l'interface utilisateur. Cependant, il n'est pas toujours possible d'éviter cet état de fait lorsque l'objectif de l'opération est de mettre à jour l'interface utilisateur. La section Problèmes liés aux unités d'exécution SWT explique comment cette opération peut être réalisée à l'aide de l'affichage SWT. Le plan de travail définit une tâche spéciale, UIJob, dont la méthode run est exécutée dans un élément asyncExec SWT. Les sous-classes de UIJob doivent implémenter la méthode runInUIThread au lieu de la méthode run.

WorkbenchJob étend UIJob afin que la tâche ne puisse être planifiée ou exécutée que lorsque le plan de travail est en cours d'exécution. Comme toujours, vous devez éviter le travail en excès au niveau de l'unité d'exécution de l'interface utilisateur car celle-ci n'est pas actualisée pendant la durée de la tâche de l'interface utilisateur.

Notifications juridiques