jface treeviewer中删除子结点的问题

时间:2023-01-20 19:38:04
各位大大们好,用jface的TreeViewer删除父节点的子结点,采用如下步骤:
1. 获取选中的子节点实体对象:
   StructuredSelection selection = (StructuredSelection) treeViewer.getSelection();
   Child child = (Child)(selection.getFirstElement());
2. 获取该子结点的实体父类对象:
   Parent parent = child.getParent();
3. 在treeViewer中删除子节点:
   treeViewer.remove(child);
4. 在实体父类对象中的子节点表List中删除该子节点:
   parent.getChildList().remove(child);
现遇到以下问题,在treeViewer窗口用鼠标操作时,当删除的记录不是父节点的最后一个子节点时,一切正常。
当删除的记录是父节点的最后一个子节点时,该记录在父类对象的子节点表List中是被删除了,可在显示的树上依然存在,再操作一下删除,才算是删掉了该子节点。请问这是什么原因,困惑中……

4 个解决方案

#1


不要用 treeViewer.remove(child); 
在parent.getChildList().remove(child); 后
用viewer.refresh(parent, false);

#2


你没有刷新,做完操作后,用一个UI线程刷新旧OK了.也就是在parent.getChildList().remove(child); 后 用viewer.refresh(parent, false); 
但是如果想楼上的话,还是不行的,因为它涉及UI线程的访问,所以要用一个线程来执行刷新操作,如下:

Display.getDefault().asyncExec(new Runnable(){
@Override
public void run() {
  //在这里写刷新的操作,注意:我不知道我写对了没有,因为很久没做这个了,你自己看看,错了就自己更正;
viewer.refresh(parent, true); 

}
});


如果我对了,就要给分哦,O(∩_∩)O~记得结贴..................

#3


一楼和二楼的方法都可行, 最主要的就是remove完后要记得调用 treeViewer 的 refresh 方法

#4


/**
 * Refreshes this viewer starting with the given element. Labels are updated
 * as described in <code>refresh(boolean updateLabels)</code>.
 * <p>
 * Unlike the <code>update</code> methods, this handles structural changes
 * to the given element (e.g. addition or removal of children). If only the
 * given element needs updating, it is more efficient to use the
 * <code>update</code> methods.
 * </p>
 * 
 * @param element
 *            the element
 * @param updateLabels
 *            <code>true</code> to update labels for existing elements,
 *            <code>false</code> to only update labels as needed, assuming
 *            that labels for existing elements are unchanged.
 * 
 * @since 2.0
 */
public void refresh(final Object element, final boolean updateLabels) {
preservingSelection(new Runnable() {
public void run() {
internalRefresh(element, updateLabels);
}
});
}

so, please use treeViewer.refresh(parent, false); 

这个本来就在UI线程里的,用一个异步的UIJOB 去刷新,要看实际的情况,如果你的逻辑放在一个JOB 里面
当然需要,在UI线程里面刷新了

#1


不要用 treeViewer.remove(child); 
在parent.getChildList().remove(child); 后
用viewer.refresh(parent, false);

#2


你没有刷新,做完操作后,用一个UI线程刷新旧OK了.也就是在parent.getChildList().remove(child); 后 用viewer.refresh(parent, false); 
但是如果想楼上的话,还是不行的,因为它涉及UI线程的访问,所以要用一个线程来执行刷新操作,如下:

Display.getDefault().asyncExec(new Runnable(){
@Override
public void run() {
  //在这里写刷新的操作,注意:我不知道我写对了没有,因为很久没做这个了,你自己看看,错了就自己更正;
viewer.refresh(parent, true); 

}
});


如果我对了,就要给分哦,O(∩_∩)O~记得结贴..................

#3


一楼和二楼的方法都可行, 最主要的就是remove完后要记得调用 treeViewer 的 refresh 方法

#4


/**
 * Refreshes this viewer starting with the given element. Labels are updated
 * as described in <code>refresh(boolean updateLabels)</code>.
 * <p>
 * Unlike the <code>update</code> methods, this handles structural changes
 * to the given element (e.g. addition or removal of children). If only the
 * given element needs updating, it is more efficient to use the
 * <code>update</code> methods.
 * </p>
 * 
 * @param element
 *            the element
 * @param updateLabels
 *            <code>true</code> to update labels for existing elements,
 *            <code>false</code> to only update labels as needed, assuming
 *            that labels for existing elements are unchanged.
 * 
 * @since 2.0
 */
public void refresh(final Object element, final boolean updateLabels) {
preservingSelection(new Runnable() {
public void run() {
internalRefresh(element, updateLabels);
}
});
}

so, please use treeViewer.refresh(parent, false); 

这个本来就在UI线程里的,用一个异步的UIJOB 去刷新,要看实际的情况,如果你的逻辑放在一个JOB 里面
当然需要,在UI线程里面刷新了