如何使用线程将数据正确绘制到XYChart.Serie? (了JavaFx)

时间:2015-12-29 20:01:11

标签: multithreading javafx charts

在下面的代码中,如果取消注释此行:

series.getData().add(new XYChart.Data<>(dataValues[columnX], dataValues[columnY]));                 

将绘制数据,但会发生线程异常。

但如果取消注释这一行:

series.getData().add(new XYChart.Series<Number,Number>(data));

没有发生线程异常,但不会绘制图形。

private XYChart.Series plotLineSeries(String filename, String separator,
        String serieLabel, int columnX, int columnY) {
    XYChart.Series series = new XYChart.Series();
    ObservableList<XYChart.Data<Number, Number>> data = 
                        FXCollections.observableArrayList();

    series.setName(serieLabel);
    Task<Void> task;
    task = new Task<Void>() {
        @Override
        protected Void call() throws Exception {
            BufferedReader br = new BufferedReader(new FileReader(filename));
            String dataLine = br.readLine();                
            while(br.readLine()!=null){
                dataLine = br.readLine();
                final String[] dataValues = dataLine.split(separator);
                data.add(new XYChart.Data(dataValues[columnX],
                    dataValues[columnY]));        

                /* if uncommnent the line below the graph will be plotted, but a thread exception will occur */
                //series.getData().add(new XYChart.Data<>(dataValues[columnX], dataValues[columnY]));                    
            }      
            /*if uncomment the line below no thread exception occurs, but the graph will not be plotted */
            //series.getData().add(new XYChart.Series<Number,Number>(data));

            return null;
        }
    };
    Thread thread = new Thread(task);
    thread.setDaemon(true);
    thread.start();        
    return series;
}   

1 个答案:

答案 0 :(得分:1)

第一个失败是因为您正在从后台线程更新图表,并且如有详细记载,您只能从FX应用程序线程更改UI。

第二,我真的不明白应该做什么。您是要将新系列添加到数据点列表中吗?

创建数据列表并从call方法返回。然后在setOnSucceeded(...)处理程序中更新图表:

private XYChart.Series plotLineSeries(String filename, String separator,
        String serieLabel, int columnX, int columnY) {
    XYChart.Series<Number, Number> series = new XYChart.Series();

    series.setName(serieLabel);

    Task<List<XYChart.Data<Number, Number>>> task;
    task = new Task<List<XYChart.Data<Number, Number>>>() {
        @Override
        protected List<XYChart.Data<Number, Number>> call() throws Exception {
            BufferedReader br = new BufferedReader(new FileReader(filename));
            List<XYChart.Data<Number,Number>> chartData = new ArrayList<>();
            String dataLine ;                
            while((dataLine = br.readLine())!=null){
                final String[] dataValues = dataLine.split(separator);
                chartData.add(new XYChart.Data(Float.valueOf(dataValues[columnX]),
                    Float.valueOf(dataValues[columnY])));        

            }      

            return chartData;
        }
    };

    task.setOnSucceeded(e -> series.getData().addAll(task.getValue()));

    Thread thread = new Thread(task);
    thread.setDaemon(true);
    thread.start();        
    return series;
}