JUNG2如何绘制相同的边名
How to draw same edge name by JUNG2
我正在用 JUNG2 做一个绘制网络拓扑的项目,现在发现 JUNG2 不能在不同的顶点上绘制相同的边(名称)。报告如下:
Exception in thread "main" java.lang.IllegalArgumentException: edge GigabitEthernet0/3<--->GigabitEthernet0/0/0/0 already exists in this graph with endpoints <HKBR1, HKBR3> and cannot be added with endpoints <HKBR2, HKBR4>
at edu.uci.ics.jung.graph.AbstractGraph.getValidatedEndpoints(AbstractGraph.java:93)
at edu.uci.ics.jung.graph.SparseMultigraph.addEdge(SparseMultigraph.java:123)
at edu.uci.ics.jung.graph.AbstractGraph.addEdge(AbstractGraph.java:60)
at pkg.DrawnTopology.DrawnTopology(DrawnTopology.java:45)
at pkg.ReadLine.main(ReadLine.java:85)
我已经将所有边和顶点存储到一个二维数组中。二维数组数据从不同的文件中学习,所以数据是动态的。由于网络拓扑可能具有相同的边名称,那么如何解决?
从技术上讲,边名称必须是唯一的,但您可以操纵图表中显示的内容。为了获得边的唯一名称,我对边的名称使用以下模式:fromVertex_edgeName_toVertex.
然后你需要 EdgeLabelTransformer
:
private class EdgeLabelTransformer<V> implements Transformer<V, String> {
@Override
public String transform(V v) {
return v.toString().substring(v.toString().indexOf("_") + 1, v.toString().lastIndexOf("_"));
}
}
这个转换器实际上告诉 VisualViewer
要显示什么。所以在我的例子中,它只显示中间部分,这导致你可以在你的图表中有多个具有相同显示名称的边。
像这样添加变压器:
visualViewer.getRenderContext().setEdgeLabelTransformer(new EdgeLabelTransformer<String>());
这个问题显然缺乏细节,但是从描述和错误消息中,可以大概猜到这里出了什么问题:
您的图表可能被定义为 Graph<V, String>
。
可能是Graph
的子class,顶点类型无所谓。关键是边的类型是String
)
并且您正在尝试像这样向图中添加边:
g.addEdge("edge0", v0, v1);
g.addEdge("edge0", v2, v3);
这会导致错误,因为边"edge0"
存在两次。 (这是有道理的。否则:当您向图表询问 "edge0"
的端点时应该发生什么?它应该是 return v0,v1
还是 v2,v3
?这简直是模棱两可)。
(请注意,这不仅是边类型为String
时的情况。对于任何边类型都会发生这种情况,只要两条边是equal
彼此)。
这里一个简单的解决方案是引入一个专用的 Edge
class 来包装字符串:
class Edge
{
private final String name;
Edge(String name)
{
this.name = name;
}
@Override
public String toString()
{
return name;
}
}
此 class 未 覆盖其 equals
方法。所以这种类型的两个对象将不相等,即使字符串相等:
Edge e0 = new Edge("edge0");
Edge e1 = new Edge("edge0");
System.out.println(e0.equals(e1)); // prints "false"
边缘标签可以简单地是这些边缘的 toString
表示,return 原始字符串。
一个例子:
import javax.swing.JFrame;
import org.apache.commons.collections15.Transformer;
import edu.uci.ics.jung.algorithms.layout.FRLayout;
import edu.uci.ics.jung.graph.DirectedSparseGraph;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.visualization.VisualizationViewer;
class Edge
{
private final String name;
Edge(String name)
{
this.name = name;
}
@Override
public String toString()
{
return name;
}
}
public class JungDuplicateEdgesTest
{
public static void main(String[] args)
{
JFrame jf = new JFrame();
final Graph<String, Edge> g = getGraph();
VisualizationViewer<String, Edge> vv =
new VisualizationViewer<String, Edge>(
new FRLayout<String, Edge>(g));
class EdgeLabelTransformer implements Transformer<Edge, String>
{
@Override
public String transform(Edge edge)
{
return edge.toString();
}
}
vv.getRenderContext().setEdgeLabelTransformer(
new EdgeLabelTransformer());
jf.getContentPane().add(vv);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.pack();
jf.setVisible(true);
}
public static Graph<String, Edge> getGraph()
{
Graph<String, Edge> g = new DirectedSparseGraph<String, Edge>();
g.addVertex("v0");
g.addVertex("v1");
g.addEdge(new Edge("e0"), "v0", "v1");
g.addEdge(new Edge("e0"), "v1", "v0");
return g;
}
}
旁注:对于某些应用程序,将边的顶点存储在 Edge
class 中也是有意义的。然后,您可以实现 equals
和 hashCode
方法,允许您在两条边具有相同顶点时将它们视为相等。
我正在用 JUNG2 做一个绘制网络拓扑的项目,现在发现 JUNG2 不能在不同的顶点上绘制相同的边(名称)。报告如下:
Exception in thread "main" java.lang.IllegalArgumentException: edge GigabitEthernet0/3<--->GigabitEthernet0/0/0/0 already exists in this graph with endpoints <HKBR1, HKBR3> and cannot be added with endpoints <HKBR2, HKBR4>
at edu.uci.ics.jung.graph.AbstractGraph.getValidatedEndpoints(AbstractGraph.java:93)
at edu.uci.ics.jung.graph.SparseMultigraph.addEdge(SparseMultigraph.java:123)
at edu.uci.ics.jung.graph.AbstractGraph.addEdge(AbstractGraph.java:60)
at pkg.DrawnTopology.DrawnTopology(DrawnTopology.java:45)
at pkg.ReadLine.main(ReadLine.java:85)
我已经将所有边和顶点存储到一个二维数组中。二维数组数据从不同的文件中学习,所以数据是动态的。由于网络拓扑可能具有相同的边名称,那么如何解决?
从技术上讲,边名称必须是唯一的,但您可以操纵图表中显示的内容。为了获得边的唯一名称,我对边的名称使用以下模式:fromVertex_edgeName_toVertex.
然后你需要 EdgeLabelTransformer
:
private class EdgeLabelTransformer<V> implements Transformer<V, String> {
@Override
public String transform(V v) {
return v.toString().substring(v.toString().indexOf("_") + 1, v.toString().lastIndexOf("_"));
}
}
这个转换器实际上告诉 VisualViewer
要显示什么。所以在我的例子中,它只显示中间部分,这导致你可以在你的图表中有多个具有相同显示名称的边。
像这样添加变压器:
visualViewer.getRenderContext().setEdgeLabelTransformer(new EdgeLabelTransformer<String>());
这个问题显然缺乏细节,但是从描述和错误消息中,可以大概猜到这里出了什么问题:
您的图表可能被定义为 Graph<V, String>
。
可能是Graph
的子class,顶点类型无所谓。关键是边的类型是String
)
并且您正在尝试像这样向图中添加边:
g.addEdge("edge0", v0, v1);
g.addEdge("edge0", v2, v3);
这会导致错误,因为边"edge0"
存在两次。 (这是有道理的。否则:当您向图表询问 "edge0"
的端点时应该发生什么?它应该是 return v0,v1
还是 v2,v3
?这简直是模棱两可)。
(请注意,这不仅是边类型为String
时的情况。对于任何边类型都会发生这种情况,只要两条边是equal
彼此)。
这里一个简单的解决方案是引入一个专用的 Edge
class 来包装字符串:
class Edge
{
private final String name;
Edge(String name)
{
this.name = name;
}
@Override
public String toString()
{
return name;
}
}
此 class 未 覆盖其 equals
方法。所以这种类型的两个对象将不相等,即使字符串相等:
Edge e0 = new Edge("edge0");
Edge e1 = new Edge("edge0");
System.out.println(e0.equals(e1)); // prints "false"
边缘标签可以简单地是这些边缘的 toString
表示,return 原始字符串。
一个例子:
import javax.swing.JFrame;
import org.apache.commons.collections15.Transformer;
import edu.uci.ics.jung.algorithms.layout.FRLayout;
import edu.uci.ics.jung.graph.DirectedSparseGraph;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.visualization.VisualizationViewer;
class Edge
{
private final String name;
Edge(String name)
{
this.name = name;
}
@Override
public String toString()
{
return name;
}
}
public class JungDuplicateEdgesTest
{
public static void main(String[] args)
{
JFrame jf = new JFrame();
final Graph<String, Edge> g = getGraph();
VisualizationViewer<String, Edge> vv =
new VisualizationViewer<String, Edge>(
new FRLayout<String, Edge>(g));
class EdgeLabelTransformer implements Transformer<Edge, String>
{
@Override
public String transform(Edge edge)
{
return edge.toString();
}
}
vv.getRenderContext().setEdgeLabelTransformer(
new EdgeLabelTransformer());
jf.getContentPane().add(vv);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.pack();
jf.setVisible(true);
}
public static Graph<String, Edge> getGraph()
{
Graph<String, Edge> g = new DirectedSparseGraph<String, Edge>();
g.addVertex("v0");
g.addVertex("v1");
g.addEdge(new Edge("e0"), "v0", "v1");
g.addEdge(new Edge("e0"), "v1", "v0");
return g;
}
}
旁注:对于某些应用程序,将边的顶点存储在 Edge
class 中也是有意义的。然后,您可以实现 equals
和 hashCode
方法,允许您在两条边具有相同顶点时将它们视为相等。