Az előadás letöltése folymat van. Kérjük, várjon

Az előadás letöltése folymat van. Kérjük, várjon

Nyílt fejlesztőrendszerek Graphical Editing Framework II.

Hasonló előadás


Az előadások a következő témára: "Nyílt fejlesztőrendszerek Graphical Editing Framework II."— Előadás másolata:

1 Nyílt fejlesztőrendszerek Graphical Editing Framework II.

2 Miről lesz szó? A GEF további lehetőségei A GEF további lehetőségei Modell tulajdonságok szerkesztése az Eclipse Properties nézetében Modell tulajdonságok szerkesztése az Eclipse Properties nézetében Szövegek (címkék) szerkesztése közvetlenül a rajzon (direct editing) Szövegek (címkék) szerkesztése közvetlenül a rajzon (direct editing) Nagyítási lehetőség Nagyítási lehetőség Vonalzó, automatikus igazítás Vonalzó, automatikus igazítás Különálló fa modellnézet Különálló fa modellnézet GEF-es szerkesztő készítése EMF modellekhez GEF-es szerkesztő készítése EMF modellekhez Kitekintés: Graphical Modeling Framework Kitekintés: Graphical Modeling Framework

3 Modell tulajdonságok A beépített Properties nézetét használjuk A beépített Properties nézetét használjuk Mindig az aktuálisan kijelölt EditParthoz tartozó tulajdonságok jelennek meg Mindig az aktuálisan kijelölt EditParthoz tartozó tulajdonságok jelennek meg Csoportokba szervezhetőek Csoportokba szervezhetőek API: org.eclipse.ui.views.properties API: org.eclipse.ui.views.properties Szerkesztés Szerkesztés beépített eszközökkel beépített eszközökkel saját PropertySheetPage implementáció saját PropertySheetPage implementáció

4 Modell tulajdonságok 2. Megjeleníthető attribútum típusok Megjeleníthető attribútum típusok IPropertyDescriptor IPropertyDescriptor Általános tulajdonság leíró Általános tulajdonság leíró Kötelező: ID, név Kötelező: ID, név Opcionális: leírás, kategória, label provider (megjelenítéshez), cell editor (szerkesztéshez), context-sensitive help ID Opcionális: leírás, kategória, label provider (megjelenítéshez), cell editor (szerkesztéshez), context-sensitive help ID Kész implementációk: Kész implementációk: PropertyDescriptor (csak olvasható) PropertyDescriptor (csak olvasható) TextPropertyDescriptor (string attribútumok) TextPropertyDescriptor (string attribútumok) CheckboxPropertyDescriptor (boolean attribútumok) CheckboxPropertyDescriptor (boolean attribútumok) ComboboxPropertyDescriptor (enum attribútumok) ComboboxPropertyDescriptor (enum attribútumok) ColorPropertyDescriptor (szín attribútumok) ColorPropertyDescriptor (szín attribútumok)

5 Modell tulajdonságok 4. Tulajdonságok leírása Tulajdonságok leírása IPropertySource interfész IPropertySource interfész getPropertyDescriptors() getPropertyDescriptors() IPropertyDescriptor tömb (!) IPropertyDescriptor tömb (!) getPropertyValue() getPropertyValue() setPropertyValue() setPropertyValue() isPropertySet() isPropertySet() Különbözik-e a jelenlegi érték a default-tól Különbözik-e a jelenlegi érték a default-tól resetPropertyValue() resetPropertyValue() getEditableValue() getEditableValue() A szerkesztőben más is megjeleníthető, pl. fully qualified name helyett local name A szerkesztőben más is megjeleníthető, pl. fully qualified name helyett local name IPropertySource2 interfész IPropertySource2 interfész isPropertyResettable(): visszaállítható-e egy értelmes alapértelmezett érték isPropertyResettable(): visszaállítható-e egy értelmes alapértelmezett érték

6 Modell tulajdonságok 5. Tulajdonságok hozzárendelése Tulajdonságok hozzárendelése Mi implementálja az IPropertySource-t? Mi implementálja az IPropertySource-t? Modell Modell Legegyszerűbb megoldás Legegyszerűbb megoldás Nem mindig kivitelezhető Nem mindig kivitelezhető EditPart EditPart getAdapter() hívás kérhet IPropertySource példányt getAdapter() hívás kérhet IPropertySource példányt Proxy osztályok Proxy osztályok IPropertySourceProvider: IPropertySource példányokat szolgáltat a modell elemekhez IPropertySourceProvider: IPropertySource példányokat szolgáltat a modell elemekhez GEF beépített osztályai ezt nem támogatják! 

7 Modell tulajdonságok 6. Proxy osztályok: Editor getAdapter() metódusa Proxy osztályok: Editor getAdapter() metódusa @Override public Object getAdapter(Class adapter) { if (adapter == IPropertySheetPage.class) { iPropertyPage = new MyPropertySheetPage(this); iPropertyPage.setPropertySourceProvider( new MyPropertySourceProvider(this)); return iPropertyPage; } […] } GEF-es undo/redo-nem minden esetben megfelelő GEF-es undo/redo-nem minden esetben megfelelő testreszabott validálás testreszabott validálás

8 Direct editing Cél: gyors szerkesztés közvetlenül a rajzon Cél: gyors szerkesztés közvetlenül a rajzon

9 Direct editing 2. Szükséges: Szükséges: DirectEditManager DirectEditManager Szerkesztő kirajzolása Szerkesztő kirajzolása DirectEditPolicy DirectEditPolicy Requestből Command előállítása Requestből Command előállítása DirectEditCommand DirectEditCommand Modell manipuláció, undo/redo információ tárolása Modell manipuláció, undo/redo információ tárolása Modell függő Modell függő CellEditorLocator CellEditorLocator Szerkesztő koordinátáinak meghatározása Szerkesztő koordinátáinak meghatározása EditPart-ok felkészítése EditPart-ok felkészítése DirectEditManager példányosítása és megjelenítése a Request hatására DirectEditManager példányosítása és megjelenítése a Request hatására Editor felkészítése Editor felkészítése DirectEditAction regisztrálása DirectEditAction regisztrálása KeyHandler (opcionális): pl F2-re direct edit aktiválása KeyHandler (opcionális): pl F2-re direct edit aktiválása

10 Direct editing 3. DirectEditManager public class ViatraEditorDirectEditManager extends DirectEditManager { extends DirectEditManager { private IVMModelElement iModelElement; private IVMModelElement iModelElement; public ViatraEditorDirectEditManager( public ViatraEditorDirectEditManager( GraphicalEditPart source, GraphicalEditPart source, Class editorType, Class editorType, CellEditorLocator locator) CellEditorLocator locator) { super(source, editorType, locator) super(source, editorType, locator) iModelElement = iModelElement = (IVMModelElement) source.getModel(); (IVMModelElement) source.getModel(); } protected void initCellEditor() protected void initCellEditor() { getCellEditor().setValue(iModelElement.getName()); getCellEditor().setValue(iModelElement.getName()); Text text = (Text) getCellEditor().getControl(); Text text = (Text) getCellEditor().getControl(); text.selectAll(); text.selectAll(); }}

11 Direct editing 4. DirectEditPolicy protected Command getDirectEditCommand( DirectEditRequest request) DirectEditRequest request){ Point p = request.getLocation(); Point p = request.getLocation(); DirectEditCommand command = DirectEditCommand command = new DirectEditCommand(); command.setModel( getHost().getModel() ); command.setModel( getHost().getModel() ); command.setText((String) command.setText((String)request.getCellEditor().getValue()); return command; return command;} Command létrehozása Request alapján Command létrehozása Request alapján

12 Direct editing 5. CellEditorLocator public void relocate(CellEditor celleditor) { Text text = (Text) celleditor.getControl(); Text text = (Text) celleditor.getControl(); Point pref = text.computeSize(-1, -1); Point pref = text.computeSize(-1, -1); Rectangle rect = null; Rectangle rect = null; rect = figure.getBounds().getCopy(); rect = figure.getBounds().getCopy(); figure.translateToAbsolute(rect); figure.translateToAbsolute(rect); text.setBounds(rect.x, rect.y, text.setBounds(rect.x, rect.y, rect.width, rect.height); } Szerkesztő téglalap helyének számítása Szerkesztő téglalap helyének számítása

13 Direct editing 6.1 EditPartok felkészítése private MyDirectEditManager directManager = null; public void performRequest(Request req) public void performRequest(Request req) { if (req.getType() if (req.getType().equals(RequestConstants.REQ_DIRECT_EDIT)).equals(RequestConstants.REQ_DIRECT_EDIT)) { performDirectEdit(); performDirectEdit(); return; return; } super.performRequest(req); super.performRequest(req); } DirectEditManager példányosítása Request hatására DirectEditManager példányosítása Request hatására

14 Direct editing 6.2 EditPartok felkészítése private void performDirectEdit() private void performDirectEdit() { if (directManager == null) if (directManager == null) { directManager = directManager = new MyDirectEditManager( this, new MyDirectEditManager( this, TextCellEditor.class, TextCellEditor.class, new MyCellEditorLocator(getFigure())); new MyCellEditorLocator(getFigure())); } directManager.show(); directManager.show(); }} DirectEditManager példányosítása Request hatására DirectEditManager példányosítása Request hatására

15 Direct editing 6.3 EditorPartok felkészítése protected void createEditPolicies() { installEditPolicy( installEditPolicy( EditPolicy.DIRECT_EDIT_ROLE, EditPolicy.DIRECT_EDIT_ROLE, new MyDirectEditPolicy()); new MyDirectEditPolicy());} DirectEditPolicy aktiválása DirectEditPolicy aktiválása

16 Direct editing 7. Editor felkészítése protected void createActions() { super.createActions(); super.createActions(); IAction action = new DirectEditAction( IAction action = new DirectEditAction( (IWorkbenchPart) this); (IWorkbenchPart) this); registry.registerAction(action); registry.registerAction(action); getSelectionActions().add(action.getId()); getSelectionActions().add(action.getId());} DirectEditAction regisztrálása DirectEditAction regisztrálása

17 Grafikus nézet nagyítása Cél: diagram vektoros nagyítása Cél: diagram vektoros nagyítása

18 Grafikus nézet nagyítása 2. Szükséges: Szükséges: Editor felkészítése Editor felkészítése ScalableRootEditPart a háttérbe ScalableRootEditPart a háttérbe ZoomManager ZoomManager ZoomInAction, ZoomOutAction ZoomInAction, ZoomOutAction getAdapter() módosítása getAdapter() módosítása ActionBarContributor felkészítése ActionBarContributor felkészítése ZoomInRetargetAction, ZoomOutRetargetAction ZoomInRetargetAction, ZoomOutRetargetAction

19 Grafikus nézet nagyítása 3.1 Editor felkészítése Editor felkészítése protected void configureGraphicalViewer() { […] […] ScalableRootEditPart rootEditPart = ScalableRootEditPart rootEditPart = new ScalableRootEditPart(); viewer.setRootEditPart(rootEditPart); viewer.setRootEditPart(rootEditPart); ZoomManager manager = rootEditPart.getZoomManager(); ZoomManager manager = rootEditPart.getZoomManager(); IAction action = new ZoomInAction(manager); IAction action = new ZoomInAction(manager); getActionRegistry().registerAction(action); getActionRegistry().registerAction(action); action = new ZoomOutAction(manager); action = new ZoomOutAction(manager); getActionRegistry().registerAction(action); getActionRegistry().registerAction(action); […] […]}

20 Grafikus nézet nagyítása 3.2 Editor felkészítése Editor felkészítése public Object getAdapter(Class type) { if (type == ZoomManager.class) if (type == ZoomManager.class) return ( (ScalableRootEditPart) return ( (ScalableRootEditPart) getGraphicalViewer().getRootEditPart()) getGraphicalViewer().getRootEditPart()).getZoomManager();.getZoomManager(); return super.getAdapter(type); return super.getAdapter(type);}

21 Grafikus nézet nagyítása 4. ActionBarContributor felkészítése ActionBarContributor felkészítése protected void buildActions() { […] […] addRetargetAction(new ZoomInRetargetAction()); addRetargetAction(new ZoomInRetargetAction()); addRetargetAction(new ZoomOutRetargetAction()); addRetargetAction(new ZoomOutRetargetAction());} public void contributeToToolBar( IToolBarManager toolBarManager) IToolBarManager toolBarManager){ toolBarManager.add(new Separator()); toolBarManager.add(new Separator()); toolBarManager.add( toolBarManager.add( getActionRegistry().getAction( getActionRegistry().getAction( GEFActionConstants.ZOOM_IN)); GEFActionConstants.ZOOM_IN)); toolBarManager.add( toolBarManager.add( getActionRegistry().getAction( getActionRegistry().getAction( GEFActionConstants.ZOOM_OUT)); GEFActionConstants.ZOOM_OUT));}

22 Grafikus nézet nagyítása 5. Extra: fix lehetőségek Extra: fix lehetőségek

23 Grafikus nézet nagyítása 6. ActionBarContributor.contributeToToolBar() ActionBarContributor.contributeToToolBar() toolBarManager.add( new ZoomComboContributionItem(getPage())); new ZoomComboContributionItem(getPage())); Editor.configureGraphicalViewer() Editor.configureGraphicalViewer() double[] zoomLevels = new double[] { 0.25,0.5,0.75,1.0,1.5,2.0,2.5,3.0,10.0,20.0 }; manager.setZoomLevels(zoomLevels); ArrayList zoomContributions = new ArrayList(); zoomContributions.add(ZoomManager.FIT_ALL);zoomContributions.add(ZoomManager.FIT_HEIGHT);zoomContributions.add(ZoomManager.FIT_WIDTH);manager.setZoomLevelContributions(zoomContributions);

24 Vonalzók, igazítás Cél: alakzatok egymáshoz igazítása „vonalzók” mentén Cél: alakzatok egymáshoz igazítása „vonalzók” mentén Használat: 1.Alakzatok kijelölése 2. Igazító gomb megnyomása

25 Vonalzók, igazítás 2. Szükséges: Szükséges: Editor kiegészítése Editor kiegészítése 6 AlignmentAction regisztrálása 6 AlignmentAction regisztrálása ActionBarContributor kiegészítése ActionBarContributor kiegészítése 6 AlignmentRetargetAction hozzáadása 6 AlignmentRetargetAction hozzáadása

26 Vonalzók, igazítás 3. ActionBarContributor.contributeToToolBar() ActionBarContributor.contributeToToolBar() toolBarManager.add(getActionRegistry().getAction(GEFActionConstants.ALIGN_LEFT));.getAction(GEFActionConstants.ALIGN_LEFT)); //.CENTER,.RIGHT,.TOP,.MIDDLE,.BOTTOM ActionBarContributor.buildActions() ActionBarContributor.buildActions() addRetargetAction(newAlignmentRetargetAction(PositionConstants.LEFT)); // PositionConstants.CENTER //.RIGHT //.TOP //.MIDDLE //.BOTTOM

27 Vonalzók, igazítás 4. Editor.createActions() Editor.createActions() public void createActions() { […] […] IAction action = IAction action = new AlignmentAction((IWorkbenchPart) this, new AlignmentAction((IWorkbenchPart) this, PositionConstants.LEFT); PositionConstants.LEFT); //.CENTER,.RIGHT,.TOP,.MIDDLE,.BOTTOM //.CENTER,.RIGHT,.TOP,.MIDDLE,.BOTTOM registry.registerAction(action); registry.registerAction(action); getSelectionActions().add(action.getId()); getSelectionActions().add(action.getId()); […] […]}

28 Fa modellnézet, kicsinyített vázlat GEF tartalmaz egy saját TreeViewer implementációt GEF tartalmaz egy saját TreeViewer implementációt TreeEditPart-okat jelenít meg TreeEditPart-okat jelenít meg fa nézetű szerkesztőhöz is felhasználható fa nézetű szerkesztőhöz is felhasználható Kiválasztás szinkronizálható a grafikus szerkesztőhöz Kiválasztás szinkronizálható a grafikus szerkesztőhöz Outline nézet alja: scrollozható thumbnail vázlat Outline nézet alja: scrollozható thumbnail vázlat

29 Fa modellnézet, kicsinyített vázlat 2. Szükséges: Szükséges: Saját ContentOutlinePage osztály Saját ContentOutlinePage osztály Editor belső osztályaként megvalósítva Editor belső osztályaként megvalósítva TreeEditPart-ok a modellhez TreeEditPart-ok a modellhez IPropertySource támogatás IPropertySource támogatás TreeEditPartFactory TreeEditPartFactory TreeEditPolicy TreeEditPolicy Csak akkor, ha a fa nézetben kell szerkesztés Csak akkor, ha a fa nézetben kell szerkesztés Saját SelectionSynchronizer Saját SelectionSynchronizer Csak akkor, ha speciális működés kell Csak akkor, ha speciális működés kell

30 Fa modellnézet, kicsinyített vázlat 3.1 MyContentOutlinePage belső osztály MyContentOutlinePage belső osztály import org.eclipse.gef.ui.parts.ContentOutlinePage; class MyContentOutlinePage extends ContentOutlinePage { private SashForm sash; private SashForm sash; public MyContentOutlinePage() public MyContentOutlinePage() { super(new TreeViewer()); super(new TreeViewer()); } public void createControl(Composite parent) public void createControl(Composite parent) { sash = new SashForm(parent, SWT.VERTICAL); sash = new SashForm(parent, SWT.VERTICAL); } public Control getControl() { public Control getControl() { return sash; return sash; }} SWT konténer control, két részből áll, elválasztó egyenes mozgatható

31 Fa modellnézet, kicsinyített vázlat 3.2 MyContentOutlinePage belső osztály „bekötése” MyContentOutlinePage belső osztály „bekötése” public Object getAdapter(Class type) { if (type == IContentOutlinePage.class) if (type == IContentOutlinePage.class) { return new MyContentOutlinePage(); return new MyContentOutlinePage(); } return super.getAdapter(type); return super.getAdapter(type);}

32 Fa modellnézet, kicsinyített vázlat 4.1 TreeEditPart-ok TreeEditPart-ok public abstract class MyTreeEditPart extends AbstractTreeEditPart extends AbstractTreeEditPart implements PropertyChangeListener implements PropertyChangeListener{ public void activate() public void activate() { super.activate(); super.activate(); ((AbstractModel)getModel()) ((AbstractModel)getModel()).addPropertyChangeListener(this);.addPropertyChangeListener(this); } public void deactivate() public void deactivate() { ((AbstractModel)getModel()) ((AbstractModel)getModel()).removePropertyChangeListener(this);.removePropertyChangeListener(this); super.deactivate(); super.deactivate(); }} Értesítési mechanizmus bekötése

33 Fa modellnézet, kicsinyített vázlat 4.2 TreeEditPart-ok TreeEditPart-ok public abstract class ContentsTreeEditPart extends MyTreeEditPart extends MyTreeEditPart{ […] […] protected List getModelChildren() protected List getModelChildren() { return ((ContentsModel)getModel()).getChildren(); return ((ContentsModel)getModel()).getChildren(); } public void propertyChange(PropertyChangeEvent evt) public void propertyChange(PropertyChangeEvent evt) { if(evt.getPropertyName() if(evt.getPropertyName().equals(ContentsModel.P_CHILDREN)).equals(ContentsModel.P_CHILDREN)) refreshChildren(); refreshChildren(); }}

34 Fa modellnézet, kicsinyített vázlat 4.3 TreeEditPart-ok TreeEditPart-ok public abstract class HelloTreeEditPart extends MyTreeEditPart extends MyTreeEditPart{ […] […] protected void refreshVisuals() protected void refreshVisuals() { HelloModel model = (HelloModel) getModel(); HelloModel model = (HelloModel) getModel(); setWidgetText(model.getText()); setWidgetText(model.getText()); } public void propertyChange(PropertyChangeEvent evt) public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName() if (evt.getPropertyName().equals(HelloModel.P_TEXT)).equals(HelloModel.P_TEXT)) refreshVisuals(); refreshVisuals(); }}

35 Fa modellnézet, kicsinyített vázlat 5. TreeEditPartFactory TreeEditPartFactory public class TreeEditPartFactory implements EditPartFactory implements EditPartFactory{ public EditPart createEditPart public EditPart createEditPart (EditPart context, Object model) (EditPart context, Object model) { EditPart part = null; EditPart part = null; if (model instanceof ContentsModel) if (model instanceof ContentsModel) part = new ContentsTreeEditPart(); part = new ContentsTreeEditPart(); else if (model instanceof HelloModel) else if (model instanceof HelloModel) part = new HelloTreeEditPart(); part = new HelloTreeEditPart(); if (part != null) if (part != null) part.setModel(model); part.setModel(model); return part; return part; }}

36 Fa modellnézet, kicsinyített vázlat 6.1 TreeViewer és EditPartok összekapcsolása TreeViewer és EditPartok összekapcsolása public class MyContentOutlinePage extends ContentOutlinePage extends ContentOutlinePage{ […] […] public void createControl(Composite parent) public void createControl(Composite parent) { getViewer().createControl(sash); getViewer().createControl(sash); getViewer().setEditDomain(getEditDomain()); getViewer().setEditDomain(getEditDomain()); getViewer().setEditPartFactory( getViewer().setEditPartFactory( new TreeEditPartFactory()); new TreeEditPartFactory()); getViewer().setContents(contentsModel); getViewer().setContents(contentsModel); getSelectionSynchronizer() getSelectionSynchronizer().addViewer(getViewer());.addViewer(getViewer()); }} Külső Editor osztály private függvénye

37 Fa modellnézet, kicsinyített vázlat 6.2 TreeViewer és EditPartok összekapcsolása TreeViewer és EditPartok összekapcsolása public class MyContentOutlinePage extends ContentOutlinePage extends ContentOutlinePage{ […] […] public void dispose() public void dispose() { getSelectionSynchronizer() getSelectionSynchronizer().removeViewer(getViewer());.removeViewer(getViewer()); super.dispose(); super.dispose(); }}

38 Fa modellnézet, kicsinyített vázlat 7. TreeEditPolicy TreeEditPolicy COMPONENT_ROLE: ComponentEditPolicy COMPONENT_ROLE: ComponentEditPolicy createDeleteCommand() createDeleteCommand() TREE_CONTAINER_ROLE: TreeContainerEditPolicy TREE_CONTAINER_ROLE: TreeContainerEditPolicy getAddCommand() getAddCommand() Tree-n belüli drag and drop Tree-n belüli drag and drop getCreateCommand() getCreateCommand() Konténeren belül jön létre a gyerek elem Konténeren belül jön létre a gyerek elem getMoveChildrenCommand() getMoveChildrenCommand() Konténeren belüli mozgatás Konténeren belüli mozgatás

39 Fa modellnézet, kicsinyített vázlat 8.1 Thumbnail összerakása Thumbnail összerakása public class MyContentOutlinePage extends ContentOutlinePage extends ContentOutlinePage{ […] […] public void createControl() public void createControl() { […] […] Canvas canvas = new Canvas(sash, SWT.BORDER); Canvas canvas = new Canvas(sash, SWT.BORDER); LightweightSystem lws = LightweightSystem lws = new LightweightSystem(canvas); new LightweightSystem(canvas); thumbnail = new ScrollableThumbnail( thumbnail = new ScrollableThumbnail( (Viewport) ((ScalableRootEditPart) (Viewport) ((ScalableRootEditPart) getGraphicalViewer() getGraphicalViewer().getRootEditPart()).getFigure());.getRootEditPart()).getFigure());

40 Fa modellnézet, kicsinyített vázlat 8.2 Thumbnail összerakása Thumbnail összerakása thumbnail.setSource(((ScalableRootEditPart) thumbnail.setSource(((ScalableRootEditPart) getGraphicalViewer().getRootEditPart()) getGraphicalViewer().getRootEditPart()).getLayer(LayerConstants.PRIMARY_LAYER));.getLayer(LayerConstants.PRIMARY_LAYER)); // PRINTABLE_LAYERS: nyilak is látszódnak! // PRINTABLE_LAYERS: nyilak is látszódnak! lws.setContents(thumbnail); lws.setContents(thumbnail); disposeListener = new DisposeListener() disposeListener = new DisposeListener() { public void widgetDisposed(DisposeEvent e) { public void widgetDisposed(DisposeEvent e) { if (thumbnail != null) { if (thumbnail != null) { thumbnail.deactivate();thumbnail = null; thumbnail.deactivate();thumbnail = null; } } } }; }; getGraphicalViewer().getControl() getGraphicalViewer().getControl().addDisposeListener(disposeListener);.addDisposeListener(disposeListener);}

41 Fa modellnézet, kicsinyített vázlat 8.3 Thumbnail összerakása Thumbnail összerakása public class MyContentOutlinePage extends ContentOutlinePage extends ContentOutlinePage{ […] […] public void dispose() public void dispose() { getSelectionSynchronizer() getSelectionSynchronizer().removeViewer(getViewer());.removeViewer(getViewer()); if (getGraphicalViewer().getControl() != null if (getGraphicalViewer().getControl() != null && !getGraphicalViewer().getControl().isDisposed()) && !getGraphicalViewer().getControl().isDisposed()) getGraphicalViewer().getControl() getGraphicalViewer().getControl().removeDisposeListener(disposeListener);.removeDisposeListener(disposeListener); super.dispose(); super.dispose(); iOutlinePage = null; iOutlinePage = null; }}

42 Fa modellnézet, kicsinyített vázlat 8.3 Thumbnail összerakása Thumbnail összerakása public class MyContentOutlinePage extends ContentOutlinePage extends ContentOutlinePage{ […] […] public void dispose() public void dispose() { getSelectionSynchronizer() getSelectionSynchronizer().removeViewer(getViewer());.removeViewer(getViewer()); if (getGraphicalViewer().getControl() != null if (getGraphicalViewer().getControl() != null && !getGraphicalViewer().getControl().isDisposed()) && !getGraphicalViewer().getControl().isDisposed()) getGraphicalViewer().getControl() getGraphicalViewer().getControl().removeDisposeListener(disposeListener);.removeDisposeListener(disposeListener); super.dispose(); super.dispose(); iOutlinePage = null; iOutlinePage = null; }}

43 Fa modellnézet, kicsinyített vázlat 9 A kész Outline nézet: A kész Outline nézet: Zoom-ot követi Zoom-ot követi „Lusta” renderelés „Lusta” renderelés

44 Eclipse Modeling Framework és GEF együttes használata Eclipse Development using the Graphical Editing Framework and the Eclipse Modeling Framework című IBM RedBook alapján http://www.redbooks.ibm.com/redbooks/pdfs/sg246302.pdf

45 Áttekintés Cél: Eclipse-be integrált grafikus szerkesztő készítése egy megadott modellezési nyelvhez Cél: Eclipse-be integrált grafikus szerkesztő készítése egy megadott modellezési nyelvhez Eszközök: Eszközök: EMF: modell EMF: modell Tárolás Tárolás Manipuláció Manipuláció Perzisztencia Perzisztencia GEF: view, controller GEF: view, controller Megjelenítés Megjelenítés Szerkesztő funkciók Szerkesztő funkciók

46 Munkafolyamat Metamodell tervezése Metamodell tervezése Annotált Java kód Annotált Java kód ECore / EMOF ECore / EMOF Rational Rose osztálydiagram Rational Rose osztálydiagram XML Schema Definition (XSD) XML Schema Definition (XSD) Kódgenerálás Kódgenerálás EMF.Model (EMF.Edit, EMF.Editor) EMF.Model (EMF.Edit, EMF.Editor) GEF-es interfész kódolása GEF-es interfész kódolása Szerkesztés Szerkesztés Perzisztencia (XMI) Perzisztencia (XMI)

47 Az EMF szolgáltatásai Kódgenerálás Kódgenerálás Model Model Reflektív API Reflektív API Konzisztencia biztosítása Konzisztencia biztosítása EMF Notification EMF Notification Edit Edit Provider osztályok szerkesztőkhöz Provider osztályok szerkesztőkhöz Editor Editor Tree view szerkesztő Tree view szerkesztő Property sheet Property sheet Undo / redo Undo / redo JFace alapúak JFace alapúak Szorosan a Szorosan a modellhez kötöttek modellhez kötöttek (1-1 leképezés) (1-1 leképezés)

48 A GEF „bekötése” Több lehetőség: Több lehetőség: EMF.Edit szerkesztőhőz GEF megjelenítés EMF.Edit szerkesztőhőz GEF megjelenítés Bonyolult, nem foglalkozunk vele Bonyolult, nem foglalkozunk vele GEF modell legyen EMF alapú GEF modell legyen EMF alapú Egyszerű(bb) Egyszerű(bb) Rugalmas Rugalmas

49 Példa: Hálózat

50 Modell – EditPart leképezés Modell Modell GEF szempontjából a megjelenítés-specifikus információ is a „modell” része  GEF szempontjából a megjelenítés-specifikus információ is a „modell” része  EMF modell kiegészítése EMF modell kiegészítése Saját „view modell” írása Saját „view modell” írása Megjelenítési információk külön perzisztenciája Megjelenítési információk külön perzisztenciája EditPart EditPart GEF „nehéz” controllerei GEF „nehéz” controllerei Model-view kapcsolat Model-view kapcsolat Felhasználói interakció kezelése Felhasználói interakció kezelése két általános ősosztály: két általános ősosztály: AbstractGraphicalEditPart AbstractGraphicalEditPart AbstractConnectionEditPart AbstractConnectionEditPart

51 GraphicalEditPart hierarchia Hierarchikus felépítés Hierarchikus felépítés Gyökér: a legfelső szintű tartalmazó elem Gyökér: a legfelső szintű tartalmazó elem Általában: gyökér = diagram „háttér” Általában: gyökér = diagram „háttér” Modellben ilyen nem szükségszerűen található  Modellben ilyen nem szükségszerűen található  pl. EMF ResourceSetnek feleltethető meg Példa: gyökér = Network Példa: gyökér = Network Továbbiak: a modell hierarchiát követve Továbbiak: a modell hierarchiát követve protected List getModelChildren(){ return getNetwork().getNodes(); }

52 Leképezés GraphicalEditPartokra Nézet nem feltétlenül követi a modell struktúráját Nézet nem feltétlenül követi a modell struktúráját „Szűkebb”: getModelChildren() minden tartalmazottként ábrázolandó modellelemet adjon vissza, és csak azokat! „Szűkebb”: getModelChildren() minden tartalmazottként ábrázolandó modellelemet adjon vissza, és csak azokat! „Tágabb”: „Tágabb”: összetettebb ábrák  több EditPart egy modell-elemhez (pl. direct editing attribútumokhoz)

53 Indirekt leképezés Általánosságban: Általánosságban: modell - GraphicalEditPart megfeleltetés tetszőleges lehet Megkötés: kiegészítő EditPartokhoz KELL egy (láthatatlan) tartalmazó EditPart Megkötés: kiegészítő EditPartokhoz KELL egy (láthatatlan) tartalmazó EditPart Oka: megjelenítés java.util.Map-et használ Oka: megjelenítés java.util.Map-et használ Megoldás: a kiegésztítők „modelljeit” a getModelChildren() hívás generálhatja Megoldás: a kiegésztítők „modelljeit” a getModelChildren() hívás generálhatja

54 Indirekt leképezés 2. ConnectionEditPart ConnectionEditPart Gyakori probléma: asszociációt kell megjeleníteni, de nincs hozzá explicit modellbeli objektum Gyakori probléma: asszociációt kell megjeleníteni, de nincs hozzá explicit modellbeli objektum Megoldás: Megoldás: Új modell-réteg írása  Új modell-réteg írása  Indirekt leképezés Indirekt leképezés EditPartokhoz kell „modell”  String id EditPartokhoz kell „modell”  String id

55 Indirekt leképezés 3. Network példa: Link indirekt leképezése Network példa: Link indirekt leképezése protected List getModelSourceConnections() { Vector s = new Vector(); Iterator i = getNetworkNode().getDownstreamLinks().iterator(); Node n; while(i.hasNext()) { n = (Node)i.next(); s.add(getNetworkNode().toString() + "->" + n.toString()); } return s; } Mi legyen az összekötők töréspontjaival?

56 Leképezés EditPartokra Network példa: Network példa: Network: Network: NetworkEditPart [AbstractGraphicalEditPart] Node: Node: NetworkNodeEditPart [AbstractGraphicalEditPart] NetworkEditPart „gyerekei” lesznek NetworkEditPart „gyerekei” lesznek Link: Link: LinkEditPart [AbstractConnectionEditPart]

57 Leképezés EditPartokra 2. Network példa: NetworkEditPartFactory Network példa: NetworkEditPartFactory public class GraphicalEditPartsFactory implements EditPartFactory { public EditPart createEditPart(EditPart context, Object obj) { if(obj instanceof Network) return new NetworkEditPart((Network)obj); else if(obj instanceof Node) return new NetworkNodeEditPart((Node)obj); else if (obj instanceof Link) return new LinkEditPart((Link)obj); return null; }

58 Tulajdonságok Property sheet Property sheet Szükséges: IPropertySource minden EditParthoz Szükséges: IPropertySource minden EditParthoz Több megoldás: Több megoldás: EMF modell módosítása  EMF modell módosítása  Proxy osztály Proxy osztály EditPart getAdapter() metódusa példányosítja EditPart getAdapter() metódusa példányosítja EMF reflektív API segítségével általános is lehet EMF reflektív API segítségével általános is lehet

59 Tulajdonságok 2. public IPropertyDescriptor[] getPropertyDescriptors() { […] while(it.hasNext()) { EAttributeattr = (EAttribute)it.next(); EDataTypetype = attr.getEAttributeType(); if(attr.isID()) { descriptors.add( new PropertyDescriptor( Integer.toString(attr.getFeatureID()), attr.getName())); } else if( type.getInstanceClass() == String.class ) { descriptors.add( new TextPropertyDescriptor( Integer.toString(attr.getFeatureID()), attr.getName())); } […] } […] }

60 EMF modellek szerkesztése GEF Command osztályok csak a modellt manipulálják GEF Command osztályok csak a modellt manipulálják Undo: elég információt kell tárolni Undo: elég információt kell tárolni Kaszkád törlés Kaszkád törlés Kétirányú referenciák törlése Kétirányú referenciák törlése Veszélyes objektum referenciák Veszélyes objektum referenciák … Általános (reflektív) megjelenítés esetén: snapshotok Általános (reflektív) megjelenítés esetén: snapshotok Tapasztalat: meglepően problémás lehet! Tapasztalat: meglepően problémás lehet!

61 A modell változásainak követése EMF Notification EMF Notification Minden EObject Notifier, amely Adaptereket értesít Minden EObject Notifier, amely Adaptereket értesít generált get-set-add-remove metódusok támogatják generált get-set-add-remove metódusok támogatják Megoldás: EditPartok implementálják az org.eclipse.emf.common.notify.Adapter interfészt Megoldás: EditPartok implementálják az org.eclipse.emf.common.notify.Adapter interfészt (De)regisztráció: activate() – deactivate() metódusokban (De)regisztráció: activate() – deactivate() metódusokban Eseménykezelés: Eseménykezelés: Jellege: push-pull Jellege: push-pull Megvalósítása: notifyChanged() metódusban Megvalósítása: notifyChanged() metódusban

62 A modell változásainak követése 2. Notification típus EseményVálasz ADDADD_MANY „Gyerekek” jöttek létre refreshChildren() Kapcsolatok jöttek létre refreshSourceConnections()refreshTargetConnections() REMOVEREMOVE_MANY „Gyerekek” törlődtek refreshChildren() Kapcsolatok törlődtek refreshSourceConnections()refreshTargetConnections() SETUNSET Modell attribútum változott refreshVisuals()

63 A modell változásainak követése 3. NetworkEditPart public void notifyChanged(Notification notification) { int type = notification.getEventType(); switch( type ) { case Notification.ADD: case Notification.ADD_MANY: case Notification.REMOVE: case Notification.REMOVE_MANY: refreshChildren(); break; case Notification.SET: refreshVisuals(); break; }

64 A modell változásainak követése 4. NetworkNodeEditPart public void notifyChanged(Notification notification) { int featureId = notification.getFeatureID( NetworkPackage.class ); switch( featureId ) { case NetworkPackage.NODE__UPSTREAM_LINKS: refreshTargetConnections(); break; case NetworkPackage.NODE__DOWNSTREAM_LINKS: refreshSourceConnections(); break; default: refreshVisuals(); break; }

65 Finomhangolás Összetett Figure-ök esetén refreshVisuals() lassú lehet Összetett Figure-ök esetén refreshVisuals() lassú lehet Megoldás: Megoldás: Figure frissítés „szétdarabolása” Figure frissítés „szétdarabolása” notifyChanged() „okosan” a megfelelő metódusokat hívja notifyChanged() „okosan” a megfelelő metódusokat hívja Indirekt leképezés Indirekt leképezés Több modell  közös EditPart Több modell  közös EditPart Multiregisztráció, leválogatás Multiregisztráció, leválogatás Egy modell  több EditPart Egy modell  több EditPart Nem kell külön figyelni, a szülő EditPart frissít Nem kell külön figyelni, a szülő EditPart frissít Tartalmazási hierarchiát nem követő eset Tartalmazási hierarchiát nem követő eset Minden érintett modell elemet figyelni kell, bonyolult lehet  Minden érintett modell elemet figyelni kell, bonyolult lehet 

66 Perzisztencia EMF: Eclipse Resource-ok könnyen használhatók EMF: Eclipse Resource-ok könnyen használhatók Kevés kézi kódolás Kevés kézi kódolás Automatikus load, save, save-as kezelés Automatikus load, save, save-as kezelés Alapértelmezett: XMIResource Alapértelmezett: XMIResource XMI fájlok XMI fájlok

67 Perzisztencia 2. NetworkModelManager private ResourceSet getResourceSet() { // Initcializálás NetworkPackageImpl.init(); // XMI resource factory regisztrációja // a.network kiterjesztésű fájlokhoz // a.network kiterjesztésű fájlokhoz Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE; Resource.Factory.Registry.INSTANCE; Map m = reg.getExtensionToFactoryMap(); m.put("network", new XMIResourceFactoryImpl()); // Új resource set generálása return new ResourceSetImpl(); }

68 Perzisztencia 3. NetworkModelManager public void load(IPath path) throws IOException { getResource(path); getResource(path); Map options = new HashMap(); Map options = new HashMap(); options.put(XMIResource.OPTION_DECLARE_XML, options.put(XMIResource.OPTION_DECLARE_XML, Boolean.TRUE); Boolean.TRUE); resource.load(options); resource.load(options);} public void save(IPath path) throws IOException {getResource(path); Map options = new HashMap(); options.put(XMIResource.OPTION_DECLARE_XML, Boolean.TRUE); Boolean.TRUE);resource.save(options);}

69 A szerkesztő összeállítása Amit nekünk kellett írni: Amit nekünk kellett írni: EditPart-ok EditPart-ok Figure-ok Figure-ok Command-ok Command-ok Action-ök Action-ök Editor Editor MultiPageEditorPart leszármazott MultiPageEditorPart leszármazott egy NetworkModelManager page-enként egy NetworkModelManager page-enként Amit az EMF adott: Amit az EMF adott: Modell Modell Értesítés Értesítés Támogatás a perzisztenciához Támogatás a perzisztenciához Reflektív API az általános megjelenítőkhöz Reflektív API az általános megjelenítőkhöz

70 A szerkesztő összeállítása 2. NetworkEditor NetworkEditor private void createGraphicalViewer(Composite parent) { viewer = new ScrollingGraphicalViewer(); […] // A nézet inicializálása viewer.setEditPartFactory( new GraphicalEditPartsFactory()); viewer.setContents( getNetworkEditor().getNetwork()); }

71 A kész szerkesztő

72 Kitekintés: Graphical Modeling Framework Növekvő igény a testreszabott (domain- specifikus) modellezési eszközökre Növekvő igény a testreszabott (domain- specifikus) modellezési eszközökre Felismerés: GEF, EMF programozása „nem könnyű” Felismerés: GEF, EMF programozása „nem könnyű” Cél: automatizáljuk a GEF kód előállítását Cél: automatizáljuk a GEF kód előállítását Bemenet: Bemenet: EMF modell EMF modell Diagram definíció Diagram definíció Kimenet: Kimenet: Domain-specifikus grafikus editor Domain-specifikus grafikus editor Megoldás: Megoldás: Eclipse Graphical Modeling Framework http://www.eclipse.org/gmf http://www.eclipse.org/gmf

73 Graphical Modeling Framework: tervek Alap: EMF modell, Diagram modell, Mapping modell Alap: EMF modell, Diagram modell, Mapping modell Megjelenítés Megjelenítés Modell-nézet laza csatolása Modell-nézet laza csatolása RCP alkalmazás is generálható RCP alkalmazás is generálható Grafikus tervező modul Draw2D figure-ökhoz Grafikus tervező modul Draw2D figure-ökhoz Szerkesztés Szerkesztés Szerkesztési funkciók széles körét támogatja Szerkesztési funkciók széles körét támogatja Undo / redo Undo / redo Jólformáltsági kényszerek alapján szintakszisvezérelt szerkesztés Jólformáltsági kényszerek alapján szintakszisvezérelt szerkesztés Összetett kényszerekhez OCL kiértékelő Összetett kényszerekhez OCL kiértékelő Perzisztencia Perzisztencia EMF szolgáltatásai alapján EMF szolgáltatásai alapján Nyomtatás Nyomtatás Vektorgrafikus és pixeles kimenet generálása Vektorgrafikus és pixeles kimenet generálása 1.0 M3 péntek óta letölthető, alapok működnek 1.0 M3 péntek óta letölthető, alapok működnek

74 GEF további lehetőségei Drag and drop Drag and drop Nyomtatás Draw2D segítségével Nyomtatás Draw2D segítségével Fejlettebb Draw2D layoutok alkalmazása (DirectedGraphLayout) Fejlettebb Draw2D layoutok alkalmazása (DirectedGraphLayout) Látványos FeedBack effektek Látványos FeedBack effektek Érdemes a GEF-examples csomagot nézegetni! Érdemes a GEF-examples csomagot nézegetni!


Letölteni ppt "Nyílt fejlesztőrendszerek Graphical Editing Framework II."

Hasonló előadás


Google Hirdetések