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.GridLayout;
16 import java.awt.Shape;
17 import java.awt.event.ActionEvent;
18 import java.awt.event.ActionListener;
19 import java.awt.event.ItemEvent;
20 import java.awt.event.ItemListener;
21 import java.awt.geom.Point2D;
22 import java.awt.geom.Rectangle2D;
23 import java.util.HashMap;
24 import java.util.Map;
25
26 import javax.media.jai.PerspectiveTransform;
27 import javax.swing.BorderFactory;
28 import javax.swing.ButtonGroup;
29 import javax.swing.JApplet;
30 import javax.swing.JButton;
31 import javax.swing.JFrame;
32 import javax.swing.JMenuBar;
33 import javax.swing.JPanel;
34 import javax.swing.JRadioButton;
35 import javax.swing.JSlider;
36 import javax.swing.event.ChangeEvent;
37 import javax.swing.event.ChangeListener;
38
39 import org.apache.commons.collections15.Transformer;
40 import org.apache.commons.collections15.TransformerUtils;
41
42 import edu.uci.ics.jung.algorithms.layout.FRLayout;
43 import edu.uci.ics.jung.algorithms.layout.Layout;
44 import edu.uci.ics.jung.algorithms.layout.StaticLayout;
45 import edu.uci.ics.jung.graph.Graph;
46 import edu.uci.ics.jung.graph.SparseMultigraph;
47 import edu.uci.ics.jung.graph.util.TestGraphs;
48 import edu.uci.ics.jung.visualization.DefaultVisualizationModel;
49 import edu.uci.ics.jung.visualization.VisualizationModel;
50 import edu.uci.ics.jung.visualization.GraphZoomScrollPane;
51 import edu.uci.ics.jung.visualization.VisualizationViewer;
52 import edu.uci.ics.jung.visualization.control.CrossoverScalingControl;
53 import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
54 import edu.uci.ics.jung.visualization.control.ScalingControl;
55 import edu.uci.ics.jung.visualization.decorators.PickableEdgePaintTransformer;
56 import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
57 import edu.uci.ics.jung.visualization.jai.PerspectiveLayoutTransformSupport;
58 import edu.uci.ics.jung.visualization.jai.PerspectiveTransformSupport;
59 import edu.uci.ics.jung.visualization.jai.PerspectiveViewTransformSupport;
60 import edu.uci.ics.jung.visualization.picking.PickedState;
61
62
63
64
65
66
67
68
69
70
71 public class PerspectiveTransformerDemo extends JApplet {
72
73
74
75
76 private static final long serialVersionUID = -702499007038889493L;
77
78
79
80
81 Graph<String,Number> graph;
82
83 Layout<String,Number> graphLayout;
84
85
86
87
88 Graph<String,Number> grid;
89
90 Layout<String,Number> gridLayout;
91
92
93
94
95 VisualizationViewer<String,Number> vv;
96
97
98
99
100 PerspectiveTransformSupport viewSupport;
101
102
103
104
105 PerspectiveTransformSupport layoutSupport;
106
107
108
109
110
111
112 @SuppressWarnings("serial")
113 public PerspectiveTransformerDemo() {
114
115
116 graph = TestGraphs.getOneComponentGraph();
117
118 graphLayout = new FRLayout<String,Number>(graph);
119 ((FRLayout<String,Number>)graphLayout).setMaxIterations(1000);
120
121 Dimension preferredSize = new Dimension(600,600);
122 Map<String,Point2D> map =
123 new HashMap<String,Point2D>();
124 Transformer<String,Point2D> vlf = TransformerUtils.mapTransformer(map);
125 grid = this.generateVertexGrid(map, preferredSize, 25);
126 gridLayout = new StaticLayout<String,Number>(grid, vlf, preferredSize);
127
128 final VisualizationModel<String,Number> visualizationModel =
129 new DefaultVisualizationModel<String,Number>(graphLayout, preferredSize);
130 vv = new VisualizationViewer<String,Number>(visualizationModel, preferredSize);
131 PickedState<Number> pes = vv.getPickedEdgeState();
132 vv.getRenderContext().setEdgeDrawPaintTransformer(new PickableEdgePaintTransformer<Number>(pes, Color.black, Color.red));
133 vv.getRenderContext().setVertexShapeTransformer(new Transformer<String,Shape>() {
134
135 public Shape transform(String v) {
136 return new Rectangle2D.Float(-10,-10,20,20);
137 }});
138 vv.setBackground(Color.white);
139
140
141 vv.setVertexToolTipTransformer(new ToStringLabeller<String>());
142
143 Container content = getContentPane();
144 GraphZoomScrollPane gzsp = new GraphZoomScrollPane(vv);
145 content.add(gzsp);
146
147
148
149
150 final DefaultModalGraphMouse<Number, Number> graphMouse =
151 new DefaultModalGraphMouse<Number, Number>();
152
153 vv.setGraphMouse(graphMouse);
154
155 viewSupport = new PerspectiveViewTransformSupport<String,Number>(vv);
156 layoutSupport = new PerspectiveLayoutTransformSupport<String,Number>(vv);
157
158 final ScalingControl scaler = new CrossoverScalingControl();
159
160 JButton plus = new JButton("+");
161 plus.addActionListener(new ActionListener() {
162 public void actionPerformed(ActionEvent e) {
163 scaler.scale(vv, 1.1f, vv.getCenter());
164 }
165 });
166 JButton minus = new JButton("-");
167 minus.addActionListener(new ActionListener() {
168 public void actionPerformed(ActionEvent e) {
169 scaler.scale(vv, 0.9f, vv.getCenter());
170 }
171 });
172 final JSlider horizontalSlider = new JSlider(-120,120,0){
173
174
175
176
177 @Override
178 public Dimension getPreferredSize() {
179 return new Dimension(80, super.getPreferredSize().height);
180 }
181 };
182
183 final JSlider verticalSlider = new JSlider(-120,120,0) {
184
185
186
187
188 @Override
189 public Dimension getPreferredSize() {
190 return new Dimension(super.getPreferredSize().width, 80);
191 }
192 };
193 verticalSlider.setOrientation(JSlider.VERTICAL);
194 final ChangeListener changeListener = new ChangeListener() {
195
196 public void stateChanged(ChangeEvent e) {
197 int vval = -verticalSlider.getValue();
198 int hval = horizontalSlider.getValue();
199
200 Dimension d = vv.getSize();
201 PerspectiveTransform pt = null;
202 pt = PerspectiveTransform.getQuadToQuad(
203 vval, hval,
204 d.width-vval, -hval,
205 d.width+vval, d.height+hval,
206 -vval, d.height-hval,
207
208 0, 0,
209 d.width, 0,
210 d.width, d.height,
211 0, d.height);
212
213 viewSupport.getPerspectiveTransformer().setPerspectiveTransform(pt);
214 layoutSupport.getPerspectiveTransformer().setPerspectiveTransform(pt);
215 vv.repaint();
216 }};
217 horizontalSlider.addChangeListener(changeListener);
218 verticalSlider.addChangeListener(changeListener);
219
220 JPanel perspectivePanel = new JPanel(new BorderLayout());
221 JPanel perspectiveCenterPanel = new JPanel(new BorderLayout());
222 perspectivePanel.setBorder(BorderFactory.createTitledBorder("Perspective Controls"));
223 final JButton center = new JButton("Center");
224 center.addActionListener(new ActionListener() {
225
226 public void actionPerformed(ActionEvent e) {
227 horizontalSlider.setValue(0);
228 verticalSlider.setValue(0);
229 }});
230 ButtonGroup radio = new ButtonGroup();
231 JRadioButton normal = new JRadioButton("None");
232 normal.addItemListener(new ItemListener() {
233 public void itemStateChanged(ItemEvent e) {
234 boolean selected = e.getStateChange() == ItemEvent.SELECTED;
235 if(selected) {
236 if(viewSupport != null) {
237 viewSupport.deactivate();
238 }
239 if(layoutSupport != null) {
240 layoutSupport.deactivate();
241 }
242 }
243 center.setEnabled(!selected);
244 horizontalSlider.setEnabled(!selected);
245 verticalSlider.setEnabled(!selected);
246 }
247 });
248
249 final JRadioButton perspectiveView = new JRadioButton("In View");
250 perspectiveView.addItemListener(new ItemListener(){
251 public void itemStateChanged(ItemEvent e) {
252 viewSupport.activate(e.getStateChange() == ItemEvent.SELECTED);
253 }
254 });
255 final JRadioButton perspectiveModel = new JRadioButton("In Layout");
256 perspectiveModel.addItemListener(new ItemListener(){
257 public void itemStateChanged(ItemEvent e) {
258 layoutSupport.activate(e.getStateChange() == ItemEvent.SELECTED);
259 }
260 });
261
262 radio.add(normal);
263 radio.add(perspectiveModel);
264 radio.add(perspectiveView);
265 normal.setSelected(true);
266
267 ButtonGroup graphRadio = new ButtonGroup();
268 JRadioButton graphButton = new JRadioButton("Graph");
269 graphButton.setSelected(true);
270 graphButton.addItemListener(new ItemListener() {
271
272 public void itemStateChanged(ItemEvent e) {
273 if(e.getStateChange() == ItemEvent.SELECTED) {
274 visualizationModel.setGraphLayout(graphLayout);
275 vv.repaint();
276 }
277 }});
278 JRadioButton gridButton = new JRadioButton("Grid");
279 gridButton.addItemListener(new ItemListener() {
280
281 public void itemStateChanged(ItemEvent e) {
282 if(e.getStateChange() == ItemEvent.SELECTED) {
283 visualizationModel.setGraphLayout(gridLayout);
284 vv.repaint();
285 }
286 }});
287 graphRadio.add(graphButton);
288 graphRadio.add(gridButton);
289
290 JPanel modePanel = new JPanel(new GridLayout(2,1));
291 modePanel.setBorder(BorderFactory.createTitledBorder("Display"));
292 modePanel.add(graphButton);
293 modePanel.add(gridButton);
294
295 JMenuBar menubar = new JMenuBar();
296 menubar.add(graphMouse.getModeMenu());
297 gzsp.setCorner(menubar);
298
299 Container controls = new JPanel(new BorderLayout());
300 JPanel zoomControls = new JPanel(new GridLayout(2,1));
301 zoomControls.setBorder(BorderFactory.createTitledBorder("Zoom"));
302 JPanel perspectiveControls = new JPanel(new GridLayout(3,1));
303 zoomControls.add(plus);
304 zoomControls.add(minus);
305 perspectiveControls.add(normal);
306 perspectiveControls.add(perspectiveModel);
307 perspectiveControls.add(perspectiveView);
308
309 controls.add(zoomControls, BorderLayout.WEST);
310 controls.add(modePanel);
311 perspectivePanel.add(perspectiveControls, BorderLayout.WEST);
312 perspectiveCenterPanel.add(horizontalSlider, BorderLayout.SOUTH);
313 perspectivePanel.add(verticalSlider, BorderLayout.EAST);
314 perspectiveCenterPanel.add(center);
315 perspectivePanel.add(perspectiveCenterPanel);
316 controls.add(perspectivePanel, BorderLayout.EAST);
317
318 content.add(controls, BorderLayout.SOUTH);
319 }
320
321 private Graph<String,Number> generateVertexGrid(Map<String,Point2D> map,
322 Dimension d, int interval) {
323 int count = d.width/interval * d.height/interval;
324 Graph<String,Number> graph = new SparseMultigraph<String,Number>();
325 String[] v = new String[count];
326 for(int i=0; i<count; i++) {
327 int x = interval*i;
328 int y = x / d.width * interval;
329 x %= d.width;
330
331 Point2D location = new Point2D.Float(x, y);
332 v[i] = ""+i;
333 map.put(v[i], location);
334 graph.addVertex(v[i]);
335 }
336 return graph;
337 }
338
339
340
341
342 public static void main(String[] args) {
343 JFrame f = new JFrame();
344 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
345 f.getContentPane().add(new PerspectiveTransformerDemo());
346 f.pack();
347 f.setVisible(true);
348 }
349 }