Guest User

Untitled

a guest
Jun 3rd, 2021
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.55 KB | None | 0 0
  1. package de.asysgmbh.lib.fx.property.impl;
  2.  
  3. import de.asysgmbh.lib.fx.property.CustomBindings;
  4. import java.lang.ref.WeakReference;
  5. import java.util.Objects;
  6. import java.util.function.Function;
  7. import javafx.beans.WeakListener;
  8. import javafx.beans.property.Property;
  9. import javafx.beans.value.ChangeListener;
  10. import javafx.beans.value.ObservableValue;
  11.  
  12. /**
  13.  *
  14.  * @author Tobias Oelgarte ([email protected])
  15.  * @param <A>
  16.  * @param <B>
  17.  */
  18. public class CustomBidirectionalBinding<A, B> implements ChangeListener<Object>, WeakListener {
  19.  
  20.     private static final System.Logger LOGGER = System.getLogger(CustomBindings.class.getName());
  21.  
  22.     private static <A, B> void checkParameters(Property<A> a, Property<B> b) {
  23.         Objects.requireNonNull(a, "First property must be specified");
  24.         Objects.requireNonNull(b, "Second property must be specified");
  25.         if (a == b) {
  26.             throw new IllegalArgumentException("Cannot bind property to itself");
  27.         }
  28.     }
  29.  
  30.     public static <A, B> CustomBidirectionalBinding<A, B> bind(Property<A> a, Property<B> b, Function<A, B> convertTo, Function<B, A> convertFrom) {
  31.         checkParameters(a, b);
  32.         Objects.requireNonNull(convertTo, "convertTo can not be null");
  33.         Objects.requireNonNull(convertFrom, "convertFrom can not be null");
  34.         final CustomBidirectionalBinding<A, B> binding = new CustomBidirectionalBinding<>(a, b, convertTo, convertFrom);
  35.         a.setValue(convertFrom.apply(b.getValue()));
  36.         a.addListener(binding);
  37.         b.addListener(binding);
  38.         return binding;
  39.     }
  40.  
  41.     public static <A, B> void unbind(Property<A> a, Property<B> b) {
  42.         checkParameters(a, b);
  43.         final CustomBidirectionalBinding<A, B> binding = new CustomBidirectionalBinding<>(a, b, null, null);
  44.         a.removeListener(binding);
  45.         b.removeListener(binding);
  46.     }
  47.  
  48.     private final WeakReference<Property<A>> aRef;
  49.     private final WeakReference<Property<B>> bRef;
  50.     private final Function<A, B> convertTo;
  51.     private final Function<B, A> convertFrom;
  52.     private final int cachedHashCode;
  53.     private boolean updating;
  54.  
  55.     private CustomBidirectionalBinding(Property<A> a, Property<B> b, Function<A, B> convertTo, Function<B, A> convertFrom) {
  56.         aRef = new WeakReference<>(a);
  57.         bRef = new WeakReference<>(b);
  58.         this.convertTo = convertTo;
  59.         this.convertFrom = convertFrom;
  60.         cachedHashCode = a.hashCode() * b.hashCode();
  61.     }
  62.  
  63.     protected Property<A> getPropertyA() {
  64.         return aRef.get();
  65.     }
  66.  
  67.     protected Property<B> getPropertyB() {
  68.         return bRef.get();
  69.     }
  70.  
  71.     @Override
  72.     public int hashCode() {
  73.         return cachedHashCode;
  74.     }
  75.  
  76.     @Override
  77.     public boolean wasGarbageCollected() {
  78.         return (getPropertyA() == null) || (getPropertyB() == null);
  79.     }
  80.  
  81.     /**
  82.      * Special equals method that considers two different CustomBindings as equal as long they refer to the same
  83.      * properties, independent of order.
  84.      *
  85.      * @param obj The reference object with which to compare.
  86.      * @return {@code true} if the two bindings are considered equal.
  87.      */
  88.     @Override
  89.     public boolean equals(Object obj) {
  90.         if (this == obj) {
  91.             return true;
  92.         }
  93.  
  94.         final Object a = getPropertyA();
  95.         final Object b = getPropertyB();
  96.         if ((a == null) || (b == null)) {
  97.             return false;
  98.         }
  99.  
  100.         if (obj instanceof CustomBidirectionalBinding) {
  101.             final CustomBidirectionalBinding<?, ?> other = (CustomBidirectionalBinding) obj;
  102.             final Object otherA = other.getPropertyA();
  103.             final Object otherB = other.getPropertyB();
  104.             if ((otherA == null) || (otherB == null)) {
  105.                 return false;
  106.             }
  107.  
  108.             if (a == otherA && b == otherB) {
  109.                 return true;
  110.             }
  111.             if (a == otherB && b == otherA) {
  112.                 return true;
  113.             }
  114.         }
  115.         return false;
  116.     }
  117.  
  118.     @Override
  119.     public void changed(ObservableValue<? extends Object> ov, Object oldValue, Object newValue) {
  120.         if (updating) {
  121.             return;
  122.         }
  123.         final Property<A> a = getPropertyA();
  124.         final Property<B> b = getPropertyB();
  125.         if ((a == null) || (b == null)) {
  126.             if (a != null) {
  127.                 a.removeListener(this);
  128.             }
  129.             if (b != null) {
  130.                 b.removeListener(this);
  131.             }
  132.         } else {
  133.             try {
  134.                 updating = true;
  135.                 if (a == ov) {
  136.                     try {
  137.                         b.setValue(convertTo.apply(a.getValue()));
  138.                     } catch (Exception ex) {
  139.                         LOGGER.log(System.Logger.Level.WARNING, "Exception while converting in custom bidirectional binding", ex);
  140.                         b.setValue(null);
  141.                     }
  142.                 } else {
  143.                     try {
  144.                         a.setValue(convertFrom.apply(b.getValue()));
  145.                     } catch (Exception ex) {
  146.                         LOGGER.log(System.Logger.Level.WARNING, "Exception while converting in custom bidirectional binding", ex);
  147.                         a.setValue(null);
  148.                     }
  149.                 }
  150.             } finally {
  151.                 updating = false;
  152.             }
  153.         }
  154.     }
  155.  
  156. }
  157.  
Advertisement
Add Comment
Please, Sign In to add comment