void (Tree tree) { var model = tree.getModel(); if (model == null) { return; } // Can't figure child count before a node is expanded, so we have to do this in two passes: // 1. first, expand everything that potentially needs expanding; // 2. second, collapse back everything that doesn't need to be expanded. TreeUtil.promiseExpand(tree, path -> { var level = path.getPathCount(); if (level == 1) { return TreeVisitor.Action.CONTINUE; // The root isn't visible and always expanded. } else { var siblingCount = model.getChildCount(path.getParentPath().getLastPathComponent()); if (level == 2) { return siblingCount < 10 ? TreeVisitor.Action.CONTINUE : TreeVisitor.Action.SKIP_SIBLINGS; } else { return siblingCount == 1 ? TreeVisitor.Action.CONTINUE : TreeVisitor.Action.SKIP_SIBLINGS; } } }).onSuccess(ignored -> { TreeUtil.promiseVisit(tree, path -> { var level = path.getPathCount(); Object value = path.getLastPathComponent(); var childCount = model.getChildCount(value); if (level == 1) { // Don't even bother visiting the tree if the root has too many children. return childCount < 10 ? TreeVisitor.Action.CONTINUE : TreeVisitor.Action.SKIP_CHILDREN; } else if (!tree.isExpanded(path)) { // Ignore everything that wasn't expanded above. return TreeVisitor.Action.SKIP_CHILDREN; } else { if (childCount == 1) { // Check auto expanded nodes, no matter how deep they are. return TreeVisitor.Action.CONTINUE; } else { // Reached the deepest auto expanded node, check its child count. if (childCount > 5) { tree.collapsePath(path); } return TreeVisitor.Action.SKIP_CHILDREN; // Same as SKIP_SIBLINGS, really, as there's only one node on this level. } } }); }); }