public static boolean scrollToVisible(@NotNull JTree tree, @NotNull TreePath path, boolean centered) {
    assert EventQueue.isDispatchThread();
    Rectangle bounds = tree.getPathBounds(path);
    if (bounds == null) {
      if (LOG.isTraceEnabled()) LOG.debug("cannot scroll to: ", path);
      return false;
    }
    internalScroll(tree, bounds, centered);
    // notify screen readers that they should notify the user that the visual appearance of the component has changed
    AccessibleContext context = tree.getAccessibleContext();
    if (context != null) context.firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY, false, true);
    // try to scroll later when the tree is ready
    long stamp = 1L + getScrollTimeStamp(tree);
    tree.putClientProperty(TREE_UTIL_SCROLL_TIME_STAMP, stamp);
    ClientProperty.put(tree, TREE_IS_BUSY, true);
    EdtScheduledExecutorService.getInstance().schedule(() -> {
      Rectangle boundsLater = stamp != getScrollTimeStamp(tree) ? null : tree.getPathBounds(path);
      if (boundsLater != null) internalScroll(tree, boundsLater, centered);
      ClientProperty.remove(tree, TREE_IS_BUSY);
    }, 5, MILLISECONDS);
    return true;
  }
public static boolean scrollToVisible(@NotNull JTree tree, @NotNull TreePath path, boolean centered)