2011-03-22 72 views
0

我在Helios SR2中構建了我的插件。支持伽利略會很高興,但在這一點上我並不過分擔心。 Windows 7:64位,64位JVM(1.6_21 IIRC)。Eclipse:嘗試將CCombo「顯示」值轉換爲「存儲」值


我有一個swt.custom.CCombo框填充條目列表的顯示值。我有一個「顯示值」 - >「存儲值」的地圖。

我想存儲存儲值,並顯示顯示值。去搞清楚。

我與BeanObservables,IObservables,DataBindingContext,所有爵士樂使用數據綁定。

我目前的方法(即不工作,或我不會問)是用自定義IConverter創建我自己的UpdateValueStrategy,它將在兩者之間進行內部映射。

我目前正試圖擴展org.eclipse.core.databinding.conversion.Converter,因爲IConverter標有@noimplement@noextend@noimplement指出客戶應該擴展Converter而不是直接實施IConverter(即使轉換器相當簡單)。

可悲的是,Eclipse的Java編譯器告訴我,這是一個禁忌:

訪問限制:該類型轉換器是不可訪問,由於所需的庫限制{安裝} \插件\ org.eclipse.core .databinding_1.3.100.I20100601-0800.jar

在相關 「.api_description」,我看到下面的XML:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<component name="org.eclipse.core.databinding_1.3.100.I20100601-0800" version="1.2"> 
    <plugin id="org.eclipse.core.databinding_1.3.100.I20100601-0800"/> 
    <package name="org.eclipse.core.databinding" visibility="1"> 
     <type name="ObservablesManager" restrictions="2"/> 
     <type name="UpdateListStrategy" restrictions="0"> 
      <method name="useMoveAndReplace" restrictions="8" signature="()Z"/> 
     </type> 
    </package> 
    <package name="org.eclipse.core.databinding.conversion" visibility="1"> 
     <type name="IConverter" restrictions="3"/> 
    </package> 
</component> 

生根感謝谷歌代碼,我發現visibility="1"意味着一個公共API。好的,太好了。

restrictions="3"另一方面,意味着@noextend @noimplement。聽起來有點熟?好的,太好了。

但是看起來IConverter上的限制在轉換器上擦掉了,使得它無法使用。我無法擴展Converter,也不能從我的構造函數中調用super(blah, blah)。有趣的是,編譯器是而不是抱怨我的執行public Object convert(Object fromObject),即使轉換器沒有它自己的一個,所以人們可能會認爲IConverter限制將適用。

顯然不是。

有沒有人有

  • 完全不同的方法?
  • 一些手段來打敗這種訪問限制的東西提交,最好以當地的方式,所以我不會在別的地方做一些愚蠢的事情。

我發現編譯器的「限制訪問」設置,並將它切換爲「警告」而不是「錯誤」。不過,我希望我能做的事情少一些。在此期間我會繼續進行此操作,但替代方案會很好。

回答

0

多麼奇怪。

好的,當我嘗試使用自動更正的「include org.eclipse.core.databinding_1.3 ...」時,什麼都沒有發生。我諷刺說,它被正確包含爲插件依賴項,並沒有修復錯誤。

在此期間,該插件的jar出現在我的插件項目的「Plug-in Dependencies」文件夾中,我可以查看它的源代碼。有人會認爲插件已正確包含在plugin.xml中

有人會錯。

我手動添加... core.databinding_1.3 ...到我的插件依賴和錯誤去。

所以看起來這是自動更正中的錯誤,而不是API限制代碼。

AH!我在我的導入包列表中有org.eclipse.core.databinding。這一定是拋棄了東西。

現在你知道了。知道有這場戰鬥。 GO代碼!


說到代碼。這是我在做什麼(或多或少):

enum MapValueDirection { 
    VALUE_TO_KEY, 
    KEY_TO_VALUE 
}; 

private class MappingConverter extends Converter { 
    Map<String, String> map = null; 

    public MappingConverter(Map<String, String> map_, MapValueDirection dir) { 
     super(String.class, String.class); 
     if (dir == MapValueDirection.VALUE_TO_KEY) { 
      map = reverseMap(map_); 
     } else { 
      map = map_; 
     } 
    } 

    private Map<String, String> reverseMap(Map<String, String> map_) { 
     Map<String, String> reversedMap = new TreeMap<String, String>(); 
     Set<Entry<String, String>> entries = map_.entrySet(); 
     for (Entry<String, String> curEnt : entries) { 
      reversedMap.put(curEnt.getValue(), curEnt.getKey()); 
     } 
     return reversedMap; 
    } 


    /* (non-Javadoc) 
    * @see org.eclipse.core.databinding.conversion.IConverter#convert(java.lang.Object) 
    */ 
    public Object convert(Object fromObject) { 
     if (map != null && fromObject != null && String.class.equals(fromObject.getClass())) { 
      Object newVal = map.get(fromObject); 
      if (newVal == null) { 
       newVal = fromObject; 
      } 
      return newVal; 
     } 
     return fromObject; 
    } 
} 

/** 
* And this is were the actual work gets done. 
*/ 
public void bindBean(Object bean, PropertyDescriptor prop) { 
    Control curControl = getControl(prop.getPropertyType()); 
    IObservableValue uiElement = getObserver(prop, curControl); 
    IOvservableValue modelElement = BeanObservables.observValue(bean, prop.getName()); 

    // "display" = key, "storage" = value 
    Map<String, String> profileFlds = getProfileFields(); 

    UpdateValueStrategy toStorage = new UpdateValueStrategy(); 
    toStorage.setConverter(new MappingConverter(profileFlds, MapValueDirection.KEY_TO_VALUE)); 

    UpdateValueStrategy toDisplay = new UpdateValueStrategy(); 
    toDisplay .setConverter(new MappingConverter(profileFlds, MapValueDirection.VALUE_TO_KEY)); 

    m_bindingContext.bindValue(uiElement, modelElement, toDisplay , toStorage); 
} 

我的實際代碼比這更復雜一點,但你明白了。我懷疑這不是非常有效,但它在整個數據綁定框架內運行良好,從概念上講(基於我公認的有限的經驗)。

製作MappingConverter的通用版本應該相當簡單,但我會將其作爲讀者的練習。