import javax.swing.tree.*; // dummy text you can use as a temporary child for a lazy-filled node sS jDynamicTree_v1_dummy = ""; // updateChildren: func(DefaultMutableTreeNode) -> bool // (true=there was a change) static JTree jDynamicTree_v1(final DefaultMutableTreeNode rootNode, final F1 updateChildren) { ret swing(func -> JTree { final JTree tree = new JTree(rootNode); tree.setShowsRootHandles(true); tree.collapseRow(0); tree.addTreeWillExpandListener(new TreeWillExpandListener { public void treeWillCollapse(TreeExpansionEvent e) {} public void treeWillExpand(TreeExpansionEvent e) { DefaultMutableTreeNode node = cast e.getPath().getLastPathComponent(); if (isTrue(pcallF(updateChildren, node))) ((DefaultTreeModel) tree.getModel()).nodeStructureChanged(node); } }); ret tree; }); }