Progressbar aus 2. Thread steuern

Hallo,

ich habe 2 Threads. Im ersten steuere ich einen Progressbar im 2. starte ich ein SQL update.

Ich möchte jetzt, wenn das Update fertig ist, den Task mit dem ProgressBar beenden und den Progressbar auf 100% setzten.
wie kann ich das machen?

  1. Task
 final Task updateProgressBar;
            updateProgressBar = new Task<Void>() {
                @Override
                protected Void call() throws Exception {
                    System.out.println("rowCount: ........... = " + rowCount );
                    double rowCountMal5 = schreiben.WriteToDB.rowCount_fuer_InDBSchreibenProgressBar*5;
                    System.out.println("rowCountMal5: " + rowCountMal5);
                                       for (double i=0; i<=1 ; i+=(1/rowCountMal5)) {
                        updateProgress(i, 1);
                        Thread.sleep(50);
                        System.out.println("In Thread: "  + i);

                    }
                    updateProgress(1,1);
                    System.out.println("Wert ProgressBar..." + testBar.getProgress());
                                    
                    
                    return null;
                }
                
            };

                        testBar.setVisible(true);
                        testBar.progressProperty().bindBidirectional((Property<Number>) updateProgressBar.progressProperty());
            
                       testBarIndicator.setVisible(true);
                       testBarIndicator.progressProperty().bindBidirectional((Property<Number>) updateProgressBar.progressProperty());
  1. Task
final Task taskUpdateSQLSkriptSQLPlus;
            taskUpdateSQLSkriptSQLPlus = new Task<Void>() {
                @Override
                protected Void call() throws Exception {
                    
                   String[] args = null;
                       //success.setText("Daten erfolgreich aktualisiertxxxx!"); 
                    schreiben.UpdateSQLSkriptSQLPlus.main(args);  
                    
                    return null;
                  
                }
            };
     
            
            new Thread(taskUpdateSQLSkriptSQLPlus).start();
            new Thread(updateProgressBar).start();

Ich habe auch probiert in einer 2. Klasse mit ``` Platform.runLater(new Runnable(){
@Override
public void run() {
success.setText(“Daten erfolgreich aktualisiert!”);
// testBarIndicator.setProgress(1.0);

                                testBar.setProgress(1.0);
                                
                            }
                        });```

den Progressbar auf 1.0 zu setzen, aber das funktioniert nicht… der Label wird geändert, aber der Progressbar nicht!

Eigentlich laufen ProgressbarUpdate und DB-Update auf ein und dem selben Thread und die Ausgabe des Zustands der Progressbar auf dem EDT in einem Paint-Event.

verstehe ich leider nicht ganz… wo trage ich dann das “100%” ein damit der StatusBar nach dem SQL Update auf 100% gesetzt wird?

Eigentlich innerhalb von schreiben.UpdateSQLSkriptSQLPlus.main(args)Wenn das nicht möglich ist, solltest du den Progressbar-Update-Thread unmittelbar davor instanzieren und starten und unmittelbar danach falls erforderlich auf 1.0 setzen. Auf dem EDT (also im Prinzip in der “paintComponent()”-Methode der Bar) kannst du dann die Progressbar bei erreichen des Wertes 1.0 wieder verschwinden lassen.

also das RunLater läuft in der schreiben.UpdateSQLSkriptSQLPlus.main(args) ab, aber hier aktuallisiert er mir den ProgressBar nicht.

Wär Hilfreich, wenn du diese Methode mal postest.

In der Main rufe ich executeSQLPlus(); auf


        SimpleDateFormat format =
                new SimpleDateFormat("yyyyMMdd");

        String sqlFile = file.toString();
        try {
            File sqlStatementFile = new File(sqlFile);
            if (!sqlStatementFile.exists()) {

                System.out.println("SQL Skript nicht vorhanden / nicht gefunden");
            }

            ProcessBuilder builder = new ProcessBuilder("cmd", "/c", "sqlplus",
                    "xxxx/xxx@xxxxx.xxx.xx", "@" + sqlStatementFile);
            Process process = builder.start();
            createInputFetcherFor(process.getInputStream());

            try {
                process.waitFor();
                System.out.println("Warten..?");
            } catch (Exception ex) {
                ex.printStackTrace();
            }

       
        } catch (IOException ex) {
            Logger.getLogger(UpdateSQLSkriptSQLPlus.class.getName()).log(Level.SEVERE, null, ex);
        }

        System.out.println("Daten in DB geschrieben (Fertig)!");
      
         
        Platform.runLater(new Runnable(){
                                @Override
                                public void run() {
                                    success.setText("Daten erfolgreich aktualisiert!");
                                  //  testBarIndicator.setProgress(1.0);
                                    testBar.setProgress(1.0);
                                   }
                            });
        
        System.out.println("success.setText wurde auf erfogreich gesetzt!!?");
        
    }
    // gehört zu executeSQLPlus() .....

    private static void createInputFetcherFor(final InputStream inputStream) {
        final ExecutorService executorService = Executors
                .newSingleThreadExecutor();
        executorService.execute(new Runnable() {
            public void run() {
                //Scanner 
                        scanner = new Scanner(inputStream);
                while (scanner.hasNextLine()) {
                    System.out.println(scanner.nextLine());
                }
                scanner.close();
                executorService.shutdown();
            }
        });

    }```

Und in “createInputFetchFor(…)” würde ich zunächst die Anzahl der Statements als Maxwert der PBar ermitteln und anschliessend in der “while”-Schleife diese PBar updaten lassen. Dafür würde diese Methode natürlich eine Instanz dieser PBar benötigen. Eine solche sollte man sich über den Controller oder der View holen, wovon mindestens eines im Model (Klasse UpdateSQLSkriptSQLPlus) bekannt sein sollte.

ok, super danke… werde ich probieren! :slight_smile:

Kannst dir auch gleich mal das hier dazu anschaun: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html

Hi,

ich habe das jetzt folgendermaßen versucht (es wird allerdings der Progressbar viel schneller bis auf 100% upgedated als der Prozess im Hintergrund braucht… wie kann ich das noch synchronieieren?
Ich dachte wenn ich den Count während der while(scanner.hasNextLine()) erhöhe müsste das doch synchron laufen, oder?

        final ExecutorService executorService = Executors
                .newSingleThreadExecutor();
        executorService.execute(new Runnable() {
            public void run() {
                //Scanner 
                        scanner = new Scanner(inputStream);
                        
                while (scanner.hasNextLine()) {
                    System.out.println(scanner.nextLine());
                   count= count+ 0.005;
                    
                    
                    
                                        Platform.runLater(new Runnable(){
                                                    @Override
                                                    public void run() {
                                                       testBar.setProgress(schass);

                                        }
                                                });
                    
                   
                }
                scanner.close();
                executorService.shutdown();
            }
        });

    }```

[QUOTE=garaq]Ich dachte wenn ich den Count während der while(scanner.hasNextLine()) erhöhe müsste das doch synchron laufen, oder?[/QUOTE]Wo synchronisierst du denn den counter mit der Anzahl der Zeilen der Textdatei? So wie ich das sehe zählst du da nur eine beliebige Konstante drauf.
Das Vorgehen ist also wie folgt:

  1. Datei zeilenweise einlesen und die Zeilen in einer Collection speichern.
  2. Inkrementalwert = 1/Anzahl der Zeilen festlegen.
  3. Collection mit den Zeilen abarbeiten und währenddessen die Progressbar mit aufaddierten Inkrementalwerten aktualisieren.

In dem Fall habe ich noch eine “beliebige” Konstanet (hier kommt wenn es funktioniert ein dynamischer (entsprechend der Tabellleneinträge richtiger Wert) hin.
An dem Testbeispiel das ich hier habe müsste der Wert genau ausreichen um am ende der While bei 100% zu sein…
Dem ist aber nicht so, leider, da der Progressbar um ein vielfaches schneller fertig. Aber eigentlich dürfte ja nur bei jedem While durchlauf der Wert erhöht werden und somit sobald keine “NextLine” mehr da ist der (in dem Fall eben mit Konstantem Wert) der Bar bei 100% sein.

Verstehe allerdings nicht warum das nicht so ist…

[QUOTE=garaq]In dem Fall habe ich noch eine “beliebige” Konstanet (hier kommt wenn es funktioniert ein dynamischer (entsprechend der Tabellleneinträge richtiger Wert) hin.
An dem Testbeispiel das ich hier habe müsste der Wert genau ausreichen um am ende der While bei 100% zu sein…[/QUOTE]Das würde ich gerne mal nachrechnen… wieviele Textzeilen hat deine Testdatei? 200 der Konstanten nach zu urteilen. Hat sie Mehr, ist die Progressbar natürlich früher auf 100%.

Stimmt fast, hatte den wert erst auf 0.01 (da 100 Werte in der Tabelle sind) habe nur zum probieren, damit der bar sicher langsamer ist auf 0.005 gestellt.

Könntest du mir evtl. in dem Code oben ausbessern was hier falsch läuft?

Hab’ mal 'ne Demo hochgeladen, die du dir ansehen kannst.

ok, Danke!