Hi,

I am trying to copy the selected jTree elements on the left to the jTree on the right. However, I had been unable to acomplish it even when I had been looking at some books, google, forums... I had attached a screenshot.

Thanks.

Dani AI

Generated

As hinted, the correct way is to copy data into new node objects and update the target tree's model. A DefaultMutableTreeNode may have only one parent, so reusing the same node instance for two trees will not work. Work on the TreeModel (DefaultTreeModel) and perform changes on the Event Dispatch Thread.

A minimal pattern:

private DefaultMutableTreeNode cloneNode(DefaultMutableTreeNode src) {
    DefaultMutableTreeNode copy = new DefaultMutableTreeNode(src.getUserObject());
    for (int i = 0; i < src.getChildCount(); i++) {
        copy.add(cloneNode((DefaultMutableTreeNode) src.getChildAt(i)));
    }
    return copy;
}

// copy selected nodes from leftTree to root of rightTree
TreePath[] paths = leftTree.getSelectionPaths();
if (paths != null) {
    DefaultTreeModel dstModel = (DefaultTreeModel) rightTree.getModel();
    DefaultMutableTreeNode dstRoot = (DefaultMutableTreeNode) dstModel.getRoot();
    for (TreePath p : paths) {
        DefaultMutableTreeNode srcNode = (DefaultMutableTreeNode) p.getLastPathComponent();
        DefaultMutableTreeNode cloned = cloneNode(srcNode);
        dstModel.insertNodeInto(cloned, dstRoot, dstRoot.getChildCount());
        rightTree.scrollPathToVisible(new TreePath(cloned.getPath()));
    }
}

Notes and gotchas:

  • If node user objects are mutable, clone or copy them too; otherwise both trees will share the same object reference.
  • When multiple nodes are selected, avoid copying a parent and its descendants twice. One simple filter is to sort selected TreePaths by getPathCount (shortest first) and skip a path if any already-accepted path is an ancestor (use TreePath.isDescendant).
  • If the intent is drag-and-drop or clipboard copy/paste, implement a TransferHandler and provide transferable data (or serializable clones) instead.
  • All model mutations should run on the EDT (SwingUtilities.invokeLater/ invokeAndWait if needed). For a move instead of copy, call removeNodeFromParent on the source model after insertion into target.

Recommended Answers

All 3 Replies

That is the only way to go?

huuuh, and your question(s) is(are), because you have various methods how to do it (inside examples)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.