Есть ли умный способ поддерживать JavaFX TreeView в актуальном состоянии с базовой моделью DOM и JPA? - PullRequest
1 голос
/ 20 февраля 2020

Привет, у меня проблемы с поддержанием актуальности моего TreeView с моделью данных, подобной DOM, которая сохраняется с использованием JPA.

Мой код довольно многословен, поэтому я разбил его на разновидность псевдокода для лучшего понимания.

мой базовый c объект DOM выглядит следующим образом: класс Node:

@Entity
public class Node{

    @Id
    private UUID uuid= UUID.randomUUID();

    @ManyToOne
    private Node parent;

    @OneToMany(orphanRemoval=true, mappedBy="parentNode", fetch=FetchType.EAGER, cascade=CascadeType.ALL)
    private List<Node> children = new ArrayList<>();

    //--- some other irrelevant fields
    //--- some other irrelevant methods

    public Node getParent (){
        return this.parent;
    }

    public boolean addChild(Node child){
        boolean result = false;
        if (!isCircularReference(child)) { // this checks whether the passed child is not a distant farther etc.
            result = this.children.add(child);
        }
        return result;
    }

Конечно, класс Node содержит немного больше, но я не думаю, что имеет отношение к topi c.

. Тогда у меня есть View Controller, который управляет объектом JAVAFX TreeView. Упрощенно это выглядит так:

public class ViewController {

    @FXML private TreeView<Node> tree;

    private Node rootNode;

    ViewController (Node root){

            Objects.requireNonNull(root);
            this.rootNode = root;
            setupView();
    }

    //some other Nodes etc.

    private void setupView(){

        TreeItem<Node> treeRootNode = new TreeItem<>(rootNode)
        this.tree.setRoot(treeRootNode);
        fillTreeNodeWithProductNode(treeRootNode , rootNode);
    }

    //recursively populates the TreeView for each child under the Node
    private void fillTreeNodeWithProductNode(final TreeItem<Node> treeNode,final Node node){
        node.getChildren().forEach(child-> {
            final TreeItem<Node> childTreeNode = new TreeNode<>(child);
            treeNode.getChildren().add(childTreeNode);
            fillTreeNodeWithProductNode(childTreeNode, child);
        });
    }

    //--- some methods for adding and Removing TreeItems under TreeItems. 
    @FXML
    private void onSaveButtonPressed(){
        // .... simplified
        EntityManager em = getEntityManager();

        Node oldRootNode = rootNode;
        rootNode = em.merge(rootNode);

        compareAndRefreshTreeView(rootNode, oldRootNode);
    }
}

Этот ViewController также обрабатывает удаление и добавление элементов Node в дерево. Здесь не показано, чтобы было проще. НО: Это отлично работает. И, насколько я могу судить, это не вызывает проблем.

Хитрость заключается в использовании JPA для сохранения и управления объектами Node. если, скажем, я использую метод EntityManager.merge(E entity) на своем rootNode , то он вернет новый экземпляр этого rootNode . Это то, что вызывает у меня проблемы. TreeView tree.get Root все еще ссылается на старый экземпляр, используемый при создании представления. Это означает, что мне нужно заново воссоздать все дерево, используя новый экземпляр, возвращенный методом EntityManager.merge(E entity). Это воссоздание приводит к тому, что древовидная структура выглядит иначе, чем когда пользователь нажимал кнопку сохранения. (дерево свернуто, позиция полосы прокрутки вершина и т. д. c.) Для лучшего пользовательского опыта я создаю ссылку на TreeItem, содержащий rootNode, до слияния, затем после воссоздания TreeView я сравниваю обе структуры и расширяю новый TreeView при необходимости. Как продемонстрировано в ViewController.onSaveButtonPressed() Ссылка на позицию scollBar также сохраняется. Это прекрасно работает, но это не так!

Итак, мой вопрос: Конечно, есть более эффективный способ синхронизации всех данных?

Надеюсь, этого кода достаточно для понимания моей проблемы, если нет, дайте мне знать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...