1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.xmlhammer.gui.overview;
24
25 import java.awt.Dimension;
26 import java.util.ArrayList;
27
28 import javax.swing.Icon;
29 import javax.swing.event.EventListenerList;
30 import javax.swing.event.TreeModelEvent;
31 import javax.swing.event.TreeModelListener;
32 import javax.swing.tree.TreeModel;
33 import javax.swing.tree.TreePath;
34
35 import org.bounce.DummyIcon;
36
37
38 public class OverviewTreeModel implements TreeModel, OverviewNode {
39 private static final Icon DUMMY_ICON = new DummyIcon(new Dimension(16, 16));
40
41 /*** Listeners. */
42 protected EventListenerList listenerList = new EventListenerList();
43
44 private ArrayList<OverviewNode> children = null;
45
46 public OverviewTreeModel() {
47 this( new ArrayList<OverviewNode>());
48 }
49
50 public OverviewTreeModel( ArrayList<OverviewNode> children) {
51 setChildren( children);
52 }
53
54 public void setChildren( ArrayList<OverviewNode> children) {
55 this.children = children;
56
57 fireTreeNodesInserted( this, new Object[] { getRoot()}, new int[] { 0, 1, 2}, children.toArray());
58 }
59
60 public void addChild( OverviewNode child) {
61 this.children.add( child);
62
63 nodeInserted( child);
64 }
65
66 public OverviewNode getRoot() {
67 return this;
68 }
69
70
71
72
73 public Object getChild( Object parent, int index) {
74 if ( parent instanceof OverviewNode){
75 return ((OverviewNode)parent).getChildNodes().get( index);
76 }
77
78 return null;
79 }
80
81
82
83
84 public int getChildCount( Object parent) {
85 if ( parent instanceof OverviewNode){
86 return ((OverviewNode)parent).getChildNodes().size();
87 }
88
89 return 0;
90 }
91
92
93
94
95 public boolean isLeaf( Object node) {
96 return getChildCount( node) == 0;
97 }
98
99
100
101
102 public void valueForPathChanged( TreePath path, Object newValue) {
103 }
104
105 public String getError() {
106 return null;
107 }
108
109 public void nodeChanged(OverviewNode node) {
110 if(node != null) {
111 OverviewNode parent = node.getParentNode();
112
113 if (parent != null) {
114 int i = parent.getChildNodes().indexOf(node);
115
116 if (i != -1) {
117 int ai[] = new int[1];
118 ai[0] = i;
119 nodesChanged(parent, ai);
120 }
121 } else {
122 nodesChanged(node, null);
123 }
124 }
125 }
126
127 public void nodePathChanged(OverviewNode node) {
128 if(node != null) {
129 OverviewNode parent = node.getParentNode();
130
131 while (parent != null) {
132 int i = parent.getChildNodes().indexOf(node);
133
134 if(i != -1) {
135 int ai[] = new int[1];
136 ai[0] = i;
137 nodesChanged(parent, ai);
138 }
139
140 node = node.getParentNode();
141 parent = node.getParentNode();
142 }
143
144 nodesChanged(node, null);
145 }
146 }
147
148 public void nodesChanged(OverviewNode node, int ai[]) {
149 if(node != null)
150
151 if( ai != null) {
152 int i = ai.length;
153
154 if( i > 0) {
155 Object aobj[] = new Object[i];
156
157 for(int j = 0; j < i; j++) {
158 aobj[j] = node.getChildNodes().get(ai[j]);
159 }
160
161 fireTreeNodesChanged(this, getPathToRoot( node, 0), ai, aobj);
162 }
163 } else {
164 fireTreeNodesChanged(this, getPathToRoot( node, 0), null, null);
165 }
166 }
167
168 public void nodeRemoved(OverviewNode node) {
169 if(node != null) {
170 fireTreeNodesRemoved(node.getParentNode(), getPathToRoot( node.getParentNode(), 0), new int[] { node.getParentNode().getChildNodes().indexOf(node) }, new OverviewNode[] { node });
171 }
172 }
173
174 public void nodeInserted(OverviewNode node) {
175 if(node != null) {
176 fireTreeNodesInserted(node.getParentNode(), getPathToRoot( node.getParentNode(), 0), new int[] { node.getParentNode().getChildNodes().indexOf(node) }, new OverviewNode[] { node });
177 }
178 }
179
180 public void structureChanged(OverviewNode node) {
181 if(node != null) {
182 fireTreeStructureChanged(this, getPathToRoot( node, 0), null, null);
183 }
184 }
185
186 public OverviewNode[] getPathToRoot(OverviewNode node, int i) {
187 OverviewNode path[] = null;
188
189 if(node == null) {
190 if(i == 0) {
191 return null;
192 }
193
194 path = new OverviewNode[i];
195 } else {
196 i++;
197
198 if(node == getRoot()) {
199 path = new OverviewNode[i];
200 } else {
201 path = getPathToRoot(node.getParentNode(), i);
202 }
203 path[path.length - i] = node;
204 }
205
206 return path;
207 }
208
209
210
211
212 public int getIndexOfChild( Object parent, Object child) {
213 if ( parent instanceof OverviewNode){
214 return ((OverviewNode)parent).getChildNodes().indexOf( child);
215 }
216
217 return 0;
218 }
219
220 /***
221 * Adds a listener for the TreeModelEvent posted after the tree changes.
222 *
223 * @see #removeTreeModelListener
224 * @param l the listener to add
225 */
226 public void addTreeModelListener(TreeModelListener l) {
227 listenerList.add(TreeModelListener.class, l);
228 }
229
230 /***
231 * Removes a listener previously added with <B>addTreeModelListener()</B>.
232 *
233 * @see #addTreeModelListener
234 * @param l the listener to remove
235 */
236 public void removeTreeModelListener(TreeModelListener l) {
237 listenerList.remove(TreeModelListener.class, l);
238 }
239
240 /***
241 * Returns an array of all the tree model listeners
242 * registered on this model.
243 *
244 * @return all of this model's <code>TreeModelListener</code>s
245 * or an empty
246 * array if no tree model listeners are currently registered
247 *
248 * @see #addTreeModelListener
249 * @see #removeTreeModelListener
250 *
251 * @since 1.4
252 */
253 public TreeModelListener[] getTreeModelListeners() {
254 return listenerList.getListeners(TreeModelListener.class);
255 }
256
257 /***
258 * Notifies all listeners that have registered interest for
259 * notification on this event type. The event instance
260 * is lazily created using the parameters passed into
261 * the fire method.
262 *
263 * @param source the node being changed
264 * @param path the path to the root node
265 * @param childIndices the indices of the changed elements
266 * @param children the changed elements
267 * @see EventListenerList
268 */
269 protected void fireTreeNodesChanged(Object source, Object[] path,
270 int[] childIndices,
271 Object[] children) {
272
273 Object[] listeners = listenerList.getListenerList();
274 TreeModelEvent e = null;
275
276
277 for (int i = listeners.length-2; i>=0; i-=2) {
278 if (listeners[i]==TreeModelListener.class) {
279
280 if (e == null)
281 e = new TreeModelEvent(source, path,
282 childIndices, children);
283 ((TreeModelListener)listeners[i+1]).treeNodesChanged(e);
284 }
285 }
286 }
287
288 /***
289 * Notifies all listeners that have registered interest for
290 * notification on this event type. The event instance
291 * is lazily created using the parameters passed into
292 * the fire method.
293 *
294 * @param source the node where new elements are being inserted
295 * @param path the path to the root node
296 * @param childIndices the indices of the new elements
297 * @param children the new elements
298 * @see EventListenerList
299 */
300 protected void fireTreeNodesInserted(Object source, Object[] path,
301 int[] childIndices,
302 Object[] children) {
303
304 Object[] listeners = listenerList.getListenerList();
305 TreeModelEvent e = null;
306
307
308 for (int i = listeners.length-2; i>=0; i-=2) {
309 if (listeners[i]==TreeModelListener.class) {
310
311 if (e == null)
312 e = new TreeModelEvent(source, path,
313 childIndices, children);
314 ((TreeModelListener)listeners[i+1]).treeNodesInserted(e);
315 }
316 }
317 }
318
319 /***
320 * Notifies all listeners that have registered interest for
321 * notification on this event type. The event instance
322 * is lazily created using the parameters passed into
323 * the fire method.
324 *
325 * @param source the node where elements are being removed
326 * @param path the path to the root node
327 * @param childIndices the indices of the removed elements
328 * @param children the removed elements
329 * @see EventListenerList
330 */
331 protected void fireTreeNodesRemoved(Object source, Object[] path,
332 int[] childIndices,
333 Object[] children) {
334
335 Object[] listeners = listenerList.getListenerList();
336 TreeModelEvent e = null;
337
338
339 for (int i = listeners.length-2; i>=0; i-=2) {
340 if (listeners[i]==TreeModelListener.class) {
341
342 if (e == null)
343 e = new TreeModelEvent(source, path,
344 childIndices, children);
345 ((TreeModelListener)listeners[i+1]).treeNodesRemoved(e);
346 }
347 }
348 }
349
350 /***
351 * Notifies all listeners that have registered interest for
352 * notification on this event type. The event instance
353 * is lazily created using the parameters passed into
354 * the fire method.
355 *
356 * @param source the node where the tree model has changed
357 * @param path the path to the root node
358 * @param childIndices the indices of the affected elements
359 * @param children the affected elements
360 * @see EventListenerList
361 */
362 protected void fireTreeStructureChanged(Object source, Object[] path,
363 int[] childIndices,
364 Object[] children) {
365
366 Object[] listeners = listenerList.getListenerList();
367 TreeModelEvent e = null;
368
369
370 for (int i = listeners.length-2; i>=0; i-=2) {
371 if (listeners[i]==TreeModelListener.class) {
372
373 if (e == null)
374 e = new TreeModelEvent(source, path,
375 childIndices, children);
376 ((TreeModelListener)listeners[i+1]).treeStructureChanged(e);
377 }
378 }
379 }
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407 public String getNodeName() {
408 return "ROOT";
409 }
410
411 public ArrayList<OverviewNode> getChildNodes() {
412 return this.children;
413 }
414
415 public OverviewNode getParentNode() {
416 return null;
417 }
418
419 public Icon getNodeIcon() {
420 return DUMMY_ICON;
421 }
422 }