Lines 40-196
Link Here
|
40 |
*/ |
40 |
*/ |
41 |
package org.netbeans.modules.visual.graph.layout; |
41 |
package org.netbeans.modules.visual.graph.layout; |
42 |
|
42 |
|
|
|
43 |
import java.awt.Point; |
44 |
import java.awt.Rectangle; |
43 |
import org.netbeans.api.visual.graph.layout.GraphLayout; |
45 |
import org.netbeans.api.visual.graph.layout.GraphLayout; |
44 |
import org.netbeans.api.visual.graph.layout.UniversalGraph; |
46 |
import org.netbeans.api.visual.graph.layout.UniversalGraph; |
45 |
import org.netbeans.api.visual.widget.Widget; |
47 |
import org.netbeans.api.visual.widget.Widget; |
46 |
|
48 |
|
47 |
import java.awt.*; |
49 |
import java.util.ArrayList; |
48 |
import java.util.*; |
50 |
import java.util.Collection; |
|
|
51 |
import java.util.HashMap; |
52 |
import java.util.HashSet; |
53 |
import java.util.List; |
54 |
import java.util.Map; |
49 |
|
55 |
|
50 |
/** |
56 |
/** |
51 |
* @author David Kaspar |
57 |
* @author David Kaspar |
52 |
*/ |
58 |
*/ |
53 |
public final class TreeGraphLayout<N,E> extends GraphLayout<N,E> { |
59 |
public final class TreeGraphLayout<N, E> extends GraphLayout<N, E> { |
54 |
|
60 |
|
55 |
private int originX; |
61 |
private int originX; |
56 |
private int originY; |
62 |
private int originY; |
57 |
private int verticalGap; |
63 |
private int verticalGap; |
58 |
private int horizontalGap; |
64 |
private int horizontalGap; |
59 |
private boolean vertical; |
65 |
private boolean vertical; |
|
|
66 |
private boolean minimizeGap; |
67 |
private N rootNode; |
68 |
private Alignment alignment; |
60 |
|
69 |
|
61 |
private N rootNode; |
70 |
public TreeGraphLayout(int originX, int originY, int verticalGap, |
62 |
|
71 |
int horizontalGap, boolean vertical, boolean minimizeGap) { |
63 |
public TreeGraphLayout (int originX, int originY, int verticalGap, int horizontalGap, boolean vertical) { |
72 |
if (vertical) { |
64 |
this.originX = originX; |
73 |
this.originX = originX; |
65 |
this.originY = originY; |
74 |
this.originY = originY; |
66 |
this.verticalGap = verticalGap; |
75 |
this.verticalGap = verticalGap; |
67 |
this.horizontalGap = horizontalGap; |
76 |
this.horizontalGap = horizontalGap; |
|
|
77 |
} else { |
78 |
this.originX = originY; |
79 |
this.originY = originX; |
80 |
this.verticalGap = horizontalGap; |
81 |
this.horizontalGap = verticalGap; |
82 |
} |
68 |
this.vertical = vertical; |
83 |
this.vertical = vertical; |
|
|
84 |
this.minimizeGap = minimizeGap; |
85 |
this.alignment = Alignment.TOP; |
69 |
} |
86 |
} |
70 |
|
87 |
|
71 |
public void setRootNode (N rootNode) { |
88 |
public TreeGraphLayout(int originX, int originY, int verticalGap, |
|
|
89 |
int horizontalGap, boolean vertical, boolean minimizeGap, |
90 |
Alignment alignment) { |
91 |
this(originX, originY, verticalGap, horizontalGap, vertical, minimizeGap); |
92 |
this.alignment = alignment; |
93 |
} |
94 |
|
95 |
public void setRootNode(N rootNode) { |
72 |
this.rootNode = rootNode; |
96 |
this.rootNode = rootNode; |
73 |
} |
97 |
} |
74 |
|
98 |
|
75 |
public void setProperties (int originX, int originY, int verticalGap, int horizontalGap, boolean vertical) { |
99 |
public void setProperties(int originX, int originY, int verticalGap, |
76 |
this.originX = originX; |
100 |
int horizontalGap, boolean vertical, boolean minimizeGap) { |
77 |
this.originY = originY; |
101 |
if (vertical) { |
78 |
this.verticalGap = verticalGap; |
102 |
this.originX = originX; |
79 |
this.horizontalGap = horizontalGap; |
103 |
this.originY = originY; |
|
|
104 |
this.verticalGap = verticalGap; |
105 |
this.horizontalGap = horizontalGap; |
106 |
} else { |
107 |
this.originX = originY; |
108 |
this.originY = originX; |
109 |
this.verticalGap = horizontalGap; |
110 |
this.horizontalGap = verticalGap; |
111 |
} |
80 |
this.vertical = vertical; |
112 |
this.vertical = vertical; |
|
|
113 |
this.minimizeGap = minimizeGap; |
81 |
} |
114 |
} |
82 |
|
115 |
|
83 |
protected void performGraphLayout (UniversalGraph<N, E> graph) { |
116 |
public void setProperties(int originX, int originY, int verticalGap, |
84 |
if (rootNode == null) |
117 |
int horizontalGap, boolean vertical, boolean minimizeGap, |
|
|
118 |
Alignment alignment) { |
119 |
this.setProperties(originX, originY, verticalGap, horizontalGap, vertical, minimizeGap); |
120 |
this.alignment = alignment; |
121 |
} |
122 |
|
123 |
protected void performGraphLayout(UniversalGraph<N, E> graph) { |
124 |
if (rootNode == null) { |
85 |
return; |
125 |
return; |
86 |
Collection<N> allNodes = graph.getNodes (); |
126 |
} |
87 |
if (! allNodes.contains (rootNode)) |
127 |
Collection<N> allNodes = graph.getNodes(); |
|
|
128 |
if (!allNodes.contains(rootNode)) { |
88 |
return; |
129 |
return; |
89 |
ArrayList<N> nodesToResolve = new ArrayList<N> (allNodes); |
130 |
} |
|
|
131 |
ArrayList<N> nodesToResolve = new ArrayList<N>(allNodes); |
90 |
|
132 |
|
91 |
HashSet<N> loadedSet = new HashSet<N> (); |
133 |
HashSet<N> loadedSet = new HashSet<N>(); |
92 |
Node root = new Node (graph, rootNode, loadedSet); |
134 |
Node root = new Node(graph, rootNode, loadedSet); |
93 |
nodesToResolve.removeAll (loadedSet); |
135 |
nodesToResolve.removeAll(loadedSet); |
94 |
if (vertical) { |
136 |
|
95 |
root.allocateHorizontally (graph); |
137 |
Map<Integer, Integer> map = root.getMaxSpaceForEveryLevel(graph); |
96 |
root.resolveVertically (originX, originY); |
138 |
|
97 |
} else { |
139 |
List<Node.LeftRight> envelope = root.layout(originX, originY, map, 0); |
98 |
root.allocateVertically (graph); |
140 |
|
99 |
root.resolveHorizontally (originX, originY); |
141 |
// correction of originX, if needed |
|
|
142 |
int moveDistance = Integer.MIN_VALUE; |
143 |
// get the most left position and determine the distance to move |
144 |
for (Node.LeftRight leftRight : envelope) { |
145 |
if (leftRight.getLeft() < originX && originX - leftRight.getLeft() > moveDistance) { |
146 |
moveDistance = originX - leftRight.getLeft(); |
147 |
} |
100 |
} |
148 |
} |
101 |
|
149 |
|
102 |
final HashMap<N, Point> resultPosition = new HashMap<N, Point> (); |
150 |
if (moveDistance == Integer.MIN_VALUE) { |
103 |
root.upload (resultPosition); |
151 |
moveDistance = 0; |
|
|
152 |
} |
153 |
|
154 |
if (!vertical) { |
155 |
root.invert(moveDistance); |
156 |
} else { |
157 |
root.relativeBoundsCorrectionX(moveDistance); |
158 |
} |
159 |
|
160 |
final HashMap<N, Point> resultPosition = new HashMap<N, Point>(); |
161 |
root.upload(resultPosition); |
104 |
|
162 |
|
105 |
for (N node : nodesToResolve) { |
163 |
for (N node : nodesToResolve) { |
106 |
Point position = new Point (); |
164 |
Point position = new Point(); |
107 |
// TODO - resolve others |
165 |
// TODO - resolve others |
108 |
resultPosition.put (node, position); |
166 |
resultPosition.put(node, position); |
109 |
} |
167 |
} |
110 |
|
168 |
|
111 |
for (Map.Entry<N, Point> entry : resultPosition.entrySet ()) |
169 |
for (Map.Entry<N, Point> entry : resultPosition.entrySet()) { |
112 |
setResolvedNodeLocation (graph, entry.getKey (), entry.getValue ()); |
170 |
setResolvedNodeLocation(graph, entry.getKey(), entry.getValue()); |
|
|
171 |
} |
113 |
} |
172 |
} |
114 |
|
173 |
|
115 |
protected void performNodesLayout (UniversalGraph<N, E> universalGraph, Collection<N> nodes) { |
174 |
protected void performNodesLayout(UniversalGraph<N, E> universalGraph, |
116 |
throw new UnsupportedOperationException (); // TODO |
175 |
Collection<N> nodes) { |
|
|
176 |
throw new UnsupportedOperationException(); // TODO |
177 |
} |
178 |
|
179 |
public enum Alignment { |
180 |
TOP, CENTER, BOTTOM |
117 |
} |
181 |
} |
118 |
|
182 |
|
119 |
private class Node { |
183 |
private class Node { |
120 |
|
184 |
|
121 |
private N node; |
185 |
private N node; |
122 |
private ArrayList<Node> children; |
186 |
private ArrayList<Node> children; |
|
|
187 |
private Rectangle relativeBounds; |
188 |
private Point point; |
189 |
private int space; |
123 |
|
190 |
|
124 |
private Rectangle relativeBounds; |
191 |
private Node(UniversalGraph<N, E> graph, N node, HashSet<N> loadedSet) { |
125 |
private int space; |
192 |
this.node = node; |
126 |
private int totalSpace; |
193 |
loadedSet.add(node); |
127 |
private Point point; |
|
|
128 |
|
194 |
|
129 |
private Node (UniversalGraph<N, E> graph, N node, HashSet<N> loadedSet) { |
195 |
children = new ArrayList<Node>(); |
130 |
this.node = node; |
196 |
for (E edge : graph.findNodeEdges(node, true, false)) { |
131 |
loadedSet.add (node); |
197 |
N child = graph.getEdgeTarget(edge); |
132 |
|
198 |
if (child != null && !loadedSet.contains(child)) { |
133 |
children = new ArrayList<Node> (); |
199 |
children.add(new Node(graph, child, loadedSet)); |
134 |
for (E edge: graph.findNodeEdges (node, true, false)) { |
200 |
} |
135 |
N child = graph.getEdgeTarget (edge); |
|
|
136 |
if (child != null && ! loadedSet.contains (child)) |
137 |
children.add (new Node (graph, child, loadedSet)); |
138 |
} |
201 |
} |
139 |
} |
202 |
} |
140 |
|
203 |
|
141 |
private int allocateHorizontally (UniversalGraph<N, E> graph) { |
204 |
/** |
142 |
Widget widget = graph.getScene ().findWidget (node); |
205 |
* This class represents an element of the envelope of a (sub)tree. |
143 |
widget.getLayout ().layout (widget); |
206 |
*/ |
144 |
relativeBounds = widget.getPreferredBounds (); |
207 |
private class LeftRight { |
145 |
space = 0; |
208 |
|
146 |
for (int i = 0; i < children.size (); i++) { |
209 |
/** the most left coordinate of this element of the envelope. */ |
147 |
if (i > 0) |
210 |
private int left; |
148 |
space += horizontalGap; |
211 |
/** hte most right coordinate of this element of the envelope. */ |
149 |
space += children.get (i).allocateHorizontally (graph); |
212 |
private int right; |
|
|
213 |
|
214 |
/** |
215 |
* Constructor |
216 |
* |
217 |
* @param left the most left coordinate of this {@link LeftRight}. |
218 |
* @param right the most right coordinate of this {@link LeftRight}. |
219 |
*/ |
220 |
public LeftRight(int left, int right) { |
221 |
this.left = left; |
222 |
this.right = right; |
150 |
} |
223 |
} |
151 |
totalSpace = Math.max (space, relativeBounds.width); |
|
|
152 |
return totalSpace; |
153 |
} |
154 |
|
224 |
|
155 |
private void resolveVertically (int x, int y) { |
225 |
/** |
156 |
point = new Point (x + totalSpace / 2, y - relativeBounds.y); |
226 |
* Getter of the most left coordinate of this {@link LeftRight}. |
157 |
x += (totalSpace - space) / 2; |
227 |
* @return the most left coordinate of this {@link LeftRight}. |
158 |
y += relativeBounds.height + verticalGap; |
228 |
*/ |
159 |
for (Node child : children) { |
229 |
public int getLeft() { |
160 |
child.resolveVertically (x, y); |
230 |
return left; |
161 |
x += child.totalSpace + horizontalGap; |
231 |
} |
|
|
232 |
|
233 |
/** |
234 |
* Getter of the most right coordinate of this {@link LeftRight}. |
235 |
* @return the most right coordinate of this {@link LeftRight}. |
236 |
*/ |
237 |
public int getRight() { |
238 |
return right; |
239 |
} |
240 |
|
241 |
/** |
242 |
* Setter of the most left coordinate of this {@link LeftRight}. |
243 |
* @param left the most left coordinate to set. |
244 |
*/ |
245 |
public void setLeft(int left) { |
246 |
this.left = left; |
247 |
} |
248 |
|
249 |
/** |
250 |
* Setter of the most right coordinate of this {@link LeftRight}. |
251 |
* @param left the most right coordinate to set. |
252 |
*/ |
253 |
public void setRight(int right) { |
254 |
this.right = right; |
162 |
} |
255 |
} |
163 |
} |
256 |
} |
164 |
|
257 |
|
165 |
private int allocateVertically (UniversalGraph<N, E> graph) { |
258 |
private Map<Integer, Integer> getMaxSpaceForEveryLevel(UniversalGraph<N, E> graph) { |
166 |
Widget widget = graph.getScene ().findWidget (node); |
259 |
Map<Integer, Integer> map = new HashMap<Integer, Integer>(); |
167 |
widget.getLayout ().layout (widget); |
260 |
calculateMaxSpace(graph, map, 0); |
168 |
relativeBounds = widget.getPreferredBounds (); |
261 |
return map; |
169 |
space = 0; |
|
|
170 |
for (int i = 0; i < children.size (); i++) { |
171 |
if (i > 0) |
172 |
space += verticalGap; |
173 |
space += children.get (i).allocateVertically (graph); |
174 |
} |
175 |
totalSpace = Math.max (space, relativeBounds.height); |
176 |
return totalSpace; |
177 |
} |
262 |
} |
178 |
|
263 |
|
179 |
private void resolveHorizontally (int x, int y) { |
264 |
/** |
180 |
point = new Point (x - relativeBounds.x, y + totalSpace / 2); |
265 |
* Method to determine the maximal space (horizontaly or verticaly) of each level in the tree. |
181 |
x += relativeBounds.width + horizontalGap; |
266 |
* @param map |
182 |
y += (totalSpace - space) / 2; |
267 |
* @param lvl |
183 |
for (Node child : children) { |
268 |
* @return |
184 |
child.resolveHorizontally (x, y); |
269 |
*/ |
185 |
y += child.totalSpace + verticalGap; |
270 |
private Map<Integer, Integer> calculateMaxSpace(UniversalGraph<N, E> graph, Map<Integer, Integer> map, int lvl) { |
|
|
271 |
|
272 |
Widget widget = graph.getScene().findWidget(node); |
273 |
widget.getLayout().layout(widget); |
274 |
relativeBounds = widget.getPreferredBounds(); |
275 |
|
276 |
if (vertical) { |
277 |
space = relativeBounds.height; |
278 |
} else { |
279 |
space = relativeBounds.width; |
280 |
} |
281 |
|
282 |
if (map.get(lvl) != null) { |
283 |
// lvl is in list, but height is greater than the old one. |
284 |
if (map.get(lvl) < space) { |
285 |
map.put(lvl, space); |
286 |
} |
287 |
} else { |
288 |
// lvl isn't in the map right now. |
289 |
map.put(lvl, space); |
290 |
} |
291 |
|
292 |
lvl++; |
293 |
|
294 |
// do iteration over all children of the current node and calculate |
295 |
// the maxSpace |
296 |
for (Node n : children) { |
297 |
n.calculateMaxSpace(graph, map, lvl); |
298 |
} |
299 |
return map; |
300 |
} |
301 |
|
302 |
/** |
303 |
* |
304 |
* @param graph |
305 |
* @param x |
306 |
* @param y |
307 |
* @return |
308 |
*/ |
309 |
private List<LeftRight> layout(int x, int y, Map<Integer, Integer> map, int lvl) { |
310 |
|
311 |
List<LeftRight> leftright = null; |
312 |
|
313 |
// if this node is a leaf (has no childs) ==> place the node at x,y and x and x + width to the envelope. |
314 |
if (children.size() == 0) { |
315 |
leftright = new ArrayList<LeftRight>(); |
316 |
|
317 |
// do the horizontal alignment |
318 |
y = doHorizontalPlacementInLevel(y, map, lvl); |
319 |
|
320 |
if (vertical) { |
321 |
y = y - relativeBounds.y; |
322 |
leftright.add(new LeftRight(x, x + relativeBounds.width)); |
323 |
} else { |
324 |
y = y - relativeBounds.x; |
325 |
leftright.add(new LeftRight(x, x + relativeBounds.height)); |
326 |
} |
327 |
|
328 |
point = new Point(x, y); |
329 |
return leftright; |
330 |
} |
331 |
|
332 |
lvl++; |
333 |
|
334 |
for (int i = 0; i < children.size(); i++) { |
335 |
if (i == 0) { |
336 |
leftright = children.get(i).layout(x, (int) (y + map.get(lvl - 1) + verticalGap), map, lvl); |
337 |
} else { |
338 |
List<LeftRight> secound = children.get(i).layout(x, (int) (y + map.get(lvl - 1) + verticalGap), map, lvl); |
339 |
|
340 |
int leftlength = leftright.size(); |
341 |
int rightlength = secound.size(); |
342 |
|
343 |
int diff = rightlength - leftlength; |
344 |
|
345 |
// Variable used for calculation of the distance to move the right subtree. |
346 |
int moveDist = Integer.MIN_VALUE; |
347 |
|
348 |
// Try to minimize the gap and move subtrees as close as possible to each other. |
349 |
if (minimizeGap) { |
350 |
// Caluculate the max distance to move |
351 |
for (int k = leftlength - 1; k >= 0; k--) { |
352 |
if (k + diff >= 0 && k >= 0) { |
353 |
int tmpmaxoverlap = leftright.get(k).right - secound.get(k + diff).left; |
354 |
if (tmpmaxoverlap > moveDist) { |
355 |
moveDist = tmpmaxoverlap; |
356 |
} |
357 |
} |
358 |
} |
359 |
} else { |
360 |
int maxRight = Integer.MIN_VALUE; |
361 |
|
362 |
for (LeftRight l : leftright) { |
363 |
maxRight = Math.max(maxRight, l.right); |
364 |
} |
365 |
|
366 |
int minLeft = Integer.MAX_VALUE; |
367 |
|
368 |
for (LeftRight s : secound) { |
369 |
minLeft = Math.min(minLeft, s.left); |
370 |
} |
371 |
moveDist = maxRight - minLeft; |
372 |
} |
373 |
|
374 |
if (moveDist > Integer.MIN_VALUE) { |
375 |
int dx = moveDist + horizontalGap; |
376 |
children.get(i).point.x += dx; |
377 |
children.get(i).moveChildrenHorizontally(dx); |
378 |
} |
379 |
|
380 |
// update moved tree envelope |
381 |
for (LeftRight lr : secound) { |
382 |
lr.setLeft(lr.getLeft() + moveDist + horizontalGap); |
383 |
lr.setRight(lr.getRight() + moveDist + horizontalGap); |
384 |
} |
385 |
|
386 |
// store the overall envelope of leftright and secound in leftright |
387 |
for (int j = rightlength - 1; j >= 0; j--) { |
388 |
// leftright wasn't as long as secound, so these elements have to be added to the envelope |
389 |
if (j < secound.size() - leftright.size()) { |
390 |
leftright.add(0, secound.get(j)); |
391 |
} else if ((j - diff) >= 0 && j >= 0) { |
392 |
// if the left envelope of secound is smaller than the left envelope of leftright, might never happen. |
393 |
if (leftright.get(j - diff).left > secound.get(j).left) { |
394 |
leftright.get(j - diff).setLeft(secound.get(j).left); |
395 |
} |
396 |
// if the right envelope of secound is greater than the right envelope of leftright, might happen every time when a subtree was added by a move to the right. |
397 |
if (leftright.get(j - diff).right < secound.get(j).right) { |
398 |
leftright.get(j - diff).setRight(secound.get(j).right); |
399 |
} |
400 |
} |
401 |
} |
402 |
} |
403 |
} |
404 |
|
405 |
lvl--; |
406 |
|
407 |
// do the horizontal alignment |
408 |
int yAlignment = doHorizontalPlacementInLevel(y, map, lvl); |
409 |
|
410 |
if (minimizeGap) { |
411 |
if (vertical) { |
412 |
point = new Point(((leftright.get(leftright.size() - 1).right + leftright.get(leftright.size() - 1).left) / 2) - (relativeBounds.width / 2), yAlignment - relativeBounds.y); |
413 |
leftright.add(new LeftRight(point.x, point.x + relativeBounds.width)); |
414 |
} else { |
415 |
point = new Point(((leftright.get(leftright.size() - 1).right + leftright.get(leftright.size() - 1).left) / 2) - (relativeBounds.height / 2), yAlignment - relativeBounds.x); |
416 |
leftright.add(new LeftRight(point.x, point.x + relativeBounds.height)); |
417 |
} |
418 |
} else { |
419 |
int leftMin = Integer.MAX_VALUE; |
420 |
int rightMax = Integer.MIN_VALUE; |
421 |
for (LeftRight l : leftright) { |
422 |
leftMin = Math.min(leftMin, l.left); |
423 |
rightMax = Math.max(rightMax, l.right); |
424 |
} |
425 |
|
426 |
assert leftMin != Integer.MAX_VALUE; |
427 |
assert rightMax != Integer.MIN_VALUE; |
428 |
|
429 |
if (vertical) { |
430 |
point = new Point(((leftMin + rightMax) / 2) - (relativeBounds.width / 2), yAlignment - relativeBounds.y); |
431 |
leftright.add(new LeftRight(point.x, point.x + relativeBounds.width)); |
432 |
} else { |
433 |
point = new Point(((leftMin + rightMax) / 2) - (relativeBounds.height / 2), yAlignment - relativeBounds.x); |
434 |
leftright.add(new LeftRight(point.x, point.x + relativeBounds.height)); |
435 |
} |
436 |
} |
437 |
|
438 |
return leftright; |
439 |
} |
440 |
|
441 |
/** |
442 |
* Method to move the children of the actual {@link Node} horizontally |
443 |
* by the given distance dx. |
444 |
* |
445 |
* @param dx the distance to move the children horizontally. |
446 |
*/ |
447 |
private void moveChildrenHorizontally(int dx) { |
448 |
for (Node n : children) { |
449 |
n.point.x += dx; |
450 |
n.moveChildrenHorizontally(dx); |
186 |
} |
451 |
} |
187 |
} |
452 |
} |
188 |
|
453 |
|
189 |
private void upload (HashMap<N, Point> result) { |
454 |
/** |
190 |
result.put (node, point); |
455 |
* |
191 |
for (Node child : children) |
456 |
* @param y |
192 |
child.upload (result); |
457 |
* @param map |
|
|
458 |
* @param lvl |
459 |
* @return |
460 |
*/ |
461 |
private int doHorizontalPlacementInLevel(int y, Map<Integer, Integer> map, int lvl) { |
462 |
int yAlignment = 0; |
463 |
|
464 |
// do the alignment |
465 |
if (alignment == Alignment.TOP) { |
466 |
// nothing to do |
467 |
yAlignment = y; |
468 |
} else if (alignment == Alignment.CENTER) { |
469 |
// place the widget in the center of the max. |
470 |
yAlignment = y + ((map.get(lvl) - space) / 2); |
471 |
} else if (alignment == Alignment.BOTTOM) { |
472 |
yAlignment = y + (map.get(lvl) - space); |
473 |
} |
474 |
return yAlignment; |
475 |
} |
476 |
|
477 |
/** |
478 |
* Method to invert x and y. Also relativeBounds correction is done and |
479 |
* a moveDistance (x-axis) can be given. |
480 |
* @param moveDistance the distance to move the subtree (x-axis). |
481 |
*/ |
482 |
private void invert(int moveDistance) { |
483 |
int tmpx = point.x + moveDistance; |
484 |
point.x = point.y; |
485 |
point.y = tmpx - relativeBounds.y; |
486 |
for (Node n : children) { |
487 |
n.invert(moveDistance); |
488 |
} |
489 |
} |
490 |
|
491 |
/** |
492 |
* Method to do a relativeBoundsCorrection (x-axis) and also to move the |
493 |
* Node for a given distance (also x-axis). |
494 |
* @param moveDistance the distance to move the subtree (x-axis). |
495 |
*/ |
496 |
private void relativeBoundsCorrectionX(int moveDistance) { |
497 |
point.x = point.x - relativeBounds.x + moveDistance; |
498 |
for (Node n : children) { |
499 |
n.relativeBoundsCorrectionX(moveDistance); |
500 |
} |
501 |
} |
502 |
|
503 |
private void upload(HashMap<N, Point> result) { |
504 |
result.put(node, point); |
505 |
for (Node child : children) { |
506 |
child.upload(result); |
507 |
} |
193 |
} |
508 |
} |
194 |
} |
509 |
} |
195 |
|
|
|
196 |
} |
510 |
} |