Javafx PieChart不应用数据(有时为NullPointerError)

Javafx PieChart不应用数据(有时为NullPointerError),javafx,nullpointerexception,fxml,pie-chart,invocationtargetexception,Javafx,Nullpointerexception,Fxml,Pie Chart,Invocationtargetexception,我正在尝试编写一个简单的程序,包括一个javafx图表。 这个程序的目的是在图表中显示目录中每个子文件夹的大小。问题: 我只想在图表中显示来自另一个类的一些数据。我在calc类中通过controller类的一个对象传输数据,在每个类中使用匹配的参数以另一种方式传输数据。但是没有应用数据,什么也没有发生。如果我直接将一些数据输入PieChartData列表,一切都会正常工作 我已经尝试过通过无休止的方式应用数据,但这只是给了我一个NullPointerError或InvocationTargetE

我正在尝试编写一个简单的程序,包括一个javafx图表。 这个程序的目的是在图表中显示目录中每个子文件夹的大小。问题:

我只想在图表中显示来自另一个类的一些数据。我在calc类中通过controller类的一个对象传输数据,在每个类中使用匹配的参数以另一种方式传输数据。但是没有应用数据,什么也没有发生。如果我直接将一些数据输入PieChartData列表,一切都会正常工作

我已经尝试过通过无休止的方式应用数据,但这只是给了我一个NullPointerError或InvocationTargetException

控制器:


package sample;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.chart.PieChart;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;

import java.io.File;
import java.nio.file.Path;

public class Controller {
    Calc calc = new Calc();

    @FXML
    public PieChart pieChart;
    public Button browse;
    public Button apply;
    public TextField pathField;

    String[] locs = new String[1000];
    double[] sizes = new double[1000];
    int count = 0;

    ObservableList<PieChart.Data> pieChartData = FXCollections.observableArrayList();

    public void handleBrowse(){
        pathField.setText("C:\\Users\\user\\Desktop\\Test");
    }
    public void apply(){
        System.out.println(pathField.getText());
        String strings = new String(pathField.getText());
        calc.main(strings);
        System.out.println("2");
        pieChart.setData(pieChartData);
    }
    public void setData(String loc, long size, int i, int aim){
        pieChartData.add(new PieChart.Data(loc,size));
        System.out.println("1");
    }


}
//alt+Enter = Import


计算:

sample.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.Separator?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="900.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
   <children>
      <PieChart fx:id="pieChart" layoutX="348.0" layoutY="50.0" prefHeight="500.0" prefWidth="500.0" title="Subfolders" />
      <Separator layoutX="316.0" layoutY="-18.0" orientation="VERTICAL" prefHeight="633.0" prefWidth="0.0" />
      <TextField fx:id="pathField" focusTraversable="false" layoutX="31.0" layoutY="115.0" prefHeight="26.0" prefWidth="188.0" promptText="Type Path                                 or" />
      <Button fx:id="browse" layoutX="222.0" layoutY="115.0" mnemonicParsing="false" onAction="#handleBrowse" prefHeight="26.0" prefWidth="65.0" text="Browse" />
      <Label layoutX="116.0" layoutY="41.0" text="Options">
         <font>
            <Font size="27.0" />
         </font>
      </Label>
      <Button fx:id="apply" layoutX="31.0" layoutY="159.0" mnemonicParsing="false" onAction="#apply" prefHeight="55.0" prefWidth="256.0" text="Apply" />
   </children>
</AnchorPane>

我希望代码显示来自控制器类的双fileSizeByte和字符串路径。

加载.fxml文件时,将构造控制器实例。 发布的解决方案的主要问题是

public void add(String loc, long size, int i, int aim){
     Controller controller = new Controller();
     controller.setData(loc,size,i,aim);
}
实际上,您将数据设置为一个新的Cotroller实例,而不是控制器使用的实例

更好的解决方案是让Calc有一个要用计算结果更新的ObservableList的引用:

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;

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

    /*
     * This method is copied from the original method called main.
     * The use of the name main is confusing.
     * The calculation done in this method has some issues, but it is not relevant
     * to the question asked.
     */
    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;

        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) {
                    System.out.println("failure");
                    e.printStackTrace();
                }
            }
        }
    }

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

    //no change in other methods 
}

你发布的代码不太可靠。我找不到的一件事是方法。请回答您的问题,并使其成为一个完整的程序,我可以复制、编译和运行。MRE是必要的建议。此外,Calc中还存在一些问题,主要问题是每次调用add时都会创建控制器的新实例。新创建的控制器实例中没有一个是FXML所使用的。我很高兴它有帮助。我希望这能解释它失败的原因。如果你在大多数情况下发布新问题,mre是必不可少的,请在这里给我留言,我会尽力帮助你。
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;

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

    /*
     * This method is copied from the original method called main.
     * The use of the name main is confusing.
     * The calculation done in this method has some issues, but it is not relevant
     * to the question asked.
     */
    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;

        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) {
                    System.out.println("failure");
                    e.printStackTrace();
                }
            }
        }
    }

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

    //no change in other methods 
}
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.chart.PieChart;
import javafx.scene.control.TextField;

public class Controller {

    @FXML
    private PieChart pieChart;

    @FXML
    private TextField pathField;

    private ObservableList<PieChart.Data> pieChartData;
    private Calc calc;

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

    @FXML
    private void handleBrowse(){
        pathField.setText("C:/Users/user/Desktop/Test");
    }

    @FXML
    private void apply(){
        String strings = new String(pathField.getText());
        calc.calcSubfoldersSize(strings);
    }
}