TreeModelListener не отвечает на изменения в TreeModel, на которые он подписан - PullRequest
2 голосов
/ 30 ноября 2011

У меня возникают некоторые затруднения с пониманием, почему я не могу заставить слушателя 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);
    }

}

1 Ответ

2 голосов
/ 30 ноября 2011

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

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

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

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

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

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

...