如果要建立可编辑2D图形程序,比较基本的要有以下几个主要需求
这样我们就提供给用户一个图形交互的方式来修改业务model,具有这种能力的程序我们可以称之为可编辑2D图形程序(a graphical editor)。
上一篇讨论到在GEF框架中形成了三个对应的树状对象模型。
为了达到之上的需求,GEF通过EditPart如上图建立了View和model之间的关联关系。
于是问题随之而来:
这些树状对象模型 如何?何时?创建
尤其困难的是通过怎样简捷的方法在EditPart中建立它们的关联呢?
GEF给出如下答案:
从上图可以看出在GEF是通过EditPartFactory根据以存在的Model 来创建并设置不同的EditPart。
EditPartFactory的接口如下:
EditPart createEditPart(EditPart context, Object model);
其中model是Object类型,因此可以看出在GEF对model没什么过多的约束,context是于要创建的EditPart有关联的EditPart,例如是将要创建EditPart的Parent。
这样GEF通过一下时序图就非常轻松的(学起来可不轻松:(),根据model对象框架建立了另外两个EditParts和Figures树状体系。[链接]见下附图 时序图。
其中在创建过程中重要的方法:
class ShapesEditor
protected void configureGraphicalViewer() { .. }
protected void initializeGraphicalViewer() {..}
class ShapesEditPartFactory
public EditPart createEditPart(EditPart context, Object modelElement) {
// get EditPart for model element
EditPart part = getPartForElement(modelElement);
// store model element in EditPart
part.setModel(modelElement);
return part;
}
/**
* Maps an object to an EditPart.
* @throws RuntimeException if no match was found (programming error)
*/
private EditPart getPartForElement(Object modelElement) {
//根据不同的model产生不同EditPart
if (modelElement instanceof ShapesDiagram) {
return new DiagramEditPart();
}
if (modelElement instanceof Shape) {
return new ShapeEditPart();
}
if (modelElement instanceof Connection) {
return new ConnectionEditPart();
}
throw new RuntimeException(
"Can't create part for model element: "
+ ((modelElement != null) ? modelElement.getClass().getName() : "null"));
}
class ShapeEditPart
public void setModel(Object model) {
if (getModel() == model)
return;
this.model = model;
}
protected IFigure createFigure() {
IFigure f = createFigureForModel();
f.setOpaque(true); // non-transparent figure
f.setBackgroundColor(ColorConstants.green);
return f;
}
/**
* Return a IFigure depending on the instance of the current model element.
* This allows this EditPart to be used for both sublasses of Shape.
*/
private IFigure createFigureForModel() {
//根据不同的model创建不同的figure
if (getModel() instanceof EllipticalShape) {
return new Ellipse();
} else if (getModel() instanceof RectangularShape) {
return new RectangleFigure();
} else {
// if Shapes gets extended the conditions above must be updated
throw new IllegalArgumentException();
}
}
至此、我们就得到了树状的MVC框架,但是,还是有些问题没有解决:
例如、已存在一个三角图形EditPart,我们想重用它,但是我们还需要增加(或删去)边框可调整的特性,如何保证无需重新建立一个新的EditPart,或者做出丑陋的继承,当功能不断组合后,出现无数子EditPart类?
在界面操作过程中,我们希望面对的是边框调整事件,或者是编辑文本事件,而不是原始的鼠标和键盘事件?
希望EditPart能够自动无误地把事件通知到相应的父及子EditPart中,同时能够按照正确的顺序对事件做出响应?
如何由框架自动完成Undo及Redo功能?
联系客服