zoukankan      html  css  js  c++  java
  • 解决EMF里引用对象的刷新问题

    假设在ecore模型里定义了两个类:产品(Product)和制造商(Manufacturer),Product通过名为manufacturer的多对一引用与Manufacturer建立关系。在应用程序里,有一些表格(TableViewer)需要在显示产品信息的同时,还要显示制造商相关信息,如制造商名称。缺省条件下,因为这些表格里每一行是一个Product实例,表格的文字更新由AdapterFactoryLabelProvider通过ProductItemProvider实现,所以在制造商名称被改变的时候产品表格无法得到更新。

    当然可以直接调用viewer.refresh()方法刷新表格,但这要求具有对viewer的引用,况且我们不知道以后还会有多少个这样的viewer需要刷新。更好的解决办法是修改ProductItemProvider,让它维护一个Adapter(即EMF里的模型监听器),并把这个监听器注册到Product对应的Manufacturer实例上。监听器的注册可以在getText()方法里实现(也许有更合适的地方),别忘了在dispose()方法里要删除这个监听器。此外,要在.genmodel里把Product的Provider Type属性值从缺省的"Singleton"改为"Stateful",如下图,这样每个Product都对应一个ProductItemProvider实例,从而对应一个这样的监听器。


    以下是ProductItemProvider里部分相关代码:

    //Define an adapter
        protected Adapter manufacturerAdapter =
             new AdapterImpl()
             {
               public void notifyChanged(Notification notification)
               {
                 //notify product viewers if manufacturer's name changed
                 if (notification.getFeatureID(Manufacturer.class) == ProductPackage.MANUFACTURER__NAME)
                   fireNotifyChanged(new ViewerNotification(notification, ProductItemProvider.this.getTarget(), false, true));
               }
             };
    
        public String getText(Object object) {
            Product product = (Product) object;
    
            //Add following codes to maintain the adapter
            Manufacturer manufacturer = product.getManufacturer();
            if (manufacturer != manufacturerAdapter.getTarget()) {
                if (manufacturerAdapter.getTarget() != null)
                    manufacturerAdapter.getTarget().eAdapters().remove(manufacturerAdapter);
                if (manufacturer != null)
                    manufacturer.eAdapters().add(manufacturerAdapter);
            }
    
            String label = var.getName();
            return label;
        }
    
      //Remove adapter when ProductItemProvider disposes
        public void dispose() {
            if (manufacturerAdapter.getTarget() != null)
                manufacturerAdapter.getTarget().eAdapters().remove(manufacturerAdapter);
            super.dispose();
        } 

    最后,需要覆盖ProductItemProvider的notifyChanged()方法,在switch里增加如下代码:

    case ProductPackage.Product__Manufacturer:
        fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), false, true));
        return;

    参考:http://dev.eclipse.org/newslists/news.eclipse.tools.emf/msg18730.html

  • 相关阅读:
    beta冲刺—— Day 4
    beta冲刺—— Day 3
    beta冲刺—— Day 2
    刚下飞机——Beta阶段随笔集合
    刚下飞机——Alpha冲刺
    刚下飞机——Beta答辩博客
    刚下飞机——用户使用调查报告
    刚下飞机——Beta冲刺总结博客
    Beta冲刺(7/7)
    Beta冲刺(6/7)
  • 原文地址:https://www.cnblogs.com/bjzhanghao/p/880854.html
Copyright © 2011-2022 走看看