Java BasicGraphEditor实现拖放顶点自动创建边而非分组功能问询
解决方案:替换默认拖放Group行为为创建Edge
我之前在基于BasicGraphEditor开发时也碰到过这个问题——默认拖拽调色板Vertex到已有Vertex上会自动创建Group,这完全不是我们想要的。要解决这个问题,核心是拦截并修改拖放处理的逻辑,判断拖放场景后替换默认的Group行为为创建Edge。
步骤1:自定义TransferHandler拦截拖放行为
BasicGraphEditor依赖mxGraphTransferHandler处理拖放,我们需要继承这个类并重写importData方法,在里面添加自定义判断逻辑:
import com.mxgraph.swing.handler.mxGraphTransferHandler; import com.mxgraph.swing.mxGraphComponent; import com.mxgraph.view.mxGraph; import java.awt.Point; import java.awt.event.MouseEvent; import javax.swing.TransferHandler; public class CustomGraphTransferHandler extends mxGraphTransferHandler { // 假设你已经有调色板的mxGraph实例引用 private final mxGraph paletteGraph; public CustomGraphTransferHandler(mxGraph paletteGraph) { this.paletteGraph = paletteGraph; } @Override public boolean importData(TransferHandler.TransferSupport support) { if (!canImport(support)) { return false; } mxGraphComponent graphComponent = (mxGraphComponent) support.getComponent(); mxGraph graph = graphComponent.getGraph(); // 获取拖放目标的Cell Object targetCell = graphComponent.getCellAt( support.getDropLocation().getX(), support.getDropLocation().getY() ); // 1. 判断目标是画布上的Vertex,且拖放源是调色板的Vertex if (targetCell != null && graph.getModel().isVertex(targetCell)) { Object[] draggedCells = getCells(support.getTransferable()); if (draggedCells != null && draggedCells.length > 0) { Object sourceCell = draggedCells[0]; // 确认源Cell来自调色板(避免拖拽画布内Cell误触发) if (paletteGraph.getModel().isVertex(sourceCell) && paletteGraph.getModel().getParent(sourceCell) == paletteGraph.getDefaultParent()) { // 2. 开始事务,避免UI不一致 graph.getModel().beginUpdate(); try { // 获取拖放位置,在画布上添加新的Vertex Point dropPoint = graphComponent.getPointForEvent((MouseEvent) support.getDropActionEvent()); Object newVertex = graph.insertVertex( graph.getDefaultParent(), null, "New Vertex", // 可替换为调色板Cell的label dropPoint.getX(), dropPoint.getY(), 80, 30 // 可替换为调色板Cell的尺寸 ); // 3. 创建Edge连接目标Vertex和新Vertex graph.insertEdge( graph.getDefaultParent(), null, "", // Edge的label,可自定义 targetCell, newVertex ); // 4. 返回true,跳过默认的Group创建逻辑 return true; } finally { graph.getModel().endUpdate(); } } } } // 不满足条件时,执行默认拖放行为 return super.importData(support); } }
步骤2:注册自定义TransferHandler到GraphComponent
在你的编辑器初始化代码中,把默认的TransferHandler替换成我们自定义的:
// 假设你的画布组件是graphComponent,调色板是paletteGraph graphComponent.setTransferHandler(new CustomGraphTransferHandler(paletteGraph));
额外优化:拖放时的视觉反馈(可选)
如果想要在拖放过程中显示Edge的预览,可以重写mxGraphComponent的getDropTarget方法,或者开启mxGraph的setDropEnabled(true),确保拖放时的光标和预览符合预期。
关键注意点
- 一定要判断源Cell来自调色板,否则拖拽画布内的Vertex到另一个Vertex上也会触发Edge创建,这可能不是你想要的。
- 所有修改Graph模型的操作都要包裹在
beginUpdate()和endUpdate()中,保证事务一致性,避免UI渲染异常。
内容的提问来源于stack exchange,提问作者Rogan Dawes
相关产品推荐
相关产品推荐

