< prev index next >

modules/javafx.base/src/main/java/javafx/beans/binding/When.java

Print this page




   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 java.lang.ref.WeakReference;



  29 
  30 import javafx.beans.InvalidationListener;
  31 import javafx.beans.NamedArg;
  32 import javafx.beans.Observable;
  33 import javafx.beans.value.ObservableBooleanValue;
  34 import javafx.beans.value.ObservableDoubleValue;
  35 import javafx.beans.value.ObservableFloatValue;
  36 import javafx.beans.value.ObservableLongValue;
  37 import javafx.beans.value.ObservableNumberValue;
  38 import javafx.beans.value.ObservableObjectValue;
  39 import javafx.beans.value.ObservableStringValue;
  40 import javafx.beans.value.ObservableValue;
  41 import javafx.collections.FXCollections;
  42 import javafx.collections.ObservableList;
  43 

  44 import com.sun.javafx.binding.DoubleConstant;
  45 import com.sun.javafx.binding.FloatConstant;
  46 import com.sun.javafx.binding.IntegerConstant;
  47 import com.sun.javafx.binding.Logging;
  48 import com.sun.javafx.binding.LongConstant;


  49 
  50 /**
  51  * Starting point for a binding that calculates a ternary expression.
  52  * <p>
  53  * A ternary expression has the basic form
  54  * {@code new When(cond).then(value1).otherwise(value2);}. The expression
  55  * {@code cond} needs to be a {@link javafx.beans.value.ObservableBooleanValue}.
  56  * Based on the value of {@code cond}, the binding contains the value of
  57  * {@code value1} (if {@code cond.getValue() == true}) or {@code value2} (if
  58  * {@code cond.getValue() == false}). The values {@code value1} and
  59  * {@code value2} have to be of the same type. They can be constant values or
  60  * implementations of {@link javafx.beans.value.ObservableValue}.
  61  * @since JavaFX 2.0
  62  */
  63 public class When {



  64     private final ObservableBooleanValue condition;
  65 
  66     /**
  67      * The constructor of {@code When}.
  68      *
  69      * @param condition
  70      *            the condition of the ternary expression
  71      */
  72     public When(final @NamedArg("condition") ObservableBooleanValue condition) {
  73         if (condition == null) {
  74             throw new NullPointerException("Condition must be specified.");
  75         }
  76         this.condition = condition;
  77     }
  78 
  79     private static class WhenListener implements InvalidationListener {
  80 
  81         private final ObservableBooleanValue condition;
  82         private final ObservableValue<?> thenValue;
  83         private final ObservableValue<?> otherwiseValue;
  84         private final WeakReference<Binding<?>> ref;
  85 
  86         private WhenListener(Binding<?> binding, ObservableBooleanValue condition, ObservableValue<?> thenValue, ObservableValue<?> otherwiseValue) {

  87             this.ref = new WeakReference<Binding<?>>(binding);
  88             this.condition = condition;
  89             this.thenValue = thenValue;
  90             this.otherwiseValue = otherwiseValue;
  91         }
  92 
  93         @Override
  94         public void invalidated(Observable observable) {
  95             final Binding<?> binding = ref.get();
  96             if (binding == null) {
  97                 condition.removeListener(this);
  98                 if (thenValue != null) {
  99                     thenValue.removeListener(this);
 100                 }
 101                 if (otherwiseValue != null) {
 102                     otherwiseValue.removeListener(this);
 103                 }
 104             } else {
 105                 // short-circuit invalidation. This Binding becomes
 106                 // only invalid if the condition changes or the
 107                 // active branch.
 108                 if (condition.equals(observable) || (binding.isValid() && (condition.get() == observable.equals(thenValue)))) {
 109                     binding.invalidate();
 110                 }
 111             }
 112         }
 113 
 114     }
 115 
 116     private static NumberBinding createNumberCondition(
 117             final ObservableBooleanValue condition,
 118             final ObservableNumberValue thenValue,
 119             final ObservableNumberValue otherwiseValue) {
 120         if ((thenValue instanceof ObservableDoubleValue) || (otherwiseValue instanceof ObservableDoubleValue)) {
 121             return new DoubleBinding() {
 122                 final InvalidationListener observer = new WhenListener(this, condition, thenValue, otherwiseValue);
 123                 {
 124                     condition.addListener(observer);
 125                     thenValue.addListener(observer);
 126                     otherwiseValue.addListener(observer);
 127                 }
 128 
 129                 @Override
 130                 public void dispose() {
 131                     condition.removeListener(observer);
 132                     thenValue.removeListener(observer);
 133                     otherwiseValue.removeListener(observer);
 134                 }







 135 
 136                 @Override
 137                 protected double computeValue() {
 138                     final boolean conditionValue = condition.get();
 139                     Logging.getLogger().finest("Condition of ternary binding expression was evaluated: {0}", conditionValue);
 140                     return conditionValue ? thenValue.doubleValue() : otherwiseValue.doubleValue();
 141                 }
 142 
 143                 @Override
 144                 public ObservableList<ObservableValue<?>> getDependencies() {
 145                     return FXCollections.unmodifiableObservableList(
 146                             FXCollections.<ObservableValue<?>> observableArrayList(condition, thenValue, otherwiseValue));
 147                 }
 148             };
 149         } else if ((thenValue instanceof ObservableFloatValue) || (otherwiseValue instanceof ObservableFloatValue)) {
 150             return new FloatBinding() {
 151                 final InvalidationListener observer = new WhenListener(this, condition, thenValue, otherwiseValue);
 152                 {
 153                     condition.addListener(observer);
 154                     thenValue.addListener(observer);
 155                     otherwiseValue.addListener(observer);
 156                 }
 157 
 158                 @Override
 159                 public void dispose() {
 160                     condition.removeListener(observer);
 161                     thenValue.removeListener(observer);
 162                     otherwiseValue.removeListener(observer);
 163                 }
 164 
 165                 @Override
 166                 protected float computeValue() {
 167                     final boolean conditionValue = condition.get();
 168                     Logging.getLogger().finest("Condition of ternary binding expression was evaluated: {0}", conditionValue);
 169                     return conditionValue ? thenValue.floatValue() : otherwiseValue.floatValue();
 170                 }
 171 
 172                 @Override
 173                 public ObservableList<ObservableValue<?>> getDependencies() {
 174                     return FXCollections.unmodifiableObservableList(
 175                             FXCollections.<ObservableValue<?>> observableArrayList(condition, thenValue, otherwiseValue));
 176                 }
 177             };
 178         } else if ((thenValue instanceof ObservableLongValue) || (otherwiseValue instanceof ObservableLongValue)) {
 179             return new LongBinding() {
 180                 final InvalidationListener observer = new WhenListener(this, condition, thenValue, otherwiseValue);
 181                 {
 182                     condition.addListener(observer);
 183                     thenValue.addListener(observer);
 184                     otherwiseValue.addListener(observer);
 185                 }
 186 
 187                 @Override
 188                 public void dispose() {
 189                     condition.removeListener(observer);
 190                     thenValue.removeListener(observer);
 191                     otherwiseValue.removeListener(observer);
 192                 }
 193 
 194                 @Override
 195                 protected long computeValue() {
 196                     final boolean conditionValue = condition.get();
 197                     Logging.getLogger().finest("Condition of ternary binding expression was evaluated: {0}", conditionValue);
 198                     return conditionValue ? thenValue.longValue() : otherwiseValue.longValue();
 199                 }
 200 
 201                 @Override
 202                 public ObservableList<ObservableValue<?>> getDependencies() {
 203                     return FXCollections.unmodifiableObservableList(
 204                             FXCollections.<ObservableValue<?>> observableArrayList(condition, thenValue, otherwiseValue));
 205                 }
 206             };
 207         } else {
 208             return new IntegerBinding() {
 209                 final InvalidationListener observer = new WhenListener(this, condition, thenValue, otherwiseValue);
 210                 {
 211                     condition.addListener(observer);
 212                     thenValue.addListener(observer);
 213                     otherwiseValue.addListener(observer);
 214                 }
 215 
 216                 @Override
 217                 public void dispose() {
 218                     condition.removeListener(observer);
 219                     thenValue.removeListener(observer);
 220                     otherwiseValue.removeListener(observer);
 221                 }
 222 
 223                 @Override
 224                 protected int computeValue() {
 225                     final boolean conditionValue = condition.get();
 226                     Logging.getLogger().finest("Condition of ternary binding expression was evaluated: {0}", conditionValue);
 227                     return conditionValue ? thenValue.intValue(): otherwiseValue.intValue();
 228                 }
 229 
 230                 @Override
 231                 public ObservableList<ObservableValue<?>> getDependencies() {
 232                     return FXCollections.unmodifiableObservableList(
 233                             FXCollections.<ObservableValue<?>> observableArrayList(condition, thenValue, otherwiseValue));
 234                 }
 235             };

 236         }
 237     }
 238 
 239     /**
 240      * If-then-else expression returning a number.
 241      * @since JavaFX 2.0
 242      */
 243     public class NumberConditionBuilder {
 244 
 245         private ObservableNumberValue thenValue;
 246 
 247         private NumberConditionBuilder(final ObservableNumberValue thenValue) {
 248             this.thenValue = thenValue;
 249         }
 250 
 251         /**
 252          * Defines the {@link javafx.beans.value.ObservableNumberValue} which
 253          * value is returned by the ternary expression if the condition is
 254          * {@code false}.
 255          *
 256          * @param otherwiseValue
 257          *            the value
 258          * @return the complete {@link DoubleBinding}
 259          */
 260         public NumberBinding otherwise(ObservableNumberValue otherwiseValue) {
 261             if (otherwiseValue == null) {
 262                 throw new NullPointerException("Value needs to be specified");








 263             }
 264             return When.createNumberCondition(condition, thenValue, otherwiseValue);
 265         }
 266 
 267         /**
 268          * Defines a constant value of the ternary expression, that is returned
 269          * if the condition is {@code false}.
 270          *
 271          * @param otherwiseValue
 272          *            the value
 273          * @return the complete {@link DoubleBinding}
 274          */
 275         public DoubleBinding otherwise(double otherwiseValue) {
 276             return (DoubleBinding) otherwise(DoubleConstant.valueOf(otherwiseValue));
 277         }
 278 
 279         /**
 280          * Defines a constant value of the ternary expression, that is returned
 281          * if the condition is {@code false}.
 282          *
 283          * @param otherwiseValue
 284          *            the value
 285          * @return the complete {@link NumberBinding}
 286          */
 287         public NumberBinding otherwise(float otherwiseValue) {
 288             return otherwise(FloatConstant.valueOf(otherwiseValue));
 289         }
 290 
 291         /**
 292          * Defines a constant value of the ternary expression, that is returned
 293          * if the condition is {@code false}.
 294          *
 295          * @param otherwiseValue
 296          *            the value
 297          * @return the complete {@link NumberBinding}
 298          */
 299         public NumberBinding otherwise(long otherwiseValue) {
 300             return otherwise(LongConstant.valueOf(otherwiseValue));
 301         }
 302 
 303         /**
 304          * Defines a constant value of the ternary expression, that is returned
 305          * if the condition is {@code false}.
 306          *
 307          * @param otherwiseValue
 308          *            the value
 309          * @return the complete {@link NumberBinding}
 310          */
 311         public NumberBinding otherwise(int otherwiseValue) {
 312             return otherwise(IntegerConstant.valueOf(otherwiseValue));
 313         }
 314     }
 315 
 316     /**
 317      * Defines the {@link javafx.beans.value.ObservableNumberValue} which value
 318      * is returned by the ternary expression if the condition is {@code true}.
 319      *
 320      * @param thenValue
 321      *            the value
 322      * @return the intermediate result which still requires the otherwise-branch
 323      */
 324     public NumberConditionBuilder then(final ObservableNumberValue thenValue) {
 325         if (thenValue == null) {
 326             throw new NullPointerException("Value needs to be specified");
 327         }
 328         return new NumberConditionBuilder(thenValue);
 329     }
 330 
 331     /**
 332      * Defines a constant value of the ternary expression, that is returned if
 333      * the condition is {@code true}.
 334      *
 335      * @param thenValue
 336      *            the value
 337      * @return the intermediate result which still requires the otherwise-branch
 338      */
 339     public NumberConditionBuilder then(double thenValue) {
 340         return new NumberConditionBuilder(DoubleConstant.valueOf(thenValue));
 341     }
 342 
 343     /**
 344      * Defines a constant value of the ternary expression, that is returned if
 345      * the condition is {@code true}.
 346      *
 347      * @param thenValue
 348      *            the value
 349      * @return the intermediate result which still requires the otherwise-branch
 350      */
 351     public NumberConditionBuilder then(float thenValue) {
 352         return new NumberConditionBuilder(FloatConstant.valueOf(thenValue));
 353     }
 354 
 355     /**
 356      * Defines a constant value of the ternary expression, that is returned if
 357      * the condition is {@code true}.
 358      *
 359      * @param thenValue
 360      *            the value
 361      * @return the intermediate result which still requires the otherwise-branch
 362      */
 363     public NumberConditionBuilder then(long thenValue) {
 364         return new NumberConditionBuilder(LongConstant.valueOf(thenValue));
 365     }
 366 
 367     /**
 368      * Defines a constant value of the ternary expression, that is returned if
 369      * the condition is {@code true}.
 370      *
 371      * @param thenValue
 372      *            the value
 373      * @return the intermediate result which still requires the otherwise-branch
 374      */
 375     public NumberConditionBuilder then(int thenValue) {
 376         return new NumberConditionBuilder(IntegerConstant.valueOf(thenValue));
 377     }
 378 
 379     /**
 380      * If-then-else expression returning Boolean.
 381      */
 382     private class BooleanCondition extends BooleanBinding {
 383         private final ObservableBooleanValue trueResult;
 384         private final boolean trueResultValue;
 385 
 386         private final ObservableBooleanValue falseResult;
 387         private final boolean falseResultValue;


 388 
 389         private final InvalidationListener observer;



 390 
 391         private BooleanCondition(final ObservableBooleanValue then, final ObservableBooleanValue otherwise) {
 392             this.trueResult = then;
 393             this.trueResultValue = false;
 394             this.falseResult = otherwise;
 395             this.falseResultValue = false;
 396             this.observer = new WhenListener(this, condition, then, otherwise);
 397             condition.addListener(observer);
 398             then.addListener(observer);
 399             otherwise.addListener(observer);
 400         }

 401 
 402         private BooleanCondition(final boolean then, final ObservableBooleanValue otherwise) {
 403             this.trueResult = null;
 404             this.trueResultValue = then;
 405             this.falseResult = otherwise;
 406             this.falseResultValue = false;
 407             this.observer = new WhenListener(this, condition, null, otherwise);
 408             condition.addListener(observer);
 409             otherwise.addListener(observer);
 410         }
 411 
 412         private BooleanCondition(final ObservableBooleanValue then, final boolean otherwise) {
 413             this.trueResult = then;
 414             this.trueResultValue = false;
 415             this.falseResult = null;
 416             this.falseResultValue = otherwise;
 417             this.observer = new WhenListener(this, condition, then, null);
 418             condition.addListener(observer);
 419             then.addListener(observer);
 420         }
 421 
 422         private BooleanCondition(final boolean then, final boolean otherwise) {
 423             this.trueResult = null;
 424             this.trueResultValue = then;
 425             this.falseResult = null;
 426             this.falseResultValue = otherwise;
 427             this.observer = null;
 428             super.bind(condition);
 429         }

 430 
 431         @Override
 432         protected boolean computeValue() {
 433             final boolean conditionValue = condition.get();
 434             Logging.getLogger().finest("Condition of ternary binding expression was evaluated: {0}", conditionValue);
 435             return conditionValue ? (trueResult != null ? trueResult.get() : trueResultValue)
 436                     : (falseResult != null ? falseResult.get() : falseResultValue);





 437         }
 438 
 439         @Override
 440         public void dispose() {
 441             if (observer == null) {
 442                 super.unbind(condition);
 443             } else {
 444                 condition.removeListener(observer);
 445                 if (trueResult != null) {
 446                     trueResult.removeListener(observer);
 447                 }
 448                 if (falseResult != null) {
 449                     falseResult.removeListener(observer);
 450                 }
 451             }
 452         }
 453 
 454         @Override
 455         public ObservableList<ObservableValue<?>> getDependencies() {
 456             assert condition != null;
 457             final ObservableList<ObservableValue<?>> seq = FXCollections.<ObservableValue<?>> observableArrayList(condition);
 458             if (trueResult != null) {
 459                 seq.add(trueResult);
 460             }
 461             if (falseResult != null) {
 462                 seq.add(falseResult);
 463             }
 464             return FXCollections.unmodifiableObservableList(seq);
 465         }
 466     }
 467 
 468     /**
 469      * An intermediate class needed while assembling the ternary expression. It
 470      * should not be used in another context.
 471      * @since JavaFX 2.0
 472      */
 473     public class BooleanConditionBuilder {
 474 
 475         private ObservableBooleanValue trueResult;
 476         private boolean trueResultValue;
 477 
 478         private BooleanConditionBuilder(final ObservableBooleanValue thenValue) {
 479             this.trueResult = thenValue;
 480         }
 481 
 482         private BooleanConditionBuilder(final boolean thenValue) {
 483             this.trueResultValue = thenValue;
 484         }
 485 
 486         /**
 487          * Defines the {@link javafx.beans.value.ObservableBooleanValue} which
 488          * value is returned by the ternary expression if the condition is
 489          * {@code false}.
 490          *
 491          * @param otherwiseValue
 492          *            the value
 493          * @return the complete {@link BooleanBinding}
 494          */
 495         public BooleanBinding otherwise(final ObservableBooleanValue otherwiseValue) {
 496             if (otherwiseValue == null) {
 497                 throw new NullPointerException("Value needs to be specified");
 498             }
 499             if (trueResult != null)
 500                 return new BooleanCondition(trueResult, otherwiseValue);
 501             else
 502                 return new BooleanCondition(trueResultValue, otherwiseValue);
 503         }
 504 
 505         /**
 506          * Defines a constant value of the ternary expression, that is returned
 507          * if the condition is {@code false}.
 508          *
 509          * @param otherwiseValue
 510          *            the value
 511          * @return the complete {@link BooleanBinding}
 512          */
 513         public BooleanBinding otherwise(final boolean otherwiseValue) {
 514             if (trueResult != null)
 515                 return new BooleanCondition(trueResult, otherwiseValue);
 516             else
 517                 return new BooleanCondition(trueResultValue, otherwiseValue);
 518         }
 519     }
 520 
 521     /**
 522      * Defines the {@link javafx.beans.value.ObservableBooleanValue} which value
 523      * is returned by the ternary expression if the condition is {@code true}.
 524      *
 525      * @param thenValue
 526      *            the value
 527      * @return the intermediate result which still requires the otherwise-branch
 528      */
 529     public BooleanConditionBuilder then(final ObservableBooleanValue thenValue) {
 530         if (thenValue == null) {
 531             throw new NullPointerException("Value needs to be specified");
 532         }
 533         return new BooleanConditionBuilder(thenValue);
 534     }
 535 
 536     /**
 537      * Defines a constant value of the ternary expression, that is returned if
 538      * the condition is {@code true}.
 539      *
 540      * @param thenValue
 541      *            the value
 542      * @return the intermediate result which still requires the otherwise-branch
 543      */
 544     public BooleanConditionBuilder then(final boolean thenValue) {
 545         return new BooleanConditionBuilder(thenValue);
 546     }
 547 
 548     /**
 549      * If-then-else expression returning String.
 550      */
 551     private class StringCondition extends StringBinding {
 552 
 553         private final ObservableStringValue trueResult;
 554         private final String trueResultValue;
 555 
 556         private final ObservableStringValue falseResult;
 557         private final String falseResultValue;
 558 
 559         private final InvalidationListener observer;
 560 
 561         private StringCondition(final ObservableStringValue then, final ObservableStringValue otherwise) {
 562             this.trueResult = then;
 563             this.trueResultValue = "";
 564             this.falseResult = otherwise;
 565             this.falseResultValue = "";
 566             this.observer = new WhenListener(this, condition, then, otherwise);
 567             condition.addListener(observer);
 568             then.addListener(observer);
 569             otherwise.addListener(observer);
 570         }
 571 
 572         private StringCondition(final String then, final ObservableStringValue otherwise) {
 573             this.trueResult = null;
 574             this.trueResultValue = then;
 575             this.falseResult = otherwise;
 576             this.falseResultValue = "";
 577             this.observer = new WhenListener(this, condition, null, otherwise);
 578             condition.addListener(observer);
 579             otherwise.addListener(observer);
 580         }
 581 
 582         private StringCondition(final ObservableStringValue then, final String otherwise) {
 583             this.trueResult = then;
 584             this.trueResultValue = "";
 585             this.falseResult = null;
 586             this.falseResultValue = otherwise;
 587             this.observer = new WhenListener(this, condition, then, null);
 588             condition.addListener(observer);
 589             then.addListener(observer);
 590         }
 591 
 592         private StringCondition(final String then, final String otherwise) {
 593             this.trueResult = null;
 594             this.trueResultValue = then;
 595             this.falseResult = null;
 596             this.falseResultValue = otherwise;
 597             this.observer = null;
 598             super.bind(condition);
 599         }
 600 
 601         @Override
 602         protected String computeValue() {
 603             final boolean conditionValue = condition.get();
 604             Logging.getLogger().finest("Condition of ternary binding expression was evaluated: {0}", conditionValue);
 605             return conditionValue ? (trueResult != null ? trueResult.get() : trueResultValue)
 606                     : (falseResult != null ? falseResult.get() : falseResultValue);
 607         }
 608 
 609         @Override
 610         public void dispose() {
 611             if (observer == null) {
 612                 super.unbind(condition);
 613             } else {
 614                 condition.removeListener(observer);
 615                 if (trueResult != null) {
 616                     trueResult.removeListener(observer);
 617                 }
 618                 if (falseResult != null) {
 619                     falseResult.removeListener(observer);
 620                 }
 621             }
 622         }
 623 




 624 
 625         @Override
 626         public ObservableList<ObservableValue<?>> getDependencies() {
 627             assert condition != null;
 628             final ObservableList<ObservableValue<?>> seq = FXCollections.<ObservableValue<?>> observableArrayList(condition);
 629             if (trueResult != null) {
 630                 seq.add(trueResult);
 631             }
 632             if (falseResult != null) {
 633                 seq.add(falseResult);
 634             }
 635             return FXCollections.unmodifiableObservableList(seq);
 636         }
 637     }
 638 
 639     /**
 640      * An intermediate class needed while assembling the ternary expression. It
 641      * should not be used in another context.
 642      * @since JavaFX 2.0
 643      */
 644     public class StringConditionBuilder {
 645 
 646         private ObservableStringValue trueResult;
 647         private String trueResultValue;
 648 
 649         private StringConditionBuilder(final ObservableStringValue thenValue) {
 650             this.trueResult = thenValue;
 651         }
 652 
 653         private StringConditionBuilder(final String thenValue) {
 654             this.trueResultValue = thenValue;
 655         }
 656 
 657         /**
 658          * Defines the {@link javafx.beans.value.ObservableStringValue} which
 659          * value is returned by the ternary expression if the condition is
 660          * {@code false}.
 661          *
 662          * @param otherwiseValue
 663          *            the value
 664          * @return the complete {@link StringBinding}
 665          */
 666         public StringBinding otherwise(final ObservableStringValue otherwiseValue) {
 667             if (trueResult != null)
 668                 return new StringCondition(trueResult, otherwiseValue);
 669             else
 670                 return new StringCondition(trueResultValue, otherwiseValue);
 671         }
 672 
 673         /**
 674          * Defines a constant value of the ternary expression, that is returned
 675          * if the condition is {@code false}.
 676          *
 677          * @param otherwiseValue
 678          *            the value
 679          * @return the complete {@link StringBinding}
 680          */
 681         public StringBinding otherwise(final String otherwiseValue) {
 682             if (trueResult != null)
 683                 return new StringCondition(trueResult, otherwiseValue);
 684             else
 685                 return new StringCondition(trueResultValue, otherwiseValue);
 686         }
 687     }
 688 
 689     /**
 690      * Defines the {@link javafx.beans.value.ObservableStringValue} which value
 691      * is returned by the ternary expression if the condition is {@code true}.
 692      *
 693      * @param thenValue
 694      *            the value
 695      * @return the intermediate result which still requires the otherwise-branch
 696      */
 697     public StringConditionBuilder then(final ObservableStringValue thenValue) {
 698         if (thenValue == null) {
 699             throw new NullPointerException("Value needs to be specified");
 700         }
 701         return new StringConditionBuilder(thenValue);
 702     }
 703 
 704     /**
 705      * Defines a constant value of the ternary expression, that is returned if
 706      * the condition is {@code true}.
 707      *
 708      * @param thenValue
 709      *            the value
 710      * @return the intermediate result which still requires the otherwise-branch
 711      */
 712     public StringConditionBuilder then(final String thenValue) {
 713         return new StringConditionBuilder(thenValue);
 714     }
 715 
 716     /**
 717      * If-then-else expression returning general objects.
 718      */
 719     private class ObjectCondition<T> extends ObjectBinding<T> {
 720 
 721         private final ObservableObjectValue<T> trueResult;
 722         private final T trueResultValue;
 723 
 724         private final ObservableObjectValue<T> falseResult;
 725         private final T falseResultValue;
 726 
 727         private final InvalidationListener observer;
 728 
 729         private ObjectCondition(final ObservableObjectValue<T> then, final ObservableObjectValue<T> otherwise) {
 730             this.trueResult = then;
 731             this.trueResultValue = null;
 732             this.falseResult = otherwise;
 733             this.falseResultValue = null;
 734             this.observer = new WhenListener(this, condition, then, otherwise);
 735             condition.addListener(observer);
 736             then.addListener(observer);
 737             otherwise.addListener(observer);
 738         }
 739 
 740         private ObjectCondition(final T then, final ObservableObjectValue<T> otherwise) {
 741             this.trueResult = null;
 742             this.trueResultValue = then;
 743             this.falseResult = otherwise;
 744             this.falseResultValue = null;
 745             this.observer = new WhenListener(this, condition, null, otherwise);
 746             condition.addListener(observer);
 747             otherwise.addListener(observer);
 748         }
 749 
 750         private ObjectCondition(final ObservableObjectValue<T> then, final T otherwise) {
 751             this.trueResult = then;
 752             this.trueResultValue = null;
 753             this.falseResult = null;
 754             this.falseResultValue = otherwise;
 755             this.observer = new WhenListener(this, condition, then, null);
 756             condition.addListener(observer);
 757             then.addListener(observer);
 758         }
 759 
 760         private ObjectCondition(final T then, final T otherwise) {
 761             this.trueResult = null;
 762             this.trueResultValue = then;
 763             this.falseResult = null;
 764             this.falseResultValue = otherwise;
 765             this.observer = null;
 766             super.bind(condition);
 767         }
 768 
 769         @Override
 770         protected T computeValue() {
 771             final boolean conditionValue = condition.get();
 772             Logging.getLogger().finest("Condition of ternary binding expression was evaluated: {0}", conditionValue);
 773             return conditionValue ? (trueResult != null ? trueResult.get() : trueResultValue)
 774                     : (falseResult != null ? falseResult.get() : falseResultValue);
 775         }
 776 
 777         @Override
 778         public void dispose() {
 779             if (observer == null) {
 780                 super.unbind(condition);
 781             } else {
 782                 condition.removeListener(observer);
 783                 if (trueResult != null) {
 784                     trueResult.removeListener(observer);
 785                 }
 786                 if (falseResult != null) {
 787                     falseResult.removeListener(observer);
 788                 }
 789             }
 790         }
 791 




 792 
 793         @Override
 794         public ObservableList<ObservableValue<?>> getDependencies() {
 795             assert condition != null;
 796             final ObservableList<ObservableValue<?>> seq = FXCollections.<ObservableValue<?>> observableArrayList(condition);
 797             if (trueResult != null) {
 798                 seq.add(trueResult);
 799             }
 800             if (falseResult != null) {
 801                 seq.add(falseResult);
 802             }
 803             return FXCollections.unmodifiableObservableList(seq);
 804         }
 805     }
 806 
 807     /**
 808      * An intermediate class needed while assembling the ternary expression. It
 809      * should not be used in another context.
 810      * @since JavaFX 2.0
 811      */
 812     public class ObjectConditionBuilder<T> {
 813 
 814         private ObservableObjectValue<T> trueResult;
 815         private T trueResultValue;
 816 
 817         private ObjectConditionBuilder(final ObservableObjectValue<T> thenValue) {
 818             this.trueResult = thenValue;
 819         }
 820 
 821         private ObjectConditionBuilder(final T thenValue) {
 822             this.trueResultValue = thenValue;
 823         }
 824 
 825         /**
 826          * Defines the {@link javafx.beans.value.ObservableObjectValue} which
 827          * value is returned by the ternary expression if the condition is
 828          * {@code false}.
 829          *
 830          * @param otherwiseValue
 831          *            the value
 832          * @return the complete {@link ObjectBinding}
 833          */
 834         public ObjectBinding<T> otherwise(final ObservableObjectValue<T> otherwiseValue) {
 835             if (otherwiseValue == null) {
 836                 throw new NullPointerException("Value needs to be specified");
 837             }
 838             if (trueResult != null)
 839                 return new ObjectCondition<T>(trueResult, otherwiseValue);
 840             else
 841                 return new ObjectCondition<T>(trueResultValue, otherwiseValue);
 842         }
 843 
 844         /**
 845          * Defines a constant value of the ternary expression, that is returned
 846          * if the condition is {@code false}.
 847          *
 848          * @param otherwiseValue
 849          *            the value
 850          * @return the complete {@link ObjectBinding}
 851          */
 852         public ObjectBinding<T> otherwise(final T otherwiseValue) {
 853             if (trueResult != null)
 854                 return new ObjectCondition<T>(trueResult, otherwiseValue);
 855             else
 856                 return new ObjectCondition<T>(trueResultValue, otherwiseValue);
 857         }
 858     }
 859 
 860     /**
 861      * Defines the {@link javafx.beans.value.ObservableObjectValue} which value
 862      * is returned by the ternary expression if the condition is {@code true}.
 863      *
 864      * @param <T> the type of the intermediate result
 865      * @param thenValue
 866      *            the value
 867      * @return the intermediate result which still requires the otherwise-branch
 868      */
 869     public <T> ObjectConditionBuilder<T> then(final ObservableObjectValue<T> thenValue) {
 870         if (thenValue == null) {
 871             throw new NullPointerException("Value needs to be specified");
 872         }
 873         return new ObjectConditionBuilder<T>(thenValue);
 874     }
 875 
 876     /**
 877      * Defines a constant value of the ternary expression, that is returned if
 878      * the condition is {@code true}.
 879      *
 880      * @param <T> the type of the intermediate result
 881      * @param thenValue
 882      *            the value
 883      * @return the intermediate result which still requires the otherwise-branch
 884      */
 885     public <T> ObjectConditionBuilder<T> then(final T thenValue) {
 886         return new ObjectConditionBuilder<T>(thenValue);
 887     }
 888 
 889 }


   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 java.lang.ref.WeakReference;
  29 import java.util.Objects;
  30 import java.util.function.BiFunction;
  31 import java.util.function.Function;
  32 
  33 import javafx.beans.InvalidationListener;
  34 import javafx.beans.NamedArg;
  35 import javafx.beans.Observable;
  36 import javafx.beans.value.ObservableBooleanValue;
  37 import javafx.beans.value.ObservableDoubleValue;
  38 import javafx.beans.value.ObservableFloatValue;
  39 import javafx.beans.value.ObservableLongValue;
  40 import javafx.beans.value.ObservableNumberValue;
  41 import javafx.beans.value.ObservableObjectValue;
  42 import javafx.beans.value.ObservableStringValue;
  43 import javafx.beans.value.ObservableValue;
  44 import javafx.collections.FXCollections;
  45 import javafx.collections.ObservableList;
  46 
  47 import com.sun.javafx.binding.BooleanConstant;
  48 import com.sun.javafx.binding.DoubleConstant;
  49 import com.sun.javafx.binding.FloatConstant;
  50 import com.sun.javafx.binding.IntegerConstant;
  51 import com.sun.javafx.binding.Logging;
  52 import com.sun.javafx.binding.LongConstant;
  53 import com.sun.javafx.binding.ObjectConstant;
  54 import com.sun.javafx.binding.StringConstant;
  55 
  56 /**
  57  * Starting point for a binding that calculates a ternary expression.
  58  * <p>
  59  * A ternary expression has the basic form
  60  * {@code new When(cond).then(value1).otherwise(value2);}. The expression
  61  * {@code cond} needs to be an {@link javafx.beans.value.ObservableBooleanValue}.
  62  * Based on the value of {@code cond}, the binding contains the value of
  63  * {@code value1} (if {@code cond.getValue() == true}) or {@code value2} (if
  64  * {@code cond.getValue() == false}). The values {@code value1} and
  65  * {@code value2} have to be of the same type. They can be constant values or
  66  * implementations of {@link javafx.beans.value.ObservableValue}.
  67  * @since JavaFX 2.0
  68  */
  69 public class When {
  70 
  71     private static final String VALUE_MUST_BE_SPECIFIED = "Value must be specified";
  72 
  73     private final ObservableBooleanValue condition;
  74 
  75     /**
  76      * The constructor of {@code When}.
  77      *
  78      * @param condition
  79      *            the condition of the ternary expression
  80      */
  81     public When(final @NamedArg("condition") ObservableBooleanValue condition) {
  82         this.condition = Objects.requireNonNull(condition, "Condition must be specified.");



  83     }
  84 
  85     private static class WhenListener implements InvalidationListener {
  86 
  87         private final ObservableBooleanValue condition;
  88         private final ObservableValue<?> thenValue;
  89         private final ObservableValue<?> otherwiseValue;
  90         private final WeakReference<Binding<?>> ref;
  91 
  92         private WhenListener(Binding<?> binding, ObservableBooleanValue condition, ObservableValue<?> thenValue,
  93                              ObservableValue<?> otherwiseValue) {
  94             this.ref = new WeakReference<Binding<?>>(binding);
  95             this.condition = condition;
  96             this.thenValue = thenValue;
  97             this.otherwiseValue = otherwiseValue;
  98         }
  99 
 100         @Override
 101         public void invalidated(Observable observable) {
 102             final Binding<?> binding = ref.get();
 103             if (binding == null) {
 104                 condition.removeListener(this);
 105                 if (thenValue != null) {
 106                     thenValue.removeListener(this);
 107                 }
 108                 if (otherwiseValue != null) {
 109                     otherwiseValue.removeListener(this);
 110                 }
 111             } else {
 112                 // short-circuit invalidation. This Binding becomes
 113                 // only invalid if the condition changes or the
 114                 // active branch.
 115                 if (condition.equals(observable) || (binding.isValid() && (condition.get() == observable.equals(thenValue)))) {
 116                     binding.invalidate();
 117                 }
 118             }
 119         }

 120     }
 121 
 122     private abstract class ConditionHolder<V, B extends Binding<V>> {











 123 
 124         protected B binding;
 125         private ObservableValue<V> thenValue;
 126         private ObservableValue<V> otherwiseValue;
 127         private InvalidationListener observer;
 128 
 129         protected void registerListeners(final ObservableValue<V> then, final ObservableValue<V> otherwise) {
 130             thenValue = then;
 131             otherwiseValue = otherwise;
 132             observer = new WhenListener(binding, condition, thenValue, otherwiseValue);
 133             condition.addListener(observer);
 134             thenValue.addListener(observer);
 135             otherwiseValue.addListener(observer);
 136         }
 137 
 138         // TODO: unnecessary - can access field directly
 139         protected B getBinding() {
 140             return binding;
 141         }


 142 
 143         protected ObservableList<ObservableValue<?>> getDependencies() {
 144             return FXCollections.unmodifiableObservableList(
 145                     FXCollections.observableArrayList(condition, thenValue, otherwiseValue));
 146         }










 147 
 148         protected V computeValue() {
 149             final boolean conditionValue = condition.get();
 150             Logging.getLogger().finest("Condition of ternary binding expression was evaluated: {0}", conditionValue);
 151             return conditionValue ? thenValue.getValue() : otherwiseValue.getValue();
 152         }

 153 
 154         protected void dispose() {
 155             condition.removeListener(observer);
 156             thenValue.removeListener(observer);
 157             otherwiseValue.removeListener(observer);
 158         }
 159     }
 160 
 161     private class DoubleConditionHolder extends ConditionHolder<Number, DoubleBinding> {













 162 
 163         protected DoubleConditionHolder(ObservableNumberValue then, ObservableNumberValue otherwise) {
 164             binding = new DoubleBinding() {




 165 
 166                 @Override
 167                 protected double computeValue() {
 168                     return DoubleConditionHolder.super.computeValue().doubleValue();


 169                 }
 170 
 171                 @Override
 172                 public ObservableList<?> getDependencies() {
 173                     return DoubleConditionHolder.super.getDependencies();










 174                 }
 175 
 176                 @Override
 177                 public void dispose() {
 178                     DoubleConditionHolder.super.dispose();















 179                 }
 180             };
 181             registerListeners(then, otherwise);
 182         }
 183     }
 184 
 185     /**
 186      * If-then-else expression returning a number.
 187      * @since JavaFX 2.0
 188      */
 189     public class NumberConditionBuilder {
 190 
 191         private ObservableNumberValue thenValue;
 192 
 193         private NumberConditionBuilder(final ObservableNumberValue thenValue) {
 194             this.thenValue = thenValue;
 195         }
 196 
 197         /**
 198          * Defines the {@link javafx.beans.value.ObservableNumberValue} whose
 199          * value is returned by the ternary expression if the condition is
 200          * {@code false}.
 201          *
 202          * @param otherwiseValue
 203          *            the value
 204          * @return the complete {@link DoubleBinding}
 205          */
 206         public NumberBinding otherwise(ObservableNumberValue otherwiseValue) {
 207             Objects.requireNonNull(otherwiseValue, VALUE_MUST_BE_SPECIFIED);
 208             // Arranged by widening conventions
 209             if ((thenValue instanceof ObservableDoubleValue) || (otherwiseValue instanceof ObservableDoubleValue)) {
 210                 return new DoubleConditionHolder(thenValue, otherwiseValue).getBinding();
 211             } else if ((thenValue instanceof ObservableFloatValue) || (otherwiseValue instanceof ObservableFloatValue)) {
 212                 return new DoubleConditionHolder(thenValue, otherwiseValue).getBinding();
 213             } else if ((thenValue instanceof ObservableLongValue) || (otherwiseValue instanceof ObservableLongValue)) {
 214                 return new DoubleConditionHolder(thenValue, otherwiseValue).getBinding();
 215             } else {
 216                 return new DoubleConditionHolder(thenValue, otherwiseValue).getBinding();
 217             }

 218         }
 219 
 220         /**
 221          * Defines a constant value of the ternary expression that is returned
 222          * if the condition is {@code false}.
 223          *
 224          * @param otherwiseValue
 225          *            the value
 226          * @return the complete {@link DoubleBinding}
 227          */
 228         public DoubleBinding otherwise(double otherwiseValue) {
 229             return (DoubleBinding) otherwise(DoubleConstant.valueOf(otherwiseValue));
 230         }
 231 
 232         /**
 233          * Defines a constant value of the ternary expression that is returned
 234          * if the condition is {@code false}.
 235          *
 236          * @param otherwiseValue
 237          *            the value
 238          * @return the complete {@link NumberBinding}
 239          */
 240         public NumberBinding otherwise(float otherwiseValue) {
 241             return otherwise(FloatConstant.valueOf(otherwiseValue));             // TODO: add note about runtime type of binding?
 242         }
 243 
 244         /**
 245          * Defines a constant value of the ternary expression that is returned
 246          * if the condition is {@code false}.
 247          *
 248          * @param otherwiseValue
 249          *            the value
 250          * @return the complete {@link NumberBinding}
 251          */
 252         public NumberBinding otherwise(long otherwiseValue) {
 253             return otherwise(LongConstant.valueOf(otherwiseValue));
 254         }
 255 
 256         /**
 257          * Defines a constant value of the ternary expression that is returned
 258          * if the condition is {@code false}.
 259          *
 260          * @param otherwiseValue
 261          *            the value
 262          * @return the complete {@link NumberBinding}
 263          */
 264         public NumberBinding otherwise(int otherwiseValue) {
 265             return otherwise(IntegerConstant.valueOf(otherwiseValue));
 266         }
 267     }
 268 
 269     /**
 270      * Defines the {@link javafx.beans.value.ObservableNumberValue} which value
 271      * is returned by the ternary expression if the condition is {@code true}.
 272      *
 273      * @param thenValue
 274      *            the value
 275      * @return the intermediate result which still requires the otherwise-branch
 276      */
 277     public NumberConditionBuilder then(final ObservableNumberValue thenValue) {
 278         Objects.requireNonNull(thenValue, VALUE_MUST_BE_SPECIFIED);


 279         return new NumberConditionBuilder(thenValue);
 280     }
 281 
 282     /**
 283      * Defines a constant value of the ternary expression that is returned if
 284      * the condition is {@code true}.
 285      *
 286      * @param thenValue
 287      *            the value
 288      * @return the intermediate result which still requires the otherwise-branch
 289      */
 290     public NumberConditionBuilder then(double thenValue) {
 291         return then(DoubleConstant.valueOf(thenValue));
 292     }
 293 
 294     /**
 295      * Defines a constant value of the ternary expression that is returned if
 296      * the condition is {@code true}.
 297      *
 298      * @param thenValue
 299      *            the value
 300      * @return the intermediate result which still requires the otherwise-branch
 301      */
 302     public NumberConditionBuilder then(float thenValue) {
 303         return then(FloatConstant.valueOf(thenValue));
 304     }
 305 
 306     /**
 307      * Defines a constant value of the ternary expression that is returned if
 308      * the condition is {@code true}.
 309      *
 310      * @param thenValue
 311      *            the value
 312      * @return the intermediate result which still requires the otherwise-branch
 313      */
 314     public NumberConditionBuilder then(long thenValue) {
 315         return then(LongConstant.valueOf(thenValue));
 316     }
 317 
 318     /**
 319      * Defines a constant value of the ternary expression that is returned if
 320      * the condition is {@code true}.
 321      *
 322      * @param thenValue
 323      *            the value
 324      * @return the intermediate result which still requires the otherwise-branch
 325      */
 326     public NumberConditionBuilder then(int thenValue) {
 327         return then(IntegerConstant.valueOf(thenValue));
 328     }
 329 
 330     private class BooleanConditionHolder extends ConditionHolder<Boolean, BooleanBinding> {
 331 
 332         private BooleanConditionHolder(ObservableValue<Boolean> then, ObservableValue<Boolean> otherwise) {
 333             binding = new BooleanBinding() {


 334 
 335                 @Override
 336                 protected boolean computeValue() {
 337                     return BooleanConditionHolder.super.computeValue();
 338                 }
 339 
 340                 @Override
 341                 public void dispose() {
 342                     BooleanConditionHolder.super.dispose();
 343                 }
 344 
 345                 @Override
 346                 public ObservableList<ObservableValue<?>> getDependencies() {
 347                     return BooleanConditionHolder.super.getDependencies();
 348                 }
 349             };
 350             registerListeners(then, otherwise);



 351         }
 352     }
 353 
 354     private abstract class ConditionBuilder<V, B extends Binding<V>> {
 355 
 356         private ObservableValue<V> thenValue;
 357         protected BiFunction<ObservableValue<V>, ObservableValue<V>, ? extends ConditionHolder<V, B>> conditionHolderGenerator;
 358         protected Function<V, ObservableValue<V>> primitiveWrapper;
 359 
 360         protected ConditionBuilder(final ObservableValue<V> thenValue) {
 361             this.thenValue = thenValue;
 362         }
 363 
 364         public B otherwise(final ObservableValue<V> otherwiseValue) {
 365             Objects.requireNonNull(otherwiseValue, VALUE_MUST_BE_SPECIFIED);
 366             return conditionHolderGenerator.apply(thenValue, otherwiseValue).getBinding();





 367         }
 368 
 369         public B otherwise(final V otherwiseValue) {
 370             return otherwise(primitiveWrapper.apply(otherwiseValue));





 371         }
 372     }
 373 
 374     /**
 375      * An intermediate class needed while assembling the ternary expression. It
 376      * should not be used in another context.
 377      * @since JavaFX 2.0
 378      */
 379     public class BooleanConditionBuilder2 extends ConditionBuilder<Boolean, BooleanBinding> {
 380 
 381         private BooleanConditionBuilder2(ObservableBooleanValue then) {
 382             super(then);
 383             conditionHolderGenerator = (thenValue, otherwiseValue) -> new BooleanConditionHolder(thenValue, otherwiseValue);
 384             primitiveWrapper = otherwiseValue -> BooleanConstant.valueOf(otherwiseValue);
 385         }
 386 
 387         /**
 388          * Defines the {@link javafx.beans.value.ObservableBooleanValue} whose
 389          * value is returned by the ternary expression if the condition is
 390          * {@code false}.
 391          *
 392          * @param otherwiseValue
 393          *            the value
 394          * @return the complete {@link BooleanBinding}
 395          */
 396         public BooleanBinding otherwise(final ObservableBooleanValue otherwiseValue) {
 397             return super.otherwise(otherwiseValue);


 398         }
 399 
 400         /**
 401          * Defines a constant value of the ternary expression that is returned
 402          * if the condition is {@code false}.
 403          *
 404          * @param otherwiseValue
 405          *            the value
 406          * @return the complete {@link BooleanBinding}
 407          */
 408         public BooleanBinding otherwise(final boolean otherwiseValue) {
 409             return super.otherwise(otherwiseValue);

 410         }
 411     }
 412 
 413     /**
 414      * An intermediate class needed while assembling the ternary expression. It
 415      * should not be used in another context.
 416      * @since JavaFX 2.0
 417      */
 418     public class BooleanConditionBuilder {
 419 
 420         private ObservableValue<Boolean> thenValue;

 421 
 422         private BooleanConditionBuilder(final ObservableBooleanValue thenValue) {
 423             this.thenValue = thenValue;




 424         }
 425 
 426         /**
 427          * Defines the {@link javafx.beans.value.ObservableBooleanValue} whose
 428          * value is returned by the ternary expression if the condition is
 429          * {@code false}.
 430          *
 431          * @param otherwiseValue
 432          *            the value
 433          * @return the complete {@link BooleanBinding}
 434          */
 435         public BooleanBinding otherwise(final ObservableBooleanValue otherwiseValue) {
 436             Objects.requireNonNull(otherwiseValue, VALUE_MUST_BE_SPECIFIED);
 437             return new BooleanConditionHolder(thenValue, otherwiseValue).getBinding();





 438         }
 439 
 440         /**
 441          * Defines a constant value of the ternary expression that is returned
 442          * if the condition is {@code false}.
 443          *
 444          * @param otherwiseValue
 445          *            the value
 446          * @return the complete {@link BooleanBinding}
 447          */
 448         public BooleanBinding otherwise(final boolean otherwiseValue) {
 449             return otherwise(BooleanConstant.valueOf(otherwiseValue));



 450         }
 451     }
 452 
 453     /**
 454      * Defines the {@link javafx.beans.value.ObservableBooleanValue} which value
 455      * is returned by the ternary expression if the condition is {@code true}.
 456      *
 457      * @param thenValue
 458      *            the value
 459      * @return the intermediate result which still requires the otherwise-branch
 460      */
 461     public BooleanConditionBuilder then(final ObservableBooleanValue thenValue) {
 462         Objects.requireNonNull(thenValue, VALUE_MUST_BE_SPECIFIED);


 463         return new BooleanConditionBuilder(thenValue);
 464     }
 465 
 466     /**
 467      * Defines a constant value of the ternary expression that is returned if
 468      * the condition is {@code true}.
 469      *
 470      * @param thenValue
 471      *            the value
 472      * @return the intermediate result which still requires the otherwise-branch
 473      */
 474     public BooleanConditionBuilder then(final boolean thenValue) {
 475         return then(BooleanConstant.valueOf(thenValue));
 476     }
 477 
 478     private class StringConditionHolder extends ConditionHolder<String, StringBinding> {











 479 
 480         protected StringConditionHolder(ObservableStringValue then, ObservableStringValue otherwise) {
 481             binding = new StringBinding() {


















 482 
 483                 @Override
 484                 protected String computeValue() {
 485                     return StringConditionHolder.super.computeValue();



































 486                 }


 487 
 488                 @Override
 489                 public void dispose() {
 490                     StringConditionHolder.super.dispose();
 491                 }
 492 
 493                 @Override
 494                 public ObservableList<ObservableValue<?>> getDependencies() {
 495                     return StringConditionHolder.super.getDependencies();
 496                 }
 497             };
 498             registerListeners(then, otherwise);





 499         }
 500     }
 501 
 502     /**
 503      * An intermediate class needed while assembling the ternary expression. It
 504      * should not be used in another context.
 505      * @since JavaFX 2.0
 506      */
 507     public class StringConditionBuilder {
 508 
 509         private ObservableStringValue thenValue;

 510 
 511         private StringConditionBuilder(final ObservableStringValue thenValue) {
 512             this.thenValue = thenValue;




 513         }
 514 
 515         /**
 516          * Defines the {@link javafx.beans.value.ObservableStringValue} whose
 517          * value is returned by the ternary expression if the condition is
 518          * {@code false}.
 519          *
 520          * @param otherwiseValue
 521          *            the value
 522          * @return the complete {@link StringBinding}
 523          */
 524         public StringBinding otherwise(final ObservableStringValue otherwiseValue) {
 525             Objects.requireNonNull(otherwiseValue, VALUE_MUST_BE_SPECIFIED);
 526             return new StringConditionHolder(thenValue, otherwiseValue).getBinding();


 527         }
 528 
 529         /**
 530          * Defines a constant value of the ternary expression that is returned
 531          * if the condition is {@code false}.
 532          *
 533          * @param otherwiseValue
 534          *            the value
 535          * @return the complete {@link StringBinding}
 536          */
 537         public StringBinding otherwise(final String otherwiseValue) {
 538             return otherwise(StringConstant.valueOf(otherwiseValue));



 539         }
 540     }
 541 
 542     /**
 543      * Defines the {@link javafx.beans.value.ObservableStringValue} which value
 544      * is returned by the ternary expression if the condition is {@code true}.
 545      *
 546      * @param thenValue
 547      *            the value
 548      * @return the intermediate result which still requires the otherwise-branch
 549      */
 550     public StringConditionBuilder then(final ObservableStringValue thenValue) {
 551         Objects.requireNonNull(thenValue, VALUE_MUST_BE_SPECIFIED);


 552         return new StringConditionBuilder(thenValue);
 553     }
 554 
 555     /**
 556      * Defines a constant value of the ternary expression that is returned if
 557      * the condition is {@code true}.
 558      *
 559      * @param thenValue
 560      *            the value
 561      * @return the intermediate result which still requires the otherwise-branch
 562      */
 563     public StringConditionBuilder then(final String thenValue) {
 564         return then(StringConstant.valueOf(thenValue));
 565     }
 566 
 567     private class ObjectConditionHolder<T> extends ConditionHolder<T, ObjectBinding<T>> {



















































 568 
 569         protected ObjectConditionHolder(ObservableObjectValue<T> then, ObservableObjectValue<T> otherwise) {
 570             binding = new ObjectBinding<T>() {





 571 
 572                 @Override
 573                 protected T computeValue() {
 574                     return ObjectConditionHolder.super.computeValue();








 575                 }


 576 
 577                 @Override
 578                 public void dispose() {
 579                     ObjectConditionHolder.super.dispose();
 580                 }
 581 
 582                 @Override
 583                 public ObservableList<ObservableValue<?>> getDependencies() {
 584                     return ObjectConditionHolder.super.getDependencies();
 585                 }
 586             };
 587             registerListeners(then, otherwise);





 588         }
 589     }
 590 
 591     /**
 592      * An intermediate class needed while assembling the ternary expression. It
 593      * should not be used in another context.
 594      * @since JavaFX 2.0
 595      */
 596     public class ObjectConditionBuilder<T> {
 597 
 598         private ObservableObjectValue<T> thenValue;

 599 
 600         private ObjectConditionBuilder(final ObservableObjectValue<T> thenValue) {
 601             this.thenValue = thenValue;




 602         }
 603 
 604         /**
 605          * Defines the {@link javafx.beans.value.ObservableObjectValue} which
 606          * value is returned by the ternary expression if the condition is
 607          * {@code false}.
 608          *
 609          * @param otherwiseValue
 610          *            the value
 611          * @return the complete {@link ObjectBinding}
 612          */
 613         public ObjectBinding<T> otherwise(final ObservableObjectValue<T> otherwiseValue) {
 614             Objects.requireNonNull(otherwiseValue, VALUE_MUST_BE_SPECIFIED);
 615             return new ObjectConditionHolder<>(thenValue, otherwiseValue).getBinding();





 616         }
 617 
 618         /**
 619          * Defines a constant value of the ternary expression that is returned
 620          * if the condition is {@code false}.
 621          *
 622          * @param otherwiseValue
 623          *            the value
 624          * @return the complete {@link ObjectBinding}
 625          */
 626         public ObjectBinding<T> otherwise(final T otherwiseValue) {
 627             return otherwise(ObjectConstant.valueOf(otherwiseValue));



 628         }
 629     }
 630 
 631     /**
 632      * Defines the {@link javafx.beans.value.ObservableObjectValue} which value
 633      * is returned by the ternary expression if the condition is {@code true}.
 634      *
 635      * @param <T> the type of the intermediate result
 636      * @param thenValue
 637      *            the value
 638      * @return the intermediate result which still requires the otherwise-branch
 639      */
 640     public <T> ObjectConditionBuilder<T> then(final ObservableObjectValue<T> thenValue) {
 641         Objects.requireNonNull(thenValue, VALUE_MUST_BE_SPECIFIED);


 642         return new ObjectConditionBuilder<T>(thenValue);
 643     }
 644 
 645     /**
 646      * Defines a constant value of the ternary expression that is returned if
 647      * the condition is {@code true}.
 648      *
 649      * @param <T> the type of the intermediate result
 650      * @param thenValue
 651      *            the value
 652      * @return the intermediate result which still requires the otherwise-branch
 653      */
 654     public <T> ObjectConditionBuilder<T> then(final T thenValue) {
 655         return then(ObjectConstant.valueOf(thenValue));
 656     }
 657 
 658 }
< prev index next >