Я строю XYChart в JavaFX.Он содержит две серии (серии 1 и 2) и третью серию (серии 3), значения которых должны быть суммой серий 1 и 2.
Теперь серия 3 должна автоматически обновляться, если изменяются значения (добавляются, удаление, замена и т. д.) серии 1 или 2.
Каков наилучший способ добиться этого?
Заранее спасибо.
package lineChart;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;
public class LineChartSample extends Application {
@Override
public void start(Stage stage) {
final NumberAxis xAxis = new NumberAxis();
final NumberAxis yAxis = new NumberAxis();
final LineChart<Number, Number> lineChart = new LineChart<Number, Number>(xAxis, yAxis);
XYChart.Series series1 = new XYChart.Series();
series1.getData().add(new XYChart.Data(1, 10));
series1.getData().add(new XYChart.Data(10, 20));
series1.getData().add(new XYChart.Data(20, 30));
lineChart.getData().add(series1);
XYChart.Series series2 = new XYChart.Series();
series2.getData().add(new XYChart.Data(1, 20));
series2.getData().add(new XYChart.Data(10, 30));
series2.getData().add(new XYChart.Data(20, 40));
lineChart.getData().add(series2);
XYChart.Series series3 = new XYChart.Series();
// series3 = series1 + series2
series3.getData().add(new XYChart.Data(1, 10 + 20));
series3.getData().add(new XYChart.Data(10, 20 + 30));
series3.getData().add(new XYChart.Data(20, 30 + 40));
lineChart.getData().add(series3);
Scene scene = new Scene(lineChart, 800, 600);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Обновление 1 Я обновил примеркод.Если я запускаю этот код, серия 3 реагирует на добавление или удаление объектов данных из серии 1 или серии 2. Но, к сожалению, он не реагирует на изменение значений объектов данных.
import javafx.application.Application;
import javafx.collections.ListChangeListener;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.chart.XYChart.Data;
import javafx.stage.Stage;
public class LineChartSample extends Application {
private static int updateCounter = 1;
private XYChart.Series<Integer, Integer> series1, series2, series3;
@Override
public void start(Stage stage) {
final NumberAxis xAxis = new NumberAxis();
final NumberAxis yAxis = new NumberAxis();
final LineChart<Integer, Integer> lineChart = new LineChart(xAxis, yAxis);
series1 = new XYChart.Series<>();
series1.getData().add(new XYChart.Data(1, 10));
series1.getData().add(new XYChart.Data(10, 20));
series1.getData().add(new XYChart.Data(20, 30));
lineChart.getData().add(series1);
series2 = new XYChart.Series<>();
series2.getData().add(new XYChart.Data(1, 20));
series2.getData().add(new XYChart.Data(10, 30));
series2.getData().add(new XYChart.Data(20, 40));
lineChart.getData().add(series2);
series3 = new XYChart.Series<>();
lineChart.getData().add(series3);
bindDataSeieses();
Scene scene = new Scene(lineChart, 800, 600);
stage.setScene(scene);
stage.show();
// update 1
updateSumSeries();
// update 2
series1.getData().remove(0);
// update 3
series1.getData().add(new XYChart.Data(1, 50));
// No update :-(
series1.getData().get(0).setYValue(200);
}
private void bindDataSeieses() {
series1.getData().addListener((ListChangeListener<Data<Integer, Integer>>) c -> updateSumSeries());
series2.getData().addListener((ListChangeListener<Data<Integer, Integer>>) c -> updateSumSeries());
}
private void updateSumSeries() {
System.out.println("Update " + updateCounter++);
// todo enhance to support series of different length
if (series1.getData().size() != series2.getData().size())
return;
series3.getData().clear();
for (int index = 0; index < series1.getData().size(); index++) {
int xValue = series1.getData().get(index).getXValue();
int yValue = series1.getData().get(index).getYValue() + series2.getData().get(index).getYValue();
series3.getData().add(new Data<>(xValue, yValue));
}
}
public static void main(String[] args) {
launch(args);
}
}