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 com.google.common.base.Function;
41 import com.google.common.base.Functions;
42
43 import edu.uci.ics.jung.algorithms.layout.FRLayout;
44 import edu.uci.ics.jung.graph.DirectedSparseGraph;
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.ModalGraphMouse.Mode;
51 import edu.uci.ics.jung.visualization.control.ScalingControl;
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 DemoLensVertexImageShaperDemo 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 "sample2"
108 };
109
110 LensSupport viewSupport;
111 LensSupport modelSupport;
112 LensSupport magnifyLayoutSupport;
113 LensSupport magnifyViewSupport;
114
115
116
117
118
119 public DemoLensVertexImageShaperDemo() {
120
121
122 graph = new DirectedSparseGraph<Number,Number>();
123 Number[] vertices = createVertices(1);
124
125
126 Map<Number,String> map = new HashMap<Number,String>();
127 for(int i=0; i<vertices.length; i++) {
128 map.put(vertices[i], iconNames[i%iconNames.length]);
129 }
130
131
132 Map<Number,Icon> iconMap = new HashMap<Number,Icon>();
133 for(int i=0; i<vertices.length; i++) {
134 String name = "/images/topic"+iconNames[i]+".gif";
135 try {
136 Icon icon =
137 new LayeredIcon(new ImageIcon(DemoLensVertexImageShaperDemo.class.getResource(name)).getImage());
138 iconMap.put(vertices[i], icon);
139 } catch(Exception ex) {
140 System.err.println("You need slashdoticons.jar in your classpath to see the image "+name);
141 }
142 }
143
144 createEdges(vertices);
145
146 FRLayout<Number, Number> layout = new FRLayout<Number, Number>(graph);
147 layout.setMaxIterations(100);
148 vv = new VisualizationViewer<Number, Number>(layout, new Dimension(600,600));
149
150 Function<Number,Paint> vpf =
151 new PickableVertexPaintTransformer<Number>(vv.getPickedVertexState(), Color.white, Color.yellow);
152 vv.getRenderContext().setVertexFillPaintTransformer(vpf);
153 vv.getRenderContext().setEdgeDrawPaintTransformer(new PickableEdgePaintTransformer<Number>(vv.getPickedEdgeState(), Color.black, Color.cyan));
154
155 vv.setBackground(Color.white);
156
157 final Function<Number,String> vertexStringerImpl =
158 new VertexStringerImpl<Number>(map);
159 vv.getRenderContext().setVertexLabelTransformer(vertexStringerImpl);
160 vv.getRenderContext().setVertexLabelRenderer(new DefaultVertexLabelRenderer(Color.cyan));
161 vv.getRenderContext().setEdgeLabelRenderer(new DefaultEdgeLabelRenderer(Color.cyan));
162
163
164
165 final VertexIconShapeTransformer<Number> vertexImageShapeFunction =
166 new VertexIconShapeTransformer<Number>(new EllipseVertexShapeTransformer<Number>());
167 vertexImageShapeFunction.setIconMap(iconMap);
168
169 final Function<Number, Icon> vertexIconFunction = Functions.forMap(iconMap);
170
171 vv.getRenderContext().setVertexShapeTransformer(vertexImageShapeFunction);
172 vv.getRenderContext().setVertexIconTransformer(vertexIconFunction);
173
174
175
176 PickedState<Number> ps = vv.getPickedVertexState();
177 ps.addItemListener(new PickWithIconListener(vertexIconFunction));
178
179 vv.addPostRenderPaintable(new VisualizationViewer.Paintable(){
180 int x;
181 int y;
182 Font font;
183 FontMetrics metrics;
184 int swidth;
185 int sheight;
186 String str = "Thank You, slashdot.org, for the images!";
187
188 public void paint(Graphics g) {
189 Dimension d = vv.getSize();
190 if(font == null) {
191 font = new Font(g.getFont().getName(), Font.BOLD, 20);
192 metrics = g.getFontMetrics(font);
193 swidth = metrics.stringWidth(str);
194 sheight = metrics.getMaxAscent()+metrics.getMaxDescent();
195 x = (d.width-swidth)/2;
196 y = (int)(d.height-sheight*1.5);
197 }
198 g.setFont(font);
199 Color oldColor = g.getColor();
200 g.setColor(Color.lightGray);
201 g.drawString(str, x, y);
202 g.setColor(oldColor);
203 }
204 public boolean useTransform() {
205 return false;
206 }
207 });
208
209
210 vv.setVertexToolTipTransformer(new ToStringLabeller());
211
212 Container content = getContentPane();
213 final GraphZoomScrollPane panel = new GraphZoomScrollPane(vv);
214 content.add(panel);
215
216 final DefaultModalGraphMouse<Number, Number> graphMouse
217 = new DefaultModalGraphMouse<Number, Number>();
218 vv.setGraphMouse(graphMouse);
219
220
221 final ScalingControl scaler = new CrossoverScalingControl();
222
223 JButton plus = new JButton("+");
224 plus.addActionListener(new ActionListener() {
225 public void actionPerformed(ActionEvent e) {
226 scaler.scale(vv, 1.1f, vv.getCenter());
227 }
228 });
229 JButton minus = new JButton("-");
230 minus.addActionListener(new ActionListener() {
231 public void actionPerformed(ActionEvent e) {
232 scaler.scale(vv, 1/1.1f, vv.getCenter());
233 }
234 });
235
236 JComboBox<Mode> modeBox = graphMouse.getModeComboBox();
237 JPanel modePanel = new JPanel();
238 modePanel.setBorder(BorderFactory.createTitledBorder("Mouse Mode"));
239 modePanel.add(modeBox);
240
241 JPanel scaleGrid = new JPanel(new GridLayout(1,0));
242 scaleGrid.setBorder(BorderFactory.createTitledBorder("Zoom"));
243 JPanel controls = new JPanel();
244 scaleGrid.add(plus);
245 scaleGrid.add(minus);
246 controls.add(scaleGrid);
247
248 controls.add(modePanel);
249 content.add(controls, BorderLayout.SOUTH);
250
251 this.viewSupport = new MagnifyImageLensSupport<Number,Number>(vv);
252
253
254
255
256 this.modelSupport = new LayoutLensSupport<Number,Number>(vv);
257
258 graphMouse.addItemListener(modelSupport.getGraphMouse().getModeListener());
259 graphMouse.addItemListener(viewSupport.getGraphMouse().getModeListener());
260
261 ButtonGroup radio = new ButtonGroup();
262 JRadioButton none = new JRadioButton("None");
263 none.addItemListener(new ItemListener(){
264 public void itemStateChanged(ItemEvent e) {
265 if(viewSupport != null) {
266 viewSupport.deactivate();
267 }
268 if(modelSupport != null) {
269 modelSupport.deactivate();
270 }
271 }
272 });
273 none.setSelected(true);
274
275 JRadioButton hyperView = new JRadioButton("View");
276 hyperView.addItemListener(new ItemListener(){
277 public void itemStateChanged(ItemEvent e) {
278 viewSupport.activate(e.getStateChange() == ItemEvent.SELECTED);
279 }
280 });
281
282 JRadioButton hyperModel = new JRadioButton("Layout");
283 hyperModel.addItemListener(new ItemListener(){
284 public void itemStateChanged(ItemEvent e) {
285 modelSupport.activate(e.getStateChange() == ItemEvent.SELECTED);
286 }
287 });
288 radio.add(none);
289 radio.add(hyperView);
290 radio.add(hyperModel);
291
292 JMenuBar menubar = new JMenuBar();
293 JMenu modeMenu = graphMouse.getModeMenu();
294 menubar.add(modeMenu);
295
296 JPanel lensPanel = new JPanel(new GridLayout(2,0));
297 lensPanel.setBorder(BorderFactory.createTitledBorder("Lens"));
298 lensPanel.add(none);
299 lensPanel.add(hyperView);
300 lensPanel.add(hyperModel);
301 controls.add(lensPanel);
302 }
303
304
305
306
307
308
309
310
311
312 class VertexStringerImpl<V> implements Function<V,String> {
313
314 Map<V,String> map = new HashMap<V,String>();
315
316 boolean enabled = true;
317
318 public VertexStringerImpl(Map<V,String> map) {
319 this.map = map;
320 }
321
322
323
324
325 public String apply(V v) {
326 if(isEnabled()) {
327 return map.get(v);
328 } else {
329 return "";
330 }
331 }
332
333
334
335
336 public boolean isEnabled() {
337 return enabled;
338 }
339
340
341
342
343 public void setEnabled(boolean enabled) {
344 this.enabled = enabled;
345 }
346 }
347
348
349
350
351
352
353 private Number[] createVertices(int count) {
354 Number[] v = new Number[count];
355 for (int i = 0; i < count; i++) {
356 v[i] = new Integer(i);
357 graph.addVertex(v[i]);
358 }
359 return v;
360 }
361
362
363
364
365
366 void createEdges(Number[] v) {
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386 }
387
388 public static class PickWithIconListener implements ItemListener {
389 Function<Number, Icon> imager;
390 Icon checked;
391
392 public PickWithIconListener(Function<Number, Icon> imager) {
393 this.imager = imager;
394 checked = new Checkmark(Color.red);
395 }
396
397 public void itemStateChanged(ItemEvent e) {
398 Icon icon = imager.apply((Number)e.getItem());
399 if(icon != null && icon instanceof LayeredIcon) {
400 if(e.getStateChange() == ItemEvent.SELECTED) {
401 ((LayeredIcon)icon).add(checked);
402 } else {
403 ((LayeredIcon)icon).remove(checked);
404 }
405 }
406 }
407 }
408
409
410 public static void main(String[] args) {
411 JFrame frame = new JFrame();
412 Container content = frame.getContentPane();
413 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
414
415 content.add(new DemoLensVertexImageShaperDemo());
416 frame.pack();
417 frame.setVisible(true);
418 }
419 }