我正在编写一个程序,其中饼图中的按钮单击数据旋转(10-12 点钟方向的切片移动到 12-2 等)。下面的代码(有点)有效,它会旋转,但会吃掉临时切片并产生整段错误。这是我第一次尝试 JavaFX,我不确定如何管理它。
private BorderPane layout;
private Scene scene;
ObservableList<PieChart.Data> pieChartData =
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));
PieChart chart = new PieChart(pieChartData);
@Override public void start(Stage stage) {
layout = new BorderPane();
scene = new Scene(layout,720,480);
stage.setTitle("People");
stage.setWidth(500);
stage.setHeight(500);
Button button = new Button();
button.setText("rotate");
layout.setBottom(button);
layout.setCenter(chart);
button.setOnAction(e -> {
rotate();
});
chart.setStartAngle(90);
chart.setTitle("Economical age groups");
stage.setScene(scene);
stage.show();
}
public void 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);
}
Run Code Online (Sandbox Code Playgroud)
这是堆栈跟踪:
Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: Children: duplicate children added: parent = Chart$1@5cfeee33[styleClass=chart-content]
at javafx.graphics/javafx.scene.Parent$3.onProposedChange(Parent.java:558)
at javafx.base/com.sun.javafx.collections.VetoableListDecorator.add(VetoableListDecorator.java:206)
at javafx.controls/javafx.scene.chart.PieChart.dataItemAdded(PieChart.java:417)
at javafx.controls/javafx.scene.chart.PieChart.lambda$new$0(PieChart.java:168)
at javafx.base/com.sun.javafx.collections.ListListenerHelper$SingleChange.fireValueChangedEvent(ListListenerHelper.java:164)
at javafx.base/com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.base/javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.base/javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
at javafx.base/javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
at javafx.base/javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
at javafx.base/javafx.collections.ModifiableObservableListBase.add(ModifiableObservableListBase.java:155)
at task.Main.rotate(Main.java:54)
at task.Main.lambda$start$0(Main.java:39)
(...and so on)
Run Code Online (Sandbox Code Playgroud)
JavaFX 图表支持添加、删除或更新数据时的动画。但是,当启用动画时,用于实际显示数据的节点在动画完成之前不会从图表中删除 - 这不是公开可见的。这意味着您不能PieChart.Data像您目前所做的那样,只删除 a然后立即重新添加它。尝试这样做会导致尝试将 a 添加Node到 aParent时,当 saidNode仍然当前是 said 的孩子时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);
Run Code Online (Sandbox Code Playgroud)
两者pieChartDataTemp和pieChartData指代相同ObservableList。因此,当您tempData在0索引处添加时,您实际上是将元素添加到当前元素,PieChart而它仍然存在于size() - 1索引处。我试图通过交换add和remove调用来解决这个问题,但这并没有解决问题——这就是我发现动画阻碍的原因。
您还可以创建一个新的PieChart并替换旧的。这不是必需的,假设我正确理解你想要做什么。它也可能会导致问题,因为您ObservableList对每个PieChart.
至少有两种解决方案。
一种解决方法是简单地禁用动画:
yourPieChart.setAnimated(false);
Run Code Online (Sandbox Code Playgroud)
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();
}
}
Run Code Online (Sandbox Code Playgroud)
旋转代码位于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()));
});
Run Code Online (Sandbox Code Playgroud)
注意我没有创建另一个PieChart.
| 归档时间: |
|
| 查看次数: |
273 次 |
| 最近记录: |