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   
10  
11  package edu.uci.ics.jung.samples;
12  import java.awt.BorderLayout;
13  import java.awt.Color;
14  import java.awt.Dimension;
15  import java.awt.Font;
16  import java.awt.event.ActionEvent;
17  import java.awt.event.ActionListener;
18  import java.awt.event.ComponentAdapter;
19  import java.awt.event.ComponentEvent;
20  import java.util.Timer;
21  import java.util.TimerTask;
22  
23  import javax.swing.JButton;
24  import javax.swing.JFrame;
25  import javax.swing.JRootPane;
26  
27  import com.google.common.base.Functions;
28  
29  import edu.uci.ics.jung.algorithms.layout.AbstractLayout;
30  import edu.uci.ics.jung.algorithms.layout.FRLayout;
31  import edu.uci.ics.jung.algorithms.layout.Layout;
32  import edu.uci.ics.jung.algorithms.layout.SpringLayout;
33  import edu.uci.ics.jung.algorithms.layout.StaticLayout;
34  import edu.uci.ics.jung.algorithms.layout.util.Relaxer;
35  import edu.uci.ics.jung.algorithms.layout.util.VisRunner;
36  import edu.uci.ics.jung.algorithms.util.IterativeContext;
37  import edu.uci.ics.jung.graph.DirectedSparseMultigraph;
38  import edu.uci.ics.jung.graph.Graph;
39  import edu.uci.ics.jung.graph.ObservableGraph;
40  import edu.uci.ics.jung.graph.event.GraphEvent;
41  import edu.uci.ics.jung.graph.event.GraphEventListener;
42  import edu.uci.ics.jung.graph.util.Graphs;
43  import edu.uci.ics.jung.visualization.VisualizationViewer;
44  import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
45  import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
46  import edu.uci.ics.jung.visualization.layout.LayoutTransition;
47  import edu.uci.ics.jung.visualization.renderers.Renderer;
48  import edu.uci.ics.jung.visualization.util.Animator;
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());
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             public void actionPerformed(ActionEvent ae) {
132             	Dimension d = vv.getSize();//new Dimension(600,600);
133                 if (switchLayout.getText().indexOf("Spring") > 0) {
134                     switchLayout.setText("Switch to FRLayout");
135                     layout =
136                     	new SpringLayout<Number,Number>(g, Functions.constant(EDGE_LENGTH));
137                     layout.setSize(d);
138             		Relaxer relaxer = new VisRunner((IterativeContext)layout);
139             		relaxer.stop();
140             		relaxer.prerelax();
141             		StaticLayout<Number,Number> staticLayout =
142             			new StaticLayout<Number,Number>(g, layout);
143     				LayoutTransition<Number,Number> lt =
144     					new LayoutTransition<Number,Number>(vv, vv.getGraphLayout(),
145     							staticLayout);
146     				Animator animator = new Animator(lt);
147     				animator.start();
148     				vv.repaint();
149 
150                 } else {
151                     switchLayout.setText("Switch to SpringLayout");
152                     layout = new FRLayout<Number,Number>(g, d);
153                     layout.setSize(d);
154             		Relaxer relaxer = new VisRunner((IterativeContext)layout);
155             		relaxer.stop();
156             		relaxer.prerelax();
157             		StaticLayout<Number,Number> staticLayout =
158             			new StaticLayout<Number,Number>(g, layout);
159     				LayoutTransition<Number,Number> lt =
160     					new LayoutTransition<Number,Number>(vv, vv.getGraphLayout(),
161     							staticLayout);
162     				Animator animator = new Animator(lt);
163     				animator.start();
164     				vv.repaint();
165 
166                 }
167             }
168         });
169 
170         getContentPane().add(switchLayout, BorderLayout.SOUTH);
171 
172         timer = new Timer();
173     }
174 
175     @Override
176     public void start() {
177         validate();
178         //set timer so applet will change
179         timer.schedule(new RemindTask(), 1000, 1000); //subsequent rate
180         vv.repaint();
181     }
182 
183     Integer v_prev = null;
184 
185     public void process() {
186 
187     	vv.getRenderContext().getPickedVertexState().clear();
188     	vv.getRenderContext().getPickedEdgeState().clear();
189         try {
190 
191             if (g.getVertexCount() < 100) {
192                 //add a vertex
193                 Integer v1 = new Integer(g.getVertexCount());
194 
195                 g.addVertex(v1);
196                 vv.getRenderContext().getPickedVertexState().pick(v1, true);
197 
198                 // wire it to some edges
199                 if (v_prev != null) {
200                 	Integer edge = g.getEdgeCount();
201                 	vv.getRenderContext().getPickedEdgeState().pick(edge, true);
202                     g.addEdge(edge, v_prev, v1);
203                     // let's connect to a random vertex, too!
204                     int rand = (int) (Math.random() * g.getVertexCount());
205                     edge = g.getEdgeCount();
206                 	vv.getRenderContext().getPickedEdgeState().pick(edge, true);
207                    g.addEdge(edge, v1, rand);
208                 }
209 
210                 v_prev = v1;
211 
212                 layout.initialize();
213 
214         		Relaxer relaxer = new VisRunner((IterativeContext)layout);
215         		relaxer.stop();
216         		relaxer.prerelax();
217         		StaticLayout<Number,Number> staticLayout =
218         			new StaticLayout<Number,Number>(g, layout);
219 				LayoutTransition<Number,Number> lt =
220 					new LayoutTransition<Number,Number>(vv, vv.getGraphLayout(),
221 							staticLayout);
222 				Animator animator = new Animator(lt);
223 				animator.start();
224 //				vv.getRenderContext().getMultiLayerTransformer().setToIdentity();
225 				vv.repaint();
226 
227             } else {
228             	done = true;
229             }
230 
231         } catch (Exception e) {
232             System.out.println(e);
233 
234         }
235     }
236 
237     class RemindTask extends TimerTask {
238 
239         @Override
240         public void run() {
241             process();
242             if(done) cancel();
243 
244         }
245     }
246 
247     public static void main(String[] args) {
248     	AnimatingAddNodeDemo and = new AnimatingAddNodeDemo();
249     	JFrame frame = new JFrame();
250     	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
251     	frame.getContentPane().add(and);
252 
253     	and.init();
254     	and.start();
255     	frame.pack();
256     	frame.setVisible(true);
257     }
258 }