2009-12-29 76 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(); 
} 

}