Kiválasztás átvitele eclipse nézetek között

Érdekes problémákba ütközik az ember, ha eclipse környékén fejleszt. Ezek nagyrészét ugyan már megoldották, de a megoldást külön művészet megtalálni a tengernyi dokumentációban. Mindenesetre legalább dokumentálták. A probléma, amiben pár napja az örömömet leltem, az az, hogy hogyan lehet egy nézet által kiválasztott elemeket átadni egy másik nézetnek, ami természetesen hasonló modell felett dolgozik. Konkrétan a Debug Visualisation projektem által definiált nézetet akartam összekötni a Variables View-vel és vice-versa.

Érdekes problémákba ütközik az ember, ha eclipse környékén fejleszt. Ezek nagyrészét ugyan már megoldották, de a megoldást külön művészet megtalálni a tengernyi dokumentációban. Mindenesetre legalább dokumentálták. A probléma, amiben pár napja az örömömet leltem, az az, hogy hogyan lehet egy nézet által kiválasztott elemeket átadni egy másik nézetnek, ami természetesen hasonló modell felett dolgozik. Konkrétan a Debug Visualisation projektem által definiált nézetet akartam összekötni a Variables View-vel és vice-versa.

Pár óra keresgélés és javadoc olvasgatás után rábukkantam a megoldásra: Minden view-t tartalmazó IWorkbenchPartSite lehetőséget biztosít egy ISelectionProvider regisztrálására, amely interfészt ad kiválasztási információk kinyerésére és átadására, továbbá listener-ek regisztrálására. A másik, csatlakoztatni kívánt view által megadott ISelectionProvider-nek az általunk generált kiválasztási eseményeket át lehet adni, illetve figyelni lehet az általa generált ilyen eseményeket.

A problémát csak az okoz, hogy egy adott view által generált és elfogadott kiválasztandó elemek az adott view modelljéből kerül ki, tehát ugyanezen modell elemeit kell neki átadni. Ha az általunk írt view más modellen, vagy ugyanazon modell felett máshogy definiálja a kiválasztást, akkor a kiválasztást konvertálni kell a modellek között. Ez természetesen csak akkor oldható meg, ha egyáltalán értelmezhető a közös kiválasztás.

Mindehhez persze az első lépés az, hogy megtaláljuk a csatlakoztatni kivánt view-t, amit az azonosítójának ismeretében tehetünk meg a következő módon:


PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(viewID).getSite().getSelectionProvider();

ahol a [cci_java]viewID[/cci_java] helyére a keresett view szöveges azonosítóját kell megadni. A Variables View azonosítóját az org.eclipse.debug.ui plugin egy [cci_java]IDebugUIConstants[/cci_java] nevű publikus interfész elérhetővé teszi.

Mint az eclipse esetében általában erre problémára is egy jól kitalált megoldás létezik, ami megfelelően egyszerű ahhoz, hogy a módszer ismeretében könnyű legyen implementálni, a nehézséget csak a módszer megtalálása jelenti.

3 thoughts on “Kiválasztás átvitele eclipse nézetek között”

  1. Szerencsére a megoldás eléggé általános. A selectionProvider() az összes JFace providerrel működik. Sőt, ha közös adatmodellen futnak, akkor lehet közös providert is használni.

    Egy csúnya megjegyzés még a dologról: ha így írod meg a kódot, akkor elég vad dolgok kijöhetnek. Egyrészt a hosszú sor nehezen olvasható, másfelől különböző hibakezelés. Pl. valahol menet közben NullPointerException jöhet, oda kell figyelni, hogy a UI threadből hívjuk ezt a dolgot, meg ilyenek. Érdemes egy kicsit megtördelni.

    Ne vedd a szívedre, csak azért szólok, nem oltani akarlak, csak szólok, mert szívtam ilyenekkel. 😀

  2. Természetesen a kód környezetében ellenőrzöm a nullpointer exception-t, és ha az ember jól átgondolja, csak kevés esetben dobhat ilyet. Az nem nagy feltételezés (miután valaki inicializálta az általunk írt view-t), hogy létezik a platform, annak egy ablaka (workbench), amin egy lap aktív (activePage). Utánna már a findView() természetesen bukhat, amennyiben nincs az adott lapon ilyen view. Viszont ha van, ahhoz mindenképpen hozzá van rendelve egy IWorkbenchPartSite, ami tartalmazza azt. A végén pedig csak azt kell ellenőrizni, hogy a selection provider létezik-e.

    Tényleg nehezen olvasható, de ha minden lépésben kirakom a részeredményt egy változóba, azon végrehajtva sanity-check-et, szvsz sokkal terjedelmesebb, és még nehezebben áttekinthetőbb kódot kapok, mintha a végén ellenőrzöm, h dobott-e kivételt és értelmes eredményt adott-e.

    Egy dologra viszont valóban nem gondoltam. Azt szépen megoldottam, hogy ha a view inicializálásakor nem találja a variables view-t (mert teszem azt nincs éppen kirakva a debug perspektívára), akkor bizonyos eseményekre újra megpróbálja megkeresni. De ha a felhasználó időközben bezárja azt, akkor a kódom egy gyönyörű widgetDisposed kivételt dob.

  3. Én sem arra gondoltam, hogy mindegyiket külön.

    De pl. jó ötlet lehet a View-t kirakni egy változóba, és meggyőződni róla, hogy az tényleg létezik-e, megjelent-e. (Esetleg, ha nem, akkor meg lehet jeleníteni, de ez feladatfüggő. :D)

    És azzal azért nagyjából megfelezted a dolgot, és a tipikus hibahelynél szakítod meg a láncot.

Leave a Reply