All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.beans.observables.properties.ObservablePropertyBase Maven / Gradle / Ivy

package com.beans.observables.properties;

import com.beans.observables.ObservableValue;
import com.beans.observables.binding.ObservableBinding;
import com.beans.observables.binding.PropertyBindingController;
import com.beans.observables.listeners.ChangeEvent;
import com.beans.observables.listeners.ChangeListener;
import com.beans.observables.listeners.ObservableEventController;
import com.notifier.EventController;

import java.lang.ref.WeakReference;
import java.util.Optional;
import java.util.function.Consumer;

/**
 * 

* Base for {@link ObservableProperty} implementations. *

*

* Provides implementations for {@link #addChangeListener(ChangeListener)}, {@link #removeChangeListener(ChangeListener)}. * Provides {@link #fireValueChangedEvent(Object, Object)} for extending classes to fire changed event. *

*

* This class can be thread-safe by defining so in the constructor. * * The thread safety manifest in the manner of accessing the list of added * listener, making {@link #addChangeListener(ChangeListener)} and {@link #removeChangeListener(ChangeListener)} * thread-safe. But, although {@link #fireValueChangedEvent(Object, Object)} is safe * in accessing the listener list, it does not limit threads from firing the event multiple times concurrently. *

* * @param type of the property data * * @since JavaBeans 1.0 */ public abstract class ObservablePropertyBase implements ObservableProperty { private final ObservableEventController mEventController; private final PropertyBindingController mBindingController; protected ObservablePropertyBase(ObservableEventController eventController, PropertyBindingController bindingController) { mEventController = eventController; mBindingController = bindingController; } protected ObservablePropertyBase(EventController eventController, PropertyBindingController bindingController) { mEventController = new ObservableEventController.Impl<>(eventController, this); mBindingController = bindingController; } @Override public final void addChangeListener(ChangeListener changeListener) { mEventController.addListener(changeListener); } @Override public final void removeChangeListener(ChangeListener changeListener) { mEventController.removeListener(changeListener); } @Override public final void bind(ObservableValue observableValue) { mBindingController.bind(observableValue, new BoundChangeHandler<>(this)); } @Override public final void bindBidirectional(ObservableProperty observableProperty) { mBindingController.bindBidirectional(observableProperty, new BoundChangeHandler<>(this)); } @Override public final void unbind() { Optional> optional = mBindingController.unbind(); if (optional.isPresent()) { ObservableBinding binding = optional.get(); setInternalDirect(binding.get()); } } /** * Invokes all added listeners, notifying them that the value has changed. * * @param oldValue the old value of the property, before the change. * @param newValue the new value of the property. */ protected final void fireValueChangedEvent(T oldValue, T newValue) { mEventController.fire(new ChangeEvent<>(this, oldValue, newValue)); } protected final boolean isBound() { return mBindingController.isBound(); } protected final Optional> getBound() { return mBindingController.getBinding(); } protected final boolean setIfBound(T value) { Optional> bindingOptional = getBound(); if (bindingOptional.isPresent()) { bindingOptional.get().set(value); return true; } return false; } protected final Optional getIfBound() { Optional> bindingOptional = getBound(); if (bindingOptional.isPresent()) { T value = bindingOptional.get().get(); setInternalDirect(value); return Optional.of(value); } return Optional.empty(); } protected abstract void setInternalDirect(T value); @Override public String toString() { return String.format("ObservableProperty [value=%s]", String.valueOf(get())); } private static class BoundChangeHandler implements Consumer> { private final WeakReference> mPropertyBase; private BoundChangeHandler(ObservablePropertyBase propertyBase) { mPropertyBase = new WeakReference<>(propertyBase); } @Override public void accept(ChangeEvent event) { ObservablePropertyBase propertyBase = mPropertyBase.get(); if (propertyBase == null) { return; } propertyBase.fireValueChangedEvent(event.getOldValue(), event.getNewValue()); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy