我正在尝试在我的RCP应用程序中构建一个视图,该视图只包含一个TreeViewer
。
树可以包含文件夹或叶子,文件夹可以包含文件夹和叶子。当我将文件夹添加到根文件夹的后端数据模型时,UI会自动更新,但如果我将文件夹添加到任何分支文件夹,UI将不会自动更新。请告诉我我的代码有什么问题。
模型类:
public class TreeNode extends BindableObject {
private Folder parent;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
super.firePropertyChange("name", this.name, this.name = name);
}
public Folder getParent() {
return parent;
}
public void setParent(Folder parent) {
this.parent = parent;
}
}
public class Folder extends TreeNode {
private List<TreeNode> children = new ArrayList<TreeNode>();
public List<TreeNode> getChildren() {
return children;
}
public void setChildren(List<TreeNode> children) {
this.children = children;
}
public void add(TreeNode node){
children.add(node);
}
}
观点:
public class ExplorerView extends ViewPart {
private WritableList data;
private TreeViewer treeViewer;
public WritableList getData() {
return data;
}
public TreeViewer getViewer(){
return treeViewer;
}
public ExplorerView() {
// TODO Auto-generated constructor stub
}
@Override
public void createPartControl(Composite parent) {
parent.setLayout(new FillLayout(SWT.HORIZONTAL));
treeViewer = new TreeViewer(parent, SWT.BORDER);
treeViewer.setContentProvider(new ObservableListTreeContentProvider(new ExplorerObservableFactory(), new ExploerTreeStructureAdvisor()));
treeViewer.setLabelProvider(new ExplorerTreeLabelProvider());
ArrayList<TreeNode> list = new ArrayList<TreeNode>();
list.add(new ExplorerDataModel().getElements()[0]);
data = new WritableList(list, TreeNode.class);
treeViewer.setInput(data);
}
@Override
public void setFocus() {
}
}
ObservableFactory:
public class ExplorerObservableFactory implements IObservableFactory {
@Override
public IObservable createObservable(Object target) {
System.out.println(target.getClass().getName());
if(target instanceof WritableList){
return (WritableList)target;
}
else if(target instanceof Folder){
List<TreeNode> children = ((Folder)target).getChildren();
return new WritableList(children, TreeNode.class);
}
return null;
}
}
TreeStructureAdvisor:
public class ExploerTreeStructureAdvisor extends TreeStructureAdvisor {
@Override
public Object getParent(Object element) {
return ((TreeNode)element).getParent();
}
@Override
public Boolean hasChildren(Object element) {
if(element instanceof Folder){
return true;
}else{
return false;
}
}
}
数据:
public class ExplorerDataModel {
public TreeNode[] getElements() {
Folder f1 = new Folder();
f1.setName("Database Connections");
Folder f11 = new Folder();
f11.setName("Credit Test");
TreeNode t1 = new TreeNode();
t1.setName("bank@localhost");
f11.add(t1);
t1.setParent(f11);
TreeNode t2 = new TreeNode();
t2.setName("credit@localhost");
f11.add(t2);
t2.setParent(f11);
Folder f12 = new Folder();
f12.setName("Credit Product");
TreeNode t3 = new TreeNode();
t3.setName("nbcbcredit@localhost");
f12.add(t3);
t3.setParent(f12);
TreeNode t4 = new TreeNode();
t4.setName("nbcbcredit_bak@localhost");
f12.add(t4);
t4.setParent(f12);
f1.add(f11);
f11.setParent(f1);
f1.add(f12);
f12.setParent(f1);
return new TreeNode[] { f1 };
}
}
测试命令处理程序:
public Object execute(ExecutionEvent event) throws ExecutionException {
ExplorerView v =(ExplorerView) HandlerUtil.getActiveWorkbenchWindow(event).getActivePage().findView("com.amarsoft.dmp.explorer.explorerView");
Folder f = new Folder();
f.setName("ODA Flat Files");
v.getData().add(f);
Folder f1 = (Folder) v.getData().get(0);
f1.setName("Database Connections (3)");
Folder f2 = new Folder();
f2.setName("Report Test");
f1.add(f2);
return null;
}
如果执行上述命令,添加的文件夹“ODA Flat Files”将立即出现在树中,但添加的文件夹“Report Test”将不在那里,如果调用TreeViewer#refresh()
一切正常,但是我想知道原因。
答案 0 :(得分:4)
修改模型不会通知您的树。刷新是告诉树数据已更改且需要更新的一种方法。如果你在eclipse中浏览java doc for jface viewers,你会发现以下引用
要处理结构更改,请改用刷新方法。
答案 1 :(得分:2)
您似乎错误配置了数据绑定...
查看官方摘要:
玩得开心! (没有任何刷新;-))
PS。对于EMF,请看一下:http://tomsondev.bestsolution.at/2009/06/08/galileo-emf-databinding-%E2%80%93-part-3/
答案 2 :(得分:1)
在ExplorerObservableFactory
替换
... else if(target instanceof Folder){
List<TreeNode> children = ((Folder)target).getChildren();
return new WritableList(children, TreeNode.class);
}
通过以下
else if(target instanceof Folder){
return BeansObservables.observeList(target, "children");
}
如果你在这里返回WritableList
,则会在其上注册contentProvider的监听器(它应该在Folder bean上注册)