如何在 JUNG 图形库中精准定位并修改指定边的样式

来源:网站主作者:樱由罗头衔:网络博主
导读:本期聚焦于小伙伴创作的《如何在 JUNG 图形库中精准定位并修改指定边的样式》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何在 JUNG 图形库中精准定位并修改指定边的样式》有用,将其分享出去将是对创作者最好的鼓励。

JUNG是Java生态中常用的图可视化与图算法处理库,很多场景需要根据业务需求修改图中某条特定边的显示样式,比如高亮两个关联节点的连接边,或者根据边的权重调整线条粗细。要实现这个需求,首先需要理解JUNG中边的管理逻辑,再通过合理的方式定位目标边,最后调用对应的样式渲染接口完成修改。

如何在 JUNG 图形库中精准定位并修改指定边的样式

JUNG中边的存储与定位逻辑

JUNG的图结构由Graph<V,E>接口定义,其中V代表节点类型,E代表边类型。边本身作为对象存储在图中,没有内置的唯一ID属性,因此不能直接通过ID快速查询。常见的定位指定边的方式有两种:一种是为边对象添加自定义属性,通过属性值匹配;另一种是通过遍历图中的所有边,根据边的两个端点节点匹配目标边。

为边添加自定义属性

如果需要频繁操作特定边,建议在创建边的时候为其添加自定义标记属性。JUNG提供了Map或者自定义边类的方式来存储额外属性,比如我们可以自定义一个边类,包含边的唯一标识字段:

// 自定义边类,包含唯一标识和业务属性
public class CustomEdge {
    private String edgeId;
    private String edgeType;
    private int weight;

    public CustomEdge(String edgeId, String edgeType, int weight) {
        this.edgeId = edgeId;
        this.edgeType = edgeType;
        this.weight = weight;
    }

    // getter方法
    public String getEdgeId() {
        return edgeId;
    }

    public String getEdgeType() {
        return edgeType;
    }

    public int getWeight() {
        return weight;
    }
}

创建图的时候指定边类型为自定义的CustomEdge,之后就可以通过边的edgeId属性快速匹配:

import edu.uci.ics.jung.graph.DirectedSparseGraph;
import java.util.Collection;

public class JungEdgeDemo {
    public static void main(String[] args) {
        // 创建有向图,节点类型为String,边类型为自定义CustomEdge
        DirectedSparseGraph<String, CustomEdge> graph = new DirectedSparseGraph<>();
        // 添加节点
        graph.addVertex("A");
        graph.addVertex("B");
        // 创建边并添加到图中
        CustomEdge edge1 = new CustomEdge("edge_1", "关联边", 5);
        graph.addEdge(edge1, "A", "B");

        // 根据edgeId查找指定边
        CustomEdge targetEdge = null;
        Collection<CustomEdge> allEdges = graph.getEdges();
        for (CustomEdge edge : allEdges) {
            if ("edge_1".equals(edge.getEdgeId())) {
                targetEdge = edge;
                break;
            }
        }
        System.out.println("找到目标边:" + (targetEdge != null ? targetEdge.getEdgeId() : "无"));
    }
}

通过端点节点匹配边

如果只知道边的两个端点节点,也可以通过GraphfindEdge方法快速获取两个节点之间的边,这种方式适合不需要额外标记属性的简单场景:

import edu.uci.ics.jung.graph.DirectedSparseGraph;

public class JungEdgeDemo2 {
    public static void main(String[] args) {
        DirectedSparseGraph<String, String> graph = new DirectedSparseGraph<>();
        graph.addVertex("A");
        graph.addVertex("B");
        // 添加边,边标识为"edge_1"
        graph.addEdge("edge_1", "A", "B");

        // 查找A到B的边
        String targetEdge = graph.findEdge("A", "B");
        System.out.println("A到B的边是:" + targetEdge);
    }
}

修改指定边的样式

JUNG中边的样式由EdgeRendererRenderer.Edge<V,E>相关接口控制,我们可以通过自定义Transformer来实现不同边的差异化样式渲染。核心是给VisualizationViewer设置边的绘制转换器,根据边的属性返回不同的样式参数。

修改边的颜色和线宽

下面的示例演示如何将指定标识的边修改为红色,线宽设置为3,其余边保持默认黑色、线宽1:

import edu.uci.ics.jung.graph.DirectedSparseGraph;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
import edu.uci.ics.jung.visualization.renderers.Renderer;
import org.apache.commons.collections15.Transformer;

import javax.swing.*;
import java.awt.*;

public class EdgeStyleDemo {
    public static void main(String[] args) {
        // 创建图结构
        DirectedSparseGraph<String, CustomEdge> graph = new DirectedSparseGraph<>();
        graph.addVertex("A");
        graph.addVertex("B");
        graph.addVertex("C");
        CustomEdge edge1 = new CustomEdge("edge_1", "关联边", 5);
        CustomEdge edge2 = new CustomEdge("edge_2", "普通边", 2);
        graph.addEdge(edge1, "A", "B");
        graph.addEdge(edge2, "B", "C");

        // 创建可视化查看器
        VisualizationViewer<String, CustomEdge> vv = new VisualizationViewer<>(graph);
        vv.setPreferredSize(new Dimension(800, 600));

        // 设置节点标签
        vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller<>());
        // 设置边标签
        vv.getRenderContext().setEdgeLabelTransformer(new Transformer<CustomEdge, String>() {
            @Override
            public String transform(CustomEdge edge) {
                return edge.getEdgeId();
            }
        });

        // 自定义边的颜色转换器:目标边红色,其余黑色
        vv.getRenderContext().setEdgeDrawPaintTransformer(new Transformer<CustomEdge, Paint>() {
            @Override
            public Paint transform(CustomEdge edge) {
                if ("edge_1".equals(edge.getEdgeId())) {
                    return Color.RED;
                }
                return Color.BLACK;
            }
        });

        // 自定义边的线宽转换器:目标边线宽3,其余线宽1
        vv.getRenderContext().setEdgeStrokeTransformer(new Transformer<CustomEdge, Stroke>() {
            @Override
            public Stroke transform(CustomEdge edge) {
                if ("edge_1".equals(edge.getEdgeId())) {
                    return new BasicStroke(3.0f);
                }
                return new BasicStroke(1.0f);
            }
        });

        // 添加鼠标控制
        DefaultModalGraphMouse<String, CustomEdge> gm = new DefaultModalGraphMouse<>();
        vv.setGraphMouse(gm);

        // 显示窗口
        JFrame frame = new JFrame("JUNG边样式修改示例");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(vv);
        frame.pack();
        frame.setVisible(true);
    }
}

修改边的线条类型

如果需要将指定边修改为虚线,只需要调整Stroke的参数即可,比如下面的转换器可以将目标边设置为虚线:

// 虚线样式转换器
vv.getRenderContext().setEdgeStrokeTransformer(new Transformer<CustomEdge, Stroke>() {
    @Override
    public Stroke transform(CustomEdge edge) {
        if ("edge_1".equals(edge.getEdgeId())) {
            // 虚线参数:线段长度、间隔长度、相位偏移
            return new BasicStroke(3.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 1.0f, new float[]{10.0f, 5.0f}, 0.0f);
        }
        return new BasicStroke(1.0f);
    }
});

注意事项

  • 如果自定义边类,需要确保边类正确实现了equalshashCode方法,避免图中边对象匹配出现异常。
  • 样式修改后如果界面没有实时更新,可以调用vv.repaint()方法手动触发重绘。
  • 如果需要动态切换边的样式,可以将目标边的标识存储在全局变量中,修改标识后重新设置转换器并刷新界面即可。

JUNG图形库边样式精准定位图可视化修改时间:2026-06-24 19:57:49

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。