Swing TreeModelListener不响应其订阅的TreeModel中的更改
我很难理解为什么我不能让TreeModelChanged侦听器响应它所订阅的模型中的更改 我已经设法在一个小例子中重现了这个问题 每当向树中添加新节点时,SysOut消息不会打印到控制台 我打算用一些命令来替换SysOut消息,以重新绘制树。目前,我使用SysOut消息只是为了证明侦听器没有被解雇 我错过了一些基本的东西吗Swing TreeModelListener不响应其订阅的TreeModel中的更改,swing,jtree,defaulttablemodel,Swing,Jtree,Defaulttablemodel,我很难理解为什么我不能让TreeModelChanged侦听器响应它所订阅的模型中的更改 我已经设法在一个小例子中重现了这个问题 每当向树中添加新节点时,SysOut消息不会打印到控制台 我打算用一些命令来替换SysOut消息,以重新绘制树。目前,我使用SysOut消息只是为了证明侦听器没有被解雇 我错过了一些基本的东西吗 import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.Act
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())
编辑
树节点只是一个(或多或少)哑数据结构。正如您在api中看到的,它不是可观察的,因此使用该数据结构的模型无法检测节点上是否有任何更改。为了让它意识到变化,你必须做两件事中的一件
- 使用模型的节点操纵方法
- 更新节点并手动通知模型(调用NodeWereInserted)
第一种是更好的方法(控制它所属的位置),第二种可能在更复杂的环境中需要(尽管我强烈建议不要这样做,这就是为什么SwingX DefaultTreeTableModel没有公开它们:)感谢您的建议,这很有效。你能解释一下“发生在它脚下”是什么意思吗?我以为侦听器监视DefaultTreeModel对象的状态变化?我原以为添加像上面代码示例这样的节点就等于这样了?