Reputation: 13
I am currently programming a progress bar in Java. I would like to add only every 10% the character #
. What is the best way to do this? I would like every 1% the value output. I tried something once. However, it does not quite work. There is an error at loader * (number / number), number)
. I don't want to write this under each other, but all in one line.
How can I improve it?
String laoder = "#";
int rounds = 1000; // Could be 10000, 250000, 60000, ...
// This is 1%
int number = 1000 / 100;
for(int i=0; i < 1000; i++){
// This is X %
if(i == number) {
// I want to print the # every 10 % and the normale percentage every 1%
// For example
// [# ] 1%
// [# ] 2%
// ....
// [## ] 10%
// [##########] Done
System.out.printf("[# %s ] \r \s%", loader * (number / number), number);
// This work, but how can I combine both
System.out.print(repeat(laoder , number / 10) + " \r");
number += number;
}
Thread.Sleep(500)
}
public static String repeat(int count, String with) {
return new String(new char[count]).replace("\0", with);
}
Upvotes: 1
Views: 162
Reputation: 20914
The way to print over the same line in the console is to print the carriage return character. In java code this is done using the following code.
System.out.print("\r");
This simply returns the cursor to the start of the line.
The below code implements your requirements.
int rounds = 1000;
int onePercent = rounds / 100;
int tenPercent = rounds / 10;
int count = 0;
String progress;
for (int i = 1; i <= rounds; i++) {
if (i % onePercent == 0) {
if (i >= onePercent) {
System.out.print("\r");
}
progress = "[";
if (i % tenPercent == 0) {
count++;
}
for (int j = 0; j < count; j++) {
progress += "#";
}
for (int k = count; k < 10; k++) {
progress += " ";
}
progress += "] ";
if (count == 10) {
progress += "Done";
}
else {
progress += (i / onePercent) + "%";
}
System.out.print(progress);
try {
Thread.sleep(500);
}
catch (InterruptedException x) {
// Ignore.
}
}
}
System.out.println();
Upvotes: 0
Reputation: 9394
This shows one way of coding it. You may want to tweak the rounding bits to your taste.
public class TestProgress {
private static String getProgress(int current, int total) {
float status = (float)current/(float)total*100;
String bar = "";
while(bar.length()*10 < status) {
bar += "#";
}
while(bar.length()<10) {
bar += " ";
}
return String.format("%3.0f [%s]", status, bar);
}
public static void main(String[] args) {
for (int i=0;i<5000;i++) {
System.out.print(getProgress(i, 5000));
System.out.print("\r");
}
}
}
Upvotes: 0
Reputation:
Try this.
System.out.printf("\r[%-10s] %d%%", repeat(percent / 10, "#"), percent);
Upvotes: 0
Reputation: 46
It's a fun problem to solve indeed. Below is one way of doing it. All calculation is done using integer numbers (no floating point).
Just note that the total must be greater than 0.
Have fun!
int total = 100; // must be greater than 0
char[] progressBar = new char[10];
Arrays.fill(progressBar, ' ');
for (int progress = 0; progress <= total; progress++) {
int percentage = progress * 100 / total;
Arrays.fill(progressBar, 0, percentage / 10, '#');
System.out.println("[" + String.valueOf(progressBar) + "] " + percentage + "%");
}
Sample output:
[ ] 0%
[# ] 10%
[## ] 20%
[### ] 30%
[#### ] 40%
[##### ] 50%
[###### ] 60%
[####### ] 70%
[######## ] 80%
[######### ] 90%
[##########] 100%
Upvotes: 2
Reputation: 1527
First off as @sanjeevRm suggested the condition on the iff will be evaluated only on the first 10% so you'd have to change it to
if(i%number==0) {
...
}
For the string part I'd suggest to build the string first and then print it to ease the manipulation of it
public String loadString(int hashCount, int maxHashCount) {
String loadString = "[";
//fill in the current loading percentage
for(int i=0; i<hashCount; i++)
loadString+="#";
//now fill in the remaining with white spaces
for(int k=0; k<(maxHashCount-hashCount); k++)
loadString+=" ";
loadString += "]";
return loadString;
}
Now within the original for loop just call the method using
loadString(i/number, rounds/number);
SN: I'm not sure this is a fix to make but you wrote that number is 1% that doesn't seem right as you're actually dividing it by 10 and not by 100. Also to make it more dynamic you should initialise the number as
number = rounds/10; //number is the 10% of the rounds keep in mind
Upvotes: 0