JFace TableViewer应该对更改列表做出反应

时间:2013-03-01 14:33:35

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

我们有以下场景:Eclipse 4 RCP-Application应该写一个日志输出。这些日志通过OSGi-Service绑定,并应使用JFace TableViewer显示。

这适用于此ViewPart的首次启动。 (因为已有日志)如果另一个插件在View启动后写入日志,则此视图也应该更新。包含视图日志(作为模型的一部分)的ArrayList已正确更新。

该表以这种方式设置:

@PostConstruct 

public void createControls(Composite parent) {
    b = new TableViewerBuilder(parent);
    b.createColumn("Datum").bindToProperty("time").build();
    b.createColumn("Message").bindToProperty("message").build();
    b.createColumn("Level").bindToProperty("level").build();
    b.createColumn("Bundle").bindToProperty("bundle").build();
    m_bindingContext = initDataBindings();
}

数据绑定是这样做的:

protected DataBindingContext initDataBindings() {
    DataBindingContext bindingContext = new DataBindingContext();
    input = new WritableList(logItemList.getItems(), LogItem.class);
    ViewerSupport.bind(tableViewer, input, BeanProperties
        .values(new String[] { "time", "message", "level" }));
    return bindingContext;

}

我们从列表中获取项目(正确更新)并将它们放入WritableList中。此列表绑定到TableViewer并显示时间戳,消息和某种日志级别。

LogItemList以这种方式设置:

public class LogItemList extends ModelObject {
     [.. stuff ..]
    private List<LogItem> items;

    public List<LogItem> getItems() {
        return items;
    }
    public void addItem(LoggingItem item) {
        LogItem logItem = new LogItem(item);
        List<LogItem> tmp = items;
        items.add(logItem);

        firePropertyChange("items", tmp, items);
    }
}

firePropertyChange - 方法继承自ModelObject - 类。

    public class ModelObject {
        private PropertyChangeSupport changeSupport = 
             new PropertyChangeSupport(this);
        protected void firePropertyChange(String propertyName, 
            Object oldValue,
            Object newValue) {
          changeSupport.firePropertyChange(propertyName, oldValue, newValue);
    }

我认为TableViewer / Databinding会对此更改事件做出反应,但事实并非如此。

有人对如何做到这一点有任何想法吗?

提前致谢, 斯特芬

1 个答案:

答案 0 :(得分:1)

WritableList不会自动监控列表。 (List如何没有通知界面?)

最简单的方法是使用LogItemList.items代替WriteableList来实施ArrayList。缺点是核心模型不像它本来应该的那样干净。

或者,您可以向传播到LogItemList的{​​{1}}添加一个侦听器。也许是一个“更清洁”的解决方案,但需要更多的工作,因为你需要子类'WritableList`。

或者您可以根据EMF实施核心模型并使用WritableList.fireListChanged(...)。方式更多的工作,但实际上,我会这样做: - )