/******************************************************************************* * Copyright (c) 2014 Bruno Medeiros and other Contributors. * 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: * Bruno Medeiros - initial API and implementation *******************************************************************************/ package melnorme.utilbox.fields; import static melnorme.utilbox.core.Assert.AssertNamespace.assertNotNull; import java.util.function.Supplier; import melnorme.utilbox.fields.FieldValueListener.FieldChangeListener; import melnorme.utilbox.ownership.IDisposable; import melnorme.utilbox.ownership.IOwner; /** * A read-only access for an observable value. * * Whenever the observable value changes, the registered listeners are notified. */ public interface IFieldView<VALUE> extends Supplier<VALUE> { @Override default VALUE get() { return getFieldValue(); } VALUE getFieldValue(); void addListener(FieldValueListener<? super VALUE> listener); default void addListener(boolean initialize, FieldValueListener<VALUE> listener) { addListener(listener); if(initialize) { listener.fieldValueChanged(getFieldValue()); } } // Alternative method to be used with lambda expressions. default void addChangeListener(FieldChangeListener listener) { addListener(listener); } void removeListener(FieldValueListener<? super VALUE> listener); /* ----------------- ----------------- */ default FieldListenerRegistration registerListener(FieldValueListener<? super VALUE> listener) { addListener(listener); return new FieldListenerRegistration(this, listener); } default FieldListenerRegistration registerListener( boolean initListener, FieldValueListener<? super VALUE> listener) { FieldListenerRegistration binding = registerListener(listener); if(initListener) { listener.fieldValueChanged(getFieldValue()); } return binding; } default FieldListenerRegistration registerChangeListener(boolean initListener, FieldChangeListener listener) { return registerListener(initListener, listener); } /** * Register a value changed listener, that automatically get unregistered when given ownedList is disposed. */ default void bindOwnedListener(IOwner owner, FieldValueListener<VALUE> listener) { registerListener(listener).bindLifetime(owner); } default void bindOwnedListener(IOwner owner, boolean initListener, FieldValueListener<VALUE> listener) { registerListener(listener).bindLifetime(owner); if(initListener) { listener.fieldValueChanged(getFieldValue()); } } public static class FieldListenerRegistration implements IDisposable { protected final IFieldView<?> field; @SuppressWarnings("rawtypes") protected final FieldValueListener listener; public <T> FieldListenerRegistration(IFieldView<T> field, FieldValueListener<? super T> listener) { this.field = assertNotNull(field); this.listener = assertNotNull(listener); } @Override public void dispose() { field.removeListener(listener); } public void bindLifetime(IOwner owner) { owner.bind(this); } } /* ----------------- ----------------- */ @SuppressWarnings("unchecked") public static <T> IFieldView<T> NULL_FIELD_VIEW() { return (IFieldView<T>) NULL_FIELD_VIEW; } public static final IFieldView<Object> NULL_FIELD_VIEW = new IFieldView<Object>() { @Override public Object getFieldValue() { return null; } @Override public void addListener(FieldValueListener<Object> listener) { // Do nothing } @Override public void removeListener(FieldValueListener<Object> listener) { // Do nothing } }; }