I need to show a json file on a javafx treeview,the structure of the json is unknown.Like the web site: json viewer site I show the tree for user to select path of a value(like xpath of xml),so if the json is too big,I only need to show the first element of any array in json.
for example,the original data is:
{
name:"tom",
schools:[
{
name:"school1",
tags:["maths","english"]
},
{
name:"school2",
tags:["english","biological"]
},
]
}
I want to show:

again:the structure of json is unknown,it is just one example.
There's no other option than recursively handling the json and create the TreeItem structure based on the element info.
(There's probably a better way of adding the symbols, but I didn't find appropriate icons.)
private static final String INPUT = "{\n"
+ " name:\"tom\",\n"
+ " schools:[\n"
+ " {\n"
+ " name:\"school1\",\n"
+ " tags:[\"maths\",\"english\"]\n"
+ " },\n"
+ " {\n"
+ " name:\"school2\",\n"
+ " tags:[\"english\",\"biological\"]\n"
+ " },\n"
+ " ]\n"
+ "}";
private static final Image JSON_IMAGE = new Image("https://i.sstatic.net/1slrh.png");
private static void prependString(TreeItem<Value> item, String string) {
String val = item.getValue().text;
item.getValue().text = (val == null
? string
: string + " : " + val);
}
private enum Type {
OBJECT(new Rectangle2D(45, 52, 16, 18)),
ARRAY(new Rectangle2D(61, 88, 16, 18)),
PROPERTY(new Rectangle2D(31, 13, 16, 18));
private final Rectangle2D viewport;
private Type(Rectangle2D viewport) {
this.viewport = viewport;
}
}
private static final class Value {
private String text;
private final Type type;
public Value(Type type) {
this.type = type;
}
public Value(String text, Type type) {
this.text = text;
this.type = type;
}
}
private static TreeItem<Value> createTree(JsonElement element) {
if (element.isJsonNull()) {
return new TreeItem<>(new Value("null", Type.PROPERTY));
} else if (element.isJsonPrimitive()) {
JsonPrimitive primitive = element.getAsJsonPrimitive();
return new TreeItem<>(new Value(primitive.isString()
? '"' + primitive.getAsString() + '"'
: primitive.getAsString(), Type.PROPERTY));
} else if (element.isJsonArray()) {
JsonArray array = element.getAsJsonArray();
TreeItem<Value> item = new TreeItem<>(new Value(Type.ARRAY));
// for (int i = 0, max = Math.min(1, array.size()); i < max; i++) {
for (int i = 0, max = array.size(); i < max; i++) {
TreeItem<Value> child = createTree(array.get(i));
prependString(child, Integer.toString(i));
item.getChildren().add(child);
}
return item;
} else {
JsonObject object = element.getAsJsonObject();
TreeItem<Value> item = new TreeItem<>(new Value(Type.OBJECT));
for (Map.Entry<String, JsonElement> property : object.entrySet()) {
TreeItem<Value> child = createTree(property.getValue());
prependString(child, property.getKey());
item.getChildren().add(child);
}
return item;
}
}
@Override
public void start(Stage primaryStage) {
JsonParser parser = new JsonParser();
JsonElement root = parser.parse(INPUT);
TreeItem<Value> treeRoot = createTree(root);
TreeView<Value> treeView = new TreeView<>(treeRoot);
treeView.setCellFactory(tv -> new TreeCell<Value>() {
private final ImageView imageView;
{
imageView = new ImageView(JSON_IMAGE);
imageView.setFitHeight(18);
imageView.setFitWidth(16);
imageView.setPreserveRatio(true);
setGraphic(imageView);
}
@Override
protected void updateItem(Value item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText("");
imageView.setVisible(false);
} else {
setText(item.text);
imageView.setVisible(true);
imageView.setViewport(item.type.viewport);
}
}
});
final Scene scene = new Scene(treeView);
primaryStage.setScene(scene);
primaryStage.show();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With