Progressbar aktualisieren

Joob

Top Contributor
Ich habe ein Klasse welche einen Download macht.
Ich kann bei dieser Klasse auch einen Returnwert bekommen, wenn ich join anwende.

Wenn ich join nicht anwende bekomme ich auf dem ProgBar den Status,
aber natürlich läuft der Thread dann für sich und der Returnwert ist nicht verwertbar.

Gibt es eine Möglichkeit das join anders zu verwenden
ohne das es den GUI Prozess einfriert oder muss ich das anders machen um
den Status anzuzeigen.

Status wird ja nur bei großen Dateien gebraucht, ich wollte es halt einfach halten
aber ggf. muss ich dann zwei verschieden Methoden schreiben.


Java:
public class GetFile
{
    String              rPaf        = "";
    String              lPaf        = "";
    ProgressBar         pb          = null;
    ProgressIndicator   pi          = null;
    boolean             doneJob     = false;
   
   
    public boolean go(String rPaf, String lPaf, ProgressBar pb, ProgressIndicator pi, boolean headfile)
    {
        this.rPaf   = rPaf;
        this.lPaf   = lPaf;
        this.pb     = pb;
        this.pi     = pi;

        Thread gfcs = new Thread(new gfcs());
        Thread gfhs = new Thread(new gfhs());
       
        if (headfile) { gfhs.start(); }
        else { gfcs.start(); }
       
        // Anzeige nur moeglich wenn join ausgeschaltet ist, also wenn einer nicht null dann kein join
        if ( (pb == null) && (pi == null) )
        {
            try
            {  
                gfcs.join();
                gfhs.join();
            }
            catch (InterruptedException ex)
            {
                Logger.getLogger(GetFile.class.getName()).log(Level.WARNING, ex.getMessage(), ex);
            }
        }
        return doneJob;
    }
   
    private class gfcs implements Runnable
    {    
        @Override
        public void run()
        {
            doneJob = getCFile(rPaf, lPaf, pb, pi);
        }
    }  

    private class gfhs implements Runnable
    {
        @Override
        public void run()
        {
            doneJob = getHFile(rPaf, lPaf, pb, pi);
        }
    }
}
 

KonradN

Super-Moderator
Mitarbeiter
Also ich bin gerade etwas verwirrt und weiss nicht genau, was Du machst.

Generell ist es so:
a) Den UI Thread blockierst Du generell nie! Das dürfte wohl der Grund sein, wieso dann keine Updates der Progressbar kommen.
b) Das Pattern ist doch, dass ein Thread, der irgendwas macht, am Ende dann Anderen ein Event schickt. Also wenn Du am Ende ein Result hast (Ich nehme da einfach einmal die Klasse Result), dann kannst Du da in der Klasse etwas haben wie (nur skizziert und im Forum geschrieben):
Java:
    private class gfhs implements Runnable
    {
        @Override
        public void run()
        {
            Result result = getHFile(rPaf, lPaf, pb, pi);
            triggerResultEvent(result);
        }
       
        private List<Consumer<Result>> resultEventListener = new ArrayList<>();
       
        private void triggerResultEvent(Result result) {
            resultEventListener.forEach(r -> r.accept(result));
        }
       
        public void addResultEventzListener(Consumer<Result> consumer) {
            resultEventListener.add(consumer);
        }
    }

Edit: Observer Pattern wäre hier das generelle Stichwort. Einfach mal nach suchen und anschauen.
 

Joob

Top Contributor
Das muss ich mir morgen mal anschauen und versuchen zu verstehen.

Ich hatte gelesen das ein Runable keinen return geben kann,
deshalb die Klassenvariable und das join.

Erst mal schönen Dank für deine Hilfe.

Bin gerade beim Umbau um keine Zugangsdaten mehr im Client zu haben,
vielleicht erinnerst Du Dich noch an mein Dilema.

Ich melde mich morgen wenn ich mich mit deinem Vorschlag beschäftigt habe.
 

Joob

Top Contributor
Ich hab mir das angesehen und glaube nicht das es mein Problem löst wenn ich es richtig verstanden habe.
Das ist so etwas wie ein Broadcast.

Grundsätzlich müsste ich mal verstehen was beim join passiert, also nicht das gewartet wird bis der Thread fertig ist,
das ist ja das was ich will und was auch gut funktioniert,

was ich meine ist warum wird, während auf das Ende des Threads gewartet wird, der ProgBar nicht aktualisiert.

Im Zusammenhang mit einem einzelnen Download auf dem auch noch gewartet werden muss da die Datei
im Anschluss verwendet wird macht das mit dem join, so wie ich es bisher verwende, nur Sinn wenn ich den Fortschritt nicht anzeigen will.

Das muss ich aber damit der Benutzer eine Rückmeldung bekommt.
Gibt es da eine Möglichkeit.
 

Joob

Top Contributor
Ich weiß das ich das nicht so gut erklären kann, deshalb versuch ich es noch einmal anders.
Was ich möchte ist.

einen sequenzellen Ablauf, als Schritt für Schritt
für einen Download
und den Status des Downloads anzeigen.

also
dosomething();
download (); - Dabei wird der ProgState angezeigt
dosomething with the downloadfile();

Ich hatte ja vorher jsch - ein sftp Tool für Java, die hatten eine Progressmonitorklasse, so was wäre glaube ich für mich das richtige.
Aber wie kann man das machen ?
 

KonradN

Super-Moderator
Mitarbeiter
Das Problem ist, dass die Anwendung Eventgesteuert ist. Stell Dir das einfach wie eine Warteschlange vor, in dem alle Events landen.

Der UI Thread macht also nichts anderes, als Events aus der Warteschlange zu nehmen um diese dann abzuarbeiten.

In dem Moment, wenn Du einen Wert bei einem Control änderst, ändert sich nicht die Anzeige. Statt dessen wird nur in die Warteschlange ein Event gestellt, das besagt: Male die Komponente neu. (Das ist dann meist das sogenannte WM_PAINT Event, das dann an das Control oder Fenster geschrieben wird.

Das ist der Grund, wieso Du langlaufende Dinge nicht im UI Thread machen darfst. Denn dann veränderst Du zwar die Werte und es kommen diese WM_PAINT Events in die Warteschlange. Aber der UI Thread ist beschäftigt und kann daher diese Events nicht abarbeiten.

Daher hast Du das in eigenen Threads gebaut. Das ist soweit richtig. Durch das join wartet der Thread aber darauf, dass der andere Thread fertig wird -> Du blockierst den UI Thread somit wieder. Eine Aktualisierung findet nicht mehr statt.

Daher kannst Du nicht darauf warten, dass ein Thread fertig wird. Was Du statt dessen machen kannst ist aber, dass Du informiert wird, wenn der Thread fertig ist. Und das ist dann z.B. über ein Observer Pattern lösbar. Das ist auch kein Broadcast sondern lediglich eine Variante, damit man aufzurufende Methoden hinterlegen kann, die dann am Ende ausgeführt werden. Wichtig ist: Das läuft dann erst einmal auf dem jeweiligen Thread - also ggf. willst Du das direkt im UI Thread haben. Das ist also nichts anderes als diese Events, die Du bei der UI Programmierung schon kennst.

Statt dies selbst zu bauen kann man auch fertige Klassen verwenden. Die meisten UI Frameworks haben eine Klasse, die genau dies bietet: Ein Thread, der einen Progress reporten kann und am Ende auch Bescheid gibt. Bei Swing wäre es der SwingWorker und bei JavaFX der Task.

ProgressMonitor brauchst Du diesbezüglich nicht, denn ich habe Dich so verstanden, dass die Anzeige vom Progress ja bereits klappt - wenn Du also die join Aufrufe auf den Threads weg nimmst, dann funktioniert die Verfolgung vom Progress aber du bekommst halt nicht mit, wann die Threads fertig sind um dann irgendwelche Werte auszulesen.
 

Joob

Top Contributor
Super Erklärung, ich bin dir echt dankbar.

Es ist schon spät, ich schau mir das morgen noch mal an um es wirklich komplett nachvollzuziehen.
Das was ich bisher verstanden habe ist, das man dafür ein Framework braucht.
Aber dann muss das doch möglich sein.

Muss man darüber noch einen Rahmen aus Klassen bauen. Weißt du wie die das machen ?
 

KonradN

Super-Moderator
Mitarbeiter
Du brauchst dazu kein Framework. Du hast alles bereits vorliegen. Und da muss man auch nicht groß weitere Klassen bauen.

Es reicht aus, deine beiden Klassen etwas zu erweitern und das dann zu nutzen.

Evtl. kannst du etwas erläutern, wie du die Methode go aufrufst / du diese Klasse nutzt. Dann kann man Dir evtl. direkt im Code zeigen, wie dies genau funktionieren würde. Wenn du es siehst, dann wirst du es vermutlich verstehen, was ich meine.
 

Joob

Top Contributor
Das ist genau mein Problem.
ENTWEDER
ich lasse join weg, dann wird der UI Thread weiter ausgeführt und der Progress angezeigt. Dann und das ist hier das Problem bekomme ich kein brauchbares Return, noch kann ich im sequenziellen Ablauf im nächsten Schritt etwas mit der Datei anfangen weil ja der Thread noch mit dem Download beschäftigt ist,
ODER
ich verwende join, dann wird der Progress nicht angezeigt aber ich bekomme einen Return und weis das bzw. ob die Datei heruntergeladen ist.

Ich habe hier mal einen Ausschnitt, das war mein erster Versuch die Klasse im Projekt einzusetzen und einen Progress anzuzeigen.
Zuvor habe ich in anderen Zusammenhängen join genutzt weil es dort wegen der Dateigröße keine Notwendigkeit zur Anzeige eines Fortschritts gab.

Folgendes habe ich mir bei der Klasse GetFile gedacht.

Wenig Code im eigentlichen Prozess.
Kein static wegen der Klassenvariablen der GetFile-Klasse.
Keine Klasse nur mit Konstructor da ich den Returnwert brauche.

INFO: rPaf = Remote Pfad and File
lPaf = Local Pfad and File

In diesem Zusammenhang ist eds eine Datenklasse die durch einen Prozess führt der diverse Downloads und Importvorgängen in einer Datenbank durchführt.

Java:
                    GetFile gf = new GetFile();
               
                    if(gf.go("1" + eds.getSkillIdInBase() + ".zip",
                                                    eds.getDirZip() + fs + eds.getTmpZipFileName(),
                                                    pmc, null, true))
                    {

Dieser Tei läuft innerhalb eines Services, und wie ich ja sagte ist es ein Download via http welcher über ein PHP Script ausgeführt wird. Dabei sind die Abläufe voneinander und Ihrem Erfolg abhängig. Deshalb die if Abfrage.

Ich bin bei meiner Suche auf concurent.ExecuterService gestoßen, meinst du das ich damit eine Lösung finde ?
 
Zuletzt bearbeitet:

KonradN

Super-Moderator
Mitarbeiter
Das Problem habe ich somit richtig verstanden. Und du zeigst schlicht immer noch zu wenig.

Du hast ja ein Programm mit einer UI. Und so ein Programm ist Event gesteuert. Somit hast Du lediglich irgend etwas, dass den Start des Downloads anstößt.
Dieser läuft dann in einem anderen Thread und aktualisiert z.B. eine ProgressBar. (Wobei man UI und Funktionalität entkoppeln sollte, aber das ist ein anderes Thema).
Denn der Thread fertig ist, dann sollte er erneut ein Event auslösen - auf dieses Event reagierst Du dann erneut und machst irgendwas. Z.B. die Auswertung des Ergebnisses.

Oder Du packst das auch noch in den Thread, der den Download macht, aber das dürfte dann gegen jede saubere Aufteilung von Code gehen.
 

Joob

Top Contributor
Ich bin da zu sehr Prozedural unterwegs wie du siehst.
Das dürfte vieleicht der Kern meines Problems sein.

Deine Aussage:
Denn der Thread fertig ist, dann sollte er erneut ein Event auslösen

Da hab ich keine wirkliche Vorstellung:
Wie soll das gehen,
ich müsste dann der GetFileKlasse noch mitteilen welche andere Klasse diese nach Erfolg auslösen soll.

Also
Java:
private class gfcs implements Runnable
    {     
        @Override
        public void run()
        {
            doneJob = getCFile(rPaf, lPaf, pb, pi);
            [I][B]hier müsste eine weitere Klasse ausgeführt werden die den gerade benötigten Ablauf weiter führt[/B][/I]
            
        }
    }

Das könnte dann aber sehr unübersichtlich werden, da der Prozess groß ist und immer weiter verschachtelt wird.

Ich fände es übersichtlicher wenn ich statt des join eine anderen Weg finden würde in dem das Return erst nach
dem Beenden des Threads ausgelöst wird ohne den UI Thread davon zu berühren.

Ich habe mich noch nicht wirklich mit concurrent beschäftigt, aber wenn ich dort bekommt man doch eine Meldung
wenn ein Thread fertig ist, oder.
 

Joob

Top Contributor
Ich bin da zu sehr Prozedural unterwegs wie du siehst.
Das dürfte vieleicht der Kern meines Problems sein.

Deine Aussage:


Da hab ich keine wirkliche Vorstellung:
Wie soll das gehen,
ich müsste dann der GetFileKlasse noch mitteilen welche andere Klasse diese nach Erfolg auslösen soll.

Also
Java:
private class gfcs implements Runnable
    {    
        @Override
        public void run()
        {
            doneJob = getCFile(rPaf, lPaf, pb, pi);
            [I][B]hier müsste eine weitere Klasse ausgeführt werden die den gerade benötigten Ablauf weiter führt[/B][/I]
           
        }
    }

Das könnte dann aber sehr unübersichtlich werden, da der Prozess groß ist und immer weiter verschachtelt wird.

Ich fände es übersichtlicher wenn ich statt des join eine anderen Weg finden würde in dem das Return erst nach
dem Beenden des Threads ausgelöst wird ohne den UI Thread davon zu berühren.

Ich habe mich noch nicht wirklich mit concurrent beschäftigt, aber dort bekommt man doch eine Meldung
wenn ein Thread fertig ist, oder.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
C ProgressBar updaten Java Basics - Anfänger-Themen 4
felix92 MP3-Player ProgressBar Java Basics - Anfänger-Themen 29
Y Progressbar beim Mysqldump Java Basics - Anfänger-Themen 3
T Progressbar füllen? Java Basics - Anfänger-Themen 3
X BufferedWriter Dauer in ProgressBar ausgeben? Java Basics - Anfänger-Themen 2
1 Erste Schritte Progressbar füllen ?? Java Basics - Anfänger-Themen 5
C ProgressBar funktioniert nicht Java Basics - Anfänger-Themen 18
K Erste Schritte Progressbar geht nicht Java Basics - Anfänger-Themen 5
P Progressbar auf der Console Java Basics - Anfänger-Themen 12
P Aktualisierungsproblem mit Progressbar Java Basics - Anfänger-Themen 5
L ProgressBar neu positionieren Java Basics - Anfänger-Themen 12
M jLabel aktuallisieren bzw Progressbar für Zeitanzeige Java Basics - Anfänger-Themen 5
M FTP Upload Applet - ProgressBar Java Basics - Anfänger-Themen 5
C Auf ProgressBar von zwei verschiedenen .class Dateien zugrei Java Basics - Anfänger-Themen 2
P Label nicht bei Progressbar zu sehen Java Basics - Anfänger-Themen 8
G ProgressBar ist verdeckt Java Basics - Anfänger-Themen 2
E ProgressBar für Kopieraktion Java Basics - Anfänger-Themen 21
H Wie hier die Progressbar benutzen? Java Basics - Anfänger-Themen 8
B Problem mit ProgressBar Java Basics - Anfänger-Themen 4
C Farbe von ProgressBar ändern Java Basics - Anfänger-Themen 3
G Progressbar aktualisiert nicht Java Basics - Anfänger-Themen 3
C Timer aktualisieren Java Basics - Anfänger-Themen 5
TimoN11 Array mit unterschiedlichen längen aktualisieren, dann als Methodenwert einsetzen Java Basics - Anfänger-Themen 1
J Java FX - Label aktualisieren Java Basics - Anfänger-Themen 1
J Aktuelle Zeit in einer JavaFX Anwendung aktualisieren lassen Java Basics - Anfänger-Themen 4
M Probleme beim aktualisieren eines JPanels Java Basics - Anfänger-Themen 7
A Input/Output System.out Ausgabe aktualisieren, ohne Konsole vollzuspamen Java Basics - Anfänger-Themen 2
P WindowBuilder aktualisieren Java Basics - Anfänger-Themen 0
L Threads Laufbild Erzeugen Problem mit Aktualisieren des JPanels Java Basics - Anfänger-Themen 2
F Problem bei ImageIcon aktualisieren Java Basics - Anfänger-Themen 5
MrSnake Tabelleninhalt aktualisieren Java Basics - Anfänger-Themen 12
R Programm aktualisieren/refreshen Java Basics - Anfänger-Themen 7
2 Uhrzeit und Datum aktualisieren Java Basics - Anfänger-Themen 12
M Methoden Methoden aktualisieren Java Basics - Anfänger-Themen 2
M Liste mit repaint aktualisieren Java Basics - Anfänger-Themen 1
B Erste Schritte Anzeige von Graphics Objekten einzeln aktualisieren Java Basics - Anfänger-Themen 1
G Input/Output Webseite Cache-Control: max-age=3 Öfters Aktualisieren? Java Basics - Anfänger-Themen 1
J Bilder in Labels aktualisieren Java Basics - Anfänger-Themen 2
G Seite aktualisieren Java Basics - Anfänger-Themen 1
O JList aktualisieren während Dateieinlesung Java Basics - Anfänger-Themen 4
W Erste Schritte Timer soll jede Sekunde Label aktualisieren Java Basics - Anfänger-Themen 5
S Erste Schritte Gui aktualisieren Java Basics - Anfänger-Themen 5
M Variable aus einer anderen Klasse aktualisieren Java Basics - Anfänger-Themen 2
V JFrame aktualisieren Java Basics - Anfänger-Themen 6
M Tabelle aktualisieren (mal wieder) Java Basics - Anfänger-Themen 10
M Erste Schritte Tabelle aktualisieren (mal wieder) Java Basics - Anfänger-Themen 7
D JTable aktualisieren Java Basics - Anfänger-Themen 2
J Variablen Aktualisieren von Instanzvariablen Java Basics - Anfänger-Themen 14
J repaint() geht gar nicht; GUI aktualisieren Java Basics - Anfänger-Themen 10
Q Zeitanzeige aktualisieren Java Basics - Anfänger-Themen 7
J Jtable änderung soll graphics aktualisieren Java Basics - Anfänger-Themen 4
R Threads GUI über Hintergrund-Thread aktualisieren Java Basics - Anfänger-Themen 6
F GUI JTextField aktualisieren Java Basics - Anfänger-Themen 3
L Zeit sekündlich aktualisieren Java Basics - Anfänger-Themen 7
J JLabels in Panel Aktualisieren Java Basics - Anfänger-Themen 5
E JList GUI aktualisieren? Java Basics - Anfänger-Themen 3
L Client aktualisieren Java Basics - Anfänger-Themen 6
Ollek ArrayList nach Datenbankeintrag aktualisieren Java Basics - Anfänger-Themen 4
U jTable aktualisieren Java Basics - Anfänger-Themen 5
B PacMan: Panel aktualisieren Java Basics - Anfänger-Themen 2
Dit_ Aktualisieren von mehreren Views Java Basics - Anfänger-Themen 2
J JList Inhalt nach JButton Klick aktualisieren Java Basics - Anfänger-Themen 8
J JTable aktualisieren wenn TableModel sich ändert Java Basics - Anfänger-Themen 6
F contentPane aktualisieren Java Basics - Anfänger-Themen 2
L JList Aktualisieren funktioniert nur Zufällig Java Basics - Anfänger-Themen 3
B JApplet aktualisieren Java Basics - Anfänger-Themen 2
N Aktualisieren JTable Java Basics - Anfänger-Themen 2
T JList aktualisieren Java Basics - Anfänger-Themen 12
T GUI aktualisieren Java Basics - Anfänger-Themen 6
C GUI aktualisieren: repaint, validate, Fenstergröße ändern bringt nichts Java Basics - Anfänger-Themen 13
C jframe bzw. jpanel aktualisieren Java Basics - Anfänger-Themen 13
E Textfeld aktualisieren Java Basics - Anfänger-Themen 3
P Textarea aktualisieren, Referenz fehlt Java Basics - Anfänger-Themen 4
G fenster aktualisieren Java Basics - Anfänger-Themen 2
Antoras Applet aktualisieren Java Basics - Anfänger-Themen 2
M Ausgabe aktualisieren/ Stoppuhr Java Basics - Anfänger-Themen 4
S Jpanel aktualisieren Java Basics - Anfänger-Themen 9
S JTable aktualisieren (nach Datenbank updade) Java Basics - Anfänger-Themen 14
S JTree aktualisieren Java Basics - Anfänger-Themen 4
M JTree aktualisieren Java Basics - Anfänger-Themen 3
K Datum mittels Thread aktualisieren Java Basics - Anfänger-Themen 6
G Bild aktualisieren Problem! Java Basics - Anfänger-Themen 2
G Liste in mehreren unabhängigen Frames aktualisieren. Java Basics - Anfänger-Themen 6
H Textarea aktualisieren Java Basics - Anfänger-Themen 2
V Menüeinträge und ähnliches aktualisieren (aus properties) Java Basics - Anfänger-Themen 10
M Aktualisieren eines JTables funktioniert nicht Java Basics - Anfänger-Themen 6
K Chart zur Laufzeit erstellen und aktualisieren Java Basics - Anfänger-Themen 2
M jTable aktualisieren Java Basics - Anfänger-Themen 5
H JTable richtig aktualisieren Java Basics - Anfänger-Themen 4
J schleife unterbrechen JTextArea aktualisieren Java Basics - Anfänger-Themen 8
W Kurse übers Internet aktualisieren Java Basics - Anfänger-Themen 6
G mehrere Frames nacheinander aktualisieren Java Basics - Anfänger-Themen 2
B JTable Werte aktualisieren Java Basics - Anfänger-Themen 2
G JList - aktualisieren Java Basics - Anfänger-Themen 6
S JTree aktualisieren bzw. komplett neu aufbauen Java Basics - Anfänger-Themen 6
F Aktualisieren einer einzelnen Zelle in JTable Java Basics - Anfänger-Themen 2
F Gebasteltet Fortschrittsanzeige: Aktualisieren Labels? Java Basics - Anfänger-Themen 4
F Aktualisieren einer Liste von einem entfernten Objekt aus. Java Basics - Anfänger-Themen 11
M JList Datenstring erweitern und JList aktualisieren Java Basics - Anfänger-Themen 5
D Applet im IE aktualisieren Java Basics - Anfänger-Themen 6

Ähnliche Java Themen

Neue Themen


Oben