6

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

这就是我想做的

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

这是我到目前为止所做的

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

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

代码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 数据绑定的概念......

4

2 回答 2

6

我建议您阅读JFace 数据绑定并使用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用于绑定很重要。

于 2013-07-20T04:57:59.760 回答
1

I don't think there's anything wrong with your approach with one possible exception. You need to make sure that the viewer is refreshed in the UI thread:

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

However there are things that you can do to make the table update more efficient. In your code above it appears to only add a single item at the top of the table, so you'd be better with a call to:

viewer.insert( text, 0 );
于 2013-07-12T08:22:56.927 回答