我有一个带有一些复选框的AreaChart,可以选择要在AreaChart上显示的系列。问题是我有此错误:

Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: Duplicate series added


这是3个复选框之一更改其值时执行的代码。

   /**AreaChart<Integer,Double> multipleGraphic;
        * CheckBox HeartRateCheck,PedalingRateCheck,AverageSpeedCheck;
        * XYChart.Series AvSpeed = new XYChart.Series();
        * XYChart.Series Cadence = new XYChart.Series();
        * XYChart.Series HeartRate = new XYChart.Series();
        **/


    private void setMultiGraph() {

            multipleGraphic.getData().removeAll(multipleGraphic.getData());
            multipleGraphic.getData().clear();

            if (HeartRateCheck.isSelected() && PedalingRateCheck.isSelected() && AverageSpeedCheck.isSelected()) {
                multipleGraphic.getData().addAll(AvSpeed, Cadence, HeartRate);
            }

            if (!HeartRateCheck.isSelected() && PedalingRateCheck.isSelected() && AverageSpeedCheck.isSelected()) {

                multipleGraphic.getData().addAll(AvSpeed, Cadence);
            }
            if (HeartRateCheck.isSelected() && !PedalingRateCheck.isSelected() && AverageSpeedCheck.isSelected()) {

                multipleGraphic.getData().addAll(AvSpeed, HeartRate);
            }
            if (HeartRateCheck.isSelected() && PedalingRateCheck.isSelected() && !AverageSpeedCheck.isSelected()) {

                multipleGraphic.getData().addAll(Cadence, HeartRate);
            }

            if (!HeartRateCheck.isSelected() && !PedalingRateCheck.isSelected() && AverageSpeedCheck.isSelected()) {

                multipleGraphic.getData().addAll(AvSpeed);
            }
            if (!HeartRateCheck.isSelected() && PedalingRateCheck.isSelected() && !AverageSpeedCheck.isSelected()) {

                multipleGraphic.getData().addAll(Cadence);
            }
            if (HeartRateCheck.isSelected() && !PedalingRateCheck.isSelected() && !AverageSpeedCheck.isSelected()) {

                multipleGraphic.getData().addAll(HeartRate);
            }
        }


Image of the AreaChart with the 3 CheckBoxes

谢谢。

最佳答案

使用复选框选中的属性更改侦听器可以根据需要在图形中添加或删除序列。

private void addSeriesListener(BooleanProperty selected, final XYChart.Series series) {
    selected.addListener((observable, wasSelected, isSelected) -> {
        if (isSelected) {
            chart.getData().add(series);
        } else {
            chart.getData().remove(series);
        }
    });
}
. . .
addSeriesListener(heartRateCheck.selectedProperty(), heartRateSeries);
addSeriesListener(cadenceCheck.selectedProperty(), cadenceSeries);
addSeriesListener(speedCheck.selectedProperty(), speedSeries);


java - Javafx上每个系列的带复选框的AreaCharts-LMLPHP

完整示例应用

import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.collections.*;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.chart.*;
import javafx.scene.control.CheckBox;
import javafx.scene.layout.*;
import javafx.stage.Stage;

import java.util.Random;

public class AreaChartSample extends Application {
    private static final String HEART_RATE = "Heart Rate";
    private static final String PEDALING_RATE = "Pedaling Rate";
    private static final String AVERAGE_SPEED = "Average Speed";

    private Random random = new Random(42);

    private NumberAxis xAxis = new NumberAxis();
    private NumberAxis yAxis = new NumberAxis();
    private AreaChart<Number, Number> chart = new AreaChart<>(xAxis, yAxis);

    private XYChart.Series<Integer, Double> heartRateSeries = new XYChart.Series<>(
            HEART_RATE, randomData(10)
    );
    private XYChart.Series<Integer, Double> cadenceSeries = new XYChart.Series<>(
            PEDALING_RATE, randomData(50)
    );
    private XYChart.Series<Integer, Double> speedSeries = new XYChart.Series<>(
            AVERAGE_SPEED, randomData(100)
    );

    private CheckBox heartRateCheck = new CheckBox(HEART_RATE);
    private CheckBox cadenceCheck = new CheckBox(PEDALING_RATE);
    private CheckBox speedCheck = new CheckBox(AVERAGE_SPEED);

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

    @Override
    public void start(Stage stage) {
        HBox controls = new HBox(10, heartRateCheck, cadenceCheck, speedCheck);
        addSeriesListener(heartRateCheck.selectedProperty(), heartRateSeries);
        addSeriesListener(cadenceCheck.selectedProperty(), cadenceSeries);
        addSeriesListener(speedCheck.selectedProperty(), speedSeries);
        heartRateCheck.selectedProperty().set(true);
        cadenceCheck.selectedProperty().set(true);
        speedCheck.selectedProperty().set(true);

        chart.setTitle("Cycling");
        VBox layout = new VBox(10, chart, controls);
        layout.setPadding(new Insets(10));
        controls.setAlignment(Pos.CENTER);

        stage.setScene(new Scene(layout));
        stage.show();
    }

    private ObservableList<XYChart.Data<Integer, Double>> randomData(
            double offset
    ) {
        ObservableList<XYChart.Data<Integer, Double>> data = FXCollections.observableArrayList();

        for (int x = 0; x < 225; x++) {
            double y = random.nextDouble() * 30 + offset;
            data.add(new XYChart.Data<>(x, y));
        }

        return data;
    }

    @SuppressWarnings("unchecked")
    private void addSeriesListener(BooleanProperty selected, final XYChart.Series series) {
        selected.addListener((observable, wasSelected, isSelected) -> {
            if (isSelected) {
                chart.getData().add(series);
            } else {
                chart.getData().remove(series);
            }
        });
    }
}

关于java - Javafx上每个系列的带复选框的AreaCharts,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37038372/

10-10 14:56