代码之家  ›  专栏  ›  技术社区  ›  Embid123

在javafx中打印会导致ClassCastException Double无法转换为字符串

  •  0
  • Embid123  · 技术社区  · 7 年前

    我一直在做一个大学项目,绘制一个叫做Lotki-Volterry模型的微分方程的解。它是关于自然界中受害者和捕食者之间的关系。窗口正常显示,当我点击任何按钮时,程序在控制台中抛出异常。我试着自己弄清楚,在大约两个小时的时间里什么地方出了问题,但没有任何效果。

    创建数据的类按预期工作,我创建了csv生成器并在excel中绘制。

    这是我的控制器类:

    package sample;
    
    import javafx.event.ActionEvent;
    import javafx.fxml.FXML;
    import javafx.scene.chart.LineChart;
    import javafx.scene.chart.NumberAxis;
    import javafx.scene.chart.XYChart;
    import javafx.scene.control.Button;
    import javafx.scene.control.TextField;
    import org.apache.commons.math3.ode.FirstOrderDifferentialEquations;
    import org.apache.commons.math3.ode.FirstOrderIntegrator;
    import org.apache.commons.math3.ode.nonstiff.EulerIntegrator;
    
    import java.util.ArrayList;
    
    public class Controller {
    
        private double aHolder = -1;
        private double bHolder = -1;
        private double cHolder = -1;
        private double dHolder = -1;
    
        //datasets
        private XYChart.Series XT = new XYChart.Series();
        private XYChart.Series VT = new XYChart.Series();
        private XYChart.Series VX = new XYChart.Series();
    
        @FXML
        private TextField textA;
    
        @FXML
        private TextField textB;
    
        @FXML
        private TextField textC;
    
        @FXML
        private TextField textD;
    
        @FXML
        private Button plotXT;
    
        @FXML
        private Button plotVT;
    
        @FXML
        private Button plotVX;
    
        @FXML
        private LineChart<Number, Number> figure;
    
        @FXML
        private NumberAxis t;
    
        @FXML
        private NumberAxis x;
    
        @FXML
        void onclickPlotVT(ActionEvent event) {
            boolean isTheSame = checkIfTheSameAndSetIfNot();
            if(!isTheSame){
                calculate();
            }
            figure.getData().clear();
            figure.getData().add(VT);
    
        }
    
        @FXML
        void onclickPlotVX(ActionEvent event) {
            boolean isTheSame = checkIfTheSameAndSetIfNot();
            if(!isTheSame){
                calculate();
            }
            figure.getData().clear();
            figure.getData().add(VX);
    
        }
    
        @FXML
        void onclickPlotXT(ActionEvent event) {
            boolean isTheSame = checkIfTheSameAndSetIfNot();
            if(!isTheSame){
                calculate();
            }
            figure.getData().clear();
            figure.getData().add(XT);
    
        }
    
        //if
         private boolean checkIfTheSameAndSetIfNot(){
            double currentA = Double.parseDouble(textA.getText());
            double currentB = Double.parseDouble(textB.getText());
            double currentC = Double.parseDouble(textC.getText());
            double currentD = Double.parseDouble(textD.getText());
    
            boolean checkA = currentA == aHolder;
            boolean checkB = currentB == bHolder;
            boolean checkC = currentC == cHolder;
            boolean checkD = currentD == dHolder;
    
            //if all parameters are the same, return true, other way false
            if(checkA && checkB && checkC && checkD){
                return true;
            }
    
            aHolder = currentA;
            bHolder = currentB;
            cHolder = currentC;
            dHolder = currentD;
    
            return false;
        }
    
        private void calculate(){
            FirstOrderDifferentialEquations diffEquSolver = new DiffEquSolverZad2(aHolder, bHolder, cHolder, dHolder);
            FirstOrderIntegrator diffEquLIntegrator = new EulerIntegrator(0.01);
            DiffEquSolverPath diffSolverEquPath = new DiffEquSolverPath();
            double [] xStart = new double [] {0,0};
            double [] xStop = new double [] {10,10};
            diffEquLIntegrator.addStepHandler(diffSolverEquPath);
            diffEquLIntegrator.integrate(diffEquSolver,0,xStart,20,xStop);
    
            ArrayList<String> csv = diffSolverEquPath.getCsv();
    
            for(String s : csv){
                String data[] = s.split(",");
                XT.getData().add(new XYChart.Data(Double.parseDouble(data[0]), Double.parseDouble(data[1])));
                VT.getData().add(new XYChart.Data(Double.parseDouble(data[0]), Double.parseDouble(data[2])));
                VX.getData().add(new XYChart.Data(Double.parseDouble(data[1]), Double.parseDouble(data[2])));
    
            }
    
            System.out.println();
        }
    
    }
    

    主类只包含创建和重新生成场景,场景由SceneBuilder生成。

    引发异常后的堆栈位置如下所示:

    Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: class java.lang.Double cannot be cast to class java.lang.String (java.lang.Double and java.lang.String are in module java.base of loader 'bootstrap')
        at javafx.controls/javafx.scene.chart.CategoryAxis.invalidateRange(CategoryAxis.java:456)
        at javafx.controls/javafx.scene.chart.LineChart.updateAxisRange(LineChart.java:207)
        at javafx.controls/javafx.scene.chart.XYChart.layoutChartChildren(XYChart.java:670)
        at javafx.controls/javafx.scene.chart.Chart$1.layoutChildren(Chart.java:95)
        at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1204)
        at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1211)
        at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1211)
        at javafx.graphics/javafx.scene.Scene.doLayoutPass(Scene.java:576)
        at javafx.graphics/javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2482)
        at javafx.graphics/com.sun.javafx.tk.Toolkit.lambda$runPulse$2(Toolkit.java:412)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at javafx.graphics/com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:411)
        at javafx.graphics/com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:438)
        at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:519)
        at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:499)
        at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:492)
        at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11(QuantumToolkit.java:320)
        at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
        at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
        at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
        at java.base/java.lang.Thread.run(Thread.java:834)
    

    其他课程(按计划进行):

    package sample;
    
    import org.apache.commons.math3.exception.DimensionMismatchException;
    import org.apache.commons.math3.exception.MaxCountExceededException;
    import org.apache.commons.math3.ode.FirstOrderDifferentialEquations;
    
    public class DiffEquSolverZad2 implements FirstOrderDifferentialEquations {
        private double a;
        private double b;
        private double c;
        private double d;
    
    
        public DiffEquSolverZad2(double a, double b, double c, double d) {
            if(a > 0 && b > 0 && c > 0 && d > 0) {
                this.a = a;
                this.b = b;
                this.c = c;
                this.d = d;
            } else {
                throw new IllegalArgumentException("All parameters must be greater than 0. ");
            }
        }
    
    
    
        @Override
        public int getDimension() {
            return 2;
        }
    
        @Override
        public void computeDerivatives(double t, double[] x, double[] dxdt) throws MaxCountExceededException, DimensionMismatchException {
            dxdt[0]= (a-b*x[1])*x[0];
            dxdt[1]= (c*x[0]-d)*x[1];
        }
    }
    
    
    package sample;
    
    import org.apache.commons.math3.exception.MaxCountExceededException;
    import org.apache.commons.math3.ode.sampling.StepHandler;
    import org.apache.commons.math3.ode.sampling.StepInterpolator;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    
    public class DiffEquSolverPath implements StepHandler {
    
        private ArrayList<String> csv = new ArrayList<>();
        private ArrayList<Double> tValues = new ArrayList<>();
    
        public ArrayList<String> getCsv() {
            return csv;
        }
    
        public void clearCSVArray(){
            csv.clear();
        }
    
        @Override
        public void init(double v, double[] doubles, double v1) {
    
        }
    
        @Override
        public void handleStep(StepInterpolator stepInterpolator, boolean b) throws MaxCountExceededException {
            double t=stepInterpolator.getCurrentTime();//czas dla którego otrzymaliśmy rozwiązanie numeryczne(obliczono wartości xi v)
            double [] x=stepInterpolator.getInterpolatedState(); //wartości x i v
    
            csv.add(t+", "+ Arrays.toString(x).replace("[", "").replace("]", ""));
    
            tValues.add(t);
        }
    }
    
        package sample;
    
    import javafx.application.Application;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.stage.Stage;
    
    public class Main extends Application {
    
        @Override
        public void start(Stage primaryStage) throws Exception{
            Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
            primaryStage.setTitle("Zad5 from L5 Numeric Methods. ");
            primaryStage.setScene(new Scene(root, 1000, 600));
            primaryStage.show();
        }
    
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    FXML文件:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.geometry.Insets?>
    <?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.BorderPane?>
    <?import javafx.scene.layout.HBox?>
    <?import javafx.scene.layout.VBox?>
    <?import javafx.scene.text.Font?>
    
    <BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="389.0" prefWidth="933.0" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
       <opaqueInsets>
          <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
       </opaqueInsets>
       <top>
          <VBox prefHeight="78.0" prefWidth="563.0" BorderPane.alignment="CENTER">
             <children>
                <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" spacing="20.0">
                   <children>
                      <Label prefHeight="50.0" prefWidth="119.0" text="Model Lotki-Volterry">
                         <font>
                            <Font name="System Bold" size="12.0" />
                         </font>
                      </Label>
                      <Label text="a:" />
                      <TextField fx:id="textA" promptText="1" />
                      <Label text="b:" />
                      <TextField fx:id="textB" promptText="1" />
                      <Label text="c:" />
                      <TextField fx:id="textC" promptText="1" />
                      <Label text="d:" />
                      <TextField fx:id="textD" promptText="1" />
                   </children>
                </HBox>
                <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" spacing="30.0">
                   <children>
                      <VBox alignment="CENTER" prefHeight="39.0" prefWidth="286.0">
                         <children>
                            <Label text="a – współczynnik przyrostu ofiar" />
                            <Label text="b – częstość umierania ofiar na skutek drapieżnictwa" />
                         </children>
                      </VBox>
                      <VBox alignment="CENTER" prefHeight="39.0" prefWidth="266.0">
                         <children>
                            <Label text="c – współczynnik przyrostu drapieżników" />
                            <Label text="d – częstość umierania drapieżników" />
                         </children>
                      </VBox>
                      <Button fx:id="plotXT" mnemonicParsing="false" onAction="#onclickPlotXT" text="Wykres x(t)" />
                      <Button fx:id="plotVT" mnemonicParsing="false" onAction="#onclickPlotVT" text="Wykres v(t)" />
                      <Button fx:id="plotVX" mnemonicParsing="false" onAction="#onclickPlotVX" text="Wykres v(x)" />
                   </children>
                </HBox>
             </children>
          </VBox>
       </top>
       <center>
          <LineChart fx:id="figure" prefHeight="249.0" prefWidth="563.0" BorderPane.alignment="CENTER">
            <xAxis>
              <CategoryAxis side="BOTTOM" />
            </xAxis>
            <yAxis>
              <NumberAxis side="LEFT" />
            </yAxis>
          </LineChart>
       </center>
    </BorderPane>
    
    0 回复  |  直到 7 年前
    推荐文章