JavaFX LineChart - ClassCastException because of the Axis' Type

后端 未结 1 736
一整个雨季
一整个雨季 2020-12-17 23:36

How do I specify the axis type for the chart from the FXML file? It seems like the default types are . If I declare my injectable field a

相关标签:
1条回答
  • 2020-12-18 00:11

    This works fine for me. I tested with the following FXML:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.scene.layout.AnchorPane?>
    <?import javafx.scene.chart.LineChart?>
    <?import javafx.scene.chart.NumberAxis?>
    
    <AnchorPane xmlns:fx="http://javafx.com/fxml">
        <LineChart fx:id="testChart">
        <xAxis><NumberAxis /></xAxis>
        <yAxis><NumberAxis /></yAxis>
        </LineChart>
    </AnchorPane>
    

    and test application:

    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.stage.Stage;
    
    public class Main extends Application {
        @Override
        public void start(Stage primaryStage) {
            try {
                TestChart chart = new TestChart();
                Scene scene = new Scene(chart.getAnchorPane(), 600, 400);
                primaryStage.setScene(scene);
                primaryStage.show();
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    It's a little difficult to tell why you are getting a ClassCastException without seeing your FXML file (and in particular the axes you are using). However, from the stack trace, it appears you are using a CategoryAxis, which is not type-compatible with a LineChart<Number, Number>.

    In general, you can declare the two data types (one for x and one for y) to be any types you want. Since you've declared

    @FXML
    private LineChart<Number, Number> testChart ;
    

    both the type of the x variable and the type of the y variable are Number.

    Referring to the Javadocs for LineChart, a LineChart<X,Y> requires an Axis<X> for the x-axis and an Axis<Y> for the y-axis. So you need an Axis<Number> for each axis. A CategoryAxis is an Axis<String> (again, refer to the Javadocs), so it cannot be used as an axis for your line chart: the data type for the axis is incompatible with the data type for the chart.

    If you tried the following in Java:

    LineChart<Number, Number> testChart ;
    testChart = new LineChart<>(new CategoryAxis(), new NumberAxis());
    

    you would get a compile error. Since you're (presumably) initializing the axes in FXML, and FXML has no type checking, you get the ClassCastException at runtime instead.

    One thing that would help your code is to use a properly typed Series:

    private XYChart.Series<Number, Number> getDummyData()
    {
        final XYChart.Series<Number, Number> series = new XYChart.Series<>();
        series.setName("My portfolio");
        // ...
    }
    

    Now the compiler will check that the type of the Series matches the type of the chart, and the type of the Data matches the type of the Series. (So series.getData().add(new XYChart.Data("1", 23)); would give a compile error, rather than a runtime error.) Since you are creating the axes in FXML, you still have no type checking on those but I think the cause of the error would (perhaps) become clearer.

    The fix is to use a NumberAxis, as in my example above, instead of your CategoryAxis. If you really want to use a CategoryAxis for the x-axis, the x values have to be Strings, and so you need to declare the LineChart as a LineChart<String, Number>. Similarly you would make the Series a Series<String, Number>.

    0 讨论(0)
提交回复
热议问题