`
liugang594
  • 浏览: 990763 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

GEF的动态变化二

    博客分类:
  • GEF
阅读更多

之前有一篇文件介绍怎么实现GEF Editor中的图元的渐近、动态变化过程的显示技巧。

 

在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);
				}
			});
 
分享到:
评论

相关推荐

    Eclipse的GEF学习

    #### 二、GEF的关键组件解析 1. **模型(Model)**:模型是应用的核心数据结构,负责存储和管理数据。在GEF中,模型需具备变化通知机制,以便于及时更新控制器和视图。通常,模型的设计应紧密贴合业务逻辑,以确保...

    GEF_Demo_Code20170307

    2. **在ViewPart中使用GEF**:通常情况下,GEF主要用于创建图形编辑器(Editor),但本示例特别指出在非Editor的ViewPart中使用GEF。ViewPart是Eclipse RCP(Rich Client Platform)中的一个组件,用于显示各种视图...

    GEF-Update-3.7.1.zip

    2. **artifacts.jar**:此文件通常包含了软件的元数据,例如依赖关系、版本信息等。在Eclipse插件开发中,它可能用于帮助Eclipse的插件管理系统理解GEF的依赖结构,以便正确地安装和运行插件。 3. **site.xml**:这...

    GEF 入门教程 中文版

    - GEF支持动态缩放,使得用户可以在不同的缩放级别下查看图形。 - 缩放可以通过菜单项或者键盘快捷键来触发。 **知识点2:键盘快捷键** - 键盘快捷键是提高用户效率的重要手段。 - GEF允许自定义键盘快捷键来执行...

    GEF锚点鼠标定位

    - **刷新视图**:更新锚点位置后,需要通知GEF视图进行重绘,以反映变化。 5. **代码示例**: 在Java中,你可以创建一个类,如`MouseTrackingAnchor`,并在其中实现`mouseMoved`方法,根据鼠标位置更新锚点的位置...

    java gef开发实例

    2. **GEF组件**: - **Figure**:表示图形元素,如线条、矩形等,是视图的基本组成单元。 - **Part**:封装了Figure,代表图形编辑中的一个可操作对象。 - **GraphicalViewer**:作为图形查看器,管理多个Part的...

    GEF_Tutorial.rar(GEF开发指南)

    **2. 创建GEF项目** 在Eclipse IDE中,你可以通过新建一个GEF项目来开始你的图形编辑器开发。这通常涉及到设置项目属性,导入必要的库,以及配置项目的构建路径。 **3. 设计模型** 在GEF中,你需要首先定义你的数据...

    GEF基础知识

    #### 二、GEF与Draw2D的关系 虽然GEF本身并不强制使用特定的图形库作为其视图层,但在实际开发中,Draw2D几乎成了GEF的标准视图层选择。这是因为GEF的很多核心概念与API设计都是与Draw2D紧密相关的,尤其是它的`...

    GEF中文教程+代码

    **2. GEF架构** GEF的核心组件包括: - **Model**:图形编辑器的数据模型,存储了图形对象的信息。 - **EditParts**:表示模型的可视化组件,它们负责将模型数据转换为屏幕上的图形。 - **Figure**:基本的绘图单元...

    GEF Description

    #### 二、GEF 解决的问题 ##### 2.1 图形编辑器的一般问题 在开发图形编辑器时,通常面临以下问题: - **模型与视图的关联**:需要建立数据模型与用户界面之间的联系,使得用户对界面的操作可以直接反映到数据...

    GEF学习资料.zip

    **二、GEF的核心概念** 1. **模型(Model)**:在GEF中,模型是数据结构的抽象,它定义了编辑器所操作的对象和它们之间的关系。模型独立于视图和控制器,是应用程序的核心部分。 2. **视图(View)**:视图是模型...

    gef入门学习项目源码

    2. **指挥者(Command)与手势(Gesture)**:GEF中的命令模式允许撤销/重做操作。手势则定义了用户如何与图形界面进行交互,如点击、拖拽等。 3. **适配器(Adapter)与扩展点(Extension Point)**:适配器用于...

    基于gef框架Demo

    View是数据的可视化表示,根据Model的变化实时更新。Controller则是Model和View之间的桥梁,处理用户交互,确保Model和View的一致性。 Gef提供了以下主要组件和特性: 1. **图形模型**:允许开发者定义图形元素的...

    GEF原理的详细介绍+程序实例和程序源码

    2. **视图(View)**:视图是模型在屏幕上的表示,由GEF的图形组件(如Figure和Part)组成,用于显示模型数据。 3. **控制器(Controller)**:处理用户输入,如鼠标点击和键盘事件,协调模型和视图的更新。 4. **...

    GEF-ALL-3.4.2(1).zip

    3. **EditPart**:编辑部分是视图和模型之间的桥梁,将模型的变化反映到视图上,同时处理用户的输入事件。每个图形元素都有一个对应的EditPart。 4. **Command**:命令模式用于封装对模型的修改操作,确保操作的可...

    GEF连接线Node之间连接

    2. **创建节点**:在`GEF`中,节点通常是`Part`的子类,如`Figure`或`Shape`,它们定义了在画布上显示的图形形状。通过自定义这些类,可以实现各种复杂形状的节点。 3. **连接线(Edge)**:连接线是`Connection`的...

    gef的入门例子(13个)

    而gef是GDB的一个插件,它扩展了GDB的功能,比如提供彩色输出、命令自动补全、增强的内存查看、快速堆栈回溯、反汇编美化、动态加载模块等。gef的目的是使调试体验更加现代化,更符合现代开发者的工作流程。 现在...

    GEF.rarGEF.rar

    2. **MVC模式**:在GEF中,模型负责存储数据,视图负责显示模型的内容,控制器处理用户的输入并更新模型。这种分离使代码更易于维护和扩展。 3. **图元(Figure)和图元工厂(FigureFactory)**:GEF中的图元是图形...

    GEF Programmer's Guide 中文版

    2. **何时使用GEF**: GEF适用于Eclipse Rich Client Platform (RCP)的应用,如编辑器、视图和向导。它特别适合在EditorPart中构建图形编辑器,也可以在大纲视图中使用。GEF需要Eclipse RCP和org.eclipse.ui.views...

Global site tag (gtag.js) - Google Analytics