2009-12-29 62 views
1

我想查找通过文档和示例动态添加节点到JTree的方法,这只能在JTree的构造函数中完成。Java动态JTree

如果可能的话,请给我看代码片段来做到这一点。

在此先感谢。

+1

您不能动态地将节点添加到JTree,因为JTree是视图部件,而不是模型部件。你需要分离和跟踪你的模型(Adrian发布了一个好的模型来使用),然后你可以动态地将节点添加到你的模型中。 – Pace 2009-12-29 17:01:52

回答

3

尝试this

编辑与更多的解释:你要根据你的MutableTreeNode树模型。上面的链接是Sun教程的一个例子。

+0

我看到这个例子,但我无法找到它的源代码,也不知道如何设置根节点或在运行时获取根节点来使用它。 感谢您的关注。 – 2009-12-29 15:29:45

6

您需要有一个TreeModel和TreeNode的自定义实现,请参见下文。只需扩展LazyTreeModel并实现loadChildren()。你可以用一个Thread()来代替它 - 工作人员相当于你的日志记录工具 和WorkerManager.getInstance()。schedule(新的LoadNodesWorker())。 Runnable接口。

public abstract class LazyTreeModel extends DefaultTreeModel implements TreeWillExpandListener { 

public LazyTreeModel(TreeNode root, JTree tree) { 
    super(root); 
    setAsksAllowsChildren(true); 
    tree.addTreeWillExpandListener(this); 
    tree.setModel(this); 
} 

public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException { 
    LazyTreeNode node = (LazyTreeNode) event.getPath().getLastPathComponent(); 
    if (node.isLoaded()) { 
     return; 
    } 
    setLoading(node, false); 
    WorkerManager.getInstance().schedule(new LoadNodesWorker(node)); 
} 

public void reloadNode(String id) { 
    LazyTreeNode node = findNode(id); 
    if (node != null) { 
     node.setLoaded(false); 
     setLoading(node, true); 
     WorkerManager.getInstance().schedule(new LoadNodesWorker(node)); 
    } 
} 

public void reloadParentNode(String id) { 
    LazyTreeNode node = findParent(id); 
    if (node != null) { 
     node.setLoaded(false); 
     setLoading(node, true); 
     WorkerManager.getInstance().schedule(new LoadNodesWorker(node)); 
    } 
} 

public LazyTreeNode findParent(String id) { 
    LazyTreeNode node = findNode(id); 
    if (node != null && node.getParent() != null) { 
     return (LazyTreeNode) node.getParent(); 
    } 
    return null; 
} 

public void loadFirstLevel() { 
    setLoading((LazyTreeNode) getRoot(), false); 
    WorkerManager.getInstance().schedule(new LoadNodesWorker((LazyTreeNode) getRoot())); 
} 

public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException { 
} 

protected void setChildren(LazyTreeNode parentNode, LazyTreeNode... nodes) { 
    if (nodes == null) { 
     return; 
    } 
    int childCount = parentNode.getChildCount(); 
    if (childCount > 0) { 
     for (int i = 0; i < childCount; i++) { 
      removeNodeFromParent((MutableTreeNode) parentNode.getChildAt(0)); 
     } 
    } 
    for (int i = 0; i < nodes.length; i++) { 
     insertNodeInto(nodes[i], parentNode, i); 
    } 
} 

private void setLoading2(final LazyTreeNode parentNode, final boolean reload) { 
    if (reload) { 
     setChildren(parentNode, createReloadingNode()); 
    } else { 
     setChildren(parentNode, createLoadingNode()); 
    } 
} 

private void setLoading(final LazyTreeNode parentNode, final boolean reload) { 
    if (SwingUtilities.isEventDispatchThread()) { 
     setLoading2(parentNode, reload); 
    } else { 
     try { 
      SwingUtilities.invokeAndWait(new Runnable() { 
       public void run() { 
        setLoading2(parentNode, reload); 
       } 
      }); 
     } catch (Exception e) { 
      LOG.error("Cannot create loading node", e); 
     } 
    } 
} 

private LazyTreeNode findNode(String id) { 
    return findNode(id, (LazyTreeNode) getRoot()); 
} 

private LazyTreeNode findNode(String id, LazyTreeNode parent) { 
    int count = parent.getChildCount(); 
    for (int i = 0; i < count; i++) { 
     LazyTreeNode node = (LazyTreeNode) parent.getChildAt(i); 
     if (id.equals(node.getId())) { 
      return node; 
     } 
     if (node.isLoaded()) { 
      node = findNode(id, node); 
      if (node != null) { 
       return node; 
      } 
     } 
    } 
    return null; 
} 

public abstract LazyTreeNode[] loadChildren(LazyTreeNode parentNode); 

protected LazyTreeNode createLoadingNode() { 
    return new LazyTreeNode(null, "Loading...", false); 
} 

protected LazyTreeNode createReloadingNode() { 
    return new LazyTreeNode(null, "Refreshing...", false); 
} 

class LoadNodesWorker implements Worker { 

    private LazyTreeNode parentNode; 

    LoadNodesWorker(LazyTreeNode parent) { 
     this.parentNode = parent; 
    } 

    public String getName() { 
     return "Lazy loading of node " + parentNode.getId(); 
    } 

    public void execute() throws Exception { 
     final LazyTreeNode[] treeNodes = loadChildren(parentNode); 
     if (treeNodes == null) { 
      return; 
     } 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       parentNode.setLoaded(true); 
       setChildren(parentNode, treeNodes); 
      } 
     }); 
    } 
} 

}

public class LazyTreeNode extends DefaultMutableTreeNode { 

private boolean loaded; 
private String id; 

public LazyTreeNode(String id) { 
    this(id, null); 
} 

public LazyTreeNode(String id, Object userObject) { 
    this(id, userObject, true); 
} 

public LazyTreeNode(String id, Object userObject, boolean allowsChildren) { 
    super(userObject, allowsChildren); 
    this.id = id; 
} 

public String getId() { 
    return id; 
} 

protected boolean isLoaded() { 
    return loaded; 
} 

protected void setLoaded(boolean loaded) { 
    this.loaded = loaded; 
} 

@Override 
public boolean isLeaf() { 
    return !getAllowsChildren(); 
} 

}