Некоторые фоновые изображения
Диаграммы JavaFX поддерживают анимацию при добавлении, удалении или обновлении данных.Однако, когда анимация включена, узлы , используемые для фактического отображения данных , не удаляются с диаграммы до тех пор, пока анимация не завершится, что не является чем-то общедоступным.Это означает, что вы не можете просто удалить PieChart.Data
, а затем немедленно добавить его, как вы это делаете в настоящее время.Попытка сделать это приводит к попытке добавить Node
к Parent
, когда указанный Node
все еще является потомком указанного Parent
.Как говорится в IllegalArgumentException
, дубликаты детей запрещены .
Проблемы в вашем коде
У вас есть этот код (из #rotate()
):
ObservableList<PieChart.Data> pieChartDataTemp = pieChartData;
int sizeOne = pieChartDataTemp.size();
PieChart.Data tempData = pieChartDataTemp.get(sizeOne - 1);
pieChartDataTemp.add(0,tempData);
if (pieChartDataTemp.size() > sizeOne) {
pieChartDataTemp.remove(pieChartDataTemp.size() - 1);
}
PieChart chartTemp = new PieChart(pieChartDataTemp);
layout.setCenter(chartTemp);
chartTemp.setStartAngle(90);
И pieChartDataTemp
, и pieChartData
относятся к одному и тому же ObservableList
.Поэтому, когда вы добавляете tempData
в индекс 0
, вы фактически добавляете элемент к текущему PieChart
, пока он все еще присутствует в индексе size() - 1
.Я попытался исправить это, поменяв местами вызовы add
и remove
, но это не решило проблему - вот как я обнаружил, что анимация мешает.
Вы также создаете новый PieChart
и замените старую.Это не обязательно, если я правильно понимаю, что вы пытаетесь сделать.Это также может вызвать проблемы, поскольку вы используете один и тот же ObservableList
для каждого PieChart
.
Решения
Существует как минимум два решения.
Отключить анимацию
Одно из исправлений - просто отключить анимацию :
yourPieChart.setAnimated(false);
Скопировать PieChart.Data
Другой вариант - создать новыйPieChart.Data
от старого.Вот пример:
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.chart.PieChart;
import javafx.scene.control.Button;
import javafx.scene.control.Separator;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
private ObservableList<PieChart.Data> createChartData() {
return FXCollections.observableArrayList(
new PieChart.Data("Post-production age", 424236),
new PieChart.Data("Production age", 1030060),
new PieChart.Data("Production age2", 1030060),
new PieChart.Data("Production age3", 1030060),
new PieChart.Data("Pre-production age", 310319)
);
}
@Override
public void start(Stage primaryStage) {
PieChart chart = new PieChart(createChartData());
chart.setStartAngle(90.0);
Button rotateBtn = new Button("Rotate");
rotateBtn.setOnAction(event -> {
event.consume();
PieChart.Data removed = chart.getData().remove(chart.getData().size() - 1);
chart.getData().add(0, new PieChart.Data(removed.getName(), removed.getPieValue()));
});
VBox root = new VBox(10, rotateBtn, new Separator(), chart);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(20));
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
}
Код поворота находится в onAction
обработчике кнопки:
rotateBtn.setOnAction(event -> {
event.consume();
PieChart.Data removed = chart.getData().remove(chart.getData().size() - 1);
chart.getData().add(0, new PieChart.Data(removed.getName(), removed.getPieValue()));
});
Примечание. Я не создаю еще один PieChart
.