不通过GMF命令自动创建模型及其相关界面显示

在GMF中,我们创建一个模型的基本流程是:

1.在GMF的Palette面板上的工具进行点击,产生对应的请求

2.当鼠标移到右侧的编辑器上时会根据请求产生对应的CreateElementCommand,当鼠标点击下去时,该命令被执行,

于是工具对应的业务模型,notation模型和对应的editpart全部生成,并在界面上展示出来,但是如何通过其他方式来

产生我们的模型及其UI显示呢。

 

现在我的程序中,是在Papyrus中,不点击右侧Palette的面板上的泳道工具,就能自动的在左侧的编辑器上创建几个泳道。

功能基本实现:但是还有些瑕疵,就是每次Figure创建出来以后,都显示在编辑器的左上角,当有多个时,就会重叠,不是很友好。

 

我自己定义了一个创建泳道的命令CreateActivityPartitionModelCommand

参数意义如下: actPartName 泳道的名称  

             rootEditPart 根EditPart(ActivityDiagramEditPart)

/*
 * 类名:CreateActivityPartitionModelCommand
 * 功能:创建泳道的命令
 */
public class CreateActivityPartitionModelCommand extends RecordingCommand {

		
		private String actPartName;
		private EditPart rootEditPart;
		
		public CreateActivityPartitionModelCommand(String actPartName, 
												   EditPart rootEditPart, 
												   TransactionalEditingDomain transactionalEditingDomain ) {
		
			super(transactionalEditingDomain);
			this.actPartName = actPartName;
			this.rootEditPart = rootEditPart;
		}
		

		/*
		 * 填充命令的具体实现内容 , 即将新创建的泳道添加到根模型中去即可(non-Javadoc)
		 * @see org.eclipse.emf.transaction.RecordingCommand#doExecute()
		 */
		@Override 		
		protected void doExecute() {
			
			//UML2 模型----ActivityPartition
			ActivityPartition newElement = UMLFactory.eINSTANCE.createActivityPartition();	
			newElement.setName(actPartName);
			
		    DiagramImpl notationModel = (DiagramImpl) rootEditPart.getModel();
		    
		    EObject domainElement = newElement;
		    View containerView = notationModel;
		    int index = -1;
		    boolean persisted = true;
		    PreferencesHint preferencesHint = new PreferencesHint("org.eclipse.papyrus.diagram.activity");
		    
		    createActivityPartition( domainElement, 
		    						 containerView, 
		    						 index, 
		    						 persisted, 
		    						 preferencesHint);
		}
	}


        /*
	 * 函数名:createActivityPartition
	 * 功能: 创建一个泳道对应的Notation模型
	 * @param domainElement 对应的业务模型
	 * @param containerView 它的父亲notation
	 * 
	 */
	public org.eclipse.gmf.runtime.notation.Node createActivityPartition(EObject domainElement, View containerView, int index, boolean persisted, PreferencesHint preferencesHint) {
		Shape node = NotationFactory.eINSTANCE.createShape();
		node.getStyles().add(NotationFactory.eINSTANCE.createHintedDiagramLinkStyle());
		node.setLayoutConstraint(NotationFactory.eINSTANCE.createBounds());
		node.setType(UMLVisualIDRegistry.getType(ActivityPartitionEditPart.VISUAL_ID));
		
		ViewUtil.insertChildView(containerView, node, index, persisted);
		node.setElement(domainElement);
		// initializeFromPreferences 
		final IPreferenceStore prefStore = (IPreferenceStore)preferencesHint.getPreferenceStore();


		PreferenceInitializerForElementHelper.initForegroundFromPrefs(node, prefStore, "ActivityPartition");

		PreferenceInitializerForElementHelper.initFontStyleFromPrefs(node, prefStore, "ActivityPartition");

		PreferenceInitializerForElementHelper.initBackgroundFromPrefs(node, prefStore, "ActivityPartition");

		org.eclipse.gmf.runtime.notation.Node label5118 = createLabel(node, UMLVisualIDRegistry.getType(ActivityPartitionNameEditPart.VISUAL_ID));
		createCompartment(node, UMLVisualIDRegistry.getType(ActivityPartitionActivityPartitionContentCompartmentEditPart.VISUAL_ID), false, false, false, false);

		PreferenceInitializerForElementHelper.initCompartmentsStatusFromPrefs(node, prefStore, "ActivityPartition");

		return node;
	}
	
	
	
	protected  org.eclipse.gmf.runtime.notation.DecorationNode createLabel(View owner, String hint) {
		DecorationNode rv = NotationFactory.eINSTANCE.createDecorationNode();
		rv.setType(hint);
		ViewUtil.insertChildView(owner, rv, ViewUtil.APPEND, true);
		return rv;
	}
	
	protected org.eclipse.gmf.runtime.notation.Node createCompartment(View owner, String hint, boolean canCollapse, boolean hasTitle, boolean canSort, boolean canFilter) {
		//SemanticListCompartment rv = NotationFactory.eINSTANCE.createSemanticListCompartment();
		//rv.setShowTitle(showTitle);
		//rv.setCollapsed(isCollapsed);
		org.eclipse.gmf.runtime.notation.Node rv;
		if(canCollapse) {
			rv = NotationFactory.eINSTANCE.createBasicCompartment();
		} else {
			rv = NotationFactory.eINSTANCE.createDecorationNode();
		}
		rv.setLayoutConstraint(NotationFactory.eINSTANCE.createBounds());

		if(hasTitle) {
			TitleStyle ts = NotationFactory.eINSTANCE.createTitleStyle();
			ts.setShowTitle(true);
			rv.getStyles().add(ts);
		}
		if(canSort) {
			rv.getStyles().add(NotationFactory.eINSTANCE.createSortingStyle());
		}
		if(canFilter) {
			rv.getStyles().add(NotationFactory.eINSTANCE.createFilteringStyle());
		}
		rv.setType(hint);
		ViewUtil.insertChildView(owner, rv, ViewUtil.APPEND, true);
		return rv;
	}



主要原理:  

我们创建ActivityPartition对应的notation模型:Shape,并将我们创建的UML2模型ActivityPartition加入到Shape

中(node.setElement(domainElement))。

当我们将ActivityPartition对应的notation模型:Shape node加入到他的父亲标记模型中去的时候,产生一个NotificationEvent事件,通知其

对应的EditPart,在该EditPart中,有对应的处理函数:handleNotificationEvent(Notification event)。

最终会调用AbstractEditPart中的refreshChildren函数。在该函数中会检查他的孩子模型对应的editpart是否存在或他们的对应关系是否正确。

如果孩子对应的editpart不存在,则创建对应的editpart。refreshChild中editPart = createChild(model);

在函数refreshChild中addChild(editPart, i);会调用editpart的getFigure。创建模型对应的图形并在界面中显示出来。

则一整套东西也自然出来了。


/**
	 * Updates the set of children EditParts so that it is in sync with the
	 * model children. This method is called from {@link #refresh()}, and may
	 * also be called in response to notification from the model. This method
	 * requires linear time to complete. Clients should call this method as few
	 * times as possible. Consider also calling {@link #removeChild(EditPart)}
	 * and {@link #addChild(EditPart, int)} which run in constant time.
	 * <P>
	 * The update is performed by comparing the existing EditParts with the set
	 * of model children returned from {@link #getModelChildren()}. EditParts
	 * whose models no longer exist are {@link #removeChild(EditPart) removed}.
	 * New models have their EditParts {@link #createChild(Object) created}.
	 * <P>
	 * This method should <em>not</em> be overridden.
	 * 
	 * @see #getModelChildren()
	 */
	protected void refreshChildren() {
		int i;
		EditPart editPart;
		Object model;

		List children = getChildren();
		int size = children.size();
		Map modelToEditPart = Collections.EMPTY_MAP;
		if (size > 0) {
			modelToEditPart = new HashMap(size);
			for (i = 0; i < size; i++) {
				editPart = (EditPart) children.get(i);
				modelToEditPart.put(editPart.getModel(), editPart);
			}
		}

		List modelObjects = getModelChildren();
		for (i = 0; i < modelObjects.size(); i++) {
			model = modelObjects.get(i);

			// Do a quick check to see if editPart[i] == model[i]
			if (i < children.size()
					&& ((EditPart) children.get(i)).getModel() == model)
				continue;

			// Look to see if the EditPart is already around but in the
			// wrong location
			editPart = (EditPart) modelToEditPart.get(model);

			if (editPart != null)
				reorderChild(editPart, i);
			else {
				// An EditPart for this model doesn't exist yet. Create and
				// insert one.
				editPart = createChild(model);
				addChild(editPart, i);
			}
		}

		// remove the remaining EditParts
		size = children.size();
		if (i < size) {
			List trash = new ArrayList(size - i);
			for (; i < size; i++)
				trash.add(children.get(i));
			for (i = 0; i < trash.size(); i++) {
				EditPart ep = (EditPart) trash.get(i);
				removeChild(ep);
			}
		}
	}

你可能感兴趣的:(GMF,自动创建模型)