private static Dimension getPreferredScrollableViewportSize(@NotNull JTree tree) {
    if (JTree.class != getPreferredScrollableViewportSizeDeclaringClass(tree)) {
      return tree.getPreferredScrollableViewportSize(); // may be null
    }
    Dimension size = getPreferredSizeWithoutScrollBars(tree);

    int fixedHeight = tree.getRowHeight();

    int modelRows = tree.getRowCount();
    if (modelRows <= 0) {
      if (fixedHeight <= 0) {
        fixedHeight = Registry.intValue("ide.preferred.scrollable.viewport.fixed.height", 0);
      }
      if (fixedHeight <= 0) {
        fixedHeight = UIManager.getInt(JBUI.CurrentTheme.Tree.rowHeightKey());
      }
      if (fixedHeight <= 0) {
        fixedHeight = JBUIScale.scale(16);
      }
    }
    int visibleRows = tree.getVisibleRowCount();
    if (visibleRows <= 0) {
      visibleRows = Registry.intValue("ide.preferred.scrollable.viewport.visible.rows", 10);
    }

    boolean addExtraSpace = (modelRows != visibleRows) && Registry.is("ide.preferred.scrollable.viewport.extra.space", true);
    Insets insets = getInnerInsets(tree);
    size.height = insets != null ? insets.top + insets.bottom : 0;
    if (0 < fixedHeight) {
      size.height += fixedHeight * visibleRows;
      if (addExtraSpace) size.height += fixedHeight / 2;
    }
    else if (visibleRows > 0) {
      int lastRow = Math.min(visibleRows, modelRows - 1);
      Rectangle bounds = tree.getRowBounds(lastRow);
      if (bounds != null) {
        size.height = bounds.y + bounds.height * (visibleRows - lastRow);
        if (addExtraSpace) {
          size.height += bounds.height / 2;
        }
        else if (insets != null) {
          size.height += insets.bottom;
        }
      }
    }
    return size;
  }
private static Dimension getPreferredScrollableViewportSize(@NotNull JTree tree)