在上一篇文章中,我们实现了为结点设置图片,但是我们还不能修改结点的图片,所有相同类型结点的图片是一样的。
本例首先给结点添加右击菜单,然后实现修改结点图片的功能。
1、修改ReserveShape1EditPart.java的部分代码,把descriptor、originalImage、OrgImageData声明处的static都去掉,否则修改一个结点之后,同类型的其他结点也会改变。
/**
* @generated NOT
*/
private ImageDescriptor descriptor = ShapesDiagramEditorPlugin
.findImageDescriptor("icons/custom/ReserveShapeFigure.jpg");
private Image originalImage = descriptor.createImage();
private ImageData OrgImageData = originalImage.getImageData();
2、在ReserveShape1EditPart类中添加方法如下:
/**
* @generated NOT
*/
public void setImageData(String imagePath) {
descriptor = ShapesDiagramEditorPlugin.findImageDescriptor(imagePath);
originalImage = descriptor.createImage();
OrgImageData = originalImage.getImageData();
}
3、在工程org.eclipse.myTest.shapes.diagram下新建一个包org.eclipse.myTest.shapes.diagram.edit.actions,用于存放我们自己的Action。在这个包中新建一个类SetImageAction,内容如下:
package org.eclipse.myTest.shapes.diagram.edit.actions;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.Assert;
import org.eclipse.emf.ecore.ENamedElement;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.domain.IEditingDomainProvider;
import org.eclipse.emf.transaction.RunnableWithResult;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.UnexecutableCommand;
import org.eclipse.gmf.runtime.common.core.util.Log;
import org.eclipse.gmf.runtime.common.core.util.Trace;
import org.eclipse.gmf.runtime.diagram.ui.actions.DiagramAction;
import org.eclipse.gmf.runtime.diagram.ui.commands.CommandProxy;
import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.internal.DiagramUIDebugOptions;
import org.eclipse.gmf.runtime.diagram.ui.internal.DiagramUIPlugin;
import org.eclipse.gmf.runtime.diagram.ui.internal.DiagramUIStatusCodes;
import org.eclipse.gmf.runtime.diagram.ui.requests.ChangePropertyValueRequest;
import org.eclipse.gmf.runtime.emf.commands.core.command.CompositeTransactionalCommand;
import org.eclipse.gmf.runtime.emf.core.util.PackageUtil;
import org.eclipse.myTest.shapes.diagram.edit.parts.ReserveShape1EditPart;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
public class SetImageAction extends DiagramAction {
private static String actionid = "org.eclipse.myTest.shapes.diagram.edit.actions.SetImageAction";
private static String actionText = "设置显示图片...";
// id of the property this action will change
private String propertyId = null;
// name of the property this action will change
private String propertyName = null;
private EditPartViewer viewer = null;
public SetImageAction(IWorkbenchPart workbenchPart, EditPartViewer viewer) {
super(workbenchPart);
this.viewer = viewer;
}
public SetImageAction(IWorkbenchPage workbenchPage, String propertyId,
String propertyName) {
super(workbenchPage);
Assert.isNotNull(propertyId);
Assert.isNotNull(propertyName);
setPropertyId(propertyId);
setPropertyName(propertyName);
}
public String getPropertyId() {
return propertyId;
}
public void setPropertyId(String propertyId) {
this.propertyId = propertyId;
}
public String getPropertyName() {
return propertyName;
}
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
@Override
protected Request createTargetRequest() {
return new ChangePropertyValueRequest(getPropertyName(),
getPropertyId());
}
protected void updateTargetRequest() {
ChangePropertyValueRequest request = (ChangePropertyValueRequest) getTargetRequest();
request.setValue(getNewPropertyValue());
}
public void init() {
super.init();
setId(actionid);
setText(actionText);
setToolTipText(actionText);
ISharedImages workbenchImages = PlatformUI.getWorkbench()
.getSharedImages();
setHoverImageDescriptor(workbenchImages
.getImageDescriptor(ISharedImages.IMG_OBJ_FILE));
setImageDescriptor(workbenchImages
.getImageDescriptor(ISharedImages.IMG_OBJ_FILE));
setDisabledImageDescriptor(workbenchImages
.getImageDescriptor(ISharedImages.IMG_OBJ_FILE));
}
protected String getCommandLabel() {
return actionText;
}
protected Object getNewPropertyValue() {
String newImgPath = "icon/test.gif";
return newImgPath;
}
@SuppressWarnings("rawtypes")
protected Object getOperationSetPropertyValue(String id) {
List set = getOperationSet();
if (!set.isEmpty()) {
IGraphicalEditPart primaryEditPart = (IGraphicalEditPart) set
.get(set.size() - 1);
return getPropertyValue(primaryEditPart, id);
}
return null;
}
@SuppressWarnings({ "rawtypes", "restriction" })
protected Object getPropertyValue(final IGraphicalEditPart editPart,
final String thePropertyId) {
try {
return editPart.getEditingDomain().runExclusive(
new RunnableWithResult.Impl() {
@SuppressWarnings("unchecked")
public void run() {
setResult(getStructuralFeatureValue(editPart,
thePropertyId));
}
});
} catch (InterruptedException e) {
Trace.catching(DiagramUIPlugin.getInstance(),
DiagramUIDebugOptions.EXCEPTIONS_CATCHING, getClass(),
"getPropertyValue", e); //$NON-NLS-1$
Log.error(DiagramUIPlugin.getInstance(),
DiagramUIStatusCodes.IGNORED_EXCEPTION_WARNING,
"getPropertyValue", e); //$NON-NLS-1$
}
return null;
}
protected boolean isSelectionListener() {
return true;
}
protected boolean digIntoGroups() {
return false;
}
private Object getStructuralFeatureValue(IGraphicalEditPart editpart,
final String thePropertyId) {
ENamedElement element = PackageUtil.getElement(thePropertyId);
if (element instanceof EStructuralFeature) {
if (digIntoGroups() && editpart instanceof GroupEditPart) {
editpart = (IGraphicalEditPart) editpart.getChildren().get(0);
}
return editpart
.getStructuralFeatureValue((EStructuralFeature) element);
}
return null;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
protected List getTargetEditParts(EditPart editpart) {
if (digIntoGroups() && editpart instanceof GroupEditPart) {
List targetEPs = new ArrayList();
for (Iterator iterator = ((GroupEditPart) editpart)
.getShapeChildren().iterator(); iterator.hasNext();) {
EditPart childEP = (EditPart) iterator.next();
targetEPs.addAll(super.getTargetEditParts(childEP));
}
return targetEPs;
}
return super.getTargetEditParts(editpart);
}
protected boolean calculateEnabled() {
EditPart editPart = viewer.getFocusEditPart();// 得到当前选中的EditPart
if (editPart instanceof ReserveShape1EditPart) {
Command command = getCommand();
return command != null && command.canExecute();
}
return false;
}
@SuppressWarnings("rawtypes")
protected Command getCommand(Request request) {
List operationSet = getOperationSet();
if (operationSet.isEmpty()) {
return UnexecutableCommand.INSTANCE;
}
Iterator editParts = operationSet.iterator();
CompositeTransactionalCommand command = new CompositeTransactionalCommand(
getEditingDomain(), getCommandLabel());
while (editParts.hasNext()) {
EditPart editPart = (EditPart) editParts.next();
Command curCommand = editPart.getCommand(request);
if (curCommand != null) {
command.compose(new CommandProxy(curCommand));
}
}
if (command.isEmpty() || command.size() != operationSet.size()) {
return UnexecutableCommand.INSTANCE;
}
return new ICommandProxy(command);
}
protected TransactionalEditingDomain getEditingDomain() {
// try adapting the workbench part
IWorkbenchPart part = getWorkbenchPart();
if (part != null) {
IEditingDomainProvider edProvider = (IEditingDomainProvider) part
.getAdapter(IEditingDomainProvider.class);
if (edProvider != null) {
EditingDomain domain = edProvider.getEditingDomain();
if (domain instanceof TransactionalEditingDomain) {
return (TransactionalEditingDomain) domain;
}
}
}
return null;
}
}
4、将上一步新建的Action添加到右击菜单。在DiagramEditorContextMenuProvider类中修改buildContextMenu()方法。
首先,为这个类添加成员变量:
/**
* @generated NOT
*/
private SetImageAction setImageAction;
然后,修改DiagramEditorContextMenuProvider()方法,在这个方法最后添加如下代码:
setImageAction = new SetImageAction(part, viewer);
setImageAction.init();
在dispose()方法的super.dispose();语句之前添加代码:
if (setImageAction != null) {
setImageAction.dispose();
setImageAction = null;
}
最后,修改buildContextMenu()方法如下:
/**
* @generated NOT
*/
//这里用来定义右击菜单
public void buildContextMenu(final IMenuManager menu) {
getViewer().flush();
try {
TransactionUtil.getEditingDomain(
(EObject) getViewer().getContents().getModel()).runExclusive(new Runnable() {
public void run() {
menu.removeAll();
menu.add(setImageAction);
menu.add(deleteAction);
}
});
} catch (Exception e) {
org.eclipse.myTest.shapes.diagram.part.ShapesDiagramEditorPlugin
.getInstance().logError("Error building context menu", e);
}
}
这个时候如果运行程序,在一个ReserveShape1EditPart的结点上右击,菜单项会显示“设置显示图片...”这一项。
5、在包org.eclipse.myTest.shapes.diagram.edit.actions下新建类FileOption,用于后面拷贝图片到指定目录:
package org.eclipse.myTest.shapes.diagram.edit.actions;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOption {
// 复制文件
public static void copyFile(String sourceFilePath, String targetFilePath)
throws IOException {
File sourceFile = new File(sourceFilePath);
File targetFile = new File(targetFilePath);
FileInputStream input = new FileInputStream(sourceFile);
BufferedInputStream inBuff = new BufferedInputStream(input);
FileOutputStream output = new FileOutputStream(targetFile);
BufferedOutputStream outBuff = new BufferedOutputStream(output);
byte[] b = new byte[1024 * 5];
int len;
while ((len = inBuff.read(b)) != -1) {
outBuff.write(b, 0, len);
}
outBuff.flush();
inBuff.close();
outBuff.close();
output.close();
input.close();
}
}
6、在包org.eclipse.myTest.shapes.diagram.edit.actions下新建类GetPath,用于获得当前工程目录:
package org.eclipse.myTest.shapes.diagram.edit.actions;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;
public class GetPath {
public static String getPathFromClass(Class cls) throws IOException {
String path = null;
if (cls == null) {
throw new NullPointerException();
}
URL url = getClassLocationURL(cls);
if (url != null) {
path = url.getPath();
if ("jar".equalsIgnoreCase(url.getProtocol())) {
try {
path = new URL(path).getPath();
} catch (MalformedURLException e) {
}
int location = path.indexOf("!/");
if (location != -1) {
path = path.substring(0, location);
}
}
File file = new File(path);
path = file.getCanonicalPath();
}
return path;
}
private static URL getClassLocationURL(final Class cls) {
if (cls == null)
throw new IllegalArgumentException("null input: cls");
URL result = null;
final String clsAsResource = cls.getName().replace('.', '/')
.concat(".class");
final ProtectionDomain pd = cls.getProtectionDomain();
if (pd != null) {
final CodeSource cs = pd.getCodeSource();
if (cs != null)
result = cs.getLocation();
if (result != null) {
if ("file".equals(result.getProtocol())) {
try {
if (result.toExternalForm().endsWith(".jar")
|| result.toExternalForm().endsWith(".zip"))
result = new URL("jar:"
.concat(result.toExternalForm())
.concat("!/").concat(clsAsResource));
else if (new File(result.getFile()).isDirectory())
result = new URL(result, clsAsResource);
} catch (MalformedURLException ignore) {
}
}
}
}
if (result == null) {
final ClassLoader clsLoader = cls.getClassLoader();
result = clsLoader != null ? clsLoader.getResource(clsAsResource)
: ClassLoader.getSystemResource(clsAsResource);
}
return result;
}
}
7、在org.eclipse.myTest.shapes.diagram.edit.commands下新建一个SetImageCommand,其内容如下:
package org.eclipse.myTest.shapes.diagram.edit.commands;
import java.io.IOException;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.myTest.shapes.diagram.edit.actions.FileOption;
import org.eclipse.myTest.shapes.diagram.edit.actions.GetPath;
import org.eclipse.myTest.shapes.diagram.edit.parts.ReserveShape1EditPart;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.ui.PlatformUI;
public class SetImageCommand extends Command {
private EditPart sourceEditPart = null;
public SetImageCommand(EditPart sourceEditPart) {
this.sourceEditPart = sourceEditPart;
}
public void execute() {
FileDialog fileDlg = new FileDialog(PlatformUI.getWorkbench()
.getDisplay().getActiveShell());
String sourceFile = fileDlg.open();
String packageName = this.getClass().getResource("").getPath();
packageName = packageName.replace("/", "\\");
String projectPath = null;
try {
String packageFullName = GetPath.getPathFromClass(this.getClass());
projectPath = packageFullName.substring(0,
packageFullName.indexOf(packageName) + 1);
} catch (IOException e1) {
projectPath = null;
e1.printStackTrace();
}
if (projectPath == null)
return;
String targetFile = projectPath + "icons\\custom\\" + "test.jpg";
try {
FileOption.copyFile(sourceFile, targetFile);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (!sourceFile.isEmpty()) {
ReserveShape1EditPart contrl = (ReserveShape1EditPart) sourceEditPart;
contrl.setImageData("icons/custom/test.jpg");
contrl.getPrimaryShape().repaint();
}
}
}
8、在org.eclipse.myTest.shapes.diagram.edit.policies下新建SetImagePolicy:
package org.eclipse.myTest.shapes.diagram.edit.policies;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.PropertyHandlerEditPolicy;
import org.eclipse.myTest.shapes.diagram.edit.commands.SetImageCommand;
public class SetImagePolicy extends PropertyHandlerEditPolicy {
public Command getCommand(Request request) {
Command cmd = null;
if ("property_change".equals(request.getType())) {
cmd = new SetImageCommand(getHost());
return cmd;
}
return null;
}
}
9、将这一Policy安装到ReserveShape1EditPart。在ReserveShape1EditPart类的createDefaultEditPolicies()方法中添加代码:
installEditPolicy(EditPolicyRoles.PROPERTY_HANDLER_ROLE, new SetImagePolicy());
10、运行一下试试:
不过现在所做的更改还不能保存,关闭程序后再运行,图片还是原来的。大概下一篇文章会写点关于保存的吧。
本例源代码:http://www.oschina.net/code/snippet_164134_6144
来源:oschina
链接:https://my.oschina.net/u/164134/blog/31982