JGraph

廉子民
2023-12-01

Design and Implementation of the JGraph Swing Component

http://jgraph.sourceforge.net/doc/paper/index.html

 

 

JGrah Manual:

关于hander:就是选中组件后出现在四周的那几个小点。

关于Vertice,Edge:We can create new simple vertices by constructing DefaultGraphCells and edges with
DefaultEdge. These classes can be instantiated with no parameters, or with an object. By
default, whatever that object returns in its toString() method will appear as the text for that
vertex or edge. Obviously, String objects return themselves in toString() and this is
sometimes the only object used in this parameter. In the HelloWorld example we use this
mechanism to assign one vertex the label “Hello” and other vertex the label “World”.

关于port的解释:a DefaultPort, might be confusing if you are familiar with graph theory.
Ports are an artificial addition in JGraph used to indicate places on a vertex where an edge may
connected to that vertex. The ends of edges connect to vertices by these ports and ports are
represented, at least in the default model provided with JGraph, as being children of one vertex.
The add() and setParent() calls are the mechanism used in JGraph in indicate the
parent/child relationship between the vertex and its port(s).

 

Vertices与Edge之间的关联:Setting up the vertices and edge to display how we would like them is done by modifying
their attributes.

 

关于Attribute map:All cells, including ports, have what is called an attribute map. This is a
java.util.Map, the JGraph default implementation of an attribute map, AttributeMap,
is a subclass of Map. Ensure you understand how Java maps operate and their basic API before
using attribute maps. Attributes are stored in key/value pairs where the keys are attributes like
color, position and text font. It is worth, at this point, you having a look at the
org.jgraph.GraphConstants class.

GraphConstants is a utility class designed to allow you to access attribute maps in a typesafe
way, i.e. ensure you are using the correct types of objects for the available attributes. It also
provides a useful guide to what attributes can be set for the various cell types. In
GraphConstants, after some initial enumeration variables, you will find a list of Strings
that represent the possible keys in attribute maps. The bottom half of the source file, roughly,
contains all the accessor methods (getXXX() and setXXX() methods) that you should use in
your application to read and change the attributes. The Javadocs of these methods and key
strings are the most up to date and complete description available, repeating them in documents
such as this one is avoided as such references quickly become outdated.

All graph cells have a storage map that you can obtain using getAttributes(). When
inserting cells you can obtain the attribute map that belongs to that cell and manipulate it before
inserting the cell into the graph. This practice is only generally advised for inserting cells, when
editing cell the process of using transport maps, not the actual cell's map ( the storage map )
should be used ( see Editing the Graph ). Below is the call, as an example, of setting the
gradient color on the first cell to orange. The attribute map from the cell is obtained with
getAttributes(), the construction of DefaultGraphCell ensures you receive a nonnull
map. Then the appropriate setter method in GraphConstants is called passing in the
map and the new value to set:
GraphConstants.setGradientColor(cells[0].getAttributes(),
Color.orange);
Another example is:
GraphConstants.setBounds(cells[0].getAttributes(), new
Rectangle2D.Double(20,20,40,20));

 

 


Note that edges all have a direction internally within JGraph, it is up to you whether
you want to reveal this directed behaviour on the visible graph. It is also worth noting that the
accessor methods frequently only apply to one or a limited number of types of cells. Setting the
line end of a vertex is meaningless and nothing will happen because of it, no error is caused by
doing such a thing for performance reasons, since no harm will come of it. The Javadocs of the
methods state when they only apply to particular cell type(s).

 


Try playing with HelloWorld for a few moments to see what simple functionality the
JGraph library provides to you. Select a vertex and what are called handles appear around the
vertex. You can drag the handles to resize the vertex, or click and drag the main part of a vertex
to move it. Double-click a vertex to bring up a simple editor that allows you to alter the labels,
you can do the same for the edge too. Click and hold the mouse down near the top-left of the
graph area and drag the mouse towards the bottom-right of the graph and release.The rectangle
that is formed during the drag is termed a marquee, releasing the mouse causes all three cells to be selected if the marquee completely overlaps the cells.Dragging any part of the selection
causes the whole selection to move at once. Functionality related to this marquee is handled by
the BasicMarqueeHandler.

 

关于JGraph的基本操作:

GraphModel model = new DefaultGraphModel();
GraphLayoutCache view = new GraphLayoutCache(model,new DefaultCellViewFactory());
JGraph graph = new JGraph(model, view);

每个程序都可以已这种方式建立一个JGraph。

关于edit:

When
an insert, edit or remove call is made, the graph model creates an object that describes the
changes that are to be made, this object is called an edit. This edit is executed on the current
state of the graph to determine the resulting graph. The reasons for abstracting the change into
an actual object is two-fold: 1) to provide listeners of the event that executing the edit fires a
means to obtain information as to what happened in the edit, 2) to provide undo support within
JGraph by storing the edit on the undo history.

 

JGraph tutorial: 

 

1定制Graph

JGraph offers the following forms of interactions:
• In-place editing
• Moving
• Cloning
• Sizing
• Bending (Adding/Removing/Moving edge points)
• Establishing Connections
• Removing Connections

2对交互的响应

You can either respond to mouse events, or to events generated by JGraph. JGraph
offers the following notifications:
• Changes to the model
• Changes to the view
• Changes to the selection
• Undoable edit happened

3定制图形的显示

JGraph performs some look-and-feel specific painting. You can customize
this painting in a limited way.

 

 

标题   JGraph开发经验谈     选择自 java008 的 Blog  
关键字   JGraph开发经验谈 
出处  http://dev.csdn.net/article/79/79509.shtm  
契子

  本来一直很少有机会接触swing或AWT的,只是最近公司要做一个工作流定制界面,所以才终于得偿所愿。我知道,如果一切从底层做起的话,恐怕时间、精力都不允许,而现成的一些工作流产品又不能满足公司特定行业工作流的需求,所以只好找一个开源的中间件进行修改了。就这样,慢慢的认识了JGraph……
  关于JGraph,open-open上是这样介绍的:JGraph,纯Java开发的图形组件,支持拖,放,缩放,合并等其它操作。它可以被结合到任何的Swing应用程序当中。
  在JGraph的网站上可以看到,它分为Free、Pro和Layout Pro版本,作为广大的“劳苦民众”来说,当然首选Free版了,呵呵~~
JGraph的画图机制

  参照了JGraph的example和源代码,发现:

  JGraph将图元定义为一个一个的cell,每个cell可以是一个顶点(Vertex)、边(Edge)或者节点(Port)中的一种。顶点可以有邻接的顶点,他们通过边相联系,边联接的两个端点称为目标和源,每个目标或者源是一个节点。节点是顶点的孩子。每个cell都可以有自己的孩子。
  每个cell的外观由相应的属性定义,属性序列是指一系列的键-值对,他们以Map形式组织,例如:

  //定义Edge的外观
  Map map = new Hashtable();
  GraphConstants.setLineEnd(map, GraphConstants.ARROW_CLASSIC);
  GraphConstants.setEndFill(map, true);
  GraphConstants.setLabelAlongEdge(map, true);
  getAttributes().applyMap(map);

而“画布”(类JGraph,不妨如此理解吧)也可以有自己的外观属性。例如:

  //定义画布的属性
  setBackground(Color.decode("#C0C0C0"));
  setEditable(false);
  setCloneable(false);
  setInvokesStopCellEditing(true);
  setJumpToDefaultPort(true);
  setPortsVisible(false);
  setGridEnabled(false);
  setGridVisible(false);
  setGridMode(JGraph.CROSS_GRID_MODE);
  setGridColor(Color.decode("#808080"));
  setGridSize(10);

JGraph的扩展

  JGraph只是提供单纯的图形绘制功能,不包含实际的数据,所以要想办法把自己的数据“加”进去才行,这恐怕就得考虑扩展JGraph了。
  顶点(Vertex)对应的类为org.jgraph.graph.DefaultGraphCell
  边(Edge)对应的类为org.jgraph.graph.DefaultEdge
  节点(Port)对应的类为org.jgraph.graph.DefaultPort
  我们要做的,仅仅是分别继承相应的类,并把自己的数据对象放进去而已。当然,还可以改变相应的外观属性。不过如果你对绘图事件也感兴趣的话(呵呵,十有八九应该有用的),还要留意一下org.jgraph.graph.BasicMarqueeHandler和org.jgraph.graph.GraphUndoManager这两个类呢。BasicMarqueeHandler中包括了在画布上点击鼠标、增加连线、合并等等事件的处理,而GraphUndoManager则主管撤销、回复事件
  如果仔细操作,你也许回发现,点击边(Edge)的端点进行移动的事件并不由GraphUndoManager来处理,这时候就要再关注一个类了:org.jgraph.graph.EdgeView.EdgeHandle,这是一个内部类,如果需要的话,自己重写一个类继承它吧。这样,大部分需要的事件都尽在自己的掌握中了
  嘿嘿~~~~
总结

  其实也没什么好总结的,写本文也是犹豫再三才开键盘的,本来准备在上个月就写呢。一直拖到现在,因为觉得只是简单的应用而已,全是基本功,没有一点“高级”的“新意”,好像实在没什么好写的。
  今天在BlogJava上看了一篇帖子,感触颇深,其中一句“整天口若悬河新技术,不如将经典的旧技术烂醉于心”,一语解开了困惑我很长时间的一个疑团!从基本功做起,不是高手,唯手熟而……
后记

  如果有朋友对类似的项目感兴趣,欢迎指点,共同研究讨论。

作者Blog:http://blog.csdn.net/java008/

 


JGraph常见问题解答

JGraph常见问题解答
http://www.idcdream.net/archive_50528.html

翻译:nxyc_twz@163.com

简介

这里是一些有关JgraphSwing组件的常见问题解答列表。但是,如果你正在搜索有关Swing问题的答案,或有关图形理论,你应该在其它地方搜索。这是为开发人员提供的第一份资源,而不是API规范的部分。

一般问题

图形是什么?

   这里有一份很好的文档:http://people.hofstra.edu/geotrans/eng/ch2en/meth2en/ch2m1en.html
   在JGraph中,图形作为显示任何有联系的对象网络的范例.通路、计算机网络、分子结构、软件体系或数据库计划都是JGraph中可以显示和交互的图的实例。

我在哪里可以获得技术支持?

  在SourceForge中提供了相应的技术支持。你可以向它提交需求、bug报告、功能需求等,同时它也提供了论坛、邮件列表、CVS库。

  JGraph技术支持站点:http://www.jgraph.org,

  API规范:http://api.jgraph.com

它是否能被使用在商业项目中?

  在许可论坛中阅读各种许可或搜索相关建议。请将你的应用程序的屏幕快照发给我们!

有哪些有效文档?

  这些文档由使用指南,API规范书组成(这些文档可以到上面提到的网站中获得)。《入门学习》中提供了一个HelloWorld示例。《MissionStatement》描述了项目的目的及主要任务。在示例部分中有更多有效示例。

怎样编译JGraph?

  JGraph有3种发布包:CVS发布包包括了用来创建Java1.3或Java1.4 源代码发布包的脚本。源代码发布包被用来使用各种Java编译器创建二进制发布包,。可以看到README文件,2.2章描述了如何编译CVS发布包,2.3章解释了如何编译源代码发布包。

XML

JGraph提供了什么XML-支持?

  JGraph支持两种不同的XML类型:

_        持续型

_        图形交换格式

  JavaSDK1.4支持基于XML的持续型(说明:JGraph仅支持短期串行化)。图形交换格式即独立于应用程序。例如,JGraphpad图形编辑器可以导出GXL格式.


我在哪里可以找到示例?

  这是一个最小的示例:

   XMLEncoderenc=newXMLEncoder(newBufferedOutputStream(newFileOutputStream(name.toString())));

   enc.writeObject(graph1);

   enc.close();

 

  XMLDecoderdec=newXMLDecoder(newBufferedInputStream(newFileInputStream(name)));

   Objectgraph2=dec.readObject();

   dec.close();

 

   ASSERT(graph1.equals(graph2));


怎样在XML中使用图像?

 Java 的XMLEncoder和Decoder仅能读、写bean-属性。由于ImageIcon的文件名没有以bean-属性的方式实现,ImageIcons能够在串行化于XML中。作为工作区,ClaudioRosati将ImageIconBean的文件名视作它的一个属性(确信使用与系统关联的有效文件名)。


GXL和SVG是什么?

  GXL是一种图形交换语言标准,它被设计用来作为图形交换语言的标准。它是几种有效基于XML的图形描述语言之一。GXL的有效描述可参考:http://www.gupro.de/GXL/.

  SVG是一种可升级的向量图形标准,它是一种用XML描述二维向量及混合向量/光栅图形的语言。有效的规范可参考:http://www.w3.org/TR/SVG/.

  SVG的不同之处在于转换可视图形描述,而GXL则描述它的结构。GXL也支持一些属性,这些属性可以用来存储位置,大小或任何其它单元的视图或模式属性。

(待续……)

 


JGraph分析
http://www.jr163.org/cup2/49/49818.htm
JGraph分析
                                                                        Johnny.Deng
JGraph是一个开源的,兼容Swing的基于MVC体系结构图形组件,具有以下特点:
1)   完全Swing兼容;
2)   简单、高效的设计;
3)   时间效率高;
4)   100 %纯Java;
生成的图例
 
二、JGraph设计
1)  MVC
Swing是Java(Sun)提供的UI标准实现之一,Swing基于AWT(Abstract Windowing Toolkit)。JGraph完全兼容Swing,它的实现仍然基于MVC体系结构。
 
 
JGraph MVC
 
View:
JGraph不包含实际的数据,它提供了数据的视;JGraph对象画图的机制是:
将图元定义为一个一个的cell,每个cell可以是一个顶点(vertex)、边(edge)或者节点(port)中的一种。顶点可以有邻接的顶点,他们通过边相联系,边联接的两个端点称为目标和源,每个目标或者源是一个节点。节点是顶点的孩子。每个cell都可以有自己的孩子。
每个cell的外观由相应的属性定义,属性序列是指一系列的键-值对,他们以Map形式组织,例如:
Map cellAttrib = new Hashtable();
// Set bounds
Rectangle2D helloBounds = new Rectangle2D.Double(20, 20, 40, 20);
GraphConstants.setBounds(cellAttrib, helloBounds);
// Set black border
GraphConstants.setBorderColor(cellAttrib, Color.black);
 
一个cell有类似这样一个cellAttrib的Map,来定义其外观。
外观可以指定诸如一条边的箭头样式等属性。
 
Model:
数据对象可以看成是JGraph中两个独立结构的链接点:grahp结构和group结构。Graph结构基于图论中的顶点、边定义。Group结构是cell的composition结构。Graph结构中getSource()和getTarget()方法,获得源和目标节点。而在group中通过getChild(),getParent()来获得cell的组成结构。
 
2)  低层基于图论逻辑
即:一个图G包含一个非空的元素集V(G)和一个E(G),其中,E(G)是V(G)中两个无序元素组成的二元组。V(G)称为图G顶点的集合,如果任意集合V(G)中的顶点x/y,(x,y)在E(G)中,边(x,y)可能以连接顶点x和y的边(弧)所代表,X与y就被称为邻接的,否则x与y不邻接。
 
三、JGraph的应用
以下是一个基于JGraph的Helloworld的分析:
import省略
public class HelloWorld {
 
  public static void main(String[] args) {
 
    // Construct Model and Graph
    //
    GraphModel model = new DefaultGraphModel();
    JGraph graph = new JGraph(model);
    graph.setSelectNewCells(true);
 
    // Create Nested Map (from Cells to Attributes)
// 此Map中记录所有属性,其中的键-值对是cell-cellAttribute
// 每个cellAttribute又是一个Map,其键-值对是具体一个cell的属性-值
    Map attributes = new Hashtable();
 
//  以下建立两个顶点(cell)Hello和World,并分别设置他们的属性Map
// Create Hello Vertex
    //
    DefaultGraphCell hello = new DefaultGraphCell("Hello");
   
    // Create Hello Vertex Attributes
    //
    Map helloAttrib = new Hashtable();
    attributes.put(hello, helloAttrib);
    // Set bounds
    Rectangle2D helloBounds = new Rectangle2D.Double(20, 20, 40, 20);
    GraphConstants.setBounds(helloAttrib, helloBounds);
    // Set black border
    GraphConstants.setBorderColor(helloAttrib, Color.black);
 
    // Add a Port
    //  每个顶点为了与其他顶点相邻接,必须添加节点(cell)
    DefaultPort hp = new DefaultPort();
    hello.add(hp);
 
    // Create World Vertex
    //
    DefaultGraphCell world = new DefaultGraphCell("World");
 
    // Create World Vertex Attributes
    //
    Map worldAttrib = new Hashtable();
    attributes.put(world, worldAttrib);
    // Set bounds
    Rectangle2D worldBounds = new Rectangle2D.Double(140, 140, 40, 20);
    GraphConstants.setBounds(worldAttrib , worldBounds);
    // Set fill color
    GraphConstants.setBackground(worldAttrib, Color.orange);
    GraphConstants.setOpaque(worldAttrib, true);
    // Set raised border
    GraphConstants.setBorder(worldAttrib,
           BorderFactory.createRaisedBevelBorder());
 
    // Add a Port
    //
    DefaultPort wp = new DefaultPort();
    world.add(wp);
 
// 建立联接两个顶点的边
// Create Edge
    //
    DefaultEdge edge = new DefaultEdge();
   
    // Create Edge Attributes
    //
    Map edgeAttrib = new Hashtable();
    attributes.put(edge, edgeAttrib);
    // Set Arrow
    int arrow = GraphConstants.ARROW_CLASSIC;
    GraphConstants.setLineEnd(edgeAttrib , arrow);
    GraphConstants.setEndFill(edgeAttrib, true);
 
    // Connect Edge
    // 边的两个端点就是两个顶点的child节点(port)
    ConnectionSet cs = new ConnectionSet(edge, hp, wp);
    Object[] cells = new Object[]{edge, hello, world};
 
    // Insert into Model
    // model构件完成
    model.insert(cells, attributes, cs, null, null);
 
    // Show in Frame
    //
    JFrame frame = new JFrame();
    frame.getContentPane().add(new JScrollPane(graph));
    //frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
  }
 
}

 

 

Jgraph分析札记- -

 http://publishblog.blogchina.com/blog/tb.b?diaryID=1075986                                      

jgraph分析的开端


Jgraph提供了诸多的构造函数,因此使用起来也很方便。如你只需要调用Jgraph(),并将其加入到一个Jcomponent中即可看到一个默认的Jgraph类的继承图示。示例代码如下:

       public static void main(String[] args) {

                      JFrame frame = new JFrame("EditorGraph");

                JGraph jgraph = new JGraph();

                frame.getContentPane().add(jgraph);

                frame.pack();

              //frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

              frame.setVisible(true);

       }

很简单吧?一开始我总是很费解,这些默认的图是怎么加进去的呢?实际上无论调用哪一个构造函数来初始化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(),显然if (model == null)是成立的。一开始我总是怀疑在创建DefaultGraphModel实例的时候会将那些默认的数据填进去。结果经过多次调试都没有发现任何填充默认数据的迹象。后来又发现setModel会填充数据,下面是setModel的代码:

       public void setModel(GraphModel newModel) {

              GraphModel oldModel = graphModel;

              graphModel = newModel;

              firePropertyChange(GRAPH_MODEL_PROPERTY, oldModel, graphModel);

              if (graphLayoutCache != null

                            && graphLayoutCache.getModel() != graphModel)

                     graphLayoutCache.setModel(graphModel);

              clearSelection();
              invalidate();}从graphLayoutCache.setModel(graphModel);的代码中可以找到填充数据的迹象,但后来一回想才发现,在graphLayoutCache.setModel(graphModel)方法中是将GraphModel中的数据填到graphLayoutCache中,以便准备显示。那么到底这些初始数据是从哪里来的?最后发现忽略了addSampleData方法的调用。

 

 

 

 类似资料: