GEF的图形渐变方法

http://www.4ucode.com/Study/Topic/1967675(引用)

在GEF的Flow例子里,已经提供了另一种实现动态变化的方式,这个实现方法主要由以下三部分组成:

 

 

  1. 需要有一个辅助类,用于记录初始和终态,并计算渐近过程
  2. 需要自定义一个布局类,借助上面的辅助类来给出当前布局
  3. 需要窗口类控制器需要监听状态变化,以决定什么时候开始激活动态过程
  4. 每个可能属于变化集的对象都需要提供一个方法,用于把自己加入到这个变化集中。
下面一部分一部分的介绍。
 
首先第一个部分,就是辅助类的实现,不过我也没写过自己的实现方式,暂且先以flow中的类作例子,见附件GraphAnimation.zip.
 
第二部分也是一个类实现,简单如下:
 
class GraphLayoutManager extends AbstractLayout {

private NumaDiagramNodePart diagram;

GraphLayoutManager(NumaDiagramNodePart diagram) {
	this.diagram = diagram;
}

protected Dimension calculatePreferredSize(IFigure container, int wHint, int hHint) {
	container.validate();
	List children = container.getChildren();
	Rectangle result =
		new Rectangle().setLocation(container.getClientArea().getLocation());
	for (int i = 0; i < children.size(); i++)
		result.union(((IFigure)children.get(i)).getBounds());
	result.resize(container.getInsets().getWidth(), container.getInsets().getHeight());
	return result.getSize();
}

public void layout(IFigure container) {
	GraphAnimation.recordInitialState(container);
	if (GraphAnimation.playbackState(container))
		return;

	CompoundDirectedGraph graph = new CompoundDirectedGraph();
	graph.setDirection(PositionConstants.EAST);
	Map partsToNodes = new HashMap();
	diagram.contributeNodesToGraph(graph, partsToNodes);
	diagram.contributeEdgesToGraph(graph, partsToNodes);
	new CompoundDirectedGraphLayout().visit(graph);
	diagram.applyGraphResults(graph, partsToNodes);
}

}
 这里借助了两个对象来实现过程:CompoundDirectedGraph和CompoundDirectedGraphLayout。
 
第三,监听状态变化,这部分主要就是通过在容器类中增加Command变化监听来实现,例如:
 
	CommandStackListener stackListener = new CommandStackListener() {
		public void commandStackChanged(EventObject event) {
			if (!GraphAnimation.captureLayout(getFigure()))
				return;
			while (GraphAnimation.step())
				getFigure().getUpdateManager().performUpdate();
			GraphAnimation.end();
		}
	};

	public void activate() {
		super.activate();
		getViewer().getEditDomain().getCommandStack().addCommandStackListener(
				stackListener);
	}

	public void deactivate() {
		getViewer().getEditDomain().getCommandStack()
				.removeCommandStackListener(stackListener);
		super.deactivate();
	}
最后一部分,也就是参与的过程,虽然上面我们已经定义好了整个辅助过程,但是具体在这一过程中有哪些对象会参与,怎么参与,需要我们自己实现,例如A是容器对象,里面有B和C对象,且B和C之间有一条连线,那么一般来说,一旦有变化,那么B,C和他们连线都需要处理。
 
对于一个结点对象,处理过程通常如:
 
	public void applyGraphResults(CompoundDirectedGraph graph, Map map) {
		for (int i = 0; i < getChildren().size(); i++) {
			NumaNodePart node = (NumaNodePart) getChildren().get(i);
			Dimension dimension = node.getFigure().getPreferredSize(-1, -1);
			Node n = (Node) map.get(node);
			node.getFigure().setBounds(
					new Rectangle(n.x, n.y, n.width, dimension.height));
			applyEdgesResults(node, graph, map);
		}
	}

	public void contributeNodesToGraph(CompoundDirectedGraph graph, Map map) {
		GraphAnimation.recordInitialState(getContentPane());
		for (int i = 0; i < getChildren().size(); i++) {
			NumaNodePart node = (NumaNodePart) getChildren().get(i);
			Node n = new Node(node);
			n.width = node.getFigure().getPreferredSize().width;
			n.height = node.getFigure().getPreferredSize().height;
			n.setPadding(new Insets(10, 8, 30, 12));
			map.put(node, n);
			graph.nodes.add(n);
		}
	}

	public void contributeEdgesToGraph(CompoundDirectedGraph graph, Map map) {
		for (int i = 0; i < getChildren().size(); i++) {
			NumaNodePart node = (NumaNodePart) children.get(i);
			List outgoing = node.getSourceConnections();
			for (int j = 0; j < outgoing.size(); j++) {
				NodeRelationPart conn = (NodeRelationPart) outgoing.get(j);
				conn.contributeToGraph(graph, map);
			}
		}
	}

	public void applyEdgesResults(NumaNodePart node,
			CompoundDirectedGraph graph, Map map) {
		List outgoing = node.getSourceConnections();
		for (int j = 0; j < outgoing.size(); j++) {
			NodeRelationPart conn = (NodeRelationPart) outgoing.get(j);
			conn.applyGraphResults(graph, map);
		}
	}
对于连线,因为要处理他们的Bend点,通常如下:
	protected void applyGraphResults(CompoundDirectedGraph graph, Map map) {
		Edge e = (Edge)map.get(this);
		NodeList nodes = e.vNodes;
		PolylineConnection conn = (PolylineConnection)getConnectionFigure();
//		conn.setTargetDecoration(new PolygonDecoration());
		if (nodes != null) {
			List bends = new ArrayList();
			for (int i = 0; i < nodes.size(); i++) {
				Node vn = nodes.getNode(i);
				int x = vn.x;
				int y = vn.y;
				if (e.isFeedback()) {
					bends.add(new AbsoluteBendpoint(x, y + vn.height));
					bends.add(new AbsoluteBendpoint(x, y));
				} else {
					bends.add(new AbsoluteBendpoint(x, y));
					bends.add(new AbsoluteBendpoint(x, y + vn.height));
				}
			}
			conn.setRoutingConstraint(bends);
		} else {
			conn.setRoutingConstraint(Collections.EMPTY_LIST);
		}
	}

	public void contributeToGraph(CompoundDirectedGraph graph, Map map) {
		GraphAnimation.recordInitialState(getConnectionFigure());
		Node source = (Node)map.get(getSource());
		Node target = (Node)map.get(getTarget());
		Edge e = new Edge(this, source, target);
		e.weight = 2;
		graph.edges.add(e);
		map.put(this, e);
	}
 并且,在他们重连的时候需要处理:
 
			figure.setConnectionRouter(new BendpointConnectionRouter(){
				public void route(Connection conn) {
					GraphAnimation.recordInitialState(conn);
					if (!GraphAnimation.playbackState(conn))
						super.route(conn);
				}
			})
posted @ 2011-11-20 20:27  fbiswt  阅读(382)  评论(0编辑  收藏  举报