]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.graphviz/src/org/simantics/graphviz/drawable/GraphDrawable.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.graphviz / src / org / simantics / graphviz / drawable / GraphDrawable.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.graphviz.drawable;\r
13 \r
14 import java.awt.Graphics2D;\r
15 import java.awt.geom.Rectangle2D;\r
16 import java.util.concurrent.Semaphore;\r
17 import java.util.concurrent.TimeUnit;\r
18 \r
19 import org.simantics.graphviz.Graph;\r
20 import org.simantics.graphviz.Graphs;\r
21 import org.simantics.graphviz.continuation.Computation;\r
22 import org.simantics.graphviz.continuation.Continuation;\r
23 import org.simantics.graphviz.internal.xdot.DrawCommand;\r
24 import org.simantics.graphviz.internal.xdot.DrawCommandParser;\r
25 \r
26 /**\r
27  * A drawable that draws a given graph.\r
28  * \r
29  * @author Hannu Niemist�\r
30  */\r
31 public class GraphDrawable implements Drawable {\r
32 \r
33         private static String DEFAULT_ALGORITHM = "dot";\r
34         \r
35         DrawCommand[] commands;\r
36         Rectangle2D bounds;\r
37         \r
38         \r
39         private Graph graph;\r
40         private String algorithm;\r
41         \r
42         public GraphDrawable(Graph graph, String algorithm) {\r
43                 setGraph(graph, algorithm);\r
44         }\r
45         \r
46         public GraphDrawable(Graph graph) {\r
47                 setGraph(graph);\r
48         }\r
49         \r
50         public GraphDrawable() {\r
51                 commands = new DrawCommand[0];\r
52                 bounds = new Rectangle2D.Double(0, 0, 100, 100);\r
53         }\r
54         \r
55         \r
56         public Graph getGraph() {\r
57                 return graph;\r
58         }\r
59         \r
60         public String getAlgorithm() {\r
61                 return algorithm;\r
62         }\r
63         /**\r
64          * Sets a new graph to be drawn. This operation may take a while. It can\r
65          * be called from any thread.\r
66          * @param graph\r
67          */\r
68         public void setGraph(Graph graph) {\r
69                 setGraph(graph, DEFAULT_ALGORITHM);\r
70         }\r
71         \r
72         /**\r
73          * Sets a new graph to be drawn. This operation may take a while. It can\r
74          * be called from any thread.\r
75          * @param graph\r
76          */\r
77         public Computation<Graph> setGraph(Graph graph, String algorithm) {\r
78             this.graph = graph;\r
79         this.algorithm = algorithm;\r
80             Computation<Graph> computation = Graphs.createXDot(graph, algorithm);\r
81             final Semaphore semaphore = new Semaphore(0);\r
82             computation.addContinuation(new Continuation<Graph>() {\r
83             @Override\r
84             public void succeeded(Graph xgraph) {\r
85                 commands = DrawCommandParser.parse(xgraph);\r
86                 readBoundingBox(xgraph);\r
87                 semaphore.release();\r
88             }\r
89 \r
90             @Override\r
91             public void failed(Exception exception) {\r
92                 exception.printStackTrace();\r
93                 semaphore.release();\r
94             }\r
95             });\r
96             try {\r
97                         semaphore.tryAcquire(5L, TimeUnit.SECONDS);\r
98                 } catch (InterruptedException e) {\r
99                         e.printStackTrace();\r
100                 }\r
101             return computation;\r
102         }\r
103         \r
104         private void readBoundingBox(Graph graph) {\r
105                 String[] parts = graph.get("bb").split(",");\r
106                 double minX = Double.parseDouble(parts[0]);\r
107                 double maxY = -Double.parseDouble(parts[1]);\r
108                 double maxX = Double.parseDouble(parts[2]);\r
109                 double minY = -Double.parseDouble(parts[3]);\r
110                 bounds = new Rectangle2D.Double(minX, minY, maxX-minX, maxY-minY);\r
111         }\r
112         \r
113         @Override\r
114         public synchronized Rectangle2D getBounds() {\r
115             if(bounds == null)\r
116                 System.err.println("bounds == null");\r
117                 return bounds;\r
118         }\r
119         \r
120         @Override\r
121         public synchronized void draw(Graphics2D g, Rectangle2D area) {\r
122                 for(DrawCommand command : commands)\r
123                         command.draw(g);\r
124         }\r
125         \r
126 }\r