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.swing;
34
35 import java.io.Serializable;
36 import java.util.Iterator;
37 import java.util.Vector;
38
39 /**
40 * Abtract class with the method which split the elements of a JTreeMap.
41 * <p>
42 * The split is done by dichotomy. We split the elements in 2 groups with a
43 * defined strategy (for example : take care of the weight of the elements)
44 * <p>
45 *
46 * @author Laurent Dutheil
47 */
48
49 public abstract class SplitStrategy implements Serializable {
50 /**
51 * calculate the positions for all the elements of the root.
52 *
53 * @param root
54 * the root to calculate
55 */
56 public void calculatePositions(final TreeMapNode root) {
57 if (root == null) {
58 return;
59 }
60
61 final Vector<TreeMapNode> v = root.getChildren();
62 if (v != null) {
63 calculatePositionsRec(root.getX(), root.getY(), root.getWidth(), root.getHeight(), this.sumWeight(v), v);
64 }
65 }
66
67 /**
68 * split the elements of a JTreeMap.
69 *
70 * @param v
71 * Vector with the elements to split (arg IN)
72 * @param v1
73 * first Vector of the split (arg OUT)
74 * @param v2
75 * second Vector of the split (arg OUT)
76 */
77 public abstract void splitElements(Vector<TreeMapNode> v, Vector<TreeMapNode> v1, Vector<TreeMapNode> v2);
78
79 /**
80 * Sum the weight of elements. <BR>
81 * You can override this method if you want to apply a coef on the weights
82 * or to cancel the effect of weight on the strategy.
83 *
84 * @param v
85 * Vector with the elements to sum
86 * @return the sum of the weight of elements
87 */
88 public double sumWeight(final Vector<TreeMapNode> v) {
89 double d = 0.0;
90 if (v != null) {
91 final int size = v.size();
92
93 for (int i = 0; i < size; i++) {
94 d += (v.elementAt(i)).getWeight();
95 }
96 }
97 return d;
98 }
99
100 protected void calculatePositionsRec(final int x0, final int y0, final int w0, final int h0, final double weight0,
101 final Vector<TreeMapNode> v) {
102
103
104 if (v.size() == 1) {
105 final TreeMapNode f = v.elementAt(0);
106 if (f.isLeaf()) {
107
108 int w = w0 - TreeMapNode.getBorder();
109 if (w < 0) {
110 w = 0;
111 }
112 int h = h0 - TreeMapNode.getBorder();
113 if (h < 0) {
114 h = 0;
115 }
116 f.setDimension(x0 + TreeMapNode.getBorder(), y0 + TreeMapNode.getBorder(), w, h);
117 } else {
118
119 f.setDimension(x0, y0, w0, h0);
120
121 int bSub;
122 if (TreeMapNode.getBorder() > 1) {
123 bSub = 2;
124 } else if (TreeMapNode.getBorder() == 1) {
125 bSub = 1;
126 } else {
127 bSub = 0;
128 }
129
130 int w = w0 - bSub;
131 if (w < 0) {
132 w = 0;
133 }
134 int h = h0 - bSub;
135 if (h < 0) {
136 h = 0;
137 }
138
139 TreeMapNode.setBorder(TreeMapNode.getBorder() - bSub);
140 calculatePositionsRec(x0 + bSub, y0 + bSub, w, h, weight0, f.getChildren());
141 TreeMapNode.setBorder(TreeMapNode.getBorder() + bSub);
142 }
143 } else {
144
145
146 final Vector<TreeMapNode> v1 = new Vector<TreeMapNode>();
147 final Vector<TreeMapNode> v2 = new Vector<TreeMapNode>();
148 double weight1;
149 double weight2;
150 this.splitElements(v, v1, v2);
151 weight1 = this.sumWeight(v1);
152 weight2 = this.sumWeight(v2);
153
154 int w1;
155 int w2;
156 int h1;
157 int h2;
158 int x2;
159 int y2;
160
161 if (w0 > h0) {
162 w1 = (int) (w0 * weight1 / weight0);
163 w2 = w0 - w1;
164 h1 = h0;
165 h2 = h0;
166 x2 = x0 + w1;
167 y2 = y0;
168 } else {
169
170 w1 = w0;
171 w2 = w0;
172 h1 = (int) (h0 * weight1 / weight0);
173 h2 = h0 - h1;
174 x2 = x0;
175 y2 = y0 + h1;
176 }
177
178 calculatePositionsRec(x0, y0, w1, h1, weight1, v1);
179 calculatePositionsRec(x2, y2, w2, h2, weight2, v2);
180 }
181 }
182
183 /**
184 * Sort the elements by descending weight.
185 *
186 * @param v
187 * Vector with the elements to be sorted
188 */
189 protected void sortVector(final Vector<TreeMapNode> v) {
190 TreeMapNode tmn;
191
192 for (int i = 0; i < v.size(); i++) {
193 for (int j = v.size() - 1; j > i; j--) {
194 if ((v.elementAt(j)).getWeight() > (v.elementAt(j - 1)).getWeight()) {
195 tmn = (v.elementAt(j));
196 v.setElementAt(v.elementAt(j - 1), j);
197 v.setElementAt(tmn, j - 1);
198 }
199 }
200 }
201
202 }
203
204 protected void workOutWeight(final Vector<TreeMapNode> v1, final Vector<TreeMapNode> v2, final Vector<TreeMapNode> vClone,
205 final double sumWeight) {
206 double memWeight = 0.0;
207 double elemWeight = 0.0;
208 for (final Iterator<TreeMapNode> i = vClone.iterator(); i.hasNext();) {
209 TreeMapNode tmn = i.next();
210 elemWeight = tmn.getWeight();
211
212 if (memWeight + elemWeight >= sumWeight / 2) {
213
214
215 if (((sumWeight / 2) - memWeight) > ((memWeight + elemWeight) - (sumWeight / 2))) {
216
217
218 memWeight += elemWeight;
219 v1.addElement(tmn);
220 } else {
221
222 if (v1.isEmpty()) {
223 v1.addElement(tmn);
224 } else {
225
226
227 v2.addElement(tmn);
228 }
229 }
230
231 while (i.hasNext()) {
232 tmn = i.next();
233 v2.addElement(tmn);
234 }
235 } else {
236
237
238 memWeight += elemWeight;
239 v1.addElement(tmn);
240 }
241 }
242 }
243 }
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259