当模型改变时更新Eclipse JFace Treeviewer ?

时间:2022-05-29 11:43:20

I am developing a RCP application with a TreeViewer. While there are good number of articles to explain how to add editing support to the Viewer (and how changes in view are updated in the model), I don't find much for updating the Treeview when the underlaying model changes. my question in short:

我正在用TreeViewer开发一个RCP应用程序。虽然有很多文章可以解释如何向查看器添加编辑支持(以及视图中的更改如何在模型中更新),但是当底层模型发生更改时,我没有找到多少更新Treeview的文章。我的问题简而言之:

TreeView ----> Model updation ------ there are lots of examples

TreeView——>模型上升——有很多例子

Model ----> Treeview updation ----- this is my question

模型----- --> - Treeview updation -----这是我的问题。

Edit: This is what I tried and it works. comments please

编辑:这就是我所尝试过的,它是有效的。请评论

viewer.getTree().addKeyListener(new KeyListener(){

    @Override
    public void keyPressed(KeyEvent e) {

    }

    @Override
    public void keyReleased(KeyEvent e) {

        if(e.keyCode==SWT.F3){
            System.out.println("F3 pressed... new element will be added");
            TreeParent root = (TreeParent) viewer.getInput();
            TreeParent activityRoot = (TreeParent) root.getChildren()[0];
            activityRoot.addChild(new TreeObject("NEW_ACTIVITY"));
            //viewer.update(root, null);
            viewer.refresh();
        }

    }

    });

2 个解决方案

#1


3  

The data model is provided by your content provider, TreeViewer does not provide any means of changing this data - you must do that it your own code. When you have changed to model you can use the following methods to tell the TreeViewer about the change:

数据模型是由内容提供者提供的,TreeViewer不提供任何修改数据的方法——您必须自己编写代码。当您更改为模型时,您可以使用以下方法告诉TreeViewer关于更改的内容:

If you have just changed what needs to be shown for a single item in the tree use

如果您刚刚更改了树使用中的单个项目需要显示的内容

TreeViewer.update(object, null);

to get that item in the tree updated. There is also an array version of this to update multiple objects.

更新树中的项目。还有一个用于更新多个对象的数组版本。

If you have added or removed objects in the tree use

如果在树中添加或删除了对象

TreeViewer.refresh();

to rebuild the whole tree or

重建整棵树

TreeViewer.refresh(object);

to refresh the part of the tree start at object.

要刷新从对象开始的树的部分。

To tell the tree about adding and removing objects there are

告诉树添加和删除对象

TreeViewer.add(parent, object);
TreeViewer.remove(object);

there are also array variants of these.

它们也有数组变体。

To help the TreeViewer find the objects call

帮助TreeViewer找到对象调用。

TreeViewer.setUseHashlookup(true);

(must be called before TreeViewer.setInput). Since this uses a hash table the objects should have sensible hashCode and equals methods. You can also use TreeViewer.setComparer to specify a different class to do the hash code and comparison.

(必须在TreeViewer.setInput之前调用)。由于使用了哈希表,因此对象应该具有合理的hashCode和equals方法。您还可以使用TreeViewer。setComparer指定一个不同的类来执行哈希代码和比较。

#2


0  

Based on the comments in this thread,one of the eclipse corner articles on using TreeViewer and few experimenting I had created a working model.

基于这篇文章中的评论,我创建了一个可以工作的模型,这是eclipse角上关于使用TreeViewer的一篇文章。

Here are the steps:

下面是步骤:

Create a listener interface like the following

创建一个监听器接口,如下所示

public interface TreeModelListener extends EventListener {
    public void onDelete(TreeObject obj);
}

Let the tree Content provider to add listeners to each tree model item and implement this interface like below

让树内容提供程序向每个树模型项添加侦听器,并实现如下所示的接口

public class TreeContentProvider implements  IStructuredContentProvider,ITreeContentProvider,TreeModelListener {

TreeViewer tv;
public TreeContentProvider(TreeViewer tv){
    this.tv=tv;
}

int cnt=0;
public void inputChanged(Viewer v, Object oldInput, Object newInput) {
    cnt ++;
    System.out.println("inputChanged() called "+oldInput+" new: "+newInput);
    if(newInput!=null){

        ((TreeParent)newInput).setListener(this);
        TreeObject []items = ((TreeParent)newInput).getChildren(); 
        for(TreeObject obj : items){
            if(obj instanceof TreeParent){
                ((TreeParent) obj).setListener(this);
            }
        }

    }
}

....

@Override
public void onDelete(TreeObject obj) {
    System.out.println("Delete of "+obj+" handled by content handler ");
    TreeParent parent = obj.getParent();
    if(parent.getChildren().length<=1){
        return;
    }
    parent.removeChild(obj);
    this.tv.refresh();
}

}

}

Add a method to the TreeModel class as below . And obviously TreeParent class should have an ArrayList of listeners that is being used in #1 above

向TreeModel类添加一个方法,如下所示。显然,TreeParent类应该有一个在上面的#1中使用的侦听器的ArrayList。

public void fireChildDelete(final TreeObject obj){

    if(this.listener!=null){
        new Runnable(){

            @Override
            public void run() {
                System.out.println("New thread spawned with ID "+Thread.currentThread().getId());
                listener.onDelete(obj);
            }

        }.run();
    }
}

Finally add KeyListener to the TreeViewer Object to handle Delete key as below:

最后,将KeyListener添加到TreeViewer对象中,以处理以下的删除键:

tv.getTree().addKeyListener(new KeyListener(){

        @Override
        public void keyPressed(KeyEvent e) {

        }

        @Override
        public void keyReleased(KeyEvent e) {

            if(e.keyCode==SWT.F3){
                System.out.println("F3 pressed... new element will be added");
                TreeParent root = (TreeParent) tv.getInput();
                TreeParent activityRoot = (TreeParent) root.getChildren()[0];
                activityRoot.addChild(new TreeObject("NEW_ACTIVITY"));
                //viewer.update(root, null);
                tv.refresh();
            }

            if(e.keyCode==SWT.DEL){


                System.out.println("DEL key pressed... element will be deleted "+((Tree)e.getSource()).getSelection().length);

                if(((Tree)e.getSource()).getSelection().length>0){
                    final IStructuredSelection selection = (IStructuredSelection) tv
                              .getSelection();
                    System.out.println("DEL#2 key pressed... element will be deleted "+selection.getFirstElement().getClass());

                    TreeParent parent =  ((TreeObject)selection.getFirstElement()).getParent();
                    parent.fireChildDelete((TreeObject) selection.getFirstElement());
                    //tv.remove(selection.getFirstElement());
                    //viewer.update(viewer.getInput(),null);
                    //tv.refresh();
                }
            }


        }

    });

#1


3  

The data model is provided by your content provider, TreeViewer does not provide any means of changing this data - you must do that it your own code. When you have changed to model you can use the following methods to tell the TreeViewer about the change:

数据模型是由内容提供者提供的,TreeViewer不提供任何修改数据的方法——您必须自己编写代码。当您更改为模型时,您可以使用以下方法告诉TreeViewer关于更改的内容:

If you have just changed what needs to be shown for a single item in the tree use

如果您刚刚更改了树使用中的单个项目需要显示的内容

TreeViewer.update(object, null);

to get that item in the tree updated. There is also an array version of this to update multiple objects.

更新树中的项目。还有一个用于更新多个对象的数组版本。

If you have added or removed objects in the tree use

如果在树中添加或删除了对象

TreeViewer.refresh();

to rebuild the whole tree or

重建整棵树

TreeViewer.refresh(object);

to refresh the part of the tree start at object.

要刷新从对象开始的树的部分。

To tell the tree about adding and removing objects there are

告诉树添加和删除对象

TreeViewer.add(parent, object);
TreeViewer.remove(object);

there are also array variants of these.

它们也有数组变体。

To help the TreeViewer find the objects call

帮助TreeViewer找到对象调用。

TreeViewer.setUseHashlookup(true);

(must be called before TreeViewer.setInput). Since this uses a hash table the objects should have sensible hashCode and equals methods. You can also use TreeViewer.setComparer to specify a different class to do the hash code and comparison.

(必须在TreeViewer.setInput之前调用)。由于使用了哈希表,因此对象应该具有合理的hashCode和equals方法。您还可以使用TreeViewer。setComparer指定一个不同的类来执行哈希代码和比较。

#2


0  

Based on the comments in this thread,one of the eclipse corner articles on using TreeViewer and few experimenting I had created a working model.

基于这篇文章中的评论,我创建了一个可以工作的模型,这是eclipse角上关于使用TreeViewer的一篇文章。

Here are the steps:

下面是步骤:

Create a listener interface like the following

创建一个监听器接口,如下所示

public interface TreeModelListener extends EventListener {
    public void onDelete(TreeObject obj);
}

Let the tree Content provider to add listeners to each tree model item and implement this interface like below

让树内容提供程序向每个树模型项添加侦听器,并实现如下所示的接口

public class TreeContentProvider implements  IStructuredContentProvider,ITreeContentProvider,TreeModelListener {

TreeViewer tv;
public TreeContentProvider(TreeViewer tv){
    this.tv=tv;
}

int cnt=0;
public void inputChanged(Viewer v, Object oldInput, Object newInput) {
    cnt ++;
    System.out.println("inputChanged() called "+oldInput+" new: "+newInput);
    if(newInput!=null){

        ((TreeParent)newInput).setListener(this);
        TreeObject []items = ((TreeParent)newInput).getChildren(); 
        for(TreeObject obj : items){
            if(obj instanceof TreeParent){
                ((TreeParent) obj).setListener(this);
            }
        }

    }
}

....

@Override
public void onDelete(TreeObject obj) {
    System.out.println("Delete of "+obj+" handled by content handler ");
    TreeParent parent = obj.getParent();
    if(parent.getChildren().length<=1){
        return;
    }
    parent.removeChild(obj);
    this.tv.refresh();
}

}

}

Add a method to the TreeModel class as below . And obviously TreeParent class should have an ArrayList of listeners that is being used in #1 above

向TreeModel类添加一个方法,如下所示。显然,TreeParent类应该有一个在上面的#1中使用的侦听器的ArrayList。

public void fireChildDelete(final TreeObject obj){

    if(this.listener!=null){
        new Runnable(){

            @Override
            public void run() {
                System.out.println("New thread spawned with ID "+Thread.currentThread().getId());
                listener.onDelete(obj);
            }

        }.run();
    }
}

Finally add KeyListener to the TreeViewer Object to handle Delete key as below:

最后,将KeyListener添加到TreeViewer对象中,以处理以下的删除键:

tv.getTree().addKeyListener(new KeyListener(){

        @Override
        public void keyPressed(KeyEvent e) {

        }

        @Override
        public void keyReleased(KeyEvent e) {

            if(e.keyCode==SWT.F3){
                System.out.println("F3 pressed... new element will be added");
                TreeParent root = (TreeParent) tv.getInput();
                TreeParent activityRoot = (TreeParent) root.getChildren()[0];
                activityRoot.addChild(new TreeObject("NEW_ACTIVITY"));
                //viewer.update(root, null);
                tv.refresh();
            }

            if(e.keyCode==SWT.DEL){


                System.out.println("DEL key pressed... element will be deleted "+((Tree)e.getSource()).getSelection().length);

                if(((Tree)e.getSource()).getSelection().length>0){
                    final IStructuredSelection selection = (IStructuredSelection) tv
                              .getSelection();
                    System.out.println("DEL#2 key pressed... element will be deleted "+selection.getFirstElement().getClass());

                    TreeParent parent =  ((TreeObject)selection.getFirstElement()).getParent();
                    parent.fireChildDelete((TreeObject) selection.getFirstElement());
                    //tv.remove(selection.getFirstElement());
                    //viewer.update(viewer.getInput(),null);
                    //tv.refresh();
                }
            }


        }

    });