1
14
15 package demo.yext.export;
16
17 import y.io.GraphMLIOHandler;
18 import y.option.OptionHandler;
19 import y.option.OptionGroup;
20 import y.option.ConstraintManager;
21 import y.view.AreaZoomMode;
22 import y.view.Arrow;
23 import y.view.EditMode;
24 import y.view.Graph2D;
25 import y.view.Graph2DView;
26 import y.io.IOHandler;
27 import y.io.SuffixFileFilter;
28 import y.util.D;
29
30 import javax.swing.AbstractAction;
31 import javax.swing.Action;
32 import javax.swing.BorderFactory;
33 import javax.swing.ImageIcon;
34 import javax.swing.JFileChooser;
35 import javax.swing.JLabel;
36 import javax.swing.JMenu;
37 import javax.swing.JMenuBar;
38 import javax.swing.JPanel;
39 import javax.swing.JToolBar;
40 import javax.swing.UIManager;
41
42 import y.view.ViewMode;
43 import y.view.YRenderingHints;
44 import yext.export.io.OutputHandler;
45
46 import java.awt.BorderLayout;
47 import java.awt.Color;
48 import java.awt.FlowLayout;
49 import java.awt.Font;
50 import java.awt.event.ActionEvent;
51 import java.awt.Point;
52 import java.awt.Rectangle;
53 import java.beans.PropertyChangeEvent;
54 import java.beans.PropertyChangeListener;
55 import java.io.IOException;
56 import java.net.URL;
57 import java.text.NumberFormat;
58 import java.util.Iterator;
59
60
70 public abstract class AbstractExportDemo extends ViewActionDemo
71 {
72 static final String GRAPH = "Graph";
73 static final String USE_CUSTOM_HEIGHT = "Use Custom Height";
74 static final String USE_CUSTOM_WIDTH = "Use Custom Width";
75 static final String VIEW = "View";
76 static final String SIZE = "Size";
77 static final String CUSTOM_WIDTH = "Custom Width";
78 static final String CUSTOM_HEIGHT = "Custom Height";
79 static final String EMPTY_BORDER_WIDTH = "Empty Border Width";
80 static final String CLIP_REGION = "Clip Region";
81 static final String SELECTION_PAINTING = "Paint Selection Marker";
82
83 protected AbstractExportDemo()
84 {
85 Color color = UIManager.getColor("Panel.background");
86 color = color != null ? color.darker() : Color.GRAY;
87 view.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 0, color));
88
89 view.getGraph2D().getDefaultEdgeRealizer().setTargetArrow(Arrow.STANDARD);
90
91 final JPanel statusBar = createStatusBar();
92 add(statusBar, BorderLayout.SOUTH);
93 }
94
95
98 protected JPanel createStatusBar()
99 {
100 final NumberFormat nf = NumberFormat.getPercentInstance();
101 nf.setMaximumFractionDigits(0);
102
103 final JLabel label = new JLabel("Zoom Factor");
104 final Font font = label.getFont().deriveFont(Font.PLAIN);
105 label.setFont(font);
106 final JLabel zoom = new JLabel();
107 zoom.setFont(font);
108
109 view.getCanvasComponent()
110 .addPropertyChangeListener("Zoom", new PropertyChangeListener()
111 {
112 public void propertyChange(final PropertyChangeEvent e)
113 {
114 zoom.setText(nf.format(e.getNewValue()));
115 }
116 });
117 zoom.setText(nf.format(view.getZoom()));
118
119 final JPanel statusBar = new JPanel(new FlowLayout(FlowLayout.LEADING, 2, 2));
120 statusBar.add(label);
121 statusBar.add(zoom);
122
123 return statusBar;
124 }
125
126
130 protected JToolBar createToolBar()
131 {
132 JToolBar bar = new JToolBar();
133 bar.add(new ClearGraphAction());
134 bar.add(new DeleteSelection());
135 bar.add(new Zoom(1.2));
136 bar.add(new Zoom(0.8));
137 bar.add(new ResetZoom());
138 bar.add(new FitContent());
139 bar.add(new ZoomArea());
140
141 return bar;
142 }
143
144
148 protected JMenuBar createMenuBar()
149 {
150 JMenuBar bar = super.createMenuBar();
151
152 JMenu menu = createSampleGraphMenu();
153 if (menu != null) {
154 bar.add(menu);
155 }
156
157 return bar;
158 }
159
160
163 protected JMenu createSampleGraphMenu()
164 {
165 String[] resources = {
166 "resource/ygraph/problemsolving.graphml",
167 "resource/ygraph/grouping.graphml",
168 "resource/ygraph/visual_edges_fight2.graphml",
169 "resource/ygraph/visual_nodes_yedxp.graphml",
170 "resource/ygraph/visual_features.graphml",
171 };
172 return createSampleGraphMenu(resources);
173 }
174
175
178 JMenu createSampleGraphMenu(final String[] resources)
179 {
180 JMenu menu = new JMenu("Sample Graphs");
181 int resolvedResourceCount = 0;
182 for (int i = 0; i < resources.length; ++i) {
183 final URL resource = getClass().getResource(resources[i]);
184 if (resource != null) {
185 ++resolvedResourceCount;
186 menu.add(new LoadResourceAction(resource));
187 }
188 else {
189 System.err.println("Could not resolve sample resource " + resources[i]);
190 }
191 }
192 if (resolvedResourceCount > 0) {
193 return menu;
194 }
195 else {
196 return null;
197 }
198 }
199
200
205 protected void loadGraph(final URL resource, final boolean updateView)
206 {
207 GraphMLIOHandler ioh = createGraphMLIOHandler();
208 try {
209 view.getGraph2D().clear();
210 ioh.read(view.getGraph2D(), resource);
211 } catch (IOException ioe) {
212 D.show(ioe);
213 }
214
215 if (updateView) {
216 view.fitContent();
217 view.getGraph2D().updateViews();
218 }
219 }
220
221
224 static ImageIcon createIcon(final String resource)
225 {
226 final URL url = AbstractExportDemo.class.getResource(resource);
227 if (url != null) {
228 return new ImageIcon(url);
229 }
230 else {
231 System.err.println("Could not resolve resource " + resource);
232 return null;
233 }
234 }
235
236
237
240 class ClearGraphAction extends AbstractAction
241 {
242 ClearGraphAction()
243 {
244 super("Clear Graph");
245 this.putValue(Action.SHORT_DESCRIPTION, "Clear Graph");
246 URL imageURL = getClass().getResource("resource/New16.gif");
247 if (imageURL != null) {
248 this.putValue(Action.SMALL_ICON, new ImageIcon(imageURL));
249 }
250 }
251
252 public void actionPerformed(ActionEvent e)
253 {
254 view.getGraph2D().clear();
255 view.updateView();
256 }
257 }
258
259
262 class ZoomArea extends AbstractAction
263 {
264 ZoomArea()
265 {
266 super("Zoom Area");
267 this.putValue(Action.SHORT_DESCRIPTION, "Zoom Area");
268 URL imageURL = getClass().getResource("resource/ZoomArea16.gif");
269 if (imageURL != null) {
270 this.putValue(Action.SMALL_ICON, new ImageIcon(imageURL));
271 }
272 }
273
274 public void actionPerformed(ActionEvent e)
275 {
276 Iterator viewModes = view.getViewModes();
277 while (viewModes.hasNext()) {
278 ViewMode viewMode = (ViewMode) viewModes.next();
279 if (viewMode instanceof EditMode) {
280 EditMode editMode = (EditMode) viewMode;
281 editMode.setChild(new AreaZoomMode(), null, null);
282 }
283 }
284 }
285 }
286
287
290 class LoadResourceAction extends AbstractAction
291 {
292 URL resource;
293
294 LoadResourceAction(URL resource)
295 {
296 this.resource = resource;
297 String file = resource.getFile();
298 putValue(Action.NAME, file.substring(file.lastIndexOf('/') + 1));
299 }
300
301 public void actionPerformed(ActionEvent ev)
302 {
303 loadGraph(resource, true);
304 }
305 }
306
307
310 class ExportAction extends AbstractAction
311 {
312 OptionHandler options;
313 OutputHandler outputHandler;
314
315 ExportAction( String name, OutputHandler outputHandler )
316 {
317 putValue(Action.NAME, name);
318 putValue(Action.SMALL_ICON, createIcon("resource/Export16.gif"));
319 putValue(Action.SHORT_DESCRIPTION, name);
320
321
322 this.outputHandler = outputHandler;
323
324
325 final String[] sizes = {
326 "Use Original Size", USE_CUSTOM_WIDTH, USE_CUSTOM_HEIGHT
327 };
328 final String[] clipRegions = {
329 GRAPH, VIEW
330 };
331
332 options = new OptionHandler(name);
334 final OptionGroup group = new OptionGroup();
335 group.setAttribute(OptionGroup.ATTRIBUTE_TITLE, name + " Options");
336 group.addItem(options.addEnum(SIZE, sizes, 0));
337 group.addItem(options.addInt(CUSTOM_WIDTH, 500));
338 group.addItem(options.addInt(CUSTOM_HEIGHT, 500));
339 group.addItem(options.addInt(EMPTY_BORDER_WIDTH, 10));
340 group.addItem(options.addEnum(CLIP_REGION, clipRegions, 0));
341 group.addItem(options.addBool(SELECTION_PAINTING, false));
342
343 final ConstraintManager cm = new ConstraintManager(options);
344 cm.setEnabledOnValueEquals(SIZE, USE_CUSTOM_WIDTH, CUSTOM_WIDTH);
345 cm.setEnabledOnValueEquals(SIZE, USE_CUSTOM_HEIGHT, CUSTOM_HEIGHT);
346 cm.setEnabledOnValueEquals(CLIP_REGION, GRAPH, EMPTY_BORDER_WIDTH);
347 }
348
349 public void actionPerformed( final ActionEvent e )
350 {
351 if (!options.showEditor(view.getFrame())) {
354 return;
355 }
356
357 if (options.getBool(SELECTION_PAINTING)) {
358 outputHandler.removeRenderingHint(YRenderingHints.KEY_SELECTION_PAINTING);
359 } else {
360 outputHandler.addRenderingHint(
361 YRenderingHints.KEY_SELECTION_PAINTING,
362 YRenderingHints.VALUE_SELECTION_PAINTING_OFF);
363 }
364
365 Graph2D graph = view.getGraph2D();
366 Graph2DView viewPort = outputHandler.createDefaultGraph2DView(graph);
367
368 configureViewPort(viewPort);
371 graph.setCurrentView(viewPort);
372
373 export(outputHandler);
376
377 graph.removeView(viewPort);
378 }
379
380
384 void configureViewPort( final Graph2DView viewPort )
385 {
386 Graph2D graph = view.getGraph2D();
387
388 double width = options.getInt(CUSTOM_WIDTH);
389 double height = options.getInt(CUSTOM_HEIGHT);
390 Point viewPoint = viewPort.getViewPoint();
391 double zoom = 1.0;
392
393 if (GRAPH.equals(options.get(CLIP_REGION))) {
394 Rectangle box = graph.getBoundingBox();
395 int border = options.getInt(EMPTY_BORDER_WIDTH);
396 box.width += 2*border;
397 box.height += 2*border;
398 box.x -= border;
399 box.y -= border;
400
401 if (USE_CUSTOM_HEIGHT.equals(options.get(SIZE))) {
402 width = height*box.getWidth()/box.getHeight();
403 } else if (USE_CUSTOM_WIDTH.equals(options.get(SIZE))) {
404 height = width*box.getHeight()/box.getWidth();
405 } else {
406 width = box.getWidth();
407 height = box.getHeight();
408 }
409 zoom = width/box.getWidth();
410 viewPoint = new Point(box.x, box.y);
411 } else if (VIEW.equals(options.get(CLIP_REGION))) {
412 if (USE_CUSTOM_HEIGHT.equals(options.get(SIZE))) {
413 width = height*view.getWidth()/view.getHeight();
414 } else if (USE_CUSTOM_WIDTH.equals(options.get(SIZE))) {
415 height = width*view.getHeight()/view.getWidth();
416 } else {
417 width = view.getWidth();
418 height = view.getHeight();
419 }
420 viewPoint = view.getViewPoint();
421 zoom = view.getZoom()*width/view.getWidth();
422 }
423
424 viewPort.setZoom(zoom);
425 viewPort.setSize((int)width, (int)height);
426 viewPort.setViewPoint(viewPoint.x, viewPoint.y);
427 }
428
429
433 void export( final IOHandler ioh)
434 {
435 JFileChooser chooser = new JFileChooser();
437 chooser.setAcceptAllFileFilterUsed(false);
438 String fne = ioh.getFileNameExtension();
439 chooser.setFileFilter(new SuffixFileFilter(
440 fne, ioh.getFileFormatString()));
441
442 if (chooser.showSaveDialog(AbstractExportDemo.this) ==
443 JFileChooser.APPROVE_OPTION) {
444 String name = chooser.getSelectedFile().toString();
445 if (!name.endsWith(fne)) {
446 name = name + '.' + fne;
447 }
448
449 try {
452 ioh.write(view.getGraph2D(), name);
453 } catch(IOException ex) {
454 D.show(ex);
455 }
456 }
457 }
458 }
459 }