我正在处理一个应用程序,我需要将ObservableArrayList中的数据保存并加载到XML文件中。我为ObservableList创建了一个带有Double和Integer属性的模型类:
package application.Model;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleIntegerProperty;
@XmlRootElement
@XmlType(name = "Object", propOrder = {"diameter", "handeling", "aantal", "basisUren", "correctie", "toeslagUren", "totaalUren", "totaalMat", "totaal"})
public class Berekening {
private final SimpleIntegerProperty diameter;
private final SimpleIntegerProperty handeling;
private final SimpleIntegerProperty aantal;
private final SimpleDoubleProperty basisUren;
private final SimpleDoubleProperty correctie;
private final SimpleDoubleProperty toeslagUren;
private final SimpleDoubleProperty totaalUren;
private final SimpleDoubleProperty totaalMat;
private final SimpleDoubleProperty totaal;
public Berekening() {
this(null, null, null, null, null, null, null, null, null);
}
public Berekening(Integer diameter, Integer handeling, Integer aantal, Double basisUren, Double correctie, Double toeslagUren, Double totaalUren, Double totaalMat, Double totaal) {
this.diameter = new SimpleIntegerProperty(diameter);
this.handeling = new SimpleIntegerProperty(handeling);
this.aantal = new SimpleIntegerProperty(aantal);
this.basisUren = new SimpleDoubleProperty(basisUren);
this.correctie = new SimpleDoubleProperty(correctie);
this.toeslagUren = new SimpleDoubleProperty(toeslagUren);
this.totaalUren = new SimpleDoubleProperty(totaalUren);
this.totaalMat = new SimpleDoubleProperty(totaalMat);
this.totaal = new SimpleDoubleProperty(totaal);
}
@XmlElement (name = "value1", required = false)
public Integer getDiameter() {
return diameter.get();
}
public void setDiameter(int diameter) {
this.diameter.set(diameter);
}
public IntegerProperty diameterProperty(){
return diameter;
}
@XmlElement (name = "value2", required = false)
public Integer getHandeling() {
return handeling.get();
}
public void setHandeling(int handeling) {
this.handeling.set(handeling);
}
public IntegerProperty handelingProperty(){
return handeling;
}
@XmlElement (name = "value3", required = false)
public Integer getAantal() {
return aantal.get();
}
public void setAantal(int aantal) {
this.aantal.set(aantal);
}
public IntegerProperty aantalProperty(){
return aantal;
}
@XmlElement (name = "value4", required = false)
public Double getBasisUren(){
return basisUren.get();
}
public void setBasisUren(double value) {
this.basisUren.set(value);
}
public DoubleProperty basisUrenProperty(){
return basisUren;
}
@XmlElement (name = "value5", required = false)
public Double getCorrectie(){
return correctie.get();
}
public void setCorrectie(double value) {
this.correctie.set(value);
}
public DoubleProperty correctieProperty(){
return correctie;
}
@XmlElement (name = "value6", required = false)
public Double getToeslagUren(){
return toeslagUren.get();
}
public void setToeslagUren(double value) {
this.toeslagUren.set(value);
}
public DoubleProperty toeslagUrenProperty(){
return toeslagUren;
}
@XmlElement (name = "value7", required = false)
public Double getTotaalUren(){
return totaalUren.get();
}
public void setTotaalUren(double value) {
this.totaalUren.set(value);
}
public DoubleProperty totaalUrenProperty(){
return totaalUren;
}
@XmlElement (name = "value8", required = false)
public Double getTotaalMat(){
return totaalMat.get();
}
public void setTotaalMat(double value) {
this.totaalMat.set(value);
}
public DoubleProperty totaalMatProperty(){
return totaalMat;
}
@XmlElement (name = "value9", required = false)
public Double getTotaal(){
return totaal.get();
}
public void setTotaal(double value) {
this.totaal.set(value);
}
public DoubleProperty totaalProperty(){
return totaal;
}
}
这是列表类:
package application.Model;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
public class BerekeningList {
@XmlElement(name = "berekening")
List<Berekening> berekeningen = new ArrayList<>();
public List<Berekening> getBerekeningen() {
return berekeningen;
}
}
ListWrapper:
package application.Model;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import application.MainApp;
import application.Util.BerekeningListAdapter;
import javafx.collections.ObservableList;
@XmlRootElement (name = "Berekeningen")
public class BerekeningListWrapper{
private ObservableList<Berekening> berekening;
@XmlJavaTypeAdapter(BerekeningListAdapter.class)
public ObservableList<Berekening> getBerekeningen(){
return berekening;
}
public void setBerekenings(ObservableList<Berekening> berekenings) {
this.berekening = berekenings;
}
}
我使用此方法将数据保存到文件中:
public void saveBerekeningDataToFile(File file) {
try {
JAXBContext context = JAXBContext
.newInstance(BerekeningListWrapper.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
BerekeningListWrapper wrapper = new BerekeningListWrapper();
wrapper.setBerekenings(berekeningData);
m.marshal(wrapper, file);
setBerekeningFilePath(file);
} catch (Exception e) {
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("Error");
alert.setHeaderText("Could not save data");
alert.setContentText("Could not save data to file:\n" + file.getPath());
alert.showAndWait();
}
}
生成的xml文件(保存似乎工作正常):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Berekeningen>
<berekeningen>
<berekening value1="15" value2="5" value3="5" value4="1.25" value5="5.0" value6="6.25" value7="270.0" value8="30.0" value9="300.0"/>
</berekeningen>
问题是将数据加载回我的应用程序,我正在使用这种方法:
public void loadBerekeningDataFromFile(File file){
try {
JAXBContext context = JAXBContext
.newInstance(BerekeningListWrapper.class);
Unmarshaller um = context.createUnmarshaller();
BerekeningListWrapper wrapper = (BerekeningListWrapper)um.unmarshal(file);
berekeningData.clear();
berekeningData.addAll(wrapper.getBerekeningen());
setBerekeningFilePath(file);
} catch (Exception e){
e.printStackTrace();
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("Error");
alert.setHeaderText("Could not load data");
alert.setContentText("Could not load data from file:\n" + file.getPath());
alert.showAndWait();
}
}
导致以:
开头的堆栈跟踪 javax.xml.bind.UnmarshalException: Unable to create an instance of
application.Model.Berekening
etc
Caused by: java.lang.NullPointerException
at application.Model.Berekening.<init>(Berekening.java:32)
at application.Model.Berekening.<init>(Berekening.java:28)
... 84 more
因此,unmarshalexception是由模型类中的NullPointerException引起的:
this.diameter = new SimpleIntegerProperty(diameter);
and
this(null, null, null, null, null, null, null, null, null);
我不知道如何解决这个问题,我已经在StackOverflow上尝试了很多不同的教程和答案,但我没有发现任何问题。 非常感谢任何帮助!
答案 0 :(得分:1)
您无法使用SimpleIntegerProperty
初始化null
。 constructor you are calling需要int
,因此当您致电diameter.intValue()
时,new SimpleIntegerProperty(diameter)
会隐式调用(&#34;取消装箱&#34;)。显然,如果diameter
为null
,则会产生NullPointerException
。
使数值类型的默认值为非null:
public Berekening() {
this(0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
}
例如,。
如果你真的需要支持空值(这是一个不太优选的选项,imho),请使用ObjectProperty
代替IntegerProperty
和DoubleProperty
:
public class Berekening {
private final ObjectProperty<Integer> diameter;
private final ObjectProperty<Integer> handeling;
private final ObjectProperty<Integer> aantal;
private final ObjectProperty<Double> basisUren;
private final ObjectProperty<Double> correctie;
private final ObjectProperty<Double> toeslagUren;
private final ObjectProperty<Double> totaalUren;
private final ObjectProperty<Double> totaalMat;
private final ObjectProperty<Double> totaal;
public Berekening() {
this(null, null, null, null, null, null, null, null, null);
}
public Berekening(Integer diameter, Integer handeling, Integer aantal, Double basisUren, Double correctie, Double toeslagUren, Double totaalUren, Double totaalMat, Double totaal) {
this.diameter = new SimpleObjectProperty<>(diameter);
this.handeling = new SimpleObjectProperty<>(handeling);
this.aantal = new SimpleObjectProperty<>(aantal);
this.basisUren = new SimpleObjectProperty<>(basisUren);
this.correctie = new SimpleObjectProperty<>(correctie);
this.toeslagUren = new SimpleObjectProperty<>(toeslagUren);
this.totaalUren = new SimpleObjectProperty<>(totaalUren);
this.totaalMat = new SimpleObjectProperty<>(totaalMat);
this.totaal = new SimpleObjectProperty<>(totaal);
}
// ...
}