在Eclipse RCP应用程序中绑定列表的数据的最佳实践

时间:2013-07-11 13:11:05

标签: java eclipse data-binding eclipse-rcp jface

我无法理解Eclipse RCP应用程序中的数据绑定。我只是无法弄清楚它应该如何工作..

这就是我想要做的事情

我有一个视图,其中应显示文本列表。文本被“存储”在一个简单的List<String>中,它通过单例提供(仅用于演示目的;))。因此,使用ListProvider的任何人都将获得文本列表。当列表更改时,我希望我的View自动更新表格内容。

这是我到目前为止所做的事情

我的列表提供程序是Observable,它将在列表更改时通知观察者。

在我看来,我创建了一个Observer来监视列表提供者,当通知观察者时我刷新了我的视图。

ListProvider的代码:

public class ListProvider extends Observable {

    private Stack<String> hist;
    private static ListProvider instance;

    // Singleton implementation
    public static ListProvidergetInstance() {
        if (null == instance) {
            instance = new ListProvider
        }
        return instance;
    }

    public void add(String text) {
        if (this.hist.size() == MAX_SIZE) {
            this.hist.remove(MAX_SIZE-1);
        }
        this.hist.add(0, text);
        // notify all observers
        this.setChanged();
        this.notifyObservers();
    }
}

视图代码:

public class TestView extends ViewPart {

private TableViewer viewer;

[...]

class ViewContentProvider implements IStructuredContentProvider {
    public void inputChanged(Viewer v, Object oldInput, Object newInput) {
    }
    public void dispose() {
    }
    public Object[] getElements(Object parent) {
        return ClipboardHistory.getInstance().getList().toArray();
    }
}

public void createPartControl(Composite parent) {
    viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
    IContentProvider contentProvider = new ViewContentProvider();
    viewer.setContentProvider(contentProvider);
    viewer.setLabelProvider(new ViewLabelProvider());
    viewer.setInput(getViewSite());

    Observer listObserver = new Observer() {
        @Override
        public void update(Observable o, Object arg) {
            // update the table viewer
            viewer.refresh();
        }
    };

    ListProvider.getInstance().addObserver(listObserver);
}
}

问题

使用ObserverObservable“正确”方式还是我错过了什么?我不确定我是否已经掌握了RCP数据绑定的概念......

2 个答案:

答案 0 :(得分:6)

我建议您阅读JFace Databinding并使用ViewerSupportObservableListContentProviderBeanProperties来简化工作。

您还可以看到一个工作示例JFace Databinding Snippet: Model to TableViewer binding作为参考,最后在ViewerSupport的帮助下完成绑定:

(...)
TableViewer peopleViewer = new TableViewer(committers);
ViewerSupport.bind(peopleViewer, new WritableList(viewModel.getPeople(),
     Person.class), BeanProperties.value(Person.class, "name"));

使用这些帮助程序,您不需要为列表实现Observer,如果您希望查看器在修改数据时更新其标签,请查看同一示例PropertyChangeSupport ,允许您在列表中通过它通知的任何元素的每次更改时刷新查看器。使用BeanProperties进行绑定非常重要。

答案 1 :(得分:1)

我不认为你的方法有一个可能的例外有什么问题。您需要确保在UI线程中刷新查看器:

Display.getDefault().asyncExec(new Runnable() {
    @Override
    public void run() {
        viewer.refresh();
    }
});

但是,您可以采取一些措施来提高表的更新效率。在上面的代码中,它似乎只在表格的顶部添加了一个项目,因此您最好通过以下方式调用:

viewer.insert( text, 0 );