2

I have an application with checkBox and 2 animated charts: Pie and Bar charts. When checkBox is checked, method which adds new data to a chart is fired. When checkBox is *un*checked, method which removes data from a chart is fired.

Everything is ok when i click a checkbox not very fast. But if i'll click checkbox again before its animation is finished, i recieve this one error:

 java.lang.NullPointerException
at javafx.scene.chart.PieChart$7.handle(PieChart.java:370)
at javafx.scene.chart.PieChart$7.handle(PieChart.java:367)
at   com.sun.scenario.animation.shared.TimelineClipCore.visitKeyFrame(TimelineClipCore.java:217)
at com.sun.scenario.animation.shared.TimelineClipCore.playTo(TimelineClipCore.java:158)
at javafx.animation.Timeline.impl_playTo(Timeline.java:182)
at com.sun.scenario.animation.shared.SingleLoopClipEnvelope.timePulse(SingleLoopClipEnvelope.java:119)
at javafx.animation.Animation.impl_timePulse(Animation.java:953)
at com.sun.scenario.animation.shared.AnimationPulseReceiver.timePulse(AnimationPulseReceiver.java:117)
at com.sun.scenario.animation.AbstractMasterTimer.timePulseImpl(AbstractMasterTimer.java:366)
at com.sun.scenario.animation.AbstractMasterTimer$MainLoop.run(AbstractMasterTimer.java:289)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:454)
at com.sun.javafx.tk.quantum.QuantumToolkit$8.run(QuantumToolkit.java:325)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:29)
at com.sun.glass.ui.win.WinApplication$2$1.run(WinApplication.java:62)
at java.lang.Thread.run(Unknown Source)

And this all happens only with PieChart. BarChart works normally.

Here is a method for checkBox onAction event:

  public void OnCheckFired(ActionEvent event) {
    Boolean b = checkBox.isSelected();
    chart.modifyChart(currentChart,b);
}

Thant is a code, which is fired, for modification of pie chart:

@Override
public void makeModifications(Chart chart, Boolean b) {
    PieChart pie = (PieChart) chart;
    ObservableList<PieChart.Data> pieChartData = pie.getData();
    pieChartData = modify(b, pieChartData);
    pie.setData(pieChartData);
}

private ObservableList<Data> modify(Boolean b, ObservableList<PieChart.Data> pieChartData)  {
    if (b) {
        pieChartData.add(new PieChart.Data("newValue", 34));
    } else {
        int size = pieChartData.size() - 1;
        pieChartData.remove(size);
    }
    return pieChartData;
}
Victoria Agafonova
  • 2,048
  • 10
  • 33
  • 50

2 Answers2

2

Unfortunately you found a bug. I've filed it as http://javafx-jira.kenai.com/browse/RT-21783

Meanwhile as a workaround you can disable checkbox for a second after each click.

Sergey Grinev
  • 34,078
  • 10
  • 128
  • 141
2

I have modified the code attached to the bug issue which is Sergey mentioned in his answer. Replaced the button with checkbox that is being disabled while the animation is playing and extra half second when the animation finished. It behaves this way every time when the selection changed.

public class Tdesst extends Application {

    private void init(Stage primaryStage) {
        VBox root = new VBox();
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        final ObservableList<PieChart.Data> pieChartData = FXCollections.observableArrayList(
                new PieChart.Data("Sun", 20),
                new PieChart.Data("IBM", 12),
                new PieChart.Data("HP", 25),
                new PieChart.Data("Dell", 22),
                new PieChart.Data("Apple", 30));
        final PieChart chart = new PieChart(pieChartData);

        final CheckBox chkbox = new CheckBox("add/remove data");

        final Timeline animation = new Timeline(
                new KeyFrame(Duration.seconds(.5),
                new EventHandler<ActionEvent>() {
                    @Override public void handle(ActionEvent actionEvent) {
                        chkbox.setDisable(false);
                    }
                }));
        animation.setCycleCount(1);

        chkbox.selectedProperty().addListener(new ChangeListener<Boolean>() {

            @Override
            public void changed(ObservableValue<? extends Boolean> arg0, Boolean oldVal, Boolean newVal) {
                chkbox.setDisable(true);
                if (newVal) {
                    pieChartData.add(new PieChart.Data("newValue", 34));
                } else {
                    pieChartData.remove(pieChartData.size() - 1);
                }
                animation.play();
            }
        });

        root.getChildren().add(chart);
        root.getChildren().add(chkbox);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        init(primaryStage);
        primaryStage.show();
        primaryStage.setTitle(VersionInfo.getRuntimeVersion());
    }

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

Or you can totally disable animating by

chart.setAnimated(false);
Uluk Biy
  • 48,655
  • 13
  • 146
  • 153