package nu.fw.jeti.util; import java.util.ArrayList; import java.util.Hashtable; import java.util.LinkedList; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; /** * Used to filter some nodes from a tree. That is nodes which the * selector decides not to show does not seem to exist in the tree. * The selector is assumed to not change behavior over time. * * @author Martin Forssen */ public class TreeModelFilter implements TreeModel, TreeModelListener { private TreeModelSelector selector; private TreeModel model; private LinkedList listeners = new LinkedList(); private Hashtable nodes = new Hashtable(30); public TreeModelFilter(TreeModel model, TreeModelSelector selector) { this.model = model; this.selector = selector; model.addTreeModelListener(this); } /* * TreeModel interface */ public Object getRoot() { return model.getRoot(); } public Object getChild(Object parent, int index) { int max = model.getChildCount(parent); for (int i=0, v=0; i 0) { TreeModelEvent e2 = createEvent(e.getTreePath(), newIndices, newChildren); for (int i = 0; i < listeners.size(); i++) { ((TreeModelListener)listeners.get(i)).treeNodesInserted(e2); } } } public void treeNodesRemoved(TreeModelEvent e) { ArrayList newIndices = new ArrayList(); ArrayList newChildren = new ArrayList(); Object parent = e.getTreePath().getLastPathComponent(); int indices[] = e.getChildIndices(); Object children[] = e.getChildren(); for (int i=0, v=0; i < indices.length; i++) { Boolean visible = (Boolean)nodes.get(children[i]); if (visible != null && visible.booleanValue()) { newIndices.add(new Integer(upperIndex(parent, indices[i]))); newChildren.add(children[i]); } nodes.remove(children[i]); } if (newIndices.size() > 0) { TreeModelEvent e2 = createEvent(e.getTreePath(), newIndices, newChildren); for (int i = 0; i < listeners.size(); i++) { ((TreeModelListener)listeners.get(i)).treeNodesRemoved(e2); } } } public void treeStructureChanged(TreeModelEvent e) { TreePath path = e.getTreePath(); Object node = path.getLastPathComponent(); nodes.put(node, Boolean.valueOf(selector.isVisible(node))); if (path.getPathCount() > 1) { path = path.getParentPath(); } TreeModelEvent e2 = new TreeModelEvent(this, path); for (int i = 0; i < listeners.size(); i++) { ((TreeModelListener)listeners.get(i)).treeStructureChanged(e2); } } private TreeModelEvent createEvent(TreePath path, ArrayList indices, ArrayList children) { int intIndices[] = new int[indices.size()]; for (int i=0; i