首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

基於 JGraph 實現工作流圖形編輯器:核心繪圖機制、擴展策略與事件處理實戰

     編輯:Java 程式設計入門

前言:尋找「可編程的畫布」

公司需構建工作流定制界面,現成產品無法滿足行業特定需求,從零繪圖成本太高。開源組件 **JGraph** (純 Java、支持拖拽/縮放/合併、可嵌入 Swing) 成為最佳中間件選擇。本文深度剖析 JGraph 核心模型、擴展機制與事件攔截實戰。

一、JGraph 核心繪圖模型:Cell/Vertex/Edge/Port

  • 屬性映射:Map<Object, Object> attributes 以鍵值對定義外觀 (顏色、線型、箭頭、標籤位置等)
  • 畫布屬性:JGraph 本身也是組件,可設置背景、網格、可編輯性、克隆行為等

二、屬性配置實例

1. Edge 樣式:帶箭頭、填充、標籤沿邊

Map<Object, Object> edgeAttr = new Hashtable<>();
GraphConstants.setLineEnd(edgeAttr, GraphConstants.ARROW_CLASSIC);
GraphConstants.setEndFill(edgeAttr, true);
GraphConstants.setLabelAlongEdge(edgeAttr, true);
edgeCell.getAttributes().applyMap(edgeAttr);

2. 畫布全局屬性

graph.setBackground(Color.decode("#C0C0C0"));
graph.setEditable(false);           // 僅查看模式
graph.setCloneable(false);          // 禁用 Ctrl+拖拽克隆
graph.setInvokesStopCellEditing(true);
graph.setJumpToDefaultPort(true);   // 邊拖拽自動吸附最近 Port
graph.setPortsVisible(false);       // 隱藏 Port 視覺標識
graph.setGridEnabled(false);
graph.setGridVisible(false);
graph.setGridColor(Color.decode("#808080"));
graph.setGridSize(10);

三、擴展策略:將業務數據「注入」圖元

1. 繼承體系映射

概念對應類角色
Cell (單元)DefaultGraphCell所有圖元基類,可包含子 Cell
Vertex (頂點/節點)DefaultGraphCell業務實體節點 (如任務、狀態、決策點)
Edge (邊/連線)DefaultEdge連接兩個 Port,有源 、目標 方向
Port (端口)DefaultPortVertex 的連接點,Edge 掛接於 Port

2. 擴展要點

  • 僅需繼承對應基類,在構造器/字段中持有業務對象引用
  • 覆寫 toString() 返回業務標識,便於調試
  • 可動態修改 Attributes Map 實現狀態可視化 (如運行中節點變綠、異常變紅)

四、事件處理深度攔截:掌控每一次交互

1. 核心事件處理類

圖元類型JGraph 基類業務擴展類攜帶數據示例
VertexDefaultGraphCellWorkflowNodeCellnodeId, nodeName, nodeType, assignee, formTemplate, script...
EdgeDefaultEdgeWorkflowTransitionEdgetransitionId, conditionExpr, priority, rollbackHandler...
PortDefaultPortWorkflowPortportId, allowedTransitionTypes...

2. 實戰:攔截邊端點重新連接

// 自定義 EdgeHandle
public class WorkflowEdgeHandle extends EdgeView.EdgeHandle {
    public WorkflowEdgeHandle(EdgeView view) { super(view); }

    @Override
    public void handleMouseReleased(MouseEvent e, Point pt) {
        // 1. 獲取目標 Port
        PortView targetPortView = getTargetPortView(pt);
        if (targetPortView == null) { super.handleMouseReleased(e, pt); return; }

        // 2. 業務規則驗證
        WorkflowPort targetPort = (WorkflowPort) targetPortView.getCell();
        WorkflowTransitionEdge edge = (WorkflowTransitionEdge) getEdgeView().getCell();
        if (!edge.isValidTargetPort(targetPort)) {
            // 3. 非法:顯示提示、還原、不調用 super
            JOptionPane.showMessageDialog(null, "不允許連接到該類型端口");
            return; // 取消重新連接
        }

        // 4. 合法:委託父類完成視圖更新
        super.handleMouseReleased(e, pt);
        
        // 5. 同步業務模型
        edge.setTargetPort(targetPort);
        workflowModel.onTransitionReconnected(edge);
    }
}

3. 註冊自定義 Handle

// 在自定義 GraphView 或 GraphUI 中
graph.getGraphLayoutCache().setEdgeViewFactory(new EdgeViewFactory() {
    public EdgeView createEdgeView(Object cell, GraphLayoutCache cache) {
        EdgeView view = new EdgeView(cell, cache);
        view.setHandleFactory(new HandleFactory() {
            public Handle createHandle(EdgeView view, int index) {
                return new WorkflowEdgeHandle(view); // 注入自定義 Handle
            }
        });
        return view;
    }
});

五、版本選擇建議

  • Free 版:核心繪圖、編輯、事件機制完整,**足夠 90% 場景**
  • Pro 版:自動佈局算法 (有向圖、層次、樹)、高級路由、SVG 導出
  • Layout Pro:專業佈局引擎獨立授權

六、結語

JGraph 以 **Cell/Vertex/Edge/Port** 四元模型 + **Map 屬性驅動渲染** + **可擴展事件處理鏈**,提供了極佳的「白盒畫布」。通過繼承注入業務數據、攔截 EdgeHandle 控制拓撲合法性、定制 UndoableEdit 實現業務級撤銷,我們在兩周內交付了滿足行業嚴格規範的工作流設計器。**基礎功夫決定上限**——深入理解 JGraph 核心模型與事件分發,比盲目追逐新框架更具長期價值。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
類職責擴展切入點
BasicMarqueeHandler滑鼠點擊、框選、連線創建、合併、移動等 UI 交互覆寫 mousePressed, mouseDragged, mouseReleased 注入業務規則 (如禁止特定類型節點連線)
GraphUndoManager撤銷/重做管理自定義 UndoableEdit 封裝業務狀態變更 (如屬性修改、拓撲變更)
EdgeView.EdgeHandle (內部類)邊端點拖拽移動 (重新連接)**關鍵**:繼承並覆寫 handleMouseReleased 攔截重新連接邏輯,驗證目標 Port 合法性