Vi har sett att JFace UI-ramverket tillhandahåller grundläggande stöd för visning av aktivitetsförlopp i en dialogruta (se Tidskrävande åtgärder för mer information). I Infrastruktur för samtidighet, gick vi igenom plattformens körningsfunktioner för samtidiga och långvariga operationer. Nu ska vi ta en titt på hur plattformens användargränssnitt förbättrar denna infrastruktur i paketet org.eclipse.ui.progress. Detta paket tillhandahåller användargränssnittet för visning av jobbförlopp i arbetsmiljön och definierar ytterligare stöd för jobb som körs i UI-tråden.
Låt oss först ta en titt på de olika typerna av bakgrundsoperationer som kan vara igång och hur de visas i arbetsmiljöns användargränssnitt:
Användarinitierade jobb är dem som användaren har startat. Arbetsmiljön visar automatiskt användarjobb i en modal dialogruta med en knapp som gör det möjligt för användaren att köra operationen i bakgrunden och fortsätta arbeta. En global inställning används till att ange huruvida användarjobb alltid ska köras i bakgrunden. Användarjobb urskiljs som sådana i jobb-APIt med (Job#setUser). Exempel på användarjobb är byggande, utcheckning av ett projekt, synkronisering med lagret, exportering av ett insticksprogram och sökning.
Automatiskt startade jobb har en betydelse för användare men startas inte av dem. Dessa jobb visas i förloppsvyn och på statusraden men ingen modal dialogruta visas när de körs. Exempel på dessa är automatiskt byggande och schemalagda synkroniseringar.
Systemoperationer startas inte av användaren och kan anses vara en plattformsimplementationsdetalj. Dessa jobb skapas när systemflaggan anges med (Job#setSystem). Exempel på systemjobb är jobb som snabbt befolkar kontroller eller beräknar dekorationer och anteckningar för vyer.
Givet en miljö där flera saker kan hända samtidigt, behöver en användare följande:
Indikering på att en långvarig operation har startats.
Användarjobb visas för användaren i en förloppsdialogruta som ger omedelbar återkoppling, medan automatiskt startade jobb visas på statusraden och i förloppsvyn. Jobb som påverkar en del ska vara schemalagda eller registrerade med delen
så att arbetsmiljön kan tillhandahålla tips till användaren om att någonting körs som påverkar den delen.
Indikering på att en operation har slutförts.
Användaren får enkelt reda på när ett användarjobb avslutas eftersom förloppsdialogrutan stängs. För jobb som inte startats av användaren finns några återkopplingsmekanismer tillgängliga. Om jobbet är schemalagt eller registrerat med en del visas delens förloppstips när det har slutförts. Om ett jobb returnerar ett fel, visas en felindikator längst ned till höger på statusraden med ett tips på att ett fel har uppstått.
Indikering på intressanta nya resultat eller ny information, utan att stjäla för mycket uppmärksamhet genom att använda en dialogruta.
Ett användarjobb kan direkt visa resultaten för användaren när operationen slutförs. För jobb som inte startats av användaren rekommenderas att använda något annat än en dialogruta till att visa resultat så att användaren inte störs. Ett exempel: en vy kan öppnas när jobbet startas och resultaten sedan visas i denna vy utan att användarens arbetsflöde störs. Dessutom kan jobbegenskaper läggas till som anger att det ska behållas i förloppsvyn och att det tillhandahåller en åtgärd som visar resultaten. I det här fallet visas en varningsindikator längst ned till höger på statusraden när ett jobb förblir i förloppsvyn och har resultat att visa användaren.
En allmän känsla av att vara i kontroll över det som körs med möjlighet att övervaka och avbryta bakgrundsoperationer.
Användarjobb ger den bästa kontrollen för användaren eftersom de enkelt kan avbrytas och de ger en stark indikering på blockerande eller samtidiga operationer som körs visa fliken Detaljer i förloppsdialogrutan. Lägg märke till att den utökade förloppsdialogrutan som tillhandahåller området Detaljer vara visas när insticksprogram använder IProgressService#busyCursorWhile
eller IProgressService#runInUI.
Dessutom ger förloppsvyn tillgång till jobb som körs.
Konsekvent rapportering av förloppet av alla installerade insticksprogram.
Fördelen med att använda förloppstjänstens API är att användarna får en konsekvent förloppsupplevelse.
Arbetsmiljöns förloppstjänst (IProgressService) är det primära gränssnittet till arbetsmiljöns förloppsstöd. Det kan erhållas från arbetsmiljön och sedan användas till att visa förloppet för både bakgrundsoperationer och operationer som körs i UI-tråden. Det främsta syftet med denna klass är att tillhandahålla en enda plats för körning av operationer och tar bort behovet för insticksprogramutvecklare att bestämma vilken mekanism som ska användas till att visa förlopp i en given situation. En annan fördel är att den förloppsdialogruta som visas med dessa metoder ger ett bra stöd att ange när en operation blockeras av en annan och ger användaren kontrollen att lösa konflikten. Där det är möjligt ska långvariga operationer köras med IProgressService#busyCursorWhile:
IProgressService progressService = PlatformUI.getWorkbench().getProgressService(); progressService.busyCursorWhile(new IRunnableWithProgress(){ public void run(IProgressMonitor monitor) { //do non-UI work } });
Den här metoden visar initialt en upptagenmarkör och ersätter den med en förloppsdialogruta om operationen varar längre än ett angivet tidsgränsvärde. Fördelen med denna metod jämfört med en förloppsdialogruta är att dialogrutan inte visas om operationen inte är långvarig. Om din operation måste uppdatera användargränssnittet kan du alltid använda Display.asyncExec eller Display.syncExec till att köra koden som modifierar användargränssnittet.
Om en operation måste köras i sin helhet i UI-tråden bör IProgressService#runInUI användas. Denna metod visar även en förloppsdialogruta om operationen blockeras och ger användaren kontroll.
progressService.runInUI( PlatformUI.getWorkbench().getProgressService(), new IRunnableWithProgress() { public void run(IProgressMonitor monitor) { //do UI work } }, Platform.getWorkspace().getRoot());
Den tredje parametern kan vara null eller en schemaläggningsregel för operationen. I det här exemplet anger vi arbetsyteroten som egentligen låser arbetsytan medan denna UI-operation körs.
Du kan också registrera en ikon för en jobbfamilj med förloppstjänsten så att förloppsvyn kan visa ikonen bredvid jobbet som körs. Här är ett exempel som visar hur den automatiskt byggande jobbfamiljen associeras till sin ikon:
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 innehåller API för schemaläggning av jobb som ändrar utseendet på en arbetsmiljödel när jobbet körs. Om ditt insticksprogram kör bakgrundsoperationer som påverkar en dels läge, kan du schemalägga jobbet via delen och användaren får då återkoppling om att delen är upptagen. Här är ett exempel:
IWorkbenchSiteProgressService siteService = (IWorkbenchSiteProgressService)view.getSite().getAdapter(IWorkbenchSiteProgressService.class); siteService.schedule(job, 0 /* now */, true /* use the half-busy cursor in the part */);
Arbetsmiljön definierar förloppsrelaterade egenskaper för jobb i IProgressConstants . Dessa kan användas till att styra hur ett jobb visas i förloppsvyn. Dessa kan användas till att be förloppsvyn behålla (IProgressConstants#KEEP_PROPERTY) ditt jobb i vyn när det har slutförts eller att bara behålla ett (IProgressConstants#KEEPONE_PROPERTY) jobb åt gången i vyn. Du kan också associera en åtgärd (IProgressConstants#ACTION_PROPERTY) med ett jobb. När ett jobb har en associerad åtgärd visar förloppsvyn en hyperlänk så att en användare kan köra åtgärden. Du kan också få reda på om ett användarjobb visas i en förloppsdialogruta (IProgressConstants#PROPERTY_IN_DIALOG). Ett tips visas längst ned på statusraden när en åtgärd är tillgänglig. Följande exempel använder dessa egenskaper:
Job job = new Job("Do Work") { public IStatus run(IProgressMonitor monitor) { // do some work. // Keep the finished job in the progress view only if it is not running in the progress dialog 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() { // show the results } }; job.setProperty(IProgressConstants.ACTION_PROPERTY, gotoAction); job.setUser(true); job.schedule();
Där det är möjligt ska långvariga operationer utföras utanför UI-tråden. Däremot kan detta inte alltid undvikas när operationens syfte är att uppdatera användargränssnittet. SWT-trådproblem beskriver hur detta kan göras med SWT-visning. Arbetsmiljön definierar ett specialjobb, UIJob, vars körningsmetod körs inuti en SWT asyncExec. Underklasser för UIJob ska implementera metoden runInUIThread istället för metoden run.
WorkbenchJob utökar UIJob så att jobbet bara kan schemaläggas eller köras när arbetsmiljön är igång. Som alltid ska du undvika omfattande arbete i UI-tråden eftersom användargränssnittet inte uppdateras under UI-jobbets varaktighet.