import javax.swing.tree.*;
static > JTree jDynamicTree(A root, IF1 makeChildren, O... _) {
ret jDynamicTree(root, toF1(makeChildren), _);
}
static > JTree jDynamicTree(final A root, final F1 makeChildren, fO... _) {
ret swing(func -> JTree {
optPar IF1 valueToText;
DefaultMutableTreeNode rootNode = new(root);
rootNode.add(new DefaultMutableTreeNode(jDynamicTree_dummy()));
final JTree tree = new JTree(rootNode) {
public S convertValueToText(O value, bool selected, bool expanded, bool leaf, int row, bool hasFocus) {
if (valueToText != null) {
O userObject = ((DefaultMutableTreeNode) value).getUserObject();
pcall { ret str(valueToText.get((A) userObject)); }
}
ret super.convertValueToText(value, selected, expanded, leaf, row, hasFocus);
}
};
tree.setShowsRootHandles(true);
tree.collapseRow(0);
final bool keepChildrenOnCollapse = optParam(_, 'keepChildrenOnCollapse, false);
bool makeChildrenIsFast = boolParam makeChildrenIsFast(_) || makeChildren == null;
bool debug = boolPar debug(_);
class jDynamicTree_Listener implements TreeWillExpandListener {
public void treeWillCollapse(TreeExpansionEvent e) {}
public void treeWillExpand(TreeExpansionEvent e) { pcall {
if (debug) print("treeWillExpand");
DefaultMutableTreeNode node = cast e.getPath().getLastPathComponent();
if (!keepChildrenOnCollapse || jDynamicTree_isInDummyState(node)) {
L l = asList(callF(makeChildren, (A) node.getUserObject()));
if (makeChildrenIsFast
? replaceTreeNodeChildren_withDummyChild2(node, l, jDynamicTree_dummy(), makeChildren)
: replaceTreeNodeChildren_withDummyChild(node, l, jDynamicTree_dummy()))
((DefaultTreeModel) tree.getModel()).nodeStructureChanged(node);
}
}}
}
tree.addTreeWillExpandListener(new jDynamicTree_Listener);
ret tree;
});
}