TreeModellistener не отвечает на изменения в TreeModel, на которые он подписывается на

StackOverflow https://stackoverflow.com/questions/8328967

  •  26-10-2019
  •  | 
  •  

Вопрос

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

Мне удалось воспроизвести проблему в небольшом примере.

Сообщение SYSOUT не печатается на консоли всякий раз, когда к дереву добавляется новый узел.

Я намерен заменить сообщение Sysout на некоторые команды, чтобы перерисовать дерево. На данный момент я использую сообщение Sysout, чтобы доказать, что слушателя не уволяется.

Я упускаю что -то фундаментальное?

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;


public class TreeTest {

    private JTree t;
    private DefaultTreeModel m ;

    public static void main(String[] args) {
         new TreeTest();

    }

    public TreeTest() {

        //Draw Frame & Panel  - set dimensions
        JFrame f = new JFrame();
        f.setSize(new Dimension(800,600));
        JPanel p = new JPanel();
        p.setSize(new Dimension(800,600));



        //Create a Tree Model. Give it a String at the root.
        m = new DefaultTreeModel(new DefaultMutableTreeNode("Root"));

        //Create a tree and add the Model to it
        t = new JTree();
        t.setModel(m);


        //Try a Tree Model Listener
        m.addTreeModelListener(new TreeModelListener() {

            private void doSomething() {
                //Should fire whenever a node is added to the model
                System.out.println("Responding to TreeModelListener");
            }
            @Override
            public void treeStructureChanged(TreeModelEvent e) {
                doSomething();

            }

            @Override
            public void treeNodesRemoved(TreeModelEvent e) {
                doSomething();

            }

            @Override
            public void treeNodesInserted(TreeModelEvent e) {
                doSomething();

            }

            @Override
            public void treeNodesChanged(TreeModelEvent e) {
                doSomething();

            }
        });     

        //Add listener to a button which adds nodes to the tree when clicked
        JButton addNode = new JButton("Add node");
        addNode.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("New Node");
                DefaultMutableTreeNode root = (DefaultMutableTreeNode) m.getRoot();
                root.add(newNode);
            }
        });

        JScrollPane s = new JScrollPane(t);


        p.add(s);
        p.add(addNode);

        p.setVisible(true);
        f.add(p);
        f.setVisible(true);
    }

}
Это было полезно?

Решение

Это потому, что модель не знает о дополнении, это происходит под ногами. Используйте методы на DefaultTreeModel, чтобы сделать вставку:

model.insertNodeInto(newNode, root, root.getChildCount())

Редактировать

TreeNode - это просто (более или менее) глупая структура данных. Как вы можете видеть в API, он не наблюдается, так что есть ни за что Для модели, которая использует эту структуру данных для обнаружения, если что -то изменилось на узле. Чтобы понять об этом изменении, вы должны сделать одну из двух вещей

  • Используйте методы манипуляции с узлом модели
  • Обновите узел и уведомите модель вручную (вызов Nodeswereinserted)

Во -первых, это предпочтительный способ (сохраняет контроль там, где он находится), второй может понадобиться в более сложных контекстах (хотя я настоятельно рекомендую никогда Сделай это, вот почему Swingx DefaultTreetableModel их не открывает :)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top