1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 package net.sf.jtreemap.ktreemap;
34
35 import java.util.ArrayList;
36 import java.util.List;
37
38 import org.eclipse.swt.graphics.Point;
39 import org.eclipse.swt.graphics.Rectangle;
40
41 /**
42 * Node of a KTreeMap.<BR>
43 * If the node is a branch, only the label is set.<BR>
44 * If the node is a leaf, we need a label, a weight and a value.
45 * <p>
46 * You can also use a TreeMapNode in a JTree.
47 *
48 * @author Laurent Dutheil
49 */
50
51 public class TreeMapNode {
52 private static final long serialVersionUID = 742372833853976103L;
53
54 private static int border = 3;
55 private double weight = 0.0;
56 private Rectangle bounds = new Rectangle(0, 0, 0, 0);
57 private Object value;
58 private ArrayList<TreeMapNode> children = new ArrayList<TreeMapNode>();
59 private TreeMapNode parent;
60
61 /**
62 * Constructor for a branch
63 * @param value value of the TreeMapNode
64 */
65 public TreeMapNode(Object value) {
66 this.value = value;
67 }
68
69 /**
70 * Constructor for a leaf.
71 *
72 * @param weight weight of the leaf (if negative, we take the absolute value).
73 * @param value Value associée à la feuille
74 */
75 public TreeMapNode(Object value, double weight) {
76 this.value = value;
77
78 this.weight = Math.abs(weight);
79 }
80
81 /**
82 * Get the max border between two nodes of the same level.
83 *
84 * @return Returns the border.
85 */
86 public static int getBorder() {
87 return TreeMapNode.border;
88 }
89
90 /**
91 * Set the max border between two nodes of the same level.
92 *
93 * @param border The border to set.
94 */
95 public static void setBorder(int border) {
96 TreeMapNode.border = border;
97 }
98
99 /**
100 * add a new child to the node.
101 *
102 * @param newChild new child
103 */
104 public void add(TreeMapNode newChild) {
105 this.children.add(newChild);
106 newChild.setParent(this);
107 this.setWeight(this.weight + newChild.getWeight());
108 }
109
110 /**
111 * get the active leaf.<BR>
112 * null if the passed position is not in this tree.
113 *
114 * @param x x-coordinate
115 * @param y y-coordinate
116 * @return active leaf
117 */
118 public TreeMapNode getActiveLeaf(int x, int y) {
119
120 if (this.isLeaf()) {
121 if ((x >= this.getX()) && (x <= this.getX() + this.getWidth())
122 && (y >= this.getY()) && (y <= this.getY() + this.getHeight())) {
123 return this;
124 }
125 } else {
126 for (TreeMapNode node : this.children) {
127 if ((x >= node.getX()) && (x <= node.getX() + node.getWidth())
128 && (y >= node.getY()) && (y <= node.getY() + node.getHeight())) {
129 return node.getActiveLeaf(x, y);
130 }
131 }
132 }
133 return null;
134 }
135
136 /**
137 * get the active leaf.<BR>
138 * null if the passed position is not in this tree.
139 *
140 * @param position position
141 * @return active leaf
142 */
143 public TreeMapNode getActiveLeaf(Point position) {
144 if (position != null) {
145 return getActiveLeaf(position.x, position.y);
146 }
147 return null;
148 }
149
150 /**
151 * @return the bounds of the KTreeMap
152 */
153 public Rectangle getBounds() {
154 return this.bounds;
155 }
156
157 /**
158 * get the first child which fits the position.<BR>
159 * null if the passed position is not in this tree.
160 *
161 * @param x x-coordinate
162 * @param y y-coordinate
163 * @return the first child which fits the position.
164 */
165 public TreeMapNode getChild(int x, int y) {
166 if (!this.isLeaf()) {
167 for (TreeMapNode node : this.children) {
168 if ((x >= node.getX()) && (x <= node.getX() + node.getWidth())
169 && (y >= node.getY()) && (y <= node.getY() + node.getHeight())) {
170 return node;
171 }
172 }
173
174 }
175 return null;
176 }
177
178 /**
179 * get the first child which fits the position.<BR>
180 * null if the passed position is not in this tree.
181 *
182 * @param position position
183 * @return the first child which fits the position.
184 */
185 public TreeMapNode getChild(Point position) {
186 if (position != null) {
187 return getChild(position.x, position.y);
188 }
189 return null;
190 }
191
192 /**
193 * get a List with the children.
194 *
195 * @return List with the children
196 */
197 @SuppressWarnings("unchecked")
198 public List<TreeMapNode> getChildren() {
199 return this.children;
200 }
201
202 /**
203 * get the height.
204 *
205 * @return the height
206 */
207 public int getHeight() {
208 return this.bounds.height;
209 }
210
211 /**
212 * get the Value.
213 *
214 * @return the value
215 */
216 public Object getValue() {
217 return this.value;
218 }
219
220 /**
221 * get the weight.
222 *
223 * @return the weight
224 */
225 public double getWeight() {
226 return this.weight;
227 }
228
229 /**
230 * get the width.
231 *
232 * @return the width
233 */
234 public int getWidth() {
235 return this.bounds.width;
236 }
237
238 /**
239 * get the x-coordinate.
240 *
241 * @return the x-coordinate
242 */
243 public int getX() {
244 return this.bounds.x;
245 }
246
247 /**
248 * get the y-coordinate.
249 *
250 * @return the y-coordinate
251 */
252 public int getY() {
253 return this.bounds.y;
254 }
255
256 /**
257 * @return true if the TreeMapNode is a leaf
258 */
259 public boolean isLeaf() {
260 return this.children.isEmpty();
261 }
262
263 /**
264 * set the position and the size.
265 * @param bounds bounds
266 */
267 public void setBounds(Rectangle bounds) {
268 this.bounds = bounds;
269 }
270
271 /**
272 * set the height.
273 *
274 * @param height la nouvelle valeur de height
275 */
276 public void setHeight(int height) {
277 this.bounds.height = height;
278 }
279
280 /**
281 * set the position.
282 *
283 * @param x x-coordinate
284 * @param y y-coordinate
285 */
286 public void setPosition(int x, int y) {
287 this.bounds.x = x;
288 this.bounds.y = y;
289 }
290
291 /**
292 * set size.
293 *
294 * @param width the new width
295 * @param height the new height
296 */
297 public void setSize(int width, int height) {
298 this.bounds.width = width;
299 this.bounds.height = height;
300 }
301
302 /**
303 * set the Value.
304 *
305 * @param value the new value
306 */
307 public void setValue(Object value) {
308 this.value = value;
309 }
310
311 /**
312 * set the weight of the node and update the parents.
313 *
314 * @param weight the new weight
315 */
316 public void setWeight(double weight) {
317 double newWeight = Math.abs(weight);
318 if (this.parent != null) {
319 this.parent.setWeight(this.parent.weight - this.weight + newWeight);
320 }
321 this.weight = newWeight;
322 }
323
324 /**
325 * set the width.
326 *
327 * @param width la nouvelle valeur de width
328 */
329 public void setWidth(int width) {
330 this.bounds.width = width;
331 }
332
333 /**
334 * set the x-coordinate.
335 *
336 * @param x the new x-coordinate
337 */
338 public void setX(int x) {
339 this.bounds.x = x;
340 }
341
342 /**
343 * set the y-coordinate.
344 *
345 * @param y the new y-coordinate
346 */
347 public void setY(int y) {
348 this.bounds.y = y;
349 }
350
351 /**
352 * @return the parent
353 */
354 public TreeMapNode getParent() {
355 return parent;
356 }
357
358 /**
359 * @param parent the parent to set
360 */
361 protected void setParent(TreeMapNode parent) {
362 this.parent = parent;
363 }
364 }
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380