View Javadoc

1   /*
2    * Copyright (c) 2003, the JUNG Project and the Regents of the University of
3    * California All rights reserved.
4    * 
5    * This software is open-source under the BSD license; see either "license.txt"
6    * or http://jung.sourceforge.net/license.txt 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.Dimension;
15  import java.awt.Graphics;
16  import java.awt.Graphics2D;
17  import java.awt.GridLayout;
18  import java.awt.Shape;
19  import java.awt.event.ActionEvent;
20  import java.awt.event.ActionListener;
21  import java.awt.event.ItemEvent;
22  import java.awt.event.ItemListener;
23  import java.awt.geom.Ellipse2D;
24  import java.awt.geom.Point2D;
25  import java.util.Collection;
26  import java.util.HashSet;
27  import java.util.Map;
28  import java.util.Set;
29  
30  import javax.swing.BorderFactory;
31  import javax.swing.JApplet;
32  import javax.swing.JButton;
33  import javax.swing.JComboBox;
34  import javax.swing.JFrame;
35  import javax.swing.JPanel;
36  import javax.swing.JToggleButton;
37  
38  import org.apache.commons.collections15.Factory;
39  import org.apache.commons.collections15.functors.ConstantTransformer;
40  
41  import edu.uci.ics.jung.algorithms.layout.Layout;
42  import edu.uci.ics.jung.algorithms.layout.PolarPoint;
43  import edu.uci.ics.jung.algorithms.layout.RadialTreeLayout;
44  import edu.uci.ics.jung.algorithms.layout.TreeLayout;
45  import edu.uci.ics.jung.graph.DirectedGraph;
46  import edu.uci.ics.jung.graph.DirectedSparseMultigraph;
47  import edu.uci.ics.jung.graph.Forest;
48  import edu.uci.ics.jung.graph.DelegateForest;
49  import edu.uci.ics.jung.graph.DelegateTree;
50  import edu.uci.ics.jung.graph.Tree;
51  import edu.uci.ics.jung.visualization.GraphZoomScrollPane;
52  import edu.uci.ics.jung.visualization.Layer;
53  import edu.uci.ics.jung.visualization.VisualizationServer;
54  import edu.uci.ics.jung.visualization.VisualizationViewer;
55  import edu.uci.ics.jung.visualization.control.CrossoverScalingControl;
56  import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
57  import edu.uci.ics.jung.visualization.control.ModalGraphMouse;
58  import edu.uci.ics.jung.visualization.control.ScalingControl;
59  import edu.uci.ics.jung.visualization.decorators.EdgeShape;
60  import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
61  import edu.uci.ics.jung.visualization.layout.LayoutTransition;
62  import edu.uci.ics.jung.visualization.util.Animator;
63  
64  /**
65   * A variant of TreeLayoutDemo that rotates the view by 90 degrees from the 
66   * default orientation.
67   * @author Tom Nelson
68   * 
69   */
70  @SuppressWarnings("serial")
71  public class L2RTreeLayoutDemo extends JApplet {
72  
73      /**
74       * the graph
75       */
76      Forest<String,Integer> graph;
77      
78      Factory<DirectedGraph<String,Integer>> graphFactory = 
79      	new Factory<DirectedGraph<String,Integer>>() {
80  
81  			public DirectedGraph<String, Integer> create() {
82  				return new DirectedSparseMultigraph<String,Integer>();
83  			}
84  		};
85  			
86  	Factory<Tree<String,Integer>> treeFactory =
87  		new Factory<Tree<String,Integer>> () {
88  
89  		public Tree<String, Integer> create() {
90  			return new DelegateTree<String,Integer>(graphFactory);
91  		}
92  	};
93  	
94  	Factory<Integer> edgeFactory = new Factory<Integer>() {
95  		int i=0;
96  		public Integer create() {
97  			return i++;
98  		}};
99      
100     Factory<String> vertexFactory = new Factory<String>() {
101     	int i=0;
102 		public String create() {
103 			return "V"+i++;
104 		}};
105 
106     /**
107      * the visual component and renderer for the graph
108      */
109     VisualizationViewer<String,Integer> vv;
110     
111     VisualizationServer.Paintable rings;
112     
113     String root;
114     
115     TreeLayout<String,Integer> treeLayout;
116     
117     RadialTreeLayout<String,Integer> radialLayout;
118 
119     public L2RTreeLayoutDemo() {
120         
121         // create a simple graph for the demo
122         graph = new DelegateForest<String,Integer>();
123 
124         createTree();
125         
126         treeLayout = new TreeLayout<String,Integer>(graph);
127         radialLayout = new RadialTreeLayout<String,Integer>(graph);
128         radialLayout.setSize(new Dimension(600,600));
129         vv =  new VisualizationViewer<String,Integer>(treeLayout, new Dimension(600,600));
130         vv.setBackground(Color.white);
131         vv.getRenderContext().setEdgeShapeTransformer(new EdgeShape.Line());
132         vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller());
133         // add a listener for ToolTips
134         vv.setVertexToolTipTransformer(new ToStringLabeller());
135         vv.getRenderContext().setArrowFillPaintTransformer(new ConstantTransformer(Color.lightGray));
136         rings = new Rings();
137         
138         setLtoR(vv);
139         
140         Container content = getContentPane();
141         final GraphZoomScrollPane panel = new GraphZoomScrollPane(vv);
142         content.add(panel);
143         
144         final DefaultModalGraphMouse graphMouse = new DefaultModalGraphMouse();
145 
146         vv.setGraphMouse(graphMouse);
147         
148         JComboBox modeBox = graphMouse.getModeComboBox();
149         modeBox.addItemListener(graphMouse.getModeListener());
150         graphMouse.setMode(ModalGraphMouse.Mode.TRANSFORMING);
151 
152         final ScalingControl scaler = new CrossoverScalingControl();
153 
154         JButton plus = new JButton("+");
155         plus.addActionListener(new ActionListener() {
156             public void actionPerformed(ActionEvent e) {
157                 scaler.scale(vv, 1.1f, vv.getCenter());
158             }
159         });
160         JButton minus = new JButton("-");
161         minus.addActionListener(new ActionListener() {
162             public void actionPerformed(ActionEvent e) {
163                 scaler.scale(vv, 1/1.1f, vv.getCenter());
164             }
165         });
166         
167         JToggleButton radial = new JToggleButton("Radial");
168         radial.addItemListener(new ItemListener() {
169 
170 			public void itemStateChanged(ItemEvent e) {
171 				if(e.getStateChange() == ItemEvent.SELECTED) {
172 					
173 					LayoutTransition<String,Integer> lt =
174 						new LayoutTransition<String,Integer>(vv, treeLayout, radialLayout);
175 					Animator animator = new Animator(lt);
176 					animator.start();
177 					vv.getRenderContext().getMultiLayerTransformer().setToIdentity();
178 					vv.addPreRenderPaintable(rings);
179 				} else {
180 					LayoutTransition<String,Integer> lt =
181 						new LayoutTransition<String,Integer>(vv, radialLayout, treeLayout);
182 					Animator animator = new Animator(lt);
183 					animator.start();
184 					vv.getRenderContext().getMultiLayerTransformer().setToIdentity();
185 					setLtoR(vv);
186 					vv.removePreRenderPaintable(rings);
187 				}
188 
189 				vv.repaint();
190 			}});
191 
192         JPanel scaleGrid = new JPanel(new GridLayout(1,0));
193         scaleGrid.setBorder(BorderFactory.createTitledBorder("Zoom"));
194 
195         JPanel controls = new JPanel();
196         scaleGrid.add(plus);
197         scaleGrid.add(minus);
198         controls.add(radial);
199         controls.add(scaleGrid);
200         controls.add(modeBox);
201 
202         content.add(controls, BorderLayout.SOUTH);
203     }
204     
205     private void setLtoR(VisualizationViewer<String,Integer> vv) {
206     	Layout<String,Integer> layout = vv.getModel().getGraphLayout();
207     	Dimension d = layout.getSize();
208     	Point2D center = new Point2D.Double(d.width/2, d.height/2);
209     	vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT).rotate(-Math.PI/2, center);
210     }
211     
212     class Rings implements VisualizationServer.Paintable {
213     	
214     	Collection<Double> depths;
215     	
216     	public Rings() {
217     		depths = getDepths();
218     	}
219     	
220     	private Collection<Double> getDepths() {
221     		Set<Double> depths = new HashSet<Double>();
222     		Map<String,PolarPoint> polarLocations = radialLayout.getPolarLocations();
223     		for(String v : graph.getVertices()) {
224     			PolarPoint pp = polarLocations.get(v);
225     			depths.add(pp.getRadius());
226     		}
227     		return depths;
228     	}
229 
230 		public void paint(Graphics g) {
231 			g.setColor(Color.lightGray);
232 		
233 			Graphics2D g2d = (Graphics2D)g;
234 			Point2D center = radialLayout.getCenter();
235 
236 			Ellipse2D ellipse = new Ellipse2D.Double();
237 			for(double d : depths) {
238 				ellipse.setFrameFromDiagonal(center.getX()-d, center.getY()-d, 
239 						center.getX()+d, center.getY()+d);
240 				Shape shape = vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT).transform(ellipse);
241 				g2d.draw(shape);
242 			}
243 		}
244 
245 		public boolean useTransform() {
246 			return true;
247 		}
248     }
249     
250     /**
251      * 
252      */
253     private void createTree() {
254     	graph.addVertex("V0");
255     	graph.addEdge(edgeFactory.create(), "V0", "V1");
256     	graph.addEdge(edgeFactory.create(), "V0", "V2");
257     	graph.addEdge(edgeFactory.create(), "V1", "V4");
258     	graph.addEdge(edgeFactory.create(), "V2", "V3");
259     	graph.addEdge(edgeFactory.create(), "V2", "V5");
260     	graph.addEdge(edgeFactory.create(), "V4", "V6");
261     	graph.addEdge(edgeFactory.create(), "V4", "V7");
262     	graph.addEdge(edgeFactory.create(), "V3", "V8");
263     	graph.addEdge(edgeFactory.create(), "V6", "V9");
264     	graph.addEdge(edgeFactory.create(), "V4", "V10");
265     	
266        	graph.addVertex("A0");
267        	graph.addEdge(edgeFactory.create(), "A0", "A1");
268        	graph.addEdge(edgeFactory.create(), "A0", "A2");
269        	graph.addEdge(edgeFactory.create(), "A0", "A3");
270        	
271        	graph.addVertex("B0");
272     	graph.addEdge(edgeFactory.create(), "B0", "B1");
273     	graph.addEdge(edgeFactory.create(), "B0", "B2");
274     	graph.addEdge(edgeFactory.create(), "B1", "B4");
275     	graph.addEdge(edgeFactory.create(), "B2", "B3");
276     	graph.addEdge(edgeFactory.create(), "B2", "B5");
277     	graph.addEdge(edgeFactory.create(), "B4", "B6");
278     	graph.addEdge(edgeFactory.create(), "B4", "B7");
279     	graph.addEdge(edgeFactory.create(), "B3", "B8");
280     	graph.addEdge(edgeFactory.create(), "B6", "B9");
281        	
282     }
283 
284 
285     /**
286      * a driver for this demo
287      */
288     public static void main(String[] args) {
289         JFrame frame = new JFrame();
290         Container content = frame.getContentPane();
291         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
292 
293         content.add(new L2RTreeLayoutDemo());
294         frame.pack();
295         frame.setVisible(true);
296     }
297 }