FULL PRODUCT VERSION :
java version "1.8.0_91"
Java(TM) SE Runtime Environment (build 1.8.0_91-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.91-b15, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 10.0.10586]
A DESCRIPTION OF THE PROBLEM :
in javafx.scene.chart.ScatterChart the dataProperty is an ObjectProperty of an Observable List, but it is possible (no compiler-error) to bind it to a ListProperty.
Changes in the bound ListProperty lead to exceptions while partly keeping working - ui is updated, but exception is thrown.
ui is updatet even for an unidirectional binding in wrong direction, which is not intended either.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
run the code below
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Application showing Chart and dot at (1,1), no Exception.
ACTUAL -
Application showing Chart and dot at (1,1), throwing NullPointerException
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at javafx.scene.chart.XYChart$2.invalidated(XYChart.java:195)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:111)
at javafx.beans.property.ObjectPropertyBase.access$000(ObjectPropertyBase.java:51)
at javafx.beans.property.ObjectPropertyBase$Listener.invalidated(ObjectPropertyBase.java:233)
at com.sun.javafx.binding.ListExpressionHelper$SingleInvalidation.fireValueChangedEvent(ListExpressionHelper.java:183)
at com.sun.javafx.binding.ListExpressionHelper.fireValueChangedEvent(ListExpressionHelper.java:109)
at javafx.beans.property.ListPropertyBase.fireValueChangedEvent(ListPropertyBase.java:200)
at javafx.beans.property.ListPropertyBase.lambda$new$29(ListPropertyBase.java:56)
at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
at javafx.collections.ModifiableObservableListBase.add(ModifiableObservableListBase.java:155)
at java.util.AbstractList.add(AbstractList.java:108)
at de.panbytes.playground.ChartPropertyBug.start(ChartPropertyBug.java:64)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package de.panbytes.playground;
import javafx.application.Application;
import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.ScatterChart;
import javafx.scene.chart.XYChart;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import java.util.ArrayList;
public class ChartPropertyBug extends Application {
public static void main(final String[] args) {
launch(args);
}
@Override
public void start(final Stage primaryStage) throws Exception {
final Series<Number, Number> series = new Series<>();
series.getData().add(new Data<>(1, 1));
final ObservableList<Series<Number, Number>> seriesList =
FXCollections.observableList(new ArrayList<>());
/*
* this doesn't work with correct binding
*/
final ListProperty<Series<Number, Number>> seriesProperty =
new SimpleListProperty<>(seriesList);
/*
* this works
*/
// final ObjectProperty<ObservableList<Series<Number, Number>>> seriesProperty =
// new SimpleObjectProperty<>(seriesList);
final XYChart<Number, Number> chart = new ScatterChart<>(new NumberAxis(), new NumberAxis());
/*
* correct binding
*/
chart.dataProperty().bind(seriesProperty);
/*
* inverted binding - works unexpectedly
*/
// seriesProperty.bind(chart.dataProperty());
/*
* modification
*/
seriesProperty.get().add(series);
final BorderPane root = new BorderPane(chart);
primaryStage.setScene(new Scene(root, 400, 400));
primaryStage.show();
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
using ObjectProperty (see source) or inverted binding (?!?)
java version "1.8.0_91"
Java(TM) SE Runtime Environment (build 1.8.0_91-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.91-b15, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 10.0.10586]
A DESCRIPTION OF THE PROBLEM :
in javafx.scene.chart.ScatterChart the dataProperty is an ObjectProperty of an Observable List, but it is possible (no compiler-error) to bind it to a ListProperty.
Changes in the bound ListProperty lead to exceptions while partly keeping working - ui is updated, but exception is thrown.
ui is updatet even for an unidirectional binding in wrong direction, which is not intended either.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
run the code below
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Application showing Chart and dot at (1,1), no Exception.
ACTUAL -
Application showing Chart and dot at (1,1), throwing NullPointerException
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at javafx.scene.chart.XYChart$2.invalidated(XYChart.java:195)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:111)
at javafx.beans.property.ObjectPropertyBase.access$000(ObjectPropertyBase.java:51)
at javafx.beans.property.ObjectPropertyBase$Listener.invalidated(ObjectPropertyBase.java:233)
at com.sun.javafx.binding.ListExpressionHelper$SingleInvalidation.fireValueChangedEvent(ListExpressionHelper.java:183)
at com.sun.javafx.binding.ListExpressionHelper.fireValueChangedEvent(ListExpressionHelper.java:109)
at javafx.beans.property.ListPropertyBase.fireValueChangedEvent(ListPropertyBase.java:200)
at javafx.beans.property.ListPropertyBase.lambda$new$29(ListPropertyBase.java:56)
at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
at javafx.collections.ModifiableObservableListBase.add(ModifiableObservableListBase.java:155)
at java.util.AbstractList.add(AbstractList.java:108)
at de.panbytes.playground.ChartPropertyBug.start(ChartPropertyBug.java:64)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package de.panbytes.playground;
import javafx.application.Application;
import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.ScatterChart;
import javafx.scene.chart.XYChart;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import java.util.ArrayList;
public class ChartPropertyBug extends Application {
public static void main(final String[] args) {
launch(args);
}
@Override
public void start(final Stage primaryStage) throws Exception {
final Series<Number, Number> series = new Series<>();
series.getData().add(new Data<>(1, 1));
final ObservableList<Series<Number, Number>> seriesList =
FXCollections.observableList(new ArrayList<>());
/*
* this doesn't work with correct binding
*/
final ListProperty<Series<Number, Number>> seriesProperty =
new SimpleListProperty<>(seriesList);
/*
* this works
*/
// final ObjectProperty<ObservableList<Series<Number, Number>>> seriesProperty =
// new SimpleObjectProperty<>(seriesList);
final XYChart<Number, Number> chart = new ScatterChart<>(new NumberAxis(), new NumberAxis());
/*
* correct binding
*/
chart.dataProperty().bind(seriesProperty);
/*
* inverted binding - works unexpectedly
*/
// seriesProperty.bind(chart.dataProperty());
/*
* modification
*/
seriesProperty.get().add(series);
final BorderPane root = new BorderPane(chart);
primaryStage.setScene(new Scene(root, 400, 400));
primaryStage.show();
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
using ObjectProperty (see source) or inverted binding (?!?)