http://www.jgraph.com/downloads/jgraph/
官网上显示的是新项目mxGraph,不是JGraph,可以通过上面的链接访问下载。
如何使用Graph
利用JGraph可以显示对象,以及对象之间的关联。一个JGraph对象并没有包含你的数据,它仅仅提供数据的视图。像其他Swing的组件一样,Graph从它的数据模型中获取数据。下面是一个Graph:
如上图所示,JGraph通过对每个元素进行绘图来显示数据。Graph显示的每个元素都包含一个自己的数据,称为一个Cell。Cell可以是一个顶点,一条边或者一个端口(定义图元之间的连接点)。顶点有一个或多个邻居,边有1个或者0个源端点和目的端点对。每个Cell有0个或多个孩子,并且有1个或者0个父亲(端口实例是顶点的孩子)。图元之间是通过树形结构组织在一起的。
指南的余下部分将讨论:
· 创建Graph
· 定制Graph
· 响应交互
· 定制Graph的显示
· 动态修改Graph
创建Graph
下图是一个在滚动面板(Scroll Pane)中使用Graph的实例。
下面的代码创建一个JGraph对象:
JGraph graph = new JGraph();
...
JScrollPane scrollPane = new JScrollPane(graph)
代码创建一个JGraph的实例,并且把它放到滚动面板(Scroll Pane)中。上面的代码中调用了JGraph的无参构造函数。JGraph将会使用一个DefaultGraphModel实例作为该Graph的模型,同时会创建一个GraphView。JGraph中相关构造函数源码如下:
public JGraph(GraphModel model, GraphLayoutCache layoutCache,
BasicMarqueeHandler mh) {
setDoubleBuffered(true);
selectionModel = new DefaultGraphSelectionModel(this);
setLayout(null);
marquee = mh;
if (model == null) {
model = new DefaultGraphModel();
setModel(model);
addSampleData(model);
} else
setModel(model);
if (layoutCache == null)
layoutCache = new GraphLayoutCache(model,
new DefaultCellViewFactory());
setGraphLayoutCache(layoutCache);
updateUI();
}
JGraph缺省实现下面的键盘绑定:
· Alt+点击,在Cell上强制拾取
· Sheft或Ctrl+点击,多选
· Shift+拖放,限制偏移方向
· Ctrl+拖放,复制
· 双击或F2,编辑
你可以通过JGraph的构造函数创建一个Graph。应该将Graph放在滚动面板(Scroll Pane)中,这样绘图超出边界也可以方便的查看。也不需要任何编码,JGraph已经为你提供了Cell编辑,选取,拾取,顶点和边的移动和大小变化。
定制Graph
JGraph提供如下形式的交互:
· 原地编辑
· 移动
· 复制
· 改变大小
· 绑定(添加、删除、移动)
· 建立连接
· 删除连接
所有的交互可以通过setEnabled(false)禁止。原地编辑对边和顶点都是可用 。默认双击将会触发编辑,点击的次数可以通过setEditClickCount进行设置。
移动、复制、改变大小、绑定、建立连接和删除连接可以在Graph实例上分别调用setMoveable, setCloneable,setSizeable,setBendable,setConnectable和setDisconnectable enable或disable。
模型通过acceptsSource和acceptsTarget函数,提供了创建连接和删除连接的良好控制。可以通过重载这两种方法,决定边的端口对,以及边的源和目的端口。
CellView提供了这些交互的另一个层面的控制,它也允许enable/disable编辑、移动、复制、改变大小、绑定、建立连接和删除连接。需要注意的是,模型可能拥有多个View,存在一个View允许连接,另一个View禁止连接的情况。
还有一些其他的函数来定制JGraph,比如setMinimumMove在移动之前设置最小的像素距离,setSnapSize设置Cell选择的最大距离。setDisconnectOnMove用来定义当执行移动操作时,选择是否从未选择的Graph上断开。setDragEnabled用来enable/disable拖拽功能。setDropEnabled设置是否接受外部源的拖入(比如剪贴板)。
响应交互
你可以响应鼠标消息,以及JGraph产生的事件。JGraph提供如下通知:
· Model变化
· View变化
· 选择变化
· 重做编辑(Undoable Edit)
JGraph与Swing的Undo支持是兼容的。用户的每一个动作,Model都会分发一个Edit来描述发生的改变。这个Edit提供了undo方法来撤销发生的变化。
如果调用了Edit的undo函数,Model就产生一个GraphModelEvent,不是UndoableEditEvent。UndoableEditEvent在JGraph试图指示一个Edit添加到命令历史中时才发出。(在多视图的环境中,必须使用GraphUndoManager的实例来保证行为的正确。)
为了检测鼠标点击事件,无论是否选中了Cell都会鼠标事情。为了区分选则的Cell,MouseListener可以利用getFirstCellForLocation来获取点击的位置。下面的代码在鼠标双击时,打印输出最上层Cell的Label:
// MouseListener that Prints the Cell on Doubleclick
graph.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
if (e.getClickCount() == 2) {
// Get Cell under Mousepointer
int x = e.getX(), y = e.getY();
Object cell = graph.getFirstCellForLocation(x, y);
// Print Cell Label
if (cell != null) {
String lab = graph.convertValueToString(cell);
System.out.println(lab);
}
}
}
});
如果你对Model的通知感兴趣,实现GraphModelListener,并通过addGraphModelListener添加GraphModelListener的实例到Model中。当Cell被插入、删除,或者对象的Label、源、目的、父亲、孩子被修改时,将会通知监听者。(确保添加一个观察者到GraphView以确保Graph的所有改变都会通知到。)下面的代码定义了一个监听者,打印输出Model的变化,并将该监听者添加到Model中。
// Define a Model Listener
public class ModelListener implements GraphModelListener {
public void graphCellsChanged(GraphModelEvent e) {
System.out.println("Change: "+e.getChange());
}
}
// Add an Instance to the Model
graph.getModel().addGraphModelListener(new ModelListener());
可视化的通知通常被GraphView处理,他继承自Observable。为了处理视图的变化,实现Observer接口,并通过addObserver添加到视图中。当Cell的大小、位置、颜色等发生变化时,视图通知Observer。(如果模型的isAttributeStore返回true,试图将被忽略,所有的属性存储在Model中。)
// Define an Observer
public class ViewObserver implements Observer {
public void update(Observable o, Object arg) {
System.out.println("View changed: "+o);
}
}
// Add an Instance to the View
graph.getView().addObserver(new ViewObserver());
下面的代码打印输入选择事件:
// Define a Selection Listener
public class MyListener implements GraphSelectionListener {
public void valueChanged(GraphSelectionEvent e) {
System.out.println("Selection changed: "+e);
}
}
// Add an Instance to the Graph
graph.addGraphSelectionListener(new MyListener());
上面的代码创建一个MyListener,实现GraphSelectionListener接口,并注册到Graph中。
为了支持Undo,一个GraphUndoManager必须通过addUndoableEditListener添加到Model中。GraphUndoManager继承自Swing的UndoManager,它在多试图环境中维护了一个命令历史。对于只有一个View的情况,可以使用UndoManager的实例即可,否则需要使用GraphUndoManager的实例来保证正确的行为。
上图所示,是一个多视图环境下的Graph Model。从逻辑的角度看,JGraph和GraphModel都产生UndoablEditEvent。然而真实的情况是,只有Model支持这些消息,视图使用Model的支持来分发UndoableEdits。视图依据UndoablEditEvent进行更新。
JGraph提供了两个高层次的监听者来控制鼠标和数据转换功能。通过重载,可以完全控制选取和数据转换,包括拖拽、剪切板和端口之间建立连接。