Terminal { @SneakyThrows @SuppressWarnings("unused") public <T> T printWaiting(Callable<T> task) { val executor = Executors.newSingleThreadExecutor(); try { val future = executor.submit(task); int i = 0; while (!future.isDone()) { if (ansi && SPIN_WAITING) { Thread.sleep(50L); val animation = "|/-\\"; if (i > 0) { print(ansi().cursorLeft(2).toString()); } val c = animation.charAt(i++ % animation.length()); val state = " " + ansi().fg(GREEN).a(c).reset().toString(); print(state); } else { Thread.sleep(5000L); print("."); } } return future.get(); } finally { executor.shutdownNow(); } } @Autowired  Terminal(@Value("${client.ansi}") boolean ansi, @Value("${client.silent}") boolean silent); static boolean isTty(); Terminal printLine(); @SneakyThrows @SuppressWarnings("unused") T printWaiting(Callable<T> task); @SneakyThrows Terminal printWaiting(Runnable task); Terminal printStatus(int stepNumber, String text); Terminal printStatus(String text); Terminal printError(String text, Object... args); Terminal printWarn(String text, Object... args); Terminal println(String text); Terminal printf(String text, Object... args); Terminal print(String text); String ansi(String text); String option(String text); String label(String text); String email(String text); String url(String text); String value(long text); String error(String text, Object... args); String warn(String text, Object... args); String value(String text); String line(); int getWidth(); void clearLine();  }
@Test public void testPrintWaiting() { val terminal = new Terminal(true, false); val result = terminal.printWaiting(this::doWork); System.out.println(result); }