序
在为老师写项目的时候我急需一个基于java的图形组件,第一次搜索就搜索到了jGraph。总体感觉还是挺容易上手的,是一套能够应对多种图形用途的工具。虽然我对其中一些编程的风格有些不是很满意。不过能做出来就是好的!而且效果十分出色,感谢jGraph社团带给我们的强大工具。
最令我欣赏的是,jGraph在对需要使用jGraph Layout Pro的学术应用只收半价,这表现了国外对于学术研究的重视,是中国需要学习的。
jGraph简介
jGraph具有相当高的交互性和自动化,是一套为图定做的组件。其主要用途是在一些需要表示图结构的应用中,比如流程图、UML、交通线路、网络等等。
jGraph在本文撰写时版本为5.8.0.0,可以在链接出找到jGraph的主页。
jGraph主要包括以下一些产品:
JGraph - The Java Open Source Graph Drawing Component ( 有Open Source )
JGraph Layout Pro - The Java Graph Layout Solution
JGraphpad Pro Diagram Editor Framework
MxGraph Thin Client - JGraph in a browser!
咱们只是学习嘛,当然只用jGraph咯。jGraph Layout Pro是一个对图进行布局的软件,看过DEMO后感觉好酷。jGraphed Pro 现在有WEB START的演示,似乎是拿来做jGraph的演示用,我在Solaris上也看到过jGraphed Pro的身影,是一套巨牛叉的图形编辑软件。 MxGraph Thin Client是利用Javascript 和 SVG 在XML通讯协议下的浏览器端的瘦客户软件,感觉也好厉害呀。
jGraph对图的操作包括:图显示、图交互、图布局、图分析等。
JGraph 的基本SWING 组件如下:
org.jgraph Basic JGraph 类
org.jgraph.event Graph 事件模型
org.jgraph.graph Graph 结构及结点
org.jgraph.plaf Graph UI 委托组件
org.jgraph.util 常用的工具类
补充一下,与jGraph类似的可用于绘图的还有eclipse的GEF。
jGraph模型
一张图——JGraph 类 的主要结构:
JGraph extends JComponent {
org.jgraph.graph.GraphModel model; (DefaultGraphModel)
org.jgraph.plaf.GraphUI ui; (BasicGraphUI)
org.jgraph.graph.GraphLayoutCache cache;
}
JGraph 除了SWING的MVC结构,即引用了MODEL和UI外,他还保持着一个奇怪的应用GraphLayoutCache。GraphLayoutCache 可以被看作是MODEL的一个扩展,它的作用是保证图中各结点的状态以及一些外观等。因为图的复杂性,使用一个GraphLayoutCache 可以用来处理这些复杂问题。
配置JGraph可以使用一系列的set方法,有许多很有用的功能可以开关。
图的逻辑结构——GraphModel 类:
满足MVC的要求,GraphModel保存着所有的图中的对象,它的默认实现DefaultGraphModel能够满足一般的需求。
GraphModel包含三个基本操作:insert() , edit() , remove() 。这些操作会起到与GraphLayoutCache相同的效果,但与GraphLayoutCache略微不同的是它的参数比较多,乍看下去比较麻烦。其实GraphModel所要求的只是结点的逻辑结构,对于结点的细节它并不关心。所以可以在初始化图时使用GraphModel,不要常常用它的方法来对细节做修改,这既不方便,也没必要。
另外,就是GraphModel提供了许多get方法,可以很方便检索相应的结点。
Cells
JGraph 的单位(Cells) 有三种:Vertex、 Edge、 Port。
Vertex 可以携带对象,由于JGraph是只负责表示的,并不真正负责数据的操作。那么在图形和数据间就需要一个使者,这就是Vertex ,Vertex 可以是文字、图形等对象。
Port 是一般比较陌生的单位,在图的算法中并不设计Port,但在图形表示中它十分有用。如同它的名字,他是Vertex上的一个端口,可以通过端口连接其他Vertex,而在JGraph中Port还可以用于改变Edge的形状等等。
Edge 与图算法中的边也有一点不同,Edge 是只能连接Port而不是Vertex的。这样,因为多了Port单元,使得Edge更加灵活、更加丰富了。
默认单元——DefaultCell:
它是DefaultEdge和DefaultPort的父类,又是DefaultMutableTreeNode的子类,其地位可以相当于Vertex。一个DefaultCell可以携带一个UserObject。每个DefaultCell还有一个AttributeMap,负责它的属性(颜色、大小等等)。用一套set方法可以修改AttributeMap。
边和端口单元——Edge、Port:
除了继承DefaultCell,Edge、Port还有一些独有的方法。
Edge有getSource() 和 getTarget() 方法,用以获得边的两端的对象(一般为Port)。还一个路由类,定义了一些路由方法。
Port 主要任务是承载Edge,所以有一些关于获得Edge的方法。另外,Port还定义了获得锚(比如一个Vertex中包含一个Port)的方法。
Cell的处理:
每个Cell包括Cell Object、Cell Renderer、Cell Editor、Cell Handle。其中Renderer负责Cell的表示,包括形状等等。Editor 做Cell的修改用,当双击Cell后则调用Editor来编辑Cell。以上都是类似与JTable 和 JTree的。
Handle 是SWING的组件中没有的,它的任务是处理Cell的大小与移动。可以重写paint()方法来指定经过鼠标拖动所导致的Cell大小和位置变化。
对于这些单元的属性的控制,可以仔细看看GraphConstants这个类的set方法,基本上所有的属性都是用这个类的set修改的。
小结
- 通过GraphConstants可以设置大部分的属性(我个人不喜欢这种方式)
- 一个Cell类型的实体,可以设置view、 renderer、 editor、 handler。
- 定制个性化的Cell ,需要继承DefaultCell 后增加新的属性和方法并实现他们,记得修改attributeMap,会有帮助的,以及引用UserObject。
- 还有一点,对于Cells只能调用插入、删除、修改方法,无法对view调用。