GEF插件开发(四,画板元素绘画)

本章节在上一章节基础上,实现画板元素的点击在主视图中生成对应的画板元素视图。(注:工程名修改为com.sunsheen.jfids.gef.usecase.plugin.demo)

1.定义抽象模型AbstractUMLModel,为所有模型父类,抽取公共信息。

PropertyChangeSupport属性实现控制器监听器的注册,使模型信息的改变能够触发控制器的响应来进行视图的更改。

public abstract class AbstractUMLModel implements Serializable{
	//父模型
	private AbstractEntityModel parent;
	//模型属性监听
	private PropertyChangeSupport listeners = new PropertyChangeSupport(this);
	
	/**
	 * 添加监听器
	 * @param listener
	 */
	public void addPropertyChangeListener(PropertyChangeListener listener) {
		listeners.addPropertyChangeListener(listener);
	}
	
	/**
	 * 触发监听
	 * @param propName
	 * @param oldValue
	 * @param newValue
	 */
	public void firePropertyChange(String propName, Object oldValue,Object newValue) {
		listeners.firePropertyChange(propName, oldValue, newValue);
	}
	
	/**
	 * 移除监听器
	 * @param listener
	 */
	public void removePropertyChangeListener(PropertyChangeListener listener) {
		listeners.removePropertyChangeListener(listener);
	}
	
	public void setParent(AbstractEntityModel parent) {
		this.parent = parent;
	}
	
	public AbstractEntityModel getParent() {
		return parent;
	}
}

2.定义抽象实体类,抽取实体模型公有属性。

抽象实体模型定义,包括视图约束信息、子模型、对应的属性改变所触发的事件信息。

public abstract class AbstractEntityModel extends AbstractUMLModel {
	/**
	 * 视图约束信息(坐标位置及长度、高度)
	 */
	private Rectangle constraint;

	/**
	 * 子模型集合
	 */
	private List<AbstractUMLModel> children = new ArrayList<AbstractUMLModel>();
	public static final String P_CONSTRAINT = "_constraint";
	public static final String P_CHILDREN = "_children";
	public static final String P_ENTITY_NAME = "_entityName";

	public Rectangle getConstraint() {
		return constraint;
	}

	public void addChild(AbstractUMLModel model) {
		children.add(model);
		model.setParent(this);
		//触发添加孩子事件
		firePropertyChange(P_CHILDREN, null, model);
	}

	public void removeChild(AbstractUMLModel model) {
		children.remove(model);
		model.setParent(this);
		firePropertyChange(P_CHILDREN, null, model);
	}

	public List<AbstractUMLModel> getChildren() {
		return this.children;
	}

	/**
	 * 设置约束信息
	 * 
	 * @param constraint
	 */
	public void setConstraint(Rectangle constraint) {
		if (constraint.x < 0) {
			constraint.x = 0;
		}
		if (constraint.y < 0) {
			constraint.y = 0;
		}
		this.constraint = constraint;
		firePropertyChange(P_CONSTRAINT, null, constraint);
	}
}

3.提取用例图的角色信息与用例信息,定义用例角色模型与用例模型。

/**
 * 用例角色模型
 * @author lz
 *
 */
public class UsecaseActorModel extends AbstractEntityModel{
	/**
	 * 角色名
	 */
	private String name;
	public UsecaseActorModel() {
		super();
		setName("角色");
	}
	
	public void setName(String name) {
		String old = this.name;
		this.name = name;
		firePropertyChange(P_ENTITY_NAME, old, name);
	}

	public String getName() {
		return name;
	}
}
/**
 * 用例模型
 * @author lz
 *
 */
public class UsecaseModel  extends AbstractEntityModel{
	private String name;
	private static final Dimension MINIMUM_SIZE = new Dimension(100,40);
	
	public UsecaseModel() {
		super();
		setName("用例");
	}

	public void setConstraint(Rectangle constraint) {
		Dimension size = constraint.getSize();
		if (MINIMUM_SIZE.contains(size)) {
			constraint.setSize(MINIMUM_SIZE);
		}
		super.setConstraint(constraint);
	}
	
	public void setName(String name) {
		String old = this.name;
		this.name = name;
		firePropertyChange(P_ENTITY_NAME, old, name);
	}
	
	public String getName() {
		return name;
	}
	
}

 

4.抽取控制器公有信息,定义AbstractEditPart类。

控制器实现PropertyChangeListener接口,让其作为属性改变监听器。控制器激活时,在对应模型中注册此监听器,当控制器失效时移除监听器

public abstract class AbstractEditPart extends AbstractGraphicalEditPart implements PropertyChangeListener{
	
	/**
	 * 激活控制器是注册模型监听器
	 */
	public void activate() {
		super.activate();
		((AbstractUMLModel) getModel()).addPropertyChangeListener(this);
	}
	
	/**
	 * 控制器无效时移除模型监听器
	 */
	public void deactivate() {
		super.deactivate();
		((AbstractUMLModel) getModel()).removePropertyChangeListener(this);
	}
}

5.定义视图模型抽象控制器。

/**
 * 抽象视图控制器
 * @author lz
 *
 */
public abstract class AbstractEntityEditPart extends AbstractEditPart{
	@Override
	public void propertyChange(PropertyChangeEvent evt) {
		// TODO Auto-generated method stub
		
	}


	@Override
	protected void createEditPolicies() {
		// TODO Auto-generated method stub
		
	}

	protected void refreshVisuals() {
		super.refreshVisuals();
		Object model = getModel();
		if (model instanceof AbstractEntityModel) {
			Rectangle constraint = ((AbstractEntityModel) model)
					.getConstraint();
			((GraphicalEditPart) getParent()).setLayoutConstraint(this,
					getFigure(), constraint);
		}
	}
}

6.定义用例角色控制器与用例控制器来响应模型的变化,增加相应的图形。

/**
 * 用例角色控制器
 * @author lz
 *
 */
public class UsecaseActorEditPart extends AbstractEntityEditPart{

	@Override
	protected IFigure createFigure() {
		UsecaseActorModel model = (UsecaseActorModel) getModel();
		UsecaseActorFigure figure = new UsecaseActorFigure(model);
		figure.getLabel().setText(model.getName());
		return figure;
	}

}
public class UsecaseEditPart extends AbstractEntityEditPart{

	@Override
	protected IFigure createFigure() {
		UsecaseModel model = (UsecaseModel) getModel();
		UsecaseFigure figure = new UsecaseFigure(model);
		figure.getLabel().setText(model.getName());
		return figure;
	}

}

7.修改根控制器

在根控制器中注册布局策略,实现通过创建命令创建子模型,并通过事件的触发来刷新子模型视图,并重写getModelChildren()返回子模型集合。

@Override
	protected void createEditPolicies() {
		installEditPolicy(EditPolicy.LAYOUT_ROLE, new RootEditPolicy());
	}

	@Override
	public void propertyChange(PropertyChangeEvent evt) {
		/**
		 * 如果模型触发RootModel.P_CHILDREN 事件/刷新孩子信息视图
		 */
		if (evt.getPropertyName().equals(RootModel.P_CHILDREN)) {
			refreshChildren();
		}
	}
	
	/**
	 * 返回子模型
	 */
	@Override
	protected List getModelChildren() {
		return ((RootModel)getModel()).getChildren();
	}
public class RootEditPolicy extends XYLayoutEditPolicy {

	@Override
	protected Command getCreateCommand(CreateRequest request) {
		CreateCommand command = new CreateCommand();
		Rectangle constraint = (Rectangle) getConstraintFor(request);
		AbstractEntityModel model = (AbstractEntityModel) request
				.getNewObject();
		model.setConstraint(constraint);
		//设置父模型
		command.setRootModel(getHost().getModel());
		command.setModel(model);
		return command;
	}

	private class CreateCommand extends Command {

		private RootModel root;
		private AbstractEntityModel model;

		public void execute() {
			root.addChild(model);
		}

		public void setRootModel(Object root) {
			this.root = (RootModel) root;
		}

		public void setModel(Object model) {
			this.model = (AbstractEntityModel) model;
		}

		public void undo() {
			root.removeChild(model);
		}
	}

}

 

8.创建用例视图与角色视图类。

/**
 * 用例角色视图
 * @author lz
 *
 */
public class UsecaseActorFigure extends Figure{
	private Label name;

	private Label image;

	public UsecaseActorFigure(UsecaseActorModel model) {
		//设置工具条布局,纵向依次排列
		ToolbarLayout layout = new ToolbarLayout();
		layout.setStretchMinorAxis(false);
		layout.setMinorAlignment(ToolbarLayout.ALIGN_CENTER);
		setLayoutManager(layout);
		setOpaque(false);

		name = new Label();
		name.setOpaque(true);

		image = new Label();
		image.setIcon(UserCaseChartPlugin.getImageDescriptor("icons/actor.gif")
					.createImage());
		image.setOpaque(true);
		add(image);
		add(getLabel());
	}

	public void updatePresentation(AbstractUMLModel model) {
		setBackgroundColor(ColorConstants.white);
		name.setBackgroundColor(ColorConstants.white);
	}

	public Label getLabel() {
		return name;
	}

	public Rectangle getCellEditorRectangle() {
		return name.getBounds().getCopy();
	}
}
/**
 * 用例图、用例图为椭圆形状,在此我们集成Ellipse类
 * @author lz
 *
 */
public class UsecaseFigure extends Ellipse{
	private Label name;

	public UsecaseFigure(UsecaseModel model) {
		name = new Label();
		setBackgroundColor(new Color(null,255, 255, 206));
		setLayoutManager(new BorderLayout());
		add(name, BorderLayout.CENTER);
	}

	public Label getLabel() {
		return name;
	}

}

9.修改PaletteUtil中画板工具关联的模型信息。实现画板元素与相应的模型关联。

private static PaletteContainer createEntityGroup(PaletteRoot root) {
		PaletteDrawer entities = new PaletteDrawer("元素");
		entities.add(createEntityEntry("角色", "用例角色", UsecaseActorModel.class,
				"icons/actor16.gif", "icons/actor16.gif"));
		entities.add(createEntityEntry("用例", "用例描述", UsecaseModel.class,
				"icons/usecase.gif", "icons/usecase.gif"));
		return entities;
	}

10 修改工厂控制器,实现用例模型与角色模型与对应的控制器进行匹配。

@Override
	public EditPart createEditPart(EditPart context, Object model) {
		EditPart part = null;
		if (model instanceof RootModel) {
			part = new RootEditPart();
		}
		if (model instanceof UsecaseModel) {
			part = new UsecaseEditPart();
		}
		if (model instanceof UsecaseActorModel) {
			part = new UsecaseActorEditPart();
		}
		// 设控制器模型
		part.setModel(model);
		return part;
	}

 

转载于:https://my.oschina.net/u/1260047/blog/739322

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值