Upload
teague
View
17
Download
0
Embed Size (px)
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