GEF:使用Draw2D画流程图

  在GEF(Graphical Editing Framework)介绍中已经对Draw2D进行了一些概要介绍,本篇从一个流程图的编写来学习Draw2D的是GEF的基础。

练习要求

做一个图下图所示流程图,流程图中的各个图例可以移动,每个不同类型的图例也不一样。 源码下载:flowchart-Draw2D.zip

基础概念

 

 

图例Figure

这里支持三种图例,图例从ActivityFigure继承下来。主要就是画图还有定义连接点FixedAnchor,下面先看看代码,代码都比较简单

  • 开始、结束图例
    public class TerminatorFigure extends ActivityFigure {
    	FixedAnchor inAnchor, outAnchor;
    
    	public TerminatorFigure() {
    		inAnchor = new FixedAnchor(this);
    		inAnchor.place = new Point(1, 0);
    		targetAnchors.put("in_term", inAnchor);
    		outAnchor = new FixedAnchor(this);
    		outAnchor.place = new Point(1, 2);
    		sourceAnchors.put("out_term", outAnchor);
    	}
    
    	public void paintFigure(Graphics g) {
    		Rectangle r = bounds;
    		g.drawArc(r.x + r.width / 8, r.y, r.width / 4, r.height - 1, 90, 180);
    		g.drawLine(r.x + r.width / 4, r.y, r.x + 3 * r.width / 4, r.y);
    		g.drawLine(r.x + r.width / 4, r.y + r.height - 1,
    				r.x + 3 * r.width / 4, r.y + r.height - 1);
    		g.drawArc(r.x + 5 * r.width / 8, r.y, r.width / 4, r.height - 1, 270,
    				180);
    		g.drawText(message, r.x + 3 * r.width / 8, r.y + r.height / 8);
    	}
    }
    
  • 分支图例
    public class DecisionFigure extends ActivityFigure {
    	FixedAnchor inAnchor, yesAnchor, noAnchor;
    
    	public DecisionFigure() {
    		inAnchor = new FixedAnchor(this);
    		inAnchor.place = new Point(1, 0);
    		targetAnchors.put("in_dec", inAnchor);
    		noAnchor = new FixedAnchor(this);
    		noAnchor.place = new Point(2, 1);
    		sourceAnchors.put("no", noAnchor);
    		yesAnchor = new FixedAnchor(this);
    		yesAnchor.place = new Point(1, 2);
    		sourceAnchors.put("yes", yesAnchor);
    	}
    
    	public void paintFigure(Graphics g) {
    		Rectangle r = bounds;
    		PointList pl = new PointList(4);
    		pl.addPoint(r.x + r.width / 2, r.y);
    		pl.addPoint(r.x, r.y + r.height / 2);
    		pl.addPoint(r.x + r.width / 2, r.y + r.height - 1);
    		pl.addPoint(r.x + r.width, r.y + r.height / 2);
    		g.drawPolygon(pl);
    		g.drawText(message, r.x + r.width / 4 + 5, r.y + 3 * r.height / 8);
    		g.drawText("N", r.x + 7 * r.width / 8, r.y + 3 * r.height / 8);
    		g.drawText("Y", r.x + r.width / 2 - 2, r.y + 3 * r.height / 4);
    	}
    }
    
  • 流程图例
    public class ProcessFigure extends ActivityFigure {
    	FixedAnchor inAnchor, outAnchor;
    
    	public ProcessFigure() {
    		inAnchor = new FixedAnchor(this);
    		inAnchor.place = new Point(1, 0);
    		targetAnchors.put("in_proc", inAnchor);
    		outAnchor = new FixedAnchor(this);
    		outAnchor.place = new Point(1, 2);
    		sourceAnchors.put("out_proc", outAnchor);
    	}
    
    	public void paintFigure(Graphics g) {
    		Rectangle r = bounds;
    		g.drawText(message, r.x + r.width / 4, r.y + r.height / 4);
    		g.drawRectangle(r.x, r.y, r.width - 1, r.height - 1);
    	}
    }
    
  • FixedAnchor:连接画线时会根据place来调用getLocation确定连接终点的位置
    public class FixedAnchor extends AbstractConnectionAnchor
    {
      Point place;
      public FixedAnchor(IFigure owner)
      {
        super(owner);
      }
      
      public Point getLocation(Point loc)
      {
        Rectangle r = getOwner().getBounds();
        int x = r.x + place.x * r.width/2;
        int y = r.y + place.y * r.height/2;
        Point p = new PrecisionPoint(x,y);
        getOwner().translateToAbsolute(p);
        return p;
      }
    }
    
  • ActivityFigure:主要处理连接点的代码
    abstract public class ActivityFigure extends Figure {
    	Rectangle r = new Rectangle();
    	Hashtable targetAnchors = new Hashtable();
    	Hashtable sourceAnchors = new Hashtable();
    	String message = new String();
    
    	public void setName(String msg) {
    		message = msg;
    		repaint();
    	}
    
    	public ConnectionAnchor ConnectionAnchorAt(Point p) {
    		ConnectionAnchor closest = null;
    		long min = Long.MAX_VALUE;
    		Hashtable conn = getSourceConnectionAnchors();
    		conn.putAll(getTargetConnectionAnchors());
    		Enumeration e = conn.elements();
    		while (e.hasMoreElements()) {
    			ConnectionAnchor c = (ConnectionAnchor) e.nextElement();
    			Point p2 = c.getLocation(null);
    			long d = p.getDistance2(p2);
    			if (d < min) {
    				min = d;
    				closest = c;
    			}
    		}
    		return closest;
    	}
    
    	public ConnectionAnchor getSourceConnectionAnchor(String name) {
    		return (ConnectionAnchor) sourceAnchors.get(name);
    	}
    
    	public ConnectionAnchor getTargetConnectionAnchor(String name) {
    		return (ConnectionAnchor) targetAnchors.get(name);
    	}
    
    	public String getSourceAnchorName(ConnectionAnchor c) {
    		Enumeration<String> keys = sourceAnchors.keys();
    		String name;
    		while (keys.hasMoreElements()) {
    			name = (String) keys.nextElement();
    			if (sourceAnchors.get(name).equals(c))
    				return name;
    		}
    		return null;
    	}
    
    	public String getTargetAnchorName(ConnectionAnchor c) {
    		Enumeration<String> keys = targetAnchors.keys();
    		String name = null;
    		while (keys.hasMoreElements()) {
    			name = (String) keys.nextElement();
    			if (targetAnchors.get(name).equals(c))
    				return name;
    		}
    		return null;
    	}
    
    	public ConnectionAnchor getSourceConnectionAnchorAt(Point p) {
    		ConnectionAnchor closest = null;
    		long min = Long.MAX_VALUE;
    		Enumeration e = getSourceConnectionAnchors().elements();
    		while (e.hasMoreElements()) {
    			ConnectionAnchor c = (ConnectionAnchor) e.nextElement();
    			Point p2 = c.getLocation(null);
    			long d = p.getDistance2(p2);
    			if (d < min) {
    				min = d;
    				closest = c;
    			}
    		}
    		return closest;
    	}
    
    	public Hashtable getSourceConnectionAnchors() {
    		return sourceAnchors;
    	}
    
    	public ConnectionAnchor getTargetConnectionAnchorAt(Point p) {
    		ConnectionAnchor closest = null;
    		long min = Long.MAX_VALUE;
    		Enumeration e = getTargetConnectionAnchors().elements();
    		while (e.hasMoreElements()) {
    			ConnectionAnchor c = (ConnectionAnchor) e.nextElement();
    			Point p2 = c.getLocation(null);
    			long d = p.getDistance2(p2);
    			if (d < min) {
    				min = d;
    				closest = c;
    			}
    		}
    		return closest;
    	}
    
    	public Hashtable getTargetConnectionAnchors() {
    		return targetAnchors;
    	}
    }
    

连接点PathFigure

连接点从PolylineConnection继承下来,在构造函数中设置目标对象连接点的装饰类,也就是示例中的三角形(PolylineDecoration),以及设定连接线路由样式,这里设置为ManhattanConnectionRouter

 

public class PathFigure extends PolylineConnection {
	public PathFigure() {
		//setSourceDecoration(new PolygonDecoration());
		setTargetDecoration(new PolylineDecoration());
		//setConnectionRouter(new BendpointConnectionRouter());
		setConnectionRouter(new ManhattanConnectionRouter());
				
	}
}

监听移动事件

 

public class Dnd extends MouseMotionListener.Stub implements MouseListener {
	public Dnd(IFigure figure) {
		figure.addMouseMotionListener(this);
		figure.addMouseListener(this);
	}

	Point start;

	public void mouseReleased(MouseEvent e) {
	}

	public void mouseClicked(MouseEvent e) {
	}

	public void mouseDoubleClicked(MouseEvent e) {
	}

	public void mousePressed(MouseEvent e) {
		start = e.getLocation();
	}

	public void mouseDragged(MouseEvent e) {
		Point p = e.getLocation();
		Dimension d = p.getDifference(start);
		start = p;
		Figure f = ((Figure) e.getSource());
		f.setBounds(f.getBounds().getTranslated(d.width, d.height));
	}
}

 

Flowchart

Flowchart是主程序代码,生成最上图所示的所有图例、连接,并把连接于连接点关联起来,并加入监听移动事件对象

 

public class Flowchart {
	public static void main(String args[]) {
		Shell shell = new Shell();
		shell.setSize(300, 400);
		shell.open();
		shell.setText("Flowchart");
		LightweightSystem lws = new LightweightSystem(shell);
		ChartFigure flowchart = new ChartFigure();
		lws.setEventDispatcher(new SWTEventDispatcherX(1800000L));		
		lws.setContents(flowchart);
		TerminatorFigure start = new TerminatorFigure();
		start.setName("Start");
		start.setToolTip(new Label("起点"));
		start.setBounds(new Rectangle(40, 20, 80, 20));
		DecisionFigure dec = new DecisionFigure();
		dec.setName("Should I?");
		dec.setBounds(new Rectangle(30, 60, 100, 60));
		ProcessFigure proc = new ProcessFigure();
		proc.setName("Do it!");
		proc.setToolTip(new Button("do it"));		
		proc.setBounds(new Rectangle(40, 140, 80, 40));
		TerminatorFigure stop = new TerminatorFigure();
		stop.setName("End");
		stop.setBounds(new Rectangle(140, 300, 80, 20));
		PathFigure path1 = new PathFigure();
		path1.setSourceAnchor(start.outAnchor);
		path1.setTargetAnchor(dec.inAnchor);
		PathFigure path2 = new PathFigure();
		path2.setSourceAnchor(dec.yesAnchor);
		path2.setTargetAnchor(proc.inAnchor);
		PathFigure path3 = new PathFigure();
		path3.setSourceAnchor(dec.noAnchor);
		path3.setTargetAnchor(stop.inAnchor);
		PathFigure path4 = new PathFigure();
		path4.setSourceAnchor(proc.outAnchor);
		path4.setTargetAnchor(stop.inAnchor);
		flowchart.add(start);
		flowchart.add(dec);
		flowchart.add(proc);
		flowchart.add(stop);
		flowchart.add(path1);
		flowchart.add(path2);
		flowchart.add(path3);
		flowchart.add(path4);
		new Dnd(start);
		new Dnd(proc);
		new Dnd(dec);
		new Dnd(stop);
		Display display = Display.getDefault();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
	}
}

 

参考:Draw2D教程

 

 

推荐:你可能需要的在线电子书

 

欢迎转载,转载请注明:转载自周金根 [ http://zhoujg.cnblogs.com/ ]



posted on 2010-11-23 16:02  周 金根  阅读(7521)  评论(0编辑  收藏  举报

导航