Как остановить JTree от разрушения после удаления узла из дерева

Я делаю JTree и у меня есть кнопка, которая удаляет узел из дерева. Каждый раз, когда я удаляю узел кнопкой, дерево автоматически разрушается. Я читал, что это потому, что я использую .reload(), Я также прочитал некоторые ответы SO, которые предложили использовать .nodeChanged(node), который я пробовал, но когда я использую это, я считаю, что модель обновляется, но дерево не перезагружается соответствующим образом в графическом интерфейсе. Как я могу заставить дерево не разрушаться?

Вот простой SSCCE с JTree по умолчанию и кнопкой для удаления узла

import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;

public class StopTreeCollapse extends JApplet {

    JTree tree = new JTree();
    JButton jbtRemove = new JButton("Remove Node");

    public StopTreeCollapse(){

        add(new JScrollPane(tree), BorderLayout.CENTER);
        add(jbtRemove, BorderLayout.SOUTH);

        jbtRemove.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                TreePath[] paths = tree.getSelectionPaths();

                if (paths == null) {
                    JOptionPane.showMessageDialog(null,
                            "No node in the tree is selected");
                    return;
                }
                DefaultMutableTreeNode node = null; 
                for (TreePath path : paths) {
                    node = (DefaultMutableTreeNode) (path.getLastPathComponent());
                    if (node.isRoot()) {
                        JOptionPane.showMessageDialog(null, "Cannot remove the root");
                    } else {
                        node.removeFromParent();
                    }
                }
                ((DefaultTreeModel) tree.getModel()).reload();
            }
        });
    }
}

1 ответ

Решение

reload() по сути, говорит: "Возможно, все дерево изменилось, забудьте все, что вы знали об этом, и начните сначала".

Вместо того, чтобы использовать node.removeFromParent() а затем перезагрузите все дерево, попробуйте

((DefaultTreeModel) tree.getModel()).removeNodeFromParent(node);

Это вызовет более конкретное событие модификации, сообщающее слушателям, что этот конкретный узел был удален, но остальная часть дерева не изменилась, поэтому вам больше не требуется reload() вызов.

Другие вопросы по тегам