Java 更新/刷新树模型

Java 更新/刷新树模型,java,swing,treemodel,Java,Swing,Treemodel,我有一系列线程定期检索RSS提要,并希望使用PropertyChangeSupport刷新自定义JTree。然而,它使用一个实现TreeModel的自定义类,我不知道如何触发自动更改。这是可能的还是我应该使用另一个类?您必须使用模型的侦听器集合,当刷新线程评论某些更改时,您必须向它们触发事件。我认为PropertyChangeSupport在这方面对您没有多大帮助,因为树模型的数据不是以JavaBeans属性的形式存在的,而且您不想触发PropertyChangeEvents 最后,在TreeM

我有一系列线程定期检索RSS提要,并希望使用PropertyChangeSupport刷新自定义JTree。然而,它使用一个实现TreeModel的自定义类,我不知道如何触发自动更改。这是可能的还是我应该使用另一个类?

您必须使用模型的侦听器集合,当刷新线程评论某些更改时,您必须向它们触发事件。我认为
PropertyChangeSupport
在这方面对您没有多大帮助,因为树模型的数据不是以JavaBeans属性的形式存在的,而且您不想触发PropertyChangeEvents

最后,在TreeModel实现中,我使用了以下方法(带有德语注释:-p)

/**
*贝纳里奇·蒂格特是一位听众,他是一位建筑大师
*这是最好的选择。
*/
私有void fireStructureChanged(树路径){
TreeModelEvent事件=新建TreeModelEvent(此,路径);
for(TreeModelListener:侦听器){
树结构改变(事件);
}
}
/**
*我是一个听话的人
*艾尼格·诺登·恩特弗恩特·沃尔登。
*/
私有无效fireNodesRemoved(树路径父路径,
int[]索引,对象[]节点){
树删除事件=
新的treemodelent(this、parentPath、索引、节点);
for(TreeModelListener:侦听器){
树状核摘除(事件);
}
}
/**
*贝纳里奇·蒂格特是一位听众,他是一位最优秀的听众
*恩特弗恩特·沃尔德。
*/
私有void fireNodeRemoved(树路径、整数索引、对象节点){
fireNodesRemoved(路径,新int[]{index},新对象[]{node});
}
/**
*这是我的听众,我的朋友
*这是一顶帽子。
*/
私有void fireNodesChanged(树路径父路径,
int[]索引,对象[]节点){
树删除事件=
新的treemodelent(this、parentPath、索引、节点);
for(TreeModelListener:侦听器){
lis.TREENODESCHANGE(事件);
}
}
/**
*听你说,这是一个好消息
*geändert帽子。
*
*@param parentPath der Pfad des ELTERNNOTENS des relevanten Knotens。
*@param index der index des Knotens unterhalb des elternnotens。
*瀑布<0,我们的听众尼希特·贝纳里奇蒂格。
*@param node der Subknoten。
*/
private void fireNodeChanged(树路径父路径,
int索引,对象节点){
如果(索引>=0){
fireNodesChanged(父路径,新int[]{index},新对象[]{node});
}
}
/**
*我的听众,我的朋友
*诺滕·艾因格特瓦尔登。
*/
私有无效FireNodeInserted(树路径父路径,
int[]索引,对象[]子节点){
树删除事件=
新的TreeModeEvent(此、父路径、索引、子节点);
for(TreeModelListener:侦听器){
立案法团(事件);
}
}
/**
*贝纳里奇·蒂格是一位听众,他是一位伟大的听众。
*/
私有无效fireNodeInserted(树路径父路径,
int索引,对象节点){
FireNodeInserted(父路径,新int[]{index},新对象[]{node});
}
然后从模型的其他部分调用正确的方法


如果您想让它变得简单,可以使用根节点simple始终触发
treeStructureChanged
事件,这将导致整个树重新加载。对于更精细的事件,您需要查看事实上发生了什么变化,然后触发此事件。

不完全确定“使用PropertyChangeListener刷新树”是什么意思,但同意Paul的观点:PropertyChangeListener在通知treeModel侦听器(包括JTree)方面没有帮助

通过适当的TreeModelEvents通知侦听器是TreeModel的任何实现的固有责任。如果它侦听所包含节点的更改(这可能引发f.i.PropertyChangeEvents),那么它必须将这些更改转换为TreeModeEvents

伪代码段:

public class MyTreeModel implements TreeModel {

     PropertyChangeListener nodeListener;

     // custom method to insert a node
     public void addNodeTo(MyBean child, MyBean parent) {
         // ... internal logic to add the new node

         fireChildAdded(getPathToRoot(parent), child)
         // add a PropertyChangeListener to new node so the model
         // can comply to its notification contract
         child.addPropertyChangeListener(getPropertyChangeListener();
     }

     protected void nodePropertyChanged(MyBean bean) {
          firePathChanged(getPathToRoot(bean));
     }

     protected TreePath getPathToRoot(MyBean bean) {
          // construct and return a treePath to the root
     }

     protected PropertyChangeListener getPropertyChangeListener() {
          if (nodeListener == null) {
             nodeListener = new PropertyChangeChangeListener() {
                 public void propertyChanged(...) {
                     nodeChanged((MyBean) e.getSource();
                 }

             );
     }

}
构建实际事件可能会有点混乱(而且文档记录得很差),这就是为什么要简化该任务

public class MyTreeModel implements TreeModel {

     PropertyChangeListener nodeListener;

     // custom method to insert a node
     public void addNodeTo(MyBean child, MyBean parent) {
         // ... internal logic to add the new node

         fireChildAdded(getPathToRoot(parent), child)
         // add a PropertyChangeListener to new node so the model
         // can comply to its notification contract
         child.addPropertyChangeListener(getPropertyChangeListener();
     }

     protected void nodePropertyChanged(MyBean bean) {
          firePathChanged(getPathToRoot(bean));
     }

     protected TreePath getPathToRoot(MyBean bean) {
          // construct and return a treePath to the root
     }

     protected PropertyChangeListener getPropertyChangeListener() {
          if (nodeListener == null) {
             nodeListener = new PropertyChangeChangeListener() {
                 public void propertyChanged(...) {
                     nodeChanged((MyBean) e.getSource();
                 }

             );
     }

}