Reputation: 1237
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?
Upvotes: 1
Views: 7887
Reputation: 209319
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.
Upvotes: 2
Reputation: 82461
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.
Upvotes: 1
Reputation: 11
Since I can't comment, I will use answer block. I have never worked with javafx but this is simple java issue. Have you defined default constructor in the second approach? Looks like its missing. Class loader needs default constructor (with no parameters)
Upvotes: 0