在上一篇文章中,咱們實現了爲結點設置圖片,可是咱們還不能修改結點的圖片,全部相同類型結點的圖片是同樣的。java
本例首先給結點添加右擊菜單,而後實現修改結點圖片的功能。dom
一、修改ReserveShape1EditPart.java的部分代碼,把descriptor、originalImage、OrgImageData聲明處的static都去掉,不然修改一個結點以後,同類型的其餘結點也會改變。eclipse
/** * @generated NOT */ private ImageDescriptor descriptor = ShapesDiagramEditorPlugin .findImageDescriptor("icons/custom/ReserveShapeFigure.jpg"); private Image originalImage = descriptor.createImage(); private ImageData OrgImageData = originalImage.getImageData();
二、在ReserveShape1EditPart類中添加方法以下:ide
/** * @generated NOT */ public void setImageData(String imagePath) { descriptor = ShapesDiagramEditorPlugin.findImageDescriptor(imagePath); originalImage = descriptor.createImage(); OrgImageData = originalImage.getImageData(); }
三、在工程org.eclipse.myTest.shapes.diagram下新建一個包org.eclipse.myTest.shapes.diagram.edit.actions,用於存放咱們本身的Action。在這個包中新建一個類SetImageAction,內容以下:ui
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; } }
四、將上一步新建的Action添加到右擊菜單。在DiagramEditorContextMenuProvider類中修改buildContextMenu()方法。this
首先,爲這個類添加成員變量:url
/** * @generated NOT */ private SetImageAction setImageAction;
而後,修改DiagramEditorContextMenuProvider()方法,在這個方法最後添加以下代碼:.net
setImageAction = new SetImageAction(part, viewer); setImageAction.init();
在dispose()方法的super.dispose();語句以前添加代碼:rest
if (setImageAction != null) { setImageAction.dispose(); setImageAction = null; }
最後,修改buildContextMenu()方法以下:code
/** * @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的結點上右擊,菜單項會顯示「設置顯示圖片...」這一項。
五、在包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(); } }
六、在包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; } }
七、在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(); } } }
八、在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; } }九、將這一Policy安裝到ReserveShape1EditPart。在ReserveShape1EditPart類的createDefaultEditPolicies()方法中添加代碼:
installEditPolicy(EditPolicyRoles.PROPERTY_HANDLER_ROLE, new SetImagePolicy());
十、運行一下試試:
不過如今所作的更改還不能保存,關閉程序後再運行,圖片仍是原來的。大概下一篇文章會寫點關於保存的吧。