JavaFX TreeView JSON Ex/通过GSON导入
我正在寻找一种将JavaFXTreeView导出为JSON的方法。为了简化整个过程,我使用了GSON。它可以很好地导出树元素的值,但是当我尝试使用整个树时,它的结尾是堆栈溢出。我相信这与父/子属性有关。是否有方法阻止GSON导出此属性JavaFX TreeView JSON Ex/通过GSON导入,java,json,javafx,treeview,gson,Java,Json,Javafx,Treeview,Gson,我正在寻找一种将JavaFXTreeView导出为JSON的方法。为了简化整个过程,我使用了GSON。它可以很好地导出树元素的值,但是当我尝试使用整个树时,它的结尾是堆栈溢出。我相信这与父/子属性有关。是否有方法阻止GSON导出此属性 我该如何再次导入整个内容?我无法导入我的简单对象,因为GSON无法处理属性。您需要使用自定义类型适配器。此外,您可以通过使用循环而不是递归来防止堆栈溢出: public class TreeItemTypeAdapter<T> extends Type
我该如何再次导入整个内容?我无法导入我的简单对象,因为GSON无法处理属性。您需要使用自定义类型适配器。此外,您可以通过使用循环而不是递归来防止堆栈溢出:
public class TreeItemTypeAdapter<T> extends TypeAdapter<TreeItem<T>> {
private Gson gson;
public void setGson(Gson gson) {
this.gson = gson;
}
private final Class<T> valueClass;
public TreeItemTypeAdapter(Class<T> valueClass) {
if (valueClass == null) {
throw new IllegalArgumentException();
}
this.valueClass = valueClass;
}
public static TreeItemTypeAdapter<String> createStringTreeItemAdapter() {
return new TreeItemTypeAdapter<>(String.class);
}
private void writeValue(JsonWriter writer, T t) throws IOException {
if (gson == null) {
writer.value(Objects.toString(t, null));
} else {
gson.toJson(t, valueClass, writer);
}
}
private T readValue(JsonReader reader) throws IOException {
if (gson == null) {
Object value = reader.nextString();
return (T) value;
} else {
return gson.fromJson(reader, valueClass);
}
}
@Override
public void write(JsonWriter writer, TreeItem<T> t) throws IOException {
writer.beginObject().name("value");
writeValue(writer, t.getValue());
writer.name("children").beginArray();
LinkedList<Iterator<TreeItem<T>>> iterators = new LinkedList<>();
iterators.add(t.getChildren().iterator());
while (!iterators.isEmpty()) {
Iterator<TreeItem<T>> last = iterators.peekLast();
if (last.hasNext()) {
TreeItem<T> ti = last.next();
writer.beginObject().name("value");
writeValue(writer, ti.getValue());
writer.name("children").beginArray();
iterators.add(ti.getChildren().iterator());
} else {
writer.endArray().endObject();
iterators.pollLast();
}
}
}
@Override
public TreeItem<T> read(JsonReader reader) throws IOException {
if (gson == null && !valueClass.getName().equals("java.lang.String")) {
throw new IllegalStateException("cannot parse classes other than String without gson provided");
}
reader.beginObject();
if (!"value".equals(reader.nextName())) {
throw new IOException("value expected");
}
TreeItem<T> root = new TreeItem<>(readValue(reader));
TreeItem<T> item = root;
if (!"children".equals(reader.nextName())) {
throw new IOException("children expected");
}
reader.beginArray();
int depth = 1;
while (depth > 0) {
if (reader.hasNext()) {
reader.beginObject();
if (!"value".equals(reader.nextName())) {
throw new IOException("value expected");
}
TreeItem<T> newItem = new TreeItem<>(readValue(reader));
item.getChildren().add(newItem);
item = newItem;
if (!"children".equals(reader.nextName())) {
throw new IOException("children expected");
}
reader.beginArray();
depth++;
} else {
depth--;
reader.endArray();
reader.endObject();
item = item.getParent();
}
}
return root;
}
}
公共类TreeItemTypeAdapter扩展了TypeAdapter{
私人Gson;
公共无效设置(Gson Gson){
this.gson=gson;
}
私有最终类valueClass;
public TreeItemTypeAdapter(类值类){
如果(valueClass==null){
抛出新的IllegalArgumentException();
}
this.valueClass=valueClass;
}
公共静态树类型适配器createStringTreeItemAdapter(){
返回新的TreeItemTypeAdapter(String.class);
}
私有void writeValue(JsonWriter writer,T)抛出IOException{
if(gson==null){
writer.value(Objects.toString(t,null));
}否则{
toJson(t,valueClass,writer);
}
}
私有T readValue(JsonReader)引发IOException{
if(gson==null){
对象值=reader.nextString();
返回(T)值;
}否则{
返回gson.fromJson(读取器,valueClass);
}
}
@凌驾
public void write(JsonWriter writer,TreeItem t)引发IOException{
writer.beginObject().name(“值”);
writeValue(writer,t.getValue());
writer.name(“children”).beginArray();
LinkedList迭代器=新建LinkedList();
add(t.getChildren().iterator());
而(!iterators.isEmpty()){
迭代器last=迭代器.peek last();
if(last.hasNext()){
TreeItem ti=last.next();
writer.beginObject().name(“值”);
writeValue(writer,ti.getValue());
writer.name(“children”).beginArray();
迭代器.add(ti.getChildren().iterator());
}否则{
writer.endArray().endObject();
iterators.pollLast();
}
}
}
@凌驾
public TreeItem read(JsonReader reader)引发IOException{
if(gson==null&&!valueClass.getName().equals(“java.lang.String”)){
抛出新的IllegalStateException(“在未提供gson的情况下无法解析字符串以外的类”);
}
reader.beginObject();
如果(!“value”.equals(reader.nextName())){
抛出新IOException(“预期值”);
}
TreeItem root=newtreeitem(readValue(reader));
TreeItem项目=根;
if(!“children.equals(reader.nextName())){
抛出新IOException(“预期的子项”);
}
reader.beginArray();
int深度=1;
而(深度>0){
if(reader.hasNext()){
reader.beginObject();
如果(!“value”.equals(reader.nextName())){
抛出新IOException(“预期值”);
}
TreeItem newItem=newtreeitem(readValue(reader));
item.getChildren().add(newItem);
项目=新项目;
if(!“children.equals(reader.nextName())){
抛出新IOException(“预期的子项”);
}
reader.beginArray();
深度++;
}否则{
深度--;
reader.endArray();
reader.endObject();
item=item.getParent();
}
}
返回根;
}
}
publicstaticvoidmain(字符串[]args){
TreeItem ti=新TreeItem(“你好世界”);
TreeItem ti2=新的TreeItem(“42”);
TreeItem ti3=新TreeItem(“Foo”);
TreeItem ti4=新的TreeItem(“条形”);
ti.getChildren().addAll(ti2,ti3);
ti2.getChildren().add(ti4);
TreeItemTypeAdapter=新的TreeItemTypeAdapter(String.class);
Gson Gson=new GsonBuilder().registerTypeAdapter(TreeItem.class,adapter).create();
适配器。setGson(gson);
System.out.println(gson.toJson(ti));
System.out.println(toString(gson.fromJson(“{\'value\”:\'Hello world\”,\'children\”:[{\'value\”:\'42\,\'children\”:[{\'value\”:\'Bar\,\'children\:[]},{\'value\:\'Foo\,\'children\:[]},
TreeItem.class));
}
私有静态字符串到字符串(TreeItem ti){
StringBuilder sb=new StringBuilder(“TreeItem[value:\”).append(ti.getValue()).append(“\”子项[”);
布尔notFirst=false;
for(TreeItem i:(List)ti.getChildren(){
如果(不是第一个){
某人加上(“,”);
}否则{
notFirst=true;
}
某人附加(toString(i));
}
返回sb.append(“]]”);
}
public static void main(String[] args) {
TreeItem<String> ti = new TreeItem<>("Hello world");
TreeItem<String> ti2 = new TreeItem<>("42");
TreeItem<String> ti3 = new TreeItem<>("Foo");
TreeItem<String> ti4 = new TreeItem<>("Bar");
ti.getChildren().addAll(ti2, ti3);
ti2.getChildren().add(ti4);
TreeItemTypeAdapter<String> adapter = new TreeItemTypeAdapter<>(String.class);
Gson gson = new GsonBuilder().registerTypeAdapter(TreeItem.class, adapter).create();
adapter.setGson(gson);
System.out.println(gson.toJson(ti));
System.out.println(toString(gson.fromJson("{\"value\":\"Hello world\",\"children\":[{\"value\":\"42\",\"children\":[{\"value\":\"Bar\",\"children\":[]}]},{\"value\":\"Foo\",\"children\":[]}]}",
TreeItem.class)));
}
private static String toString(TreeItem ti) {
StringBuilder sb = new StringBuilder("TreeItem [ value: \"").append(ti.getValue()).append("\" children [");
boolean notFirst = false;
for (TreeItem i : (List<TreeItem>) ti.getChildren()) {
if (notFirst) {
sb.append(",");
} else {
notFirst = true;
}
sb.append(toString(i));
}
return sb.append("]]").toString();
}