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.ObservableDoubleValue;
  29 import javafx.beans.value.ObservableNumberValue;
  30 import javafx.collections.FXCollections;
  31 import javafx.collections.ObservableList;
  32 import javafx.beans.value.ObservableValue;
  33 
  34 /**
  35  * {@code DoubleExpression} is an
  36  * {@link javafx.beans.value.ObservableDoubleValue} plus additional convenience
  37  * methods to generate bindings in a fluent style.
  38  * <p>
  39  * A concrete sub-class of {@code DoubleExpression} has to implement the method
  40  * {@link javafx.beans.value.ObservableDoubleValue#get()}, which provides the
  41  * actual value of this expression.
  42  * @since JavaFX 2.0
  43  */
  44 public abstract class DoubleExpression extends NumberExpressionBase implements
  45         ObservableDoubleValue {
  46 
  47     @Override
  48     public int intValue() {
  49         return (int) get();
  50     }
  51 
  52     @Override
  53     public long longValue() {
  54         return (long) get();
  55     }
  56 
  57     @Override
  58     public float floatValue() {
  59         return (float) get();
  60     }
  61 
  62     @Override
  63     public double doubleValue() {
  64         return get();
  65     }
  66 
  67     @Override
  68     public Double getValue() {
  69         return get();
  70     }
  71 
  72     /**
  73      * Returns a {@code DoubleExpression} that wraps a
  74      * {@link javafx.beans.value.ObservableDoubleValue}. If the
  75      * {@code ObservableDoubleValue} is already a {@code DoubleExpression}, it
  76      * will be returned. Otherwise a new
  77      * {@link javafx.beans.binding.DoubleBinding} is created that is bound to
  78      * the {@code ObservableDoubleValue}.
  79      *
  80      * @param value
  81      *            The source {@code ObservableDoubleValue}
  82      * @return A {@code DoubleExpression} that wraps the
  83      *         {@code ObservableDoubleValue} if necessary
  84      * @throws NullPointerException
  85      *             if {@code value} is {@code null}
  86      */
  87     public static DoubleExpression doubleExpression(
  88             final ObservableDoubleValue value) {
  89         if (value == null) {
  90             throw new NullPointerException("Value must be specified.");
  91         }
  92         return (value instanceof DoubleExpression) ? (DoubleExpression) value
  93                 : new DoubleBinding() {
  94                     {
  95                         super.bind(value);
  96                     }
  97 
  98                     @Override
  99                     public void dispose() {
 100                         super.unbind(value);
 101                     }
 102 
 103                     @Override
 104                     protected double computeValue() {
 105                         return value.get();
 106                     }
 107 
 108                     @Override
 109                     public ObservableList<ObservableDoubleValue> getDependencies() {
 110                         return FXCollections.singletonObservableList(value);
 111                     }
 112                 };
 113     }
 114 
 115     /**
 116      * Returns a {@code DoubleExpression} that wraps an
 117      * {@link javafx.beans.value.ObservableValue}. If the
 118      * {@code ObservableValue} is already a {@code DoubleExpression}, it
 119      * will be returned. Otherwise a new
 120      * {@link javafx.beans.binding.DoubleBinding} is created that is bound to
 121      * the {@code ObservableValue}.
 122      *
 123      * <p>
 124      * Note: this method can be used to convert an {@link ObjectExpression} or
 125      * {@link javafx.beans.property.ObjectProperty} of specific number type to DoubleExpression, which
 126      * is essentially an {@code ObservableValue<Number>}. See sample below.
 127      *
 128      * <blockquote><pre>
 129      *   DoubleProperty doubleProperty = new SimpleDoubleProperty(1.0);
 130      *   ObjectProperty&lt;Double&gt; objectProperty = new SimpleObjectProperty&lt;&gt;(2.0);
 131      *   BooleanBinding binding = doubleProperty.greaterThan(DoubleExpression.doubleExpression(objectProperty));
 132      * </pre></blockquote>
 133      *
 134      * Note: null values will be interpreted as 0.0
 135      *
 136      * @param <T> The type of Number to be wrapped
 137      * @param value
 138      *            The source {@code ObservableValue}
 139      * @return A {@code DoubleExpression} that wraps the
 140      *         {@code ObservableValue} if necessary
 141      * @throws NullPointerException
 142      *             if {@code value} is {@code null}
 143      * @since JavaFX 8.0
 144      */
 145     public static <T extends Number> DoubleExpression doubleExpression(final ObservableValue<T> value) {
 146         if (value == null) {
 147             throw new NullPointerException("Value must be specified.");
 148         }
 149         return (value instanceof DoubleExpression) ? (DoubleExpression) value
 150                 : new DoubleBinding() {
 151             {
 152                 super.bind(value);
 153             }
 154 
 155             @Override
 156             public void dispose() {
 157                 super.unbind(value);
 158             }
 159 
 160             @Override
 161             protected double computeValue() {
 162                 final T val = value.getValue();
 163                 return val == null ? 0.0 : val.doubleValue();
 164             }
 165 
 166             @Override
 167             public ObservableList<ObservableValue<T>> getDependencies() {
 168                 return FXCollections.singletonObservableList(value);
 169             }
 170         };
 171     }
 172 
 173     @Override
 174     public DoubleBinding negate() {
 175         return (DoubleBinding) Bindings.negate(this);
 176     }
 177 
 178     @Override
 179     public DoubleBinding add(final ObservableNumberValue other) {
 180         return (DoubleBinding) Bindings.add(this, other);
 181     }
 182 
 183     @Override
 184     public DoubleBinding add(final double other) {
 185         return Bindings.add(this, other);
 186     }
 187 
 188     @Override
 189     public DoubleBinding add(final float other) {
 190         return (DoubleBinding) Bindings.add(this, other);
 191     }
 192 
 193     @Override
 194     public DoubleBinding add(final long other) {
 195         return (DoubleBinding) Bindings.add(this, other);
 196     }
 197 
 198     @Override
 199     public DoubleBinding add(final int other) {
 200         return (DoubleBinding) Bindings.add(this, other);
 201     }
 202 
 203     @Override
 204     public DoubleBinding subtract(final ObservableNumberValue other) {
 205         return (DoubleBinding) Bindings.subtract(this, other);
 206     }
 207 
 208     @Override
 209     public DoubleBinding subtract(final double other) {
 210         return Bindings.subtract(this, other);
 211     }
 212 
 213     @Override
 214     public DoubleBinding subtract(final float other) {
 215         return (DoubleBinding) Bindings.subtract(this, other);
 216     }
 217 
 218     @Override
 219     public DoubleBinding subtract(final long other) {
 220         return (DoubleBinding) Bindings.subtract(this, other);
 221     }
 222 
 223     @Override
 224     public DoubleBinding subtract(final int other) {
 225         return (DoubleBinding) Bindings.subtract(this, other);
 226     }
 227 
 228     @Override
 229     public DoubleBinding multiply(final ObservableNumberValue other) {
 230         return (DoubleBinding) Bindings.multiply(this, other);
 231     }
 232 
 233     @Override
 234     public DoubleBinding multiply(final double other) {
 235         return Bindings.multiply(this, other);
 236     }
 237 
 238     @Override
 239     public DoubleBinding multiply(final float other) {
 240         return (DoubleBinding) Bindings.multiply(this, other);
 241     }
 242 
 243     @Override
 244     public DoubleBinding multiply(final long other) {
 245         return (DoubleBinding) Bindings.multiply(this, other);
 246     }
 247 
 248     @Override
 249     public DoubleBinding multiply(final int other) {
 250         return (DoubleBinding) Bindings.multiply(this, other);
 251     }
 252 
 253     @Override
 254     public DoubleBinding divide(final ObservableNumberValue other) {
 255         return (DoubleBinding) Bindings.divide(this, other);
 256     }
 257 
 258     @Override
 259     public DoubleBinding divide(final double other) {
 260         return Bindings.divide(this, other);
 261     }
 262 
 263     @Override
 264     public DoubleBinding divide(final float other) {
 265         return (DoubleBinding) Bindings.divide(this, other);
 266     }
 267 
 268     @Override
 269     public DoubleBinding divide(final long other) {
 270         return (DoubleBinding) Bindings.divide(this, other);
 271     }
 272 
 273     @Override
 274     public DoubleBinding divide(final int other) {
 275         return (DoubleBinding) Bindings.divide(this, other);
 276     }
 277 
 278     /**
 279      * Creates an {@link javafx.beans.binding.ObjectExpression} that holds the value
 280      * of this {@code DoubleExpression}. If the
 281      * value of this {@code DoubleExpression} changes, the value of the
 282      * {@code ObjectExpression} will be updated automatically.
 283      *
 284      * @return the new {@code ObjectExpression}
 285      * @since JavaFX 8.0
 286      */
 287     public ObjectExpression<Double> asObject() {
 288         return new ObjectBinding<Double>() {
 289             {
 290                 bind(DoubleExpression.this);
 291             }
 292 
 293             @Override
 294             public void dispose() {
 295                 unbind(DoubleExpression.this);
 296             }
 297 
 298             @Override
 299             protected Double computeValue() {
 300                 return DoubleExpression.this.getValue();
 301             }
 302         };
 303     }
 304 }