Nyílt fejlesztőrendszerek

Preview:

DESCRIPTION

Nyílt fejlesztőrendszerek. Graphical Editing Framework. GEF célja. Grafikus szerkesztőprogramok Integráció az Eclipse környezetbe Tetszőleges modell megjelenítése Magas absztrakciós szint. Példa. GEF felépítése. Interakció (MVC) Modell  nézet leképzés Eclipse integráció. - PowerPoint PPT Presentation

Citation preview

Nyílt Nyílt fejlesztőrendszerekfejlesztőrendszerek

Graphical Editing FrameworkGraphical Editing Framework

GEF céljaGEF célja

Grafikus szerkesztőprogramokGrafikus szerkesztőprogramok Integráció az Eclipse környezetbeIntegráció az Eclipse környezetbe Tetszőleges modell megjelenítéseTetszőleges modell megjelenítése Magas absztrakciós szintMagas absztrakciós szint

PéldaPélda

GEF felépítéseGEF felépítése

Interakció (MVC)Interakció (MVC) Modell Modell nézet leképzés nézet leképzés Eclipse integrációEclipse integráció

MegjelenítésMegjelenítés Elemek elrendezéseElemek elrendezése NagyításNagyítás

NatívNatív (SWT) (SWT) rétegréteg

MVC sémaMVC séma

Modell – Nézet – VezérlőModell – Nézet – Vezérlő Adatok tárolása és megjelenítése különAdatok tárolása és megjelenítése külön Modell: adatok tárolásaModell: adatok tárolása Nézet: grafikus megjelenítésNézet: grafikus megjelenítés Vezérlő: felhasználói interakcióVezérlő: felhasználói interakció Elterjedt: JSF, Swing, JFace, MFCElterjedt: JSF, Swing, JFace, MFC

MVC a gyakorlatbanMVC a gyakorlatban

MODELMODELLL

MODELMODELLL

NÉZENÉZETT

NÉZENÉZETT

FelhasználóFelhasználó

1. felhasználói akció1. felhasználói akció

VezérlőVezérlő

2. modell módosítás2. modell módosítás

3. visszajelzés3. visszajelzés

4. nézet frissítése4. nézet frissítése

5. modell lekérdezése5. modell lekérdezése

6. megjelenítés6. megjelenítés

MVC részei a GEF-ben I.MVC részei a GEF-ben I.

Modell: tetszőlegesModell: tetszőleges EMF, Java osztályok, adatbázisEMF, Java osztályok, adatbázis Hierarchikus felépítés (gyökeres fa)Hierarchikus felépítés (gyökeres fa) Támogatnia kell az értesítéseketTámogatnia kell az értesítéseket

Jelentés a vezérlőnek, ha módosítás történtJelentés a vezérlőnek, ha módosítás történt 1 modell 1 modell több nézet esetén fontos több nézet esetén fontos Pl. EMF Notification FrameworkPl. EMF Notification Framework

Üzleti modell: struktúra, adatokÜzleti modell: struktúra, adatok Nézeti modell: megjelenítési információkNézeti modell: megjelenítési információk

Pl. pozíció, méret.Pl. pozíció, méret.

Egyszerű modellEgyszerű modellpublic class ElsoModelpublic class ElsoModel{{ private String name; private String name; private Rectangle bounds; private Rectangle bounds;

public String getName() {public String getName() { return name; return name; } }

public void setName(String n) {public void setName(String n) { name = n; name = n; } }

public Rectangle getBounds() {public Rectangle getBounds() { return bounds; return bounds; } }

public void setBounds(Rectangle r) {public void setBounds(Rectangle r) { bounds = r; bounds = r; } }}}

Üzleti modellÜzleti modell

Nézeti modellNézeti modell

Egyszerű értesítésEgyszerű értesítéspublic interface MyModelListener {public interface MyModelListener { public void modelChanged(); public void modelChanged();}}

public class ElsoModel {public class ElsoModel { ... ... private List<MyModelListener> listeners; private List<MyModelListener> listeners; public ElsoModel() { public ElsoModel() { listeners = new Vector<MyModelListener>(); listeners = new Vector<MyModelListener>(); } } public void addListener(MyModelListener list) { public void addListener(MyModelListener list) { listeners.add(list); listeners.add(list); } } public void removeListener(MyModelListener list) { public void removeListener(MyModelListener list) { listeners.remove(list); listeners.remove(list); } } private void fireListeners() { private void fireListeners() { for (MyModelListener list : listeners) for (MyModelListener list : listeners) list.modelChanged(); list.modelChanged(); } }}}

Push vs. pull értesítésPush vs. pull értesítés

Pull: Csak annyit küld, hogy változás Pull: Csak annyit küld, hogy változás történttörtént Gyors, erőforráskímélőGyors, erőforráskímélő Minden változó attribútumot vizsgálni kellMinden változó attribútumot vizsgálni kell

Push: Pontosan megmondjuk, hogy mi Push: Pontosan megmondjuk, hogy mi változott (pl. új X pozíció = 172)változott (pl. új X pozíció = 172) El kell küldeni magát a változást is, lassúEl kell küldeni magát a változást is, lassú Könnyen feldolgozhatóKönnyen feldolgozható

MVC részei a GEF-ben II.MVC részei a GEF-ben II.

Nézet: Draw2D osztályokNézet: Draw2D osztályok SWT-re épülő grafikus könyvtárSWT-re épülő grafikus könyvtár Egyszerű elemek (címke, téglalap, nyíl)Egyszerű elemek (címke, téglalap, nyíl) Hierarchikus megjelenítésHierarchikus megjelenítés Alap építőelem: FigureAlap építőelem: Figure GEF nézet = Draw2D Figure példányGEF nézet = Draw2D Figure példány Bármely SWT alkalmazásban használhatóBármely SWT alkalmazásban használható

Saját üzenetkezelése is vanSaját üzenetkezelése is van

Draw2D hierarchiaDraw2D hierarchia

Minden gyerek csak a szülőjén belülMinden gyerek csak a szülőjén belül Gyerekek balról jobbraGyerekek balról jobbra Pontosan 1 gyökérelemPontosan 1 gyökérelem

1

3 6

4 5

212 34 5 6

Draw2D LayoutManagerDraw2D LayoutManager

Gyerekek elrendezése szülőn belülGyerekek elrendezése szülőn belül Több beépített, lehet saját isTöbb beépített, lehet saját is Constraint: Egy gyerek elhelyezésével Constraint: Egy gyerek elhelyezésével

kapcsolatos kényszerkapcsolatos kényszer SWT-nél ez volt a LayoutDataSWT-nél ez volt a LayoutData Szülő pozíció és méret + LayoutManager + Szülő pozíció és méret + LayoutManager +

Constraint Constraint Gyerek pozíció és méret Gyerek pozíció és méret Szülőben kell megadni, nem a gyerekben!!!Szülőben kell megadni, nem a gyerekben!!!

Draw2D LayoutManagerekDraw2D LayoutManagerek

Top

BorderLayout FlowLayout

Bottom

Left

RightCenter

1 2

3 4

ToolbarLayoutXYLayout

12,8,20,10

30,20,27,14

1 2 3

ConstraintConstraint

Draw2D alapelemekDraw2D alapelemek

Egyszerű elemekEgyszerű elemek Label, Button, CheckBox, ImageLabel, Button, CheckBox, Image

Geometriai alakzatokGeometriai alakzatok RectangleFigure, Ellipse, TriangleRectangleFigure, Ellipse, Triangle

Panel: általános konténer elemPanel: általános konténer elem ScrollPane: görgethető tartalmú elemScrollPane: görgethető tartalmú elem

Draw2D alapelemekDraw2D alapelemekpublic class Pelda1 extends Figurepublic class Pelda1 extends Figure{{ public Pelda1() { public Pelda1() { setOpaque(true); setOpaque(true); setBackgroundColor(ColorConstants.white); setBackgroundColor(ColorConstants.white); setLayoutManager(new ToolbarLayout()); setLayoutManager(new ToolbarLayout()); add(new Label("Label!")); add(new Label("Label!")); add(new CheckBox("CheckBox!")); add(new CheckBox("CheckBox!")); add(new Button("Button!")); add(new Button("Button!")); add(new RectangleFigure()); add(new RectangleFigure()); add(new Ellipse()); add(new Ellipse()); add(new RoundedRectangle()); add(new RoundedRectangle()); add(new Triangle()); add(new Triangle()); for (int i = 3; i <= 6; i++) for (int i = 3; i <= 6; i++) ((Figure) getChildren().get(i)).setPreferredSize(-1, 40); ((Figure) getChildren().get(i)).setPreferredSize(-1, 40); } }}}

Alapból minden átlátszóAlapból minden átlátszó

Minden elemnek lehet egy preferrált Minden elemnek lehet egy preferrált mérete, LayoutManagerek mérete, LayoutManagerek

figyelembe vehetikfigyelembe vehetik

Draw2D keretekDraw2D keretek

Minden Figurehöz rendelhető keretMinden Figurehöz rendelhető keret TitleBarBorder: dialógusablak jellegTitleBarBorder: dialógusablak jelleg LineBorder: egyszerű vonalLineBorder: egyszerű vonal MarginBorder: üres helyMarginBorder: üres hely Keretek egymásba ágyazhatókKeretek egymásba ágyazhatók

CompoundBorderCompoundBorder Megosztható Figureök közöttMegosztható Figureök között

Draw2D keretekDraw2D keretekpublic class Example2 extends Figurepublic class Example2 extends Figure{{ public Example2() public Example2() { {

setOpaque(true);setOpaque(true);setBackgroundColor(ColorConstants.white);setBackgroundColor(ColorConstants.white);setLayoutManager(new XYLayout());setLayoutManager(new XYLayout());TitleBarBorder tb = new TitleBarBorder("TitleBarBorder");TitleBarBorder tb = new TitleBarBorder("TitleBarBorder");tb.setTextColor(ColorConstants.white);tb.setTextColor(ColorConstants.white);setBorder(new CompoundBorder(new LineBorder(1), tb));setBorder(new CompoundBorder(new LineBorder(1), tb));Label lbl = new Label("Címke");Label lbl = new Label("Címke");lbl.setBorder(new CompoundBorder(lbl.setBorder(new CompoundBorder(

new LineBorder(1), new CompoundBorder(new LineBorder(1), new CompoundBorder( new MarginBorder(2, 10, 20, 30), new MarginBorder(2, 10, 20, 30),

new LineBorder(ColorConstants.blue, 5)))); new LineBorder(ColorConstants.blue, 5))));add(lbl);add(lbl);setConstraint(lbl, new Rectangle(20, 20, 120, 70));setConstraint(lbl, new Rectangle(20, 20, 120, 70));

} }

}}Constraint megadása a szülőbenConstraint megadása a szülőben

Draw2D egyéb elemekDraw2D egyéb elemek

Nyilak: lásd későbbNyilak: lásd később Beépített elemek kombinációja nem Beépített elemek kombinációja nem

mindig elégséges mindig elégséges saját elemek saját elemek paintFigure() felülírása kellpaintFigure() felülírása kell Tetszőleges SWT rajzoló kód lehetTetszőleges SWT rajzoló kód lehet

Draw2D saját elemDraw2D saját elempublic class Example3 extends Figurepublic class Example3 extends Figure{{ @Override @Override protected void paintFigure(Graphics graphics) protected void paintFigure(Graphics graphics) { {

Rectangle r = getBounds();Rectangle r = getBounds();PaletteData pd = new PaletteData(0xff0000, 0xff00, 0xff);PaletteData pd = new PaletteData(0xff0000, 0xff00, 0xff);pd.redShift = -16; pd.greenShift = -8; pd.blueShift = 0;pd.redShift = -16; pd.greenShift = -8; pd.blueShift = 0;pd.isDirect = true;pd.isDirect = true;ImageData id = new ImageData(r.width, r.height, 24, pd);ImageData id = new ImageData(r.width, r.height, 24, pd);for (int u = 0; u < r.width; u++)for (int u = 0; u < r.width; u++) for (int v = 0; v < r.height; v++) for (int v = 0; v < r.height; v++) { {

int rc = ((int) ((Math.sin(u * 9.0 / r.width) +int rc = ((int) ((Math.sin(u * 9.0 / r.width) + Math.cos(v * 7.0 / r.height)) * 256.0)) % 256; Math.cos(v * 7.0 / r.height)) * 256.0)) % 256;id.setPixel(u, v, rc << 16);id.setPixel(u, v, rc << 16);

} }Image img = new Image(Display.getCurrent(), id);Image img = new Image(Display.getCurrent(), id);graphics.drawImage(img, r.getTopLeft());graphics.drawImage(img, r.getTopLeft());

} }

}}

MVC részei a GEF-ben III.MVC részei a GEF-ben III.

Vezérlő: EditPart osztályokVezérlő: EditPart osztályok GEF „lelke”GEF „lelke” Kapcsolat a modell és a nézet közöttKapcsolat a modell és a nézet között 1 Figure 1 Figure 1 EditPart 1 EditPart 1 modell elem 1 modell elem több EditPart is lehet több EditPart is lehet

Minden nézethez egy példányMinden nézethez egy példány Felhasználói akciók kezeléseFelhasználói akciók kezelése

GEF szerkesztő lépéseiGEF szerkesztő lépései

Kezdeti nézet felépítéseKezdeti nézet felépítése Modell bejárása, nézet elkészítéseModell bejárása, nézet elkészítése Szerkesztési „szabályok” meghatározásaSzerkesztési „szabályok” meghatározása

Felhasználói akciókFelhasználói akciók Üzenetek értelmezése a szerkesztési Üzenetek értelmezése a szerkesztési

„szabályok” alapján„szabályok” alapján Modell módosításaModell módosítása Nézetek frissítéseNézetek frissítése

1. Kezdeti nézet felépítése1. Kezdeti nézet felépítése

Modell alapján EditPartok létrehozásaModell alapján EditPartok létrehozása EditPartFactoryEditPartFactory

Nézet Figureök példányosításaNézet Figureök példányosítása GraphicalEditPart.createFigure()GraphicalEditPart.createFigure()

Modell gyökér

EditParthierarchia

… …

Gyerekek

fig

fig…fig

Nézet

EditPartViewerEditPartViewer

Egy EditPart hierarchia megjelenítéséért Egy EditPart hierarchia megjelenítéséért felelősfelelős

Elvben hasonló, mint a JFace viewerekElvben hasonló, mint a JFace viewerek Fa- vagy grafikus nézetFa- vagy grafikus nézet

TreeViewer: tipikusan Outline nézethezTreeViewer: tipikusan Outline nézethez GraphicalViewer: grafikus nézetGraphicalViewer: grafikus nézet

ScrollingGraphicalViewer: éppen ez az aktuális ScrollingGraphicalViewer: éppen ez az aktuális javasolt megvalósítás (pár hónapja még nem is javasolt megvalósítás (pár hónapja még nem is létezett ilyen osztály létezett ilyen osztály ))

EditPartViewer II.EditPartViewer II.

Három szükséges alkotóelemHárom szükséges alkotóelem EditDomain: GEF alkalmazás „állapota”EditDomain: GEF alkalmazás „állapota” EditPartFactory: modell EditPartFactory: modell EditPart leképzés EditPart leképzés Gyökér modellelemGyökér modellelem

......public void createPartControl(Composite parent) {public void createPartControl(Composite parent) { ScrollingGraphicalViewer sgv = new ScrollingGraphicalViewer(); ScrollingGraphicalViewer sgv = new ScrollingGraphicalViewer(); sgv.setEditDomain(new DefaultEditDomain(this)); sgv.setEditDomain(new DefaultEditDomain(this)); sgv.setEditPartFactory(new MyEditPartFactory()); sgv.setEditPartFactory(new MyEditPartFactory()); sgv.setContents(model_gyoker_elem); sgv.setContents(model_gyoker_elem); sgv.createControl(parent); sgv.createControl(parent);}}......

EditDomainEditDomain

GEF állapotGEF állapot Aktív eszköz (active tool)Aktív eszköz (active tool)

Éppen használt szerkesztő funkcióÉppen használt szerkesztő funkció Pl. kijelölés, új elem, törlésPl. kijelölés, új elem, törlés

CommandStackCommandStack Elvégzett módosítások listájaElvégzett módosítások listája Undo / redo támogatáshozUndo / redo támogatáshoz

Használjuk mindig a DefaultEditDomain-tHasználjuk mindig a DefaultEditDomain-t

EditPartFactoryEditPartFactory

Modell alapján EditPart generálásaModell alapján EditPart generálása

public class ElsoGEFEditPartFactory implements EditPartFactorypublic class ElsoGEFEditPartFactory implements EditPartFactory{{ public EditPart createEditPart(EditPart context, Object model) public EditPart createEditPart(EditPart context, Object model) { { EditPart ep = null; EditPart ep = null;

if (model instanceof ElemModel) if (model instanceof ElemModel) ep = new ElemEditPart(); ep = new ElemEditPart(); else if (model instanceof SzuloModel) else if (model instanceof SzuloModel) ep = new SzuloEditPart(); ep = new SzuloEditPart();

if (ep != null) if (ep != null) ep.setModel(model); ep.setModel(model); return ep; return ep; } }}}

Szülő EditPartSzülő EditPart

EditPart tud tárolni egy EditPart tud tárolni egy modell referenciátmodell referenciát

Nézet legenerálásaNézet legenerálása

EditPart feladataEditPart feladata Sajátunkat célszerű származtatni azSajátunkat célszerű származtatni az

AbstractGraphicalEditPart osztálybólAbstractGraphicalEditPart osztálybólpublic class ElemEditPart extends AbstractGraphicalEditPartpublic class ElemEditPart extends AbstractGraphicalEditPart{{ ... ... @Override @Override protected IFigure createFigure() protected IFigure createFigure() { { // Saját Figure létrehozása // Saját Figure létrehozása ElemFigure fig = new ElemFigure(); ElemFigure fig = new ElemFigure(); return fig; return fig; } } ... ...}}

Modell bejárásaModell bejárása

EditPartViewer tartalmaEditPartViewer tartalma EditPartFactoryEditPartFactory Modell gyökér elemeModell gyökér eleme

Hogy jutunk el a modell többi részéhez?Hogy jutunk el a modell többi részéhez? EditParton keresztülEditParton keresztül Mindenki megmondja a saját gyerekeitMindenki megmondja a saját gyerekeit Rekurzívan bejárható az egész modellRekurzívan bejárható az egész modell

Ne legyen benne tartalmazás körNe legyen benne tartalmazás kör

Modell bejárásaModell bejárása

EditPart.getModelChildren()EditPart.getModelChildren() Az EditParthoz tartozó modellelem gyerekeit Az EditParthoz tartozó modellelem gyerekeit

kell visszaadni listakéntkell visszaadni listaként Lista sorrendje számít Lista sorrendje számít nézetek takarása nézetek takarása

public class SzuloEditPart extends AbstractGraphicalEditPartpublic class SzuloEditPart extends AbstractGraphicalEditPart{{ ... ... @Override @Override protected List getModelChildren() protected List getModelChildren() { { // Saját modell lekérdezése // Saját modell lekérdezése SzuloModel szm = ((SzuloModel) getModel()); SzuloModel szm = ((SzuloModel) getModel()); return szm.getChildren(); return szm.getChildren(); } } ... ...}}

EditPartból a saját EditPartból a saját modell elérésemodell elérése

Modell-függő függvény, Modell-függő függvény, nem GEF!nem GEF!

Nézet felépítés összefoglalásNézet felépítés összefoglalás

Modell

GraphicalViewer

EditPartok Figureök

EditPartFactory

Content PaneContent Pane

X modellelem gyerekeinek a nézetei X X modellelem gyerekeinek a nézetei X nézetének a gyerekeinézetének a gyerekei Összetett Figurek esetén nem jóÖsszetett Figurek esetén nem jó

ContentPane: Figure ős X gyerekeinekContentPane: Figure ős X gyerekeinek EditPartban adhatjuk megEditPartban adhatjuk meg

Saját Figureünkben gondoskodni kell rólaSaját Figureünkben gondoskodni kell róla

......@Override@Overridepublic IFigure getContentPane() {public IFigure getContentPane() {

return ((MyFigure) getFigure()).getGyerekekHelye();return ((MyFigure) getFigure()).getGyerekekHelye();}}......

Szerkesztés szereplői I.Szerkesztés szereplői I.

EditDomain: fogadja az eseményeket az EditDomain: fogadja az eseményeket az SWT-től, és továbbítja az aktív ToolnakSWT-től, és továbbítja az aktív Toolnak Nem végez feldolgozást, csak összefogja egy Nem végez feldolgozást, csak összefogja egy

modell összes nézetétmodell összes nézetét Tool: egy szerkesztési funkciót jelképezTool: egy szerkesztési funkciót jelképez

Feldolgozza az SWT üzeneteketFeldolgozza az SWT üzeneteket Létrehoz egy (vagy több) Request-etLétrehoz egy (vagy több) Request-et

Szerkesztés szereplői II.Szerkesztés szereplői II.

RequestRequest GEF-szintű eseményGEF-szintű esemény Pl. CreateRequest, DeleteRequestPl. CreateRequest, DeleteRequest Továbbítódik a cél EditParthozTovábbítódik a cél EditParthoz

EditPolicyEditPolicy EditParthoz tartozó „szerkesztési szabály”EditParthoz tartozó „szerkesztési szabály” Request Request Command leképzés Command leképzés 1 EditPart 1 EditPart több EditPolicy lehet több EditPolicy lehet

Szerkesztés szereplői III.Szerkesztés szereplői III.

CommandCommand A modell módosítását végziA modell módosítását végzi Visszavonható (ha megírjuk Visszavonható (ha megírjuk ))

CommandStackCommandStack Végrehajtott Commandok vermeVégrehajtott Commandok verme Ez biztosítja az undo/redo lehetőségétEz biztosítja az undo/redo lehetőségét EditDomainenként pontosan egy darabEditDomainenként pontosan egy darab Mindig ezen keresztül módosítsunk!Mindig ezen keresztül módosítsunk!

Szerkesztés szereplői IV.Szerkesztés szereplői IV.

EditPartEditPart A saját EditPolicyjai segítségével átalakítja a A saját EditPolicyjai segítségével átalakítja a

bejövő Requestet egy Commandábejövő Requestet egy Commandá Észleli a modell változását az értesítési Észleli a modell változását az értesítési

mechanizmuson keresztülmechanizmuson keresztül Modellváltozás esetén frissíti a nézetet, illetve Modellváltozás esetén frissíti a nézetet, illetve

a struktúráta struktúrát

Szerkesztés szereplői V.Szerkesztés szereplői V.

ActionAction Nem GEF-specifikus (JFace)Nem GEF-specifikus (JFace) Nem „grafikus” felhasználói akcióNem „grafikus” felhasználói akció

Menüelemek, billentyűlenyomások, toolbar elemekMenüelemek, billentyűlenyomások, toolbar elemek GEF biztosít néhány wrappert, amik lehetővé GEF biztosít néhány wrappert, amik lehetővé

teszik a CommandStack egyszerű elérésétteszik a CommandStack egyszerű elérését ActionRegistry: actionök listájaActionRegistry: actionök listája

Több helyen szereplő azonos actionökhözTöbb helyen szereplő azonos actionökhöz

Nincs több (lényeges) szereplőNincs több (lényeges) szereplő

Szerkesztés folyamataSzerkesztés folyamata

FigureFigure

ModellModell

CommandStackCommandStack EditPolicyEditPolicy

EditPartEditPart

ToolTool

SWTSWT EditDomainEditDomain1.SWT üzenet1.SWT üzenet

2.SWT üzenet2.SWT üzenet

8.Frissítés8.Frissítés

3.Request3.Request

4.Request4.Request

5.Command5.Command6.Módosítás6.Módosítás

7.Értesítés7.Értesítés

ToolTool

Beépített ToolokBeépített Toolok SelectionTool, CreationTool, MarqueeToolSelectionTool, CreationTool, MarqueeTool

Saját Tool is készíthetőSaját Tool is készíthető TargetingTool: Ha van egy cél EditPartTargetingTool: Ha van egy cél EditPart AbstractTool: teljesen általánosAbstractTool: teljesen általános

Aktív tool módosításaAktív tool módosítása EditDomain.setActiveTool()EditDomain.setActiveTool() Eszköztár (Palette): lásd későbbEszköztár (Palette): lásd később

RequestRequest

ChangeBoundsRequest: átméretezésChangeBoundsRequest: átméretezés CreationRequest: elem létrehozásaCreationRequest: elem létrehozása Minden Requesthez tartozik egy típus Minden Requesthez tartozik egy típus

azonosítóazonosító RequestConstants osztálybanRequestConstants osztályban REQ_xxx konstansokREQ_xxx konstansok EditPolicyk ez alapján azonosítjákEditPolicyk ez alapján azonosítják

EditPolicyEditPolicy

Pontosan egy EditParthoz tartozikPontosan egy EditParthoz tartozik getHost()-al lekérdezhetőgetHost()-al lekérdezhető 1 EditPart 1 EditPart több EditPolicy lehet több EditPolicy lehet

Azonosítás sztring kulcsokkal (EditPolicy.xxx)Azonosítás sztring kulcsokkal (EditPolicy.xxx)

FeladataiFeladatai Request Request Command leképzés Command leképzés

Command getCommand(Request)Command getCommand(Request) Grafikus visszajelzés a felhasználónakGrafikus visszajelzés a felhasználónak

show(Source/Target)Feedback()show(Source/Target)Feedback()

EditPolicy II.EditPolicy II.

Beépített absztrakt ősosztályokBeépített absztrakt ősosztályok Némi előfeldolgozást végeznek a RequestenNémi előfeldolgozást végeznek a Requesten ComponentEditPolicy: törlésComponentEditPolicy: törlés ContainerEditPolicy: létrehozásContainerEditPolicy: létrehozás LayoutEditPolicy: átméretezésLayoutEditPolicy: átméretezés XYLayoutEditPolicy: átméretezés, ha az XYLayoutEditPolicy: átméretezés, ha az

EditPart nézete XYLayoutot használEditPart nézete XYLayoutot használ Biztosítja a grafikus visszajelzéstBiztosítja a grafikus visszajelzést

EditPolicy példaEditPolicy példapublic class MyLayoutEditPolicy extends XYLayoutEditPolicy {public class MyLayoutEditPolicy extends XYLayoutEditPolicy {

protected Command createAddCommand(EditPart child,protected Command createAddCommand(EditPart child, Object constraint) { Object constraint) {

return null;return null;}}

protected Command createChangeConstraintCommand(protected Command createChangeConstraintCommand(EditPart child, Object constraint) {EditPart child, Object constraint) {

if (child.getModel() instanceof ElemModel && if (child.getModel() instanceof ElemModel && constraint instanceof Rectangle) constraint instanceof Rectangle) return new MyResizeCommand(((ElemModel) child.getModel()), return new MyResizeCommand(((ElemModel) child.getModel()),

((Rectangle) constraint));((Rectangle) constraint)); return null; return null;}}

protected Command getCreateCommand(CreateRequest request) {protected Command getCreateCommand(CreateRequest request) {return null;return null;

}}

protected Command getDeleteDependantCommand(Request req) {protected Command getDeleteDependantCommand(Request req) {return null;return null;

}}}}

XYLayout szülőXYLayout szülő

ÁtméretezésÁtméretezés

Saját CommandSaját Command

Command példaCommand példapublic class MyResizeCommand extends Commandpublic class MyResizeCommand extends Command{{

ElemModel model;ElemModel model;Rectangle newsize, oldsize;Rectangle newsize, oldsize;public MyResizeCommand(ElemModel m, Rectangle r)public MyResizeCommand(ElemModel m, Rectangle r){{

model = m; newsize = r;model = m; newsize = r;}}public boolean canExecute() {public boolean canExecute() {

return (r.width >= 40 && r.height >= 40);return (r.width >= 40 && r.height >= 40);}}public void execute() {public void execute() {

oldsize = model.getBounds();oldsize = model.getBounds();model.setBounds(newsize);model.setBounds(newsize);

}}public boolean canUndo() {public boolean canUndo() {

return true;return true;}}public void undo() {public void undo() {

model.setBounds(oldsize);model.setBounds(oldsize);}}

}}

Végrehajthatóság Végrehajthatóság feltételefeltétele

Modell függvényModell függvény

EditPart részeiEditPart részei

EditPolicyk telepítéseEditPolicyk telepítése createEditPolicies(), installEditPolicy()createEditPolicies(), installEditPolicy()

Modell figyeléseModell figyelése activate(), deactivate()activate(), deactivate()

Nézet frissítéseNézet frissítése refreshVisuals(): nem strukturális módosításrefreshVisuals(): nem strukturális módosítás refreshChildren(): gyerekek listája változikrefreshChildren(): gyerekek listája változik

EditPart példa I.EditPart példa I.public class SzuloEditPart extends AbstractGraphicalEditPartpublic class SzuloEditPart extends AbstractGraphicalEditPart implements MyModelListener implements MyModelListener{{

protected IFigure createFigure() {protected IFigure createFigure() {return new SzuloView();return new SzuloView();

}}

protected void createEditPolicies() {protected void createEditPolicies() {installEditPolicy(EditPolicy.LAYOUT_ROLE,installEditPolicy(EditPolicy.LAYOUT_ROLE,

new MyLayoutEditPolicy()); new MyLayoutEditPolicy());}}

protected List getModelChildren() {protected List getModelChildren() {return ((SzuloModel) getModel()).getChildren();return ((SzuloModel) getModel()).getChildren();

}}

protected void refreshVisuals() {protected void refreshVisuals() {((SzuloView) getFigure()).setLabel(((SzuloView) getFigure()).setLabel(

((SzuloModel) getModel()).getName());((SzuloModel) getModel()).getName());}}......

EditPolicy IDEditPolicy IDEditPolicy EditPolicy telepítésetelepítése

Nézet frissítéseNézet frissítése

EditPart példa II.EditPart példa II.......public void activate() {public void activate() {

super.activate();super.activate();((SzuloModel) getModel()).addListener(this);((SzuloModel) getModel()).addListener(this);

}}

public void deactivate() {public void deactivate() {((SzuloModel) getModel()).removeListener(this);((SzuloModel) getModel()).removeListener(this);super.deactivate();super.deactivate();

}}

public void modelChanged() {public void modelChanged() {refreshVisuals();refreshVisuals();refreshChildren();refreshChildren();

}}}}

Modellfigyelés kezdeteModellfigyelés kezdete

Modellfigyelés végeModellfigyelés vége

Modell ezt hívja (vö. Modell ezt hívja (vö. MyModelListener)MyModelListener)

Gyerekek frissítéseGyerekek frissítése

Mit kell nekünk megírni I.Mit kell nekünk megírni I.

Modell kód, értesítésselModell kód, értesítéssel Generáltatható EMF-el (jövő hét)Generáltatható EMF-el (jövő hét)

Nézet osztályokNézet osztályok EditPart osztályok 1.EditPart osztályok 1.

Modell megjelenítésModell megjelenítés createFigure(), refreshVisuals()createFigure(), refreshVisuals()

Modell változás figyelésModell változás figyelés activate(), deactivate()activate(), deactivate()

Mit kell nekünk megírni II.Mit kell nekünk megírni II.

EditPartFactory (modell EditPartFactory (modell EditPart) EditPart) Modell módosító CommandokModell módosító Commandok Saját EditPolicyk, amik a Commandokat Saját EditPolicyk, amik a Commandokat

használjákhasználják Milyen műveleteket engedünk megMilyen műveleteket engedünk meg

EditPart oszályok 2.EditPart oszályok 2. EditPolicyk hozzárendeléseEditPolicyk hozzárendelése

Editor és tartozékaiEditor és tartozékai

Editor készítéseEditor készítése

FeladataiFeladatai Létrehoz egy EditPartViewertLétrehoz egy EditPartViewert Kezeli a nem grafikus műveleteketKezeli a nem grafikus műveleteket

Actionök (undo/redo is ezek közé tartozik)Actionök (undo/redo is ezek közé tartozik) Létrehozza a menü és toolbar bejegyzéseketLétrehozza a menü és toolbar bejegyzéseket

ActionBarContributor (lásd labor)ActionBarContributor (lásd labor)

MegoldásMegoldás Saját EditorPart, ezeket mi írjuk megSaját EditorPart, ezeket mi írjuk meg GraphicalEditor használataGraphicalEditor használata

Nem ajánlott, de egyszerű Nem ajánlott, de egyszerű

GraphicalEditorGraphicalEditor

Ősosztály GEFes Eclipse editorokhozŐsosztály GEFes Eclipse editorokhoz Létrehoz egy ScrollingGraphicalViewer-tLétrehoz egy ScrollingGraphicalViewer-t Létrehoz egy pár általános ActiontLétrehoz egy pár általános Actiont

Undo, redo, törlés, nyomtatás, mentésUndo, redo, törlés, nyomtatás, mentés Nem jeleníti meg őket seholNem jeleníti meg őket sehol

Használjuk az editor készítése közben Használjuk az editor készítése közben teszteléshez, kísérletezéshez, de a végső teszteléshez, kísérletezéshez, de a végső alkalmazásba inkább ne kerüljönalkalmazásba inkább ne kerüljön

GraphicalEditor használataGraphicalEditor használatapublic class ElsoGEFEditor extends GraphicalEditorpublic class ElsoGEFEditor extends GraphicalEditor{{

public ElsoGEFEditor() {public ElsoGEFEditor() {setEditDomain(new DefaultEditDomain(this));setEditDomain(new DefaultEditDomain(this));

}}

protected void configureGraphicalViewer() {protected void configureGraphicalViewer() {getGraphicalViewer().setEditPartFactory(getGraphicalViewer().setEditPartFactory(

new ElsoGEFEditPartFactory());new ElsoGEFEditPartFactory());}}

public void init(IEditorSite site, IEditorInput input) public void init(IEditorSite site, IEditorInput input) throws PartInitException {throws PartInitException {

super.init(site, input);super.init(site, input);// Modell felépítése az input alapján// Modell felépítése az input alapján

}}

protected void initializeGraphicalViewer()protected void initializeGraphicalViewer(){{

getGraphicalViewer().setContents(modell_gyoker);getGraphicalViewer().setContents(modell_gyoker);}}......

}}

EditDomain kell a EditDomain kell a konstruktorban!konstruktorban!

EditPartFactory EditPartFactory megadásamegadása

Megnyitott fájl Megnyitott fájl feldolgozás (Eclipse)feldolgozás (Eclipse)

Modell gyökérelem Modell gyökérelem megadásamegadása

Eszköztár (Palette)Eszköztár (Palette)

Aktív eszköz váltásaAktív eszköz váltása Eszközök grafikus megjelenítéseEszközök grafikus megjelenítése Belül ez is egy külön GEF viewerBelül ez is egy külön GEF viewer PaletteRoot: eszköztár gyökerePaletteRoot: eszköztár gyökere PaletteEntry: eszköztár bejegyzésPaletteEntry: eszköztár bejegyzés

PaletteContainer: eszközök csoportjaPaletteContainer: eszközök csoportja ToolEntry: egy konkrét eszközToolEntry: egy konkrét eszköz

Gyakori ToolEntrykGyakori ToolEntryk

SelectionToolEntry: kijelölés eszközSelectionToolEntry: kijelölés eszköz MarqueeToolEntry: csoportos kijelölésMarqueeToolEntry: csoportos kijelölés CreationToolEntry: elem létrehozásaCreationToolEntry: elem létrehozása

Nehézkes használniNehézkes használni Factory osztály, ez lekérdezhető a Requesten Factory osztály, ez lekérdezhető a Requesten

kereszül az EditPolicyban kereszül az EditPolicyban azonosítás azonosítás Minden ToolEntryhez tartozikMinden ToolEntryhez tartozik

Név, rövid leírás, kis/nagy ikonNév, rövid leírás, kis/nagy ikon Tool osztály, amit példányosítTool osztály, amit példányosít

GraphicalEditorWithPaletteGraphicalEditorWithPalette

Olyan GraphicalEditor, ami létrehozza Olyan GraphicalEditor, ami létrehozza saját magának az eszköztáratsaját magának az eszköztárat

Szintén nem javasolt használniSzintén nem javasolt használni Eszköztárhoz csak egy függvényt kell Eszköztárhoz csak egy függvényt kell

megírnunkmegírnunk getPaletteRoot()getPaletteRoot()

GraphicalEditorWithPalette példaGraphicalEditorWithPalette példapublic class ElsoGEFEditor extends GraphicalEditorWithPalettepublic class ElsoGEFEditor extends GraphicalEditorWithPalette{{

protected PaletteRoot getPaletteRoot() {protected PaletteRoot getPaletteRoot() { PaletteRoot root = new PaletteRoot(); PaletteRoot root = new PaletteRoot(); PaletteGroup sgrp = new PaletteGroup("Selection"); PaletteGroup sgrp = new PaletteGroup("Selection"); ToolEntry tool = new SelectionToolEntry(); ToolEntry tool = new SelectionToolEntry(); selectionToolGroup.add(tool); selectionToolGroup.add(tool); root.setDefaultEntry(tool); root.setDefaultEntry(tool); tool = new MarqueeToolEntry(); tool = new MarqueeToolEntry(); selectionToolGroup.add(tool); selectionToolGroup.add(tool); root.add(selectionToolGroup); root.add(selectionToolGroup); root.add(new PaletteSeparator()); root.add(new PaletteSeparator()); root.add(new CreationToolEntry("New Place", root.add(new CreationToolEntry("New Place", "Creates a new Petri net place","Creates a new Petri net place", new SimpleFactory(PetriPlace.class),new SimpleFactory(PetriPlace.class),

MyPlugin.getImageDescriptor(„place.png”),MyPlugin.getImageDescriptor(„place.png”),MyPlugin.getImageDescriptor(„place.png”));MyPlugin.getImageDescriptor(„place.png”));

... ... return root; return root;}}......

}}

Új eszköztárÚj eszköztár

Csoport Csoport

Elválasztó vonalElválasztó vonal

Factory a Factory a létrehozáshozlétrehozáshoz

NyilakNyilak

Hasonlóak a normál objektumokhozHasonlóak a normál objektumokhoz Megjelenítés külön (felsőbb) rétegbenMegjelenítés külön (felsőbb) rétegben

Nyíl mindig látszik, akkor is ha nem kéne Nyíl mindig látszik, akkor is ha nem kéne Van saját EditPartjukVan saját EditPartjuk

AbstractConnectionEditPartAbstractConnectionEditPartból származikból származik Saját EditPolicyk, Requestek, ...Saját EditPolicyk, Requestek, ...

Irányítottak (modell szinten)Irányítottak (modell szinten)

Nyíl modellNyíl modell

Szintén semmi megkötésSzintén semmi megkötés Célszerű ha tudja a saját forrását és céljátCélszerű ha tudja a saját forrását és célját Forrás/cél objektumnak mindenképpen tudnia Forrás/cél objektumnak mindenképpen tudnia

kell a nyilakrólkell a nyilakról Navigálás a nyilakhoz a forrás/cél EditPartbanNavigálás a nyilakhoz a forrás/cél EditPartban

getModel(Source|Target)Connections()getModel(Source|Target)Connections()

......protected List getModelSourceConnections() {protected List getModelSourceConnections() {

return ((ElemModel)getModel()).getForrasNyilak();return ((ElemModel)getModel()).getForrasNyilak();}}

protected List getModelTargetConnections() {protected List getModelTargetConnections() {return ((ElemModel)getModel()).getCelNyilak();return ((ElemModel)getModel()).getCelNyilak();

}}... ...

Nyíl nézetNyíl nézet

Draw2D PolylineConnection példányDraw2D PolylineConnection példány Figure leszármazott Figure leszármazott lehetnek gyerekei lehetnek gyerekei GEF-ben nincs nyíl hierarchiaGEF-ben nincs nyíl hierarchia

Mindegyik a teljes szerkesztőt kitölthetiMindegyik a teljes szerkesztőt kitöltheti Speciális elemekSpeciális elemek

ConnectionAnchor: végpontok helyeConnectionAnchor: végpontok helye ConnectionRouter: nyíl alakjaConnectionRouter: nyíl alakja RotatableDecoration: végpontok „dísze”RotatableDecoration: végpontok „dísze”

ConnectionAnchorConnectionAnchor

Nyíl két Anchor között megyNyíl két Anchor között megy Forrás/cél EditPartok biztosítjákForrás/cél EditPartok biztosítják

NodeEditPart interfészen deklarált metódusokNodeEditPart interfészen deklarált metódusok get(Source|Target)ConnectionAnchor()get(Source|Target)ConnectionAnchor()

Két megvalósításKét megvalósítás ChopboxAnchor: téglalap FigurehözChopboxAnchor: téglalap Figurehöz EllipseAnchor: ellipszis FigurehözEllipseAnchor: ellipszis Figurehöz

Egyéb esetben kell sajátot írniEgyéb esetben kell sajátot írni

ConnectionRouterConnectionRouter

A két Anchor közötti közbenső pontokat A két Anchor közötti közbenső pontokat számolja kiszámolja ki

≈ ≈ LayoutManager, itt is lehet ConstraintLayoutManager, itt is lehet Constraint TípusaiTípusai

NullRouter: egyenes vonalNullRouter: egyenes vonal BendpointConnectionRouter: töréspontokBendpointConnectionRouter: töréspontok ......

Jövő: görbe nyilak támogatásaJövő: görbe nyilak támogatása

Nyíl nézet példaNyíl nézet példapublic class NyilView extends PolylineConnection {public class NyilView extends PolylineConnection {

private Label lbl;private Label lbl;

public NyilView1()public NyilView1(){{

lbl = new Label();lbl = new Label();lbl.setOpaque(true);lbl.setOpaque(true);lbl.setBorder(new LineBorder());lbl.setBorder(new LineBorder());add(lbl, new ConnectionLocator(this,add(lbl, new ConnectionLocator(this,

ConnectionLocator.MIDDLE)); ConnectionLocator.MIDDLE));

PolygonDecoration decors = new PolygonDecoration();PolygonDecoration decors = new PolygonDecoration();decors.setTemplate(PolygonDecoration.TRIANGLE_TIP);decors.setTemplate(PolygonDecoration.TRIANGLE_TIP);setTargetDecoration(decors);setTargetDecoration(decors);

setConnectionRouter(new BendpointConnectionRouter());setConnectionRouter(new BendpointConnectionRouter());}}

public setTorespontok(List<Bendpoint> tplista)public setTorespontok(List<Bendpoint> tplista){{

setRoutingConstraint(tplista);setRoutingConstraint(tplista);}}

}}

Nyíl megjelenítés problémákNyíl megjelenítés problémák

Töréspontok elmásznak zoom eseténTöréspontok elmásznak zoom esetén Minden nyíl mindig láthatóMinden nyíl mindig látható

Nyíl EditPartNyíl EditPart

Ősosztály: AbstractConnectionEditPartŐsosztály: AbstractConnectionEditPart Mindent tud, amit a többi EditPartMindent tud, amit a többi EditPart

Nyíl nézet létrehozása: createFigure()Nyíl nézet létrehozása: createFigure() Mindenképpen egy PolylineConnection kellMindenképpen egy PolylineConnection kell

Forrás és cél EditPartok lekérdezhetőkForrás és cél EditPartok lekérdezhetők getSource() és getTarget() függvényekgetSource() és getTarget() függvények Létrehozás közben nem feltétlenül elérhető!Létrehozás közben nem feltétlenül elérhető!

Szerepelnie kell az EditPartFactoryban isSzerepelnie kell az EditPartFactoryban is

Nyíl szerkesztésNyíl szerkesztés

Speciális nyíl EditPolicykSpeciális nyíl EditPolicyk ConnectionEditPolicy: törlésConnectionEditPolicy: törlés ConnectionEndpointEditPolicy: kijelölésConnectionEndpointEditPolicy: kijelölés

Mindeképpen telepíteni kell a kijelöléshezMindeképpen telepíteni kell a kijelöléshez BendpointEditPolicy: töréspontok módosításaBendpointEditPolicy: töréspontok módosítása

Csak akkor, ha BendpointConnectionRouter vanCsak akkor, ha BendpointConnectionRouter van

Nyíl létrehozásNyíl létrehozás

GraphicalNodeEditPolicyGraphicalNodeEditPolicy Nem a nyíl EditParthoz, hanem a forrás/cél Nem a nyíl EditParthoz, hanem a forrás/cél

elemek EditPartjához tartozik!elemek EditPartjához tartozik! Két lépcsős létrehozásKét lépcsős létrehozás

1. getConnectionCreateCommand()1. getConnectionCreateCommand() Request Request Command (ez nem hajtódik végre) Command (ez nem hajtódik végre)

2. getConnectionCompleteCommand()2. getConnectionCompleteCommand() Request + első Command Request + első Command végső Command végső Command

Csak ez hajtódik végre!Csak ez hajtódik végre!

Mit kell nekünk megírni III.Mit kell nekünk megírni III.

Nyíl modell kód, értesítésselNyíl modell kód, értesítéssel Nyíl források/célok modelljében el kell tudni Nyíl források/célok modelljében el kell tudni

érni az onnan induló/oda érkező nyilakat!érni az onnan induló/oda érkező nyilakat! Nyíl nézet osztályokNyíl nézet osztályok Nyíl EditPart osztályokNyíl EditPart osztályok

Modell megjelenítésModell megjelenítés createFigure(), refreshVisuals()createFigure(), refreshVisuals()

Modell változás figyelésModell változás figyelés activate(), deactivate()activate(), deactivate()

Mit kell nekünk megírni IV.Mit kell nekünk megírni IV.

Nyíl szerkesztő CommandokNyíl szerkesztő Commandok Nyíl saját EditPolicykNyíl saját EditPolicyk

Törlés, töréspontok módosítása, ...Törlés, töréspontok módosítása, ... Nyíl létrehozás EditPolicyNyíl létrehozás EditPolicy

Forrás/cél EditParthoz tartozikForrás/cél EditParthoz tartozik GraphicalNodeEditPolicyGraphicalNodeEditPolicy Két lépcsősKét lépcsős

Cél EditParté az első lépés!Cél EditParté az első lépés!

További funkciókTovábbi funkciók

Modell tulajdonságok szerkesztése az Modell tulajdonságok szerkesztése az Eclipse Eclipse PropertiesProperties nézetében nézetében

Szövegek (címkék) szerkesztése Szövegek (címkék) szerkesztése közvetlenül a rajzon (direct editing)közvetlenül a rajzon (direct editing)

Nagyítási lehetőségNagyítási lehetőség Különálló fa modellnézetKülönálló fa modellnézet Rajzok nyomtatása (Draw2D segítségével)Rajzok nyomtatása (Draw2D segítségével) Vonalzó, automatikus igazításVonalzó, automatikus igazítás

További információkTovábbi információk

www.eclipse.org/gefwww.eclipse.org/gef Hivatalos GEF oldalHivatalos GEF oldal

eclipsewiki.editme.com/GefDescriptioneclipsewiki.editme.com/GefDescription felületes, de legalább angol leírásfelületes, de legalább angol leírás

www13.plala.or.jp/observe/#gefwww13.plala.or.jp/observe/#gef japán, de a forráskódok követhetőkjapán, de a forráskódok követhetők 2.x-es Eclipse/GEFhez, azóta kicsit változott2.x-es Eclipse/GEFhez, azóta kicsit változott