2011-03-23 76 views
2

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

回答

3

您必须使用模型的侦听器集合,并且当您的清爽线程评论一些更改时,您必须将事件触发给它们。我不认为PropertyChangeSupport会在这里帮助你很多,因为树模型的数据不是以Java bean属性的形式存在的,而且你不想触发PropertyChangeEvents。

TreeModel中实现我做最后一点,我做了这些方法(与德国评论:-P)

/** 
* Benachrichtigt die Listener, dass die Struktur unterhalb 
* eines bestimmten Knotens komplett geändert wurde. 
*/ 
private void fireStructureChanged(TreePath path) { 
    TreeModelEvent event = new TreeModelEvent(this, path); 
    for(TreeModelListener lis : listeners) { 
     lis.treeStructureChanged(event); 
    } 
} 

/** 
* Benachrichtigt die Listener, dass unterhalb eines Knotens 
* einige Knoten entfernt wurden. 
*/ 
private void fireNodesRemoved(TreePath parentPath, 
           int[] indices, Object[] nodes) { 
    TreeModelEvent event = 
     new TreeModelEvent(this, parentPath, indices, nodes); 
    for(TreeModelListener lis : listeners) { 
     lis.treeNodesRemoved(event); 
    } 
} 

/** 
* Benachrichtigt die Listener, dass ein bestimmter Knoten 
* entfernt wurde. 
*/ 
private void fireNodeRemoved(TreePath path, int index, Object node) { 
    fireNodesRemoved(path, new int[]{index}, new Object[]{node}); 
} 


/** 
* Benachrichtigt die Listener, dass sich das Aussehen einiger 
* Unterknoten eines Knotens geändert hat. 
*/ 
private void fireNodesChanged(TreePath parentPath, 
           int[] indices, Object[] nodes) { 
    TreeModelEvent event = 
     new TreeModelEvent(this, parentPath, indices, nodes); 
    for(TreeModelListener lis : listeners) { 
     lis.treeNodesChanged(event); 
    } 
} 

/** 
* Benachrichtigt die Listener, dass sich das Aussehen eines Knotens 
* geändert hat. 
* 
* @param parentPath der Pfad des Elternknotens des relevanten Knotens. 
* @param index der Index des Knotens unterhalb des Elternknotens. 
*   Falls < 0, werden die Listener nicht benachrichtigt. 
* @param node der Subknoten. 
*/ 
private void fireNodeChanged(TreePath parentPath, 
          int index, Object node) { 
    if(index >= 0) { 
     fireNodesChanged(parentPath, new int[]{index}, new Object[]{node}); 
    } 
} 

/** 
* Benachrichtigt die Listener, dass unterhalb eines Knotens einige 
* Knoten eingefügt wurden. 
*/ 
private void fireNodesInserted(TreePath parentPath, 
           int[] indices, Object[] subNodes) { 
    TreeModelEvent event = 
     new TreeModelEvent(this, parentPath, indices, subNodes); 
    for(TreeModelListener lis : listeners) { 
     lis.treeNodesInserted(event); 
    } 
} 

/** 
* Benachrichtigt die Listener, dass ein Knoten eingefügt wurde. 
*/ 
private void fireNodeInserted(TreePath parentPath, 
           int index, Object node) { 
    fireNodesInserted(parentPath, new int[]{index}, new Object[]{node}); 
} 

然后从不管什么时候改变了正确的方法是调用模型的其他部分。

如果您想简化一下,您可以简单地始终使用根节点激发一个treeStructureChanged事件,这会导致整个树重新加载。对于更好的事件,你需要看看事实上发生了什么变化,然后解决这个问题。

2

不能完全确定,你的意思是“用一个PropertyChangeListener刷新树”,但与保罗认同:一个PropertyChangeListener不有益通知的TreeModel听众(其中包括JTree的)。

这是TreeModel的任何实现通过适当的TreeModelEvents通知其侦听器的内在责任。如果它监听包含节点的变化(可能触发f.i. PropertyChangeEvents),那么它必须将它们转换为TreeModelEvents。

伪代码片段:

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(); 
       } 

      ); 
    } 

} 

构建真实事件是一个有点混乱(且不良记录),这就是为什么SwingX has a helper class TreeModelSupport来简化这一任务。