tags:

views:

297

answers:

3
+1  Q: 

Java dynamic JTree

I want to find the method that adds nodes to a JTree dynamically, looking through the documentation and the examples, this can only be done at the constructor of the JTree.

If possible please show me the code snippets to do this.

Thanks in advance.

+3  A: 

Try this

Edit with more explanation: you want your tree model to be based on MutableTreeNode. The link above is an example from the Sun tutorial.

I82Much
I saw this example, but i cant find the source code for it nor i know how to set a root node or get the root node at runtime to use it.Thanks for your concern.
Ahmad Hajou
+3  A: 

You need to have a custom implementation of a TreeModel and TreeNode, see bellow. Just extend LazyTreeModel and implement loadChildren().

There a few dependencies that you must replace with your implementations : LOG - your logger and WorkerManager.getInstance().schedule(new LoadNodesWorker()) you can replace it with a Thread() - Worker is the equivalent of 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();
}

}

adrian.tarau
+1  A: 

The Sun example tutorial mentioned by I82Much, includes a demo project, DynamicTreeDemo, that is made up of the two source files DynamicTreeDemo.java and DynamicTree.java. You should be able to get to them from these links.

clartaq