1
2
3
4
5
6
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.AffineTransform;
24 import java.awt.geom.Ellipse2D;
25 import java.awt.geom.Point2D;
26
27 import javax.swing.BorderFactory;
28 import javax.swing.JApplet;
29 import javax.swing.JButton;
30 import javax.swing.JComboBox;
31 import javax.swing.JFrame;
32 import javax.swing.JPanel;
33 import javax.swing.JRadioButton;
34 import javax.swing.JToggleButton;
35
36 import org.apache.commons.collections15.Factory;
37 import org.apache.commons.collections15.functors.ConstantTransformer;
38
39 import edu.uci.ics.jung.algorithms.layout.BalloonLayout;
40 import edu.uci.ics.jung.algorithms.layout.TreeLayout;
41 import edu.uci.ics.jung.graph.DirectedGraph;
42 import edu.uci.ics.jung.graph.DirectedSparseMultigraph;
43 import edu.uci.ics.jung.graph.Forest;
44 import edu.uci.ics.jung.graph.DelegateForest;
45 import edu.uci.ics.jung.graph.DelegateTree;
46 import edu.uci.ics.jung.graph.Tree;
47 import edu.uci.ics.jung.visualization.GraphZoomScrollPane;
48 import edu.uci.ics.jung.visualization.Layer;
49 import edu.uci.ics.jung.visualization.VisualizationServer;
50 import edu.uci.ics.jung.visualization.VisualizationViewer;
51 import edu.uci.ics.jung.visualization.control.CrossoverScalingControl;
52 import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
53 import edu.uci.ics.jung.visualization.control.ModalGraphMouse;
54 import edu.uci.ics.jung.visualization.control.ModalLensGraphMouse;
55 import edu.uci.ics.jung.visualization.control.ScalingControl;
56 import edu.uci.ics.jung.visualization.decorators.EdgeShape;
57 import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
58 import edu.uci.ics.jung.visualization.layout.LayoutTransition;
59 import edu.uci.ics.jung.visualization.transform.LensSupport;
60 import edu.uci.ics.jung.visualization.transform.MutableTransformer;
61 import edu.uci.ics.jung.visualization.transform.MutableTransformerDecorator;
62 import edu.uci.ics.jung.visualization.transform.shape.HyperbolicShapeTransformer;
63 import edu.uci.ics.jung.visualization.transform.shape.ViewLensSupport;
64 import edu.uci.ics.jung.visualization.util.Animator;
65
66
67
68
69
70
71
72
73
74 @SuppressWarnings("serial")
75 public class BalloonLayoutDemo extends JApplet {
76
77
78
79
80 Forest<String,Integer> graph;
81
82 Factory<DirectedGraph<String,Integer>> graphFactory =
83 new Factory<DirectedGraph<String,Integer>>() {
84
85 public DirectedGraph<String, Integer> create() {
86 return new DirectedSparseMultigraph<String,Integer>();
87 }
88 };
89
90 Factory<Tree<String,Integer>> treeFactory =
91 new Factory<Tree<String,Integer>> () {
92
93 public Tree<String, Integer> create() {
94 return new DelegateTree<String,Integer>(graphFactory);
95 }
96 };
97
98 Factory<Integer> edgeFactory = new Factory<Integer>() {
99 int i=0;
100 public Integer create() {
101 return i++;
102 }};
103
104 Factory<String> vertexFactory = new Factory<String>() {
105 int i=0;
106 public String create() {
107 return "V"+i++;
108 }};
109
110
111
112
113 VisualizationViewer<String,Integer> vv;
114
115 VisualizationServer.Paintable rings;
116
117 String root;
118
119 TreeLayout<String,Integer> layout;
120
121 BalloonLayout<String,Integer> radialLayout;
122
123
124
125 LensSupport hyperbolicViewSupport;
126
127 public BalloonLayoutDemo() {
128
129
130 graph = new DelegateForest<String,Integer>();
131
132 createTree();
133
134 layout = new TreeLayout<String,Integer>(graph);
135 radialLayout = new BalloonLayout<String,Integer>(graph);
136 radialLayout.setSize(new Dimension(900,900));
137 vv = new VisualizationViewer<String,Integer>(layout, new Dimension(600,600));
138 vv.setBackground(Color.white);
139 vv.getRenderContext().setEdgeShapeTransformer(new EdgeShape.Line());
140 vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller());
141
142 vv.setVertexToolTipTransformer(new ToStringLabeller());
143 vv.getRenderContext().setArrowFillPaintTransformer(new ConstantTransformer(Color.lightGray));
144 rings = new Rings(radialLayout);
145
146 Container content = getContentPane();
147 final GraphZoomScrollPane panel = new GraphZoomScrollPane(vv);
148 content.add(panel);
149
150 final DefaultModalGraphMouse graphMouse = new DefaultModalGraphMouse();
151
152 vv.setGraphMouse(graphMouse);
153 vv.addKeyListener(graphMouse.getModeKeyListener());
154
155 hyperbolicViewSupport =
156 new ViewLensSupport<String,Integer>(vv, new HyperbolicShapeTransformer(vv,
157 vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.VIEW)),
158 new ModalLensGraphMouse());
159
160
161 graphMouse.addItemListener(hyperbolicViewSupport.getGraphMouse().getModeListener());
162
163 JComboBox modeBox = graphMouse.getModeComboBox();
164 modeBox.addItemListener(graphMouse.getModeListener());
165 graphMouse.setMode(ModalGraphMouse.Mode.TRANSFORMING);
166
167 final ScalingControl scaler = new CrossoverScalingControl();
168
169 vv.scaleToLayout(scaler);
170
171 JButton plus = new JButton("+");
172 plus.addActionListener(new ActionListener() {
173 public void actionPerformed(ActionEvent e) {
174 scaler.scale(vv, 1.1f, vv.getCenter());
175 }
176 });
177 JButton minus = new JButton("-");
178 minus.addActionListener(new ActionListener() {
179 public void actionPerformed(ActionEvent e) {
180 scaler.scale(vv, 1/1.1f, vv.getCenter());
181 }
182 });
183
184 JToggleButton radial = new JToggleButton("Balloon");
185 radial.addItemListener(new ItemListener() {
186
187 public void itemStateChanged(ItemEvent e) {
188 if(e.getStateChange() == ItemEvent.SELECTED) {
189
190 LayoutTransition<String,Integer> lt =
191 new LayoutTransition<String,Integer>(vv, layout, radialLayout);
192 Animator animator = new Animator(lt);
193 animator.start();
194 vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT).setToIdentity();
195 vv.addPreRenderPaintable(rings);
196 } else {
197
198 LayoutTransition<String,Integer> lt =
199 new LayoutTransition<String,Integer>(vv, radialLayout, layout);
200 Animator animator = new Animator(lt);
201 animator.start();
202 vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT).setToIdentity();
203 vv.removePreRenderPaintable(rings);
204 }
205 vv.repaint();
206 }});
207 final JRadioButton hyperView = new JRadioButton("Hyperbolic View");
208 hyperView.addItemListener(new ItemListener(){
209 public void itemStateChanged(ItemEvent e) {
210 hyperbolicViewSupport.activate(e.getStateChange() == ItemEvent.SELECTED);
211 }
212 });
213
214 JPanel scaleGrid = new JPanel(new GridLayout(1,0));
215 scaleGrid.setBorder(BorderFactory.createTitledBorder("Zoom"));
216
217 JPanel controls = new JPanel();
218 scaleGrid.add(plus);
219 scaleGrid.add(minus);
220 controls.add(radial);
221 controls.add(scaleGrid);
222 controls.add(modeBox);
223 controls.add(hyperView);
224 content.add(controls, BorderLayout.SOUTH);
225 }
226
227 class Rings implements VisualizationServer.Paintable {
228
229 BalloonLayout<String,Integer> layout;
230
231 public Rings(BalloonLayout<String,Integer> layout) {
232 this.layout = layout;
233 }
234
235 public void paint(Graphics g) {
236 g.setColor(Color.gray);
237
238 Graphics2D g2d = (Graphics2D)g;
239
240 Ellipse2D ellipse = new Ellipse2D.Double();
241 for(String v : layout.getGraph().getVertices()) {
242 Double radius = layout.getRadii().get(v);
243 if(radius == null) continue;
244 Point2D p = layout.transform(v);
245 ellipse.setFrame(-radius, -radius, 2*radius, 2*radius);
246 AffineTransform at = AffineTransform.getTranslateInstance(p.getX(), p.getY());
247 Shape shape = at.createTransformedShape(ellipse);
248
249 MutableTransformer viewTransformer =
250 vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.VIEW);
251
252 if(viewTransformer instanceof MutableTransformerDecorator) {
253 shape = vv.getRenderContext().getMultiLayerTransformer().transform(shape);
254 } else {
255 shape = vv.getRenderContext().getMultiLayerTransformer().transform(Layer.LAYOUT,shape);
256 }
257
258 g2d.draw(shape);
259 }
260 }
261
262 public boolean useTransform() {
263 return true;
264 }
265 }
266
267
268
269
270 private void createTree() {
271
272 graph.addVertex("A0");
273 graph.addEdge(edgeFactory.create(), "A0", "B0");
274 graph.addEdge(edgeFactory.create(), "A0", "B1");
275 graph.addEdge(edgeFactory.create(), "A0", "B2");
276
277 graph.addEdge(edgeFactory.create(), "B0", "C0");
278 graph.addEdge(edgeFactory.create(), "B0", "C1");
279 graph.addEdge(edgeFactory.create(), "B0", "C2");
280 graph.addEdge(edgeFactory.create(), "B0", "C3");
281
282 graph.addEdge(edgeFactory.create(), "C2", "H0");
283 graph.addEdge(edgeFactory.create(), "C2", "H1");
284
285 graph.addEdge(edgeFactory.create(), "B1", "D0");
286 graph.addEdge(edgeFactory.create(), "B1", "D1");
287 graph.addEdge(edgeFactory.create(), "B1", "D2");
288
289 graph.addEdge(edgeFactory.create(), "B2", "E0");
290 graph.addEdge(edgeFactory.create(), "B2", "E1");
291 graph.addEdge(edgeFactory.create(), "B2", "E2");
292
293 graph.addEdge(edgeFactory.create(), "D0", "F0");
294 graph.addEdge(edgeFactory.create(), "D0", "F1");
295 graph.addEdge(edgeFactory.create(), "D0", "F2");
296
297 graph.addEdge(edgeFactory.create(), "D1", "G0");
298 graph.addEdge(edgeFactory.create(), "D1", "G1");
299 graph.addEdge(edgeFactory.create(), "D1", "G2");
300 graph.addEdge(edgeFactory.create(), "D1", "G3");
301 graph.addEdge(edgeFactory.create(), "D1", "G4");
302 graph.addEdge(edgeFactory.create(), "D1", "G5");
303 graph.addEdge(edgeFactory.create(), "D1", "G6");
304 graph.addEdge(edgeFactory.create(), "D1", "G7");
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324 }
325
326
327
328
329 public static void main(String[] args) {
330 JFrame frame = new JFrame();
331 Container content = frame.getContentPane();
332 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
333
334 content.add(new BalloonLayoutDemo());
335 frame.pack();
336 frame.setVisible(true);
337 }
338 }