|
1 /*************************************************************************** |
|
2 Title: graphbrowser/GraphView.java |
|
3 Author: Stefan Berghofer, TU Muenchen |
|
4 Options: :tabSize=4: |
|
5 |
|
6 This class defines the window in which the graph is displayed. It |
|
7 contains methods for handling events such as collapsing / uncollapsing |
|
8 nodes of the graph. |
|
9 ***************************************************************************/ |
|
10 |
|
11 package isabelle.graphbrowser; |
|
12 |
|
13 import java.awt.*; |
|
14 import java.awt.event.*; |
|
15 import java.io.*; |
|
16 import java.util.*; |
|
17 |
|
18 public class GraphView extends Canvas implements MouseListener, MouseMotionListener { |
|
19 Graph gra, gra2; |
|
20 GraphBrowser browser; |
|
21 Vertex v = null; |
|
22 Vector collapsed = new Vector(10,10); |
|
23 Vector collapsedDirs = new Vector(10,10); |
|
24 TreeBrowser tb; |
|
25 long timestamp; |
|
26 Vertex highlighted = null; |
|
27 Dimension size; |
|
28 boolean parent_needs_layout; |
|
29 Font font; |
|
30 |
|
31 public void setTreeBrowser(TreeBrowser br) { |
|
32 tb=br; |
|
33 } |
|
34 |
|
35 public GraphBrowser getBrowser() { return browser; } |
|
36 |
|
37 public Graph getGraph() { return gra; } |
|
38 |
|
39 public Graph getOriginalGraph() { return gra2; } |
|
40 |
|
41 public GraphView(Graph gr, GraphBrowser br, Font f) { |
|
42 gra2=gr; |
|
43 browser=br; |
|
44 gra=(Graph)(gra2.clone()); |
|
45 parent_needs_layout = true; |
|
46 size = new Dimension(0, 0); |
|
47 font = f; |
|
48 addMouseListener(this); |
|
49 addMouseMotionListener(this); |
|
50 } |
|
51 |
|
52 public void PS(String fname,boolean printable) throws IOException { |
|
53 Graph gra3 = (Graph)gra.clone(); |
|
54 gra3.layout(null); |
|
55 gra3.PS(fname,printable); |
|
56 } |
|
57 |
|
58 public void paint(Graphics g) { |
|
59 g.setFont(font); |
|
60 gra.draw(g); |
|
61 if (highlighted!=null) highlighted.drawBox(g,Color.white); |
|
62 size = new Dimension(gra.max_x-gra.min_x, gra.max_y-gra.min_y); |
|
63 if (parent_needs_layout) { |
|
64 parent_needs_layout = false; |
|
65 getParent().doLayout(); |
|
66 } |
|
67 } |
|
68 |
|
69 public Dimension getPreferredSize() { |
|
70 return size; |
|
71 } |
|
72 |
|
73 public void mouseMoved(MouseEvent evt) { |
|
74 int x = evt.getX() + gra.min_x; |
|
75 int y = evt.getY() + gra.min_y; |
|
76 |
|
77 Vertex v2=gra.vertexAt(x,y); |
|
78 Graphics g=getGraphics(); |
|
79 g.setFont(font); |
|
80 g.translate(-gra.min_x,-gra.min_y); |
|
81 if (highlighted!=null) { |
|
82 highlighted.drawBox(g,Color.lightGray); |
|
83 highlighted=null; |
|
84 } |
|
85 if (v2!=v) { |
|
86 if (v!=null) v.removeButtons(g); |
|
87 if (v2!=null) v2.drawButtons(g); |
|
88 v=v2; |
|
89 } |
|
90 } |
|
91 |
|
92 public void mouseDragged(MouseEvent evt) {} |
|
93 |
|
94 /*****************************************************************/ |
|
95 /* This method is called if successor / predecessor nodes (whose */ |
|
96 /* numbers are stored in Vector c) of a certain node should be */ |
|
97 /* displayed again */ |
|
98 /*****************************************************************/ |
|
99 |
|
100 void uncollapse(Vector c) { |
|
101 collapsed.removeElement(c); |
|
102 collapseNodes(); |
|
103 } |
|
104 |
|
105 /*****************************************************************/ |
|
106 /* This method is called by class TreeBrowser when directories */ |
|
107 /* are collapsed / uncollapsed by the user */ |
|
108 /*****************************************************************/ |
|
109 |
|
110 public void collapseDir(Vector v) { |
|
111 collapsedDirs=v; |
|
112 |
|
113 collapseNodes(); |
|
114 } |
|
115 |
|
116 /*****************************************************************/ |
|
117 /* Inflate node again */ |
|
118 /*****************************************************************/ |
|
119 |
|
120 public void inflateNode(Vector c) { |
|
121 Enumeration e1; |
|
122 |
|
123 e1=collapsedDirs.elements(); |
|
124 while (e1.hasMoreElements()) { |
|
125 Directory d=(Directory)(e1.nextElement()); |
|
126 if (d.collapsed==c) { |
|
127 tb.selectNode(d.getNode()); |
|
128 return; |
|
129 } |
|
130 } |
|
131 |
|
132 collapsed.removeElement(c); |
|
133 e1=gra2.getVertices(); |
|
134 while (e1.hasMoreElements()) { |
|
135 Vertex vx=(Vertex)(e1.nextElement()); |
|
136 if (vx.getUp()==c) vx.setUp(null); |
|
137 if (vx.getDown()==c) vx.setDown(null); |
|
138 } |
|
139 |
|
140 collapseNodes(); |
|
141 relayout(); |
|
142 } |
|
143 |
|
144 public void relayout() { |
|
145 Graphics g = getGraphics(); |
|
146 g.setFont(font); |
|
147 browser.showWaitMessage(); |
|
148 highlighted=null; |
|
149 gra.layout(g); |
|
150 v=null; |
|
151 parent_needs_layout = true; |
|
152 update(g); |
|
153 browser.showReadyMessage(); |
|
154 } |
|
155 |
|
156 public void focusToVertex(int n) { |
|
157 Vertex vx=gra.getVertexByNum(n); |
|
158 if (vx!=null) { |
|
159 ScrollPane scrollp = (ScrollPane)(getParent()); |
|
160 Dimension vpsize = scrollp.getViewportSize(); |
|
161 |
|
162 int x = vx.getX()-gra.min_x; |
|
163 int y = vx.getY()-gra.min_y; |
|
164 int offset_x = Math.min(scrollp.getHAdjustable().getMaximum(), |
|
165 Math.max(0,x-vpsize.width/2)); |
|
166 int offset_y = Math.min(scrollp.getVAdjustable().getMaximum(), |
|
167 Math.max(0,y-vpsize.height/2)); |
|
168 |
|
169 Graphics g=getGraphics(); |
|
170 g.setFont(font); |
|
171 g.translate(-gra.min_x,-gra.min_y); |
|
172 if (highlighted!=null) highlighted.drawBox(g,Color.lightGray); |
|
173 vx.drawBox(g,Color.white); |
|
174 highlighted=vx; |
|
175 scrollp.setScrollPosition(offset_x, offset_y); |
|
176 } |
|
177 } |
|
178 |
|
179 /*****************************************************************/ |
|
180 /* Create new graph with collapsed nodes */ |
|
181 /*****************************************************************/ |
|
182 |
|
183 public void collapseNodes() { |
|
184 Enumeration e1=collapsed.elements(); |
|
185 gra=(Graph)(gra2.clone()); |
|
186 |
|
187 while (e1.hasMoreElements()) { |
|
188 Vector v1=(Vector)(e1.nextElement()); |
|
189 Vector v2=gra.decode(v1); |
|
190 if (!v2.isEmpty()) gra.collapse(v2,"[. . . .]",v1); |
|
191 } |
|
192 |
|
193 e1=collapsedDirs.elements(); |
|
194 |
|
195 while (e1.hasMoreElements()) { |
|
196 Directory d=(Directory)(e1.nextElement()); |
|
197 Vector v=gra.decode(d.getCollapsed()); |
|
198 if (!v.isEmpty()) |
|
199 gra.collapse(v,"["+d.getName()+"]",d.getCollapsed()); |
|
200 } |
|
201 } |
|
202 |
|
203 public void mouseClicked(MouseEvent evt) { |
|
204 Vector code = null; |
|
205 Vertex v2; |
|
206 int x = evt.getX() + gra.min_x; |
|
207 int y = evt.getY() + gra.min_y; |
|
208 |
|
209 if (v!=null) { |
|
210 int num=v.getNumber(); |
|
211 v2=gra2.getVertexByNum(num); |
|
212 if (v.leftButton(x,y)) { |
|
213 if (v.getUp()!=null) { |
|
214 code=v.getUp(); |
|
215 v2.setUp(null); |
|
216 v=null; |
|
217 uncollapse(code); |
|
218 relayout(); |
|
219 focusToVertex(num); |
|
220 } else { |
|
221 Vector vs=v2.getPreds(); |
|
222 code=gra2.encode(vs); |
|
223 v.setUp(code);v2.setUp(code); |
|
224 v=null; |
|
225 collapsed.insertElementAt(code,0); |
|
226 collapseNodes(); |
|
227 relayout(); |
|
228 focusToVertex(num); |
|
229 } |
|
230 } else if (v.rightButton(x,y)) { |
|
231 if (v.getDown()!=null) { |
|
232 code=v.getDown(); |
|
233 v2.setDown(null); |
|
234 v=null; |
|
235 uncollapse(code); |
|
236 relayout(); |
|
237 focusToVertex(num); |
|
238 } else { |
|
239 Vector vs=v2.getSuccs(); |
|
240 code=gra2.encode(vs); |
|
241 v.setDown(code);v2.setDown(code); |
|
242 v=null; |
|
243 collapsed.insertElementAt(code,0); |
|
244 collapseNodes(); |
|
245 relayout(); |
|
246 focusToVertex(num); |
|
247 } |
|
248 } else if (v.getInflate()!=null) { |
|
249 inflateNode(v.getInflate()); |
|
250 v=null; |
|
251 } else { |
|
252 if (evt.getWhen()-timestamp < 400 && !(v.getPath().equals(""))) |
|
253 browser.viewFile(v.getPath()); |
|
254 timestamp=evt.getWhen(); |
|
255 } |
|
256 } |
|
257 } |
|
258 |
|
259 public void mouseExited(MouseEvent evt) { |
|
260 Graphics g=getGraphics(); |
|
261 g.setFont(font); |
|
262 g.translate(-gra.min_x,-gra.min_y); |
|
263 if (highlighted!=null) { |
|
264 highlighted.drawBox(g,Color.lightGray); |
|
265 highlighted=null; |
|
266 } |
|
267 if (v!=null) v.removeButtons(g); |
|
268 v=null; |
|
269 } |
|
270 |
|
271 public void mouseEntered(MouseEvent evt) {} |
|
272 |
|
273 public void mousePressed(MouseEvent evt) {} |
|
274 |
|
275 public void mouseReleased(MouseEvent evt) {} |
|
276 } |