I lavori con esecuzione lunga (quelli che durano più di un secondo) devono riportare l'avanzamento al metodo IProgressMonitor, che lo trasferisce al metodo run del lavoro. Nella vista di avanzamento del workbench verranno visualizzati tutti i messaggi di avanzamento e le unità dei lavori completati forniti a questo controllo.
Il controllo di avanzamento deve inoltre essere utilizzato per verificare le richieste di annullamento effettuate dalla vista di avanzamento. Quando un utente (o un plugin che utilizza l'API del lavoro) tenta di annullare un lavoro, il metodo isCanceled() di IProgressMonitor restituisce un valore true. È responsabilità del lavoro verificare frequentemente lo stato di annullamento e rispondere a una richiesta di annullamento uscendo dal metodo run non appena possibile, una volta individuato un annullamento. Il metodo run riporta l'avanzamento e risponde all'annullamento del lavoro:
public IStatus run(IProgressMonitor monitor) { final int ticks = 6000; monitor.beginTask("Doing some work", ticks); try { for (int i = 0; i < ticks; i++) { if (monitor.isCanceled()) return Status.CANCEL_STATUS; monitor.subTask("Processing tick #" + i); //... do some work ... monitor.worked(1); } } finally { monitor.done(); } return Status.OK_STATUS;
}
Il metodo beginTask viene utilizzato per denominare l'attività nella vista di avanzamento corrispondente e per stabilire la percentuale totale di lavoro da eseguire, in modo che la vista possa calcolare l'avanzamento. I messaggi subTask vengono visualizzati come un elemento secondario della struttura ad albero dell'avanzamento, man mano che il lavoro viene eseguito. La vista di avanzamento calcola e visualizza una percentuale di completamento in basa alla quantità di lavoro riportata nelle chiamate worked.
La classe IProgressMonitor
viene progettata con il supporto UI corrispondente. Il plugin UI della piattaforma fornisce il supporto in modo che il workbench possa visualizzare l'avanzamento per i lavori in esecuzione. È possibile impostare i lavori tenendo conto di questo concetto, in modo da controllare il modo in cui vengono presentati.
Per informazioni dettagliate sulle API disponibili per la visualizzazione dell'avanzamento dei lavori, fare riferimento a Supporto simultaneità del workbench.
Cosa accade se il lavoro utilizzato presenta un'implementazione di livello inferiore che non si desidera mostrare agli utenti? È possibile indicare il lavoro come un lavoro di sistema. Un lavoro di sistema è come qualsiasi altro lavoro, eccetto che per il fatto che il supporto UI corrispondente non imposta una vista di avanzamento né mostra altre UI associate all'esecuzione del lavoro. Se il lavoro non viene inizializzato direttamente dall'utente o da un'attività periodica che può essere configurata da un utente, il lavoro è un lavoro di sistema. Il protocollo per l'impostazione di un lavoro di sistema è semplice:
class TrivialJob extends Job { public TrivialJob() { super("Trivial Job"); setSystem(true); } ... }
La chiamata setSystem deve essere eseguita prima che il lavoro venga pianificato. Un'eccezione viene attivata se si tenta questa chiamata su un lavoro attualmente in attesa, interrotto o in esecuzione.
Se il lavoro è un'operazione di lunga durata inizializzata da un utente, questo lavoro deve essere indicato come un lavoro dell'utente. Un lavoro dell'utente viene visualizzato in una finestra di dialogo di avanzamento modale che presenta un pulsante per lo spostamento della finestra sullo sfondo. Il workbench definisce una preferenza utente che controlla se queste finestre di dialogo sono sempre modali. Definendo il lavoro come un lavoro dell'utente, il feedback di avanzamento viene reso automaticamente conforme alla preferenza dell'utente per la visualizzazione dell'avanzamento. Il protocollo per l'impostazione di un lavoro dell'utente è simile:
class TrivialJob extends Job { public TrivialJob() { super("Trivial Job"); setUser(true); } ... }
Anche la chiamata setUser deve essere eseguita prima che il lavoro venga pianificato.
I gruppi di avanzamento rappresentano un altro meccanismo che può essere utilizzato per influenzare il modo in cui un lavoro viene visualizzato nell'UI. Quando è più appropriato visualizzare l'avanzamento aggregato di più lavori correlati nell'UI, può essere creata una classe IProgressMonitor speciale che rappresenta un gruppo di lavori correlati. Questo controllo viene creato utilizzando il protocollo IJobManager. Nel seguente frammento viene visualizzato come creare un gruppo di avanzamento e associarlo ad un lavoro.
... IJobManager jobMan = Platform.getJobManager(); myGroup = jobMan.createProgressGroup(); job.setProgressGroup(myGroup, 600); // specify the units of work the job needs to show. job.schedule() ...
La funzione di raggruppamento consente ai plugin di suddividere le attività in più lavori, se necessario, e di riportare i lavori all'utente come se fossero una singola attività. Il controllo del gruppo di avanzamento gestisce i dettagli del calcolo della percentuale di completamento relativa a tutti i lavori del gruppo.
Un lavoro deve essere inserito nel gruppo di avanzamento prima di essere pianificato. Una volta completata l'esecuzione, il riferimento del lavoro al gruppo di avanzamento viene perduto. Se il lavoro deve essere pianificato di nuovo, deve essere impostato nel gruppo ancora una volta prima di essere pianificato.