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:
Úkoly iniciované uživatelem jsou úlohy, které spustil uživatel. Pracovní plocha automaticky ukáže uživatelské úkoly v modálním dialogu průběhu, s tlačítkem umožňujícím uživateli spustit operaci v pozadí a pokračovat s prací. Globální předvolba určuje, zda mají uživatelské úkoly vždy běžet na pozadí. Uživatelské úkoly jsou vzájemně odlišeny v rozhraní API úkolu s použitím (Job#setUser). Mezi příklady uživatelských úkolů patří sestavení, zapůjčení projektu, synchronizace s úložištěm, export modulu plug-in a hledání.
Automaticky spuštěné úkoly sice pro uživatele mají význam, avšak samotní uživatelé je nespouštějí. Tyto úkoly se zobrazují v pohledu s průběhem a ve stavovém řádku. Jsou-li však aktivní, nezobrazuje se modální dialog průběhu. Mezi příklady patří automatické sestavení a naplánovaná synchronizace.
Systémové operace nespouští uživatel a lze je považovat za záležitost implementace platformy. Tyto úkoly se vytvářejí nastavením systémového příznaku s použitím (Job#setSystem). Mezi příklady systémových úkolů patří úlohy, které jen pomalu zaplňují prvky nebo provádí výpočet zdobení a anotací pro pohledy.
V prostředí, ve kterém může současně docházet k několika dějům, uživatel potřebuje:
Indikaci, že byla spuštěna dlouhodobě spuštěná operace.
Uživatelské úkoly jsou uživateli zobrazeny v dialogu průběhu, poskytujícím okamžitou zpětnou vazbu, zatímco automaticky spuštěné úkoly jsou zobrazeny na stavovém řádku a v pohledu s průběhem. Úkoly ovlivňující část měly být naplánovány nebo registrovány pro část, aby pracovní plocha mohla uživateli poskytnout informace o spuštění děje, který může ovlivnit část.
Indikaci ukončení operace.
Uživatel je informován o ukončení uživatelského úkolu uzavřením dialogu průběhu. Pro neuživatelské úkoly je k dispozici řada mechanizmů zpětné vazby. Pokud je úloha naplánována nebo registrována pro část, zobrazí se informace o průběhu částí po jejím dokončení. Pokud úkol vrátí chybu, objeví se v pravé spodní části stavového řádku indikátor chyby, zobrazující informaci, že došlo k chybě.
Indikaci nových zajímavých výsledků nebo nových informací bez ztráty výběru aktivního prvku při použití dialogového okna.
Uživatelský úkol může přímo zobrazit výsledky uživateli, když je operace dokončena. Pro neuživatelské úkoly doporučujeme použít k zobrazení výsledků jiný prostředek než dialogové okno, aby nedocházelo k narušování činnosti uživatele. Při spuštění úkolu lze například otevřít pohled a výsledky zobrazovat bez narušení postupu uživatele v tomto pohledu. Navíc lze přidat vlastnosti úkolu indikující, že má úkol zůstat v pohledu s průběhem a že obsahuje akci, která zobrazí výsledky. V tomto případě se v pravém spodním rohu stavového řádku zobrazí varování, pokud úkol zůstává v pohledu s průběhem a má-li výsledky určené k zobrazení uživateli.
Obecný pocit přehledu o tom, co je spuštěno, se schopností monitorovat a zrušit operace v pozadí.
Uživatelské úkoly poskytují uživateli optimální kontrolu, protože je lze snadno rušit a poskytují účinnou signalizaci blokování nebo běžících souběžných operací prostřednictvím karty Podrobnosti dialogu průběhu. Povšimněte si, že rozšířený dialog průběhu, který obsahuje oblast Podrobnosti, se zobrazuje pouze v případě, že moduly plug-in používají IProgressService#busyCursorWhilen nebo IProgressService#runInUI.
Navíc poskytuje pohled s průběhem přístup ke spuštěným úkolům.
Konzistentní vytváření zpráv průběhu všemi instalovanými moduly plug-in.
Výhodou používání služby indikace průběhu API je to, že uživatelé získají konzistentní zkušenosti s průběhem.
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);
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í */);
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();
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í.