1
14
15 package demo.yext.svg;
16
17 import y.base.Edge;
18 import y.base.Node;
19 import y.base.NodeCursor;
20 import y.geom.YRectangle;
21 import y.layout.EdgeLabelModel;
22 import y.util.D;
23 import y.view.EdgeLabel;
24 import y.view.EdgeRealizer;
25 import y.view.Graph2D;
26 import y.view.Graph2DView;
27 import y.view.NodeRealizer;
28 import yext.svg.view.SVGNodeRealizer;
29
30 import java.awt.BorderLayout;
31 import java.awt.Component;
32 import java.awt.Dimension;
33 import java.awt.Graphics;
34 import java.awt.Graphics2D;
35 import java.awt.Point;
36 import java.awt.RenderingHints;
37 import java.awt.datatransfer.DataFlavor;
38 import java.awt.datatransfer.StringSelection;
39 import java.awt.datatransfer.Transferable;
40 import java.awt.datatransfer.UnsupportedFlavorException;
41 import java.awt.dnd.DnDConstants;
42 import java.awt.dnd.DragGestureEvent;
43 import java.awt.dnd.DragGestureListener;
44 import java.awt.dnd.DragSource;
45 import java.awt.dnd.DropTarget;
46 import java.awt.dnd.DropTargetDragEvent;
47 import java.awt.dnd.DropTargetDropEvent;
48 import java.awt.dnd.DropTargetEvent;
49 import java.awt.dnd.DropTargetListener;
50 import java.io.IOException;
51 import java.net.URL;
52 import java.util.Collection;
53 import java.util.HashMap;
54 import java.util.Map;
55 import javax.swing.DefaultListCellRenderer;
56 import javax.swing.Icon;
57 import javax.swing.JLabel;
58 import javax.swing.JList;
59 import javax.swing.JOptionPane;
60 import javax.swing.JScrollPane;
61 import javax.swing.JSplitPane;
62 import javax.swing.ListCellRenderer;
63 import javax.swing.ListSelectionModel;
64 import javax.swing.event.ListSelectionEvent;
65 import javax.swing.event.ListSelectionListener;
66
67
68
72 public class SVGNodeRealizerDemo extends SVGExportDemo {
73
78 public SVGNodeRealizerDemo() {
79 createGraph();
81
82 view.fitContent();
84 view.updateView();
85
86 createContent();
88 }
89
90
93 private void createContent() {
94 final String[] tmp = {
95 "camera.svg",
96 "cdrom.svg",
97 "computer.svg",
98 "floppy.svg",
99 "harddisk.svg",
100 "ipod.svg",
101 "network.svg",
102 "printer.svg",
103 "scanner.svg",
104 "zipdisk.svg"
105 };
106 double maxW = 90.0;
107 final Map stringToRealizerMap = new HashMap();
108 final Map inverse = new HashMap();
109 for (int i = 0; i < tmp.length; ++i) {
110 final SVGNodeRealizer snr = createSvgRealizer(tmp[i]);
111 if (maxW < snr.getWidth()) {
112 maxW = snr.getWidth();
113 }
114 final URL url = snr.getSVGURL();
115 if (url != null) {
116 final String s = url.toString();
117 stringToRealizerMap.put(s, snr);
118 inverse.put(snr, s);
119 }
120 }
121
122 if (inverse.isEmpty()) {
123 JOptionPane.showMessageDialog(
124 this,
125 "Could not find SVG resources.",
126 "Warning",
127 JOptionPane.WARNING_MESSAGE);
128 System.err.println("Could not find SVG resources.");
129 return;
130 }
131
132 final DragAndDropSupport templates =
133 new DragAndDropSupport(inverse.keySet(), view) {
134 protected String getTextValue( final NodeRealizer selected ) {
135 return (String) inverse.get(selected);
136 }
137
138 protected NodeRealizer createNodeRealizerFromTextValue( final String s ) {
139 return (NodeRealizer) stringToRealizerMap.get(s);
140 }
141 };
142
143 int prefW = (int) (1.5 * maxW);
144 prefW += 10 - (prefW % 10);
145 final JScrollPane templatesScroll = new JScrollPane(templates.getList());
146 templatesScroll.setPreferredSize(
147 new Dimension(prefW, view.getPreferredSize().height));
148 remove(view);
149 add(new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, templatesScroll, view),
150 BorderLayout.CENTER);
151 }
152
153
156 private void createGraph() {
157 final Graph2D graph = view.getGraph2D();
158 final Node computer = graph.createNode(createSvgRealizer("computer.svg"));
159 final Node cdrom = graph.createNode(createSvgRealizer("cdrom.svg"));
160 final Node hd = graph.createNode(createSvgRealizer("harddisk.svg"));
161 final Node printer = graph.createNode(createSvgRealizer("printer.svg"));
162 final Node scanner = graph.createNode(createSvgRealizer("scanner.svg"));
163 final Node ipod = graph.createNode(createSvgRealizer("ipod.svg"));
164
165 final Edge hasCdrom = graph.createEdge(computer, cdrom);
167 final Edge hasHd = graph.createEdge(computer, hd);
168 final Edge hasPrinter = graph.createEdge(computer, printer);
169 final Edge hasScanner = graph.createEdge(computer, scanner);
170 graph.createEdge(computer, ipod);
171
172 double maxW = 0;
174 double maxH = 0;
175
176 NodeRealizer nr;
177 for (NodeCursor nc = graph.nodes(); nc.ok(); nc.next()) {
178 nr = graph.getRealizer(nc.node());
179 if (maxW < nr.getWidth()) {
180 maxW = nr.getWidth();
181 }
182 if (maxH < nr.getHeight()) {
183 maxH = nr.getHeight();
184 }
185 }
186
187 nr = graph.getRealizer(computer);
188 nr.setCenter(0.0, 0.0);
189
190 nr = graph.getRealizer(cdrom);
191 nr.setCenter(maxW, 3 * maxH);
192 nr = graph.getRealizer(hd);
193 nr.setCenter(-maxW, 3 * maxH);
194
195 nr = graph.getRealizer(printer);
196 nr.setCenter(3 * maxW, maxH);
197 nr = graph.getRealizer(scanner);
198 nr.setCenter(3 * maxW, -maxH);
199
200 nr = graph.getRealizer(ipod);
201 nr.setCenter(-3 * maxW, 0.0);
202
203 EdgeRealizer er;
204 er = graph.getRealizer(hasCdrom);
205 er.appendBend(0.0, 2 * maxH);
206 er.appendBend(maxW, 2 * maxH);
207
208 er = graph.getRealizer(hasHd);
209 er.appendBend(0.0, 2 * maxH);
210 er.appendBend(-maxW, 2 * maxH);
211 er.setLabelText("Storage Devices");
212 double[] size;
213 size = getLabelSize(er);
214 setLabelPosition(er, -size[0] * 0.5, 2 * maxH + 5);
215
216 er = graph.getRealizer(hasPrinter);
217 er.appendBend(2 * maxW, 0.0);
218 er.appendBend(2 * maxW, maxH);
219
220 er = graph.getRealizer(hasScanner);
221 er.appendBend(2 * maxW, 0.0);
222 er.appendBend(2 * maxW, -maxH);
223 er.setLabelText("Periphery");
224 size = getLabelSize(er);
225 setLabelPosition(er, 2 * maxW - size[0] - 5, -size[1] - 5);
226 }
227
228
233 private static double[] getLabelSize( final EdgeRealizer er ) {
234 final EdgeLabel label = er.getLabel();
235 final YRectangle bounds = label.getBox();
236 final double w = bounds.getWidth();
237 final double h = bounds.getHeight();
238 return new double[]{w, h};
239 }
240
241
245 private static void setLabelPosition(
246 final EdgeRealizer er, final double x, final double y
247 ) {
248 final Edge edge = er.getEdge();
249 final Graph2D graph = (Graph2D) edge.getGraph();
250 final EdgeLabel label = er.getLabel();
251
252 final YRectangle oldBounds = label.getBox();
253 final YRectangle newBounds =
254 new YRectangle(x, y, oldBounds.getWidth(), oldBounds.getHeight());
255
256 label.setModel(EdgeLabel.FREE);
257 final EdgeLabelModel model = label.getLabelModel();
258 final Object param =
259 model.createModelParameter(newBounds, er,
260 graph.getRealizer(edge.source()),
261 graph.getRealizer(edge.target()));
262 label.setModelParameter(param);
263 }
264
265
269 private static SVGNodeRealizer createSvgRealizer( final String icon ) {
270 URL url = null;
271 try {
272 url = SVGNodeRealizerDemo.class.getResource("resource/svg/" + icon);
273 } catch (Exception ex) {
274 System.err.println("Can't find SVG resource resource/svg/" + icon);
275 ex.printStackTrace(System.err);
276 url = null;
277 }
278
279 if (url != null) {
280 return new SVGNodeRealizer(url);
281 } else {
282 final SVGNodeRealizer nr = new SVGNodeRealizer();
283 nr.setLabelText(icon);
284 return nr;
285 }
286 }
287
288
289 public static void main( final String[] args ) {
290 initLnF();
291
292 (new SVGNodeRealizerDemo()).start();
293 }
294
295
300
301
305 public abstract static class DragAndDropSupport {
306 private final JList realizerList;
307
308 public DragAndDropSupport( Collection nodeRealizerList, final Graph2DView view ) {
309 this(nodeRealizerList.toArray(), view);
310 }
311
312 public DragAndDropSupport( Object[] nodeRealizers, final Graph2DView view ) {
313 realizerList = new JList(nodeRealizers);
315 realizerList.setCellRenderer(new NodeRealizerCellRenderer());
316
317 realizerList.addListSelectionListener(new ListSelectionListener() {
319 public void valueChanged( ListSelectionEvent e ) {
320 if (realizerList.getSelectedValue() instanceof NodeRealizer) {
321 nodeRealizerSelected(view);
322 }
323 }
324 });
325
326 realizerList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
327 realizerList.setSelectedIndex(0);
328
329 final DragSource dragSource = new DragSource();
332 dragSource.createDefaultDragGestureRecognizer(realizerList, DnDConstants.ACTION_MOVE,
333 new DragGestureListener() {
334 public void dragGestureRecognized( DragGestureEvent event ) {
335 Object selected = realizerList.getSelectedValue();
336 final String textValue = getTextValue((NodeRealizer) selected);
337 if (textValue != null) {
338 StringSelection text = new StringSelection(textValue);
339 dragSource.startDrag(event, DragSource.DefaultMoveDrop, text, null);
341 }
342 }
343 });
344
345 DropTarget dropTarget = new DropTarget(view.getCanvasComponent(),
348 new DropTargetListener() {
349
350 public void dragEnter( DropTargetDragEvent event ) {
352 if (checkStringFlavor(event)) {
353 event.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
354 } else {
355 event.rejectDrag();
356 }
357 }
358
359 private boolean checkStringFlavor( DropTargetDragEvent event ) {
361 DataFlavor[] flavors = event.getCurrentDataFlavors();
363 for (int i = 0; i < flavors.length; i++) {
364 if (flavors[i] == DataFlavor.stringFlavor) {
365 return true;
366 }
367 }
368 return false;
369 }
370
371 public void drop( DropTargetDropEvent event ) {
373 try {
374 boolean foundStringFlavor = false;
376 DataFlavor[] flavors = event.getCurrentDataFlavors();
377 for (int i = 0; i < flavors.length; i++) {
378 if (flavors[i] == DataFlavor.stringFlavor) {
379 foundStringFlavor = true;
380 break;
381 }
382 }
383 if (foundStringFlavor) {
384 event.acceptDrop(event.getDropAction());
385 } else {
386 event.rejectDrop();
387 return;
388 }
389 } catch (RuntimeException rex) {
390 event.rejectDrop();
391 D.show(rex);
392 }
393 try {
394 Transferable transferable = event.getTransferable();
395 String s = (String) transferable.getTransferData(DataFlavor.stringFlavor);
396 Point p = event.getLocation();
397 NodeRealizer r = createNodeRealizerFromTextValue(s);
398 if (r != null) {
399 final double worldCoordX = view.toWorldCoordX(p.x);
401 final double worldCoordY = view.toWorldCoordY(p.y);
402 event.dropComplete(dropRealizer(view, r, worldCoordX, worldCoordY));
403 } else {
404 event.dropComplete(false);
406 }
407 } catch (IOException ioe) {
408 event.dropComplete(false);
410 D.show(ioe);
411 } catch (UnsupportedFlavorException ufe) {
412 event.dropComplete(false);
414 D.show(ufe);
415 } catch (RuntimeException x) {
416 event.dropComplete(false);
417 throw x;
418 }
419 }
420
421 public void dragExit( DropTargetEvent dte ) {
423 }
424
425 public void dropActionChanged( DropTargetDragEvent dtde ) {
427 dragEnter(dtde);
428 }
429
430 public void dragOver( DropTargetDragEvent dtde ) {
432 dragEnter(dtde);
433 }
434 });
435 }
436
437
444 protected abstract String getTextValue( NodeRealizer selected );
445
446
453 protected abstract NodeRealizer createNodeRealizerFromTextValue( String s );
454
455
461 protected boolean dropRealizer( Graph2DView view, NodeRealizer r, double worldCoordX, double worldCoordY ) {
462 final Graph2D graph = view.getGraph2D();
463 r = r.createCopy();
464
465 if (view.getGridMode()) {
466 double gridSize = view.getGridResolution();
467 double x = Math.floor(worldCoordX / gridSize + 0.5) * gridSize;
468 double y = Math.floor(worldCoordY / gridSize + 0.5) * gridSize;
469
470 r.setCenter(x, y);
471 } else {
472 r.setCenter(worldCoordX, worldCoordY);
473 }
474 graph.createNode(r);
475 view.updateView();
476 return true;
477 }
478
479
483 protected void nodeRealizerSelected( Graph2DView view ) {
484 view.getGraph2D().setDefaultNodeRealizer((NodeRealizer) realizerList.getSelectedValue());
485 }
486
487
490 public JList getList() {
491 return realizerList;
492 }
493 }
494
495
496
500 public static final class NodeRealizerCellRenderer
501 implements ListCellRenderer {
502
503 private DefaultListCellRenderer renderer = new DefaultListCellRenderer();
504 private NodeRealizerIcon icon = new NodeRealizerIcon();
505
506 public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus ) {
507 JLabel label = (JLabel) renderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
508 icon.setRealizer((NodeRealizer) value);
509 label.setText("");
510 label.setIcon(icon);
511 return label;
512 }
513
514
517 public static final class NodeRealizerIcon implements Icon {
518 private static final int inset = 10;
519 private NodeRealizer realizer;
520
521 public void setRealizer( NodeRealizer realizer ) {
522 this.realizer = realizer;
523 }
524
525 public int getIconWidth() {
526 return (int) (realizer.getWidth() + inset);
527 }
528
529 public int getIconHeight() {
530 return (int) (realizer.getHeight() + inset);
531 }
532
533 public void paintIcon( Component c, Graphics g, int x, int y ) {
534 realizer.setLocation(x + inset * 0.5d, y + inset * 0.5d);
535 g = g.create();
536 try {
537 final Graphics2D gfx = (Graphics2D) g;
538 gfx.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
539 realizer.paint(gfx);
540 } finally {
541 g.dispose();
542 }
543 }
544 }
545 }
546 }
547