JBPM實踐之:在流程圖上高亮顯示指定的任務節點

在作流程的流轉歷史時,一般狀況下仍是以列表的形式表現,可是這樣老是感受不太直觀,JBPM號稱是面向圖的編程,那麼爲何咱們不能在流程圖上顯示咱們的流轉歷史呢,至少咱們能夠在流程圖上高亮顯示當前流程執行到了哪一個節點,若是能這樣的話用戶能夠很輕鬆並且一目瞭然的看到流程的流轉狀況。
  我發如今JBPM自帶的例子中有相似的效果,後來無心中又在網上發現了一篇文章《 JBPM圖形化流程監控》,做者簡單的闡述了圖形化流程監控的實現思路,讓我欣喜萬分,最終決定一試,呵呵,首先讓我秀一下戰果吧:



                            圖1:當前任務節點





                  圖2:當前流程中的活動任務

   下面簡單的說說實現思路:
   一、首先若是咱們想高亮顯示某一任務節點,咱們至少會知道該任務的某個實例,那麼咱們能夠經過該taskInstance取得該任務所在的任務節點名稱如:String nodeName = taskInstance.getTask().getTaskNode().getName();
   二、其次咱們使用JBPM的Eclipse插件畫流程圖的時候,工具除了生成流程圖以外還會有一個gpd.xml,該文件記錄了流程圖的大小及其中的節點的座標及每一個節點的長寬,這就是說咱們能夠用DOM4J來解析該流程圖,從而獲得咱們要高亮顯示的那個節點的座標及大小。
   三、最後咱們能夠經過以上兩步獲得的信息,以該流程圖中爲背景圖案在其上畫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 [] p_w_picpathDimension  =  extractImageDimension(rootDiagramElement);
21               // 具體的畫圖代碼
22              String p_w_picpathLink  =  processImagePath;
23              sbString.append( " <table border=0 cellspacing=0 cellpadding=0 width= "   +  p_w_picpathDimension[ 0 +   "  height= "   +  p_w_picpathDimension[ 1 +   "  style=\ " position:relative\ " > " );
24              sbString.append( "   <tr> " );
25              sbString.append( "     <td width= "   +  p_w_picpathDimension[ 0 +   "  height= "   +  p_w_picpathDimension[ 1 +   "  style=\ " background - p_w_picpath:url( "  + p_w_picpathLink +  " )\ "  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 [] p_w_picpathDimension  =  extractImageDimension(rootDiagramElement);
19              
20              String p_w_picpathLink  =  processImagePath;  
21              sbString.append( " <table border=0 cellspacing=0 cellpadding=0 width= "   +  p_w_picpathDimension[ 0 +   "  height= "   +  p_w_picpathDimension[ 1 +   "   style=\ " position:relative\ " > " );
22              sbString.append( "   <tr> " );
23              sbString.append( "     <td width= "   +  p_w_picpathDimension[ 0 +   "  height= "   +  p_w_picpathDimension[ 1 +   "  style=\ " background - p_w_picpath:url( "  + p_w_picpathLink +  " )\ "  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的動態效果,實現更增強大的功能,但願能對你有所幫助!
        尊重原創,原創地址: http://www.blogjava.net/ycyk168/archive/2009/03/31/231092.html
相關文章
相關標籤/搜索