View Javadoc
1   /*
2    * Copyright (c) 2003, The JUNG Authors
3    * All rights reserved.
4    * 
5    * This software is open-source under the BSD license; see either "license.txt"
6    * or https://github.com/jrtom/jung/blob/master/LICENSE for a description.
7    * 
8    */
9   package edu.uci.ics.jung.samples;
10  
11  import java.awt.BorderLayout;
12  import java.awt.Color;
13  import java.awt.Container;
14  import java.awt.event.ActionEvent;
15  import java.awt.event.ActionListener;
16  import java.awt.event.MouseEvent;
17  import java.io.IOException;
18  
19  import javax.swing.JButton;
20  import javax.swing.JFrame;
21  import javax.swing.JMenuBar;
22  import javax.swing.JPanel;
23  import javax.xml.parsers.ParserConfigurationException;
24  
25  import org.xml.sax.SAXException;
26  
27  import com.google.common.base.Function;
28  import com.google.common.base.Supplier;
29  
30  import edu.uci.ics.jung.algorithms.layout.FRLayout;
31  import edu.uci.ics.jung.graph.DirectedGraph;
32  import edu.uci.ics.jung.graph.DirectedSparseMultigraph;
33  import edu.uci.ics.jung.io.GraphMLReader;
34  import edu.uci.ics.jung.visualization.GraphZoomScrollPane;
35  import edu.uci.ics.jung.visualization.VisualizationViewer;
36  import edu.uci.ics.jung.visualization.control.AbstractModalGraphMouse;
37  import edu.uci.ics.jung.visualization.control.CrossoverScalingControl;
38  import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
39  import edu.uci.ics.jung.visualization.control.GraphMouseListener;
40  import edu.uci.ics.jung.visualization.control.ScalingControl;
41  import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
42  import edu.uci.ics.jung.visualization.renderers.GradientVertexRenderer;
43  import edu.uci.ics.jung.visualization.renderers.Renderer;
44  import edu.uci.ics.jung.visualization.renderers.BasicVertexLabelRenderer.InsidePositioner;
45  
46  
47  /**
48   * Demonstrates loading (and visualizing) a graph from a GraphML file.
49   * 
50   * @author Tom Nelson
51   * 
52   */
53  public class GraphFromGraphMLDemo {
54  
55      /**
56       * the visual component and renderer for the graph
57       */
58      VisualizationViewer<Number, Number> vv;
59      
60      /**
61       * Creates an instance showing a simple graph with controls to demonstrate the zoom features.
62       * @param filename the file containing the graph data we're reading
63       * @throws ParserConfigurationException if a SAX parser cannot be constructed
64       * @throws SAXException if the SAX parser factory cannot be constructed
65       * @throws IOException if the file cannot be read
66       */
67      public GraphFromGraphMLDemo(String filename) throws ParserConfigurationException, SAXException, IOException {
68          
69      	Supplier<Number> vertexFactory = new Supplier<Number>() {
70      		int n = 0;
71      		public Number get() { return n++; }
72      	};
73      	Supplier<Number> edgeFactory = new Supplier<Number>() {
74      		int n = 0;
75      		public Number get() { return n++; }
76      	};
77      	
78      	GraphMLReader<DirectedGraph<Number,Number>, Number, Number> gmlr = 
79      	    new GraphMLReader<DirectedGraph<Number,Number>, Number, Number>(vertexFactory, edgeFactory);
80      	final DirectedGraph<Number,Number> graph = new DirectedSparseMultigraph<Number,Number>();
81      	gmlr.load(filename, graph);
82      	
83          // create a simple graph for the demo
84          vv =  new VisualizationViewer<Number,Number>(new FRLayout<Number,Number>(graph));
85  
86          vv.addGraphMouseListener(new TestGraphMouseListener<Number>());
87          vv.getRenderer().setVertexRenderer(
88          		new GradientVertexRenderer<Number,Number>(
89          				Color.white, Color.red, 
90          				Color.white, Color.blue,
91          				vv.getPickedVertexState(),
92          				false));
93          
94          // add my listeners for ToolTips
95          vv.setVertexToolTipTransformer(new ToStringLabeller());
96          vv.setEdgeToolTipTransformer(new Function<Number,String>() {
97  			public String apply(Number edge) {
98  				return "E"+graph.getEndpoints(edge).toString();
99  			}});
100         
101         vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller());
102         vv.getRenderer().getVertexLabelRenderer().setPositioner(new InsidePositioner());
103         vv.getRenderer().getVertexLabelRenderer().setPosition(Renderer.VertexLabel.Position.AUTO);
104         
105         // create a frome to hold the graph
106         final JFrame frame = new JFrame();
107         Container content = frame.getContentPane();
108         final GraphZoomScrollPane panel = new GraphZoomScrollPane(vv);
109         content.add(panel);
110         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
111         final AbstractModalGraphMouse graphMouse = new DefaultModalGraphMouse<Number,Number>();
112         vv.setGraphMouse(graphMouse);
113         vv.addKeyListener(graphMouse.getModeKeyListener());
114 
115         JMenuBar menubar = new JMenuBar();
116         menubar.add(graphMouse.getModeMenu());
117         panel.setCorner(menubar);
118 
119         
120         vv.addKeyListener(graphMouse.getModeKeyListener());
121         vv.setToolTipText("<html><center>Type 'p' for Pick mode<p>Type 't' for Transform mode");
122         
123         final ScalingControl scaler = new CrossoverScalingControl();
124 
125         JButton plus = new JButton("+");
126         plus.addActionListener(new ActionListener() {
127             public void actionPerformed(ActionEvent e) {
128                 scaler.scale(vv, 1.1f, vv.getCenter());
129             }
130         });
131         JButton minus = new JButton("-");
132         minus.addActionListener(new ActionListener() {
133             public void actionPerformed(ActionEvent e) {
134                 scaler.scale(vv, 1/1.1f, vv.getCenter());
135             }
136         });
137 
138         JPanel controls = new JPanel();
139         controls.add(plus);
140         controls.add(minus);
141         content.add(controls, BorderLayout.SOUTH);
142 
143         frame.pack();
144         frame.setVisible(true);
145     }
146     
147     /**
148      * A nested class to demo the GraphMouseListener finding the
149      * right vertices after zoom/pan
150      */
151     static class TestGraphMouseListener<V> implements GraphMouseListener<V> {
152         
153     		public void graphClicked(V v, MouseEvent me) {
154     		    System.err.println("Vertex "+v+" was clicked at ("+me.getX()+","+me.getY()+")");
155     		}
156     		public void graphPressed(V v, MouseEvent me) {
157     		    System.err.println("Vertex "+v+" was pressed at ("+me.getX()+","+me.getY()+")");
158     		}
159     		public void graphReleased(V v, MouseEvent me) {
160     		    System.err.println("Vertex "+v+" was released at ("+me.getX()+","+me.getY()+")");
161     		}
162     }
163 
164     /**
165      * @param args if this contains at least one element, the first will be used as the file to read
166      * @throws ParserConfigurationException if a SAX parser cannot be constructed
167      * @throws SAXException if the SAX parser factory cannot be constructed
168      * @throws IOException if the file cannot be read
169      */
170     public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException 
171     {
172     	String filename = "simple.graphml";
173     	if(args.length > 0) filename = args[0];
174         new GraphFromGraphMLDemo(filename);
175     }
176 }