taxtreemodel.java

来自「《深入浅出设计模式》的完整源代码」· Java 代码 · 共 228 行

JAVA
228
字号
package taxonomy;import javax.swing.event.*;import javax.swing.tree.*;import java.util.Enumeration;import java.util.Vector;/**  An implementation of the TreeModel interface for use with taxonomies.  @see javax.swing.tree.TableModel  @see <u>Java Swing</u> pp 556  @see <u>Java Swing</u> pp 574*/public class TaxTreeModel implements TreeModel {  /**    A collection of listeners to this model.  */  private Vector treeModelListeners = new Vector();  /**    A listener to be notified when undoable edits are made to this model.  */  private UndoableEditListener undoListener;  /**    A reference to the root of the taxonomy this model describes.  */  private Node root;  /**    Construct a new taxonomy tree model.    @param aRoot A reference to the root of the taxonomy this model describes    @param aListener A listener to be notified when undoable edits are made                        to this model  */  public TaxTreeModel(Node aRoot, UndoableEditListener aListener) {    root = aRoot;    undoListener = aListener;  }  /**    Find an element within the taxonomy.    @param val The element to locate    @return A reference to the node in the taxonomy that contains            <code>val</code>, or <code>null</code> if <code>val</code>            is not found  */  public Node find(Object val) {    return locate(root, val);  }  // Helper routine for find.  Performs depth first search starting at n.  private Node locate(Node n, Object val) {    Node lostNode = null;    if(n.getElement().equals(val)) {      lostNode = n;    } else {      for(int i = 0; i < n.fanOut(); i++) {        lostNode = locate((Node)n.nthChild(i), val);        if(lostNode != null) {          break;        }      }    }    return lostNode;  }  /**   * method added for debug, but every tree should have at least one!   * does an in-order traversal   * @param n the node to start from   */  private void traverse(Node n) {    for(int j = 0; j < n.fanOut(); j++) {      Node temp = (Node)n.nthChild(j);      traverse(temp);      if(temp.fanOut() == 0) {        break;      }    }  }  /**    Build a tree model event.    @param aNode The root of the modified subtree    @return A tree model event which can be passed to any tree model listeners    @see javax.swing.event.TreeModelEvent  */  public TreeModelEvent buildTreeModelEvent(Node aNode) {    // store the path from aNode to the root of the underlying taxonomy    // in a vector    Vector pathVector = new Vector();    aNode.getPathToRoot(pathVector);    // allocate an array of objects that's the same size as the path    // from aNode to the root of the underlying taxonomy    // copy the path information from the vector to the array of objects    Object[] pathArray = pathVector.toArray();    // construct and return a new TreeModelEvent using this path    TreeModelEvent treeEvent = new TreeModelEvent(this, pathArray);    return treeEvent;  }  /**    Add an entry to the taxonomy (encoding that <code>pVal isa cVal</code>).    @param pVal Parent element    @param cVal Child element  */  public void addChild(Object pVal, Object cVal) {    // perform the insertion on the underlying taxonomy    Node parentNode;    parentNode = find(pVal);    Node childNode = parentNode.addChild(cVal);    // build a tree model event for this insertion    // notify any tree model listeners about this event    TreeModelEvent ev = buildTreeModelEvent(parentNode);    notifyTreeModelListeners(ev);    // notify the undoable edit listener that such an event has taken place    if(undoListener != null) {      undoListener.undoableEditHappened(new UndoableEditEvent(this, new UndoableTreeEdit(this, ev, pVal, cVal)));    }  }  /**    Notify all tree model listeners that some tree model event has occurred.    @param tme The tree model event that has occurred    @see javax.swing.event.TreeModelListener    @see javax.swing.event.TreeModelListener#treeStructureChanged(javax.swing.event.TreeModelEvent)  */  public void notifyTreeModelListeners(TreeModelEvent tme) {    for(int j = 0; j < treeModelListeners.size(); j++) {      TreeModelListener aListener = (TreeModelListener)treeModelListeners.get(j);      aListener.treeStructureChanged(tme);    }  }  /**   *  Adds a listener for the TreeModelEvent posted after the tree changes.   * @param tml A TreeModelListener   */  public void addTreeModelListener(TreeModelListener tml) {    treeModelListeners.add(tml);  }  /**    Returns the child of <code>parent</code> at index <code>index</code> in    the parent's child array.    @param parent A reference to a node in the taxonomy tree    @param index The index of the desired child of parent    @return A reference to the desired child node of parent  */  public Object getChild (Object parent, int index) {    return ((Node)parent).nthChild(index);  }  /**    Returns the number of children of <code>parent</code>.    @param parent A refernce to a node in the taxonomy tree    @return The number of children of parent  */  public int getChildCount(Object parent) {    int number = ((Node)parent).fanOut();    return number;  }  /**    Returns the index of <code>child</code> in <code>parent</code>.    @param parent A reference to a node in the taxonomy tree    @param child A reference to a node in the taxonomy tree    @return The index of child in parent's array of children  */  public int getIndexOfChild(Object parent, Object child) {    return ((Node)parent).positionOfChild((Node)child);  }  /**    Returns the root of this taxonomy tree.    @return A reference to the root node of this taxonomy tree  */  public Object getRoot() {    return root;  }  /**    Returns true if node is a leaf.    @param node A reference to a node in the taxonomy tree    @return <code>true</code> if node is a leaf, <code>false</code> otherwise  */  public boolean isLeaf(Object node) {    return ((Node)node).isLeaf();  }  /**    Removes a listener previously added with addTreeModelListener().    @param tml A TreeModelListener  */  public void removeTreeModelListener(TreeModelListener tml) {    if(treeModelListeners.contains(tml))      treeModelListeners.remove(tml);  }  /**    Messaged when the user has altered the value for the item    identified by path to newValue.  <em>Not used by this model.</em>  */  public void valueForPathChanged(TreePath path, Object newValue) {}}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?