2

我很难理解为什么我无法让 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);
    }

}
4

1 回答 1

2

那是因为模型不知道添加,它发生在它的脚下。使用 DefaultTreeModel 上的方法进行插入:

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

编辑

TreeNode 只是一个(或多或少)愚蠢的数据结构。正如您在 api 中看到的,它不是 Observable,因此使用该数据结构的模型无法检测节点上是否有任何更改为了让它意识到变化,你必须做两件事之一

  • 使用模型的节点操作方法
  • 更新节点并手动通知模型(调用nodesWereInserted)

第一种是更可取的方式(控制它所属的位置),第二种可能需要在更复杂的上下文中(尽管我强烈建议永远不要这样做,这就是 SwingX DefaultTreeTableModel 没有暴露它们的原因:)

于 2011-11-30T16:19:05.380 回答