NoSuchMethodException () when extending javafx.scene.chart.LineChart


Question

I am trying to extend javafx.scene.chart.LineChart in order to add some extra features.

I have implemented the two constructors

public LiveLineChart(Timeline animation, Axis<Number> xAxis, Axis<Number> yAxis)

and

public LiveLineChart(Timeline animation, Axis<Number> xAxis, Axis<Number> yAxis, ObservableList<Series<Number, Number>> data)

My project compiles, however, when I run, I get this:

Caused by: java.lang.NoSuchMethodException: org.mypackage.LiveLineChart.<init>()
at java.lang.Class.getConstructor0(Class.java:2971)
at java.lang.Class.newInstance(Class.java:403)
... 20 more

If I try to implement a default (empty) constructor, I get a compile error:

no suitable constructor found for LineChart(no arguments)
constructor LineChart.LineChart(Axis<Number>,Axis<Number>) is not applicable
  (actual and formal argument lists differ in length)
constructor LineChart.LineChart(Axis<Number>,Axis<Number>,ObservableList<Series<Number,Number>>) is not applicable
  (actual and formal argument lists differ in length)

What am I missing to be able to get this to run?

1
1
6/27/2014 2:58:40 PM

Accepted Answer

LineChart has no default constructor, so you need to invoke one of the constructors that it declares explicitly from a constructor you define. Looking at the constructors you've said you declared, you probably need something like this:

public LiveLineChart(Timeline animation, Axis<Number> xAxis, Axis<Number> yAxis) {
    super(xAxis, yAxis);
    // ...
}

public LiveLineChart(Timeline animation, Axis<Number> xAxis, Axis<Number> yAxis, ObservableList<Series<Number, Number>> data) {
    super(xAxis, yAxis, data) ;
    // ...
}

If you want to be able to create a LiveLineChart from FXML, you either need a no-argument constructor, or a builder class. A no-argument constructor will not leave you any mechanism to initialize the axes (since they are managed by your superclass and are immutable, i.e. there is no way to set them once the superclass constructor has been invoked). So you most likely need to define the following:

public class LiveLineChartBuilder {
    private Axis<Number> xAxis ;
    private Axis<Number> yAxis ;
    private Timeline animation ;
    private ObservableList<Series<Number,Number>> data ;

    public static LiveLineChartBuilder create() {
        return new LiveLineChartBuilder();
    }

    public LiveLineChartBuilder xAxis(Axis<Number> xAxis) {
        this.xAxis = xAxis ;
        return this ;
    }

    public LiveLineChartBuilder yAxis(Axis<Number> yAxis) {
        this.yAxis = yAxis ;
        return this ;
    }

    public LiveLineChartBuilder animation(Timeline animation) {
        this.animation = animation ;
        return this ;
    }

    public LiveLineChartBuilder data(Series<Number, Number> data) {
        this.data = data ;
        return this ;
    }

    public LiveLineChart build() {
        // if else may not be necessary, depending on how you define constructors in LiveLineChart
        if (data == null) {
            return new LiveLineChart(animation, xAxis, yAxis);
        } else {
            return new LiveLineChart(animation, xAxis, yAxis, data);
        }
    }
}

This will enable you to do

<LiveLineChart>
<xAxis><NumberAxis><!-- ... --></NumberAxis></xAxis>
<!-- etc -->
</LiveLineChart>

in your FXML.

1
6/27/2014 3:56:53 PM

Since there is no default constructor in LineChart and you need to call one of the base class's constructors explicitly or use constructor chaining:

public LiveLineChart() {
    super(new ValueAxis<Number>(), new ValueAxis<Number>()); // use LineChart.LineChart(Axis<Number>,Axis<Number>)
    // do further initialisation
}

or

public LiveLineChart() {
    this(new ValueAxis<Number>(), new ValueAxis<Number>()); // use LiveLineChart(Timeline animation, Axis<Number> xAxis, Axis<Number> yAxis)
    // do further initialisation
}

Of course you can use any other axis type instead of ValueAxis too.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon