| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| // *** HideableTreeModel *** |
| import java.awt.*; |
| import java.awt.event.*; |
| import java.util.ArrayList; |
| import java.util.Enumeration; |
| import java.util.Vector; |
| import javax.swing.*; |
| import javax.swing.event.*; |
| import javax.swing.tree.*; |
| |
| |
| public class HideableTreeModel implements TreeModel { |
| |
| private Vector modelListeners = new Vector(); |
| private Object root = null; |
| |
| |
| public HideableTreeModel(TreeNode _root) { |
| super(); |
| setRoot(_root); |
| } |
| |
| |
| public Object getRoot() { |
| return this.root; |
| } |
| |
| |
| protected void setRoot(Object r) { |
| this.root = r; |
| } |
| |
| |
| public Object[] getPathToRoot(Object node) { |
| return getPathToRoot(node, 0); |
| } |
| |
| |
| private Object[] getPathToRoot(Object node, int i) { |
| Object anode[]; |
| if(node == null) { |
| if(i == 0) { |
| return null; |
| } |
| anode = new Object[i]; |
| } else { |
| i++; |
| if(node == getRoot()) { |
| anode = new Object[i]; |
| } else { |
| anode = getPathToRoot(getParent(node), i); |
| } |
| anode[anode.length - i] = node; |
| } |
| return anode; |
| } |
| |
| |
| public void addTreeModelListener(TreeModelListener l) { |
| modelListeners.addElement(l); |
| } |
| |
| |
| public void removeTreeModelListener(TreeModelListener l) { |
| modelListeners.removeElement(l); |
| } |
| |
| |
| public void reload() { |
| reload(getRoot()); |
| } |
| |
| |
| public void reload(Object node) { |
| if(node != null) { |
| TreePath tp = new TreePath(getPathToRoot(node)); |
| fireTreeStructureChanged(new TreeModelEvent(this, tp)); |
| } |
| } |
| |
| |
| public void valueForPathChanged(TreePath path, Object newValue) { |
| nodeChanged(path.getLastPathComponent()); |
| } |
| |
| public void nodeInserted(Object node, Object child) { |
| nodeInserted(node, child, -1); |
| } |
| |
| |
| public void nodeInserted(Object node, Object child, int index) { |
| if(index < 0) { |
| index = getIndexOfChild(node, child); |
| } |
| if(node != null && child != null && index >= 0) { |
| TreePath tp = new TreePath(getPathToRoot(node)); |
| int[] ai = { index }; |
| Object[] ac = { child }; |
| fireTreeNodesInserted(new TreeModelEvent(this, tp, ai, ac)); |
| } |
| } |
| |
| |
| public void nodeRemoved(Object node, Object child, int index) { |
| if(node != null && child != null && index >= 0) { |
| TreePath tp = new TreePath(getPathToRoot(node)); |
| int[] ai = { index }; |
| Object[] ac = { child }; |
| fireTreeNodesRemoved(new TreeModelEvent(this, tp, ai, ac)); |
| } |
| } |
| |
| |
| public void nodeChanged(Object node) { |
| if(node != null) { |
| TreePath tp = new TreePath(getPathToRoot(node)); |
| fireTreeNodesChanged(new TreeModelEvent(this, tp, null, null)); |
| } |
| } |
| |
| |
| protected void fireTreeNodesChanged(TreeModelEvent event) { |
| for(int i = 0; i < modelListeners.size(); i++) { |
| ((TreeModelListener)modelListeners.elementAt(i)).treeNodesChanged(event); |
| } |
| } |
| |
| |
| protected void fireTreeNodesInserted(TreeModelEvent event) { |
| for(int i = 0; i < modelListeners.size(); i++) { |
| ((TreeModelListener)modelListeners.elementAt(i)).treeNodesInserted(event); |
| } |
| } |
| |
| |
| protected void fireTreeNodesRemoved(TreeModelEvent event) { |
| for(int i = 0; i < modelListeners.size(); i++) { |
| ((TreeModelListener)modelListeners.elementAt(i)).treeNodesRemoved(event); |
| } |
| } |
| |
| protected void fireTreeStructureChanged(TreeModelEvent event) { |
| for(int i = 0; i < modelListeners.size(); i++) { |
| ((TreeModelListener)modelListeners.elementAt(i)).treeStructureChanged(event); |
| } |
| } |
| |
| |
| public ArrayList getExpandedPaths(JTree tree) { |
| ArrayList expandedPaths = new ArrayList(); |
| addExpandedPaths(tree, tree.getPathForRow(0), expandedPaths); |
| return expandedPaths; |
| } |
| |
| |
| private void addExpandedPaths(JTree tree, TreePath path, ArrayList pathlist) { |
| Enumeration aEnum = tree.getExpandedDescendants(path); |
| while(aEnum.hasMoreElements()) { |
| TreePath tp = (TreePath) aEnum.nextElement(); |
| pathlist.add(tp); |
| addExpandedPaths(tree, tp, pathlist); |
| } |
| } |
| |
| |
| public void expandPaths(JTree tree, ArrayList pathlist) { |
| for(int i = 0; i < pathlist.size(); i++) { |
| tree.expandPath((TreePath)pathlist.get(i)); |
| } |
| } |
| |
| |
| public boolean isLeaf(Object _oNode) { |
| if(_oNode instanceof TreeNode) { |
| return ((TreeNode) _oNode).isLeaf(); |
| } |
| return true; |
| } |
| |
| |
| |
| public Object getParent(Object node) { |
| if(node != getRoot() && (node instanceof TreeNode)) { |
| return ((TreeNode)node).getParent(); |
| } |
| return null; |
| } |
| |
| |
| public boolean isNodeVisible(Object node) { |
| if(node != getRoot()) { |
| if(node instanceof HideableMutableTreeNode) { |
| return ((HideableMutableTreeNode)node).isVisible(); |
| } |
| } |
| return true; |
| } |
| |
| |
| public boolean setNodeVisible(Object node, boolean v) { |
| // can't hide root |
| if(node != getRoot()) { |
| if(node instanceof HideableMutableTreeNode) { |
| HideableMutableTreeNode n = (HideableMutableTreeNode)node; |
| if(v != n.isVisible()) { |
| TreeNode parent = n.getParent(); |
| if(v) { |
| // need to get index after showing... |
| n.setVisible(v); |
| int index = getIndexOfChild(parent, n); |
| nodeInserted(parent, n, index); |
| } else { |
| // need to get index before hiding... |
| int index = getIndexOfChild(parent, n); |
| n.setVisible(v); |
| nodeRemoved(parent, n, index); |
| } |
| } |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| |
| public boolean isPathToNodeVisible(Object node) { |
| Object[] path = getPathToRoot(node); |
| for(int i = 0; i < path.length; i++) { |
| if(!isNodeVisible(path[i])) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| |
| public void ensurePathToNodeVisible(Object node) { |
| Object[] path = getPathToRoot(node); |
| for(int i = 0; i < path.length; i++) { |
| setNodeVisible(path[i], true); |
| } |
| } |
| |
| |
| public Object getChild(Object parent, int index) { |
| if(parent instanceof TreeNode) { |
| TreeNode p = (TreeNode) parent; |
| for(int i = 0, j = -1; i < p.getChildCount(); i++) { |
| TreeNode pc = (TreeNode)p.getChildAt(i); |
| if(isNodeVisible(pc)) { |
| j++; |
| } |
| if(j == index) { |
| return pc; |
| } |
| } |
| } |
| return null; |
| } |
| |
| |
| public int getChildCount(Object parent) { |
| int count = 0; |
| if(parent instanceof TreeNode) { |
| TreeNode p = (TreeNode) parent; |
| for(int i = 0; i < p.getChildCount(); i++) { |
| TreeNode pc = (TreeNode)p.getChildAt(i); |
| if(isNodeVisible(pc)) { |
| count++; |
| } |
| } |
| } |
| return count; |
| } |
| |
| |
| public int getIndexOfChild(Object parent, Object child) { |
| int index = -1; |
| if(parent instanceof TreeNode && child instanceof TreeNode) { |
| TreeNode p = (TreeNode)parent; |
| TreeNode c = (TreeNode)child; |
| if(isNodeVisible(c)) { |
| index = 0; |
| for(int i = 0; i < p.getChildCount(); i++) { |
| TreeNode pc = (TreeNode)p.getChildAt(i); |
| if(pc.equals(c)) { |
| return index; |
| } |
| if(isNodeVisible(pc)) { |
| index++; |
| } |
| } |
| } |
| } |
| return index; |
| } |
| } |