2011-11-30 47 views
1

我有些困扰理解为什么我无法让TreeModelChanged监听器响应它所订阅的模型中的更改。TreeModelListener没有响应它所订阅的TreeModel中的更改

我已经设法在一个小例子中重现了这个问题。

每当将新节点添加到树中时,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); 
    } 

} 

回答

2

这是因为模型不知道增加,它发生在它的脚下。使用上DefaultTreeModel的方法做插入:

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

编辑

一个树节点仅仅是一个(或多或少)哑数据结构。正如你在api中看到的那样,它不是可观察的,所以对于使用该数据结构来检测节点上是否有任何改变的模型,存在没有办法。为了使它认识到变化的,你必须手工做两件事

一个
  • 使用的型号
  • 更新节点的节点操作方法,并通知模型(主叫nodesWereInserted)

首先是更好的方式(保持它所属的控制),第二更可能需要更复杂的上下文(虽然我强烈建议从来没有做到这一点,这就是为什么SwingX DefaultTreeTableModel没有公开他们:)

+0

感谢您的建议,这是可行的。你能解释一下它“在脚下发生的事情”吗?我以为收听者注意到DefaultTreeModel对象上的状态变化?我曾经想过,添加上面的代码示例等节点会等同于那个? – 8bitjunkie

+0

感谢您的澄清 – 8bitjunkie