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.Font;
16 import java.awt.FontMetrics;
17 import java.awt.Graphics;
18 import java.awt.GridLayout;
19 import java.awt.Paint;
20 import java.awt.event.ActionEvent;
21 import java.awt.event.ActionListener;
22 import java.awt.event.ItemEvent;
23 import java.awt.event.ItemListener;
24 import java.util.HashMap;
25 import java.util.Map;
26
27 import javax.swing.BorderFactory;
28 import javax.swing.ButtonGroup;
29 import javax.swing.Icon;
30 import javax.swing.ImageIcon;
31 import javax.swing.JApplet;
32 import javax.swing.JButton;
33 import javax.swing.JComboBox;
34 import javax.swing.JFrame;
35 import javax.swing.JMenu;
36 import javax.swing.JMenuBar;
37 import javax.swing.JPanel;
38 import javax.swing.JRadioButton;
39
40 import org.apache.commons.collections15.Transformer;
41
42 import edu.uci.ics.jung.algorithms.layout.FRLayout;
43 import edu.uci.ics.jung.graph.DirectedSparseGraph;
44 import edu.uci.ics.jung.graph.util.EdgeType;
45 import edu.uci.ics.jung.visualization.GraphZoomScrollPane;
46 import edu.uci.ics.jung.visualization.LayeredIcon;
47 import edu.uci.ics.jung.visualization.VisualizationViewer;
48 import edu.uci.ics.jung.visualization.control.CrossoverScalingControl;
49 import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
50 import edu.uci.ics.jung.visualization.control.ScalingControl;
51 import edu.uci.ics.jung.visualization.decorators.DefaultVertexIconTransformer;
52 import edu.uci.ics.jung.visualization.decorators.EllipseVertexShapeTransformer;
53 import edu.uci.ics.jung.visualization.decorators.PickableEdgePaintTransformer;
54 import edu.uci.ics.jung.visualization.decorators.PickableVertexPaintTransformer;
55 import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
56 import edu.uci.ics.jung.visualization.decorators.VertexIconShapeTransformer;
57 import edu.uci.ics.jung.visualization.picking.PickedState;
58 import edu.uci.ics.jung.visualization.renderers.Checkmark;
59 import edu.uci.ics.jung.visualization.renderers.DefaultEdgeLabelRenderer;
60 import edu.uci.ics.jung.visualization.renderers.DefaultVertexLabelRenderer;
61 import edu.uci.ics.jung.visualization.transform.LayoutLensSupport;
62 import edu.uci.ics.jung.visualization.transform.LensSupport;
63 import edu.uci.ics.jung.visualization.transform.shape.MagnifyImageLensSupport;
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86 public class LensVertexImageShaperDemo extends JApplet {
87
88
89
90
91 private static final long serialVersionUID = 5432239991020505763L;
92
93
94
95
96 DirectedSparseGraph<Number, Number> graph;
97
98
99
100
101 VisualizationViewer<Number,Number> vv;
102
103
104
105
106 String[] iconNames = {
107 "apple",
108 "os",
109 "x",
110 "linux",
111 "inputdevices",
112 "wireless",
113 "graphics3",
114 "gamespcgames",
115 "humor",
116 "music",
117 "privacy"
118 };
119
120 LensSupport viewSupport;
121 LensSupport modelSupport;
122 LensSupport magnifyLayoutSupport;
123 LensSupport magnifyViewSupport;
124
125
126
127
128
129 public LensVertexImageShaperDemo() {
130
131
132 graph = new DirectedSparseGraph<Number,Number>();
133 Number[] vertices = createVertices(11);
134
135
136 Map<Number,String> map = new HashMap<Number,String>();
137 for(int i=0; i<vertices.length; i++) {
138 map.put(vertices[i], iconNames[i%iconNames.length]);
139 }
140
141
142 Map<Number,Icon> iconMap = new HashMap<Number,Icon>();
143 for(int i=0; i<vertices.length; i++) {
144 String name = "/images/topic"+iconNames[i]+".gif";
145 try {
146 Icon icon =
147 new LayeredIcon(new ImageIcon(LensVertexImageShaperDemo.class.getResource(name)).getImage());
148 iconMap.put(vertices[i], icon);
149 } catch(Exception ex) {
150 System.err.println("You need slashdoticons.jar in your classpath to see the image "+name);
151 }
152 }
153
154 createEdges(vertices);
155
156 FRLayout<Number, Number> layout = new FRLayout<Number, Number>(graph);
157 layout.setMaxIterations(100);
158 vv = new VisualizationViewer<Number, Number>(layout, new Dimension(600,600));
159
160 Transformer<Number,Paint> vpf =
161 new PickableVertexPaintTransformer<Number>(vv.getPickedVertexState(), Color.white, Color.yellow);
162 vv.getRenderContext().setVertexFillPaintTransformer(vpf);
163 vv.getRenderContext().setEdgeDrawPaintTransformer(new PickableEdgePaintTransformer<Number>(vv.getPickedEdgeState(), Color.black, Color.cyan));
164
165 vv.setBackground(Color.white);
166
167 final Transformer<Number,String> vertexStringerImpl =
168 new VertexStringerImpl<Number>(map);
169 vv.getRenderContext().setVertexLabelTransformer(vertexStringerImpl);
170 vv.getRenderContext().setVertexLabelRenderer(new DefaultVertexLabelRenderer(Color.cyan));
171 vv.getRenderContext().setEdgeLabelRenderer(new DefaultEdgeLabelRenderer(Color.cyan));
172
173
174
175 final VertexIconShapeTransformer<Number> vertexImageShapeFunction =
176 new VertexIconShapeTransformer<Number>(new EllipseVertexShapeTransformer<Number>());
177
178 final DefaultVertexIconTransformer<Number> vertexIconFunction =
179 new DefaultVertexIconTransformer<Number>();
180
181 vertexImageShapeFunction.setIconMap(iconMap);
182 vertexIconFunction.setIconMap(iconMap);
183
184 vv.getRenderContext().setVertexShapeTransformer(vertexImageShapeFunction);
185 vv.getRenderContext().setVertexIconTransformer(vertexIconFunction);
186
187
188
189
190 PickedState<Number> ps = vv.getPickedVertexState();
191 ps.addItemListener(new PickWithIconListener(vertexIconFunction));
192
193 vv.addPostRenderPaintable(new VisualizationViewer.Paintable(){
194 int x;
195 int y;
196 Font font;
197 FontMetrics metrics;
198 int swidth;
199 int sheight;
200 String str = "Thank You, slashdot.org, for the images!";
201
202 public void paint(Graphics g) {
203 Dimension d = vv.getSize();
204 if(font == null) {
205 font = new Font(g.getFont().getName(), Font.BOLD, 20);
206 metrics = g.getFontMetrics(font);
207 swidth = metrics.stringWidth(str);
208 sheight = metrics.getMaxAscent()+metrics.getMaxDescent();
209 x = (d.width-swidth)/2;
210 y = (int)(d.height-sheight*1.5);
211 }
212 g.setFont(font);
213 Color oldColor = g.getColor();
214 g.setColor(Color.lightGray);
215 g.drawString(str, x, y);
216 g.setColor(oldColor);
217 }
218 public boolean useTransform() {
219 return false;
220 }
221 });
222
223
224 vv.setVertexToolTipTransformer(new ToStringLabeller<Number>());
225
226 Container content = getContentPane();
227 final GraphZoomScrollPane panel = new GraphZoomScrollPane(vv);
228 content.add(panel);
229
230 final DefaultModalGraphMouse graphMouse = new DefaultModalGraphMouse();
231 vv.setGraphMouse(graphMouse);
232
233
234 final ScalingControl scaler = new CrossoverScalingControl();
235
236 JButton plus = new JButton("+");
237 plus.addActionListener(new ActionListener() {
238 public void actionPerformed(ActionEvent e) {
239 scaler.scale(vv, 1.1f, vv.getCenter());
240 }
241 });
242 JButton minus = new JButton("-");
243 minus.addActionListener(new ActionListener() {
244 public void actionPerformed(ActionEvent e) {
245 scaler.scale(vv, 1/1.1f, vv.getCenter());
246 }
247 });
248
249 JComboBox modeBox = graphMouse.getModeComboBox();
250 JPanel modePanel = new JPanel();
251 modePanel.setBorder(BorderFactory.createTitledBorder("Mouse Mode"));
252 modePanel.add(modeBox);
253
254 JPanel scaleGrid = new JPanel(new GridLayout(1,0));
255 scaleGrid.setBorder(BorderFactory.createTitledBorder("Zoom"));
256 JPanel controls = new JPanel();
257 scaleGrid.add(plus);
258 scaleGrid.add(minus);
259 controls.add(scaleGrid);
260
261 controls.add(modePanel);
262 content.add(controls, BorderLayout.SOUTH);
263
264 this.viewSupport = new MagnifyImageLensSupport<Number,Number>(vv);
265
266
267
268
269 this.modelSupport = new LayoutLensSupport<Number,Number>(vv);
270
271 graphMouse.addItemListener(modelSupport.getGraphMouse().getModeListener());
272 graphMouse.addItemListener(viewSupport.getGraphMouse().getModeListener());
273
274 ButtonGroup radio = new ButtonGroup();
275 JRadioButton none = new JRadioButton("None");
276 none.addItemListener(new ItemListener(){
277 public void itemStateChanged(ItemEvent e) {
278 if(viewSupport != null) {
279 viewSupport.deactivate();
280 }
281 if(modelSupport != null) {
282 modelSupport.deactivate();
283 }
284 }
285 });
286 none.setSelected(true);
287
288 JRadioButton hyperView = new JRadioButton("View");
289 hyperView.addItemListener(new ItemListener(){
290 public void itemStateChanged(ItemEvent e) {
291 viewSupport.activate(e.getStateChange() == ItemEvent.SELECTED);
292 }
293 });
294
295 JRadioButton hyperModel = new JRadioButton("Layout");
296 hyperModel.addItemListener(new ItemListener(){
297 public void itemStateChanged(ItemEvent e) {
298 modelSupport.activate(e.getStateChange() == ItemEvent.SELECTED);
299 }
300 });
301 radio.add(none);
302 radio.add(hyperView);
303 radio.add(hyperModel);
304
305 JMenuBar menubar = new JMenuBar();
306 JMenu modeMenu = graphMouse.getModeMenu();
307 menubar.add(modeMenu);
308
309 JPanel lensPanel = new JPanel(new GridLayout(2,0));
310 lensPanel.setBorder(BorderFactory.createTitledBorder("Lens"));
311 lensPanel.add(none);
312 lensPanel.add(hyperView);
313 lensPanel.add(hyperModel);
314 controls.add(lensPanel);
315 }
316
317
318
319
320
321
322
323
324
325 class VertexStringerImpl<V> implements Transformer<V,String> {
326
327 Map<V,String> map = new HashMap<V,String>();
328
329 boolean enabled = true;
330
331 public VertexStringerImpl(Map<V,String> map) {
332 this.map = map;
333 }
334
335
336
337
338 public String transform(V v) {
339 if(isEnabled()) {
340 return map.get(v);
341 } else {
342 return "";
343 }
344 }
345
346
347
348
349 public boolean isEnabled() {
350 return enabled;
351 }
352
353
354
355
356 public void setEnabled(boolean enabled) {
357 this.enabled = enabled;
358 }
359 }
360
361
362
363
364
365
366 private Number[] createVertices(int count) {
367 Number[] v = new Number[count];
368 for (int i = 0; i < count; i++) {
369 v[i] = new Integer(i);
370 graph.addVertex(v[i]);
371 }
372 return v;
373 }
374
375
376
377
378
379 void createEdges(Number[] v) {
380 graph.addEdge(new Double(Math.random()), v[0], v[1], EdgeType.DIRECTED);
381 graph.addEdge(new Double(Math.random()), v[3], v[0], EdgeType.DIRECTED);
382 graph.addEdge(new Double(Math.random()), v[0], v[4], EdgeType.DIRECTED);
383 graph.addEdge(new Double(Math.random()), v[4], v[5], EdgeType.DIRECTED);
384 graph.addEdge(new Double(Math.random()), v[5], v[3], EdgeType.DIRECTED);
385 graph.addEdge(new Double(Math.random()), v[2], v[1], EdgeType.DIRECTED);
386 graph.addEdge(new Double(Math.random()), v[4], v[1], EdgeType.DIRECTED);
387 graph.addEdge(new Double(Math.random()), v[8], v[2], EdgeType.DIRECTED);
388 graph.addEdge(new Double(Math.random()), v[3], v[8], EdgeType.DIRECTED);
389 graph.addEdge(new Double(Math.random()), v[6], v[7], EdgeType.DIRECTED);
390 graph.addEdge(new Double(Math.random()), v[7], v[5], EdgeType.DIRECTED);
391 graph.addEdge(new Double(Math.random()), v[0], v[9], EdgeType.DIRECTED);
392 graph.addEdge(new Double(Math.random()), v[9], v[8], EdgeType.DIRECTED);
393 graph.addEdge(new Double(Math.random()), v[7], v[6], EdgeType.DIRECTED);
394 graph.addEdge(new Double(Math.random()), v[6], v[5], EdgeType.DIRECTED);
395 graph.addEdge(new Double(Math.random()), v[4], v[2], EdgeType.DIRECTED);
396 graph.addEdge(new Double(Math.random()), v[5], v[4], EdgeType.DIRECTED);
397 graph.addEdge(new Double(Math.random()), v[4], v[10], EdgeType.DIRECTED);
398 graph.addEdge(new Double(Math.random()), v[10], v[4], EdgeType.DIRECTED);
399 }
400
401 public static class PickWithIconListener implements ItemListener {
402 DefaultVertexIconTransformer<Number> imager;
403 Icon checked;
404
405 public PickWithIconListener(DefaultVertexIconTransformer<Number> imager) {
406 this.imager = imager;
407 checked = new Checkmark(Color.red);
408 }
409
410 public void itemStateChanged(ItemEvent e) {
411 Icon icon = imager.transform((Number)e.getItem());
412 if(icon != null && icon instanceof LayeredIcon) {
413 if(e.getStateChange() == ItemEvent.SELECTED) {
414 ((LayeredIcon)icon).add(checked);
415 } else {
416 ((LayeredIcon)icon).remove(checked);
417 }
418 }
419 }
420 }
421
422
423
424
425
426 public static void main(String[] args) {
427 JFrame frame = new JFrame();
428 Container content = frame.getContentPane();
429 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
430
431 content.add(new LensVertexImageShaperDemo());
432 frame.pack();
433 frame.setVisible(true);
434 }
435 }