1 
2 // *** HideableTreeModel ***
3 import java.awt.*;
4 import java.awt.event.*;
5 import java.util.ArrayList;
6 import java.util.Enumeration;
7 import java.util.Vector;
8 import javax.swing.*;
9 import javax.swing.event.*;
10 import javax.swing.tree.*;
11 
12 
13 public class HideableTreeModel implements TreeModel {
14 
15 	private Vector modelListeners = new Vector();
16 	private Object root = null;
17 
18 
19         public HideableTreeModel(TreeNode _root) {
20             super();
21             setRoot(_root);
22 	}
23 
24 
25 	public Object getRoot() {
26 		return this.root;
27 	}
28 
29 
30         protected void setRoot(Object r) {
31             this.root = r;
32 	}
33 
34 
35         public Object[] getPathToRoot(Object node) {
36             return getPathToRoot(node, 0);
37 	}
38 
39 
40         private Object[] getPathToRoot(Object node, int i) {
41             Object anode[];
42             if(node == null) {
43                 if(i == 0) {
44                     return null;
45                 }
46                 anode = new Object[i];
47             } else {
48                 i++;
49                 if(node == getRoot()) {
50                     anode = new Object[i];
51                 } else {
52                     anode = getPathToRoot(getParent(node), i);
53                 }
54                 anode[anode.length - i] = node;
55             }
56             return anode;
57 	}
58 
59 
60         public void addTreeModelListener(TreeModelListener l) {
61             modelListeners.addElement(l);
62 	}
63 
64 
65         public void removeTreeModelListener(TreeModelListener l) {
66             modelListeners.removeElement(l);
67 	}
68 
69 
70 	public void reload() {
71             reload(getRoot());
72 	}
73 
74 
75         public void reload(Object node) {
76             if(node != null) {
77                 TreePath tp = new TreePath(getPathToRoot(node));
78                 fireTreeStructureChanged(new TreeModelEvent(this, tp));
79             }
80 	}
81 
82 
83         public void valueForPathChanged(TreePath path, Object newValue) {
84             nodeChanged(path.getLastPathComponent());
85 	}
86 
87 	public void nodeInserted(Object node, Object child) {
88             nodeInserted(node, child, -1);
89 	}
90 
91 
92         public void nodeInserted(Object node, Object child, int index) {
93             if(index < 0) {
94                 index = getIndexOfChild(node, child);
95             }
96             if(node != null && child != null && index >= 0) {
97                 TreePath tp = new TreePath(getPathToRoot(node));
98                 int[] ai = { index };
99                 Object[] ac = { child };
100                 fireTreeNodesInserted(new TreeModelEvent(this, tp, ai, ac));
101             }
102 	}
103 
104 
105         public void nodeRemoved(Object node, Object child, int index) {
106             if(node != null && child != null && index >= 0) {
107                 TreePath tp = new TreePath(getPathToRoot(node));
108                 int[] ai = { index };
109                 Object[] ac = { child };
110                 fireTreeNodesRemoved(new TreeModelEvent(this, tp, ai, ac));
111             }
112 	}
113 
114 
115         public void nodeChanged(Object node) {
116             if(node != null) {
117                 TreePath tp = new TreePath(getPathToRoot(node));
118                 fireTreeNodesChanged(new TreeModelEvent(this, tp, null, null));
119             }
120 	}
121 
122 
123         protected void fireTreeNodesChanged(TreeModelEvent event) {
124             for(int i = 0; i < modelListeners.size(); i++) {
125                 ((TreeModelListener)modelListeners.elementAt(i)).treeNodesChanged(event);
126             }
127 	}
128 
129 
130         protected void fireTreeNodesInserted(TreeModelEvent event) {
131             for(int i = 0; i < modelListeners.size(); i++) {
132                 ((TreeModelListener)modelListeners.elementAt(i)).treeNodesInserted(event);
133             }
134 	}
135 
136 
137         protected void fireTreeNodesRemoved(TreeModelEvent event) {
138             for(int i = 0; i < modelListeners.size(); i++) {
139                 ((TreeModelListener)modelListeners.elementAt(i)).treeNodesRemoved(event);
140             }
141 	}
142 
143 	protected void fireTreeStructureChanged(TreeModelEvent event) {
144             for(int i = 0; i < modelListeners.size(); i++) {
145                 ((TreeModelListener)modelListeners.elementAt(i)).treeStructureChanged(event);
146             }
147 	}
148 
149 
150         public ArrayList getExpandedPaths(JTree tree) {
151 		ArrayList expandedPaths = new ArrayList();
152 		addExpandedPaths(tree, tree.getPathForRow(0), expandedPaths);
153 		return expandedPaths;
154 	}
155 
156 
157         private void addExpandedPaths(JTree tree, TreePath path, ArrayList pathlist) {
158             Enumeration aEnum = tree.getExpandedDescendants(path);
159             while(aEnum.hasMoreElements()) {
160                 TreePath tp = (TreePath) aEnum.nextElement();
161                 pathlist.add(tp);
162                 addExpandedPaths(tree, tp, pathlist);
163             }
164 	}
165 
166 
167         public void expandPaths(JTree tree, ArrayList pathlist) {
168             for(int i = 0; i < pathlist.size(); i++) {
169                 tree.expandPath((TreePath)pathlist.get(i));
170             }
171 	}
172 
173 
174         public boolean isLeaf(Object _oNode) {
175             if(_oNode instanceof TreeNode) {
176                 return ((TreeNode) _oNode).isLeaf();
177             }
178             return true;
179 	}
180 
181 
182 
183 	public Object getParent(Object node) {
184             if(node != getRoot() && (node instanceof TreeNode)) {
185                 return ((TreeNode)node).getParent();
186             }
187             return null;
188 	}
189 
190 
191         public boolean isNodeVisible(Object node) {
192             if(node != getRoot()) {
193                 if(node instanceof HideableMutableTreeNode) {
194                         return ((HideableMutableTreeNode)node).isVisible();
195                 }
196             }
197             return true;
198 	}
199 
200 
201         public boolean setNodeVisible(Object node, boolean v) {
202             // can't hide root
203             if(node != getRoot()) {
204                 if(node instanceof HideableMutableTreeNode) {
205                     HideableMutableTreeNode n = (HideableMutableTreeNode)node;
206                     if(v != n.isVisible()) {
207                         TreeNode parent = n.getParent();
208                         if(v) {
209                             // need to get index after showing...
210                             n.setVisible(v);
211                             int index = getIndexOfChild(parent, n);
212                             nodeInserted(parent, n, index);
213                         } else {
214                             // need to get index before hiding...
215                             int index = getIndexOfChild(parent, n);
216                             n.setVisible(v);
217                             nodeRemoved(parent, n, index);
218                         }
219                     }
220                     return true;
221                 }
222             }
223             return false;
224 	}
225 
226 
227         public boolean isPathToNodeVisible(Object node) {
228             Object[] path = getPathToRoot(node);
229             for(int i = 0; i < path.length; i++) {
230                 if(!isNodeVisible(path[i])) {
231                     return false;
232                 }
233             }
234             return true;
235 	}
236 
237 
238         public void ensurePathToNodeVisible(Object node) {
239             Object[] path = getPathToRoot(node);
240             for(int i = 0; i < path.length; i++) {
241                 setNodeVisible(path[i], true);
242             }
243 	}
244 
245 
246         public Object getChild(Object parent, int index) {
247             if(parent instanceof TreeNode) {
248                 TreeNode p = (TreeNode) parent;
249                 for(int i = 0, j = -1; i < p.getChildCount(); i++) {
250                     TreeNode pc = (TreeNode)p.getChildAt(i);
251                     if(isNodeVisible(pc)) {
252                         j++;
253                     }
254                     if(j == index) {
255                         return pc;
256                     }
257                 }
258             }
259             return null;
260 	}
261 
262 
263         public int getChildCount(Object parent) {
264             int count = 0;
265             if(parent instanceof TreeNode) {
266                 TreeNode p = (TreeNode) parent;
267                 for(int i = 0; i < p.getChildCount(); i++) {
268                     TreeNode pc = (TreeNode)p.getChildAt(i);
269                     if(isNodeVisible(pc)) {
270                         count++;
271                     }
272                 }
273             }
274             return count;
275 	}
276 
277 
278         public int getIndexOfChild(Object parent, Object child) {
279             int index = -1;
280             if(parent instanceof TreeNode && child instanceof TreeNode) {
281                 TreeNode p = (TreeNode)parent;
282                 TreeNode c = (TreeNode)child;
283                 if(isNodeVisible(c)) {
284                     index = 0;
285                     for(int i = 0; i < p.getChildCount(); i++) {
286                         TreeNode pc = (TreeNode)p.getChildAt(i);
287                         if(pc.equals(c)) {
288                             return index;
289                         }
290                         if(isNodeVisible(pc)) {
291                             index++;
292                         }
293                     }
294                 }
295             }
296             return index;
297 	}
298 }