2016-09-13 23 views
1

JavaFX TreeViewをJSONにエクスポートする方法を探しています。このプロセス全体を簡単にするために、私はGSONを使用します。 TreeItemの値をエクスポートしていますが、ツリー全体を使用しようとするとスタックのオーバーフローが発生します。私はこれが親子属性と関係していると信じています。 GSONがこの属性をエクスポートしないようにする方法はありますか?JavaFX TreeView JSON Ex/GSON経由でのインポート

また、全体をもう一度インポートするにはどうすればよいですか。私はGSONがプロパティを扱うことができないので、私の単純なオブジェクトをインポートすることができませんでした。

+0

も参照してください:http://stackoverflow.com/q/40196602/59087 –

答えて

1

カスタムタイプのアダプタを使用する必要があります。さらに、あなたの代わりに再帰のループを使用してstackoverflowsを防ぐことができます。

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; 
    } 

} 
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(); 
} 
関連する問題