1

I have an FXML file chart.fxml and a Controller class Controller.java for that FXML file. I wanted to make a LineChart using SceneBuilder, and initialize its data using a Controller.

However, when I run my program, the LineChart has no data/just shows the default LineChart.

This is my Controller.java class:

package exercise;

import javafx.fxml.FXML;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;

import java.util.HashMap;
import java.util.Map;

public class Controller {

    @FXML
    private LineChart<Number, Number> lineChart;

    void initData() {
        Map<Integer, Integer> map = initMap();
        NumberAxis x = new NumberAxis(
                map.entrySet().stream()
                        .min((p1, p2) -> p2.getKey() - p1.getKey())
                        .get()
                        .getKey(),
                map.entrySet().stream()
                        .min((p1, p2) -> p2.getKey() - p1.getKey())
                        .get()
                        .getValue(), 4
        );
        NumberAxis y = new NumberAxis();
        x.setLabel("Year");
        y.setLabel("Ranking");
        this.lineChart = new LineChart<>(x, y);
        this.lineChart.setTitle("Chart");

        XYChart.Series data = new XYChart.Series();
        data.setName("Ranks");
        map.forEach((key, value) -> data.getData().add(new XYChart.Data(key, value)));

        lineChart.getData().add(data);
    }

    private HashMap<Integer, Integer> initMap() {
        HashMap<Integer, Integer> values = new HashMap<>();
        values.put(2007, 73);
        values.put(2008, 68);
        values.put(2009, 72);
        values.put(2010, 72);
        values.put(2011, 74);
        values.put(2012, 73);
        values.put(2013, 76);
        values.put(2014, 73);
        values.put(2015, 67);
        values.put(2016, 56);
        values.put(2017, 56);
        return values;
    }
}

This is my Main class:

package exercise;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;

public class Main extends Application {

    @Override
    public void start(Stage window) throws IOException {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/chart.fxml"));
        window.setScene(new Scene(loader.load()));

        Controller controller = loader.getController();
        controller.initData();
        window.show();
    }

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

How do I fix this?

noodles888
  • 31
  • 5
  • Have you mentioned the controller in the `fxml` file? – AKSingh Oct 26 '21 at 12:51
  • @AKSingh Yes, the fx:controller on my FXML file is set to `exercise.Controller`. – noodles888 Oct 26 '21 at 12:53
  • 2
    Don’t create a new `LineChart` in `initData()`. Just use the one injected from the FXML. If you need access to the axes, define those in the FXML and inject them to the controller too. – James_D Oct 26 '21 at 13:09
  • 2
    Add the fxml to the question formatted as code. – jewelsea Oct 26 '21 at 13:20
  • 1
    Seems to be a duplicate of [all the duplicates listed here](https://stackoverflow.com/questions/69721937/problem-loading-webpage-in-javafx-application-creating-simple-browser). – jewelsea Oct 26 '21 at 13:21
  • @James_D I see. Another question, the `NumberAxis` for my xAxis in my `LineChart` also accepts values for its constructor which are the lowerBound, upperBound, and tickUnit. How do I also set values for the NumberAxis constructor? – noodles888 Oct 27 '21 at 02:53
  • 1
    There's nothing special about it; just treat it the same way as everything else. Either in FXML: `` or do it in the `initialize()` method in the controller: `` and `xAxis.setLowerBound(...);` etc. – James_D Oct 27 '21 at 02:57
  • @James_D I added the `lowerBound="2007"`, `upperBound="2017"`, and `tickUnit="4"` on my FXML file, but whenever I run try program, the line is fixed on a single position https://snipboard.io/ZEq3p4.jpg – noodles888 Oct 27 '21 at 03:27
  • 1
    With those bounds, you probably want `forceZeroInRange="false"` as well. – James_D Oct 27 '21 at 03:31
  • @James_D That fixed it. Thank you very much! – noodles888 Oct 27 '21 at 03:33

0 Answers0