/******************************************************************************* * 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 java.text.MessageFormat; 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.value.AbstractObservableValue; import org.eclipse.core.databinding.observable.value.IObservableValue; import org.eclipse.core.runtime.Assert; import com.rcpcompany.uibindings.model.utils.BasicUtils; /** * A decorating observable value that formats the decorated value with a {@link MessageFormat}. * <p> * When the message is <code>null</code> will the decorated valued just be copied through. * * @author Tonny Madsen, The RCP Company */ public class MessageFormatObservableValue extends AbstractObservableValue { /** * The current format - possible <code>null</code>. */ private String myFormat; /** * The observable to be decorated. */ private final IObservableValue myDecorated; /** * Constructs and returns a new observable value. * * @param decorated the decorated observable value * @param format the initial format - possibly <code>null</code> */ public MessageFormatObservableValue(IObservableValue decorated, String format) { super(); myDecorated = decorated; Assert.isTrue(decorated.getValueType() == String.class); setMessageFormat(format); if (format == null) { updateValue(); } } @Override public synchronized void dispose() { if (hasListeners()) { lastListenerRemoved(); } super.dispose(); } private final IChangeListener myChangeListener = new IChangeListener() { @Override public void handleChange(ChangeEvent event) { updateValue(); } }; @Override protected void firstListenerAdded() { myDecorated.addChangeListener(myChangeListener); super.firstListenerAdded(); } @Override protected void lastListenerRemoved() { myDecorated.removeChangeListener(myChangeListener); super.lastListenerRemoved(); } /** * Sets the format to use. * * @param format the new format */ public void setMessageFormat(String format) { if (format == null ? myFormat == null : format.equals(myFormat)) return; myFormat = format; updateValue(); } @Override public Object getValueType() { return String.class; } @Override protected Object doGetValue() { return myCurrectValue; } @Override protected void doSetValue(Object value) { if (myFormat != null) throw new IllegalStateException(getClass().getSimpleName() + " has format and can thus not be set"); myDecorated.setValue(value); } /** * The current decorated value. */ public String myCurrectValue; /** * Updates the current value and fires an event if needed. */ protected void updateValue() { String decoratedValue = null; final Object v = myDecorated.getValue(); final String origValue = v != null ? v.toString() : ""; if (myFormat == null) { decoratedValue = origValue; } else { decoratedValue = MessageFormat.format(myFormat, origValue); } if (BasicUtils.equals(decoratedValue, myCurrectValue)) return; fireValueChange(Diffs.createValueDiff(myCurrectValue, myCurrectValue = decoratedValue)); } }