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   
10  
11  package edu.uci.ics.jung.samples;
12  import edu.uci.ics.jung.algorithms.layout.AbstractLayout;
13  import edu.uci.ics.jung.algorithms.layout.FRLayout;
14  import edu.uci.ics.jung.algorithms.layout.Layout;
15  import edu.uci.ics.jung.algorithms.layout.SpringLayout;
16  import edu.uci.ics.jung.algorithms.layout.StaticLayout;
17  import edu.uci.ics.jung.algorithms.layout.util.Relaxer;
18  import edu.uci.ics.jung.algorithms.layout.util.VisRunner;
19  import edu.uci.ics.jung.algorithms.util.IterativeContext;
20  import edu.uci.ics.jung.graph.DirectedSparseMultigraph;
21  import edu.uci.ics.jung.graph.Graph;
22  import edu.uci.ics.jung.graph.ObservableGraph;
23  import edu.uci.ics.jung.graph.event.GraphEvent;
24  import edu.uci.ics.jung.graph.event.GraphEventListener;
25  import edu.uci.ics.jung.graph.util.Graphs;
26  import edu.uci.ics.jung.visualization.VisualizationViewer;
27  import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
28  import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
29  import edu.uci.ics.jung.visualization.layout.LayoutTransition;
30  import edu.uci.ics.jung.visualization.renderers.Renderer;
31  import edu.uci.ics.jung.visualization.util.Animator;
32  
33  import org.apache.commons.collections15.functors.ConstantTransformer;
34  
35  import java.awt.BorderLayout;
36  import java.awt.Color;
37  import java.awt.Dimension;
38  import java.awt.Font;
39  import java.awt.event.ActionEvent;
40  import java.awt.event.ActionListener;
41  import java.awt.event.ComponentAdapter;
42  import java.awt.event.ComponentEvent;
43  import java.util.Timer;
44  import java.util.TimerTask;
45  
46  import javax.swing.JButton;
47  import javax.swing.JFrame;
48  import javax.swing.JRootPane;
49  
50  /**
51   * A variation of AddNodeDemo that animates transitions between graph states.
52   *
53   * @author Tom Nelson
54   */
55  public class AnimatingAddNodeDemo extends javax.swing.JApplet {
56  
57      /**
58  	 *
59  	 */
60  	private static final long serialVersionUID = -5345319851341875800L;
61  
62  	private Graph<Number,Number> g = null;
63  
64      private VisualizationViewer<Number,Number> vv = null;
65  
66      private AbstractLayout<Number,Number> layout = null;
67  
68      Timer timer;
69  
70      boolean done;
71  
72      protected JButton switchLayout;
73  
74      public static final int EDGE_LENGTH = 100;
75  
76      @Override
77      public void init() {
78  
79          //create a graph
80      	Graph<Number,Number> ig = Graphs.<Number,Number>synchronizedDirectedGraph(new DirectedSparseMultigraph<Number,Number>());
81  
82          ObservableGraph<Number,Number> og = new ObservableGraph<Number,Number>(ig);
83          og.addGraphEventListener(new GraphEventListener<Number,Number>() {
84  
85  			public void handleGraphEvent(GraphEvent<Number, Number> evt) {
86  				System.err.println("got "+evt);
87  
88  			}});
89          this.g = og;
90          //create a graphdraw
91          layout = new FRLayout<Number,Number>(g);
92          layout.setSize(new Dimension(600,600));
93  		Relaxer relaxer = new VisRunner((IterativeContext)layout);
94  		relaxer.stop();
95  		relaxer.prerelax();
96  
97  		Layout<Number,Number> staticLayout =
98  			new StaticLayout<Number,Number>(g, layout);
99  
100         vv = new VisualizationViewer<Number,Number>(staticLayout, new Dimension(600,600));
101 
102         JRootPane rp = this.getRootPane();
103         rp.putClientProperty("defeatSystemEventQueueCheck", Boolean.TRUE);
104 
105         getContentPane().setLayout(new BorderLayout());
106         getContentPane().setBackground(java.awt.Color.lightGray);
107         getContentPane().setFont(new Font("Serif", Font.PLAIN, 12));
108 
109         vv.setGraphMouse(new DefaultModalGraphMouse<Number,Number>());
110 
111         vv.getRenderer().getVertexLabelRenderer().setPosition(Renderer.VertexLabel.Position.CNTR);
112         vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller<Number>());
113         vv.setForeground(Color.white);
114 
115         vv.addComponentListener(new ComponentAdapter() {
116 
117 			/**
118 			 * @see java.awt.event.ComponentAdapter#componentResized(java.awt.event.ComponentEvent)
119 			 */
120 			@Override
121 			public void componentResized(ComponentEvent arg0) {
122 				super.componentResized(arg0);
123 				System.err.println("resized");
124 				layout.setSize(arg0.getComponent().getSize());
125 			}});
126 
127         getContentPane().add(vv);
128         switchLayout = new JButton("Switch to SpringLayout");
129         switchLayout.addActionListener(new ActionListener() {
130 
131             @SuppressWarnings("unchecked")
132             public void actionPerformed(ActionEvent ae) {
133             	Dimension d = vv.getSize();//new Dimension(600,600);
134                 if (switchLayout.getText().indexOf("Spring") > 0) {
135                     switchLayout.setText("Switch to FRLayout");
136                     layout =
137                     	new SpringLayout<Number,Number>(g, new ConstantTransformer(EDGE_LENGTH));
138                     layout.setSize(d);
139             		Relaxer relaxer = new VisRunner((IterativeContext)layout);
140             		relaxer.stop();
141             		relaxer.prerelax();
142             		StaticLayout<Number,Number> staticLayout =
143             			new StaticLayout<Number,Number>(g, layout);
144     				LayoutTransition<Number,Number> lt =
145     					new LayoutTransition<Number,Number>(vv, vv.getGraphLayout(),
146     							staticLayout);
147     				Animator animator = new Animator(lt);
148     				animator.start();
149     			//	vv.getRenderContext().getMultiLayerTransformer().setToIdentity();
150     				vv.repaint();
151 
152                 } else {
153                     switchLayout.setText("Switch to SpringLayout");
154                     layout = new FRLayout<Number,Number>(g, d);
155                     layout.setSize(d);
156             		Relaxer relaxer = new VisRunner((IterativeContext)layout);
157             		relaxer.stop();
158             		relaxer.prerelax();
159             		StaticLayout<Number,Number> staticLayout =
160             			new StaticLayout<Number,Number>(g, layout);
161     				LayoutTransition<Number,Number> lt =
162     					new LayoutTransition<Number,Number>(vv, vv.getGraphLayout(),
163     							staticLayout);
164     				Animator animator = new Animator(lt);
165     				animator.start();
166     			//	vv.getRenderContext().getMultiLayerTransformer().setToIdentity();
167     				vv.repaint();
168 
169                 }
170             }
171         });
172 
173         getContentPane().add(switchLayout, BorderLayout.SOUTH);
174 
175         timer = new Timer();
176     }
177 
178     @Override
179     public void start() {
180         validate();
181         //set timer so applet will change
182         timer.schedule(new RemindTask(), 1000, 1000); //subsequent rate
183         vv.repaint();
184     }
185 
186     Integer v_prev = null;
187 
188     public void process() {
189 
190     	vv.getRenderContext().getPickedVertexState().clear();
191     	vv.getRenderContext().getPickedEdgeState().clear();
192         try {
193 
194             if (g.getVertexCount() < 100) {
195                 //add a vertex
196                 Integer v1 = new Integer(g.getVertexCount());
197 
198                 g.addVertex(v1);
199                 vv.getRenderContext().getPickedVertexState().pick(v1, true);
200 
201                 // wire it to some edges
202                 if (v_prev != null) {
203                 	Integer edge = g.getEdgeCount();
204                 	vv.getRenderContext().getPickedEdgeState().pick(edge, true);
205                     g.addEdge(edge, v_prev, v1);
206                     // let's connect to a random vertex, too!
207                     int rand = (int) (Math.random() * g.getVertexCount());
208                     edge = g.getEdgeCount();
209                 	vv.getRenderContext().getPickedEdgeState().pick(edge, true);
210                    g.addEdge(edge, v1, rand);
211                 }
212 
213                 v_prev = v1;
214 
215                 layout.initialize();
216 
217         		Relaxer relaxer = new VisRunner((IterativeContext)layout);
218         		relaxer.stop();
219         		relaxer.prerelax();
220         		StaticLayout<Number,Number> staticLayout =
221         			new StaticLayout<Number,Number>(g, layout);
222 				LayoutTransition<Number,Number> lt =
223 					new LayoutTransition<Number,Number>(vv, vv.getGraphLayout(),
224 							staticLayout);
225 				Animator animator = new Animator(lt);
226 				animator.start();
227 //				vv.getRenderContext().getMultiLayerTransformer().setToIdentity();
228 				vv.repaint();
229 
230             } else {
231             	done = true;
232             }
233 
234         } catch (Exception e) {
235             System.out.println(e);
236 
237         }
238     }
239 
240     class RemindTask extends TimerTask {
241 
242         @Override
243         public void run() {
244             process();
245             if(done) cancel();
246 
247         }
248     }
249 
250     public static void main(String[] args) {
251     	AnimatingAddNodeDemo and = new AnimatingAddNodeDemo();
252     	JFrame frame = new JFrame();
253     	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
254     	frame.getContentPane().add(and);
255 
256     	and.init();
257     	and.start();
258     	frame.pack();
259     	frame.setVisible(true);
260     }
261 }