マウス操作を可能にするには、グラフの表示にBasicVisuzalizationServer[V,E]クラスの代りに、そのサブクラスであるVisualizationViewer[V,E]クラスを使用します。さらに、VisualizationViewer[V,E]クラスのインスタンスにマウスイベントを処理するオブジェクトを設定します。
1: import swing._
2: import java.awt.Dimension
3: import edu.uci.ics.jung.algorithms.layout.{FRLayout,Layout}
4: import edu.uci.ics.jung.graph.{Graph,UndirectedSparseGraph}
5: import edu.uci.ics.jung.visualization.VisualizationViewer
6: import edu.uci.ics.jung.visualization.control.{DefaultModalGraphMouse,ModalGraphMouse}
7: object Sample6a extends SimpleSwingApplication {
8: def top = new MainFrame {
9: title = "Graph View: Mouse Operation"
10: val graph: Graph[MyNode,MyEdge] = createGraph
11: val viewArea = new Dimension(300, 300)
12: val layout: Layout[MyNode,MyEdge] = new FRLayout[MyNode,MyEdge](graph, viewArea)
13: val panel = new VisualizationViewer[MyNode,MyEdge](layout, viewArea)
14: val gm = new DefaultModalGraphMouse[MyNode,MyEdge]
15: gm.setMode(ModalGraphMouse.Mode.TRANSFORMING)
16: panel.setGraphMouse(gm)
17: contents = Component.wrap(panel)
18: }
19: def createGraph: Graph[MyNode,MyEdge] = {
20: val g: Graph[MyNode,MyEdge] = new UndirectedSparseGraph[MyNode,MyEdge]
21: val n1 = new MyNode("n1")
(中略)
29: g.addEdge(new MyEdge("e1"), n1, n2)
(中略)
41: g
42: }
43: }
13行目で、VisualizationViewer[MyNode,MyEdge]クラスのインスタンスを作成してpanelとしています。マウスイベントを処理するオブジェクトはDefaultModalGraphMouse[V,E]クラスのインスタンスで、14行目で生成されています。15行目はマウスイベントの使い方を指定しています。ここではTRANSFORMINGを指定することで、マウスによって変形ができます。実際にはTRANSFORMINGはデフォルトなので、15行目は無くても構いません。16行目でVisualizationViewer[MyNode,MyEdge]クラスのインスタンスであるpanelにgmを設定しています。
上のプログラムを実行するとすると、たとえば下のようなグラフが描かれます。ウィンドウ内でマウスをドラッグすると、グラフがそのままの形で移動します。
下はマウスホイールによってグラフを縮小したところです。
下はShiftキーやMetaキーとともにマウスをドラッグしてグラフを変形したところです。
マウスイベントの使い方を変更すれば、マウスによる操作を変えることができます。上の例では、マウスイベントを処理するDefaultModalGraphMouse[V,E]クラスのインスタンスに、TRANSFORMINGを指定しましたが、PICKINGを指定することで、マウスでノードを掴んで移動することができます。
14: val gm = new DefaultModalGraphMouse[MyNode,MyEdge] 15: gm.setMode(ModalGraphMouse.Mode.PICKING) 16: panel.setGraphMouse(gm)
下の図は右下のノードをマウスで移動している様子です。マウスで掴んだノードは黄色に変っています。
マウスで移動中のノードの色を指定することもできます。
21: val pickedNodePaint: Transformer[MyNode,Paint] =
new PickableVertexPaintTransformer[MyNode](panel.getPickedVertexState,
Color.RED, Color.BLUE)
22: panel.getRenderContext.setVertexFillPaintTransformer(pickedNodePaint)
まず掴まれたノードの色を指定するTransformer[MyNode,Paint]型のオブジェクトを作成します。21行目では、掴まれていないノードを赤、掴まれているノードを青にしています。そしてそのオブジェクトをsetVertexFillPaintTransformer()メソッドで設定しています。
下の図は右下のノードをマウスで移動している様子です。マウスで掴んだノードが青色に変っています。
ノードをマウスでポイントしたときに、ツールチップを表示させることもできます。
setVertexToolTipTransformer()メソッドで、ノードから文字列への写像を設定すると、ノードをマウスでポイントした際にノードに対応する文字列が表示されます。
15: val gm = new DefaultModalGraphMouse[MyNode,MyEdge] 16: panel.setGraphMouse(gm) 17: panel.setVertexToolTipTransformer(new ToStringLabeller[MyNode])
下の図は右下のノードをマウスでポイントしたところです。ノードのラベル「n3」がツールチップで表示されています(スクリーンをキャプチャした際にマウスポインタは消えてしまいました)。
下のように、Transformer[MyNode,String]型のオブジェクトで、ノードから文字列への写像を定義し、その写像をsetVertexToolTipTransformer()メソッドで指定することで、toString()メソッドで返される文字列だけでなく、独自に定義した文字列をツールチップで表示することもできます。
17: val pointedNodeNote = new Transformer[MyNode,String] {
18: override def transform(n: MyNode): String = "annotation of " + n.label
19: }
20: panel.setVertexToolTipTransformer(pointedNodeNote)
下の図は左上のノードをマウスでポイントしたところです。「annotation of n4」というツールチップが表示されています(スクリーンをキャプチャした際にマウスポインタは消えてしまいました)。