天天看點

eclipse GMF 制作簡單工作流流程設計器(3)1.自定義節點圖示2.自定義形狀

本節教程在第二節的基礎上繼續完善工作流流程設計器,本節的主要内容有:

  1. 自定義節點圖示
  2. 自定義形狀

1.自定義節點圖示

通過GMF向導生成的節點都是矩形,為了使圖形更加美觀、更好的使用者UI,我們需要自定義圖形節點。下面以開始和結束活的為例,介紹如何使用自定義圖示。

  1. 我們繼續在第二節基礎上,打開com.mjt.flow.diagram項目,在icons建立檔案夾custom,将之前準備好的的圖示放入該目錄,這裡使用的是start.png和end.png,圖檔大小32*32。
  2. 由于需要使用自定義圖示,是以需要在flow.gmfgraph檔案進行圖形設定,需要将形狀設定成自定義形狀。

a) 選擇Canvas Gallery Default->Figure Descriptor StartActivityFigure,将子節點Retangle StartActivityFigure删除,右鍵點選Figure Descriptor StartActivityFigure,New Child->Custom Figure, 輸入名稱StartActivityFigure, 在Qualified Class Name填寫自定義的類名,這個類一般繼承org.eclipse.draw2d.Figure,在這裡填寫類 名:com.mjt.flow.diagram.figure.StartActivityFigure,按照同樣方法,在 EndActivityFigure建立Custom Figure;建立完畢後如下圖:

eclipse GMF 制作簡單工作流流程設計器(3)1.自定義節點圖示2.自定義形狀

b)開始和結束活動使用圖檔大小固定,在這裡我們把它改成不可變大小,設定Node StartActivity和Node EndActivity的Resize Constraint為NONE,如下圖:

eclipse GMF 制作簡單工作流流程設計器(3)1.自定義節點圖示2.自定義形狀

c)在圖形檔案flow.gmfgraph定義了自定義類,現在需要建立這個兩個類,首先建立開始活動Figure類,該類繼承org.eclipse.draw2d.Figure這個類,如下:

eclipse GMF 制作簡單工作流流程設計器(3)1.自定義節點圖示2.自定義形狀

d)類向導建立com.mjt.flow.diagram.figure.StartActivityFigure這個類後,這個類是個空白的類,什麼都沒有,現在我們覆寫基類的paintFigure(Graphics graphics)方法,輸入以下代碼:

package com.mjt.flow.diagram.figure;

import org.eclipse.draw2d.Figure;

import org.eclipse.draw2d.Graphics;

import org.eclipse.jface.resource.ImageDescriptor;

import org.eclipse.swt.graphics.Image;

import com.mjt.flow.diagram.part.FlowDiagramEditorPlugin;

public class StartActivityFigure extends Figure {

    @Override

    protected void paintFigure(Graphics graphics) {

        setFigureImage(graphics, "icons/custom/start.png",32,3); //$NON-NLS-1$

    }

    protected void setFigureImage(Graphics graphics, String imagePath, int width, int height){

        super.paintFigure(graphics);

        ImageDescriptor descriptor = FlowDiagramEditorPlugin.findImageDescriptor(imagePath);

        Image image = descriptor.createImage();//建立圖形

        graphics.drawImage(image, getLocation());//繪制圖示

        setPreferredSize(width, height); //設定首選(預設)大小

    }

}

按 照同樣的方法,建立EndActivityFigure。兩個類代碼重複,可以将活動的Figure建立一個抽象類,如上述的 setFigureImage方法可以放到這個抽象類中,提高代碼的重用性,在此處隻是一個示範,建立兩個相似的類,不進行優化了,有興趣的話可以檢視源 代碼。

e)同時還需要設設定NodeFigure的DefaultSize,打開 com.mjt.flow.diagram.edit.parts.StartActivityEditPart這個類,在 createNodePlate()方法中建立DefaultSizeNodeFigure類時,需要設定DefaultSize為26、26,同時不要 忘記設定EndtActivityEditPart類,如下:

    protected NodeFigure createNodePlate() {

        DefaultSizeNodeFigure result = new DefaultSizeNodeFigure(26,26);

        return result;

    }

Tip:@generated NOT标注可以當GMF重新生成代碼的時候不會被覆寫,不會重新生成。

f)gmfgrap檔案改動過了,需要重新生成flow.gmfgen檔案,删除flow.gmfgen檔案,右鍵點選 flow.gmfmap檔案,Create Generator Model...,點選Generate Diagram Code...,重新生成diagram code。

g)運作一下如下圖:

eclipse GMF 制作簡單工作流流程設計器(3)1.自定義節點圖示2.自定義形狀

h)細心的您是否發現,當在畫開始和結束活動時,如果拖動的比較大時,此時圖形有不能調整大小,怎麼辦呢?這時需要您添加另外的代碼控制圖形大小。

此 時需要覆寫com.mjt.flow.diagram.edit.parts.StartActivityEditPart中的 handleNotificationEvent(Notification notification)方法,在這裡進行控制圖形的大小,如下:

    @Override

    protected void handleNotificationEvent(Notification notification) {

        setToPreferredSize(notification, getFigure(),

                (View) getModel(), getEditingDomain(), getDiagramEditDomain());

        super.handleNotificationEvent(notification);

    }

    public static void setToPreferredSize(Notification notification, IFigure figure, View model,

            TransactionalEditingDomain editingDomain, IDiagramEditDomain diagramEditDomain){

        if(notification.getEventType()==Notification.SET

                && !figure.getSize().equals(figure.getPreferredSize())){

            SetBoundsCommand boundsCommand = new SetBoundsCommand(editingDomain,"", //$NON-NLS-1$

                    new EObjectAdapter(model),figure.getPreferredSize());

            diagramEditDomain.getDiagramCommandStack().execute(new ICommandProxy(boundsCommand));

        }

    }

i)再仔細看一下下面的圖形,有沒有發現,當連接配接線成斜線的時候,由于裡面的圖形是圓形而外框是矩形,預設情況下,連接配接線的錨點是矩形的。如下:

eclipse GMF 制作簡單工作流流程設計器(3)1.自定義節點圖示2.自定義形狀

如 何自定義錨點呢?這時候需要覆寫 com.supcon.workflow.xpdl.diagram.edit.parts.StartActivityEditPart#getSourceConnectionAnchor 和#getTargetConnectionAnchor方法,如下:

    @Override

    public ConnectionAnchor getSourceConnectionAnchor(

            ConnectionEditPart connEditPart) {

        return new EllipseAnchor(getFigure());

    }

    @Override

    public ConnectionAnchor getSourceConnectionAnchor(Request request) {

        return new EllipseAnchor(getFigure());

    }

    @Override

    public ConnectionAnchor getTargetConnectionAnchor(

            ConnectionEditPart connEditPart) {

        return new EllipseAnchor(getFigure());

    }

    @Override

    public ConnectionAnchor getTargetConnectionAnchor(Request request) {

        return new EllipseAnchor(getFigure());

    }

draw2d 為我們提供很多預設的Anchor,這裡使用的是橢圓的Anchor,實作的Anchor除了EllipseAnchor還有 DiamondConnectionAnchor、ChopboxAnchor、SlidableAnchor等,有興趣的話可以自己去研究一下,同時可 以自定義Anchor,隻要繼承抽象類org.eclipse.draw2d.AbstractConnectionAnchor來完成自定義的 ConnectionAnchor。

再看一下運作結果:

eclipse GMF 制作簡單工作流流程設計器(3)1.自定義節點圖示2.自定義形狀

2.自定義形狀

這一塊内容我們将以AutoActivity活動為例,對其進行自定義形狀,采用漸變填充。

a)首先按照自定義節點圖示的方法,在flow.gmfgraph建立Custom Figure, 由于原來有子節點GridLayout和Label, 删除後重新加上去,如下圖:

eclipse GMF 制作簡單工作流流程設計器(3)1.自定義節點圖示2.自定義形狀

b) 建立自定義形狀類com.mjt.flow.diagram.figure.AutoActivityFigure, 繼承org.eclipse.draw2d.Shape,由于Shape是抽象類,需要實作兩個方法fillShape(Graphics graphics)和outlineShape(Graphics graphics),前面主要用于圖形填充,後者用于形狀外邊框。

類代碼如下:

package com.mjt.flow.diagram.figure;

import org.eclipse.draw2d.ColorConstants;

import org.eclipse.draw2d.Graphics;

import org.eclipse.draw2d.Shape;

import org.eclipse.draw2d.geometry.Dimension;

import org.eclipse.draw2d.geometry.Rectangle;

import org.eclipse.swt.graphics.Color;

import org.eclipse.swt.graphics.Path;

import org.eclipse.swt.graphics.RGB;

public class AutoActivityFigure extends Shape {

    protected Dimension corner = new Dimension(20, 20);

    @Override

    protected void fillShape(Graphics graphics) {

        //通過路徑繪制圓角矩形

        Path path = new Path(null);

        path.addArc(getBounds().x, getBounds().y, corner.width, corner.height, 180, -90);

        path.addArc(getBounds().x+getBounds().width-corner.width, getBounds().y, corner.width, corner.height, 90,-90);

        path.addArc(getBounds().x+getBounds().width-corner.width, getBounds().y+getBounds().height-corner.height, corner.width, corner.height, 0,-90);

        path.addArc(getBounds().x, getBounds().y+getBounds().height-corner.height, corner.width, corner.height, 270,-90);

        graphics.setClip(path);

        //漸變填充

        graphics.setForegroundColor(ColorConstants.white);

        graphics.setBackgroundColor(new Color(null, new RGB(200,220,230)));

        graphics.fillGradient(getBounds(), true);

    }

    @Override

    protected void outlineShape(Graphics graphics) {

        float lineInset = Math.max(1.0f, getLineWidthFloat()) / 2.0f;

        int inset1 = (int) Math.floor(lineInset);

        int inset2 = (int) Math.ceil(lineInset);

        Rectangle r = Rectangle.SINGLETON.setBounds(getBounds());

        r.x += inset1;

        r.y += inset1;

        r.width -= inset1 + inset2;

        r.height -= inset1 + inset2;

        graphics.setForegroundColor(new Color(null, new RGB(40,100,120)));

        graphics.drawRoundRectangle(r, Math.max(0, corner.width

                - (int) lineInset), Math

                .max(0, corner.height - (int) lineInset));

    }

}

上面定義的圓角橢圓半徑為(20,20)。

c)重新生成flow.gmfgen檔案,并重新生成diagram代碼。

d)運作結果如下:

eclipse GMF 制作簡單工作流流程設計器(3)1.自定義節點圖示2.自定義形狀

源代碼請看附件

這一節講完了,下一節的内容是如何擴充流程的自定義字段。

由于平時比較忙,可能寫的比較簡單,有些地方沒有詳細說明,一筆帶過,如果有什麼不明白之處,歡迎通過郵件聯系。

本系列教程盡量會在最短的時間内寫出來。

繼續閱讀