`
defrag_sly
  • 浏览: 129703 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

以GefTree为例解释一下如何结合使用gef+emf(2)

阅读更多
创建gef框架。
按照基本习惯定义gef各部分包名:



Gef是一个标准的MVC框架,模型层变化,以EditPart为中枢,驱动界面显示层的改变。这就需要建立EditPart与模型层的关联,和EditPart与显示层的关联。
下面介绍EMF模型如何与EditPart建立基本关联。
创建EMFBaseEditPart。
package org.rufus.gef.emf.examples.tree;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
import org.rufus.gef.emf.model.tree.tree.TreePackage;

abstract public class EmfBasePart extends AbstractGraphicalEditPart {

	private org.rufus.gef.emf.examples.tree.EmfBasePart.Adapter adapter;

	@Override
	public void activate() {
		super.activate();
		adapter = new Adapter();
		(((EObject) getModel()).eAdapters()).add(adapter);

	}

	private class Adapter extends AbstractAdapter {
		public void notifyChanged(Notification notification) {
			if (TreePackage.eINSTANCE.getTree_Root().equals(
					notification.getFeature())
					|| TreePackage.eINSTANCE.getTreeContainer_Node().equals(
							notification.getFeature())
							|| TreePackage.eINSTANCE.getDiagram_Trees().equals(
									notification.getFeature())) {
				refreshChildren();
			} else if (TreePackage.eINSTANCE.getTreeNode_Id().equals(
					notification.getFeature())
					|| TreePackage.eINSTANCE.getTreeNode_Name().equals(
							notification.getFeature())) {
				refreshVisuals();
			}
		}
	}

	@Override
	public void deactivate() {
		(((EObject) getModel()).eAdapters()).remove(adapter);
		super.deactivate();
	}
}

这里的关联建立主要在内部类Adapter中实现,为了使代码清晰,我创建了一个超类AbstractAdapter,这个类没有任何作用仅仅是将没必要实现的代码隐藏掉。
在EMF中通知机制是通过Notification发送出来的,Notification对象中记录着相应得改变,每种类型的变化都有特有的Feature来指示。这部分不理解的可以在代码运行起来后多调试几次。
通知对象建立好了,下面就需要把这个通知对象与EditPart建立关联。
方法activate与deactivate。是在EditPart创建和移除时分别执行的两个方法。所以在这里加入对模型的监听,是比较恰当的,在deactivate中除去监听器的做法,可以减少整个应用内存中的对象引用,适当的提高效率。
创建EditPartFactory与PaletteFactory并将两个Factory注册在Editor中。
Editor中注册代码:
public class TreeEditor extends GraphicalEditorWithPalette {
	protected void configureGraphicalViewer() {
		super.configureGraphicalViewer();
		scalableRootEditPart = new ScalableRootEditPart();
		getGraphicalViewer().setRootEditPart(scalableRootEditPart);
		getGraphicalViewer().setEditPartFactory(new TreeEditPartFactory());
……………………
	}
	protected PaletteRoot getPaletteRoot() {
		if (root == null)
			root = TreePaletteFactory.createPalette();
		return root;
	}
}


PaletteFactory中有一个需要注意的地方:我们需要创建自己的CreationFactory,如果大家接触过普通的gef就会发现这个区别。原因是EMF的Model构造与普通javabean情况下的构造稍有不同。有兴趣的可以对比我的CreationFactory与gef.SimpleFactory

以上几个类已经将GEF有EMF的基本关联建立完毕。剩余部分的关联仅在Command中涉及创建,修改,删除具体Model时有所关联。

介绍控制器EditPart的创建:DiagramEditPart,TreeEditPart,TreeContainEditPart,TreeNodeEditPart。一般情况下。模型的数量与part的数量是1对1 的。特殊需求也可以不遵守。每个EditPart都需要继承基类EmfBasePart。
如大家了解的EditPart是负责Figure(表现层)的创建,与具体逻辑操作,EditPolicy的加载。
以DiagramEditPart为例:
package org.rufus.gef.examples.tree.parts;

import java.util.List;

import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.editpolicies.ConstrainedLayoutEditPolicy;
import org.eclipse.gef.editpolicies.NonResizableEditPolicy;
import org.eclipse.gef.requests.CreateRequest;
import org.rufus.gef.emf.examples.tree.EmfBasePart;
import org.rufus.gef.emf.model.tree.tree.Diagram;
import org.rufus.gef.examples.tree.editpolicy.DiagramContainerEditPolicy;
import org.rufus.gef.examples.tree.figures.DiagramLayoutManager;

/**
 * @author shily Created on Feb 16, 2009
 */
public class DiagramPart extends EmfBasePart {
	@Override
	public Command getCommand(Request request) {
		return super.getCommand(request);
	}

	@Override
	public EditPart getTargetEditPart(Request request) {
		return super.getTargetEditPart(request);
	}

	@Override
	protected IFigure createFigure() {
		Figure f = new Figure();
		f.setLayoutManager(new DiagramLayoutManager());
		return f;
	}

	@Override
	protected List getModelChildren() {
		return this.getDiagram().getTrees();
	}

	private Diagram getDiagram() {
		return (Diagram) this.getModel();
	}

	@Override
	public void performRequest(Request req) {	
		super.performRequest(req);
	}

	@Override
	protected void createEditPolicies() {

		installEditPolicy(EditPolicy.LAYOUT_ROLE,
				new ConstrainedLayoutEditPolicy() {

					@Override
					protected Command createChangeConstraintCommand(
							EditPart child, Object constraint) {
						// cant move
						return null;
					}

					@Override
					protected Command getCreateCommand(CreateRequest request) {
						return null;
					}

					protected EditPolicy createChildEditPolicy(EditPart child) {
						// selection able
						return new NonResizableEditPolicy();
					}

					@Override
					protected Object getConstraintFor(Point point) {
						// TODO Auto-generated method stub
						return null;
					}

					@Override
					protected Object getConstraintFor(Rectangle rect) {
						// TODO Auto-generated method stub
						return null;
					}

				});
		// tree create able
		installEditPolicy(EditPolicy.CONTAINER_ROLE,
				new DiagramContainerEditPolicy());
	}

}

但是这里需要讲两个方法getModelChildren(),和policy. createChildEditPolicy()。
方法getModelChildren是在每次刷新子元素时需要访问的方法,我们需要提供相应的子元素集,gef默认提供了一个空list。有些好的设计,会将这个方法设计到BaseEditPart中。如GMF。
方法createChildEditPolicy()是给子Part创建默认Policy。有些人解释是可以做到统一管理,父part就需要管理子part。但是我的理解有些出入。不管怎样,请大家写代码是保持一个统一的风格。不要对代码的维护造成影响。
顺便说一下figure的布局类DiagramLayoutManager,请感兴趣的同学自己阅读吧。这是表现层的一部分。
为了做出tree的效果,我制作了2个figure。TreeNodeContainerFigure和NodeFigure这部分的代码很简单,TreeNodeContainerFigure中提供expand和collapse方法,NodeFigure重写了paintFigure方法。稍稍阅读就可以理解了。为ContainerFigure制作了一个LayoutManager,主要是一些布局算法,有些方法还结合了Editpolicy一起使用。特性的东西不再赘述。

一个包含model,Editpart,figure,editpolicy等基本结构的gef框架便构建好了。

下面说一下Emf的特性,数据的持久化。

在以前的例子中(不是使用emf模型的例子)。我并没有做数据的持久化,也就是说,每一次编辑并没有保存在文件里。使用了emf就可以利用它自身的特性。具体代码见Editor类。
package org.rufus.gef.examples.tree.editors;
/**
 * @author shily Created on Feb 16, 2009
 */
public class TreeEditor extends GraphicalEditorWithPalette {
	。。。。。。。。。。。。。。。。。。。。
	/**
	 * @see org.eclipse.gef.ui.parts.GraphicalEditor#initializeGraphicalViewer()
	 */
	protected void initializeGraphicalViewer() {

		// emf getresource

		FileEditorInput ei = (FileEditorInput) this.getEditorInput();
		ResourceSet resourceSet = new ResourceSetImpl();
		IFile file = (IFile) getEditorInput().getAdapter(IFile.class);
		URI fileURI = URI.createPlatformResourceURI(file.getFullPath()
				.toString(), true);

		EObject object = null;
		try {
			Resource resource = resourceSet.getResource(fileURI, true);
			object = resource.getContents().get(0);
		} catch (Exception e) {
			// resource has nothing
			object = TreeFactory.eINSTANCE.createDiagram();
		}
		// TreeFactory.eINSTANCE.createDiagram()
		getGraphicalViewer().setContents(object);

		getGraphicalViewer().addDropTargetListener(
				new TemplateTransferDropTargetListener(getGraphicalViewer()));
			。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

	}

	

	/**
	 * @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public void doSave(IProgressMonitor monitor) {

		// emf resource save
		// Save only resources that have actually changed.
		//
		final Map<Object, Object> saveOptions = new HashMap<Object, Object>();
		saveOptions.put(Resource.OPTION_SAVE_ONLY_IF_CHANGED,
				Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER);

		// Do the work within an operation because this is a long running
		// activity that modifies the workbench.
		//
		WorkspaceModifyOperation operation = new WorkspaceModifyOperation() {
			// This is the method that gets invoked when the operation runs.
			//
			@Override
			public void execute(IProgressMonitor monitor) {
				// Save the resources to the file system.
				//

				boolean first = true;
				// Create a resource set
				//
				ResourceSet resourceSet = new ResourceSetImpl();

				// Get the URI of the model file.
				//
				IFile file = (IFile) getEditorInput().getAdapter(IFile.class);
				URI fileURI = URI.createPlatformResourceURI(file.getFullPath()
						.toString(), true);

				// Create a resource for this file.
				//
				Resource resource = resourceSet.createResource(fileURI);

				// Add the initial model object to the contents.
				//
				EObject rootObject = (EObject) getGraphicalViewer()
						.getContents().getModel();
				if (rootObject != null) {
					resource.getContents().add(rootObject);
				}

				// Save the contents of the resource to the file system.
				//				
				try {
					resource.save(saveOptions);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		};
		try {
			// This runs the options, and shows progress.
			//
			new ProgressMonitorDialog(getSite().getShell()).run(true, false,
					operation);
			// fire saved
			this.getCommandStack().markSaveLocation();
			commandStackChanged(null);
		} catch (Exception exception) {
			// Something went wrong that shouldn't.
			//		
		}

	}	
}


注:我的实现并没有考虑多文件,以解异常等等复杂情况。是简单的例子。如果考虑复杂情况,代码可能会更复杂,可供参考的是GMF的默认实现,这里只是展现一下emf的强大功能。
  • 大小: 24.5 KB
3
0
分享到:
评论

相关推荐

    VE 1.2 +GEF+EMF 集成包(virtual editor 1.2) 及说明文档

    VE 1.2 +GEF+EMF 集成包(virtual editor 1.2) emf-sdo-runtime-2.2.0.zip GEF-runtime-3.2.zip VE-runtime-1.2.1.zip VE-SDK-1.2.1.zip 还要继续下载第二个包一起解压 第二个包名称为: VE 1.2 +GEF+EMF 集成包...

    VE 1.2 +GEF+EMF 集成包(virtual editor 1.2) 及说明文档.zip.002

    VE 1.2 +GEF+EMF 集成包(virtual editor 1.2) 及说明文档.zip.002

    Eclipse开发使用GEF和EMF(IBM 红皮书)中英文对照版

    2. 模型和视图的关系:阐述如何使用EMF来定义数据模型,并通过GEF展示为图形界面。 3. 图形编辑器的构建:详细步骤指导如何使用GEF创建可交互的图形编辑器,包括图元的创建、布局管理、编辑操作的实现等。 4. EMF...

    eclipse gef+ve+emf下载

    eclipse gef,ve,emf图形界面插件下载 emf-sdo-runtime-2.2.0.zip GEF-runtime-3.2.zip VE-SDK-1.2.1.zip 安装方式:在eclipse目录下创建两个子目录myplugins和links,然后在myplugins目录下建三个子目录emf,...

    EMF+GEF+VE

    在Eclipse-jee-helios-SR2-win32这个版本的Eclipse集成开发环境中,结合EMF、GEF和VE,开发者可以更方便地设计和实现基于ArcEngine的地图编辑和展示功能,创建出具有图形化界面和模型驱动的GIS应用程序。 通过将EMF...

    EMF、GEF、VE 适合于Eclipse 3.2.0

    VE基于EMF和GEF,它扩展了这两者的功能,使得开发者能够以图形化的方式处理Java类和对象,提高了开发效率和代码的可读性。 在Eclipse 3.2.0版本中,这三种技术的集成使得开发人员能够在同一环境中使用统一的接口和...

    GEF快速入门教程和EMF教程

    本文将详细介绍如何使用Graphical Editing Framework (GEF)实现一个简单的“Hello World”示例,并结合Eclipse Modeling Framework (EMF)进行扩展。通过此教程,读者能够理解GEF的基本架构以及如何在Eclipse RCP应用...

    适用于eclipse3.5的VE1.4插件+emf+GEF

    GEF提供了一组基础类和工具,可以帮助开发者快速创建出交互式的图形编辑界面,与EMF结合使用,能够实现强大的可视化建模功能。 5. **安装过程**:在安装VE1.4插件之前,首先需要安装EMF和GEF。这通常通过Eclipse的...

    EMF_GEF_入门系列

    EMF(Eclipse Modeling Framework)和GEF(Graphical Editing Framework)是两个在Java开发环境中广泛使用的开源框架,尤其在创建图形用户界面和建模工具方面。本入门系列旨在帮助初学者快速理解并掌握这两个强大的...

    m2eclipse+gef+svn插件离线安装包

    安装m2eclipse插件时会依赖gef插件和svn插件,压缩包内包含m2eclipse + gef + svn的全部插件安装包,可以直接离线安装,本人亲测,在Eclipse3.7下安装成功,可以新建Maven项目。 需要注意的是,在离线安装时,切记...

    eclipse emf&gef

    通过将GEF与EMF结合使用,可以轻松创建高度可定制的图形化编辑器,用于编辑由EMF生成的模型。 **3.3 GEF编辑器开发流程** 1. **定义模型**:首先使用EMF定义模型。 2. **创建视图**:使用GEF创建一个图形化的视图...

    emf2.4.2+gef3.4.2+ve1.5.0+中语言文包

    与EMF结合使用时,开发者可以创建基于模型的图形化编辑器,用于设计复杂的系统或应用程序架构。 VE(Visual Editor)是一个基于EMF和GEF的插件,专为Eclipse提供了可视化开发环境。VE1.5.0是该插件的一个版本,它...

    Eclipse GEF+Draw2DAPI

    通过阅读这两个API文档,开发者可以学习如何初始化和配置GEF编辑器,创建和操作EditParts,使用Draw2D进行图形绘制,以及如何结合RCP来构建一个完整的图形编辑应用。同时,文档还可能包含示例代码和常见问题解答,...

    elicpse3.4插件visual editor(ve)1.4+emf2.4+gef3.4完美整合版,适合myeclipse7.0,eclipse3.4

    GEF 3.4 版本在兼容性和性能方面有显著提升,可以与VE结合使用,提供更强大的图形化编程体验。 这个压缩包文件包含的 "features" 和 "plugins" 文件夹是Eclipse插件的安装目录结构。下载并解压后,将这些文件复制到...

    emf swt runtime gef

    4. 示例代码和项目:可能包括了使用EMF、SWT和GEF创建的示例应用程序或编辑器,帮助开发者理解如何结合使用这些技术。 5. 文档和教程:详细介绍了如何使用这三个框架,包括API参考、用户指南和最佳实践。 通过学习...

    ve1.4.0插件 GEF3.2 EMF2.2.0 全套打包

    【标题】:“ve1.4.0插件 GEF3.2 EMF2.2.0 全套打包”这一压缩包包含了用于开发图形化界面的重要工具,包括Visual Editor(VE)1.4.0版本,以及其依赖的Graphical Editing Framework(GEF)3.2版和Eclipse Modeling ...

    GEF EMF GMF 资源

    GEF Example source code 博文链接:https://jamesblog.iteye.com/blog/148279

    Eclipse完整包,插件(emf2.4.2+gef3.4.2)+中文包+eclipse3.5.1

    这个压缩包包含的是一份Eclipse的完整安装,其中包括了两个重要的插件:EMF(Eclipse Modeling Framework)2.4.2版本和GEF(Graphical Editing Framework)3.4.2版本,以及Eclipse的中文语言包和3.5.1版本的Eclipse...

Global site tag (gtag.js) - Google Analytics