猿问

如何解决使用 JavaFX 在场景生成器中绘制图表的问题

我的程序有问题。我想在提供数据(方程的系数)后绘制图表。


我尝试更改我的导入(它对某些变量有帮助)我更改了 java.awt* 为 javafx.scene ...(很少导入)。


FXML 文件:


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


<?import javafx.scene.chart.CategoryAxis?>

<?import javafx.scene.chart.LineChart?>

<?import javafx.scene.chart.NumberAxis?>

<?import javafx.scene.control.Button?>

<?import javafx.scene.control.Label?>

<?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="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" layoutX="24.0" layoutY="598.0" prefHeight="33.0" prefWidth="106.0" text="a=" AnchorPane.bottomAnchor="75.0" AnchorPane.leftAnchor="24.0" AnchorPane.rightAnchor="670.0" />

        <TextField fx:id="factorB" layoutX="24.0" layoutY="630.0" prefHeight="33.0" prefWidth="106.0" text="b=" AnchorPane.bottomAnchor="37.0" AnchorPane.leftAnchor="24.0" AnchorPane.rightAnchor="670.0" />

        <TextField fx:id="factorC" layoutX="24.0" layoutY="674.0" prefHeight="33.0" prefWidth="106.0" text="c=" AnchorPane.bottomAnchor="1.0" AnchorPane.leftAnchor="24.0" AnchorPane.rightAnchor="670.0" />

        <TextField layoutX="158.0" layoutY="592.0" prefHeight="47.0" prefWidth="120.0" text="xMin=" AnchorPane.bottomAnchor="61.0" AnchorPane.leftAnchor="158.0" AnchorPane.rightAnchor="522.0" fx:id="xMin" />

        <TextField layoutX="158.0" layoutY="650.0" prefHeight="47.0" prefWidth="120.0" text="xMax=" AnchorPane.bottomAnchor="3.0" AnchorPane.leftAnchor="158.0" AnchorPane.rightAnchor="522.0" fx:id="xMax" />

        <Label fx:id="label" layoutX="468.0" layoutY="629.0" prefHeight="61.0" prefWidth="276.0" text="f(x)=" AnchorPane.bottomAnchor="30.0" AnchorPane.leftAnchor="468.0" AnchorPane.rightAnchor="56.0">



LineChart (fx:id="drawChart") 生成的部分进行通信:“未解析的 fx:id 参考

qq_花开花谢_0
浏览 113回答 1
1回答

开满天机

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

相关分类

Java
我要回答