到现在为止,我们已经完成了很多工作了:图形的缩放,移动;增加,删除;连线的增加删除,重定向。
不过我们还没有办法修改我们HelloWorld上的文字。这一节我们就来实现对文字的修改。
一、直接编辑的支持
要想支持编辑功能。显示我们也需要安装Policy,写command。那好,我们先做好这部分工作。
EditPolicy里有一个直接编辑Policy:DirectEditPolicy。我们写一个子类继承这个Policy,然后显然应该把它安放在HelloWorldEditPart上。OK,先完成这些。
在HelloWorldEditPart里安装Policy:
installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, new HelloWorldDirectEditPolicy());
实现HelloWorldDirectEditPolicy:
public class HelloWorldDirectEditPolicy extends DirectEditPolicy {
@Override
protected Command getDirectEditCommand(DirectEditRequest request) {
return null;
}
@Override
protected void showCurrentEditValue(DirectEditRequest request) {
}
}
下面我们先完成编辑命令。显示要完成这个编辑,我们至少需要两个东西:当前编辑的HelloWorld对象、修改后的值。所以我们的command可以实现如下:
public class DirectEditHelloWorldCommand extends Command {
private HelloWorldModel model;
private String text;
private String old;
public DirectEditHelloWorldCommand(HelloWorldModel model, String text) {
super();
this.model = model;
this.text = text;
}
@Override
public void execute() {
old = model.getText();
model.setText(text);
}
@Override
public void undo() {
text = model.getText();
model.setText(old);
}
}
再回过头来完成我们的Policy:
public class HelloWorldDirectEditPolicy extends DirectEditPolicy {
@Override
protected Command getDirectEditCommand(DirectEditRequest request) {
Text text = (Text) request.getCellEditor().getControl();
DirectEditHelloWorldCommand command = new DirectEditHelloWorldCommand(
(HelloWorldModel) getHost().getModel(), text.getText().trim());
return command;
}
@Override
protected void showCurrentEditValue(DirectEditRequest request) {
}
}
方法showCurrentEditValue后面我们再讲。这里我们还有一个假设:假设编辑控件是一个text框,至于具体是什么,应该由你选择的CellEditor的类型决定,所以可以肯定在这里我们将选择TextCellEditor。在做树和表的编辑时我们也会用到这个。
我们已经完成了一个完整的过程。按理说我们可以操作了。一般来说GEF上的编辑都是单击鼠标就可以显示出来了。但是现在如果我们单击鼠标,什么也不会出现。为什么呢?
上面我们也提到了,我们选择了TextCellEditor,所以我们在Policy里就把CellEditor的Control强制为Text。我们是这样做的。不过想一想,好像我们还没有在哪个地方告诉GEF我们的选择吧?没有,绝对的没有。
而且除此之外,还有一个问题:假如GEF知道我们是要用TextCellEditor。它又怎么知道这个Text放在什么位置、大小如何呢?这些都是要考虑的问题。所以我们必须有一个地方告诉它这些问题的答案。
这里就要提到另一个类:DirectEditManager。要想实现直接编辑功能,我们需要提供一个DirectEditManager类,用来给出上面问题的答案。DirectEditManager是一个抽象类,我们必须给出一个具体的实现。那我们就首先实现我们的DirectEditManager类。首先看一下DirectEditManager的构造方法(选其中一个):
public DirectEditManager(GraphicalEditPart source, Class editorType, CellEditorLocator locator)
基中:
@param source the source edit part:要编辑的模型的EditPart
@param editorType the cell editor type:编辑单元类,如TextCellEditor.class
@param locator the locator:决定编辑控件的大小和位置,需要自己实现
OK,那现在我们需要实现的类有两个:一个DirectEditManager的实现类;一个CellEditorLocator的实现类。
我们首先来实现CellEditorLocator的实现类:
public class HelloWorldCellEditorLocator implements CellEditorLocator {
private HelloWorldModel model;
public HelloWorldCellEditorLocator(HelloWorldModel model) {
super();
this.model = model;
}
public void relocate(CellEditor celleditor) {
Text text = (Text) celleditor.getControl();
Rectangle constraints = model.getConstraints();
text.setBounds(constraints.x, constraints.y, constraints.width,
constraints.height);
}
}
这里我们增加了一个构造方法,传入编辑的模型,让编辑控件的大小刚好等于编辑模型的图形大小。
下面实现DirectEditManager:
public class HelloWorldDirectEditManager extends DirectEditManager{
public HelloWorldDirectEditManager(GraphicalEditPart source,
Class editorType, CellEditorLocator locator) {
super(source, editorType, locator);
}
@Override
protected void initCellEditor() {
Text text = (Text) getCellEditor().getControl();
HelloWorldModel model = (HelloWorldModel) getEditPart().getModel();
text.setText(model.getText());
}
}
这里我们让编辑控件的初始值为模型的text值。
完了,完成了两个类的实现。下面就是要想把它放哪了。