1 /*
   2  * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javafx.beans.binding;
  27 
  28 import javafx.beans.value.ObservableFloatValue;
  29 import javafx.collections.FXCollections;
  30 import javafx.collections.ObservableList;
  31 import javafx.beans.value.ObservableValue;
  32 
  33 /**
  34  * {@code FloatExpression} is an
  35  * {@link javafx.beans.value.ObservableFloatValue} plus additional convenience
  36  * methods to generate bindings in a fluent style.
  37  * <p>
  38  * A concrete sub-class of {@code FloatExpression} has to implement the method
  39  * {@link javafx.beans.value.ObservableFloatValue#get()}, which provides the
  40  * actual value of this expression.
  41  * @since JavaFX 2.0
  42  */
  43 public abstract class FloatExpression extends NumberExpressionBase implements
  44         ObservableFloatValue {
  45 
  46     @Override
  47     public int intValue() {
  48         return (int) get();
  49     }
  50 
  51     @Override
  52     public long longValue() {
  53         return (long) get();
  54     }
  55 
  56     @Override
  57     public float floatValue() {
  58         return get();
  59     }
  60 
  61     @Override
  62     public double doubleValue() {
  63         return (double) get();
  64     }
  65 
  66     @Override
  67     public Float getValue() {
  68         return get();
  69     }
  70 
  71     /**
  72      * Returns a {@code FloatExpression} that wraps a
  73      * {@link javafx.beans.value.ObservableFloatValue}. If the
  74      * {@code ObservableFloatValue} is already a {@code FloatExpression}, it
  75      * will be returned. Otherwise a new
  76      * {@link javafx.beans.binding.FloatBinding} is created that is bound to the
  77      * {@code ObservableFloatValue}.
  78      *
  79      * @param value
  80      *            The source {@code ObservableFloatValue}
  81      * @return A {@code FloatExpression} that wraps the
  82      *         {@code ObservableFloatValue} if necessary
  83      * @throws NullPointerException
  84      *             if {@code value} is {@code null}
  85      */
  86     public static FloatExpression floatExpression(
  87             final ObservableFloatValue value) {
  88         if (value == null) {
  89             throw new NullPointerException("Value must be specified.");
  90         }
  91         return (value instanceof FloatExpression) ? (FloatExpression) value
  92                 : new FloatBinding() {
  93                     {
  94                         super.bind(value);
  95                     }
  96 
  97                     @Override
  98                     public void dispose() {
  99                         super.unbind(value);
 100                     }
 101 
 102                     @Override
 103                     protected float computeValue() {
 104                         return value.get();
 105                     }
 106 
 107                     @Override
 108                     public ObservableList<ObservableFloatValue> getDependencies() {
 109                         return FXCollections.singletonObservableList(value);
 110                     }
 111                 };
 112     }
 113 
 114     /**
 115      * Returns a {@code FloatExpression} that wraps an
 116      * {@link javafx.beans.value.ObservableValue}. If the
 117      * {@code ObservableValue} is already a {@code FloatExpression}, it
 118      * will be returned. Otherwise a new
 119      * {@link javafx.beans.binding.FloatBinding} is created that is bound to
 120      * the {@code ObservableValue}.
 121      *
 122      * <p>
 123      * Note: this method can be used to convert an {@link ObjectExpression} or
 124      * {@link javafx.beans.property.ObjectProperty} of specific number type to FloatExpression, which
 125      * is essentially an {@code ObservableValue<Number>}. See sample below.
 126      *
 127      * <blockquote><pre>
 128      *   FloatProperty floatProperty = new SimpleFloatProperty(1.0f);
 129      *   ObjectProperty&lt;Float&gt; objectProperty = new SimpleObjectProperty&lt;&gt;(2.0f);
 130      *   BooleanBinding binding = floatProperty.greaterThan(FloatExpression.floatExpression(objectProperty));
 131      * </pre></blockquote>
 132      *
 133      *  Note: null values will be interpreted as 0f
 134      *
 135      * @param <T> The type of Number to be wrapped
 136      * @param value
 137      *            The source {@code ObservableValue}
 138      * @return A {@code FloatExpression} that wraps the
 139      *         {@code ObservableValue} if necessary
 140      * @throws NullPointerException
 141      *             if {@code value} is {@code null}
 142      * @since JavaFX 8.0
 143      */
 144     public static <T extends Number> FloatExpression floatExpression(final ObservableValue<T> value) {
 145         if (value == null) {
 146             throw new NullPointerException("Value must be specified.");
 147         }
 148         return (value instanceof FloatExpression) ? (FloatExpression) value
 149                 : new FloatBinding() {
 150             {
 151                 super.bind(value);
 152             }
 153 
 154             @Override
 155             public void dispose() {
 156                 super.unbind(value);
 157             }
 158 
 159             @Override
 160             protected float computeValue() {
 161                 final T val = value.getValue();
 162                 return val == null ? 0f :  val.floatValue();
 163             }
 164 
 165             @Override
 166             public ObservableList<ObservableValue<T>> getDependencies() {
 167                 return FXCollections.singletonObservableList(value);
 168             }
 169         };
 170     }
 171 
 172 
 173     @Override
 174     public FloatBinding negate() {
 175         return (FloatBinding) Bindings.negate(this);
 176     }
 177 
 178     @Override
 179     public DoubleBinding add(final double other) {
 180         return Bindings.add(this, other);
 181     }
 182 
 183     @Override
 184     public FloatBinding add(final float other) {
 185         return (FloatBinding) Bindings.add(this, other);
 186     }
 187 
 188     @Override
 189     public FloatBinding add(final long other) {
 190         return (FloatBinding) Bindings.add(this, other);
 191     }
 192 
 193     @Override
 194     public FloatBinding add(final int other) {
 195         return (FloatBinding) Bindings.add(this, other);
 196     }
 197 
 198     @Override
 199     public DoubleBinding subtract(final double other) {
 200         return Bindings.subtract(this, other);
 201     }
 202 
 203     @Override
 204     public FloatBinding subtract(final float other) {
 205         return (FloatBinding) Bindings.subtract(this, other);
 206     }
 207 
 208     @Override
 209     public FloatBinding subtract(final long other) {
 210         return (FloatBinding) Bindings.subtract(this, other);
 211     }
 212 
 213     @Override
 214     public FloatBinding subtract(final int other) {
 215         return (FloatBinding) Bindings.subtract(this, other);
 216     }
 217 
 218     @Override
 219     public DoubleBinding multiply(final double other) {
 220         return Bindings.multiply(this, other);
 221     }
 222 
 223     @Override
 224     public FloatBinding multiply(final float other) {
 225         return (FloatBinding) Bindings.multiply(this, other);
 226     }
 227 
 228     @Override
 229     public FloatBinding multiply(final long other) {
 230         return (FloatBinding) Bindings.multiply(this, other);
 231     }
 232 
 233     @Override
 234     public FloatBinding multiply(final int other) {
 235         return (FloatBinding) Bindings.multiply(this, other);
 236     }
 237 
 238     @Override
 239     public DoubleBinding divide(final double other) {
 240         return Bindings.divide(this, other);
 241     }
 242 
 243     @Override
 244     public FloatBinding divide(final float other) {
 245         return (FloatBinding) Bindings.divide(this, other);
 246     }
 247 
 248     @Override
 249     public FloatBinding divide(final long other) {
 250         return (FloatBinding) Bindings.divide(this, other);
 251     }
 252 
 253     @Override
 254     public FloatBinding divide(final int other) {
 255         return (FloatBinding) Bindings.divide(this, other);
 256     }
 257 
 258     /**
 259      * Creates an {@link javafx.beans.binding.ObjectExpression} that holds the value
 260      * of this {@code FloatExpression}. If the
 261      * value of this {@code FloatExpression} changes, the value of the
 262      * {@code ObjectExpression} will be updated automatically.
 263      *
 264      * @return the new {@code ObjectExpression}
 265      * @since JavaFX 8.0
 266      */
 267     public ObjectExpression<Float> asObject() {
 268         return new ObjectBinding<Float>() {
 269             {
 270                 bind(FloatExpression.this);
 271             }
 272 
 273             @Override
 274             public void dispose() {
 275                 unbind(FloatExpression.this);
 276             }
 277 
 278             @Override
 279             protected Float computeValue() {
 280                 return FloatExpression.this.getValue();
 281             }
 282         };
 283     }
 284 }