We’re working on an application that allows a user to copy nodes from one tree to another. We have two trees and buttons between them. It turned out that copying nodes wasn’t as straightforward was we had hoped.
There were two issues. First when you add a node to a tree the first thing the component does is remove it from it’s current parent. Fortunately the XMLNode class provides a cloneNode function so before adding a node we only need to call cloneNode. The second issue is with branch settings. When you set a node as a branch using setIsBranch the Tree stores this information separately from the Tree’s data provider. Furthermore, there is no public method to retrieve branch information since getIsBranch will return true if the node is set as a branch OR if it has children.
In the end we created two functions, copySelectedNode clones and copies the selected node from one tree to another and then it calls copyIsBranchInfo to copy the branch information for the copied nodes. copyIsBranchInfo is a separate function since it needs to call itself recursively for all children of the copied node.
function copySelectedNode(fromTree:Tree, toTree:Tree):Void {
// do a deep clone so the copied node isn't removed from old tree
var fromNode:XMLNode = fromTree.selectedNode;
var toNode:XMLNode = fromNode.cloneNode(true);
toTree.addTreeNode(toNode);
copyIsBranchInfo(fromTree, fromNode, toTree, toNode);
}
function copyIsBranchInfo(fromTree:Tree,
fromNode:XMLNode,
toTree:Tree,
toNode:XMLNode):Void {
// Tree doesn't provide a method for checking if a node is
// absolutely set to a branch, it only has getIsBranch which returns
// true if it's set as a branch OR if it has children, which isn't what we
// want.
//
// branchNodes isn't defined as private, but it's clearly intended
// to be private. Iin order to accomlish a correct copy, we're
// going to access it anyways.
//
// if nothing is absolutely set, exit
if (fromTree.branchNodes == undefined) {
return;
}
if (fromTree.branchNodes[fromNode["getID"]()]) {
toTree.setIsBranch(toNode, true);
}
if (fromNode.hasChildNodes()) {
fromNode = fromNode.firstChild;
toNode = toNode.firstChild;
while (fromNode != undefined) {
copyIsBranchInfo(fromTree, fromNode, toTree, toNode);
fromNode = fromNode.nextSibling;
toNode = toNode.nextSibling;
}
}
}
copyButton.addEventListener("click",this);
function click(eventObj) {
copySelectedNode(leftTree, rightTree);
}