This question already has an answer here:
-
Command line progress bar in Java
12 answers
Is there are easy way to implement a rolling percentage for a process in Java, to be displayed in the console? I have a percentage data type (double) I generated during a particular process, but can I force it to the console window and have it refresh, instead of just printing a new line for each new update to the percentage? I was thinking about pushing a cls and updating, because I'm working in a Windows environment, but I was hoping Java had some sort of built-in capability. All suggestions welcomed! Thanks!
You can print a carriage return \r
to put the cursor back to the beginning of line.
Example:
public class ProgressDemo {
static void updateProgress(double progressPercentage) {
final int width = 50; // progress bar width in chars
System.out.print("\r[");
int i = 0;
for (; i <= (int)(progressPercentage*width); i++) {
System.out.print(".");
}
for (; i < width; i++) {
System.out.print(" ");
}
System.out.print("]");
}
public static void main(String[] args) {
try {
for (double progressPercentage = 0.0; progressPercentage < 1.0; progressPercentage += 0.01) {
updateProgress(progressPercentage);
Thread.sleep(20);
}
} catch (InterruptedException e) {}
}
}
I use following code:
public static void main(String[] args) {
long total = 235;
long startTime = System.currentTimeMillis();
for (int i = 1; i <= total; i = i + 3) {
try {
Thread.sleep(50);
printProgress(startTime, total, i);
} catch (InterruptedException e) {
}
}
}
private static void printProgress(long startTime, long total, long current) {
long eta = current == 0 ? 0 :
(total - current) * (System.currentTimeMillis() - startTime) / current;
String etaHms = current == 0 ? "N/A" :
String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(eta),
TimeUnit.MILLISECONDS.toMinutes(eta) % TimeUnit.HOURS.toMinutes(1),
TimeUnit.MILLISECONDS.toSeconds(eta) % TimeUnit.MINUTES.toSeconds(1));
StringBuilder string = new StringBuilder(140);
int percent = (int) (current * 100 / total);
string
.append('\r')
.append(String.join("", Collections.nCopies(percent == 0 ? 2 : 2 - (int) (Math.log10(percent)), " ")))
.append(String.format(" %d%% [", percent))
.append(String.join("", Collections.nCopies(percent, "=")))
.append('>')
.append(String.join("", Collections.nCopies(100 - percent, " ")))
.append(']')
.append(String.join("", Collections.nCopies(current == 0 ? (int) (Math.log10(total)) : (int) (Math.log10(total)) - (int) (Math.log10(current)), " ")))
.append(String.format(" %d/%d, ETA: %s", current, total, etaHms));
System.out.print(string);
}
The result:
I have written such a package in Java.
https://github.com/ctongfei/progressbar
I don't think there's a built-in capability to do what you're looking for.
There is a library that will do it (JLine).
See this tutorial
I'm quite sure there is no way to change anything that the console has already printed because Java considers the console (standard out) to be a PrintStream.
Don't know about anything built in to java itself, but you can use terminal control codes to do things like reposition the cursor. Some details here: http://www.termsys.demon.co.uk/vtansi.htm
Clear the console by running the os specific command and then print the new percentage
import java.util.Random;
public class ConsoleProgress {
private static String CURSOR_STRING = "0%.......10%.......20%.......30%.......40%.......50%.......60%.......70%.......80%.......90%.....100%";
private static final double MAX_STEP = CURSOR_STRING.length() - 1;
private double max;
private double step;
private double cursor;
private double lastCursor;
public static void main(String[] args) throws InterruptedException {
// ---------------------------------------------------------------------------------
int max = new Random().nextInt(400) + 1;
// ---------------------------------------------------------------------------------
// Example of use :
// ---------------------------------------------------------------------------------
ConsoleProgress progress = new ConsoleProgress("Progress (" + max + ") : ", max);
for (int i = 1; i <= max; i++, progress.nextProgress()) {
Thread.sleep(3L); // a task with no prints
}
}
public ConsoleProgress(String title, int maxCounts) {
cursor = 0.;
max = maxCounts;
step = MAX_STEP / max;
System.out.print(title);
printCursor();
nextProgress();
}
public void nextProgress() {
printCursor();
cursor += step;
}
private void printCursor() {
int intCursor = (int) Math.round(cursor) + 1;
System.out.print(CURSOR_STRING.substring((int) lastCursor, intCursor));
if (lastCursor != intCursor && intCursor == CURSOR_STRING.length())
System.out.println(); // final print
lastCursor = intCursor;
}
}
Late for the party, but here's an answer:
public static String getSingleLineProgress(double progress) {
String progressOutput = "Progress: |";
String padding = Strings.padEnd("", (int) Math.ceil(progress / 5), '=');
progressOutput += Strings.padEnd(padding, 0, ' ') + df.format(progress) + "%|\r";
if (progress == 100.0D) {
progressOutput += "\n";
}
return progressOutput;
}
Remember to use System.out.print()
instead of System.out.println()