我可以使用“包装器”类来编组ObservableList,如下所示。但是我不能将其解组回以前的wrapper类。
这个想法是:我有一个“支出”的ObservableList。我将此列表放入包装器类中,并将该类保存为XML。结果看起来像这样:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <List> <root> <category>[none]</category> <period>Year</period> <title>asd</title> <value>354</value> </root> </List>
我无法将其带回包装对象。我真的很感谢任何帮助。
主类JAXBContext(对所有人可见):
JAXBContext jc = JAXBContext.newInstance(MyWrapperForList.class, Expense.class);
主类SAVEBUTTON:
public class SaveButtonListener implements EventHandler<ActionEvent> { @Override public void handle(ActionEvent arg0) { File serializedFile = new File(PATH); try { if (serializedFile.exists() == false) serializedFile.createNewFile(); PrintWriter xmlOut = new PrintWriter(serializedFile); Marshaller m = jc.createMarshaller(); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); List<Expense> saveList = new ArrayList<>(); saveList.addAll(data); MyWrapperForList<Expense> wrapper = new MyWrapperForList<>(saveList); JAXBElement<MyWrapperForList> jaxbElement = new JAXBElement<>( new QName("List"), MyWrapperForList.class, wrapper); m.marshal(jaxbElement, xmlOut); xmlOut.flush(); xmlOut.close();
主类-LOADBUTTON:
public class LoadButtonListener implements EventHandler<ActionEvent> { @Override public void handle(ActionEvent arg0) { try { Unmarshaller unmarshaller = jc.createUnmarshaller(); StreamSource xml = new StreamSource(PATH); MyWrapperForList<Expense> unwrapper = unmarshaller.unmarshal(xml, MyWrapperForList.class).getValue(); List<Expense> tempList = new ArrayList<>(); tempList.addAll(unwrapper.getItems()); System.out.println(tempList.get(0).getTitle()); } catch (Exception e) { e.printStackTrace(); } } }
包装类:
公共类MyWrapperForList {
private List<Expense> list; public MyWrapperForList() { list = new ArrayList<>(); } public MyWrapperForList(List<Expense> expenses) { this.list = expenses; } @XmlAnyElement(lax=true) public List<Expense> getItems() { return list; }
}
费用等级:
@XmlRootElement(name =“ root”)公共类费用{
private String title; private String category; private String period; private String value; public Expense() {} //Default constructor is needed for XML-handling public Expense(String title, String value, String period, String category) { this.title = title; this.value = value; this.period = period; this.category = category; } @XmlElement(name = "title") public String getTitle() { return this.title; } @XmlElement(name = "category") public String getCategory() { return this.category; } @XmlElement(name = "period") public String getPeriod() { return this.period; } @XmlElement(name = "value") public String getValue() { return this.value; }
我从Blaise Doughan使用了本教程:http://blog.bdoughan.com/2012/11/creating- generic-list-wrapper-in-jaxb.html
如果要MyWrapperForList解组持有的实例,ObservableList则需要通过以下方式之一设置类。
MyWrapperForList
ObservableList
类型属性ObservableList
import javax.xml.bind.annotation.XmlAnyElement; import javafx.collections.*; public class MyWrapperForList<T> { private ObservableList<T> list; public MyWrapperForList() { list = FXCollections.<T>observableArrayList(); } public MyWrapperForList(ObservableList<T> list) { this.list = list; } @XmlAnyElement(lax = true) public ObservableList<T> getItems() { return list; } }
List 属性已初始化为的实例 ObservableList
List
import java.util.List; import javax.xml.bind.annotation.XmlAnyElement; import javafx.collections.*; public class MyWrapperForList<T> { private List<T> list = FXCollections.<T>observableArrayList(); public MyWrapperForList() { list = FXCollections.<T>observableArrayList(); } public MyWrapperForList(List<T> list) { this.list = list; } @XmlAnyElement(lax = true) public List<T> getItems() { return list; } }
输入(nub.xml)
<List> <root> <category>[none]</category> <period>Year</period> <title>dfg</title> <value>4</value> </root> <root> <category>[none]</category> <period>Year</period> <title>ROBO</title> <value>1234</value> </root> </List>
演示版
import java.util.List; import javax.xml.bind.JAXBContext; import javax.xml.bind.Unmarshaller; import javax.xml.transform.stream.StreamSource; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(MyWrapperForList.class, Expense.class); //UNMARSHALLING Unmarshaller unmarshaller = jc.createUnmarshaller(); StreamSource xml = new StreamSource("src/forum18594548/nub.xml"); MyWrapperForList<Expense> wrapper = (MyWrapperForList<Expense>) unmarshaller.unmarshal(xml, MyWrapperForList.class).getValue(); List<Expense> data = wrapper.getItems(); System.out.println(data.getClass()); for(Expense expense : data) { System.out.println(expense); } } }
输出量
class com.sun.javafx.collections.ObservableListWrapper forum18594548.Expense@789df61d forum18594548.Expense@4a8927c8
更新
第一:感谢您的工作,布莱斯!我为您对我所做的一切感到非常高兴!我尝试了您在这里写的内容(与我写的差不多),并且得到了与您类似的输出(相同类型)。但是列表中的对象全部用null引用。如果我写System.out.println(data.get(0).getTitle()); 它说空。列表中有确切数量的对象,但是所有属性均引用为null。:(
我想我在这ObservableList方面有了远见,只是想念您真正的问题是您如何映射Expense课程。由于只有get方法,因此应使用@XmlAccessorType(XmlAccessType.FIELD)以下方法映射到字段。
Expense
get
@XmlAccessorType(XmlAccessType.FIELD)
import javax.xml.bind.annotation.*; @XmlRootElement(name="root") @XmlAccessorType(XmlAccessType.FIELD) public class Expense { private String title; private String category; private String period; private String value; public Expense() { } public Expense(String title, String value, String period, String category) { this.title = title; this.value = value; this.period = period; this.category = category; } public String getTitle() { return this.title; } public String getCategory() { return this.category; } public String getPeriod() { return this.period; } public String getValue() { return this.value; } }