📄 treeobject.java
字号:
package com.socialite.bizlogic.tree;
import com.socialite.bizlogic.tree.TreeNodeObject;
import com.socialite.bizlogic.util.XMLObject;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.DefaultMutableTreeNode;
import java.util.HashMap;
import java.util.ArrayList;
/*
DynamicTreeDemo:
rootNode = new DefaultMutableTreeNode("Root Node");
treeModel = new DefaultTreeModel(rootNode);
treeModel.addTreeModelListener(new MyTreeModelListener());
tree = new JTree(treeModel);
tree.setEditable(true);
tree.getSelectionModel().setSelectionMode
(TreeSelectionModel.SINGLE_TREE_SELECTION);
tree.setShowsRootHandles(true);
By explicitly creating the tree's model, the code guarantees
that the tree's model is an instance of DefaultTreeModel. That
way, we know all the methods that the tree model supports. For
example, we know that we can invoke the model's insertNodeInto
method, even though that method is not required by the TreeModel
interface.
*/
//TreeObject的同步,ArrayList,HashMap对象的同步还没有考虑(考虑了前者,后者应该就有保证了)
public class TreeObject{
private DefaultTreeModel dfModel;
private TreeNodeObject node;
private DefaultMutableTreeNode fatherDfNode=null;
private TreeNodeObject rootNode=null;
private DefaultMutableTreeNode dfNode;
private static HashMap hMap=new HashMap(200);
private ArrayList aList=new ArrayList();
//构造函数,组装DefaultTreeModel
public TreeObject(XMLObject xmlTree){
String c=xmlTree.getValue("bizlogic.resultparameter.count");
int count=0;
if(c==null){
//什么也不做,此时rootNode==null
}else{
try{
count=Integer.parseInt(c);
}catch(NumberFormatException e){
return;//什么也不做,此时rootNode==null
}
}
//先以根节点构造一个DefaultTreeModel
String node_id="0";
String father_id=null;
String name="Root";
String url=null;
//以rootNode为根节点构造一个DefaultTreeModel树对象
rootNode=new TreeNodeObject(node_id,father_id,name,url);
dfNode=new DefaultMutableTreeNode(rootNode);
dfModel=new DefaultTreeModel(dfNode);
//HashMap中添加node_id到dfNode的映射
hMap.put(node_id,dfNode);
//开始组装树
for(int i=1;i<=count;i++){
node_id=xmlTree.getValue("bizlogic.resultparameter.node_id"+i);
father_id=xmlTree.getValue("bizlogic.resultparameter.father_id"+i);
name=xmlTree.getValue("bizlogic.resultparameter.name"+i);
url=xmlTree.getValue("bizlogic.resultparameter.url"+i);
//构造一个TreeNodeObject对象
node=new TreeNodeObject(node_id,father_id,name,url);
//以node对象为UserObject构造一DefaultMutableTreeNode
dfNode=new DefaultMutableTreeNode(node);
if(!(node_id.trim().equalsIgnoreCase("0"))){//不是root
//查找父亲节点
fatherDfNode=(DefaultMutableTreeNode)hMap.get(father_id);
if(fatherDfNode!=null){//找到则添加为子节点
fatherDfNode.add(dfNode);
//HashMap中添加node_id到dfNode的映射
hMap.put(node_id,dfNode);
}else{//找不到则先将TreeNodeObject类型对象node放入ArrayList
aList.add(node);
}
}
}
//多次遍历ArrayList,将没有组装到树中的节点组装
while(!(aList.isEmpty())){
int aListSize=aList.size();
for(int i=0;i<aListSize;i++){
node=(TreeNodeObject)aList.get(i);
dfNode=new DefaultMutableTreeNode(node);
node_id=node.getNodeId();
father_id=node.getFatherId();
//查找父亲节点
fatherDfNode=(DefaultMutableTreeNode)hMap.get(father_id);
if(fatherDfNode!=null){//找到则添加为子节点
fatherDfNode.add(dfNode);
//HashMap中添加node_id到dfNode的映射
hMap.put(node_id,dfNode);
//删除ArrayList中该节点
aList.remove(i);
}
}
}
}
/*
*
* 判断是否组装了实际的树
*/
/*ublic boolean isExist(){
if(!rootNode==null){
return true;
}
return false;
}
*/
//增加新节点
public void addNode(TreeNodeObject who){
DefaultMutableTreeNode fatherDfNode=null;
DefaultMutableTreeNode dfNode=null;
String node_id=who.getNodeId();
String father_id=who.getFatherId();
dfNode=new DefaultMutableTreeNode(who);
fatherDfNode=(DefaultMutableTreeNode)hMap.get(father_id);
fatherDfNode.add(dfNode);//执行增加子节点
//HashMap中添加node_id到dfNode的映射
hMap.put(node_id,dfNode);
}
//删除节点,如果是非叶子节点则子树一起删除
public void deleteNode(TreeNodeObject who){
DefaultMutableTreeNode dfNode=null;
String node_id=who.getNodeId();
//从hashMap中得到要删除的对象
dfNode=(DefaultMutableTreeNode)hMap.get(node_id);
//修改hashMap
//???更新HashMap,此时已经被删除的子树中节点已经不存在,hMap对应的值应该是null???
//hMap.remove(node_id);//这种方法行吗,需要用下面的第归方法吗
removeObjectFromHashMap(node_id);
//Removes the subtree rooted at this node from the tree, giving this node a null parent.
dfNode.removeFromParent();//从树中删除该节点对应的子树
}
//第归删除HashMap中的节点
private void removeObjectFromHashMap(String whoId){
DefaultMutableTreeNode dfNode=null;
//String node_id=who.getNodeId();
//从hashMap中得到要删除的mapping
dfNode=(DefaultMutableTreeNode)hMap.get(whoId);
DefaultMutableTreeNode dfChild=null;
TreeNodeObject child=null;
String node_id=null;
int childCount=dfNode.getChildCount();
if(childCount==0){
hMap.remove(whoId);
}else{
for(int i=1;i<childCount;i++){
//得到DefaultMutableTreeNode,转化为TreeNodeObject,得到node_id
dfChild=(DefaultMutableTreeNode)dfNode.getChildAt(i);
child=(TreeNodeObject)dfChild.getUserObject();
node_id=child.getNodeId();
//第归调用
removeObjectFromHashMap(node_id);
}
}
}
//修改节点(node_id是不能变的),father_id也不能改变,如果要改变father_id,以后实现move方法
public void modifyNode(TreeNodeObject newNode){
DefaultMutableTreeNode dfNode=null;
TreeNodeObject node=null;
String node_id=newNode.getNodeId();
//从hashMap中得到要修改的对象
dfNode=(DefaultMutableTreeNode)hMap.get(node_id);
node=(TreeNodeObject)dfNode.getUserObject();
//String old_father_id=node.getFatherId();
//String new_node_id=newNode.getNodeId();
//String new_father_id=newNode.getFatherId();
String new_name=newNode.getName();
String new_url=newNode.getUrl();
node.setName(new_name);
node.setUrl(new_url);
//下面的工作还需要吗
dfNode=new DefaultMutableTreeNode(node);
hMap.put(node_id,dfNode);
}
}
/*
TreeObject.java的几个问题:
(1)第93行,108行,119行,124行。
看出来问题没有?93和119无论结点是否能在散列表中找到父结点,都创建一个DefaultMutableTreeNode,不错但效率低下。应当在找到父结点之后(100和125的for循环内部)才创建一个DefaultMutableTreeNode表示子结点。
(2)117到134的for循环
有问题。如果132行remove一个元素,将导致后续元素整体向前挪动。导致问题一:整体挪动效率低下。问题二:下标i++将使得一个元素在这趟for循环中无法访问到。
解决办法一:仍然使用ArrayList,针对第二个问题,在132行之后加一个i--。
解决办法二:将aList定义为链表LinkedList,而不是ArrayList;并且不要通过get(int),而是通过迭代器ListIterator的next()和remove()。
(3)115行开始的while循环
有死循环的可能性。如果一趟while循环没有使得aList元素个数减少呢?所以在while循环外部首先记录aList长度,在循环内部最后判断aList长度是否发生了变化,如果未变化则跳出while循环(接下来该怎么处理,你自己决定)。
(4)178的疑问
应该用你定义的递归方法removeObjectFromHashMap,这样删除得彻底。
(5)242的疑问
不需要。因为你是对散列表中的对象调用方法,并不影响散列表今后的查找。
(6)221的move方法,比较容易,你应该会写吧。
注:这几点在v2中修改
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -