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