简体   繁体   中英

How to pass data from java program to javafx application chart?

I am new to JavaFX but I am not new to Java. I have a big complex system that produces some results in a loop. What I am trying to achieve is to plot the results of each iteration on a JavaFX chart. I was doing this with no problem with the java jFreeChart libraries, but now I am trying to switch to JavaFX. Charts looks more fancy and I like the way style is handled. Anyway, I am struggling in trying to understand how to add points to a XYChart.Series object in a JavaFX application. All tutorials on the oracle website start with some fixed points that the application knows a-priori and they are added using something like:

`series.getData().add(new XYChart.Data(1, 23));`

But what I am trying to achieve is a bit different. In my case my application produces some results and as soon as they are produced (random time) I want to plot them on a chart. I launch a thread with the javafx.application.Application, but when I try to add some points to the Series object I get a java.lang.IllegalStateException: Not on FX application thread; currentThread = main java.lang.IllegalStateException: Not on FX application thread; currentThread = main exception. What is the correct way to pass data points to a JavaFX chart? I thought that the closest way to do this is to override the Event type, Event object and create a whole Event handling structure... but this looks way too complicated for the simple thing I am trying to archive! Can you please tell me, in your opinion, what is the best/simplest way for doing this?

EDIT: Here is some code for you to have a look and give me some advice:

public class Chart extends Application {

    private final static XYChart.Series series = new XYChart.Series();

    public static void addValue(double gen, double val) {
        series.getData().add(new XYChart.Data(gen, val));
    }

    @Override
    public void start(Stage primaryStage) {

        primaryStage.setTitle("Chart");

        final NumberAxis xAxis = new NumberAxis();
        final NumberAxis yAxis = new NumberAxis();

        final LineChart<Number,Number> lineChart = 
                new LineChart<Number,Number>(xAxis,yAxis);


        //defining training set series
        series.setName("Training");


        Scene scene = new Scene(lineChart, 800, 600);
        lineChart.getData().add(series);
        primaryStage.setScene(scene);

        primaryStage.show();

    }

}


class Launcher extends Thread {

    @Override
    public void run() {
        Application.launch(Chart.class);
    }

    public static void main(String[] args) throws InterruptedException {
        new Launcher().start();
        System.out.println("Now doing something else...");

        for (int i = 0; i < 1000; i++) {
            double trainValue = Math.random();
            Chart.addValue(i, trainValue);
            Thread.sleep(500);
        }
    }

}

to be sure that the code to add points to the chart is executed within the JavaFX thread you could add it into a Runnable-Object which gets executed on the JavaFX thread:

Platform.runLater(new Runnable() {
    @Override
    public void run() {
       // code to add points to the chart
    }
});

Hope this helps. Torsten

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM