Láthattuk, hogy a JFace UI keretrendszer alap támogatást biztosít a
feladat-előrehaladás párbeszédablakban megjelenítéséhez (részletes
információkat a Hosszan futó műveletek
rész tartalmaz). A
Konkurencia-infrastruktúrában áttekintettük
a konkurens és hosszan futó műveletek platform futási támogatását. Most
megtekintjük, hogy a platform UI az
org.eclipse.ui.progress csomagban hogyan javítja ezt az
infrastruktúrát. Ez a csomag biztosítja a felhasználói felületet a
feladat-előrehaladás munkaterületen megjelenítéséhez, és további
támogatást ad meg az UI szálban futó feladatokhoz.
Először tekintsük meg azon háttérműveletek különböző típusait és a munkaterület felhasználói felületén megjelenésük módját, amelyek futhatnak:
A Felhasználó által kezdeményezett feladatokat a felhasználó aktiválta. A munkaterület automatikusan megjeleníti a felhasználói feladatokat egy modális előrehaladási párbeszédablakban egy olyan gombbal, amely lehetővé teszi a művelet háttérben futtatását és a munka folytatását. Egy globális beállítás jelzi, hogy a felhasználói feladatnak mindig háttérben kell-e futnia. A felhasználói feladatok úgy vannak megkülönböztetve, ahogy a Job API-ban (Job#setUser). Felhasználói feladatok például: összeépítés, projekt kiiktatása, szinkronizálás a lerakattal, bedolgozó exportálása és keresés.
Az Automatikusan aktivált feladatoknak van értelme a felhasználók számára, azonban nem a felhasználók kezdeményezték azokat. Ezek a feladatok megjelennek az előrehaladás-nézetben és az állapotsoron, de a modális előrehaladás párbeszédablak nem kerül megjelenítésre, ha a feladatok futnak. Példák: automatikus összeépítés és ütemezett szinkronizálás.
A Rendszerműveleteket nem a felhasználók aktiválják és platformmegvalósítási részletként tekinthetők. Ezeket a feladatokat a a rendszerjelző beállítása hozza létre (Job#setSystem). Rendszerfeladatok példái: feladatok, amelyek késleltetetten töltik fel a vezérlőelemeket vagy feldolgozzák a nézetek dekorációit és feljegyzéseit.
Adva van egy környezet, amelyben számos dolog történhet egyszerre, amikor a
felhasználónak az alábbiakra van szüksége:
Jelzés, ha a hosszan futó művelet elindításra került.
A felhasználói feladatok megjelennek a felhasználó számára az előrehaladás
párbeszédablakban azonnali visszajelzést biztosítva, amíg az automatikusan
aktivált feladatok megjelennek az állapotsoron és az előrehaladás
nézetben. A részt befolyásoló feladatokat ütemezni
és regisztrálni kell a résszel, így a munkaterület tippeket
biztosíthat a felhasználó számára azzal kapcsolatban, hogy egy olyan dolog
fut, amely befolyásolja a részt.
Jelzés, amikor a művelet befejeződött.
A felhasználó könnyen észreveheti a felhasználói feladat befejeződését, mivel
az előrehaladás párbeszédablak bezáródik. Nem felhasználói feladatok
esetén rendelkezésre áll néhány visszajelzési mechanizmus. Ha a feladat
ütemezésre és bejegyzésre került a résszel, akkor
befejezéskor megjelenik a részek előrehaladás tippje. Ha a
feladat hibát ad vissza, akkor a hibajelző megjelenik az állapotsor jobb
alsó részében, amely megjeleníti, hogy hiba történt.
Az érdekes új eredmények vagy új információk jelzése anélkül, hogy a fókusz elkerülne egy párbeszédablak használatával.
A felhasználói feladat közvetlenül megjeleníti az eredményeket a
felhasználó számára, amikor a művelet befejeződik. Nem felhasználói feladat
esetén nem javasolt a párbeszédablakok használata az eredmények megjelenítésére
annak érdekében, hogy a felhasználót ne zavarjuk meg. Például egy nézetet
lehetne megnyitni amikor a feladat elindul és az eredmények ebben a nézetben
jelennének meg a felhasználó munkafolyamatának megzavarása nélkül. Továbbá
feladattulajdonságok adhatók hozzá a feladathoz
annak jelzésére, hogy azt a folyamat nézetben kell tartani és, hogy az egy
műveletet biztosít az eredmények megjelenítésére. Ebben az esetben egy
figyelmeztetésjelző megjelenik az állapotsor jobb alsó részén, amikor a feladat
az előrehaladás nézetben marad, és rendelkezik a felhasználó számára
megjelenítendő eredményekkel.
A futó dolgok kézbentartásának általános érzése, valamint a háttérműveletek figyelésének és leállításának lehetősége.
A felhasználói feladatok a legjobb vezérelhetőséget biztosítják a
felhasználó számára, mivel egyszerűen törölhetők és határozott jelzést
biztosítanak a blokkoló és párhuzamos műveletekhez, amelyek az előrehaladás
párbeszédablak Részletek lapján keresztül futnak. Ne feledje el, hogy a
bővített előrehaladás párbeszédablak által biztosított Részletek terület
csak akkor kerül megjelenítésre, ha a bedolgozók használják az
IProgressService#busyCursorWhile
vagy
IProgressService#runInUI
elemet.
Ezen felül az előrehaladás nézet hozzáférést biztosít a futó feladatokhoz.
Az előrehaladás összefüggő jelentése az összes telepített bedolgozó alapján.
Az előrehaladás szolgáltatás API előnye, hogy a felhasználók konzisztens
előrehaladást tapasztalhatnak.
A munkaterület előrehaladás szolgáltatás (IProgressService) az elsődleges felület a munkaterület előrehaladás támogatásához. Ez a munkaterületről kérhető le, majd megjeleníti az előrehaladást az UI szálban futó műveletekhez és háttérműveletekhez. Az osztály fő célja, hogy a futó műveletekhez mindent egy helyen biztosítson, ezáltal a bedolgozófejlesztőknek nem kell eldönteniük, hogy milyen mechanizmusokat kell használni az előrehaladás megjelenítéséhez egy adott helyzetben. Másik előny, hogy ezen metódusokkal megjelenő előrehaladás párbeszédablak támogatja annak jelzését, hogy a műveletet egy másik blokkolja és lehetővé teszi a felhasználó számára, hogy vezérelje a konfliktus feloldását. Ahol lehetséges, a hosszan futó feladatokat az IProgressService#busyCursorWhile segítségével kell futtatni:
IProgressService progressService = PlatformUI.getWorkbench().getProgressService(); progressService.busyCursorWhile(new IRunnableWithProgress(){ public void run(IProgressMonitor monitor) { //nem UI feladat végzése } });
Ez a metódus kezdetben egy foglalt kurzort jelenít meg, és ha a művelet a megadott küszöbértéknél tovább tart, akkor lecseréli ezt egy előrehaladás párbeszédablakra. Ezen metódus előnye az előrehaladás párbeszédablakkal szemben, hogyha a művelet rövid ideig fut, akkor az előrehaladás párbeszédablak nem jelenik meg. Ha a műveletnek frissítenie kell a felhasználói felületet, akkor mindig használhat egy Display.asyncExec vagy Display.syncExec elemet a kód futtatásához, amely módosítja a felhasználói felületet.
Ha egy műveletet teljes egészében kell futtatni a felhasználói felületen, akkor az IProgressService#runInUI elemet kell használni. Ez a metódus megjelenít egy előrehaladás párbeszédablakot is, ha a művelet blokkolva van, és biztosítja a vezérlést a felhasználó számára.
progressService.runInUI( PlatformUI.getWorkbench().getProgressService(), new IRunnableWithProgress() { public void run(IProgressMonitor monitor) { //UI feladat végzése } }, Platform.getWorkspace().getRoot());
A harmadik paraméter lehet null, vagy a művelet ütemezési szabálya. Ebben a példában megadjuk a munkaterület-gyökeret, amely zárolja a munkaterületet, amíg ez az UI feladat fut.
Az előrehaladás szolgáltatással a feladatcsaládhoz egy ikon is regisztrálható, így az előrehaladás nézet a futó feladat mellett megjelenítheti az ikont. Az alábbiakban látható egy példa arra, hogy a feladatcsalád automatikus összeépítése hogyan társítható ezzel az ikonnal:
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);
Az IWorkbenchSiteProgressService alkalmazás programozási felületet tartalmaz a feladatok ütemezéséhez, amely módosítja a munkaterületrész megjelenítését, miközben a feladat fut. Ha a bedolgozó háttérműveleteket futtat, amelyek hatással vannak a rész állapotára, akkor a feladat ütemezhető a részen keresztül, és a felhasználó visszajelzést kap arról, hogy a rész foglalt. Az alábbiakban látható egy példa:
IWorkbenchSiteProgressService siteService = (IWorkbenchSiteProgressService)view.getSite().getAdapter(IWorkbenchSiteProgressService.class); siteService.schedule(job, 0 /* most */, true /* fel használt kurzort használ */);
A munkaterület az előrehaladással kapcsolatos tulajdonságokat határoz meg a feladatok számára az IProgressConstants felületben. Ezek segítségével a feladat megjelenése vezérelhető az előrehaladás nézetben. Ezek előírhatják az előrehaladás nézetnek, hogy (IProgressConstants#KEEP_PROPERTY) a feladat befejezés után a nézetben maradjon, vagy hogy csak egy (IProgressConstants#KEEPONE_PROPERTY) feladat maradjon egyszerre a nézetben. A feladathoz társítható egy tevékenység (IProgressConstants#ACTION_PROPERTY). Ha a feladat rendelkezik egy társított tevékenységgel, akkor az előrehaladás nézet megjelenít egy hivatkozást, így a felhasználó futtathatja a tevékenységet. Azt is észreveheti, hogy a felhasználó aktuálisan megjelenik-e az előrehaladás párbeszédablakban (IProgressConstants#PROPERTY_IN_DIALOG). Egy tipp jelenik meg az állapotsor jobb alsó részében, amikor az állapotsor rendelkezésre áll. Az alábbi példa ezen tulajdonságokat használja:
Job job = new Job("Do Work") { public IStatus run(IProgressMonitor monitor) { // feladatok elvégzése. // csak a befejezett feladat megtartása az előrehaladás nézetben, ha nem fut az előrehaladás párbeszédablakban 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() { // megjeleníti az eredményeket } }; job.setProperty(IProgressConstants.ACTION_PROPERTY, gotoAction); job.setUser(true); job.schedule();
Ahol lehetséges, ott a hosszútávú műveleteket az UI szálon kívül kell végrehajtani. Ez nem mindig lehetséges, amikor a művelet célja az UI frissítése. SWT szálkezelési problémák bemutatják, hogy ez hogyan hajtható végre az SWT Display segítségével. A munkaterület egy speciális feladatot - UIJob - ad meg, amelynek run metódusa egy SWT asyncExec elemen belül fut. Az UIJob alosztályainak a run metódus helyett a runInUIThread metódust kell megvalósítaniuk.
WorkbenchJob kiterjeszti az UIJob feladatot, így a feladat csak akkor ütemezhető vagy futtatható, amikor a munkaterület fut. Ahogy mindig, most is el kell kerülni a túlzott munkát az UI szálban, mivel az UI nem kerül frissítésre az UI feladat során.