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.Ellipse2D;
24 import java.awt.geom.Point2D;
25 import java.util.Collection;
26 import java.util.HashSet;
27 import java.util.Map;
28 import java.util.Set;
29
30 import javax.swing.BorderFactory;
31 import javax.swing.JApplet;
32 import javax.swing.JButton;
33 import javax.swing.JFrame;
34 import javax.swing.JMenuBar;
35 import javax.swing.JPanel;
36 import javax.swing.JRadioButton;
37
38 import com.google.common.base.Supplier;
39
40 import edu.uci.ics.jung.algorithms.layout.PolarPoint;
41 import edu.uci.ics.jung.algorithms.layout.RadialTreeLayout;
42 import edu.uci.ics.jung.algorithms.layout.TreeLayout;
43 import edu.uci.ics.jung.graph.DelegateForest;
44 import edu.uci.ics.jung.graph.DelegateTree;
45 import edu.uci.ics.jung.graph.DirectedGraph;
46 import edu.uci.ics.jung.graph.DirectedSparseGraph;
47 import edu.uci.ics.jung.graph.Forest;
48 import edu.uci.ics.jung.graph.Tree;
49 import edu.uci.ics.jung.visualization.DefaultVisualizationModel;
50 import edu.uci.ics.jung.visualization.GraphZoomScrollPane;
51 import edu.uci.ics.jung.visualization.Layer;
52 import edu.uci.ics.jung.visualization.VisualizationModel;
53 import edu.uci.ics.jung.visualization.VisualizationServer;
54 import edu.uci.ics.jung.visualization.VisualizationViewer;
55 import edu.uci.ics.jung.visualization.control.CrossoverScalingControl;
56 import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
57 import edu.uci.ics.jung.visualization.control.ModalLensGraphMouse;
58 import edu.uci.ics.jung.visualization.control.ScalingControl;
59 import edu.uci.ics.jung.visualization.decorators.EdgeShape;
60 import edu.uci.ics.jung.visualization.decorators.PickableEdgePaintTransformer;
61 import edu.uci.ics.jung.visualization.decorators.PickableVertexPaintTransformer;
62 import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
63 import edu.uci.ics.jung.visualization.picking.PickedState;
64 import edu.uci.ics.jung.visualization.transform.LensSupport;
65 import edu.uci.ics.jung.visualization.transform.shape.HyperbolicShapeTransformer;
66 import edu.uci.ics.jung.visualization.transform.shape.ViewLensSupport;
67
68
69
70
71
72
73
74
75
76 @SuppressWarnings("serial")
77 public class RadialTreeLensDemo extends JApplet {
78
79 Forest<String,Integer> graph;
80
81 Supplier<DirectedGraph<String,Integer>> graphFactory =
82 new Supplier<DirectedGraph<String,Integer>>() {
83
84 public DirectedGraph<String, Integer> get() {
85 return new DirectedSparseGraph<String,Integer>();
86 }
87 };
88
89 Supplier<Tree<String,Integer>> treeFactory =
90 new Supplier<Tree<String,Integer>> () {
91
92 public Tree<String, Integer> get() {
93 return new DelegateTree<String,Integer>(graphFactory);
94 }
95 };
96 Supplier<Integer> edgeFactory = new Supplier<Integer>() {
97 int i=0;
98 public Integer get() {
99 return i++;
100 }
101 };
102
103 Supplier<String> vertexFactory = new Supplier<String>() {
104 int i=0;
105 public String get() {
106 return "V"+i++;
107 }
108 };
109
110 VisualizationServer.Paintable rings;
111
112 String root;
113
114 TreeLayout<String,Integer> layout;
115
116 RadialTreeLayout<String,Integer> radialLayout;
117
118
119
120
121 VisualizationViewer<String,Integer> vv;
122
123
124
125
126 LensSupport hyperbolicViewSupport;
127
128 ScalingControl scaler;
129
130
131
132
133
134
135 public RadialTreeLensDemo() {
136
137
138
139 graph = new DelegateForest<String,Integer>();
140
141 createTree();
142
143 layout = new TreeLayout<String,Integer>(graph);
144 radialLayout = new RadialTreeLayout<String,Integer>(graph);
145 radialLayout.setSize(new Dimension(600,600));
146
147 Dimension preferredSize = new Dimension(600,600);
148
149 final VisualizationModel<String,Integer> visualizationModel =
150 new DefaultVisualizationModel<String,Integer>(radialLayout, preferredSize);
151 vv = new VisualizationViewer<String,Integer>(visualizationModel, preferredSize);
152
153 PickedState<String> ps = vv.getPickedVertexState();
154 PickedState<Integer> pes = vv.getPickedEdgeState();
155 vv.getRenderContext().setVertexFillPaintTransformer(new PickableVertexPaintTransformer<String>(ps, Color.red, Color.yellow));
156 vv.getRenderContext().setEdgeDrawPaintTransformer(new PickableEdgePaintTransformer<Integer>(pes, Color.black, Color.cyan));
157 vv.setBackground(Color.white);
158
159 vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller());
160 vv.getRenderContext().setEdgeShapeTransformer(EdgeShape.line(graph));
161
162
163 vv.setVertexToolTipTransformer(new ToStringLabeller());
164
165 Container content = getContentPane();
166 GraphZoomScrollPane gzsp = new GraphZoomScrollPane(vv);
167 content.add(gzsp);
168
169 final DefaultModalGraphMouse<String,Integer> graphMouse
170 = new DefaultModalGraphMouse<String,Integer>();
171
172 vv.setGraphMouse(graphMouse);
173 vv.addKeyListener(graphMouse.getModeKeyListener());
174 rings = new Rings();
175 vv.addPreRenderPaintable(rings);
176
177 hyperbolicViewSupport =
178 new ViewLensSupport<String,Integer>(vv, new HyperbolicShapeTransformer(vv,
179 vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.VIEW)),
180 new ModalLensGraphMouse());
181
182 final ScalingControl scaler = new CrossoverScalingControl();
183
184 JButton plus = new JButton("+");
185 plus.addActionListener(new ActionListener() {
186 public void actionPerformed(ActionEvent e) {
187 scaler.scale(vv, 1.1f, vv.getCenter());
188 }
189 });
190 JButton minus = new JButton("-");
191 minus.addActionListener(new ActionListener() {
192 public void actionPerformed(ActionEvent e) {
193 scaler.scale(vv, 1/1.1f, vv.getCenter());
194 }
195 });
196
197 final JRadioButton hyperView = new JRadioButton("Hyperbolic View");
198 hyperView.addItemListener(new ItemListener(){
199 public void itemStateChanged(ItemEvent e) {
200 hyperbolicViewSupport.activate(e.getStateChange() == ItemEvent.SELECTED);
201 }
202 });
203
204 graphMouse.addItemListener(hyperbolicViewSupport.getGraphMouse().getModeListener());
205
206 JMenuBar menubar = new JMenuBar();
207 menubar.add(graphMouse.getModeMenu());
208 gzsp.setCorner(menubar);
209
210 JPanel controls = new JPanel();
211 JPanel zoomControls = new JPanel(new GridLayout(2,1));
212 zoomControls.setBorder(BorderFactory.createTitledBorder("Zoom"));
213 JPanel hyperControls = new JPanel(new GridLayout(3,2));
214 hyperControls.setBorder(BorderFactory.createTitledBorder("Examiner Lens"));
215 zoomControls.add(plus);
216 zoomControls.add(minus);
217 JPanel modeControls = new JPanel(new BorderLayout());
218 modeControls.setBorder(BorderFactory.createTitledBorder("Mouse Mode"));
219 modeControls.add(graphMouse.getModeComboBox());
220 hyperControls.add(hyperView);
221
222 controls.add(zoomControls);
223 controls.add(hyperControls);
224 controls.add(modeControls);
225 content.add(controls, BorderLayout.SOUTH);
226 }
227
228 private void createTree() {
229 graph.addVertex("V0");
230 graph.addEdge(edgeFactory.get(), "V0", "V1");
231 graph.addEdge(edgeFactory.get(), "V0", "V2");
232 graph.addEdge(edgeFactory.get(), "V1", "V4");
233 graph.addEdge(edgeFactory.get(), "V2", "V3");
234 graph.addEdge(edgeFactory.get(), "V2", "V5");
235 graph.addEdge(edgeFactory.get(), "V4", "V6");
236 graph.addEdge(edgeFactory.get(), "V4", "V7");
237 graph.addEdge(edgeFactory.get(), "V3", "V8");
238 graph.addEdge(edgeFactory.get(), "V6", "V9");
239 graph.addEdge(edgeFactory.get(), "V4", "V10");
240
241 graph.addVertex("A0");
242 graph.addEdge(edgeFactory.get(), "A0", "A1");
243 graph.addEdge(edgeFactory.get(), "A0", "A2");
244 graph.addEdge(edgeFactory.get(), "A0", "A3");
245
246 graph.addVertex("B0");
247 graph.addEdge(edgeFactory.get(), "B0", "B1");
248 graph.addEdge(edgeFactory.get(), "B0", "B2");
249 graph.addEdge(edgeFactory.get(), "B1", "B4");
250 graph.addEdge(edgeFactory.get(), "B2", "B3");
251 graph.addEdge(edgeFactory.get(), "B2", "B5");
252 graph.addEdge(edgeFactory.get(), "B4", "B6");
253 graph.addEdge(edgeFactory.get(), "B4", "B7");
254 graph.addEdge(edgeFactory.get(), "B3", "B8");
255 graph.addEdge(edgeFactory.get(), "B6", "B9");
256
257 }
258
259 class Rings implements VisualizationServer.Paintable {
260
261 Collection<Double> depths;
262
263 public Rings() {
264 depths = getDepths();
265 }
266
267 private Collection<Double> getDepths() {
268 Set<Double> depths = new HashSet<Double>();
269 Map<String,PolarPoint> polarLocations = radialLayout.getPolarLocations();
270 for(String v : graph.getVertices()) {
271 PolarPoint pp = polarLocations.get(v);
272 depths.add(pp.getRadius());
273 }
274 return depths;
275 }
276
277 public void paint(Graphics g) {
278 g.setColor(Color.gray);
279 Graphics2D g2d = (Graphics2D)g;
280 Point2D center = radialLayout.getCenter();
281
282 Ellipse2D ellipse = new Ellipse2D.Double();
283 for(double d : depths) {
284 ellipse.setFrameFromDiagonal(center.getX()-d, center.getY()-d,
285 center.getX()+d, center.getY()+d);
286 Shape shape =
287 vv.getRenderContext().getMultiLayerTransformer().transform(ellipse);
288 g2d.draw(shape);
289 }
290 }
291
292 public boolean useTransform() {
293 return true;
294 }
295 }
296
297 public static void main(String[] args) {
298 JFrame f = new JFrame();
299 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
300 f.getContentPane().add(new RadialTreeLensDemo());
301 f.pack();
302 f.setVisible(true);
303 }
304 }