|
|
Re: EMF data binding: one model value split to multiple targets [message #1219368 is a reply to message #1219336] |
Tue, 03 December 2013 14:41 |
Martin Jacob Messages: 191 Registered: July 2009 |
Senior Member |
|
|
Thank you Tom.
I implemented in the following way:
package de.bahntechnik.dd.util.eclipse.emf.ui.widgets;
import static de.bahntechnik.dd.util.i18n.I18n._;
import java.util.Calendar;
import java.util.TimeZone;
import org.eclipse.core.databinding.observable.Diffs;
import org.eclipse.core.databinding.observable.value.AbstractObservableValue;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.emf.databinding.EMFDataBindingContext;
import org.eclipse.emf.databinding.FeaturePath;
import org.eclipse.emf.databinding.edit.EMFEditProperties;
import org.eclipse.emf.databinding.edit.IEMFEditValueProperty;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Spinner;
import de.bahntechnik.dd.util.eclipse.emf.ui.IEMFUiBinding;
public class SpinnerTime extends Composite implements IEMFUiBinding {
protected FeaturePath mFeaturePath;
protected EditingDomain mEditingDomain;
protected IObservableValue mOvModel = null;
protected IObservableValue mOvTarget = null;
private Spinner mSpinnerDay;
private Spinner mSpinnerHour;
private Spinner mSpinnerMinute;
private Spinner mSpinnerSecond;
private Object mCachedValue;
private long mTimeMin_ms;
private long mTimeMax_ms;
public SpinnerTime(Composite pParent, int pStyle, EditingDomain pEditingDomain,
EStructuralFeature[] pFeaturePath) {
this(pParent, pStyle, pEditingDomain, null, pFeaturePath);
}
public SpinnerTime(Composite pParent, int pStyle, EditingDomain pEditingDomain, EObject pEOb,
EStructuralFeature[] pFeaturePath) {
super(pParent, pStyle);
mEditingDomain = pEditingDomain;
mFeaturePath = FeaturePath.fromList(pFeaturePath);
createContent();
updateBinding(pEOb);
}
protected void createContent() {
this.setLayout(new GridLayout(6, false));
mSpinnerDay = new Spinner(this, SWT.NONE);
mSpinnerDay.setMinimum(1);
mSpinnerDay.setDigits(0);
mSpinnerDay.setIncrement(1);
mSpinnerDay.setToolTipText(_("day"));
mSpinnerHour = new Spinner(this, SWT.NONE);
mSpinnerHour.setMinimum(0);
mSpinnerHour.setMaximum(23);
mSpinnerHour.setDigits(0);
mSpinnerHour.setIncrement(1);
mSpinnerHour.setToolTipText(_("hour"));
Label lLabel = new Label(this, SWT.NONE);
lLabel.setText(":");
mSpinnerMinute = new Spinner(this, SWT.NONE);
mSpinnerMinute.setMinimum(0);
mSpinnerMinute.setMaximum(59);
mSpinnerMinute.setDigits(0);
mSpinnerMinute.setIncrement(1);
mSpinnerMinute.setPageIncrement(10);
mSpinnerMinute.setToolTipText(_("minute"));
lLabel = new Label(this, SWT.NONE);
lLabel.setText(":");
mSpinnerSecond = new Spinner(this, SWT.NONE);
mSpinnerSecond.setMinimum(0);
mSpinnerSecond.setMaximum(599);
mSpinnerSecond.setDigits(1);
mSpinnerSecond.setIncrement(1);
mSpinnerSecond.setPageIncrement(10);
mSpinnerSecond.setToolTipText(_("second"));
}
@Override
public void updateBinding() {
if (null != mOvModel) {
mOvModel.dispose();
mOvModel = null;
}
if (null != mOvTarget) {
mOvTarget.dispose();
mOvTarget = null;
}
}
@Override
public void updateBinding(EObject pEObj) {
updateBinding();
if (null != pEObj) {
EMFDataBindingContext lCtx = new EMFDataBindingContext();
IEMFEditValueProperty lProp = EMFEditProperties.value(mEditingDomain, mFeaturePath);
mOvModel = lProp.observe(pEObj);
mOvTarget = new SpinnerTimeObservableValue();
lCtx.bindValue(mOvTarget, mOvModel);
}
}
@Override
public void dispose() {
updateBinding();
super.dispose();
}
protected class SpinnerTimeObservableValue extends AbstractObservableValue implements ModifyListener {
public SpinnerTimeObservableValue() {
mSpinnerDay.addModifyListener(this);
mSpinnerHour.addModifyListener(this);
mSpinnerMinute.addModifyListener(this);
mSpinnerSecond.addModifyListener(this);
}
@Override
public Object getValueType() {
return Calendar.class;
}
@Override
protected Object doGetValue() {
Calendar lRet = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
lRet.setTimeInMillis(0);
lRet.set(Calendar.DAY_OF_YEAR, mSpinnerDay.getSelection());
lRet.set(Calendar.HOUR_OF_DAY, mSpinnerHour.getSelection());
lRet.set(Calendar.MINUTE, mSpinnerMinute.getSelection());
lRet.set(Calendar.SECOND, ((int) Math.floor(mSpinnerSecond.getSelection() / 10.0)));
lRet.set(Calendar.MILLISECOND,
(int) Math.round(((mSpinnerSecond.getSelection() / 10.0 -
Math.floor(mSpinnerSecond.getSelection() / 10.0)) * 10)) * 100);
return lRet.getTimeInMillis();
}
@Override
protected void doSetValue(Object value) {
if (value instanceof Long) {
Calendar lCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
lCal.setTimeInMillis((Long) value);
mSpinnerDay.setSelection(lCal.get(Calendar.DAY_OF_YEAR));
mSpinnerHour.setSelection(lCal.get(Calendar.HOUR_OF_DAY));
mSpinnerMinute.setSelection(lCal.get(Calendar.MINUTE));
mSpinnerSecond.setSelection((lCal.get(Calendar.SECOND) * 10 + lCal.get(Calendar.MILLISECOND) /
100));
} else {
throw new IllegalArgumentException("Unsupported value type! " +
value.getClass().getCanonicalName());
}
}
@Override
public synchronized void dispose() {
mSpinnerDay.removeModifyListener(this);
mSpinnerHour.removeModifyListener(this);
mSpinnerMinute.removeModifyListener(this);
mSpinnerSecond.removeModifyListener(this);
super.dispose();
}
@Override
public void modifyText(ModifyEvent e) {
Object lOldValue = mCachedValue;
mCachedValue = doGetValue();
fireValueChange(Diffs.createValueDiff(lOldValue, mCachedValue));
}
}
}
schrieb Tom Schindl, Am 03.12.2013 12:58:
> Did you take a look at how DateAndTimeObservableValue is working? I
> think you have a very similar use case!
>
> Tom
>
> On 03.12.13 11:59, Martin Jacob wrote:
>> Hi,
>>
>> I have to implement a time editor using separate
>> org.eclipse.swt.widgets.Spinner for day, hour, minute and second.
>> The model has just one value for time.
>> To write a converter from model to target is easy. e.g.:
>> protected class ModelToTargetUpdateStrategyDay extends
>> UpdateValueStrategy {
>> @Override
>> public Object convert(Object value) {
>> Calendar lCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
>> lCal.setTimeInMillis(Long.valueOf((String) value));
>> return lCal.get(Calendar.DAY_OF_YEAR);
>> }
>> }
>>
>> But the converter from target to model is my problem. I guess its not a
>> good idea to get the current values from all spinners to calculate the
>> return value. But is there another better way to do?
>>
>>
>> PS: The reason I have to implement this is because the
>> org.eclipse.swt.widgets.Combo can not display >65000 values.
>>
>> any help is appreciated, Martin
>
|
|
|
Powered by
FUDForum. Page generated in 0.03010 seconds