一、增加属性页的支持
return null;
}
public IPropertyDescriptor[] getPropertyDescriptors() {
IPropertyDescriptor[] descriptors = new IPropertyDescriptor[5];
descriptors[0] = new TextPropertyDescriptor(HelloWorldModel.P_TEXT,
"name");
descriptors[1] = new TextPropertyDescriptor("x", "x");
descriptors[2] = new TextPropertyDescriptor("y", "y");
descriptors[3] = new TextPropertyDescriptor("width", "width");
descriptors[4] = new TextPropertyDescriptor("height", "height");
return descriptors;
}
public Object getPropertyValue(Object id) {
HelloWorldModel model = (HelloWorldModel) getModel();
Rectangle constraints = model.getConstraints();
if (id.equals(HelloWorldModel.P_TEXT)) {
return model.getText();
} else if (id.equals("x")) {
return constraints.x+"";
} else if (id.equals("y")) {
return constraints.y+"";
} else if (id.equals("width")) {
return constraints.width+"";
} else if (id.equals("height")) {
return constraints.height+"";
}
return null;
}
public boolean isPropertySet(Object id) {
return true;
}
public void resetPropertyValue(Object id) {
HelloWorldModel model = (HelloWorldModel) getModel();
if (id.equals(HelloWorldModel.P_TEXT)) {
(model).setText("<unname>");
} else {
model.setConstraints(new Rectangle(0, 0, 100, 20));
}
}
public void setPropertyValue(Object id, Object value) {
HelloWorldModel model = (HelloWorldModel) getModel();
Rectangle constraints = model.getConstraints();
if (id.equals(HelloWorldModel.P_TEXT)) {
((HelloWorldModel) getModel()).setText(value.toString());
} else {
int parseInt = Integer.parseInt(value.toString());
if (id.equals("x")) {
constraints = new Rectangle(parseInt, constraints.y,
constraints.width, constraints.height);
} else if (id.equals("y")) {
constraints = new Rectangle(constraints.x, parseInt,
constraints.width, constraints.height);
} else if (id.equals("width")) {
constraints = new Rectangle(constraints.x, constraints.y,
parseInt, constraints.height);
} else if (id.equals("height")) {
constraints = new Rectangle(constraints.x, constraints.y,
constraints.width, parseInt);
}
model.setConstraints(constraints);
}
}
图一
二、增加大纲视图
@Override
public Object getAdapter(Class type) {
if(type.equals(IContentOutlinePage.class)){
return new DiagramEditorOutlinePage(getGraphicalViewer());
}
return super.getAdapter(type);
}
public class DiagramEditorOutlinePage extends ContentOutlinePage {
private GraphicalViewer viewer;
private Composite control;
public DiagramEditorOutlinePage(GraphicalViewer graphicalViewer) {
this.viewer = graphicalViewer;
}
@Override
public void createControl(Composite parent) {
control = new Composite(parent, SWT.NONE);
control.setLayout(new GridLayout(1, false));
control.setLayoutData(new GridData(GridData.FILL_BOTH));
Canvas canvas = new Canvas(control, SWT.NONE);
canvas.setLayoutData(new GridData(GridData.FILL_BOTH));
LightweightSystem liSystem = new LightweightSystem(canvas);
ScalableFreeformRootEditPart rootEditPart = ((ScalableFreeformRootEditPart) viewer
.getRootEditPart());
ScrollableThumbnail thumbnail = new ScrollableThumbnail(
(Viewport) rootEditPart.getFigure());
thumbnail.setSource(rootEditPart
.getLayer(LayerConstants.SCALABLE_LAYERS));
liSystem.setContents(thumbnail);
}
@Override
public Control getControl() {
return control;
}
@Override
public void setFocus() {
control.setFocus();
}
}
protected void initializeOverview() {
LightweightSystem lws = new LightweightSystem(overview);
RootEditPart rep = getGraphicalViewer().getRootEditPart();
DiagramRootEditPart root = (DiagramRootEditPart) rep;
thumbnail = new ScrollableThumbnail((Viewport) root.getFigure());
// thumbnail.setSource(root.getLayer(LayerConstants.PRINTABLE_LAYERS));
thumbnail.setSource(root.getLayer(LayerConstants.SCALABLE_LAYERS));
lws.setContents(thumbnail);
disposeListener = new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
if (thumbnail != null) {
thumbnail.deactivate();
thumbnail = null;
}
}
};
getEditor().addDisposeListener(disposeListener);
this.overviewInitialized = true;
}
图二
三、dirty标记的增加
一般来说,在Eclipse里,当Editor的内容发生改变时,会有个dirty标记,例如:。但是目前我们的Editor上有编辑时并不会出现dirty标记。所以我们也应该给我们的Editor提供一个。
其实目前也不是对编辑完全无知。当我们做了一些修改,然后关闭时,会得到一个提示:
说明我们的编辑器已经知道了有改动。之所没有显示dirty标记,是因为我们没有通知它。在Eclipse里,要想显示dirty标记是需要发出通知的。下面我们就来完成我们的dirty标记。
我们先理解几点:
1.我们都知道(假设)Eclipse里的Editor是通过方法:isDirty()的返回值来判断是否为脏。
2.Eclipse里的Editor并不是一直轮询isDirty()方法的,它是需要一个事件触发的。
3.我们都知道,所有的GEF里的操作都是通过command来完成的,而所有的command都是放在一个command堆栈中的。这个堆栈可以由editor直接得到。
有这三条,我觉得就够了:isDirty()方法的返回值就由命令栈是否为空决定了。所以就只剩下一个问题了:怎么发出通知机制?简单的想应该是在每个command执行和撤消时都需要发出这个通知。那如果真要这么实现的话,我想大家都会觉得很不好了。幸好,在GEF的Editor里就有一个方法可以完成这件事:commandStackChanged(EventObject event)。 在这个方法在每次命令栈有变化的时候都被会调用。
不知道大家有没有注意到:虽然我们的脏标记没有出来。但是我们的Actions是否可用的状态总是正确。说明这个action的状态总是被更新了。其实看看源码就知道是怎么回事了。commandStackChanged(EventObject event)的默认实现如下:
public void commandStackChanged(EventObject event) {
updateActions(stackActions);
}
所以action的状态总是会被更新的。
刚才上面我也说到了,如果我们要自己完成发出事件机制,那么我们需要在每个command有执行或撤消的地方都发出一个事件。事实上GEF本身也是这样做的,我们看一下commandStackChanged(EventObject event)方法被调用的地方就知道了:
图三
那现在知道怎么做了没?好了,不说了,直接给出代码:
@Override
public boolean isDirty() {
return getCommandStack().isDirty();
}
@Override
public void commandStackChanged(EventObject event) {
super.commandStackChanged(event);
firePropertyChange(PROP_DIRTY);
}
最后再编辑的时候:
图四