我无法理解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);
}
}
问题
使用Observer
和Observable
“正确”方式还是我错过了什么?我不确定我是否已经掌握了RCP数据绑定的概念......
答案 0 :(得分:6)
我建议您阅读JFace Databinding并使用ViewerSupport
,ObservableListContentProvider
和BeanProperties
来简化工作。
您还可以看到一个工作示例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 );