Eclipse: Попытка преобразовать значение «display» в CCombo в значение «storage» - PullRequest
0 голосов
/ 22 марта 2011

Я строю свой плагин в 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 довольно тривиален).

К сожалению, Java-компилятор Eclipse говорит мне, что нет-нет:

Ограничение доступа: преобразователь типов недоступен из-за ограничения на требуемую библиотеку {install} \ plugins \ 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>

С помощью Google Code я вижу, что visibility="1" означает общедоступный API.Хорошо, отлично.

restrictions="3" с другой стороны, означает @noextend @noimplement.Звучит знакомо?Хорошо, отлично.

Но кажется, что ограничения на IConverter стираются на Converter, делая невозможным использование.Я не могу расширить Converter, и я не могу вызвать super(blah, blah) из моего конструктора.Интересно, что компилятор не жалуется на мою реализацию public Object convert(Object fromObject), даже несмотря на то, что у Converter нет его собственной, поэтому можно подумать, что ограничения IConverter будут применяться.

Очевидно, нет.

У кого-нибудь есть

  • Совершенно другой подход?
  • Некоторые способы превратить это ограничение доступа в представление, желательно локальным способом, чтобы я не делал ничего глупого в другом месте.

Я обнаружил «ограниченный доступ»настройки для компилятора и переключили его на «предупреждение», а не «ошибка».Тем не менее, я надеюсь, что я могу сделать что-то менее глобальное.Я продолжу с этим в это время, но альтернатива была бы хороша.

1 Ответ

0 голосов
/ 22 марта 2011

Как странно.

Хорошо, когда я попытался использовать автокоррекцию "include org.eclipse.core.databinding_1.3 ...", ничего не произошло. Я уверен, что он был правильно включен как зависимость от плагина и не исправил ошибку.

За это время баночка этого плагина появилась в папке «Plug-in Dependencies» моего проекта плагина, и я смог просмотреть его источник. Можно подумать, что плагин был правильно включен в plugin.xml

Один был бы неправ.

Я вручную добавил ... core.databinding_1.3 ... к моим зависимостям плагина и ошибкам, ушедшим.

Так что, похоже, это ошибка в автокоррекции, а не в коде ограничения API.

АХ! Я имел 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 должно быть довольно тривиальным, но я оставлю это как упражнение для читателя.

...