package com.limegroup.gnutella.gui.statistics; import java.io.IOException; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.MutableTreeNode; import javax.swing.tree.TreeModel; /** * This class creates the <tt>TreeModel</tt> used in the <tt>JTree</tt> of * the statistics pane. */ //2345678|012345678|012345678|012345678|012345678|012345678|012345678|012345678| final class StatisticsTreeModel { /** * Handle to the <tt>DefaultTreeModel</tt> implementation. */ private DefaultTreeModel _treeModel; /** * Constant handle to the root node of the tree. */ private final StatisticsTreeNode ROOT = new StatisticsTreeNode( new StatisticsPaneParent(StatisticsMediator.ROOT_NODE_KEY), ""); /** * The constructor constructs the <tt>MutableTreeNode</tt> instances * as well as the <tt>TreeModel</tt>. */ StatisticsTreeModel() { _treeModel = new DefaultTreeModel(ROOT); } /** * Adds a new <tt>StatisticsTreeNode</tt> to one of the root node's * children. This should only be called during tree construction. * The first key cannot denote the root. * * @param parentKey the unique identifying key of the node to add as * well as the key for the locale-specific name for * the node as it appears to the user * * @param pane the <tt>StatisticsPane</tt> containing display information * for this node */ void addNode(final String parentKey, final StatisticsPane pane) { MutableTreeNode newNode = new StatisticsTreeNode(pane); MutableTreeNode parentNode; try { parentNode = getParentNode(ROOT, parentKey); } catch (IOException e) { e.printStackTrace(); //the parent node could not be found, so return return; } if (parentNode == null) { // this should never happen return; } // insert the new node _treeModel.insertNodeInto(newNode, parentNode, parentNode.getChildCount()); _treeModel.reload(parentNode); } /** * Removes all children from the node with the specified key. * * @param parentKey the key of the parent node whose children should be * removed */ void removeAllChildren(final String parentKey) { try { MutableTreeNode parentNode = getParentNode(ROOT, parentKey); for(int i=_treeModel.getChildCount(parentNode)-1; i>=0; i--) { MutableTreeNode child = (MutableTreeNode)_treeModel.getChild(parentNode, i); _treeModel.removeNodeFromParent(child); } _treeModel.reload(); } catch(IOException e) { e.printStackTrace(); // this should never happen -- not much we can do if it does } } /** * This method performs a recursive depth-first search for the * parent node with the specified key. * * @param node the current node to search through * @param parentKey the key that will match the key of the parent node * we are searching for * @return the <tt>MutableTreeNode</tt> instance corresponding to * the specified key, or <tt>null</tt> if it could not be found * @throws IOException if a corresponding key does not exist */ private final MutableTreeNode getParentNode(MutableTreeNode node, final String parentKey) throws IOException { if (parentKey == StatisticsMediator.ROOT_NODE_KEY) { return ROOT; } // note that we use the key to denote equality, as each node may // have the same visual name, but it will not have the same key for (int i = 0, length=node.getChildCount(); i<length; i++) { StatisticsTreeNode curNode = (StatisticsTreeNode)node.getChildAt(i); if (curNode.getTitleKey().equals((parentKey))) { return curNode; } MutableTreeNode toReturn = getParentNode(curNode, parentKey); if(toReturn != null) return toReturn; if(curNode.isRoot() && i==(length-1)) { // this means we have looped through all of the nodes // without finding the parent key, so throw an exception String msg = "Parent node not in statistics tree."; throw new IOException(msg); } } // this will never happen -- the exception should always be thrown return null; } /** * Returns the wrapped <tt>TreeModel</tt> instance. * * @return the enclosed <tt>TreeModel</tt> instance */ final TreeModel getTreeModel() { return _treeModel; } }