ノードの文字列表現、つまりtoString()メソッドで返される文字列をラベルとしてノードの側に表示しましょう。Sample3a.javaを下のように改造します。
1: import java.awt.Dimension; 2: import java.awt.geom.Point2D; 3: import javax.swing.JFrame; 4: import edu.uci.ics.jung.algorithms.layout.Layout; 5: import edu.uci.ics.jung.algorithms.layout.StaticLayout; 6: import edu.uci.ics.jung.graph.Graph; 7: import edu.uci.ics.jung.graph.UndirectedSparseGraph; 8: import edu.uci.ics.jung.visualization.BasicVisualizationServer; 9: import edu.uci.ics.jung.visualization.decorators.ToStringLabeller; 10: public class Sample4a { 11: public static void main(String[] args) { 12: Graph<MyNode,MyEdge> graph = new UndirectedSparseGraph<MyNode,MyEdge>(); 13: MyNode n1 = new MyNode("n1"); 14: MyNode n2 = new MyNode("n2"); 15: MyNode n3 = new MyNode("n3"); 16: graph.addEdge(new MyEdge("e1"), n1, n2); 17: graph.addEdge(new MyEdge("e2"), n2, n3); 18: Layout<MyNode,MyEdge> layout = new StaticLayout<MyNode,MyEdge>(graph); 19: layout.setLocation(n1, new Point2D.Double(100, 100)); 20: layout.setLocation(n2, new Point2D.Double(200, 100)); 21: layout.setLocation(n3, new Point2D.Double(150, 200)); 22: BasicVisualizationServer<MyNode,MyEdge> panel = new BasicVisualizationServer<MyNode,MyEdge>(layout, new Dimension(300, 300)); 23: panel.getRenderContext().setVertexLabelTransformer(new ToStringLabeller<MyNode>()); 24: JFrame frame = new JFrame("Graph View: Showing Node Labels"); 25: frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 26: frame.getContentPane().add(panel); 27: frame.pack(); 28: frame.setVisible(true); 29: } 30: }
23行目がノードに文字列を表示するように指定している行で、BasicVisualizationServer<MyNode,MyEdge>オブジェクトのpanelに対して、ラベル付けの方法を設定しています。ToStringLabeller<V>クラスは、Transformer<V,String>インタフェースを実装したクラスで、Vクラスのオブジェクトに対して、その文字列表現を対応付けます。MyNodeクラスではコンストラクタで設定した文字列labelがtoString()メソッドで返されるので、labelが「n1」のノードには文字列「n1」がそのまま表示されます。
上のプログラムを実行するとすると下のように表示されます。
toString()メソッドで返される文字列ではなく、独自に定義した文字列をラベルとして表示しましょう。Sample4a.javaの23行目を下のように改造します。
23: Transformer<MyNode,String> labeller = new Transformer<MyNode,String>() { 24: @Override 25: public String transform(MyNode n) { 26: return "node: " + n.label; 27: } 28: }; 29: panel.getRenderContext().setVertexLabelTransformer(labeller);
ラベル付けの方法は、23行目から28行目で、Transformer<MyNode,String>オブジェクトのtransform()メソッドによって定義しています。ここでは26行目にあるように、「"node: " + n.label」として定義しています。つまりlabelが「n1」のノードには文字列「node: n1」が表示されます。29行目がノードに文字列を表示するように指定している行で、panelに対してラベル付けの方法を定義したlabellerを設定しています。
上のプログラムを実行するとすると下のようなウィンドウが現われます。
Transformerクラスはパッケージorg.apache.commons.collections15で定義されているクラスで、JUNG2.0で定義されているものではありません。
JUNG2.0では、ラベル表示だけでなく、グラフのノードやエッジに対する属性値を定義するためにTransformerクラスを利用します。そのため、上のような定義を至る所で行います。
上の例ではノードのラベルがノードの右下に表示されている。ラベルの位置を変更するには、下のような行を(たとえば、29行目の次に)追加します。
panel.getRenderer().getVertexLabelRenderer().setPosition(Position.CNTR);
この行を追加すると下のような表示になります。つまりラベルがノードの中心に表示されます。下の例では、ラベルが短かいので、ノードの内側に納まっていますが、ラベルが長い場合には、ノードの左右にはみ出ます。
位置はCNTR(中央)以外に、上から時計回りに、N、NE、E、SE、S、SW、W、NWの8方向が選択できます。たとえばPosition.Nを指定すると、ノードの上部に配置されます。デフォルトはSEで、右下です。これら以外にAUTOも指定できます。自動で「うまく」配置してくれるもののようです。たとえば、同じグラフにPosition.AUTOを指定すると下のようになります。
エッジに文字列を表示する方法も、ノードと同様です。BasicVisualizationServer<MyNode,MyEdge>オブジェクトのpanelに対して、setEdgeLabelTransformer()メソッドで、エッジのラベル付けの方法を定義したオブジェクトを設定します。
panel.getRenderContext().setEdgeLabelTransformer(new ToStringLabeller<MyEdge>());
エッジのラベルは下のように表示されます。
独自に定義した文字列をラベルとして表示する方法も、ノードと同様です。
23: Transformer<MyEdge,String> edgeLabeller = new Transformer<MyEdge, String>() { 24: @Override 25: public String transform(MyEdge e) { 26: return "edge: " + e.label; 27: } 28: }; 29: panel.getRenderContext().setEdgeLabelTransformer(edgeLabeller);
エッジのラベルは下のように表示されます。