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