1

I'm working on a value marker for a line chart in JavaFX 2.2. I therefore used the answer on an existing question here on stackoverflow and the example by Sergey Grinev is working fine. However, if I want to use FXML to add a chart instead of adding it hardcoded I have problems determing the size of the chart's background.

I moved the initialization of the chart and the valueMarker to the initialize() method which the FXMLLoader automatically calls after the root element has been processed (see the note in the JavaFX Documentation). But if I now use the following code to determine the size of the chart's background it returns just 0.0 for every bound value:

Node chartArea = chart.lookup(".chart-plot-background");
Bounds chartAreaBounds = chartArea.localToScene(chartArea.getBoundsInLocal());

The exact same code in the updateMarker() method returns the determined size of the chart's background on the second call. On the first call the bounds are set, but minX isn't correct. Here is my code:

public class LineChartValueMarker extends Application {

    @FXML
    private LineChart<Number, Number> chart;

    @FXML
    private Line valueMarker;

    @FXML
    private NumberAxis yAxis;

    private XYChart.Series<Number, Number> series = new XYChart.Series<>();

    private void updateMarker() {
        Node chartArea = chart.lookup(".chart-plot-background");
        Bounds chartAreaBounds = chartArea.localToScene(chartArea
                .getBoundsInLocal());

        // SIZE OF THE CHART IS DETERMINED
        System.out.println(chartAreaBounds);

        valueMarker.setStartX(chartAreaBounds.getMinX());
        valueMarker.setEndX(chartAreaBounds.getMaxX());
    }

    public void initialize() {
        series.getData().add(new XYChart.Data(0, 0));
        series.getData().add(new XYChart.Data(10, 20));

        chart.getData().addAll(series);

        // add new value on mouseclick for testing
        chart.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent t) {
                series.getData().add(
                        new XYChart.Data(series.getData().size() * 10,
                                30 + 50 * new Random().nextDouble()));
                updateMarker();
            }
        });

        // find chart area Node
        Node chartArea = chart.lookup(".chart-plot-background");
        Bounds chartAreaBounds = chartArea.localToScene(chartArea
                .getBoundsInLocal());

        // SIZE AND POSITION OF THE CHART IS 0.0
        System.out.println(chartAreaBounds);
    }

    @Override
    public void start(Stage stage) throws IOException {
        FXMLLoader loader = new FXMLLoader();

        InputStream in = this.getClass().getResourceAsStream(
                "LineChartValueMarker.fxml");
        loader.setBuilderFactory(new JavaFXBuilderFactory());
        loader.setLocation(this.getClass().getResource(
                "LineChartValueMarker.fxml"));

        Pane pane = (Pane) loader.load(in);
        Scene scene = new Scene(pane);
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}

I added upper case comments on the position in the code where I print the bounds (and I removed the update of the Y coordinate of the valueMarker). Here is the output:

BoundingBox [minX:0.0, minY:0.0, minZ:0.0, width:0.0, height:0.0, depth:0.0, maxX:0.0, maxY:0.0, maxZ:0.0]
BoundingBox [minX:45.0, minY:15.0, minZ:0.0, width:441.0, height:318.0, depth:0.0, maxX:486.0, maxY:333.0, maxZ:0.0]
BoundingBox [minX:37.0, minY:15.0, minZ:0.0, width:449.0, height:318.0, depth:0.0, maxX:486.0, maxY:333.0, maxZ:0.0]

The first output line comes from the initialize() method, the second line from the first call of updateMarker() (first mouseclick on the graph) and the third line from the second call of updateMarker() (second mouseclick on the graph) which finally returns the correct bound values of the chart's background.

Now my question: How or when can I determine the correct size of the chart's background (best in the initialize() method)? I hope there's someone who can help, because I have no explanation for this behavior. Thank you!

Community
  • 1
  • 1
Horrorente
  • 314
  • 3
  • 13

0 Answers0