简体   繁体   English

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

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

My JavaFX application calculates the folder sizes of every folder one level under another folder. 我的JavaFX应用程序计算另一个文件夹下一个级别的每个文件夹的文件夹大小。 My problem is that when I hit the apply button, which starts the calculation in another class, I want an indeterminate progress-indicator to show the user that the app is working right now and hasn't hung itself up. 我的问题是,当我点击应用按钮,它开始另一个类的计算时,我想要一个不确定的进度指示器向用户显示该应用程序现在正在工作并且没有自行挂起。 By default, the progress-indicator is set to invisible and is just set to visible during the calculation. 默认情况下,progress-indicator设置为不可见,并且在计算过程中设置为可见。 Unfortunately, it doesn't show up when I call it. 不幸的是,当我打电话时它没有显示出来。 I'm not sure, but when the calculation is finished and the data from it is set to a JavaFX.Pie-Chart, I might have caught a glimpse of the indicator. 我不确定,但是当计算完成并且来自它的数据被设置为JavaFX.Pie-Chart时,我可能已经看到了指标。

I've already tried to set the Indicator to visible by default and simply cover it up with a new Rectangle, but this didn't work either. 我已经尝试将Indicator设置为默认可见,只需用新的Rectangle覆盖它,但这也不起作用。

Controller: 控制器:

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 document: 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>


Calc 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;
    }
}

EDIT: 编辑:

Main 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);
    }
}

Controller 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 is available in @Tobias answer. @Tobias答案中提供了Calc类。 When I run the project, I simply launch the Main class 当我运行项目时,我只需启动Main类

I would guess, that the UI hangs during the calculation and therefore not showing your indicator as the UI can't update. 我猜,在计算过程中UI会挂起,因此无法显示您的指示器,因为UI无法更新。 At the end, when the calculation finished, the indicator will be set to visible and then invisible again, because the calculation finished (that is probably what the short flash of the indidcator is). 最后,当计算完成时,指示器将被设置为可见,然后再次不可见,因为计算完成(这可能是指示器的短暂闪烁)。

The solution is to put your calculation in a new Thread , so it can run in parallel and the UI Thread is not blocked by the calculation. 解决方案是将您的计算放在一个新的Thread ,这样它就可以并行运行,并且UI Thread不会被计算阻塞。

Take a look at this answer for example to see how you can create a new thread. 这个答案为例,看看如何创建一个新线程。

The problem is, that the execution of the apply method blocks the FX-Thread , so the progress indicator can't be displayed. 问题是, apply方法执行会阻止FX-Thread ,因此无法显示进度指示器。

So the execution needs to be done in another Thread (or a Task) to make the progress indicator visible. 因此,执行需要在另一个线程(或任务)中完成,以使进度指示器可见。 Then when the Task has succeeded you can set the visibility of the progress indicator to false again. 然后,当任务成功时,您可以再次将进度指示器的可见性设置为false。 (Also a problem is that the apply method is just to fast, so the indicator doesn't show up. I added a sleep of 10 seconds to show it's working) (另一个问题是apply方法只是为了快速,所以指示器没有出现。我加了一个10秒的睡眠来显示它正在工作)

A solution would be to change your apply() method like this: 一个解决方案是改变你的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
}

EDIT: 编辑:

In order to answer your question in the comments: 为了在评论中回答您的问题:

If you change the class Calc like this it should work (marked the edits with comments): 如果您更改类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;
    }
}

In the updated Controller class that you showed in your answer, I think is another problem in this part: 在您在答案中显示的更新的Controller类中,我认为这部分是另一个问题:

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

Even if the method-call calc.calcSubfoldersSize(strings) is working, the next call of Platform.runLater(() -> initialize()); 即使方法调用calc.calcSubfoldersSize(strings)正在工作,下一次调用Platform.runLater(() -> initialize()); will reset the results that were found. 将重置找到的结果。 So you should delete the last line Platform.runLater(() -> initialize()); 所以你应该删除最后一行Platform.runLater(() -> initialize());

For completeness here is the full Controller class that worked for me: 为了完整性,这里是完整的Controller类,对我有用:

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();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM