Visual Library

Posted by | · · · · | Cégélet · Liquiface | Nincs hozzászólás a(z) Visual Library bejegyzéshez

A Liquiface plugin

Fedex napi projektünkben a Liquiface-ben használtunk egy számunkra új libraryt a Visual Libraryt. Ebben a bejegyzésben erről lesz szó bővebben.

Az ötlet

Az ötlet, hogy ezt használjuk a netbeans oldalán megtalálható Database Explorer tutorialból származott. Korábban jártam már az oldalon és emlékeztem, hogy viszonylag egyszerűen oldották meg benne az adatbázis szerkezet megjelenítését. Tetszett a kinézete is és mivel mi is adatbázis modellt szerettünk volna megjeleníteni, kézenfekvőnek tűnt, hogy használjuk fel az ott leírtakat.

Visual Library

A Visual library a Netbeans platform része és a régi Graph library leszármazottja. Gráf központú modellezésre ajánlják.  A rendszer alap eleme a scene, erre pakolhatunk widgeteket. Szinte minden vizuális elem implementálja a widget interfészt még a scene is.  A példában is szereplő VMD graph scene adta az alapot, amin elkezdtem dolgozni. A VMD a Visual Mobile Designer rövidítése. Ez egy gráf központú modellekhez ajánlott GraphPinScene alapú elemkészlet.  Hamar kiderült hogy megjelenítésre tökéletesen alkalmas, azonban kívülről hozzáférni frissíteni már nem olyan egyszerű.

A graph scene 3 elemet ismer: Nodewidget - ezek a táblák, tartalmazhatnak pinwidgeteket; PinWidget - ezek az oszlopok; Edge - ezek a foreign keyek vonalai.

A graph scene 3 elemet ismer: Nodewidget – ezek a táblák, tartalmazhatnak pinwidgeteket; PinWidget – ezek az oszlopok; Edge – ezek a foreign keyek vonalai.

A pozitívumok

Volt néhány dolog, ami viszont nagyon tetszett. Például néhány sorból megoldható, hogy támogassa a scene a zoomolást, panninget, kijelölést.  Van egy egységes widget interfész amivel a legtöbb dolgot le lehet kezelni.  Az adatbázis modellt a táblák összeköttetéseivel nagyon egyszerűen meg lehetett jeleníteni, mintha erre tervezték volna :). Van egy jól működő action kezelő rendszer, ezek tulajdonképpen események amiket a klikkelések, mozgatások egyebek váltanak ki és végiggyűrűznek a widget fán felfelé, amíg el nem kapja őket valamelyik widget. Ilyen action például a PopupMenuAction amivel egyszerűen lehet egy swinges popupmenüt bekötni egy widgetre, ami jobbklikkre fel fog jönni.


//Nagyon egyszerű beállítani a Zoomolást, Panningot, Selectiont
getActions ().addAction (ActionFactory.createZoomAction ());
getActions ().addAction (ActionFactory.createPanAction ());
getActions ().addAction (ActionFactory.createRectangularSelectAction (this, backgroundLayer));

/*A popupmenüt is actionnel tudjuk hozzáadni,
a paraméternek átadott objectumnak meg kell valósítani a
PopupMenuProvider interfészt ami egyetlen függvény implementálását jelenti :
public JPopupMenu getPopupMenu (Widget widget, Point localLocation); */
WidgetAction popupAction = ActionFactory.createPopupMenuAction(SceneFacade.getInstance());
getActions().addAction(popupAction);

A problémák

A graph scene 3 elemet ismer: Nodewidget – ezek a táblák, tartalmazhatnak pinwidgeteket; PinWidget – ezek az oszlopok; Edge – ezek a foreign keyek vonalai.

Először megpróbáltam csak a már létező VMD osztályokat (Node, Pin, Connection, Scene) használva kívülről hozzáférni, frissíteni a megjelenítést. Ez azonban igen nehézkesen ment, pár funkció nagyon hiányzott.

A VMD osztályai teljesen megfeleltek volna némi módosítással, azonban sok helyen private függvényekben egy-egy sor miatt rengeteg kódot kellett átemelni, ráadásul az érintett függvények private változókon dolgoztak, amiket leszármaztatással nem is lehetett elérni így kénytelen voltam az egész osztályt újra implementálni (gyakorlatilag lemásolni) és beleírni azt a pár sort, ami egy jobb metódusszervezéssel elkerülhető lett volna.

A vége az lett, hogy leszedtem a Netbeans forráskódját a Visual Librarival együtt és kinéztem a VMD osztályokból ami nekem kell és kibővítettem a hiányzó részekkel. A tanulság az, hogy egy csomó időt megspórolhattam volna, ha egyből ezzel kezdem.

Az edgeknek van egy olyan tulajdonságuk, hogy routing policy. Ez nem más, mint a PinWidgeteket összekötő nyilak útvonaltervezésének módja. Alapértelmezésben ez egy “ortogonálisnak” nevezett módszer, lényege hogy a nodeokat kikerülve, több töréssel köti össze az összeköttetendő pontokat. Az algoritmus több útvonalat is megvizsgál majd igyekszik kiválasztani a legjobbat. Minél több node van a felületen annál erősforrásigényesebb a számítás. A tapasztalat az hogy exponenciálisan nő. Így érdemes átváltani nagy elemszámnál a direkt összeköttetésre, ilyenkor a nodeok felett átívelve egyenes vonalban köti össze a két pontot. Az is csak egy profiling után derült ki, hogy 99%-ban az útvonaltervező függvényekben időzik a program. Mielőtt kimértem volna, próbálkoztam az animálás kapcsolásával, amiből később feature lett :), valamint a layout módosításával hátha az elrendezés
kiszámítása lassú. Az algoritmuson valószínűleg lehetne javítani, de 3 osztályban 4-5 egymásba ágyazott cikluson keresztül számol tele nehezen értelmezhető matematikai műveletekkel, valamint kikommentezett kódokkal, amiket valami miatt bent hagytak. És nem éreztem hogy rászánnám azt a 1-2 hetet, amíg megpróbálom elfogadható sebességűre hozni, már ha egyátalán lehetséges.

Részlet az OrthogonalSearchRouter osztályból :


public java.util.List routeConnection(ConnectionWidget widget) {
/* How this works:
* 1) get the source and target anchors
* 2) determine collisions - needed for the actual routing
* 3) get the centers of the source and target anchor
* 4) check to see if the anchor will allow the route to connect to
*    any side. This really means that the router can test every
*    orthogonal direction out of the center of the anchor. If not
*    allowed then get the attach point from the anchor and use it to
*    determine the route.
* 5) Iterate through the different allowed orthogonal directions from
*    the target and source to find the actual "best" route. This route
*    or Solution with contain a list of points for the route.
* 6) Send the list of best points to the source anchor and allow it to
*    alter the points. The assumption is that the anchor will only move
*    the end point to the appropriate intersection point.
* 7) Repeat (6) for the target.
* 8) Now that the "best" points have been moved they may not represent
*    an orthogonal path any longer. Calculate the directions coming from/to
*    the anchors in preparation for re-routing.
* 9) Using the new endpoints(6&7) and the directions(8), re-route
*    and get the updated solution.
*
*/
Anchor sourceAnchor = widget.getSourceAnchor();
Anchor targetAnchor = widget.getTargetAnchor();

Látszik, hogy nem egy egyszerű algoritmus és sajnos eléggé erőforrásigényes is.

A jövő

A Netbeans fejlesztés is új volt, a Visual Libraryval is most találkoztam először. Elsőre nagyon jónak és egyszerűnek tűnt. Jobban megismerve már úgy tűnt hogy nem igazán arra találták ki, amire mi szeretnénk használni. A vége felé pedig elkezdett fény gyúlni ismét, lehet más szintről kellett volna nekiindulni, nem a VMD szintjéről hanem alacsonyabb szintről és a mi igényeinknek megfelelően felépíteni egy hasonló packaget amiben esetleg használunk pár meglévő komponenst. Van pár refactor ötlet ami így a vége felé vált világossá, hogy jobb lett volna úgy szervezni, ezeket a jövőben mindenképpen meg szeretném valósítani. Végszóként a Visual Library egy jó eszköz, csak megfelelően kell használni, végletekig testreszabható, de ehhez érdemes leszedni a forráskódot és végignézni.


No Comments

Leave a comment