1.2 编辑操作的组织
对象类 | 程序分析 |
|
| 通过下面的Map结构,可以有效的组织你的编辑操作,并且放在一个undo事件中 Map nested = new Hashtable(); Map attributeMap1 = new Hashtable(); GraphConstants.setLineColor(attributeMap1 , Color.orange); nested.put(cell1, attributeMap1 ); 。。。。。 graph.getgraphLayoutCache().edit(nested, null, null, null); 效果图如下所示 |
|
|
|
|
| 在insert,edit或者remove被调时,graph model会创建edit对象,描述所发生的变化。这样的话可以有两个方面的好处: 1,可以通过listener来临听编辑过程中发生了什么。 2,存储edit到undo历史中以支持undo操作 Edit()方法会检查有无变化来触发更新操作。(这个检查方法是比较复杂的) |
|
移除操作 | Object[] keys = new Object[] { GraphConstants.ICON }; GraphConstants.setRemoveAttributes(map, keys);
|
|
|
The AUTOSIZE attribute is in both the pre-edit storage map and the transport map. In this case the post-edit storage map holds the value passed in through the transport map. |
|
1.1.3 GraphModel
Graph
Model | GraphModel保存了Graph的逻辑结构,可以看做是Graph的数据源。 图的属性,如位置,样式细节和行为控制(如是否可拖动)都是数据源。 大部分图形工具包仅仅图形化显示节点和关系图,而Jgraph做的更多。 insert(), edit() and remove()三个方法与 GraphLayoutCache中方法同样 |
|
| Accessing the Graph Model Data 访问模型数据 默认情况下,每一个顶点或者边加入Jgraph当中时,都会从根节点下形成树形状,Port作为节点的子节点:如下图所示
|
|
| getRootCount() 返回根结点的数目,上面的例子当中返回的数目是3. getRootAt() getIndexOfRoot(Object) 根结点的序号是-1,第一个节点是0, contains(Object) |
|
| 通过GraphModel接口访问连接属性 getSource(Object edge)方法和getTarget(Object edge)方法读取cells. edges(Object port)用来遍历所有连接的边 Object getParent(Object child) int getIndexOfChild(Object parent, Object child) Object getChild(Object parent, int index) int getChildCount(Object parent) |
|
|
|
|
| 下面给出一个例子取出所有的连接边 List listEdges = new ArrayList(); int numChildren = model.getChildCount(cell); for (int i = 0; i < numChildren; i++) { Object port = model.getChild(cell, i); if (model.isPort(port)) { Iterator iter = model.edges(port); while (iter.hasNext()) { listEdges.add(iter.next()); }}} 取边对应的顶点: Object sourceVertex = model.getParent(model.getSource(edge)); Object targetVertex = model.getParent(model.getTarget(edge)); |
|
|
|
|
|
|
|
|
|
|
1.1.4 Cell的类型
对象类 | 程序分析 |
|
| 有三种基本的Cell类型: vertices, edges and ports. 顶点可以是方形,圆形,图标或者是复合图形,边可以是单向的,并行的,自循环的。 |
|
GraphCell Interface | 单元格的接口和默认实现 GraphCell是Graph cells应当继承的接口。 GrpahCell的方法有:setAttributes(). getAttributes() |
|
|
|
|
DEFAULTGRAPHCELL | 顶点使用 DEFAULTGRAPHCELL,边和Port使用DEFAULTGRAPHCELL的子类。
public DefaultGraphCell(Object userObject, AttributeMap storageMap, MutableTreeNode[] children)
|
|
User Objects | userObject 用户自定义对象可以存储任意扩展对象,例如一个workflow编辑器,用户对象可以表示开始,分支,连接等节点。 用户对象可以整体放入构造函数中。 cells[0] = new DefaultGraphCell(new String("Hello")); JGraph.convertValueToString(Object). GraphModel.getValue(Object) GraphConstants.setValue(Object) |
|
Cell Views | 所有的graph cells最少关联一个cell view。 Cell view关联renderer, and editor and a cell handle |
|
| Renderers是Swing的一种flyweight设计.所有的组件都要绘制同一形状,所心可以共享一个render,以节省很多内存消耗。当一个cell被呈现时,cell的所有属性会传入render实例中。
|
|
| Editor是cell view的一个关联组件,比如in-place editor就是DefaultGraphCellEditor,, |
|
| Cell Handles 在Swing并没有同样的设计。Jgraph中可以改变cell的边界,移动,而cell handles就是用于处理上述任务的。CellHandle类似于MouseMotionListener MouseListener 。Cell Handle提供 paint(Graphics g) overlay(Graphics g)方法, 在live-preview时处理绘制 ,通常使用XOR绘制方式。 Jgraph 提供一个handle的默认实现 SizeHandle,EdgeHandle,RootHandle.
RootHandle处理移动 SizeHandle处理定义边界大小 EdgeHandle处理连接与断形连接 |
|
层次结构 |
|
|
View Factory | GraphLayoutCache传入一个 CellViewFactory作为参数 也可调用setFactory()方法 |
|
默认的Cell Views实现类:
| VertexView顶点,EdgeView和PortView PortView的size属性是hare-coded的,所以没有定义大小的功能。 getLocation() and shouldInvokePortMagic(), EdgeView比上面的两个View复杂一些。针对EdgeView有一些基本的设计原则来说明 Edge有一个label,同时也有extra labels.一个边有两个control point:start point和end point |
|
默认的 render实现类:
| PortRenderer是PortView的默认render实现,一个PortRenderer实例为所有的PortView服务,这也就是为什么getRendererComponent()传入三个状态:selected,preview和focus状态,并存入到 renderer中去。在render的paint方法中,renderer根据存储的状态来正确绘制 VertexRenderer继承了Jlabel, EdgeRenderer |
|
|
|
|
|
|
|
|
|
|
1.1.5 Cell的使用
顶点的使用
设置边框:
bounds = GraphConstants.getBounds(allAttributes);
if (bounds == null) {
bounds = allAttributes.createRect(defaultBounds);
GraphConstants.setBounds(allAttributes, bounds);
}
GraphConstants.setResize(map, true);
GraphConstants.setAutoSize(map, true);
设置图标:
public static class ScaledVertexRenderer extends VertexRenderer {
public void paint(Graphics g) {
Icon icon = getIcon();
setIcon(null);
Dimension d = getSize();
Image img = null;
if (icon instanceof ImageIcon)
img = ((ImageIcon) icon).getImage();
if (img != null)
g.drawImage(img, 0, 0, d.width - 1, d.height - 1,graph);
super.paint(g);
}
}
显示图标:
public static class ScaledVertexRenderer extends VertexRenderer {
public void paint(Graphics g) {
Icon icon = getIcon();
setIcon(null);
Dimension d = getSize();
Image img = null;
if (icon instanceof ImageIcon)
img = ((ImageIcon) icon).getImage();
if (img != null)
g.drawImage(img, 0, 0, d.width - 1, d.height - 1,
graph);
super.paint(g);
}
}
GraphConstants.setVerticalAlignment(Map, int);
SwingConstants: TOP, CENTER (the default), or BOTTOM.
GraphConstants.setHorizontalAlignment(Map, int);
SwingConstants: LEFT, CENTER (the default for image-only labels), RIGHT,
LEADING (the default for text-only labels) or TRAILING.
GraphConstants.setBorder(map, orderFactory.createRaisedBevelBorder());
GraphConstants.setBorder(map,BorderFactory.createLineBorder(graph.getBackground(), 6) );
GraphConstants.setInset() provides a means to place a buffered area around a label, so getPreferredSize() returns a Dimension large enough for the label plus the inset. This Dimension is used by the one-shot resize and autosizing functionality.
边的使用
GraphConstants.setLabelPosition(Map, Point2D);
Point2D point = new Point2D.Double(GraphConstants.PERMILLE/2, 0);
GraphConstants.setExtraLabels(Map, Object[])
GraphConstants.setExtraLabelPositions(Map, Point2D)
Object[] labels = {new String("0...*"),new String("1")};
Point2D[] labelPositions = {new Point2D.Double
(GraphConstants.PERMILLE*7/8, -20), new Point2D.Double
(GraphConstants.PERMILLE/8, -20)};
GraphConstants.setExtraLabelPositions(edge.getAttributes(),labelPositions);
GraphConstants.setExtraLabels(edge.getAttributes(), labels);
setLabelAlongEdge(map, true);
GraphConstants.setLineWidth(map, 5); //sets the edge line width to 5
GraphConstants.setLineColor(map, Color.blue);
// sets the edge line color to blue
setDashPattern(Map, float[])
setDashOffset(Map, float)
GraphConstants.setLineBegin(Map, int)
GraphConstants.setLineEnd(Map, int)