читать текстовый текст json из текстового файла и создавать древовидное представление содержимого в javafx scene builder [duplicate]

Виртуальные деструкторы полезны, когда вы можете удалить экземпляр производного класса с помощью указателя на базовый класс:

class Base 
{
    // some virtual methods
};

class Derived : public Base
{
    ~Derived()
    {
        // Do some important cleanup
    }
};

Здесь вы заметите, что я не объявлял деструктор базы virtual. Теперь давайте посмотрим на следующий фрагмент:

Base *b = new Derived();
// use b
delete b; // Here's the problem!

Поскольку деструктор базы не является virtual, а b является Base*, указывающим на объект Derived, delete b имеет неопределенное поведение :

delete b], если статический тип подлежащего удалению объекта отличается от его динамического типа, статический тип должен быть базовый класс динамического типа объекта, подлежащего удалению, и статический тип должен иметь виртуальный деструктор или поведение не определено.

blockquote>

В большинстве реализаций вызов деструктора будет разрешен как и любой не виртуальный код, что означает, что деструктор базового класса будет вызываться, но не тот, который был получен из производного класса, что приведет к утечке ресурсов.

Подводя итог, всегда создавайте деструкторы базовых классов virtual, когда они предназначены для управления полиморфно.

Если вы хотите предотвратить удаление экземпляра с помощью указателя базового класса, вы можете сделать деструктор базового класса защищенным и не виртуальным; при этом компилятор не позволит вам называть delete указателем базового класса.

Вы можете узнать больше о деструкторе виртуальности и виртуального базового класса в этой статье от Herb Sutter .

1
задан nod 26 June 2018 в 09:42
поделиться

1 ответ

Нет другого выбора, кроме рекурсивной обработки json и создания структуры TreeItem на основе информации элемента.

(Вероятно, есть лучший способ добавить символы, но я не нашел подходящих иконки.)

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.stack.imgur.com/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();
}
0
ответ дан fabian 16 August 2018 в 03:04
поделиться
  • 1
    Отлично, это то, что мне нужно. Я, вероятно, думал о том, как писать, но не писал. Но интересно, как вы сделали скобки и фигурные скобки? Значки или символы? Но я не могу найти символы. И если читать только первый элемент массива, возможно, он больше соответствует вопросу. – nod 26 June 2018 в 12:07
  • 2
    Я не мог найти символы в любом месте, поэтому он использовал ваш снимок экрана и скорректировал окно просмотра, чтобы отобразить соответствующую часть этого изображения. Не лучшее решение, и вы, вероятно, должны создать свои собственные изображения или использовать некоторые Shape s (Text / Rectangle), чтобы не нарушать какие-либо авторские права ... – fabian 26 June 2018 в 12:14
  • 3
    Если я хочу добавить флажок к элементам дерева и все еще показывать изображение, что мне делать? – nod 6 July 2018 в 08:21
  • 4
    Измените реализацию TreeCell. Это новый вопрос, хотя на комментарий нельзя ответить должным образом. – fabian 6 July 2018 в 08:35
Другие вопросы по тегам:

Похожие вопросы: