当我设置 Progress-Indicator.setVisible(true) 时,Javafx Progress-Indicator 不显示

Javafx Progress-Indicator doesn't show up when I set Progress-Indicator.setVisible(true)

我的 JavaFX 应用程序计算另一个文件夹下一层的每个文件夹的文件夹大小。我的问题是,当我点击应用按钮时,它会在另一个 class 中开始计算,我想要一个不确定的进度指示器来向用户显示该应用程序正在运行并且没有挂断。默认情况下,进度指示器设置为不可见,并且在计算期间仅设置为可见。不幸的是,当我调用它时它没有出现。我不确定,但是当计算完成并将其中的数据设置为 JavaFX.Pie-图表时,我可能已经瞥见了指标。

我已经尝试将 Indicator 设置为默认可见,并简单地用一个新的 Rectangle 覆盖它,但这也没有用。

控制器:

package sample;

import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.chart.PieChart;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.TextField;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Rectangle;
import javafx.stage.DirectoryChooser;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;

public class Controller {

    @FXML
    private PieChart pieChart;
    @FXML
    private TextField pathField;
    @FXML
    private Label subfolder;
    @FXML
    private Button up;
    @FXML
    private Button hide;
    @FXML
    private Button showHidden;
    @FXML
    private VBox field1;
    @FXML
    private VBox field2;
    @FXML
    private VBox field3;
    @FXML
    private VBox field4;
    @FXML
    private AnchorPane parentContainer;
    @FXML
    private ProgressIndicator loading;



    private ObservableList<PieChart.Data> pieChartData;
    private Calc calc;
    public File directory;
    String[] unit = {"Bytes", "KB", "MB", "GB", "TB", "PB", "ZB", "EB"};
    int units = 0;
    boolean hideSegment = false;
    String[] hiddenPath = new String[500];
    double[] hiddenSize = new double[500];
    int Stelle = 499;
    boolean first = true;

    @FXML
    void initialize(){
        pieChartData = FXCollections.observableArrayList();
        calc = new Calc(pieChartData);
        updataLabads();
        pieChart.setData(pieChartData);
    }

    @FXML
    private void handleBrowse(){
        Stage stage = new Stage();
        final DirectoryChooser dirChooser = new DirectoryChooser();
        directory = dirChooser.showDialog(stage);
        if(directory != null){
            pathField.setText(directory.toString());
        }
    }

    @FXML
    private void apply(){
        loading.setVisible(true);
        directory = Paths.get(pathField.getText()).toFile();
        if(directory!=null){
            pieChartData.clear();
            String strings = new String(pathField.getText());
            calc.calcSubfoldersSize(strings);
            updataLabads();
        }
        loading.setVisible(false);
    }

    public void updataLabads(){
        pieChart.getData().forEach(data -> {
            data.getNode().addEventHandler(MouseEvent.MOUSE_ENTERED, e -> {

                for(int i=0;(data.getPieValue()/(Math.pow(1024, i))) > 1000;i++){
                    //System.out.println(i);
                    units = i+1;
                }
                subfolder.setText(data.getName() + ", " + Math.round(data.getPieValue()/(Math.pow(1024,units))) + " " + unit[units]);
                //System.out.println(Math.round(data.getPieValue()/(Math.pow(1024,units))) + " " + unit[units]);
            });
        });
        pieChart.getData().forEach(data -> {
            data.getNode().addEventHandler(MouseEvent.MOUSE_RELEASED, e -> {
                if(hideSegment == false){
                    pathField.setText(pathField.getText() + "\" + data.getName());
                    apply();
                }else if(hideSegment == true){
                    pieChartData.remove(data);
                    hideSegment = false;
                    if(first == true){
                        first = false;
                        Stelle = 0;
                    }
                    hiddenPath[Stelle] = data.getName();
                    hiddenSize[Stelle] = data.getPieValue();
                    System.out.println("Hidden Variables have been updatet on Port " + Stelle);
                    Stelle++;
                    pieChart.setData(pieChartData);
                }
            });
        });
    }

    @FXML
    private void up(){
        while(!pathField.getText().substring(pathField.getText().length()-1).equals("\")){
            pathField.setText(pathField.getText().substring(0, pathField.getText().length()-1));
        }
        pathField.setText(pathField.getText().substring(0, pathField.getText().length()-1));
        apply();
    }

    @FXML
    public void hide(){
        if(hideSegment == false)hideSegment = true;
        else if(hideSegment == true)hideSegment = false;
    }

    @FXML
    public void showHidden(){
        System.out.println("Tried to load HiddenVariables on Port " + (Stelle-1));
        System.out.println(hiddenPath[Stelle-1] + "   " + hiddenSize[Stelle-1]);
        if(!hiddenPath[Stelle-1].equals(null)){
            for(int i=Stelle; i!=0; i--){
                pieChartData.add(new PieChart.Data(hiddenPath[Stelle-1], hiddenSize[Stelle-1]));
                hiddenPath[Stelle-1] = "";
                hiddenSize[Stelle-1] = 0;
                Stelle--;
                pieChart.setData(pieChartData);
                updataLabads();
            }
        }
    }

    @FXML
    public void Home() throws IOException {
        Parent root = FXMLLoader.load(getClass().getResource("Home.fxml"));
        Scene scene = up.getScene();
        root.translateYProperty().set(scene.getHeight());
        parentContainer.getChildren().add(root);
        Timeline timeline = new Timeline();
        KeyValue kv = new KeyValue(root.translateYProperty(), 0 , Interpolator.EASE_BOTH);
        KeyFrame kf = new KeyFrame(Duration.seconds(.5), kv);
        timeline.getKeyFrames().add(kf);
        timeline.play();
        parentContainer.getChildren().remove(parentContainer);
    }

    @FXML
    public void Files(){}

    @FXML
    public void Settings(){}

    @FXML
    public void Close(){
        Platform.exit();
    }
}

fxml 文件:

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

<?import javafx.scene.chart.PieChart?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ProgressIndicator?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.shape.SVGPath?>
<?import javafx.scene.text.Font?>

<AnchorPane fx:id="parentContainer" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="1000.0" style="-fx-background-color: #2A2E37;" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
   <children>
      <HBox prefHeight="600.0" prefWidth="1000.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
         <children>
            <VBox alignment="CENTER" prefHeight="600.0" prefWidth="858.0" />
         </children>
      </HBox>
      <PieChart fx:id="pieChart" layoutX="-341.0" layoutY="37.0" legendVisible="false" prefHeight="500.0" prefWidth="2000.0" stylesheets="@pieChart.css" />
      <Label layoutX="620.0" layoutY="24.0" text="Subfolders" textFill="#b2b2b2">
         <font>
            <Font size="24.0" />
         </font>
      </Label>
      <Label fx:id="subfolder" alignment="CENTER" layoutX="374.0" layoutY="551.0" prefHeight="26.0" prefWidth="584.0" textFill="#b2b2b2">
         <font>
            <Font size="25.0" />
         </font>
      </Label>
      <HBox maxHeight="1.7976931348623157E308" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="100.0" prefWidth="320.0">
         <children>
            <VBox prefHeight="200.0" prefWidth="20.0">
               <children>
                  <HBox minHeight="-Infinity" prefHeight="320.0" prefWidth="200.0" style="-fx-background-color: #353841;" />
                  <HBox minHeight="-Infinity" prefHeight="280.0" prefWidth="200.0" style="-fx-background-color: #3F434B;" />
               </children>
            </VBox>
            <VBox minHeight="-Infinity" prefHeight="600.0" prefWidth="280.0">
               <children>
                  <VBox prefHeight="604.0" prefWidth="280.0">
                     <children>
                        <VBox style="-fx-background-color: #353841;">
                           <children>
                              <HBox prefHeight="50.0" prefWidth="280.0">
                                 <children>
                                    <Label fx:id="label" alignment="BOTTOM_CENTER" contentDisplay="CENTER" prefHeight="64.0" prefWidth="280.0" text="Options" textAlignment="CENTER" textFill="#b2b2b2">
                                       <font>
                                          <Font size="28.0" />
                                       </font>
                                    </Label>
                                 </children>
                              </HBox>
                              <HBox prefHeight="64.0" prefWidth="200.0">
                                 <children>
                                    <HBox alignment="CENTER" minWidth="-Infinity" prefHeight="64.0" prefWidth="195.0">
                                       <children>
                                          <TextField fx:id="pathField" focusTraversable="false" prefHeight="48.0" prefWidth="175.0" promptText="Type Path                          or:" stylesheets="@textField.css" />
                                       </children>
                                    </HBox>
                                    <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0">
                                       <children>
                                          <Button fx:id="browse" mnemonicParsing="false" onAction="#handleBrowse" prefHeight="48.0" prefWidth="68.0" stylesheets="@FXbuttons.css" text="Browse" />
                                       </children>
                                    </HBox>
                                 </children>
                              </HBox>
                              <HBox alignment="CENTER" prefHeight="64.0" prefWidth="200.0">
                                 <children>
                                    <Button fx:id="apply" mnemonicParsing="false" onAction="#apply" prefHeight="48.0" prefWidth="262.0" stylesheets="@FXbuttons.css" text="Apply" />
                                 </children>
                              </HBox>
                              <HBox alignment="CENTER" prefHeight="64.0" prefWidth="200.0">
                                 <children>
                                    <Button fx:id="up" mnemonicParsing="false" onAction="#up" prefHeight="48.0" prefWidth="262.0" stylesheets="@FXbuttons.css" text="Up" />
                                 </children>
                              </HBox>
                              <HBox prefHeight="78.0" prefWidth="200.0">
                                 <children>
                                    <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0">
                                       <children>
                                          <Button fx:id="hide" mnemonicParsing="false" onAction="#hide" prefHeight="48.0" prefWidth="124.0" stylesheets="@FXbuttons.css" text="Hide" />
                                       </children>
                                    </HBox>
                                    <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0">
                                       <children>
                                          <Button fx:id="showHidden" mnemonicParsing="false" onAction="#showHidden" prefHeight="48.0" prefWidth="124.0" stylesheets="@FXbuttons.css" text="Show hidden" />
                                       </children>
                                    </HBox>
                                 </children>
                              </HBox>
                           </children>
                        </VBox>
                        <VBox prefHeight="280.0" prefWidth="100.0" style="-fx-background-color: #3F434B;">
                           <children>
                              <HBox prefHeight="140.0" prefWidth="200.0">
                                 <children>
                                    <VBox alignment="CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onMouseClicked="#Home" prefHeight="140.0" prefWidth="140.0" styleClass="vbox" stylesheets="@fields.css">
                                       <children>
                                          <SVGPath content="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z" fill="#4a4d55" scaleX="2.44" scaleY="2.44" />
                                       </children>
                                    </VBox>
                                    <VBox id="VBox" alignment="CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onMouseClicked="#Files" prefHeight="140.0" prefWidth="140.0" styleClass="VBox" stylesheets="@fields.css">
                                       <children>
                                          <SVGPath content="M11 2v20c-5.07-.5-9-4.79-9-10s3.93-9.5 9-10zm2.03 0v8.99H22c-.47-4.74-4.24-8.52-8.97-8.99zm0 11.01V22c4.74-.47 8.5-4.25 8.97-8.99h-8.97z" fill="#4a4d55" scaleX="2.44" scaleY="2.44" />
                                       </children>
                                    </VBox>
                                 </children>
                              </HBox>
                              <HBox prefHeight="140.0" prefWidth="200.0">
                                 <children>
                                    <VBox alignment="CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onMouseClicked="#Settings" prefHeight="140.0" prefWidth="140.0" stylesheets="@locked.css">
                                       <children>
                                          <SVGPath content="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2zM18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z" fill="#4a4d55" scaleX="2.88" scaleY="2.88" styleClass="icon-settings" />
                                       </children>
                                    </VBox>
                                    <VBox alignment="CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onMouseClicked="#Close" prefHeight="140.0" prefWidth="140.0" stylesheets="@fields.css">
                                       <children>
                                          <SVGPath content="M13 3h-2v10h2V3zm4.83 2.17l-1.42 1.42C17.99 7.86 19 9.81 19 12c0 3.87-3.13 7-7 7s-7-3.13-7-7c0-2.19 1.01-4.14 2.58-5.42L6.17 5.17C4.23 6.82 3 9.26 3 12c0 4.97 4.03 9 9 9s9-4.03 9-9c0-2.74-1.23-5.18-3.17-6.83z" fill="#4a4d55" scaleX="2.44" scaleY="2.44" />
                                       </children>
                                    </VBox>
                                 </children>
                              </HBox>
                           </children>
                        </VBox>
                     </children>
                  </VBox>
               </children>
            </VBox>
            <VBox minWidth="-Infinity" prefHeight="200.0" prefWidth="20.0">
               <children>
                  <HBox minHeight="-Infinity" prefHeight="320.0" prefWidth="200.0" style="-fx-background-color: #353841;" />
                  <HBox minHeight="-Infinity" prefHeight="280.0" prefWidth="200.0" style="-fx-background-color: #3F434B;" />
               </children>
            </VBox>
         </children>
      </HBox>
      <ProgressIndicator fx:id="loading" layoutX="627.0" layoutY="250.0" minHeight="-Infinity" minWidth="-Infinity" prefHeight="100.0" prefWidth="100.0" visible="false" />
   </children>
</AnchorPane>


计算 class:

package sample;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import javafx.collections.ObservableList;
import javafx.scene.chart.PieChart;

public class Calc {

    private int totalFolder=0, totalFile=0;
    private static int counter = 0;
    private final ObservableList<PieChart.Data> pieChartData;
    private long filesInRoot = 0;
    Path fileInRoot;


    //added a constructor to receive a reference of the Observable list
    public Calc(ObservableList<PieChart.Data> pieChartData) {
        this.pieChartData = pieChartData;
    }


    public void calcSubfoldersSize(String sPath) { //replaces public void main(String args)

        File nativeFile = new File(sPath);
        File file = new File(nativeFile.toString());

        String[] files = file.list();
        Path path;

        filesInRoot = 0;
        if(file.isDirectory()) {
            for(int i=0; i<=files.length-1; i++) {
                path = Paths.get(files[i]);
                file = path.toFile();
                counter ++;
            }

            String[] paths = new String[counter];
            for(int i=0; i<=files.length-1; i++) {
                path = Paths.get(files[i]);
                file = path.toFile();
                paths[i] = file.toString();
            }

            for(int i=0; i!=counter; i++) {

            }
            for(int i = 0; i+1 <= paths.length; i++) {
                try {
                    Calc size = new Calc(pieChartData); //the only line changed in the method
                    long fileSizeByte = size.getFileSize(new File(nativeFile.toString() + "\" + paths[i]));
                    add(paths[i],fileSizeByte,i,paths.length);
                } catch (Exception e) {
                    fileInRoot = Paths.get(nativeFile.toString()+"\" + paths[i]);
                    filesInRoot = filesInRoot + fileInRoot.toFile().length();
                }
            }
            if(filesInRoot!=0){
                pieChartData.add(new PieChart.Data("Files in Directory",filesInRoot));
                System.out.println(filesInRoot);
            }
        }
    }

    //let add update the observable list
    public void add(String loc, long size, int i, int aim){
        pieChartData.add(new PieChart.Data(loc,size));
    }

    public long getFileSize(File folder) {
        long foldersize = 0;

        totalFolder++;
//          System.out.println("Folder: " + folder + "  (Source: getFileSize)");
        File[] filelist = folder.listFiles();
//          System.out.println(folder.listFiles());

        for (int i = 0; i < filelist.length; i++) {
            if (filelist[i].isDirectory()) {
                foldersize += getFileSize(filelist[i]);
            } else {
                totalFile++;
                foldersize += filelist[i].length();
            }
        }

        return foldersize;

    }

    public int getTotalFolder() {
        return totalFolder;
    }

    public int getTotalFile() {
        return totalFile;
    }
}

编辑:

主要Class:

package sample;

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) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("Files.fxml"));
        primaryStage.setTitle("Fileview.io");
        primaryStage.setScene(new Scene(root));
        primaryStage.setResizable(false);
        primaryStage.show();
    }


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

控制器Class:

package sample;

import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.chart.PieChart;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.TextField;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Rectangle;
import javafx.stage.DirectoryChooser;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;

public class Controller {

    @FXML
    private PieChart pieChart;
    @FXML
    private TextField pathField;
    @FXML
    private Label subfolder;
    @FXML
    private Button up;
    @FXML
    private Button hide;
    @FXML
    private Button showHidden;
    @FXML
    private VBox field1;
    @FXML
    private VBox field2;
    @FXML
    private VBox field3;
    @FXML
    private VBox field4;
    @FXML
    private AnchorPane parentContainer;
    @FXML
    private ProgressIndicator loading;



    private ObservableList<PieChart.Data> pieChartData;
    private Calc calc;
    public File directory;
    String[] unit = {"Bytes", "KB", "MB", "GB", "TB", "PB", "ZB", "EB"};
    int units = 0;
    boolean hideSegment = false;
    String[] hiddenPath = new String[500];
    double[] hiddenSize = new double[500];
    int Stelle = 499;
    boolean first = true;


    @FXML
    private void handleBrowse(){
        Stage stage = new Stage();
        final DirectoryChooser dirChooser = new DirectoryChooser();
        directory = dirChooser.showDialog(stage);
        if(directory != null){
            pathField.setText(directory.toString());
        }
    }

    @FXML
    private void apply() {
        loading.setVisible(true);

        Task<Void> applyTask = new Task<Void>() {

            @Override
            protected Void call() throws Exception {

                Thread.sleep(0);//sleep for 10 seconds just to show that the progress indicator is working

                directory = Paths.get(pathField.getText()).toFile();
                if (directory != null) {
                    //fx-parts need to be executed by Platform.runLater(...)
                    Platform.runLater(() -> pieChartData.clear());
                    String strings = new String(pathField.getText());
                    calc.calcSubfoldersSize(strings);
                    //again let fx-parts be executed in the fx-application-thread
                    Platform.runLater(() -> updataLabads());
                }

                return null;
            }
        };

        applyTask.setOnSucceeded(e -> loading.setVisible(false));
        applyTask.setOnFailed(e -> loading.setVisible(false));//handle error here...

        new Thread(applyTask, "Apply thread").start();

        //loading.setVisible(false); //done when the task ends
    }

    public void updataLabads(){
        pieChart.getData().forEach(data -> {
            data.getNode().addEventHandler(MouseEvent.MOUSE_ENTERED, e -> {

                for(int i=0;(data.getPieValue()/(Math.pow(1024, i))) > 1000;i++){
                    //System.out.println(i);
                    units = i+1;
                }
                subfolder.setText(data.getName() + ", " + Math.round(data.getPieValue()/(Math.pow(1024,units))) + " " + unit[units]);
                //System.out.println(Math.round(data.getPieValue()/(Math.pow(1024,units))) + " " + unit[units]);
            });
        });
        pieChart.getData().forEach(data -> {
            data.getNode().addEventHandler(MouseEvent.MOUSE_RELEASED, e -> {
                if(hideSegment == false){
                    pathField.setText(pathField.getText() + "\" + data.getName());
                    apply();
                }else if(hideSegment == true){
                    pieChartData.remove(data);
                    hideSegment = false;
                    if(first == true){
                        first = false;
                        Stelle = 0;
                    }
                    hiddenPath[Stelle] = data.getName();
                    hiddenSize[Stelle] = data.getPieValue();
                    System.out.println("Hidden Variables have been updatet on Port " + Stelle);
                    Stelle++;
                    pieChart.setData(pieChartData);
                }
            });
        });
    }

    @FXML
    private void up(){
        while(!pathField.getText().substring(pathField.getText().length()-1).equals("\")){
            pathField.setText(pathField.getText().substring(0, pathField.getText().length()-1));
        }
        pathField.setText(pathField.getText().substring(0, pathField.getText().length()-1));
        apply();
    }

    @FXML
    public void hide(){
        if(hideSegment == false)hideSegment = true;
        else if(hideSegment == true)hideSegment = false;
    }

    @FXML
    public void showHidden(){
        System.out.println("Tried to load HiddenVariables on Port " + (Stelle-1));
        System.out.println(hiddenPath[Stelle-1] + "   " + hiddenSize[Stelle-1]);
        if(!hiddenPath[Stelle-1].equals(null)){
            for(int i=Stelle; i!=0; i--){
                pieChartData.add(new PieChart.Data(hiddenPath[Stelle-1], hiddenSize[Stelle-1]));
                hiddenPath[Stelle-1] = "";
                hiddenSize[Stelle-1] = 0;
                Stelle--;
                pieChart.setData(pieChartData);
                updataLabads();
            }
        }
    }

    public void initialize(){
        pieChartData = FXCollections.observableArrayList();
        updataLabads();
        calc = new Calc(pieChartData);
        pieChart.setData(pieChartData);
    }

    @FXML
    public void Home() throws IOException {
        Parent root = FXMLLoader.load(getClass().getResource("Home.fxml"));
        Scene scene = up.getScene();
        root.translateYProperty().set(scene.getHeight());
        parentContainer.getChildren().add(root);
        Timeline timeline = new Timeline();
        KeyValue kv = new KeyValue(root.translateYProperty(), 0 , Interpolator.EASE_BOTH);
        KeyFrame kf = new KeyFrame(Duration.seconds(.5), kv);
        timeline.getKeyFrames().add(kf);
        timeline.play();
        parentContainer.getChildren().remove(parentContainer);
    }

    @FXML
    public void Files(){}

    @FXML
    public void Settings(){}

    @FXML
    public void Close(){
        Platform.exit();
    }
}

Calc class 在@Tobias 答案中可用。 当我 运行 项目时,我只是启动 Main class

我猜想,UI 在计算过程中挂起,因此没有显示您的指标,因为 UI 无法更新。最后,当计算完成时,指标会设置为可见,然后又不可见,因为计算完成(这可能是指标短闪的原因)。

解决方案是将你的计算放在一个新的 Thread 中,这样它就可以 运行 并行并且 UI 线程不会被计算阻塞。

查看 this answer 示例,了解如何创建新线程。

问题是,apply 方法的执行阻塞了FX-Thread,所以无法显示进度指示器。

因此需要在另一个线程(或任务)中执行才能使进度指示器可见。然后,当任务成功时,您可以再次将进度指示器的可见性设置为 false。 (还有一个问题是apply方法只是为了快,所以指示器没有出现。我加了10秒的sleep以显示它正在工作)

一个解决方案是像这样更改您的 apply() 方法:

@FXML
private void apply() {
    loading.setVisible(true);

    Task<Void> applyTask = new Task<Void>() {

        @Override
        protected Void call() throws Exception {

            Thread.sleep(10000);//sleep for 10 seconds just to show that the progress indicator is working

            directory = Paths.get(pathField.getText()).toFile();
            if (directory != null) {
                //fx-parts need to be executed by Platform.runLater(...)
                Platform.runLater(() -> pieChartData.clear());

                String strings = new String(pathField.getText());
                calc.calcSubfoldersSize(strings);

                //again let fx-parts be executed in the fx-application-thread
                Platform.runLater(() -> updataLabads());
            }

            return null;
        }
    };

    applyTask.setOnSucceeded(e -> loading.setVisible(false));
    applyTask.setOnFailed(e -> loading.setVisible(false));//handle error here...

    new Thread(applyTask, "Apply thread").start();

    //loading.setVisible(false); //done when the task ends
}

编辑:

为了在评论中回答你的问题:

如果你像这样更改 class Calc 它应该可以工作(用评论标记编辑):

package sample;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;

import javafx.application.Platform;
import javafx.collections.ObservableList;
import javafx.scene.chart.PieChart;

public class Calc {

    private int totalFolder = 0, totalFile = 0;
    private static int counter = 0;
    private final ObservableList<PieChart.Data> pieChartData;
    private ArrayList<PieChart.Data> pieChartData2;//EDIT: here you don't need an ObservableList, a simple ArrayList will do it
    private long filesInRoot = 0;
    Path fileInRoot;

    //added a constructor to receive a reference of the Observable list
    public Calc(ObservableList<PieChart.Data> pieChartData) {
        this.pieChartData = pieChartData;//EDIT: when you set this.pieChartData = pieChartData2 the parameter would be ignored...
        pieChartData2 = new ArrayList<PieChart.Data>();
    }

    public void calcSubfoldersSize(String sPath) { //replaces public void main(String args)
        File nativeFile = new File(sPath);
        File file = new File(nativeFile.toString());

        String[] files = file.list();
        Path path;

        filesInRoot = 0;
        if (file.isDirectory()) {
            for (int i = 0; i <= files.length - 1; i++) {
                path = Paths.get(files[i]);
                file = path.toFile();
                counter++;
            }

            String[] paths = new String[counter];
            for (int i = 0; i <= files.length - 1; i++) {
                path = Paths.get(files[i]);
                file = path.toFile();
                paths[i] = file.toString();
            }

            for (int i = 0; i != counter; i++) {

            }
            for (int i = 0; i + 1 <= paths.length; i++) {
                try {
                    Calc size = new Calc(pieChartData); //the only line changed in the method
                    long fileSizeByte = size.getFileSize(new File(nativeFile.toString() + "\" + paths[i]));
                    add(paths[i], fileSizeByte, i, paths.length);
                }
                catch (Exception e) {
                    fileInRoot = Paths.get(nativeFile.toString() + "\" + paths[i]);
                    filesInRoot = filesInRoot + fileInRoot.toFile().length();
                }
            }
            if (filesInRoot != 0) {
                add("Files in Directory", filesInRoot, 1, 100);
                pieChartData2.add(new PieChart.Data("Files in Directory", filesInRoot));
                System.out.println(filesInRoot);
            }
        }

        //EDIT: let this part be executed by the fx-application thread:
        Platform.runLater(() -> pieChartData.addAll(pieChartData2));
    }

    //let add update the observable list
    public void add(String loc, long size, int i, int aim) {
        pieChartData2.add(new PieChart.Data(loc, size));//EDIT: the error seems to occur here because pieChartData2 was null (but I'm not sure why there was no exception shown...; probably because it's executed in the task...) 
    }

    public long getFileSize(File folder) {
        long foldersize = 0;

        totalFolder++;
        //          System.out.println("Folder: " + folder + "  (Source: getFileSize)");
        File[] filelist = folder.listFiles();
        //          System.out.println(folder.listFiles());

        for (int i = 0; i < filelist.length; i++) {
            if (filelist[i].isDirectory()) {
                foldersize += getFileSize(filelist[i]);
            }
            else {
                totalFile++;
                foldersize += filelist[i].length();
            }
        }

        return foldersize;

    }

    public int getTotalFolder() {
        return totalFolder;
    }

    public int getTotalFile() {
        return totalFile;
    }
}

在您的回答中显示的更新后的 Controller class 中,我认为这部分是另一个问题:

//...
String strings = new String(pathField.getText());
calc.calcSubfoldersSize(strings);
Platform.runLater(() -> initialize());
//...

即使 method-call calc.calcSubfoldersSize(strings) 正在工作,下一次调用 Platform.runLater(() -> initialize()); 也会重置找到的结果。所以你应该删除最后一行 Platform.runLater(() -> initialize());

为完整起见,这里是对我有用的完整 Controller class:

package sample;

import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;

import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.chart.PieChart;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.TextField;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.stage.DirectoryChooser;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Controller {

    @FXML
    private PieChart pieChart;
    @FXML
    private TextField pathField;
    @FXML
    private Label subfolder;
    @FXML
    private Button up;
    @FXML
    private Button hide;
    @FXML
    private Button showHidden;
    @FXML
    private VBox field1;
    @FXML
    private VBox field2;
    @FXML
    private VBox field3;
    @FXML
    private VBox field4;
    @FXML
    private AnchorPane parentContainer;
    @FXML
    private ProgressIndicator loading;

    private ObservableList<PieChart.Data> pieChartData;
    private Calc calc;
    public File directory;
    String[] unit = {"Bytes", "KB", "MB", "GB", "TB", "PB", "ZB", "EB"};
    int units = 0;
    boolean hideSegment = false;
    String[] hiddenPath = new String[500];
    double[] hiddenSize = new double[500];
    int Stelle = 499;
    boolean first = true;

    @FXML
    void initialize() {
        pieChartData = FXCollections.observableArrayList();
        calc = new Calc(pieChartData);
        updataLabads();
        pieChart.setData(pieChartData);
    }

    @FXML
    private void handleBrowse() {
        Stage stage = new Stage();
        final DirectoryChooser dirChooser = new DirectoryChooser();
        directory = dirChooser.showDialog(stage);
        if (directory != null) {
            pathField.setText(directory.toString());
        }
    }

    @FXML
    private void apply() {
        loading.setVisible(true);

        Task<Void> applyTask = new Task<Void>() {

            @Override
            protected Void call() throws Exception {

                Thread.sleep(3000);//sleep for 3 seconds just to show that the progress indicator is working

                directory = Paths.get(pathField.getText()).toFile();
                if (directory != null) {
                    //fx-parts need to be executed by Platform.runLater(...)
                    Platform.runLater(() -> pieChartData.clear());

                    String strings = new String(pathField.getText());
                    calc.calcSubfoldersSize(strings);

                    //again let fx-parts be executed in the fx-application-thread
                    Platform.runLater(() -> updataLabads());
                }

                return null;
            }
        };

        applyTask.setOnSucceeded(e -> loading.setVisible(false));
        applyTask.setOnFailed(e -> loading.setVisible(false));//handle error here...

        new Thread(applyTask, "Apply thread").start();

        //loading.setVisible(false); //done when the task ends
    }

    public void updataLabads() {
        pieChart.getData().forEach(data -> {
            data.getNode().addEventHandler(MouseEvent.MOUSE_ENTERED, e -> {

                for (int i = 0; (data.getPieValue() / (Math.pow(1024, i))) > 1000; i++) {
                    //System.out.println(i);
                    units = i + 1;
                }
                subfolder.setText(data.getName() + ", " + Math.round(data.getPieValue() / (Math.pow(1024, units))) + " " + unit[units]);
                //System.out.println(Math.round(data.getPieValue()/(Math.pow(1024,units))) + " " + unit[units]);
            });
        });
        pieChart.getData().forEach(data -> {
            data.getNode().addEventHandler(MouseEvent.MOUSE_RELEASED, e -> {
                if (hideSegment == false) {
                    pathField.setText(pathField.getText() + "\" + data.getName());
                    apply();
                }
                else if (hideSegment == true) {
                    pieChartData.remove(data);
                    hideSegment = false;
                    if (first == true) {
                        first = false;
                        Stelle = 0;
                    }
                    hiddenPath[Stelle] = data.getName();
                    hiddenSize[Stelle] = data.getPieValue();
                    System.out.println("Hidden Variables have been updatet on Port " + Stelle);
                    Stelle++;
                    pieChart.setData(pieChartData);
                }
            });
        });
    }

    @FXML
    private void up() {
        while (!pathField.getText().substring(pathField.getText().length() - 1).equals("\")) {
            pathField.setText(pathField.getText().substring(0, pathField.getText().length() - 1));
        }
        pathField.setText(pathField.getText().substring(0, pathField.getText().length() - 1));
        apply();
    }

    @FXML
    public void hide() {
        if (hideSegment == false)
            hideSegment = true;
        else if (hideSegment == true)
            hideSegment = false;
    }

    @FXML
    public void showHidden() {
        System.out.println("Tried to load HiddenVariables on Port " + (Stelle - 1));
        System.out.println(hiddenPath[Stelle - 1] + "   " + hiddenSize[Stelle - 1]);
        if (!hiddenPath[Stelle - 1].equals(null)) {
            for (int i = Stelle; i != 0; i--) {
                pieChartData.add(new PieChart.Data(hiddenPath[Stelle - 1], hiddenSize[Stelle - 1]));
                hiddenPath[Stelle - 1] = "";
                hiddenSize[Stelle - 1] = 0;
                Stelle--;
                pieChart.setData(pieChartData);
                updataLabads();
            }
        }
    }

    @FXML
    public void Home() throws IOException {
        Parent root = FXMLLoader.load(getClass().getResource("Home.fxml"));
        Scene scene = up.getScene();
        root.translateYProperty().set(scene.getHeight());
        parentContainer.getChildren().add(root);
        Timeline timeline = new Timeline();
        KeyValue kv = new KeyValue(root.translateYProperty(), 0, Interpolator.EASE_BOTH);
        KeyFrame kf = new KeyFrame(Duration.seconds(.5), kv);
        timeline.getKeyFrames().add(kf);
        timeline.play();
        parentContainer.getChildren().remove(parentContainer);
    }

    @FXML
    public void Files() {}

    @FXML
    public void Settings() {}

    @FXML
    public void Close() {
        Platform.exit();
    }
}