1 / 71

Nyílt fejlesztőrendszerek

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ó.

teague
Télécharger la présentation

Nyílt fejlesztőrendszerek

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Nyílt fejlesztőrendszerek Graphical Editing Framework

  2. GEF célja • Grafikus szerkesztőprogramok • Integráció az Eclipse környezetbe • Tetszőleges modell megjelenítése • Magas absztrakciós szint

  3. Példa

  4. GEF felépítése • Interakció (MVC) • Modell  nézet leképzés • Eclipse integráció • Megjelenítés • Elemek elrendezése • Nagyítás • Natív (SWT) réteg

  5. MVC séma • Modell – Nézet – Vezérlő • Adatok tárolása és megjelenítése külön • Modell: adatok tárolása • Nézet: grafikus megjelenítés • Vezérlő: felhasználói interakció • Elterjedt: JSF, Swing, JFace, MFC

  6. MVC a gyakorlatban Felhasználó Vezérlő 1. felhasználói akció 6. megjelenítés 2. modell módosítás 4. nézet frissítése NÉZET 3. visszajelzés MODELL 5. modell lekérdezése

  7. MVC részei a GEF-ben I. • Modell: tetszőleges • EMF, Java osztályok, adatbázis • Hierarchikus felépítés (gyökeres fa) • Támogatnia kell az értesítéseket • Jelentés a vezérlőnek, ha módosítás történt • 1 modell  több nézet esetén fontos • Pl. EMF Notification Framework • Üzleti modell: struktúra, adatok • Nézeti modell: megjelenítési információk • Pl. pozíció, méret.

  8. Egyszerű modell Üzleti modell public class ElsoModel{ private String name; private Rectangle bounds; public String getName() { return name; } public void setName(String n) { name = n; } public Rectangle getBounds() { return bounds; } public void setBounds(Rectangle r) { bounds = r; }} Nézeti modell

  9. Egyszerű értesítés public interface MyModelListener { public void modelChanged();}public class ElsoModel { ... private List<MyModelListener> listeners; public ElsoModel() { listeners = new Vector<MyModelListener>(); } public void addListener(MyModelListener list) { listeners.add(list); } public void removeListener(MyModelListener list) { listeners.remove(list); } private void fireListeners() { for (MyModelListener list : listeners) list.modelChanged(); }}

  10. Push vs. pull értesítés • Pull: Csak annyit küld, hogy változás történt • Gyors, erőforráskímélő • Minden változó attribútumot vizsgálni kell • Push: Pontosan megmondjuk, hogy mi változott (pl. új X pozíció = 172) • El kell küldeni magát a változást is, lassú • Könnyen feldolgozható

  11. MVC részei a GEF-ben II. • Nézet: Draw2D osztályok • SWT-re épülő grafikus könyvtár • Egyszerű elemek (címke, téglalap, nyíl) • Hierarchikus megjelenítés • Alap építőelem: Figure • GEF nézet = Draw2D Figure példány • Bármely SWT alkalmazásban használható • Saját üzenetkezelése is van

  12. Draw2D hierarchia • Minden gyerek csak a szülőjén belül • Gyerekek balról jobbra • Pontosan 1 gyökérelem 1 1 6 2 3 2 3 6 5 4 4 5

  13. Draw2D LayoutManager • Gyerekek elrendezése szülőn belül • Több beépített, lehet saját is • Constraint: Egy gyerek elhelyezésével kapcsolatos kényszer • SWT-nél ez volt a LayoutData • Szülő pozíció és méret + LayoutManager + Constraint  Gyerek pozíció és méret • Szülőben kell megadni, nem a gyerekben!!!

  14. Draw2D LayoutManagerek BorderLayout FlowLayout Top 1 2 Left Center Right 3 4 Constraint Bottom XYLayout ToolbarLayout 1 2 3 12,8,20,10 30,20,27,14

  15. Draw2D alapelemek • Egyszerű elemek • Label, Button, CheckBox, Image • Geometriai alakzatok • RectangleFigure, Ellipse, Triangle • Panel: általános konténer elem • ScrollPane: görgethető tartalmú elem

  16. Draw2D alapelemek public class Pelda1 extends Figure{ public Pelda1() { setOpaque(true); setBackgroundColor(ColorConstants.white); setLayoutManager(new ToolbarLayout()); add(new Label("Label!")); add(new CheckBox("CheckBox!")); add(new Button("Button!")); add(new RectangleFigure()); add(new Ellipse()); add(new RoundedRectangle()); add(new Triangle()); for (int i = 3; i <= 6; i++) ((Figure) getChildren().get(i)).setPreferredSize(-1, 40); }} Alapból minden átlátszó Minden elemnek lehet egy preferrált mérete, LayoutManagerek figyelembe vehetik

  17. Draw2D keretek • Minden Figurehöz rendelhető keret • TitleBarBorder: dialógusablak jelleg • LineBorder: egyszerű vonal • MarginBorder: üres hely • Keretek egymásba ágyazhatók • CompoundBorder • Megosztható Figureök között

  18. Draw2D keretek public class Example2 extends Figure{ public Example2() { setOpaque(true); setBackgroundColor(ColorConstants.white); setLayoutManager(new XYLayout()); TitleBarBorder tb = new TitleBarBorder("TitleBarBorder"); tb.setTextColor(ColorConstants.white); setBorder(new CompoundBorder(new LineBorder(1), tb)); Label lbl = new Label("Címke"); lbl.setBorder(new CompoundBorder( new LineBorder(1), new CompoundBorder( new MarginBorder(2, 10, 20, 30), new LineBorder(ColorConstants.blue, 5)))); add(lbl); setConstraint(lbl, new Rectangle(20, 20, 120, 70)); } } Constraint megadása a szülőben

  19. Draw2D egyéb elemek • Nyilak: lásd később • Beépített elemek kombinációja nem mindig elégséges  saját elemek • paintFigure() felülírása kell • Tetszőleges SWT rajzoló kód lehet

  20. Draw2D saját elem public class Example3 extends Figure{ @Override protected void paintFigure(Graphics graphics) { Rectangle r = getBounds(); PaletteData pd = new PaletteData(0xff0000, 0xff00, 0xff); pd.redShift = -16; pd.greenShift = -8; pd.blueShift = 0; pd.isDirect = true; ImageData id = new ImageData(r.width, r.height, 24, pd); for (int u = 0; u < r.width; u++) for (int v = 0; v < r.height; v++) { int rc = ((int) ((Math.sin(u * 9.0 / r.width) + Math.cos(v * 7.0 / r.height)) * 256.0)) % 256; id.setPixel(u, v, rc << 16); } Image img = new Image(Display.getCurrent(), id); graphics.drawImage(img, r.getTopLeft()); } }

  21. MVC részei a GEF-ben III. • Vezérlő: EditPart osztályok • GEF „lelke” • Kapcsolat a modell és a nézet között • 1 Figure  1 EditPart • 1 modell elem  több EditPart is lehet • Minden nézethez egy példány • Felhasználói akciók kezelése

  22. GEF szerkesztő lépései • Kezdeti nézet felépítése • Modell bejárása, nézet elkészítése • Szerkesztési „szabályok” meghatározása • Felhasználói akciók • Üzenetek értelmezése a szerkesztési „szabályok” alapján • Modell módosítása • Nézetek frissítése

  23. 1. Kezdeti nézet felépítése • Modell alapján EditPartok létrehozása • EditPartFactory • Nézet Figureök példányosítása • GraphicalEditPart.createFigure() EditPart hierarchia fig Nézet Modell gyökér Gyerekek fig fig … … …

  24. EditPartViewer • Egy EditPart hierarchia megjelenítéséért felelős • Elvben hasonló, mint a JFace viewerek • Fa- vagy grafikus nézet • TreeViewer: tipikusan Outline nézethez • GraphicalViewer: grafikus nézet • ScrollingGraphicalViewer: éppen ez az aktuális javasolt megvalósítás (pár hónapja még nem is létezett ilyen osztály )

  25. EditPartViewer II. • Három szükséges alkotóelem • EditDomain: GEF alkalmazás „állapota” • EditPartFactory: modell  EditPart leképzés • Gyökér modellelem ...public void createPartControl(Composite parent) { ScrollingGraphicalViewer sgv = new ScrollingGraphicalViewer(); sgv.setEditDomain(new DefaultEditDomain(this)); sgv.setEditPartFactory(new MyEditPartFactory()); sgv.setContents(model_gyoker_elem); sgv.createControl(parent);}...

  26. EditDomain • GEF állapot • Aktív eszköz (active tool) • Éppen használt szerkesztő funkció • Pl. kijelölés, új elem, törlés • CommandStack • Elvégzett módosítások listája • Undo / redo támogatáshoz • Használjuk mindig a DefaultEditDomain-t

  27. EditPartFactory • Modell alapján EditPart generálása public class ElsoGEFEditPartFactory implements EditPartFactory{ public EditPart createEditPart(EditPart context, Object model) { EditPart ep = null; if (model instanceof ElemModel) ep = new ElemEditPart(); else if (model instanceof SzuloModel) ep = new SzuloEditPart(); if (ep != null) ep.setModel(model); return ep; }} Szülő EditPart EditPart tud tárolni egy modell referenciát

  28. Nézet legenerálása • EditPart feladata • Sajátunkat célszerű származtatni azAbstractGraphicalEditPart osztályból public class ElemEditPart extends AbstractGraphicalEditPart{ ... @Override protected IFigure createFigure() { // Saját Figure létrehozása ElemFigure fig = new ElemFigure(); return fig; } ...}

  29. Modell bejárása • EditPartViewer tartalma • EditPartFactory • Modell gyökér eleme • Hogy jutunk el a modell többi részéhez? • EditParton keresztül • Mindenki megmondja a saját gyerekeit • Rekurzívan bejárható az egész modell • Ne legyen benne tartalmazás kör

  30. Modell bejárása • EditPart.getModelChildren() • Az EditParthoz tartozó modellelem gyerekeit kell visszaadni listaként • Lista sorrendje számít  nézetek takarása public class SzuloEditPart extends AbstractGraphicalEditPart{ ... @Override protected List getModelChildren() { // Saját modell lekérdezése SzuloModel szm = ((SzuloModel) getModel()); return szm.getChildren(); } ...} EditPartból a saját modell elérése Modell-függő függvény, nem GEF!

  31. Nézet felépítés összefoglalás GraphicalViewer EditPart Factory Modell EditPartok Figureök

  32. Content Pane • X modellelem gyerekeinek a nézetei X nézetének a gyerekei • Összetett Figurek esetén nem jó • ContentPane: Figure ős X gyerekeinek • EditPartban adhatjuk meg • Saját Figureünkben gondoskodni kell róla ...@Overridepublic IFigure getContentPane() { return ((MyFigure) getFigure()).getGyerekekHelye();}...

  33. Szerkesztés szereplői I. • EditDomain: fogadja az eseményeket az SWT-től, és továbbítja az aktív Toolnak • Nem végez feldolgozást, csak összefogja egy modell összes nézetét • Tool: egy szerkesztési funkciót jelképez • Feldolgozza az SWT üzeneteket • Létrehoz egy (vagy több) Request-et

  34. Szerkesztés szereplői II. • Request • GEF-szintű esemény • Pl. CreateRequest, DeleteRequest • Továbbítódik a cél EditParthoz • EditPolicy • EditParthoz tartozó „szerkesztési szabály” • Request  Command leképzés • 1 EditPart  több EditPolicy lehet

  35. Szerkesztés szereplői III. • Command • A modell módosítását végzi • Visszavonható (ha megírjuk ) • CommandStack • Végrehajtott Commandok verme • Ez biztosítja az undo/redo lehetőségét • EditDomainenként pontosan egy darab • Mindig ezen keresztül módosítsunk!

  36. Szerkesztés szereplői IV. • EditPart • A saját EditPolicyjai segítségével átalakítja a bejövő Requestet egy Commandá • Észleli a modell változását az értesítési mechanizmuson keresztül • Modellváltozás esetén frissíti a nézetet, illetve a struktúrát

  37. Szerkesztés szereplői V. • Action • Nem GEF-specifikus (JFace) • Nem „grafikus” felhasználói akció • Menüelemek, billentyűlenyomások, toolbar elemek • GEF biztosít néhány wrappert, amik lehetővé teszik a CommandStack egyszerű elérését • ActionRegistry: actionök listája • Több helyen szereplő azonos actionökhöz • Nincs több (lényeges) szereplő

  38. Szerkesztés folyamata 1.SWT üzenet SWT EditDomain 2.SWT üzenet Figure 8.Frissítés Tool 3.Request Modell 7.Értesítés EditPart 6.Módosítás 4.Request 5.Command CommandStack EditPolicy

  39. Tool • Beépített Toolok • SelectionTool, CreationTool, MarqueeTool • Saját Tool is készíthető • TargetingTool: Ha van egy cél EditPart • AbstractTool: teljesen általános • Aktív tool módosítása • EditDomain.setActiveTool() • Eszköztár (Palette): lásd később

  40. Request • ChangeBoundsRequest: átméretezés • CreationRequest: elem létrehozása • Minden Requesthez tartozik egy típus azonosító • RequestConstants osztályban • REQ_xxx konstansok • EditPolicyk ez alapján azonosítják

  41. EditPolicy • Pontosan egy EditParthoz tartozik • getHost()-al lekérdezhető • 1 EditPart  több EditPolicy lehet • Azonosítás sztring kulcsokkal (EditPolicy.xxx) • Feladatai • Request  Command leképzés • Command getCommand(Request) • Grafikus visszajelzés a felhasználónak • show(Source/Target)Feedback()

  42. EditPolicy II. • Beépített absztrakt ősosztályok • Némi előfeldolgozást végeznek a Requesten • ComponentEditPolicy: törlés • ContainerEditPolicy: létrehozás • LayoutEditPolicy: átméretezés • XYLayoutEditPolicy: átméretezés, ha az EditPart nézete XYLayoutot használ • Biztosítja a grafikus visszajelzést

  43. EditPolicy példa XYLayout szülő public class MyLayoutEditPolicy extends XYLayoutEditPolicy { protected Command createAddCommand(EditPart child, Object constraint) { return null; } protected Command createChangeConstraintCommand( EditPart child, Object constraint) { if (child.getModel() instanceof ElemModel && constraint instanceof Rectangle) return new MyResizeCommand(((ElemModel) child.getModel()), ((Rectangle) constraint)); return null; } protected Command getCreateCommand(CreateRequest request) { return null; } protected Command getDeleteDependantCommand(Request req) { return null; }} Átméretezés Saját Command

  44. Command példa public class MyResizeCommand extends Command{ ElemModel model; Rectangle newsize, oldsize; public MyResizeCommand(ElemModel m, Rectangle r) { model = m; newsize = r; } public boolean canExecute() { return (r.width >= 40 && r.height >= 40); } public void execute() { oldsize = model.getBounds(); model.setBounds(newsize); } public boolean canUndo() { return true; } public void undo() { model.setBounds(oldsize); }} Végrehajthatóság feltétele Modell függvény

  45. EditPart részei • EditPolicyk telepítése • createEditPolicies(), installEditPolicy() • Modell figyelése • activate(), deactivate() • Nézet frissítése • refreshVisuals(): nem strukturális módosítás • refreshChildren(): gyerekek listája változik

  46. EditPart példa I. public class SzuloEditPart extends AbstractGraphicalEditPart implements MyModelListener{ protected IFigure createFigure() { return new SzuloView(); } protected void createEditPolicies() { installEditPolicy(EditPolicy.LAYOUT_ROLE, new MyLayoutEditPolicy()); } protected List getModelChildren() { return ((SzuloModel) getModel()).getChildren(); } protected void refreshVisuals() { ((SzuloView) getFigure()).setLabel( ((SzuloModel) getModel()).getName()); } ... EditPolicy telepítése EditPolicy ID Nézet frissítése

  47. EditPart példa II. Modellfigyelés kezdete ... public void activate() { super.activate(); ((SzuloModel) getModel()).addListener(this); } public void deactivate() { ((SzuloModel) getModel()).removeListener(this); super.deactivate(); } public void modelChanged() { refreshVisuals(); refreshChildren(); }} Modellfigyelés vége Modell ezt hívja (vö. MyModelListener) Gyerekek frissítése

  48. Mit kell nekünk megírni I. • Modell kód, értesítéssel • Generáltatható EMF-el (jövő hét) • Nézet osztályok • EditPart osztályok 1. • Modell megjelenítés • createFigure(), refreshVisuals() • Modell változás figyelés • activate(), deactivate()

  49. Mit kell nekünk megírni II. • EditPartFactory (modell  EditPart) • Modell módosító Commandok • Saját EditPolicyk, amik a Commandokat használják • Milyen műveleteket engedünk meg • EditPart oszályok 2. • EditPolicyk hozzárendelése • Editor és tartozékai

  50. Editor készítése • Feladatai • Létrehoz egy EditPartViewert • Kezeli a nem grafikus műveleteket • Actionök (undo/redo is ezek közé tartozik) • Létrehozza a menü és toolbar bejegyzéseket • ActionBarContributor (lásd labor) • Megoldás • Saját EditorPart, ezeket mi írjuk meg • GraphicalEditor használata • Nem ajánlott, de egyszerű 

More Related