Podpora souběžnosti pracovní plochy

Viděli jste, že rámec uživatelského rozhraní JFace poskytuje základní podporu pro zobrazení postupu úlohy v dialogovém okně (viz Dlouhodobá operace, kde jsou uvedeny podrobnosti). V Souběžné infrastruktuře jsme uvedli přehled běhové podpory platformy pro souběžné a dlouhodobé operace. Nyní se podívejme, jak uživatelské rozhraní platformy tuto infrastrukturu rozšiřuje v balíčku org.eclipse.ui.progress. Tento balíček dodává uživatelské rozhraní pro zobrazení průběhu úkolu na pracovní ploše a definuje dodatečnou podporu pro úkoly, které běží v podprocesu uživatelského rozhraní.

Nejprve se věnujme různým typům operací spuštěných v pozadí a způsobu jejich zobrazení v uživatelském rozhraní pracovní plochy:


V prostředí, ve kterém může současně docházet k několika dějům, uživatel potřebuje:

Služba indikace průběhu

Služba indikace průběhu pracovní plochy (IProgressService) je primárním rozhraním průběhové podpory pracovní plochy. Je možné ji získat z pracovní plochy a pak použít k zobrazení průběhu pro operace v pozadí i operace běžící v podprocesu uživatelského rozhraní. Hlavním účelem této třídy je poskytnutí jednoho hlavního místa pro běžící operace, čímž jsou vývojáři modulů plug-in zbaveni povinnosti rozhodovat, které mechanizmy by měly být použity pro zobrazení průběhu v konkrétní situaci. Další výhodou je to, že dialog průběhu zobrazený těmito metodami poskytuje dobrou podporu pro indikování, když je operace blokována jinou a dávají uživateli kontrolu nad vyřešením konfliktu. Tam kde je to možné by dlouhodobé operace měly být spuštěny pomocí IProgressService#busyCursorWhile:

   IProgressService progressService = PlatformUI.getWorkbench().getProgressService();
   progressService.busyCursorWhile(new IRunnableWithProgress(){
         public void run(IProgressMonitor monitor) {
         //dělá práci jinou než s uživatelským rozhraním
      }
   });

Tato metoda nejprve zobrazí běžící kurzor a nahradí jej dialogem průběhu, pokud operace trvá déle, než zadaný časový limit. Přednost této metody nad použitím dialogu průběhu spočívá ve skutečnosti, že dialog průběhu se nezobrazí, pokud jde o rychle dokončenou operaci. Pokud vaše operace musí aktualizovat uživatelské rozhraní, vždy ke spuštění kódu upravujícího uživatelské rozhraní použijte Display.asyncExec nebo Display.syncExec.

Musí-li být celá operace spuštěna v rámci vlákna uživatelského rozhraní, měli byste použít IProgressService#runInUI. Tato metoda zobrazí dialog průběhu a předá řízení uživateli rovněž v situaci, kdy je operace blokována.

   progressService.runInUI(
      PlatformUI.getWorkbench().getProgressService(),
      new IRunnableWithProgress() {
         public void run(IProgressMonitor monitor) {
            //dělá práci související s uživatelským rozhraním
         }
      },
      Platform.getWorkspace().getRoot());

Třetí parametr může být null nebo plánovací pravidlo pro operaci. V tomto příkladu zadáváme kořen pracovního prostoru, který na dobu realizace operace s uživatelským rozhraním uzamkne pracovní prostor.

Službou signalizace průběhu můžete rovněž pro řadu úkolů registrovat ikonu, která se bude zobrazovat v pohledu průběhu vedle spuštěné úlohy. Níže uvádíme příklad přiřazení ikony řadě úkolů automatického sestavení:

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

Zobrazení zaneprázdnění části

IWorkbenchSiteProgressService obsahuje rozhraní API pro plánování úloh, které během své činnosti mění vzhled části pracovní plochy. Pokud váš modul plug-in používá operace běžící v pozadí, které mění stav části, můžete úlohu naplánovat prostřednictvím části a uživateli bude signalizováno zaneprázdnění části. Zde je příklad:

   IWorkbenchSiteProgressService siteService =
      (IWorkbenchSiteProgressService)view.getSite().getAdapter(IWorkbenchSiteProgressService.class);
   siteService.schedule(job, 0 /* nyní */, true /* použije v části kurzor částečného zaneprázdnění */);

Vlastnosti průběhu pro úkoly

Pracovní plocha definuje pro úkoly vlastnosti týkající se průběhu v IProgressConstants . Tyto úkoly lze použít k řízení způsobu zobrazování úkolu v pohledu s průběhem. Ty pak mohou být použity ke sdělení pohledu s průběhem, aby ponechal (IProgressConstants#KEEP_PROPERTY) váš úkol v pohledu po jeho dokončení, nebo ponechal vždy pouze jeden (IProgressConstants#KEEPONE_PROPERTY) úkol v pohledu. K úkolu můžete také přiřadit akci (IProgressConstants#ACTION_PROPERTY). Když je k úkolu přiřazena akce, pohled s průběhem zobrazí hypertextový odkaz, aby mohl uživatel akci spustit. Můžete také zjistit, zda je uživatelský úkol aktuálně zobrazen v dialogu průběhu (IProgressConstants#PROPERTY_IN_DIALOG). Vpravo dole na stavovém řádku je uveden pokyn, když je akce k dispozici. Následující příklad používá tyto vlastnosti:

   Job job = new Job("Do Work") {
         public IStatus run(IProgressMonitor monitor) {
         // provedení určitých úkonů.
         // Ponechat dokončený úkol v pohledu s průběhem pouze v případě, že neběží v dialogu průběhu
         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() {
         // zobrazí výsledky
      }
   };
   job.setProperty(IProgressConstants.ACTION_PROPERTY, gotoAction);
   job.setUser(true);
job.schedule();

Úkoly pracovní plochy

Tam, kde je to možné, by dlouhodobé operace měly být provedeny mimo podproces uživatelského rozhraní. Není však možné se tomu vždy vyhnout, když je účelem operace aktualizace uživatelského rozhraní. Problematika podprocesů SWT vysvětluje, jak to může být provedeno pomocí SWT Zobrazení. Pracovní plocha definuje speciální úkol, UIJob, jehož metoda spuštění běží uvnitř SWT asyncExec. Podtřídy UIJob by měly implementovat metodu runInUIThread namísto metody Spustit.

WorkbenchJob rozšiřuje UIJob, takže úkol může být naplánován nebo spuštěn pouze, když je spuštěna pracovní plocha. Jako vždy byste se měli vyhnout nadměrné práci v podprocesu uživatelského rozhraní, protože uživatelské rozhraní se po dobu trvání úkolu uživatelského rozhraní neobnoví.