Vi har sett at rammeverket for JFace-brukergrensesnittet gir grunnleggende støtte for visning av
oppgavefremdrift i en dialogboks (du finner mer informasjon under Tidkrevende
operasjoner). Under Infrastruktur for samtidighet så vi på
plattformens kjøretidsstøtte for samtidighet og tidkrevende operasjoner. Vi skal nå se
nærmere på hvordan plattformens brukergrensesnitt forbedrer denne infrastrukturen i
pakken
org.eclipse.ui.progress. Denne pakken inneholder brukergrensesnittet for visning
av jobbfremdrift i arbeidsbenken og definerer ytterligere støtte for jobber som kjører i
brukergrensesnittråden.
La oss først se på de ulike bakgrunnsoperasjonene som kjører og hvordan de vises i arbeidsbenkens brukergrensesnitt:
Jobber som er brukerstartet, er jobber som brukeren har utløst. Arbeidsbenken viser automatisk brukerjobber i en modal fremdriftsdialogboks med en knapp som brukeren kan velge for å kjøre operasjonen i bakgrunnen, og fortsette arbeidet. En global preferanse brukes for å angi om brukerjobber alltid skal kjøres i bakgrunnen. Brukerjobber angis som brukerjobber i jobbprogrammeringsgrensesnittet ved hjelp av (Job#setUser). Eksempler på brukerjobber er bygging, uthenting av et prosjekt, synkronisering med datalageret, eksport av en plugin-modul og søking.
Jobber som utløses automatisk er nyttige for brukerne, men startes ikke av brukeren. Disse jobbene vises i fremdriftsvisningen og statuslinjen, men det blir ikke vist noen modal fremdriftsdialogboks når de kjøres. Automatisk bygging og planlagt synkronisering er eksempler på dette.
Systemoperasjoner utløses ikke av brukeren og kan betraktes som en plattformimplementeringsdetalj. Disse jobbene opprettes ved å definere systemflagget ved hjelp av (Job#setSystem). Eksempler på systemjobber er jobber som fyller ut widgeter eller behandler dekorasjoner og annotasjoner for visninger.
En bruker trenger følgende i et miljø der det skjer flere ting samtidig:
Indikasjon på at en tidkrevende operasjon har startet.
Brukeren ser brukerjobber i en fremdriftsdialogboks som gir umiddelbar tilbakemelding, mens
jobber som utløses automatisk, vises på statuslinjen og i fremdriftsvisningen. Jobber som virker inn på
en del, må være planlagt eller registrert med delen
slik at arbeidsbenken kan gi brukeren tips om at noe som påvirker delen, kjøres.
Indikasjon på at en operasjon er avsluttet.
Brukeren vet når en brukerjobb avsluttes fordi fremdriftsdialogboksen lukkes. For
jobber som ikke startes av brukeren, finnes det også et par tilbakemeldingsmekanismer. Hvis jobben
er planlagt eller registrert med en del, vil delens
fremdriftstips bli vist når den er fullført. Hvis jobben returnerer en feil, vises en feilindikator
nederst til høyre på statuslinjen som angir at det har oppstått en feil.
Diskret indikasjon på nye interessante resultater eller ny informasjon uten å bruke en dialogboks.
En brukerjobb kan vise resultater direkte for brukeren når operasjonen er fullført. For
jobber som ikke startes av brukeren, slipper brukeren å bli forstyrret når resultatene
ikke blir vist i dialogbokser. En visning kan for eksempel åpnes når jobben starter
og resultatet vises i denne visningen uten å forstyrre brukerens arbeidsflyt. I tillegg
kan det legges til jobbegenskaper for å angi at jobben skal beholdes i
fremdriftsvisningen, og samtidig angi at den inneholder en handling som viser resultatet.
I så fall vises en advarselindikator nederst til høyre på statuslinjen når det gjenstår en jobb
i fremdriftsvisningen som har resultater som skal vises til brukeren.
En generell opplevelse av å ha kontroll over hva som kjøres og kunne overvåke og avbryte bakgrunnsoperasjoner.
Brukerjobber gir brukeren mest kontroll siden det er enkelt å avbryte dem og de tydelig
angir blokkerende eller samtidige operasjoner som kjøres, via fanebladet Detaljer
i fremdriftsdialogboksen. Merk at den utvidede fremdriftsdialogboksen med fanebladet
Detaljer, bare vises når plugin-modulen bruker IProgressService#busyCursorWhile
eller IProgressService#runInUI.
I tillegg gir fremdriftsvisningen tilgang til jobber som kjører.
Enhetlig fremdriftsrapportering fra alle installerte plugin-moduler.
Fordelen med å bruke fremdriftstjenestens programmeringsgrensesnitt, er at brukerne
opplever fremdriften som enhetlig.
Arbeidsbenkens fremdriftstjeneste (IProgressService) er det primære grensesnittet for arbeidsbenkens fremdriftsstøtte. Dette kan hentes fra arbeidsbenken og deretter brukes for å vise fremdrift både for bakgrunnsoperasjoner og operasjoner som kjøres i brukergrensesnittråden. Hovedformålet med denne klassen er å oppgi ett sted for kjøring av operasjoner, noe som fjerner behovet for at plugin-utviklere må avgjøre hva slags mekanisme som skal brukes for å vise fremdriften i en gitt situasjon. En annen fordel er at fremdriftsdialogboksen som vises med disse metodene, gir god støtte for å angi når en operasjon blokkeres av en annen operasjon og gir brukeren kontroll til å løse konflikten. Der det er mulig skal tidkrevende operasjoner kjøres ved hjelp av IProgressService#busyCursorWhile:
IProgressService progressService = PlatformUI.getWorkbench().getProgressService(); progressService.busyCursorWhile(new IRunnableWithProgress(){ public void run(IProgressMonitor monitor) { //do non-UI work } });
Denne metoden viser først en opptattmarkør som erstattes med en fremdriftsdialogboks, hvis operasjonen varer lenger enn en oppgitt tidsgrenseverdi. Fordelen med denne metoden fremfor en fremdriftsdialogboks, er at fremdriftsdialogboksen ikke blir vist hvis ikke operasjonen er langvarig. Hvis operasjonen skal oppdatere brukergrensesnittet, kan du alltid bruke Display.asyncExec eller Display.syncExec for å kjøre koden som endrer brukergrensesnittet.
Hvis en operasjon i sin helhet skal kjøres i brukergrensesnittråden, må IProgressService#runInUI brukes. Denne metoden viser også en fremdriftsdialogboks hvis operasjonen er blokkert og gir brukeren kontroll.
progressService.runInUI( PlatformUI.getWorkbench().getProgressService(), new IRunnableWithProgress() { public void run(IProgressMonitor monitor) { //do UI work } }, Platform.getWorkspace().getRoot());
Den tredje parameteren kan være null eller en planleggingsregel for operasjonen. I dette eksempelet angir vi arbeidsområderoten som låser arbeidsområdet mens brukergrensesnittoperasjonen kjøres.
Du kan også registrere et jobbfamilieikon med fremdriftstjenesten slik at fremdriftsvisningen viser ikonet ved siden av jobben som kjøres. Her er et eksempel som viser hvordan den automatisk bygde jobbfamilien, tilknyttes ikonet:
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 inneholder programmeringsgrensesnitt for planleggingsjobber som kan endre utseendet til en arbeidsbenkdel mens jobben kjøres. Hvis plugin-modulen kjører bakgrunnsoperasjoner som påvirker tilstanden til en del, kan du planlegge jobben via delen og brukeren får tilbakemelding om at delen er opptatt. Her er et eksempel:
IWorkbenchSiteProgressService siteService = (IWorkbenchSiteProgressService)view.getSite().getAdapter(IWorkbenchSiteProgressService.class); siteService.schedule(job, 0 /* now */, true /* use the half-busy cursor in the part */);
Arbeidsbenken definerer fremdriftsrelaterte egenskaper for jobber i IProgressConstants . Disse kan brukes for å kontrollere hvordan jobben vises i fremdriftsvisningen. Disse kan brukes til å angi fremdriftsvisningen for å beholde (IProgressConstants#KEEP_PROPERTY) jobben i visningen etter at den er fullført, eller bare beholde en (IProgressConstants#KEEPONE_PROPERTY) jobb om gangen i visningen. Du kan også knytte en handling (IProgressConstants#ACTION_PROPERTY) til en jobb. Når det er tilknyttet en jobb til en handling, viser fremdriftsvisningen en hyperlink slik at brukeren kan kjøre handlingen. Du kan finne ut om en brukerjobb vises i fremdriftsdialogboksen (IProgressConstants#PROPERTY_IN_DIALOG). Når en handling er tilgjengelig, vises et tips nederst til høyre på statuslinjen. Eksempelet nedenfor bruker disse egenskapene:
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();
Der det er mulig skal tidkrevende operasjoner utføres utenfor en brukergrensesnittråd. Dette kan imidlertid ikke alltid unngås når formålet med operasjonen er å oppdatere brukergrensesnittet. Trådbehandlingsspørsmål beskriver hvordan dette kan gjøres ved hjelp av SWT Display. Arbeidsbenken definerer en spesialjobb, UIJob, som har en kjøringsmetode som kjøres i en SWT asyncExec. Subklasser for UIJob skal implementere metoden runInUIThread i stedet for metoden run.
WorkbenchJob utvider UIJob slik at jobben bare kan planlegges eller kjøres når arbeidsbenken kjører. Som alltid bør du unngå omfattende arbeid i brukergrensesnittråden fordi brukergrensesnittet ikke oppdateres så lenge brukergrensesnittjobben eksisterer.