package iiuf.swing; import java.util.ArrayList; import java.util.Iterator; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import javax.swing.tree.TreeModel; import javax.swing.event.TreeModelListener; import javax.swing.event.TreeModelEvent; import iiuf.log.Log; import iiuf.util.EventListenerList; import iiuf.util.Util; /** A tree model implementation that wraps a subtree of a tree model. (c) 2000, 2001, IIUF, DIUF<p> @author $Author: ohitz $ @version $Name: $ $Revision: 1.1 $ */ public class SubTreeModel implements TreeModel, TreeModelListener { private EventListenerList listenerList = new EventListenerList(); private TreeModel model; private TreeNode root; private TreePath rootPath; private static int count; SubTreeModel(TreeModel model_, TreeNode root) { count++; model = model_; setRoot(root); model.removeTreeModelListener(this); model.addTreeModelListener(this); } private void setRoot(TreeNode root_) { root = root_; rootPath = getPathToRoot(root); } public void treeNodesChanged(TreeModelEvent e) { if(!Util.contains(e.getTreePath().getPath(), root)) return; TreeModelListener[] listeners = (TreeModelListener[])listenerList.getListeners(TreeModelListener.class); TreeModelEvent ev = listeners.length == 0 ? null : new TreeModelEvent(this, relative(e.getTreePath()), e.getChildIndices(), e.getChildren()); for(int i = 0; i < listeners.length; i++) listeners[i].treeNodesChanged(ev); } public void treeNodesInserted(TreeModelEvent e) { if(!Util.contains(e.getTreePath().getPath(), root)) return; TreeModelListener[] listeners = (TreeModelListener[])listenerList.getListeners(TreeModelListener.class); TreeModelEvent ev = listeners.length == 0 ? null : new TreeModelEvent(this, relative(e.getTreePath()), e.getChildIndices(), e.getChildren()); for(int i = 0; i < listeners.length; i++) listeners[i].treeNodesInserted(ev); } public void treeNodesRemoved(TreeModelEvent e) { if(!Util.contains(e.getTreePath().getPath(), root)) return; TreeModelListener[] listeners = (TreeModelListener[])listenerList.getListeners(TreeModelListener.class); Object[] childs = e.getChildren(); for(int i = 0; i < childs.length; i++) { if(isAChildOf((TreeNode)childs[i], root)){ setRoot((TreeNode)e.getTreePath().getLastPathComponent()); TreeModelEvent ev = listeners.length == 0 ? null : new TreeModelEvent(this, new TreePath(root)); for(int j = 0; j < listeners.length; j++) listeners[j].treeStructureChanged(ev); return; } } TreeModelEvent ev = listeners.length == 0 ? null : new TreeModelEvent(this, relative(e.getTreePath()), e.getChildIndices(), e.getChildren()); for(int i = 0; i < listeners.length; i++) listeners[i].treeNodesRemoved(ev); } public void treeStructureChanged(TreeModelEvent e) { if(!Util.contains(e.getTreePath().getPath(), root)) return; TreeModelListener[] listeners = (TreeModelListener[])listenerList.getListeners(TreeModelListener.class); TreeModelEvent ev = null; if(isAChildOf((TreeNode)e.getTreePath().getLastPathComponent(), root)) { setRoot((TreeNode)e.getTreePath().getLastPathComponent()); ev = new TreeModelEvent(this, new TreePath(root)); } else ev = new TreeModelEvent(this, relative(e.getTreePath()), e.getChildIndices(), e.getChildren()); for(int i = 0; i < listeners.length; i++) listeners[i].treeStructureChanged(ev); } public boolean isAChildOf(TreeNode startNode, TreeNode testNode) { if(testNode == null) return false; if(testNode == startNode) return true; else return isAChildOf(startNode, testNode.getParent()); } public void addTreeModelListener(TreeModelListener l) { listenerList.add(TreeModelListener.class, l); } public void addTreeModelListener(TreeModelListener l, boolean weak) { listenerList.add(TreeModelListener.class, l, weak); } public void removeTreeModelListener(TreeModelListener l) { listenerList.remove(TreeModelListener.class, l); } public Object getChild(Object parent, int index) { return model.getChild(parent, index); } public int getChildCount(Object parent) { return model.getChildCount(parent); } public int getIndexOfChild(Object parent, Object child) { return model.getIndexOfChild(parent, child); } public Object getRoot() { return root; } public boolean isLeaf(Object node) { return model.isLeaf(node); } public void valueForPathChanged(TreePath path, Object newValue) { model.valueForPathChanged(absolute(path), newValue); } private TreePath getPathToRoot(TreeNode node) { ArrayList pa = new ArrayList(); for(; node != model.getRoot(); node = node.getParent()) pa.add(0, node); pa.add(0, model.getRoot()); return new TreePath(pa.toArray()); } public TreePath absolute(TreePath relPath) { if(relPath == null) return null; int rpl = rootPath.getPathCount() - 1; Object[] result = new Object[rpl + relPath.getPathCount()]; for(int i = 0; i < rpl; i++) result[i] = rootPath.getPathComponent(i); for(int i = 0; i < relPath.getPathCount(); i++) result[i + rpl] = relPath.getPathComponent(i); return new TreePath(result); } private Object[] relativeO(Object[] absPath) { if(absPath == null) return null; int rpl = rootPath.getPathCount() - 1; Object[] result = new Object[absPath.length - rpl]; for(int i = 0; i < result.length; i++) result[i] = absPath[i + rpl]; return result; } public TreePath relative(TreePath absPath) { if(absPath == null) return null; return new TreePath(relativeO(absPath.getPath())); } public String toString() { return "SubTreeModel" + count; } } /* $Log: SubTreeModel.java,v $ Revision 1.1 2002/07/11 12:09:52 ohitz Initial checkin Revision 1.5 2001/01/12 08:26:21 schubige TJGUI update and some TreeView bug fixes Revision 1.4 2001/01/04 09:58:49 schubige fixed bugs reported by iiuf.dev.java.Verify Revision 1.3 2001/01/03 16:54:55 schubige various bugs fixed reported by iiuf.dev.java.Verify Revision 1.2 2001/01/03 12:40:18 schubige graph stuff beta Revision 1.1 2001/01/03 08:31:31 schubige graph stuff beta */