Progressbar auf der Console

  • Themenstarter Themenstarter Progressbar
  • Beginndatum Beginndatum
P

Progressbar

Gast
Hi,

ich habe eine Methode mit dem Rückgabewert
Code:
void
und ihre Berechnung im Durchschnitt ca. 15 Sekunden dauert. Aufgerufen wird sie in der
Code:
main
-Methode. Hierfür möchte ich eine Art Progressbar auf der Console ausgeben. Dafür habe ich folgende Methode, von der ich vermute, dass sie nicht viel bringen wird:

Java:
public static void printProgBar(int percent) {
		StringBuilder bar = new StringBuilder("[");

		for (int i = 0; i < 50; i++) {
			if (i < (percent / 2)) {
				bar.append("=");
			} else if (i == (percent / 2)) {
				bar.append(">");
			} else {
				bar.append(" ");
			}
		}

		bar.append("]   " + percent + "%     ");
		System.out.print("\r" + bar.toString());
	}

Rudimentärer Auszug aus der Main.java:

Java:
public class Main {

	public static void main(String[] args) {

		method.doSomething(input); //Das ist die Methode mit Rückgabewert void, die "lange" dauert
		
		//...
	}

Frage: Kann ich diese Methode doch irgendwie hinbiegen, dass ich eine Art Progressbar hinbekomme? Oder gibt es eine andere Möglichkeit, wie ich das deichseln könnte?

Danke euch.
 
Ja gut, du hast ja dein Problem eigentlich auch nur umrissen. Woran es nun scheitert, habe ich nicht deinem Posting entnehmen können.

Dann rate ich mal weiter:
Um die Berechnung von einer Konsolenausgabe abzukoppeln, musst du mit Threads arbeiten.
Hilft dir das?
 
Gut, das stimmt natürlich, wofür ich mich entschuldige.

Das Problem an der Sache ist folgendes. Die Methode
Code:
doSomething(Object o);
ist eine schon vorgefertigte Methode, die ich nicht verändern, sondern nur aufrufen kann. Sie dauert eben ziemlich lange (ca. 15 Sekunden) und ich hätte gerne für die Zeitspanne der Methodenausführungsdauer (sorry, weiß nicht, wie ich es besser formulieren soll) eine Art ProgressBar gehabt.

Die Methode

Java:
public static void printProgBar(int percent) {
        StringBuilder bar = new StringBuilder("[");
 
        for (int i = 0; i < 50; i++) {
            if (i < (percent / 2)) {
                bar.append("=");
            } else if (i == (percent / 2)) {
                bar.append(">");
            } else {
                bar.append(" ");
            }
        }
 
        bar.append("]   " + percent + "%     ");
        System.out.print("\r" + bar.toString());
    }

benötigt ja eine Art Prozentindikator, die ich im Voraus ja logischerweise nicht weiß bzw. ich bräuchte eine Art "Timer" mit der ich einen int-Wert ermittel, sodass ich die
Code:
printProgBar(int percent)
verwenden kann.

Threads? Hm.. Wie würde mir das konkret helfen?

Danke schonmal!
 
Wenn du nicht bestimmen kannst, wie lange die Methode brauchst, kannst du es auch nicht anzeigen.
Alternative wäre eine Anzeige die unabhängig von der Dauer ist (z.B. die inzwischen beliebte Kreis-Animation)

Der Thread hilft dir insofern als dass du deine animation ablaufen lassen kannst, während die methode läuft. Das würde sonst nicht gehen.
 
Kreis-Animation? Wie sieht sowas denn z.B. aus? Eventuell könnte ich ja das wirklich verwenden.
 
Threads? Hm.. Wie würde mir das konkret helfen?

Da gibt es jede Menge Ratschläge. Google mal unter WorkerThread oder SwingWorker. Letzteres ist halt für Swing-Applikationen zugeschnitten, weil in Swing langlaufende Berechnungen NICHT den Event-Dispatch-Thread blockieren sollten, damit die GUI noch bedienbar bleibt während der Thread noch läuft-

Jedenfalls solltest Du zwei Threads A+B haben. Thread-A "berechnet" Deine Eingabe, also doSomething(). Der Thread-B wartet darauf, dass ihm "mitgeteilt" wird, dass Thread-A ein Stückchen weitergekommen ist. Diesen Fortschritt "malt" er als Progressbar auf die Konsole.

Irgenwie muss aber Deine doSomething()-Methode dahingehend geändert werden, dass sie mitteilt wie weit die Berechnung gekommen ist. Sonst bleibt noch so etwas wie in Swing ein "Indeterminate ProgressBar", wenn man nur sehen kann, dass es noch läuft man aber nicht weiss, wie lange noch. Das ist mit einer Kreis-Animation möglich, weil es dreht sich was ;-). Das scheint mir für eine Konsole eigentlich ganz gut zu passen. Wenn da / | \ - schnell hintereinander an der gleichen Stelle gezeichnet werden sieht es aus wie ein drehender Propeller, oder?
 
Zuletzt bearbeitet:
Wie gefällt Dir denn diese "Animation"

Java:
		int i = 0;
		while (true) {
			System.out.print( "-\\|/".charAt(i)+"\r");			
			i = ++i % 4;
			Thread.sleep(300);
		}
 
Die Animation ist schon in Ordnung.

Ich befürchte aber, dass es für mein spezielles Problem wohl keine Lösung gibt / geben kann. Ich weiß im Voraus ja nicht, wie lange die Methode für die Bearbeitung braucht. Außerdem hat sie den Rückgabewert void, mit dem ich ja schon gleich gar nichts anfangen kann. Bearbeiten kann ich die Methode auch nicht, da sie aus einem Framework stammt.

Ich werd dann wohl ein einfaches "Bitte warten Sie auf den Abschluss des Jobs!" oder so ausgeben lassen.

Schade eigentlich.
 
Hallo
Wie wäre diese Idee: doSomething() setzt den Fortschritt regelmäßig in eine Instanzvariable. Deren Wert kannst Du dann ausgeben. Die Ausgabe sollte (wie schon von anderen gesagt) in einem separaten Thread laufen. Ich hoffe, das hilft Dir. (wenn ja: danke-Button🙂)
 
Ich meine, das alles geliefert wurde, damit es funzt.

Hier mein kleines Beispiel:
Java:
public class A {
	public A() {
	}

	public static void main(String[] args) throws InterruptedException {
		Thread worker = new Worker();
		worker.start();
		int i = 0;
		while (worker.isAlive()) {
			System.out.print( "-\\|/".charAt(i)+"\r");			
			i = ++i % 4;
			Thread.sleep(300);
		}
	}
}

class Worker extends Thread {
	@Override
	public void run() {
		try {
			Thread.sleep(15000);
			System.out.println("Berechnung fertig.");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
}
 

Zurück
Oben