/******************************************************************************* * Copyright (c) 2006-2013 The RCP Company and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * The RCP Company - initial API and implementation *******************************************************************************/ package com.rcpcompany.uibindings.observables; import org.eclipse.core.databinding.observable.ChangeEvent; import org.eclipse.core.databinding.observable.Diffs; import org.eclipse.core.databinding.observable.IChangeListener; import org.eclipse.core.databinding.observable.IObserving; import org.eclipse.core.databinding.observable.value.AbstractObservableValue; import org.eclipse.core.databinding.observable.value.IObservableValue; import org.eclipse.core.runtime.Assert; import org.eclipse.emf.ecore.EcorePackage; /** * Observable value that will return <code>true</code> or <code>false</code> if an observed value * has a specific guard value. * <p> * Note that although it is possible to set this observable value to <code>true</code> - which sets * the observed value to the guard value - it is not possible to set it to <code>false</code>. * <p> * The primary use of this observable value is as the observable for radio button groups. * * @author Tonny Madsen, The RCP Company */ public class GuardObservableValue extends AbstractObservableValue implements IObserving { private final IObservableValue myObserved; private final Object myGuardValue; private final boolean myNegate; /** * Constructs and returns a new observable guard value. * * @param observed the observed value * @param guardValue the guard value * @param negate TODO */ public GuardObservableValue(IObservableValue observed, Object guardValue, boolean negate) { super(observed.getRealm()); Assert.isNotNull(observed); Assert.isNotNull(guardValue); myObserved = observed; myGuardValue = guardValue; myNegate = negate; currentValue = doGetValue(); } /** * The current value of this observable */ protected Object currentValue; private final IChangeListener myListListener = new IChangeListener() { @Override public void handleChange(ChangeEvent event) { final Object newValue = doGetValue(); if (currentValue != newValue) { fireValueChange(Diffs.createValueDiff(currentValue, currentValue = newValue)); } } }; @Override public synchronized void dispose() { if (hasListeners()) { lastListenerRemoved(); } super.dispose(); } @Override protected void firstListenerAdded() { super.firstListenerAdded(); myObserved.addChangeListener(myListListener); } @Override protected void lastListenerRemoved() { myObserved.removeChangeListener(myListListener); super.lastListenerRemoved(); } @Override protected Object doGetValue() { return myGuardValue.equals(myObserved.getValue()) ^ myNegate; } @Override protected void doSetValue(Object value) { if (!(value instanceof Boolean)) throw new IllegalStateException("Value of " + this.getClass().getSimpleName() + " must be boolean"); if ((Boolean) value != myNegate) { myObserved.setValue(myGuardValue); } } @Override public Object getValueType() { return EcorePackage.Literals.EBOOLEAN; } @Override public Object getObserved() { return myObserved; } }