I am trying to write a custom graphing components that I can reuse to draw graphs on multiple tabs within an application.
A single instance of the graph is composed of an FXML file consisting of an AnchorPane with 5 Canvas all on top of each other for each series I would like to display. Each Canvas is assigned an fx:id. I then have a graphFXMLController.java file associated with this, each canvas is given a GraphicsContext, and when running a function I can draw upon each canvas.
On my main application controller file, I declare the component with:
@FXML
public GraphFXMLController spectrumgraph;
In my main application FXML file I import my graphFXMLController file with:
<?import measuremefx.GraphFXMLController?>
and then I declare my component with:
<GraphFXMLController id="AnchorPane" fx:id="spectrumgraph" layoutX="-23.0" layoutY="314.0" prefHeight="357.0" prefWidth="601.0" />
My GraphFXMLController file is:
public class GraphFXMLController extends AnchorPane implements Initializable {
@FXML
public Canvas backgroundCanvas;
@FXML
public Canvas series1Canvas;
@FXML
public Canvas series2Canvas;
@FXML
public Canvas series3Canvas;
@FXML
public Canvas series4Canvas;
@FXML
public Canvas savedSeriesCanvas;
public GraphFXMLController(){
System.out.println("Graph Initialised");
GraphicsContext backgroundGC = backgroundCanvas.getGraphicsContext2D();
}
the idea is that I can then call on the graphics context to then draw my series. However, currently when I try and run the application, I can see when the main page loads, it calls for the GraphFXMLController to load as I get the System out message, but I get a null pointer error on my GraphicsContext declaration. It appears that there is a null pointer to backgroundCanvas. Which I do not understand as it should be initialised in the @FXML statement.
Below is the graphFXML file showing that the backgroundCanvas should be there.
<?import javafx.scene.canvas.Canvas?>
<?import javafx.scene.layout.AnchorPane?>
<fx:root id="AnchorPane" minHeight="200.0" minWidth="300.0" prefHeight="300.0" prefWidth="600.0" type="AnchorPane" xmlns="http://javafx.com/javafx/9" xmlns:fx="http://javafx.com/fxml/1" fx:controller="measuremefx.GraphFXMLController">
<children>
<Canvas fx:id="backgroundCanvas" height="300.0" width="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
<Canvas fx:id="series1Canvas" height="300.0" width="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
<Canvas fx:id="series2Canvas" height="300.0" width="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
<Canvas fx:id="series3Canvas" height="300.0" layoutX="7.0" width="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
<Canvas fx:id="series4Canvas" height="300.0" width="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
<Canvas fx:id="savedSeriesCanvas" height="300.0" layoutY="-1.0" width="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</fx:root>
I haver tried moving the GraphicsContext declaration into an @FXML statement after the backgroundCanvas statement, however it still returns null pointer. Am I loading this incorrectly?
Any help would be much appreciated. I implement several instances of this specific type of graph, all with logarithmic axis and very quick 20Hz refresh rate and without being able to use instances of this code, this project would get messy very quickly.