Java动态JTree

时间:2009-12-29 13:36:13

标签: java swing

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

如果可能的话,请告诉我代码片段。

提前致谢。

3 个答案:

答案 0 :(得分:7)

您需要具有TreeModel和TreeNode的自定义实现,请参阅下面的内容。只需扩展LazyTreeModel并实现loadChildren()。

您必须用您的实现替换一些依赖项:LOG - 您的记录器 和WorkerManager.getInstance()。schedule(新的LoadNodesWorker())你可以用Thread()替换它 - Worker相当于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();
}

}

答案 1 :(得分:3)

尝试this

使用更多解释进行编辑:您希望树模型基于MutableTreeNode。上面的链接是Sun教程中的一个示例。

答案 2 :(得分:1)

I82Much提到的Sun示例教程包括一个演示项目DynamicTreeDemo,该项目由两个源文件DynamicTreeDemo.javaDynamicTree.java组成。你应该可以从这些链接找到他们。