void (@NotNull JTree tree, boolean strict, int keepSelectionLevel) { assert EventQueue.isDispatchThread(); int row = tree.getRowCount(); if (row <= 1) return; // nothing to collapse final TreePath leadSelectionPath = tree.getLeadSelectionPath(); int minCount = 1; // allowed path count to collapse if (!tree.isRootVisible()) minCount++; if (!tree.getShowsRootHandles()) { minCount++; strict = true; } // use the parent path of the normalized selection path to prohibit its collapsing TreePath prohibited = leadSelectionPath == null ? null : normalize(leadSelectionPath, minCount, keepSelectionLevel).getParentPath(); // Collapse all while (0 < row--) { if (!strict && row == 0) break; TreePath path = tree.getPathForRow(row); assert path != null : "path is not found at row " + row; int pathCount = path.getPathCount(); if (pathCount < minCount) continue; if (pathCount == minCount && row > 0) strict = true; if (!isAlwaysExpand(path) && !path.isDescendant(prohibited)) tree.collapsePath(path); } if (leadSelectionPath == null) return; // no selection to restore if (!strict) minCount++; // top level node is not collapsed internalSelect(tree, normalize(leadSelectionPath, minCount, keepSelectionLevel)); }