AbstractLayoutCache () { if (is("ide.tree.experimental.layout.cache", true)) { return new DefaultTreeLayoutCache(path -> { handleAutoExpand(path); return Unit.INSTANCE; }); } if (isLargeModel() && getRowHeight() > 0) { return new FixedHeightLayoutCache(); } return new VariableHeightLayoutCache() { @Override public void setExpandedState(TreePath path, boolean isExpanded) { int oldRowCount = getRowCount(); super.setExpandedState(path, isExpanded); if (isExpanded) onSingleChildInserted(path, oldRowCount); } @Override public void treeNodesInserted(TreeModelEvent event) { int oldRowCount = getRowCount(); super.treeNodesInserted(event); onSingleChildInserted(event.getTreePath(), oldRowCount); } private void onSingleChildInserted(TreePath path, int oldRowCount) { if (path == null || oldRowCount + 1 != getRowCount()) return; JTree tree = getTree(); if (!shouldAutoExpand(tree, path)) return; TreeModel model = tree.getModel(); if (model instanceof AsyncTreeModel && 1 == model.getChildCount(path.getLastPathComponent())) { int pathCount = 1 + path.getPathCount(); for (int i = 0; i <= oldRowCount; i++) { TreePath row = getPathForRow(i); if (row != null && pathCount == row.getPathCount() && path.equals(row.getParentPath())) { handleAutoExpand(row); // this code is intended to auto-expand a single child node return; } } } } }; }