マウス操作を可能にするには、グラフの表示にBasicVisuzalizationServer<V,E>クラスの代りに、そのサブクラスであるVisualizationViewer<V,E>クラスを使用します。さらに、VisualizationViewerオブジェクトにマウスイベントを処理するオブジェクトを設定します。
1: import java.awt.Dimension; 2: import javax.swing.JFrame; 3: import edu.uci.ics.jung.algorithms.layout.FRLayout; 4: import edu.uci.ics.jung.algorithms.layout.Layout; 5: import edu.uci.ics.jung.graph.Graph; 6: import edu.uci.ics.jung.graph.UndirectedSparseGraph; 7: import edu.uci.ics.jung.visualization.VisualizationViewer; 8: import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse; 9: import edu.uci.ics.jung.visualization.control.ModalGraphMouse; 10: public class Sample6a { 11: public static void main(String[] args) { 12: Dimension viewArea = new Dimension(300, 300); 13: Graph<MyNode,MyEdge> graph = createGraph(); 14: Layout<MyNode,MyEdge> layout = new FRLayout<MyNode,MyEdge>(graph, viewArea); 15: VisualizationViewer<MyNode,MyEdge> panel = new VisualizationViewer<MyNode,MyEdge>(layout, viewArea); 16: DefaultModalGraphMouse<MyNode,MyEdge> gm = new DefaultModalGraphMouse<MyNode,MyEdge>(); 17: gm.setMode(ModalGraphMouse.Mode.TRANSFORMING); // default 18: panel.setGraphMouse(gm); 19: JFrame frame = new JFrame("Graph View: Mouse Operation"); 20: frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 21: frame.getContentPane().add(panel); 22: frame.pack(); 23: frame.setVisible(true); 24: } 25: private static Graph<MyNode,MyEdge> createGraph() { 26: Graph<MyNode,MyEdge> g = new UndirectedSparseGraph<MyNode,MyEdge>(); 27: MyNode n1 = new MyNode("n1"); 28: MyNode n2 = new MyNode("n2"); 29: MyNode n3 = new MyNode("n3"); 30: MyNode n4 = new MyNode("n4"); 31: MyNode n5 = new MyNode("n5"); 32: MyNode n6 = new MyNode("n6"); 33: MyNode n7 = new MyNode("n7"); 34: MyNode n8 = new MyNode("n8"); 35: g.addEdge(new MyEdge("e1"), n1, n2); 36: g.addEdge(new MyEdge("e2"), n2, n3); 37: g.addEdge(new MyEdge("e3"), n3, n4); 38: g.addEdge(new MyEdge("e4"), n4, n1); 39: g.addEdge(new MyEdge("e5"), n5, n6); 40: g.addEdge(new MyEdge("e6"), n6, n7); 41: g.addEdge(new MyEdge("e7"), n7, n8); 42: g.addEdge(new MyEdge("e8"), n8, n5); 43: g.addEdge(new MyEdge("e9"), n1, n5); 44: g.addEdge(new MyEdge("e10"), n2, n6); 45: g.addEdge(new MyEdge("e11"), n3, n7); 46: g.addEdge(new MyEdge("e12"), n4, n8); 47: return g; 48: } 49: }
15行目で、VisualizationViewer<MyNode,MyEdge>クラスのオブジェクトを作成してpanelとしています。マウスイベントを処理するオブジェクトはDefaultModalGraphMouse<V,E>クラスのオブジェクトで、16行目で生成されています。17行目はマウスイベントの使い方を指定しています。ここではTRANSFORMINGを指定することで、マウスによって変形ができます。実際にはTRANSFORMINGはデフォルトなので、17行目(と9行目)は無くても構いません。18行目でVisualizationViewer<MyNode,MyEdge>クラスのオブジェクトであるpanelにgmを設定しています。
上のプログラムを実行するとすると、たとえば下のようなグラフが描かれます。ウィンドウ内でマウスをドラッグすると、グラフがそのままの形で移動します。
下はマウスホイールによってグラフを縮小したところです。
下はShiftキーやMetaキーとともにマウスをドラッグしてグラフを変形したところです。
マウスイベントの使い方を変更すれば、マウスによる操作を変えることができます。上の例では、マウスイベントを処理するDefaultModalGraphMouse<V,E>のオブジェクトに、TRANSFORMINGを指定しましたが、PICKINGを指定することで、マウスでノードを掴んで移動することができます。
17: DefaultModalGraphMouse<Integer,Number> gm = new DefaultModalGraphMouse<Integer,Number>(); 18: gm.setMode(ModalGraphMouse.Mode.PICKING); 19: panel.setGraphMouse(gm);
下の図は右下のノードをマウスで移動している様子です。マウスで掴んだノードは黄色に変っています。
マウスで移動中のノードの色を指定することもできます。
24: Transformer<MyNode,Paint> pickedNodePaint = new PickableVertexPaintTransformer<MyNode>(panel.getPickedVertexState(), Color.RED, Color.BLUE); 25: panel.getRenderContext().setVertexFillPaintTransformer(pickedNodePaint);
まず掴まれたノードの色を指定するTransformer<MyNode,Paint>オブジェクトを作成します。25行目では、掴まれていないノードを赤、掴まれているノードを青にしています。そしてそのオブジェクトをsetVertexFillPaintTransformer()メソッドで設定しています。
下の図は右下のノードをマウスで移動している様子です。マウスで掴んだノードが青色に変っています。
ノードをマウスでポイントしたときに、ノードに対するアノテーションを表示させることもできます。
setVertexToolTipTransformer()メソッドで、ノードから文字列への写像を設定すると、ノードをマウスでポイントした際にノードに対応する文字列が表示されます。
16: DefaultModalGraphMouse<MyNode,MyEdge> gm = new DefaultModalGraphMouse<MyNode,MyEdge>(); 17: panel.setGraphMouse(gm); 18: panel.setVertexToolTipTransformer(new ToStringLabeller<MyNode>());
下の図は右下のノードをマウスでポイントしたところです。ノードのラベル「n3」がアノテーションとして表示されています(スクリーンをキャプチャした際にマウスポインタは消えてしまいました)。
下のように、Transformer<MyNode,String>オブジェクトで、ノードから文字列への写像を定義し、その写像をsetVertexToolTipTransformer()メソッドで指定することで、toString()メソッドで返される文字列だけでなく、独自に定義した文字列をアノテーションとして表示することもできます。
18: Transformer<MyNode,String> pointedNodeNote = new Transformer<MyNode,String>() { 19: @Override 20: public String transform(MyNode n) { 21: return "annotation of " + n.label; 22: } 23: }; 24: panel.setVertexToolTipTransformer(pointedNodeNote);
下の図は左上のノードをマウスでポイントしたところです。ノードの「annotation of n4」というアノテーションが表示されています(スクリーンをキャプチャした際にマウスポインタは消えてしまいました)。