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 }