JavaFX Im Controller die ProgressBar mit Task updaten

Ingerten

Bekanntes Mitglied
Hallo Männers,

ich beschäftige mich noch nicht so lange mit JavaFX und ich bin da jetzt wieder über eine Sache gestolpert, wo ich mal Hilfe brauche.

Ich möchte eine ProgressBar Laden lassen, wenn ich es mit einem Button starte, dann klappt es, wenn ich es aber in der "initialize-Methode" starten will, klappt es nicht.

Das verstehe ich nicht.

Stage
Java:
import java.io.IOException;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;


public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
                      
            try {
               
                Parent     root = FXMLLoader.load(getClass().getResource("MeinFXML.fxml"));
                Scene scene = new Scene(root);
   
                primaryStage.setTitle("mein Feinster");
                primaryStage.setScene(scene);
                primaryStage.show();
               
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    }


    public static void main(String[] args) {
        launch(args);
    }

}

FXML
Java:
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="316.0" prefWidth="362.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Controller">
  <children>
  <VBox alignment="CENTER" prefHeight="200.0" prefWidth="100.0" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0">
  <children>
  <ProgressBar fx:id="meineProzessBar" prefWidth="200.0" progress="0.0" />
  <Label fx:id="label" text="Label" />
  <Button fx:id="startButton" mnemonicParsing="false" onAction="#actionStart" text="Start">
  <font>
  <Font size="20.0" />
  </font>
  <VBox.margin>
  <Insets top="10.0" />
  </VBox.margin>
  </Button>
  </children>
  </VBox>
  </children>
</AnchorPane>

Controller
Java:
import java.net.URL;
import java.util.ResourceBundle;

import javafx.application.Platform;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;

public class Controller {

    private Task copyWorker;

    @FXML private Button startButton;
    @FXML private ProgressBar meineProzessBar;
    @FXML private Label label;


    @FXML void actionStart(ActionEvent event) {

        copyWorker = createWorker();

        meineProzessBar.progressProperty().unbind();
        meineProzessBar.progressProperty().bind(copyWorker.progressProperty());
        label.textProperty().bind(copyWorker.messageProperty());

        new Thread(copyWorker).start();
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public void initialize(URL location, ResourceBundle resources) {
       
          Platform.runLater(() -> {
                copyWorker = createWorker();

                meineProzessBar.progressProperty().unbind();
                meineProzessBar.progressProperty().bind(copyWorker.progressProperty());
                label.textProperty().bind(copyWorker.messageProperty());

                new Thread(copyWorker).start();
        
          });
       
    }

    public Task createWorker() {
        return new Task() {
            @Override
            protected Object call() throws Exception {
                for (int i = 0; i < 10; i++) {
                    Thread.sleep(2000);
                    updateMessage(i + "");
                    updateProgress(i + 1, 10);

                    System.out.println(meineProzessBar.getProgress());
                }
                return true;
            }
        };
    }

}
 
Ach, jetzt habe ich den Fehler gefunden, ich habe das "implements Initializable" vergessen, dann klappt es auch.

Aber jetzt komme ich zu meinem eigentlichen Problem, ich will in einem Ordner PDF-Dateien zählen und den Status mit der ProgressBar anzeigen lassen.

aber die ProgressBar wird nicht aktualisiert.

Java:
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ResourceBundle;

import application.Main;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;

public class Controller implements Initializable{

    private Task copyWorker;
    private int countPDF;

    @FXML private Button startButton;
    @FXML private ProgressBar meineProzessBar;
    @FXML private Label label;


    @FXML void actionStart(ActionEvent event) {

        copyWorker = createWorker(PfadErmitteln("A01"));

        meineProzessBar.progressProperty().unbind();
        meineProzessBar.progressProperty().bind(copyWorker.progressProperty());
        label.textProperty().bind(copyWorker.messageProperty());

        new Thread(copyWorker).start();
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public void initialize(URL location, ResourceBundle resources) {
       
          Platform.runLater(() -> {
                copyWorker = createWorker(PfadErmitteln("A01"));

                meineProzessBar.progressProperty().unbind();
                meineProzessBar.progressProperty().bind(copyWorker.progressProperty());
                label.textProperty().bind(copyWorker.messageProperty());

                new Thread(copyWorker).start();
        
          });
       
    }

    public Task createWorker(File fileRoot) {
        return new Task() {
          
            @Override
            protected Object call() throws Exception {

                File[] files = fileRoot.listFiles();
                for (File file : files) {

                    if (!file.isDirectory()) {
                        String dateiName = file.getName();
                       
                        if(dateiName.endsWith(".pdf")){
                            countPDF++;
                            System.out.println("gefundene PDF: "+countPDF);
                        }

                        updateMessage(countPDF + "");
                        updateProgress(countPDF, 10);
                        System.out.println("erg: " + countPDF );

                    }
                    else{
                        new Thread(createWorker(file)).start();
                    }
                }

                return true;
            }
        };
    }
   
    public File PfadErmitteln(String objectName) {
        URI pfadURI = null;
        URI ordnerDaten = URI.create(objectName);

            try {
                pfadURI = Main.class.getProtectionDomain().getCodeSource().getLocation().toURI();
            } catch (URISyntaxException e1) {
                e1.printStackTrace();
            }


        File filePfad = new File( pfadURI );
        filePfad = filePfad.getParentFile();
        File fileDatei = new File(filePfad + File.separator + ordnerDaten);
   
        return fileDatei;
    }

}
 
Hi,
Wozu brauchst du die Zeile in der Methode: createWorker(File fileRoot) ?
Java:
else{
   new Thread(createWorker(file)).start();
}
Möchtest du damit rekursiv alle pdfs von allen Verzeichnissen ermitteln?
Hier mal ein Beispiel wie es gehen könnte; aber ohne Rekursion und es werden nur die pdfs-vom Root-Verzeichnis ermittelt.
Controller.java: (Controller vom fxml)
Java:
import java.io.File;
import java.util.LinkedList;
import java.util.List;
import javafx.concurrent.Task;
import javafx.concurrent.WorkerStateEvent;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;

public class Controller {
    @FXML
    private Button startButton;
    @FXML
    private ProgressBar meineProzessBar;
    @FXML
    private Label label;
  
    private Task<Boolean> copyWorker;
    private int countPDF;
    private File directory;

    @FXML
    private void actionStart(ActionEvent event) {  
        String path = "C:\\Users\\user\\eBooks\\";
        directory = new File(path);
        if(!directory.isDirectory())
            return;
        countPDF = 0;
        copyWorker = createWorker(directory);
        copyWorker.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
            @Override
            public void handle(WorkerStateEvent event) {
                startButton.setDisable(false);
                label.textProperty().unbind();
                label.setText("Total wurden " + countPDF + " PDF-Dateien gefunden!");
            }
        });
        meineProzessBar.progressProperty().unbind();
        meineProzessBar.progressProperty().bind(copyWorker.progressProperty());
        label.textProperty().bind(copyWorker.messageProperty());
        new Thread(copyWorker).start();
        startButton.setDisable(true);
    }

    private Task<Boolean> createWorker(File fileRoot) {     
        return new Task<Boolean>() {
            @Override
            protected Boolean call() throws Exception {
                List<File> fileList = new LinkedList<>();

                File[] files = fileRoot.listFiles();
                for(File file : files) {
                    if(file.isDirectory())
                        continue;
                    fileList.add(file);
                }
              
                for (File file : fileList) {
                    String dateiName = file.getName();
                    if(dateiName.endsWith(".pdf")){
                        updateMessage(++countPDF + "");
                        updateProgress(countPDF, fileList.size());
                        Thread.sleep(200);
                    }
                }
                return true;
            }
        };
    }
}
 
Hi, danke erstmal für deine Antwort, das funktioniert schonmal, danke dafür.


Hi,
Wozu brauchst du die Zeile in der Methode: createWorker(File fileRoot) ?
Code (Java):
else{
new Thread(createWorker(file)).start();
}
Möchtest du damit rekursiv alle pdfs von allen Verzeichnissen ermitteln?

Ja, ich habe mehrere Verzeichnisse, die ich durchsuchen muss.

Ich habe jetzt versucht, in allen Verzeichnissen die PDFs zu zählen, aber ohne Erfolg, ich habe am Ende das Ergebnis, aber die ProgressBar wird nicht einwandfrei aktualisiert.

Ich weiss grade nicht weiter.

Java:
import java.io.File;
import java.util.LinkedList;
import java.util.List;
import javafx.concurrent.Task;
import javafx.concurrent.WorkerStateEvent;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;

public class Controller {
    @FXML
    private Button startButton;
    @FXML
    private ProgressBar meineProzessBar;
    @FXML
    private Label label;
    private Task<Boolean> copyWorker;
    private int countPDF;
    private File directory;

    @FXML
    private void actionStart(ActionEvent event) {
        String path = "C:\\Users\\user\\eBooks\\";
        directory = new File(path);
        if(!directory.isDirectory())
            return;
        countPDF = 0;
        copyWorker = createWorker(directory);
        copyWorker.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
            @Override
            public void handle(WorkerStateEvent event) {
                startButton.setDisable(false);
                label.textProperty().unbind();
                label.setText("Total wurden " + countPDF + " PDF-Dateien gefunden!");
            }
        });
        meineProzessBar.progressProperty().unbind();
        meineProzessBar.progressProperty().bind(copyWorker.progressProperty());
        label.textProperty().bind(copyWorker.messageProperty());
        new Thread(copyWorker).start();
        startButton.setDisable(true);
     
      
    }
  


    private Task<Boolean> createWorker(File fileRoot) {  
        return new Task<Boolean>() {
            @Override
            protected Boolean call() throws Exception {
                List<File> fileList = new LinkedList<>();

                File[] files = fileRoot.listFiles();
                for(File file : files) {
                    if(file.isDirectory()){
                      
                        System.out.println("Ordner: " + file);                         
                        createWorker(file).run();                     
                    } 
                    else{
                        fileList.add(file);
                    }
                }
           
           
                for (File file : fileList) {
                    String dateiName = file.getName();
                    if(dateiName.endsWith(".pdf")){
                        updateMessage(++countPDF + "");
                        updateProgress(countPDF, 12);
                        System.out.println("Datei: " + countPDF + " -> " + file);
                        Thread.sleep(200);
                  
                    }
                }
               
                return true;
             
            }
        };
    }
}
 
Du brauchst übrigens nicht das Initializable-Interface (welches übrigens Deprecated ist).
Einfach eine Methode "public void initialize() { ... }" mit "@FXML" annotieren und gut ist. Da die Initializeable noch URL-Location und ResourceBundle reingeben: Wenn du die unbedingt brauchst, kannst du das per "@FXML" auch bekommen. Gibt, glaube ich, ein spezielles Namenschema dafür - aber dass kenn' ich gerade nicht...
 
Hier ist die Lösung, klappt wunderbar.

@dzim, wenn du Lust und Zeit hast, kannst du mir ja mal deinen Lösungsansatz posten, das würde mich sehr interessieren

Ein Dank an euch Zwei und liebe Grüsse.

Java:
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Stack;

import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.concurrent.WorkerStateEvent;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;

public class Controller {
    @FXML
    private Button startButton;
    @FXML
    private ProgressBar meineProzessBar;
    @FXML
    private Label label;
    private Task<ObservableList<Integer>> meinWorker;
    private int countPDF;
    private Path directory;

    @FXML
    private void actionStart(ActionEvent event) {
        String path = "F:\\MultiTOP test\\A02\\";
        directory = (Path) Paths.get("F:\\MultiTOP test\\A02\\");
//        if(!directory.isDirectory())
//            return;
        countPDF = 0;
        meinWorker = createWorker();
        meinWorker.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
            @Override
            public void handle(WorkerStateEvent event) {
                startButton.setDisable(false);
                label.textProperty().unbind();
//                label.setText("Total wurden " + countPDF + " PDF-Dateien gefunden!");
            }
        });
        meineProzessBar.progressProperty().unbind();
        meineProzessBar.progressProperty().bind(meinWorker.progressProperty());
        label.textProperty().bind(meinWorker.messageProperty());
        new Thread(meinWorker).start();
        startButton.setDisable(true);
    }

    private Task<ObservableList<Integer>> createWorker() {

        return new Task<ObservableList<Integer>>() {
            @Override
            protected ObservableList<Integer> call() throws Exception {
                Stack<Path> stack = new Stack<Path>();
                stack.push(directory);
                int i = 0;
                while (!stack.empty()) {
                    if (isCancelled()) {
                        break;
                    }
                    Path root = stack.pop();
                    try (DirectoryStream<Path> stream = Files.newDirectoryStream(root);) {
                        for (java.nio.file.Path path : stream) {
                            if (Files.isDirectory(path)) {
                                stack.push(path);
                            } else {

                                if (path.toString().endsWith(".pdf")) {
                                    i++;
                                    System.out.println(path);
//                                    results.add(i);
                                    updateProgress(i, 94);
//                                    updateValue(results);
                                    updateMessage(i + "");
                                    Thread.sleep(5);
                                }
                            }
                        }
                    } catch (IOException ex) {
                        System.out.println(ex.getMessage());
                    }

                }
                return null;
            }

        };

    }
}
 

Zurück
Oben