Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package de.asysgmbh.lib.fx.property.impl;
- import de.asysgmbh.lib.fx.property.CustomBindings;
- import java.lang.ref.WeakReference;
- import java.util.Objects;
- import java.util.function.Function;
- import javafx.beans.WeakListener;
- import javafx.beans.property.Property;
- import javafx.beans.value.ChangeListener;
- import javafx.beans.value.ObservableValue;
- /**
- *
- * @author Tobias Oelgarte ([email protected])
- * @param <A>
- * @param <B>
- */
- public class CustomBidirectionalBinding<A, B> implements ChangeListener<Object>, WeakListener {
- private static final System.Logger LOGGER = System.getLogger(CustomBindings.class.getName());
- private static <A, B> void checkParameters(Property<A> a, Property<B> b) {
- Objects.requireNonNull(a, "First property must be specified");
- Objects.requireNonNull(b, "Second property must be specified");
- if (a == b) {
- throw new IllegalArgumentException("Cannot bind property to itself");
- }
- }
- public static <A, B> CustomBidirectionalBinding<A, B> bind(Property<A> a, Property<B> b, Function<A, B> convertTo, Function<B, A> convertFrom) {
- checkParameters(a, b);
- Objects.requireNonNull(convertTo, "convertTo can not be null");
- Objects.requireNonNull(convertFrom, "convertFrom can not be null");
- final CustomBidirectionalBinding<A, B> binding = new CustomBidirectionalBinding<>(a, b, convertTo, convertFrom);
- a.setValue(convertFrom.apply(b.getValue()));
- a.addListener(binding);
- b.addListener(binding);
- return binding;
- }
- public static <A, B> void unbind(Property<A> a, Property<B> b) {
- checkParameters(a, b);
- final CustomBidirectionalBinding<A, B> binding = new CustomBidirectionalBinding<>(a, b, null, null);
- a.removeListener(binding);
- b.removeListener(binding);
- }
- private final WeakReference<Property<A>> aRef;
- private final WeakReference<Property<B>> bRef;
- private final Function<A, B> convertTo;
- private final Function<B, A> convertFrom;
- private final int cachedHashCode;
- private boolean updating;
- private CustomBidirectionalBinding(Property<A> a, Property<B> b, Function<A, B> convertTo, Function<B, A> convertFrom) {
- aRef = new WeakReference<>(a);
- bRef = new WeakReference<>(b);
- this.convertTo = convertTo;
- this.convertFrom = convertFrom;
- cachedHashCode = a.hashCode() * b.hashCode();
- }
- protected Property<A> getPropertyA() {
- return aRef.get();
- }
- protected Property<B> getPropertyB() {
- return bRef.get();
- }
- @Override
- public int hashCode() {
- return cachedHashCode;
- }
- @Override
- public boolean wasGarbageCollected() {
- return (getPropertyA() == null) || (getPropertyB() == null);
- }
- /**
- * Special equals method that considers two different CustomBindings as equal as long they refer to the same
- * properties, independent of order.
- *
- * @param obj The reference object with which to compare.
- * @return {@code true} if the two bindings are considered equal.
- */
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- final Object a = getPropertyA();
- final Object b = getPropertyB();
- if ((a == null) || (b == null)) {
- return false;
- }
- if (obj instanceof CustomBidirectionalBinding) {
- final CustomBidirectionalBinding<?, ?> other = (CustomBidirectionalBinding) obj;
- final Object otherA = other.getPropertyA();
- final Object otherB = other.getPropertyB();
- if ((otherA == null) || (otherB == null)) {
- return false;
- }
- if (a == otherA && b == otherB) {
- return true;
- }
- if (a == otherB && b == otherA) {
- return true;
- }
- }
- return false;
- }
- @Override
- public void changed(ObservableValue<? extends Object> ov, Object oldValue, Object newValue) {
- if (updating) {
- return;
- }
- final Property<A> a = getPropertyA();
- final Property<B> b = getPropertyB();
- if ((a == null) || (b == null)) {
- if (a != null) {
- a.removeListener(this);
- }
- if (b != null) {
- b.removeListener(this);
- }
- } else {
- try {
- updating = true;
- if (a == ov) {
- try {
- b.setValue(convertTo.apply(a.getValue()));
- } catch (Exception ex) {
- LOGGER.log(System.Logger.Level.WARNING, "Exception while converting in custom bidirectional binding", ex);
- b.setValue(null);
- }
- } else {
- try {
- a.setValue(convertFrom.apply(b.getValue()));
- } catch (Exception ex) {
- LOGGER.log(System.Logger.Level.WARNING, "Exception while converting in custom bidirectional binding", ex);
- a.setValue(null);
- }
- }
- } finally {
- updating = false;
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment