shogitai
shogitai

Reputation: 1961

Stoppable Java console progressbar

I am looking for a way to stop the progress of the following bar:

private static void cancellaaaaaaaaable() throws InterruptedException {
    System.out.println("Cancellaaaaaaable!");
    System.out.print(ANSI_RED);
    for(int i = 0; i < 79; i++){
        // Something that allows user input/interaction capable to stop the progressbar
        System.out.print("█");
        TimeUnit.MILLISECONDS.sleep(500);
    }
    System.out.print(ANSI_RESET);
}

When the progressbar starts, the user should have about 40 seconds to decide to stop and cancel the progress bar.

enter image description here

Is there a way to do that? It's great any keyboard input, except those that brutally stop the process.

Upvotes: 3

Views: 519

Answers (2)

Arnaud
Arnaud

Reputation: 17524

Here is a solution inspired from how to read from standard input non-blocking?

The idea is to check whether there is something to read from System.in .

Note that this only works if the input is validated (like with the Enter key), but even an empty input works (Enter key pressed directly), so you could add some "Press Enter to cancel" message .

private static void cancellaaaaaaaaable() throws InterruptedException {
    System.out.println("Cancellaaaaaaable!");
    System.out.print(ANSI_RED);

    InputStreamReader inStream = new InputStreamReader(System.in);
    BufferedReader bufferedReader = new BufferedReader(inStream);
    for (int i = 0; i < 79; i++) {

        System.out.print("█");
        TimeUnit.MILLISECONDS.sleep(500);

        // Something that allows user input/interaction capable to stop the progressbar
        try {
            if (bufferedReader.ready()) {
                break;
            }
        } catch (IOException e) {

            e.printStackTrace();
        }
    }
    System.out.print(ANSI_RESET);
}

Note that you may perform more advanced console things with Java Curses Library for instance.

Upvotes: 3

define a Callable:

class MyCallable implements Callable<Boolean> {

    @Override
    public Boolean call() throws Exception {
        for (int i = 0; i <= 99; i++) {
            System.out.print("█");
            try {
                TimeUnit.MILLISECONDS.sleep(500);
            } catch (InterruptedException e) {
                e.getStackTrace();
                return false;
            }
        }
        return true;
    }
}

then a FutureTask and an ExecutroService:

public static void main(String[] args) throws InterruptedException {
    System.out.println("Cancellaaaaaaable!");
    MyCallable callable1 = new MyCallable();
    FutureTask<Boolean> futureTask1 = new FutureTask<>(callable1);

    ExecutorService executor = Executors.newFixedThreadPool(1);
    executor.execute(futureTask1);
    TimeUnit.MILLISECONDS.sleep(500);
    futureTask1.cancel(true);
    System.out.println("\nDone");

}

and cancel that whenever you need it doing:

futureTask1.cancel(true);

Upvotes: 1

Related Questions