1 回答
TA贡献1786条经验 获得超12个赞
代码中有几个错误,例如:
//Parser Text Field -> double
控制器中的 -block 执行得太早 = >NullPointerException
。当调用
controller.drawChart(stage)
-start
方法controller
equalsnull
=>时NullPointerException
。在
drawChart
控制器的 - 方法中series
equalsnull
,因为chart
equalsnull
=>NullPointerException
。控制器中缺少对图表的引用。这已经在评论中指出了。
CategoryAxis
用作 x 轴的类型,尽管 x 数据是数值。
在修复这些错误之前,应该改进架构(这会自动修复一些错误):
Controller
-class:由于图表必须初始化,然后在每次单击按钮时更新,因此控制器中的以下更改将很有用:因此,该
Controller
-class 如下所示:实现一个
initialize
方法,可以在其中进行必要的初始化。实现一个
updateChart
- 方法,该方法在单击按钮时调用并更新图表。定义对折线图的引用。
定义对两个轴的参考。
public class Controller {
@FXML
TextField factorA;
@FXML
TextField factorB;
@FXML
TextField factorC;
@FXML
TextField xMin;
@FXML
TextField xMax;
@FXML
Label label;
@FXML
Button button;
@FXML
LineChart<Number, Number> chart;
@FXML
NumberAxis xAxis;
@FXML
NumberAxis yAxis;
@FXML
public void updateChart() {/*ToDo*/}
public void initialize(){/*ToDo*/}
}
Main-class:在start-method 中,仅需要加载 FXML:
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("/fxml/sample.fxml"));
Scene scene = new Scene(root, 800, 800);
stage.setScene(scene);
stage.show();
}
FXML:应进行以下更改:
将折线图的 ID 更改为
fx:id="chart"
将 LineChart 的 x 轴类型更改为
NumberAxis
添加
onAction="#updateChart"
到按钮。updateChart
单击按钮时将调用- 方法。fx:id="xAxis"
为两个轴(和)定义 IDfx:id="yAxis"
。删除所有文本字段的所有非数字字符(例如
text="a="
)的初始化,否则解析会出现问题(使用标签或水印更有意义,例如promptText="a"
)。
然后,FXML 变为:
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="700.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="grahps.Controller">
<children>
<TextField fx:id="factorA" prefHeight="33.0" prefWidth="106.0" AnchorPane.bottomAnchor="75.0" AnchorPane.leftAnchor="24.0" AnchorPane.rightAnchor="670.0" promptText="a" />
<TextField fx:id="factorB" prefHeight="33.0" prefWidth="106.0" AnchorPane.bottomAnchor="37.0" AnchorPane.leftAnchor="24.0" AnchorPane.rightAnchor="670.0" promptText="b" />
<TextField fx:id="factorC" prefHeight="33.0" prefWidth="106.0" AnchorPane.bottomAnchor="1.0" AnchorPane.leftAnchor="24.0" AnchorPane.rightAnchor="670.0" promptText="c" />
<TextField fx:id="xMin" prefHeight="47.0" prefWidth="120.0" AnchorPane.bottomAnchor="61.0" AnchorPane.leftAnchor="158.0" AnchorPane.rightAnchor="522.0" promptText="xMin" />
<TextField fx:id="xMax" prefHeight="47.0" prefWidth="120.0" AnchorPane.bottomAnchor="3.0" AnchorPane.leftAnchor="158.0" AnchorPane.rightAnchor="522.0" promptText="xMax" />
<Label fx:id="label" prefHeight="61.0" prefWidth="276.0" AnchorPane.bottomAnchor="30.0" AnchorPane.leftAnchor="468.0" AnchorPane.rightAnchor="56.0" text="f(x)=" >
<font>
<Font size="18.0" />
</font>
</Label>
<LineChart fx:id="chart" prefHeight="598.0" prefWidth="800.0" title="Chart">
<xAxis>
<NumberAxis fx:id="xAxis" side="BOTTOM" />
</xAxis>
<yAxis>
<NumberAxis fx:id="yAxis" side="LEFT" />
</yAxis>
</LineChart>
<Button fx:id="button" prefHeight="61.0" prefWidth="98.0" layoutX="317.0" layoutY="612.0" mnemonicParsing="false" text="Rysuj wykres" onAction="#updateChart" />
</children>
</AnchorPane>
通过这些更改,应用程序启动时会显示一个空图表(因为尚未实现初始化)。单击该按钮没有任何效果(因为尚未实施更新)。
初始化:
public void initialize(){
initChartProperties();
initInputControls();
XYChart.Series<Number, Number> series = getSeries();
chart.getData().add(series);
}
-methodgetSeries本质上包含 -method 的逻辑drawChart:
private XYChart.Series<Number, Number> getSeries() {
double xMax1 = Double.parseDouble(xMax.getText());
double xMin1 = Double.parseDouble(xMin.getText());
double a = Double.parseDouble(factorA.getText());
double b = Double.parseDouble(factorB.getText());
double c = Double.parseDouble(factorC.getText());
XYChart.Series<Number,Number> series = new XYChart.Series<Number, Number>();
series.setName("Chart");
String pattern;
if (a == 0 && c == 0) {
pattern = "f(x)=" + factorB.getText();
label.setText(pattern);
} else if (c == 0) {
pattern = "f(x)=" + factorA.getText() + "x+" + factorB.getText();
label.setText(pattern);
for (double i = xMin1; i <= xMax1; i++) {
double y = a * i + b;
series.getData().add(new Data<Number, Number>(i, y));
}
} else {
pattern = "f(x)=" + factorA.getText() + "x^2+" + factorB.getText() + "x+" + factorC.getText();
label.setText(pattern);
for (double i = xMin1; i < xMax1; i++) {
double y = a * i * i + b * i + c;
series.getData().add(new Data<Number, Number>(i, y));
}
}
return series;
}
-方法initInputControls初始化输入控件,例如:
private void initInputControls() {
xMax.setText("100.0");
xMin.setText("10.0");
factorA.setText("1.0");
factorB.setText("2.0");
factorC.setText("3.0");
}
-方法initChartProperties初始化图表:
private void initChartProperties() {
chart.setAnimated(true);
xAxis.setLabel("X Label");
yAxis.setLabel("Y Label");
}
如果您想在启动时显示空图表,只需删除 - 方法中的最后三行即可initialize。
更新:更新只是删除旧系列并将新系列添加到图表中:
@FXML
public void updateChart() {
XYChart.Series<Number, Number> series = getSeries();
chart.getData().clear();
chart.getData().add(series);
}
进行这些更改后,应用程序将按预期运行。左图显示启动后的应用程序,右图显示更新输入值后的应用程序。
有些事情仍然可以改进,例如,如果窗口大小更改,应用程序将无法正确缩放。此外,缺少输入字段的验证。可以在 - 方法中禁用图表动画initChartProperties
。
更新: 如果不显示任何符号,请添加 -initChartProperties
方法:
chart.setCreateSymbols(false);
结果是:
添加回答
举报