1 回答

TA貢獻1786條經(jīng)驗 獲得超13個贊
代碼中有幾個錯誤,例如:
//Parser Text Field -> double
控制器中的 -block 執(zhí)行得太早 = >NullPointerException
。當調(diào)用
controller.drawChart(stage)
-start
方法controller
equalsnull
=>時NullPointerException
。在
drawChart
控制器的 - 方法中series
equalsnull
,因為chart
equalsnull
=>NullPointerException
。控制器中缺少對圖表的引用。這已經(jīng)在評論中指出了。
CategoryAxis
用作 x 軸的類型,盡管 x 數(shù)據(jù)是數(shù)值。
在修復這些錯誤之前,應該改進架構(這會自動修復一些錯誤):
Controller
-class:由于圖表必須初始化,然后在每次單擊按鈕時更新,因此控制器中的以下更改將很有用:因此,該
Controller
-class 如下所示:實現(xiàn)一個
initialize
方法,可以在其中進行必要的初始化。實現(xiàn)一個
updateChart
- 方法,該方法在單擊按鈕時調(diào)用并更新圖表。定義對折線圖的引用。
定義對兩個軸的參考。
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
單擊按鈕時將調(diào)用- 方法。fx:id="xAxis"
為兩個軸(和)定義 IDfx:id="yAxis"
。刪除所有文本字段的所有非數(shù)字字符(例如
text="a="
)的初始化,否則解析會出現(xiàn)問題(使用標簽或水印更有意義,例如promptText="a"
)。
然后,F(xiàn)XML 變?yōu)椋?/p>
<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>
通過這些更改,應用程序啟動時會顯示一個空圖表(因為尚未實現(xiàn)初始化)。單擊該按鈕沒有任何效果(因為尚未實施更新)。
初始化:
public void initialize(){
initChartProperties();
initInputControls();
XYChart.Series<Number, Number> series = getSeries();
chart.getData().add(series);
}
-methodgetSeries本質(zhì)上包含 -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
。
更新: 如果不顯示任何符號,請?zhí)砑?-initChartProperties
方法:
chart.setCreateSymbols(false);
結果是:
添加回答
舉報