我正在使用Helios SR2构建我的插件。支持伽利略很高兴,但我现在并不过分担心。 Windows 7:64位,64位JVM(1.6_21 IIRC)。
我的swt.custom.CCombo
框中填充了条目列表的显示值。我有一个“显示值”的地图 - > “储值”。
我想存储存储值,并显示显示值。去图。
我正在使用与BeanObservables,IObservables,DataBindingContext,所有爵士乐的数据绑定。
我当前的方法(不起作用或我不会问)是使用自定义UpdateValueStrategy
创建我自己的IConverter
,它将在内部映射两者之间。
我目前正在尝试扩展org.eclipse.core.databinding.conversion.Converter
,因为IConverter标有@noimplement
和@noextend
。 @noimplement
表示客户端应该扩展Converter
而不是直接实现IConverter(即使Converter非常简单)。
可悲的是,Eclipse的Java编译器告诉我这是禁止的:
访问限制:由于对所需库{install} \ plugins \ org.eclipse.core.databinding_1.3.100.I20100601-0800.jar
的限制,无法访问Converter类型
在相关的“.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>
感谢Google Code,我发现visibility="1"
表示公共API。好的,很棒。
restrictions="3"
表示@noextend @noimplement。听起来有点熟?好的,很棒。
但似乎对IConverter的限制正在转换为转换器,因此无法使用。我无法扩展Converter,也不能从构造函数中调用super(blah, blah)
。有趣的是,编译器不抱怨我public Object convert(Object fromObject)
的实现,即使Converter没有自己的实现,所以人们可能会认为IConverter
限制适用。< / p>
显然不是。
有没有人
我找到了编译器的“限制访问”设置,并将其切换为“警告”而不是“错误”。但是,我希望我能做的事情不那么全球化。我会在同一时间继续这样做,但另一种选择会很好。
答案 0 :(得分:0)
多么奇怪。
好的,当我尝试使用自动更正“include org.eclipse.core.databinding_1.3 ......”时,没有任何反应。我不知道它是否正确包含在插件依赖项中并且没有修复错误。
在此期间,该插件的jar出现在我的插件项目的“Plug-in Dependencies”文件夹中,我能够查看其来源。有人会认为插件正确地包含在plugin.xml
中一个人错了。
我手动添加了... core.databinding_1.3 ...我的插件依赖项和错误Went Away。
因此,这似乎是自动更正中的错误,而不是API限制代码中的错误。
AH!我在Imported Packages列表中有org.eclipse.core.databinding。那一定是抛弃了。
所以现在你知道了。并且知道有战斗。 GO CODE!
说到代码。这就是我正在做的事情(或多或少):
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的通用版本应该是相当简单的,但我会把它留作读者练习。