值变更监听器未触发

时间:2018-12-13 16:44:35

标签: java data-binding jface

我正在尝试在自定义(非swt非JFACE)日期时间小部件上实现JFace数据绑定。该小部件由第三方从头开始制作,我们在应用程序中使用它。

我正在尝试向其添加数据绑定,并且在我创建绑定时,“ fillInitialValue”方法确实能够将正确的日期放入小部件中,但是它几乎可以正常工作,但是值更改侦听器是不起作用(其中的断点,根本不执行)。

在ValueBinding类(org.eclipse.core.databinding)中,它确实添加了侦听器

target.addValueChangeListener(targetChangeListener);

目标是我的AbstractObservableValue实现(DateChooserObserver),而侦听器是默认的

private IValueChangeListener targetChangeListener = new IValueChangeListener() {
    @Override
    public void handleValueChange(ValueChangeEvent event) {
        if (!updatingTarget
                && !Util.equals(event.diff.getOldValue(), event.diff
                        .getNewValue())) {
            doUpdate(target, model, targetToModel, false, false);
        }
    }
};

这是我的目标观察者:

public class DateChooserObserver extends AbstractObservableValue<Date> {

    private DateChooserCombo widget;

    public DateChooserObserver(DateChooserCombo widget) {
        super();
        this.widget = widget;
    }

    @Override
    public Object getValueType() {
        return Date.class;
    }

    @Override
    protected Date doGetValue() {
        return widget.getValue();
    }

    @Override
    protected void doSetValue(Date value) {
        widget.setValue(value);
    }

}

我唯一能想到的是,我可能需要(以某种方式)在实际的日期字段而不是小部件上放置一个值更改观察器,但我不确定如何。

我不知道为什么它不起作用。我确实拥有的两个转换器(将属性转换为小部件和将小部件转换为属性)都最初启动,但是,就像我说的那样,侦听器未检测到小部件的java.util.date字段(或小部件本身)中的更改。 ,我不知道),并且在选择新日期时未执行将小部件转换为属性

1 个答案:

答案 0 :(得分:0)

为避免成为DenverCoder9,我将提交所有解决方案。

第一件事:我没有对正在使用的小部件的完全访问权限,因此我无法实现“正确”的实现,但确实找到了解决方法:

AbstractObservableValue类具有一个addValueChangeListener(ValueChangeListener listener)方法,您可以重写该方法。这样可以直接访问侦听器,并且可以强制激活它的“ handleEvent”方法。

我现在没有实际的代码,希望我不要忘记下周一更新此答案,但是解决方案是这样的:

public class DateChooserObserver extends AbstractObservableValue<Date> {

    ...

    @Override
    public void setValueChangeListener(ValueChangeListener listener) {
        super.setValueChangeListener(listener);
        widget.getText().addModifyListener(e -> {
            listener.handleEvent(new ValueChangeEvent(this, getDummyDiff();
        });
    }

    // returns a diff with different dates to always evaluate true in doUpdate()
    public ValueDiff<Date> getDummyDiff() {
        return new ValueDiff() {

            @Override
            public Date getOldValue() {
                return new Date(1,1,1);
            }

            @Override
            public Date getNewValue() {
                return new Date(1,1,2);
            }
        }

    }

升级将是在差异中提供实际的旧/新日期,因为如果日期未更改,它将尝试不执行更新,但是我无法获取它们,因此“始终为真” diff是我唯一的解决方案。

TL; DR,有一个侦听器,侦听器会做事,但如果您没有兼容的小部件或无法访问小部件的内部工作原理,则需要强制该侦听器的handle事件。

P.S。我不确定doUpdate()是否是数据绑定中方法的名称,只是一个占位符,无论如何都没有任何意义。