零全零美(www.zzgwt.com)
生活中的很多事情,并不像If...Else那么简单!
posts - 96,comments - 52,trackbacks - 0
  在做流程的流转历史时,通常情况下还是以列表的形式表现,但是这样总是感觉不太直观,JBPM号称是面向图的编程,那么为什么我们不能在流程图上显示我们的流转历史呢,至少我们可以在流程图上高亮显示当前流程执行到了哪个节点,如果能这样的话用户可以很轻松而且一目了然的看到流程的流转情况。
  我发现在JBPM自带的例子中有类似的效果,后来无意中又在网上发现了一篇文章《 JBPM图形化流程监控》,作者简单的阐述了图形化流程监控的实现思路,让我欣喜万分,最终决定一试,呵呵,首先让我秀一下战果吧:



                            图1:当前任务节点





                  图2:当前流程中的活动任务

   下面简单的说说实现思路:
   1、首先如果我们想高亮显示某一任务节点,我们至少会知道该任务的某个实例,那么我们可以通过该taskInstance取得该任务所在的任务节点名称如:String nodeName =
taskInstance.getTask().getTaskNode().getName();
   2、其次我们使用JBPM的Eclipse插件画流程图的时候,工具除了生成流程图之外还会有一个gpd.xml,该文件记录了流程图的大小及其中的节点的坐标及每个节点的长宽,这就是说我们可以用DOM4J来解析该流程图,从而得到我们要高亮显示的那个节点的坐标及大小。
   3、最后我们可以通过以上两步得到的信息,以该流程图中为背景图案在其上画DIV,来高亮显示相应节点。
   需要说明的是,我这种实现思路跟JBPM自带例子的思路有一点不同,JBPM是在部署流程定义的时候把流程定义图也一样的放入了数据库,所以他是以IO流的方式来处理,而我这种是完全在本地解析XML文件。
   呵呵,大体思路就是这样了,不知道我有没有说明白,不过不明白不要紧,下面我们就来看具体的代码实现,大家都是coder,还是用代码交流起来比较方便啊,大家手头都有gpd.xml文件的模板,所以这个文件的代码就不往上贴了:
 1     /**
 2      * 功能描述:解析指定Node节点的x、y坐标以及该节点的width和height<br>
 3      * @param root
 4      * @param nodeName
 5      * @return int[]
 6      */
 7     private int[] extractBoxConstraint(Element root, String nodeName) {
 8         int[] result = new int[4];
 9         XPath xPath = new DefaultXPath("//node[@name='" + nodeName + "']");
10         Element node = (Element) xPath.selectSingleNode(root);
11         result[0= Integer.valueOf(node.attribute("x").getValue()).intValue() - 4;
12         result[1= Integer.valueOf(node.attribute("y").getValue()).intValue() - 4;
13         result[2= Integer.valueOf(node.attribute("width").getValue()).intValue() + 4;
14         result[3= Integer.valueOf(node.attribute("height").getValue()).intValue() + 4;
15         return result;
16     }
17 
18     /**
19      * 功能描述:获取gpd文件中流程图的width和height<br>
20      * @param root
21      * @return int[]
22      */
23     private int[] extractImageDimension(Element root) {
24         int[] result = new int[2];
25         result[0= Integer.valueOf(root.attribute("width").getValue()).intValue();
26         result[1= Integer.valueOf(root.attribute("height").getValue()).intValue();
27         return result;
28     }
  以上两个方法是纯DOM4J实现,作用就是解析gpd.xml文件以获取我们想要得到的信息,这两段代码是JBPM例子中带有的,高亮显示的具体的应用代码如下:
 1     /**
 2      * 在流程图上高亮显示节点 功能描述:<br>
 3      * 
 4      * @param taskInstanceId
 5      *            任务实例ID
 6      * @param gpdPath
 7      *            流程图坐标文件路径
 8      * @param processImagePath
 9      *            流程图路径
10      */
11     public String ProcessImageForCurrentTask(long taskInstanceId,String gpdPath,String processImagePath) {
12         StringBuffer sbString = new StringBuffer();
13         try {
14             //初始化dom4j
15             Element rootDiagramElement = new SAXReader().read(gpdPath).getRootElement();
16             //获取当前TaskInstance
17             TaskInstance taskInstance = this.defaultJbpmDAO.findTaskInstance(taskInstanceId);
18             //解析gpd.xml
19             int[] boxConstraint = extractBoxConstraint(rootDiagramElement, taskInstance.getTask().getTaskNode().getName());
20             int[] imageDimension = extractImageDimension(rootDiagramElement);
21             //具体的画图代码
22             String imageLink = processImagePath;
23             sbString.append("<table border=0 cellspacing=0 cellpadding=0 width=" + imageDimension[0+ " height=" + imageDimension[1+ " style=\"position:relative\">");
24             sbString.append("  <tr>");
25             sbString.append("    <td width=" + imageDimension[0+ " height=" + imageDimension[1+ " style=\"background-image:url(" + imageLink + ")\" valign=top>");
26             sbString.append("    <div style=\"position:absolute;");
27             sbString.append("                left:"+boxConstraint[0]+ "px; top:"+ boxConstraint[1+"px;width:" + boxConstraint[2+"px;height:"+ boxConstraint[3+"px;");
28             sbString.append("                z-index:1;    border-color:red;    border-width:4; ");
29             sbString.append("                border-style: groove; background-color: transparent;\">");
30             sbString.append("    </div>");
31             sbString.append("    </td>");
32             sbString.append("  </tr>");
33             sbString.append("</table>");
34 
35         } catch (Exception e) {
36             e.printStackTrace();
37         }
38         return sbString.toString();
39     }
40
   虽然代码比较多,但是思路很清晰,我也就不罗嗦了,上面是给出了指定的taskInstance的ID,可以用来高亮显示指定的任务节点,如果我们想要显示指定流程中处于活跃状态的任务的话,可以传入processInstance的ID,然后得到该流程中的符合条件的任务,循环的生成DIV就行了,看具体代码:
 1     /**
 2      * 功能描述:在流程图上高亮显示指定流程中处于活跃状态的节点 <br>
 3      * 
 4      * @param taskInstanceId
 5      *            任务实例ID
 6      * @param gpdPath
 7      *            流程图坐标文件路径
 8      * @param processImagePath
 9      *            流程图路径
10      */
11     public String processImage(final long processInstanceId, final String gpdPath, final String processImagePath) {
12         StringBuffer sbString = new StringBuffer();
13         try {
14             Element rootDiagramElement = new SAXReader().read(gpdPath).getRootElement();
15 
16             //取得活跃状态的任务
17             List<TaskInstance> activeTaskObjectList = this.defaultJbpmDAO.getTaskInstanceListFormProcess(processInstanceId, TaskStateType.TASK_UNFINISHED);
18             int[] imageDimension = extractImageDimension(rootDiagramElement);
19             
20             String imageLink = processImagePath;  
21             sbString.append("<table border=0 cellspacing=0 cellpadding=0 width=" + imageDimension[0+ " height=" + imageDimension[1+ "  style=\"position:relative\">");
22             sbString.append("  <tr>");
23             sbString.append("    <td width=" + imageDimension[0+ " height=" + imageDimension[1+ " style=\"background-image:url(" + imageLink + ")\" valign=top>");
24             //循环的画DIV,注意此处DIV的相对布局
25             for (TaskInstance taskInstance : activeTaskObjectList) {
26                 int[] boxConstraint = extractBoxConstraint(rootDiagramElement, taskInstance.getTask().getTaskNode().getName());
27                 sbString.append("    <div style=\"position:absolute;");
28                 sbString.append("                left:" + boxConstraint[0+ "px; top:" + boxConstraint[1+ "px; width:" + boxConstraint[2+ "px;height:" + boxConstraint[3+ "px;");
29                 sbString.append("                z-index:1;    border-color: red;    border-width: 4; ");
30                 sbString.append("                border-style: groove; background-color: transparent;\">");
31                 sbString.append("    </div>");
32             }
33             sbString.append("    </td>");
34             sbString.append("  </tr>");
35             sbString.append("</table>");
36 
37         } catch (Exception e) {
38             e.printStackTrace();
39         }
40         return sbString.toString();
41 
42     }
43 
   呵呵,到这我们的目的就已经实现了,可以看到这样在页面上输出的是标准的HTML,我们甚至可以加入JS的动态效果,实现更加强大的功能,希望能对你有所帮助!
posted on 2008-09-25 13:30 零全零美 阅读(6469) 评论(5)  编辑  收藏 所属分类: jbpm

FeedBack:
# re: JBPM之:在流程图上高亮显示指定的任务节点
2008-09-26 09:50 | CowNew开源团队
吼吼,那篇文章写的可是“转载自http://www.blogjava.net/huanzhugege/archive/2007/11/19/161678.html”呀,呵呵  回复  更多评论
  
# re: JBPM实践之:在流程图上高亮显示指定的任务节点
2009-02-10 18:09 | javathinker
能否把这个例子的源码发我一份啊,this.defaultJbpmDAO.getTaskInstanceListFormProcess(processInstanceId, TaskStateType.TASK_UNFINISHED); 这个方法是如何实现的啊。
我的邮箱是cattle_liu@163.com
谢谢你了!  回复  更多评论
  
# re: JBPM实践之:在流程图上高亮显示指定的任务节点
2009-03-31 14:45 | s
没有整理好的程序不要拿出来害人  回复  更多评论
  
# re: JBPM实践之:在流程图上高亮显示指定的任务节点
2009-03-31 14:59 | CowNew开源团队
@s
人家求你看了吗?不愿意看别看呀。
我很气愤,要为博主打抱不平,今天不把楼上这个S骂出绿屎来,算你没吃过韭菜。蛤蟆转长虫又托生个王八,三辈没眼眉的玩意。说话也不利落,老跟含着狗粮似的,你个花椒木。一个眼的判官,瞎鬼。木鱼改梆子,挨敲的货。癞蛤蟆插毛,你算飞禽还算走兽?撅屁股看天,有眼无珠。不怕你眼儿紧,我这有大棒槌。说句实在话,为了你,操不尽的心,还有你大爷。  回复  更多评论
  
# re: JBPM实践之:在流程图上高亮显示指定的任务节点
2009-12-10 14:38 | 冰岩
TaskStateType 这个没看懂,哪来的  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: