progressbar
progressbar copied to clipboard
Multiple progress bars end up on a single line under osx with 0.9.4
I am creating multiple progress bars, each one as a task in a thread pool (up to 300). When. the thread pool is running more than one task at once, the progress bars all end up on the same line.
I checked an Terminal.cursorMovementSupported
is set to true.
The code looks like this:
executorService.submit(() -> {
try (CliProgressMonitor progressMonitor = new CliProgressMonitor(message, terminalWidth.get())) {
// do long running task
}
});
private static final class CliProgressMonitor extends BatchingProgressMonitor implements AutoCloseable {
private final ProgressBar progressBar;
public CliProgressMonitor(String message, int terminalWidth) {
this.progressBar = new ProgressBarBuilder()
.setStyle(ProgressBarStyle.UNICODE_BLOCK)
.setTaskName(message)
.setMaxRenderedLength(terminalWidth)
.hideETA()
.build();
}
...
}
Is there anything wrong with the approach, should the closing of the progressbar be changed or sth?
Thanks for your help!
Which environment are you running in? e.g. Linux terminal, or Windows WSL, or in a Docker container?
Under osx, I tried with iterm2 as well as wezTerm. This is what it looks like..
So, every "Fetching repo..." is an own progressbar (that is the message), and if you look closely, the last line flips between the 10 concurrent running progresses and only creates a newline once the progress is finished.
I am creating multiple progress bars, each one as a task in a thread pool (up to 300). When. the thread pool is running more than one task at once, the progress bars all end up on the same line.
I checked an
Terminal.cursorMovementSupported
is set to true.The code looks like this:
executorService.submit(() -> { try (CliProgressMonitor progressMonitor = new CliProgressMonitor(message, terminalWidth.get())) { // do long running task } }); private static final class CliProgressMonitor extends BatchingProgressMonitor implements AutoCloseable { private final ProgressBar progressBar; public CliProgressMonitor(String message, int terminalWidth) { this.progressBar = new ProgressBarBuilder() .setStyle(ProgressBarStyle.UNICODE_BLOCK) .setTaskName(message) .setMaxRenderedLength(terminalWidth) .hideETA() .build(); } ... }
Is there anything wrong with the approach, should the closing of the progressbar be changed or sth?
Thanks for your help!
maybe you can try this
/**
* 支持在控制台打印多行进度条
*
* @author LCTR
* @date 2023-05-07
*/
public class ConsoleMultiProgressBarConsumer
extends ConsoleProgressBarConsumer {
final int index;
final PrintStream out;
public ConsoleMultiProgressBarConsumer(PrintStream out,
int index) {
super(out);
this.out = out;
this.index = index;
}
public ConsoleMultiProgressBarConsumer(PrintStream out,
int maxRenderedLength,
int index) {
super(out,
maxRenderedLength);
this.out = out;
this.index = index;
}
@Override
public void accept(String str) {
out.print(StringExtension.newString("\r\n",
index));
out.print(matcher.appendTail(sb));
//super.accept(str);
out.print(StringExtension.newString("\033[F",
index));
}
}
new ProgressBarBuilder()
.setTaskName("#01"))
.setInitialMax(100)
.setConsumer(new ConsoleMultiProgressBarConsumer(new PrintStream(new FileOutputStream(FileDescriptor.out)),
1))
.hideEta()
.setUpdateIntervalMillis(100)
.build();
new ProgressBarBuilder()
.setTaskName("#02"))
.setInitialMax(100)
.setConsumer(new ConsoleMultiProgressBarConsumer(new PrintStream(new FileOutputStream(FileDescriptor.out)),
2))
.hideEta()
.setUpdateIntervalMillis(100)
.build();
new ProgressBarBuilder()
.setTaskName("#03"))
.setInitialMax(100)
.setConsumer(new ConsoleMultiProgressBarConsumer(new PrintStream(new FileOutputStream(FileDescriptor.out)),
3))
.hideEta()
.setUpdateIntervalMillis(100)
.build();
I am creating multiple progress bars, each one as a task in a thread pool (up to 300). When. the thread pool is running more than one task at once, the progress bars all end up on the same line. I checked an
Terminal.cursorMovementSupported
is set to true. The code looks like this:executorService.submit(() -> { try (CliProgressMonitor progressMonitor = new CliProgressMonitor(message, terminalWidth.get())) { // do long running task } }); private static final class CliProgressMonitor extends BatchingProgressMonitor implements AutoCloseable { private final ProgressBar progressBar; public CliProgressMonitor(String message, int terminalWidth) { this.progressBar = new ProgressBarBuilder() .setStyle(ProgressBarStyle.UNICODE_BLOCK) .setTaskName(message) .setMaxRenderedLength(terminalWidth) .hideETA() .build(); } ... }
Is there anything wrong with the approach, should the closing of the progressbar be changed or sth? Thanks for your help!
maybe you can try this
/** * 支持在控制台打印多行进度条 * * @author LCTR * @date 2023-05-07 */ public class ConsoleMultiProgressBarConsumer extends ConsoleProgressBarConsumer { final int index; final PrintStream out; public ConsoleMultiProgressBarConsumer(PrintStream out, int index) { super(out); this.out = out; this.index = index; } public ConsoleMultiProgressBarConsumer(PrintStream out, int maxRenderedLength, int index) { super(out, maxRenderedLength); this.out = out; this.index = index; } @Override public void accept(String str) { out.print(StringExtension.newString("\r\n", index)); out.print(matcher.appendTail(sb)); //super.accept(str); out.print(StringExtension.newString("\033[F", index)); } }
new ProgressBarBuilder() .setTaskName("#01")) .setInitialMax(100) .setConsumer(new ConsoleMultiProgressBarConsumer(new PrintStream(new FileOutputStream(FileDescriptor.out)), 1)) .hideEta() .setUpdateIntervalMillis(100) .build(); new ProgressBarBuilder() .setTaskName("#02")) .setInitialMax(100) .setConsumer(new ConsoleMultiProgressBarConsumer(new PrintStream(new FileOutputStream(FileDescriptor.out)), 2)) .hideEta() .setUpdateIntervalMillis(100) .build(); new ProgressBarBuilder() .setTaskName("#03")) .setInitialMax(100) .setConsumer(new ConsoleMultiProgressBarConsumer(new PrintStream(new FileOutputStream(FileDescriptor.out)), 3)) .hideEta() .setUpdateIntervalMillis(100) .build();
i dont really understand this, where are the matcher
and sb
in the accept method coming from?
/**
* @author Cool_Loong
*/
public class ConsoleMultiProgressBarConsumer extends ConsoleProgressBarConsumer {
final PrintStream out;
final boolean first;
public ConsoleMultiProgressBarConsumer(PrintStream out, boolean isFirst) {
super(out);
this.out = out;
this.first = isFirst;
}
public ConsoleMultiProgressBarConsumer(PrintStream out, int maxRenderedLength, boolean isFirst) {
super(out, maxRenderedLength);
this.out = out;
this.first = isFirst;
}
@Override
public void accept(String str) {
if (first) {
out.print('\n');
out.print("-".repeat(this.getMaxRenderedLength()));
}
out.print("\r\n");
super.accept(str);
}
}
FIRST = new AtomicBoolean(true);
ProgressBar pb = progressBarBuilder.setTaskName("region " + srcRegion.getRegionX() + "," + srcRegion.getRegionZ())
.setInitialMax(1024)
.setStyle(ProgressBarStyle.ASCII)
.setConsumer(new ConsoleMultiProgressBarConsumer(System.out, FIRST.getAndSet(false)))
.build()
Displaying multiple lines by a “line feed” character.
I am creating multiple progress bars, each one as a task in a thread pool (up to 300). When. the thread pool is running more than one task at once, the progress bars all end up on the same line. I checked an
Terminal.cursorMovementSupported
is set to true. The code looks like this:executorService.submit(() -> { try (CliProgressMonitor progressMonitor = new CliProgressMonitor(message, terminalWidth.get())) { // do long running task } }); private static final class CliProgressMonitor extends BatchingProgressMonitor implements AutoCloseable { private final ProgressBar progressBar; public CliProgressMonitor(String message, int terminalWidth) { this.progressBar = new ProgressBarBuilder() .setStyle(ProgressBarStyle.UNICODE_BLOCK) .setTaskName(message) .setMaxRenderedLength(terminalWidth) .hideETA() .build(); } ... }
Is there anything wrong with the approach, should the closing of the progressbar be changed or sth? Thanks for your help!
maybe you can try this
/** * 支持在控制台打印多行进度条 * * @author LCTR * @date 2023-05-07 */ public class ConsoleMultiProgressBarConsumer extends ConsoleProgressBarConsumer { final int index; final PrintStream out; public ConsoleMultiProgressBarConsumer(PrintStream out, int index) { super(out); this.out = out; this.index = index; } public ConsoleMultiProgressBarConsumer(PrintStream out, int maxRenderedLength, int index) { super(out, maxRenderedLength); this.out = out; this.index = index; } @Override public void accept(String str) { out.print(StringExtension.newString("\r\n", index)); out.print(matcher.appendTail(sb)); //super.accept(str); out.print(StringExtension.newString("\033[F", index)); } }
new ProgressBarBuilder() .setTaskName("#01")) .setInitialMax(100) .setConsumer(new ConsoleMultiProgressBarConsumer(new PrintStream(new FileOutputStream(FileDescriptor.out)), 1)) .hideEta() .setUpdateIntervalMillis(100) .build(); new ProgressBarBuilder() .setTaskName("#02")) .setInitialMax(100) .setConsumer(new ConsoleMultiProgressBarConsumer(new PrintStream(new FileOutputStream(FileDescriptor.out)), 2)) .hideEta() .setUpdateIntervalMillis(100) .build(); new ProgressBarBuilder() .setTaskName("#03")) .setInitialMax(100) .setConsumer(new ConsoleMultiProgressBarConsumer(new PrintStream(new FileOutputStream(FileDescriptor.out)), 3)) .hideEta() .setUpdateIntervalMillis(100) .build();
i dont really understand this, where are the
matcher
andsb
in the accept method coming from?
oh!that's my fault,I have omitted some irrelevant code,The correct content is this
out.print(str);