1 /* 2 * Copyright (c) 2010, 2016, 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 java.lang.ref.WeakReference; 29 import java.text.Format; 30 import java.util.List; 31 import java.util.Locale; 32 import java.util.Map; 33 import java.util.Set; 34 import java.util.concurrent.Callable; 35 import javafx.beans.InvalidationListener; 36 import javafx.beans.Observable; 37 import javafx.beans.property.Property; 38 import javafx.beans.value.ObservableBooleanValue; 39 import javafx.beans.value.ObservableDoubleValue; 40 import javafx.beans.value.ObservableFloatValue; 41 import javafx.beans.value.ObservableIntegerValue; 42 import javafx.beans.value.ObservableLongValue; 43 import javafx.beans.value.ObservableNumberValue; 44 import javafx.beans.value.ObservableObjectValue; 45 import javafx.beans.value.ObservableStringValue; 46 import javafx.beans.value.ObservableValue; 47 import javafx.collections.FXCollections; 48 import javafx.collections.ObservableList; 49 import javafx.collections.ObservableMap; 50 import javafx.collections.ObservableSet; 51 import javafx.util.StringConverter; 52 import com.sun.javafx.binding.BidirectionalBinding; 53 import com.sun.javafx.binding.BidirectionalContentBinding; 54 import com.sun.javafx.binding.ContentBinding; 55 import com.sun.javafx.binding.DoubleConstant; 56 import com.sun.javafx.binding.FloatConstant; 57 import com.sun.javafx.binding.IntegerConstant; 58 import com.sun.javafx.binding.Logging; 59 import com.sun.javafx.binding.LongConstant; 60 import com.sun.javafx.binding.ObjectConstant; 61 import com.sun.javafx.binding.SelectBinding; 62 import com.sun.javafx.binding.StringConstant; 63 import com.sun.javafx.binding.StringFormatter; 64 import com.sun.javafx.collections.ImmutableObservableList; 65 import javafx.collections.ObservableArray; 66 import javafx.collections.ObservableFloatArray; 67 import javafx.collections.ObservableIntegerArray; 68 69 /** 70 * Bindings is a helper class with a lot of utility functions to create simple 71 * bindings. 72 * <p> 73 * Usually there are two possibilities to define the same operation: the Fluent 74 * API and the the factory methods in this class. This allows a developer to 75 * define complex expression in a way that is most easy to understand. For 76 * instance the expression {@code result = a*b + c*d} can be defined using only 77 * the Fluent API: 78 * <p> 79 * {@code DoubleBinding result = a.multiply(b).add(c.multiply(d));} 80 * <p> 81 * Or using only factory methods in Bindings: 82 * <p> 83 * {@code NumberBinding result = add (multiply(a, b), multiply(c,d));} 84 * <p> 85 * Or mixing both possibilities: 86 * <p> 87 * {@code NumberBinding result = add (a.multiply(b), c.multiply(d));} 88 * <p> 89 * The main difference between using the Fluent API and using the factory 90 * methods in this class is that the Fluent API requires that at least one of 91 * the operands is an Expression (see {@link javafx.beans.binding}). (Every 92 * Expression contains a static method that generates an Expression from an 93 * {@link javafx.beans.value.ObservableValue}.) 94 * <p> 95 * Also if you watched closely, you might have noticed that the return type of 96 * the Fluent API is different in the examples above. In a lot of cases the 97 * Fluent API allows to be more specific about the returned type (see 98 * {@link javafx.beans.binding.NumberExpression} for more details about implicit 99 * casting. 100 * </p> 101 * <p><a id="DeployAppAsModule"></a><b>Deploying an Application as a Module</b></p> 102 * <p> 103 * If any class used in a select-binding (see the various {@code select*} 104 * methods) is in a named module, then it must be reflectively accessible to the 105 * {@code javafx.base} module. 106 * A class is reflectively accessible if the module 107 * {@link Module#isOpen(String,Module) opens} the containing package to at 108 * least the {@code javafx.base} module. 109 * </p> 110 * <p> 111 * For example, if {@code com.foo.MyClass} is in the {@code foo.app} module, 112 * the {@code module-info.java} might 113 * look like this: 114 * </p> 115 * 116 <pre>{@code module foo.app { 117 opens com.foo to javafx.base; 118 }}</pre> 119 * 120 * <p> 121 * Alternatively, a class is reflectively accessible if the module 122 * {@link Module#isExported(String) exports} the containing package 123 * unconditionally. 124 * </p> 125 * 126 * @see Binding 127 * @see NumberBinding 128 * 129 * 130 * @since JavaFX 2.0 131 */ 132 public final class Bindings { 133 134 private Bindings() { 135 } 136 137 // ================================================================================================================= 138 // Helper functions to create custom bindings 139 140 /** 141 * Helper function to create a custom {@link BooleanBinding}. 142 * 143 * @param func The function that calculates the value of this binding 144 * @param dependencies The dependencies of this binding 145 * @return The generated binding 146 * @since JavaFX 2.1 147 */ 148 public static BooleanBinding createBooleanBinding(final Callable<Boolean> func, final Observable... dependencies) { 149 return new BooleanBinding() { 150 { 151 bind(dependencies); 152 } 153 154 @Override 155 protected boolean computeValue() { 156 try { 157 return func.call(); 158 } catch (Exception e) { 159 Logging.getLogger().warning("Exception while evaluating binding", e); 160 return false; 161 } 162 } 163 164 @Override 165 public void dispose() { 166 super.unbind(dependencies); 167 } 168 169 @Override 170 public ObservableList<?> getDependencies() { 171 return ((dependencies == null) || (dependencies.length == 0))? 172 FXCollections.emptyObservableList() 173 : (dependencies.length == 1)? 174 FXCollections.singletonObservableList(dependencies[0]) 175 : new ImmutableObservableList<Observable>(dependencies); 176 } 177 }; 178 } 179 180 /** 181 * Helper function to create a custom {@link DoubleBinding}. 182 * 183 * @param func The function that calculates the value of this binding 184 * @param dependencies The dependencies of this binding 185 * @return The generated binding 186 * @since JavaFX 2.1 187 */ 188 public static DoubleBinding createDoubleBinding(final Callable<Double> func, final Observable... dependencies) { 189 return new DoubleBinding() { 190 { 191 bind(dependencies); 192 } 193 194 @Override 195 protected double computeValue() { 196 try { 197 return func.call(); 198 } catch (Exception e) { 199 Logging.getLogger().warning("Exception while evaluating binding", e); 200 return 0.0; 201 } 202 } 203 204 @Override 205 public void dispose() { 206 super.unbind(dependencies); 207 } 208 209 @Override 210 public ObservableList<?> getDependencies() { 211 return ((dependencies == null) || (dependencies.length == 0))? 212 FXCollections.emptyObservableList() 213 : (dependencies.length == 1)? 214 FXCollections.singletonObservableList(dependencies[0]) 215 : new ImmutableObservableList<Observable>(dependencies); 216 } 217 }; 218 } 219 220 /** 221 * Helper function to create a custom {@link FloatBinding}. 222 * 223 * @param func The function that calculates the value of this binding 224 * @param dependencies The dependencies of this binding 225 * @return The generated binding 226 * @since JavaFX 2.1 227 */ 228 public static FloatBinding createFloatBinding(final Callable<Float> func, final Observable... dependencies) { 229 return new FloatBinding() { 230 { 231 bind(dependencies); 232 } 233 234 @Override 235 protected float computeValue() { 236 try { 237 return func.call(); 238 } catch (Exception e) { 239 Logging.getLogger().warning("Exception while evaluating binding", e); 240 return 0.0f; 241 } 242 } 243 244 @Override 245 public void dispose() { 246 super.unbind(dependencies); 247 } 248 249 @Override 250 public ObservableList<?> getDependencies() { 251 return ((dependencies == null) || (dependencies.length == 0))? 252 FXCollections.emptyObservableList() 253 : (dependencies.length == 1)? 254 FXCollections.singletonObservableList(dependencies[0]) 255 : new ImmutableObservableList<Observable>(dependencies); 256 } 257 }; 258 } 259 260 /** 261 * Helper function to create a custom {@link IntegerBinding}. 262 * 263 * @param func The function that calculates the value of this binding 264 * @param dependencies The dependencies of this binding 265 * @return The generated binding 266 * @since JavaFX 2.1 267 */ 268 public static IntegerBinding createIntegerBinding(final Callable<Integer> func, final Observable... dependencies) { 269 return new IntegerBinding() { 270 { 271 bind(dependencies); 272 } 273 274 @Override 275 protected int computeValue() { 276 try { 277 return func.call(); 278 } catch (Exception e) { 279 Logging.getLogger().warning("Exception while evaluating binding", e); 280 return 0; 281 } 282 } 283 284 @Override 285 public void dispose() { 286 super.unbind(dependencies); 287 } 288 289 @Override 290 public ObservableList<?> getDependencies() { 291 return ((dependencies == null) || (dependencies.length == 0))? 292 FXCollections.emptyObservableList() 293 : (dependencies.length == 1)? 294 FXCollections.singletonObservableList(dependencies[0]) 295 : new ImmutableObservableList<Observable>(dependencies); 296 } 297 }; 298 } 299 300 /** 301 * Helper function to create a custom {@link LongBinding}. 302 * 303 * @param func The function that calculates the value of this binding 304 * @param dependencies The dependencies of this binding 305 * @return The generated binding 306 * @since JavaFX 2.1 307 */ 308 public static LongBinding createLongBinding(final Callable<Long> func, final Observable... dependencies) { 309 return new LongBinding() { 310 { 311 bind(dependencies); 312 } 313 314 @Override 315 protected long computeValue() { 316 try { 317 return func.call(); 318 } catch (Exception e) { 319 Logging.getLogger().warning("Exception while evaluating binding", e); 320 return 0L; 321 } 322 } 323 324 @Override 325 public void dispose() { 326 super.unbind(dependencies); 327 } 328 329 @Override 330 public ObservableList<?> getDependencies() { 331 return ((dependencies == null) || (dependencies.length == 0))? 332 FXCollections.emptyObservableList() 333 : (dependencies.length == 1)? 334 FXCollections.singletonObservableList(dependencies[0]) 335 : new ImmutableObservableList<Observable>(dependencies); 336 } 337 }; 338 } 339 340 /** 341 * Helper function to create a custom {@link ObjectBinding}. 342 * 343 * @param <T> the type of the bound {@code Object} 344 * @param func The function that calculates the value of this binding 345 * @param dependencies The dependencies of this binding 346 * @return The generated binding 347 * @since JavaFX 2.1 348 */ 349 public static <T> ObjectBinding<T> createObjectBinding(final Callable<T> func, final Observable... dependencies) { 350 return new ObjectBinding<T>() { 351 { 352 bind(dependencies); 353 } 354 355 @Override 356 protected T computeValue() { 357 try { 358 return func.call(); 359 } catch (Exception e) { 360 Logging.getLogger().warning("Exception while evaluating binding", e); 361 return null; 362 } 363 } 364 365 @Override 366 public void dispose() { 367 super.unbind(dependencies); 368 } 369 370 @Override 371 public ObservableList<?> getDependencies() { 372 return ((dependencies == null) || (dependencies.length == 0))? 373 FXCollections.emptyObservableList() 374 : (dependencies.length == 1)? 375 FXCollections.singletonObservableList(dependencies[0]) 376 : new ImmutableObservableList<Observable>(dependencies); 377 } 378 }; 379 } 380 381 /** 382 * Helper function to create a custom {@link StringBinding}. 383 * 384 * @param func The function that calculates the value of this binding 385 * @param dependencies The dependencies of this binding 386 * @return The generated binding 387 * @since JavaFX 2.1 388 */ 389 public static StringBinding createStringBinding(final Callable<String> func, final Observable... dependencies) { 390 return new StringBinding() { 391 { 392 bind(dependencies); 393 } 394 395 @Override 396 protected String computeValue() { 397 try { 398 return func.call(); 399 } catch (Exception e) { 400 Logging.getLogger().warning("Exception while evaluating binding", e); 401 return ""; 402 } 403 } 404 405 @Override 406 public void dispose() { 407 super.unbind(dependencies); 408 } 409 410 @Override 411 public ObservableList<?> getDependencies() { 412 return ((dependencies == null) || (dependencies.length == 0))? 413 FXCollections.emptyObservableList() 414 : (dependencies.length == 1)? 415 FXCollections.singletonObservableList(dependencies[0]) 416 : new ImmutableObservableList<Observable>(dependencies); 417 } 418 }; 419 } 420 421 422 // ================================================================================================================= 423 // Select Bindings 424 425 /** 426 * Creates a binding used to get a member, such as {@code a.b.c}. The value 427 * of the binding will be {@code c}, or {@code null} if {@code c} could not 428 * be reached (due to {@code b} not having a {@code c} property, 429 * {@code b} being {@code null}, or {@code c} not being the right type etc.). 430 * <p> 431 * All classes and properties used in a select-binding have to be 432 * declared public. 433 * Additionally, if any class is in a named module, then it must be 434 * reflectively accessible to the {@code javafx.base} module (see 435 * <a href="#DeployAppAsModule">Deploying an Application as a Module</a>). 436 * </p> 437 * <p> 438 * Note: since 8.0, JavaBeans properties are supported and might be in the chain. 439 * </p> 440 * 441 * @param <T> the type of the wrapped {@code Object} 442 * @param root 443 * The root {@link javafx.beans.value.ObservableValue} 444 * @param steps 445 * The property names to reach the final property 446 * @return the created {@link ObjectBinding} 447 */ 448 public static <T> ObjectBinding<T> select(ObservableValue<?> root, String... steps) { 449 return new SelectBinding.AsObject<T>(root, steps); 450 } 451 452 /** 453 * Creates a binding used to get a member, such as {@code a.b.c}. The value 454 * of the binding will be {@code c}, or {@code 0.0} if {@code c} could not 455 * be reached (due to {@code b} not having a {@code c} property, 456 * {@code b} being {@code null}, or {@code c} not being a {@code Number} etc.). 457 * <p> 458 * All classes and properties used in a select-binding have to be 459 * declared public. 460 * Additionally, if any class is in a named module, then it must be 461 * reflectively accessible to the {@code javafx.base} module (see 462 * <a href="#DeployAppAsModule">Deploying an Application as a Module</a>). 463 * </p> 464 * <p> 465 * Note: since 8.0, JavaBeans properties are supported and might be in the chain. 466 * </p> 467 * 468 * @param root 469 * The root {@link javafx.beans.value.ObservableValue} 470 * @param steps 471 * The property names to reach the final property 472 * @return the created {@link DoubleBinding} 473 */ 474 public static DoubleBinding selectDouble(ObservableValue<?> root, String... steps) { 475 return new SelectBinding.AsDouble(root, steps); 476 } 477 478 /** 479 * Creates a binding used to get a member, such as {@code a.b.c}. The value 480 * of the binding will be {@code c}, or {@code 0.0f} if {@code c} could not 481 * be reached (due to {@code b} not having a {@code c} property, 482 * {@code b} being {@code null}, or {@code c} not being a {@code Number} etc.). 483 * <p> 484 * All classes and properties used in a select-binding have to be 485 * declared public. 486 * Additionally, if any class is in a named module, then it must be 487 * reflectively accessible to the {@code javafx.base} module (see 488 * <a href="#DeployAppAsModule">Deploying an Application as a Module</a>). 489 * </p> 490 * <p> 491 * Note: since 8.0, JavaBeans properties are supported and might be in the chain. 492 * </p> 493 * 494 * @param root 495 * The root {@link javafx.beans.value.ObservableValue} 496 * @param steps 497 * The property names to reach the final property 498 * @return the created {@link FloatBinding} 499 */ 500 public static FloatBinding selectFloat(ObservableValue<?> root, String... steps) { 501 return new SelectBinding.AsFloat(root, steps); 502 } 503 504 /** 505 * Creates a binding used to get a member, such as {@code a.b.c}. The value 506 * of the binding will be {@code c}, or {@code 0} if {@code c} could not 507 * be reached (due to {@code b} not having a {@code c} property, 508 * {@code b} being {@code null}, or {@code c} not being a {@code Number} etc.). 509 * <p> 510 * All classes and properties used in a select-binding have to be 511 * declared public. 512 * Additionally, if any class is in a named module, then it must be 513 * reflectively accessible to the {@code javafx.base} module (see 514 * <a href="#DeployAppAsModule">Deploying an Application as a Module</a>). 515 * </p> 516 * <p> 517 * Note: since 8.0, JavaBeans properties are supported and might be in the chain. 518 * </p> 519 * 520 * @param root 521 * The root {@link javafx.beans.value.ObservableValue} 522 * @param steps 523 * The property names to reach the final property 524 * @return the created {@link IntegerBinding} 525 */ 526 public static IntegerBinding selectInteger(ObservableValue<?> root, String... steps) { 527 return new SelectBinding.AsInteger(root, steps); 528 } 529 530 /** 531 * Creates a binding used to get a member, such as {@code a.b.c}. The value 532 * of the binding will be {@code c}, or {@code 0L} if {@code c} could not 533 * be reached (due to {@code b} not having a {@code c} property, 534 * {@code b} being {@code null}, or {@code c} not being a {@code Number} etc.). 535 * <p> 536 * All classes and properties used in a select-binding have to be 537 * declared public. 538 * Additionally, if any class is in a named module, then it must be 539 * reflectively accessible to the {@code javafx.base} module (see 540 * <a href="#DeployAppAsModule">Deploying an Application as a Module</a>). 541 * </p> 542 * <p> 543 * Note: since 8.0, JavaBeans properties are supported and might be in the chain. 544 * </p> 545 * 546 * @param root 547 * The root {@link javafx.beans.value.ObservableValue} 548 * @param steps 549 * The property names to reach the final property 550 * @return the created {@link LongBinding} 551 */ 552 public static LongBinding selectLong(ObservableValue<?> root, String... steps) { 553 return new SelectBinding.AsLong(root, steps); 554 } 555 556 /** 557 * Creates a binding used to get a member, such as {@code a.b.c}. The value 558 * of the binding will be {@code c}, or {@code false} if {@code c} could not 559 * be reached (due to {@code b} not having a {@code c} property, 560 * {@code b} being {@code null}, or {@code c} not being a {@code boolean} etc.). 561 * <p> 562 * All classes and properties used in a select-binding have to be 563 * declared public. 564 * Additionally, if any class is in a named module, then it must be 565 * reflectively accessible to the {@code javafx.base} module (see 566 * <a href="#DeployAppAsModule">Deploying an Application as a Module</a>). 567 * </p> 568 * <p> 569 * Note: since 8.0, JavaBeans properties are supported and might be in the chain. 570 * </p> 571 * 572 * @param root 573 * The root {@link javafx.beans.value.ObservableValue} 574 * @param steps 575 * The property names to reach the final property 576 * @return the created {@link ObjectBinding} 577 */ 578 public static BooleanBinding selectBoolean(ObservableValue<?> root, String... steps) { 579 return new SelectBinding.AsBoolean(root, steps); 580 } 581 582 /** 583 * Creates a binding used to get a member, such as {@code a.b.c}. The value 584 * of the binding will be {@code c}, or {@code ""} if {@code c} could not 585 * be reached (due to {@code b} not having a {@code c} property, 586 * {@code b} being {@code null}, or {@code c} not being a {@code String} etc.). 587 * <p> 588 * All classes and properties used in a select-binding have to be 589 * declared public. 590 * Additionally, if any class is in a named module, then it must be 591 * reflectively accessible to the {@code javafx.base} module (see 592 * <a href="#DeployAppAsModule">Deploying an Application as a Module</a>). 593 * </p> 594 * <p> 595 * Note: since 8.0, JavaBeans properties are supported and might be in the chain. 596 * </p> 597 * 598 * @param root 599 * The root {@link javafx.beans.value.ObservableValue} 600 * @param steps 601 * The property names to reach the final property 602 * @return the created {@link ObjectBinding} 603 */ 604 public static StringBinding selectString(ObservableValue<?> root, String... steps) { 605 return new SelectBinding.AsString(root, steps); 606 } 607 608 /** 609 * Creates a binding used to get a member, such as {@code a.b.c}. The value 610 * of the binding will be {@code c}, or {@code null} if {@code c} could not 611 * be reached (due to {@code b} not having a {@code c} property, 612 * {@code b} being {@code null}, or {@code c} not being the right type etc.). 613 * <p> 614 * All classes and properties used in a select-binding have to be 615 * declared public. 616 * Additionally, if any class is in a named module, then it must be 617 * reflectively accessible to the {@code javafx.base} module (see 618 * <a href="#DeployAppAsModule">Deploying an Application as a Module</a>). 619 * </p> 620 * 621 * <p> 622 * If root has JavaFX properties, this call is equivalent to {@link #select(javafx.beans.value.ObservableValue, java.lang.String[])}, 623 * with the {@code root} and {@code step[0]} being substituted with the relevant property object. 624 * </p> 625 * 626 * @param <T> the type of the wrapped {@code Object} 627 * @param root 628 * The root bean. 629 * @param steps 630 * The property names to reach the final property. The first step 631 * must be specified as it marks the property of the root bean. 632 * @return the created {@link ObjectBinding} 633 * @since JavaFX 8.0 634 */ 635 public static <T> ObjectBinding<T> select(Object root, String... steps) { 636 return new SelectBinding.AsObject<T>(root, steps); 637 } 638 639 /** 640 * Creates a binding used to get a member, such as {@code a.b.c}. The value 641 * of the binding will be {@code c}, or {@code 0.0} if {@code c} could not 642 * be reached (due to {@code b} not having a {@code c} property, 643 * {@code b} being {@code null}, or {@code c} not being a {@code Number} etc.). 644 * <p> 645 * All classes and properties used in a select-binding have to be 646 * declared public. 647 * Additionally, if any class is in a named module, then it must be 648 * reflectively accessible to the {@code javafx.base} module (see 649 * <a href="#DeployAppAsModule">Deploying an Application as a Module</a>). 650 * </p> 651 * 652 * <p> 653 * If root has JavaFX properties, this call is equivalent to {@link #selectDouble(javafx.beans.value.ObservableValue, java.lang.String[])}, 654 * with the {@code root} and {@code step[0]} being substituted with the relevant property object. 655 * </p> 656 * 657 * @param root 658 * The root bean. 659 * @param steps 660 * The property names to reach the final property. The first step 661 * must be specified as it marks the property of the root bean. 662 * @return the created {@link DoubleBinding} 663 * @since JavaFX 8.0 664 */ 665 public static DoubleBinding selectDouble(Object root, String... steps) { 666 return new SelectBinding.AsDouble(root, steps); 667 } 668 669 /** 670 * Creates a binding used to get a member, such as {@code a.b.c}. The value 671 * of the binding will be {@code c}, or {@code 0.0f} if {@code c} could not 672 * be reached (due to {@code b} not having a {@code c} property, 673 * {@code b} being {@code null}, or {@code c} not being a {@code Number} etc.). 674 * <p> 675 * All classes and properties used in a select-binding have to be 676 * declared public. 677 * Additionally, if any class is in a named module, then it must be 678 * reflectively accessible to the {@code javafx.base} module (see 679 * <a href="#DeployAppAsModule">Deploying an Application as a Module</a>). 680 * </p> 681 * 682 * <p> 683 * If root has JavaFX properties, this call is equivalent to {@link #selectFloat(javafx.beans.value.ObservableValue, java.lang.String[])}, 684 * with the {@code root} and {@code step[0]} being substituted with the relevant property object. 685 * </p> 686 * 687 * @param root 688 * The root bean. 689 * @param steps 690 * The property names to reach the final property. The first step 691 * must be specified as it marks the property of the root bean. 692 * @return the created {@link FloatBinding} 693 * @since JavaFX 8.0 694 */ 695 public static FloatBinding selectFloat(Object root, String... steps) { 696 return new SelectBinding.AsFloat(root, steps); 697 } 698 699 /** 700 * Creates a binding used to get a member, such as {@code a.b.c}. The value 701 * of the binding will be {@code c}, or {@code 0} if {@code c} could not 702 * be reached (due to {@code b} not having a {@code c} property, 703 * {@code b} being {@code null}, or {@code c} not being a {@code Number} etc.). 704 * <p> 705 * All classes and properties used in a select-binding have to be 706 * declared public. 707 * Additionally, if any class is in a named module, then it must be 708 * reflectively accessible to the {@code javafx.base} module (see 709 * <a href="#DeployAppAsModule">Deploying an Application as a Module</a>). 710 * </p> 711 * 712 * <p> 713 * If root has JavaFX properties, this call is equivalent to {@link #selectInteger(javafx.beans.value.ObservableValue, java.lang.String[])}, 714 * with the {@code root} and {@code step[0]} being substituted with the relevant property object. 715 * </p> 716 * 717 * @param root 718 * The root bean. 719 * @param steps 720 * The property names to reach the final property. The first step 721 * must be specified as it marks the property of the root bean. 722 * @return the created {@link IntegerBinding} 723 * @since JavaFX 8.0 724 */ 725 public static IntegerBinding selectInteger(Object root, String... steps) { 726 return new SelectBinding.AsInteger(root, steps); 727 } 728 729 /** 730 * Creates a binding used to get a member, such as {@code a.b.c}. The value 731 * of the binding will be {@code c}, or {@code 0L} if {@code c} could not 732 * be reached (due to {@code b} not having a {@code c} property, 733 * {@code b} being {@code null}, or {@code c} not being a {@code Number} etc.). 734 * <p> 735 * All classes and properties used in a select-binding have to be 736 * declared public. 737 * Additionally, if any class is in a named module, then it must be 738 * reflectively accessible to the {@code javafx.base} module (see 739 * <a href="#DeployAppAsModule">Deploying an Application as a Module</a>). 740 * </p> 741 * 742 * <p> 743 * If root has JavaFX properties, this call is equivalent to {@link #selectLong(javafx.beans.value.ObservableValue, java.lang.String[])}, 744 * with the {@code root} and {@code step[0]} being substituted with the relevant property object. 745 * </p> 746 * 747 * @param root 748 * The root bean. 749 * @param steps 750 * The property names to reach the final property. The first step 751 * must be specified as it marks the property of the root bean. 752 * @return the created {@link LongBinding} 753 * @since JavaFX 8.0 754 */ 755 public static LongBinding selectLong(Object root, String... steps) { 756 return new SelectBinding.AsLong(root, steps); 757 } 758 759 /** 760 * Creates a binding used to get a member, such as {@code a.b.c}. The value 761 * of the binding will be {@code c}, or {@code false} if {@code c} could not 762 * be reached (due to {@code b} not having a {@code c} property, 763 * {@code b} being {@code null}, or {@code c} not being a {@code boolean} etc.). 764 * <p> 765 * All classes and properties used in a select-binding have to be 766 * declared public. 767 * Additionally, if any class is in a named module, then it must be 768 * reflectively accessible to the {@code javafx.base} module (see 769 * <a href="#DeployAppAsModule">Deploying an Application as a Module</a>). 770 * </p> 771 * 772 * <p> 773 * If root has JavaFX properties, this call is equivalent to {@link #selectBoolean(javafx.beans.value.ObservableValue, java.lang.String[])}, 774 * with the {@code root} and {@code step[0]} being substituted with the relevant property object. 775 * </p> 776 * 777 * @param root 778 * The root bean. 779 * @param steps 780 * The property names to reach the final property. The first step 781 * must be specified as it marks the property of the root bean. 782 * @return the created {@link ObjectBinding} 783 * @since JavaFX 8.0 784 */ 785 public static BooleanBinding selectBoolean(Object root, String... steps) { 786 return new SelectBinding.AsBoolean(root, steps); 787 } 788 789 /** 790 * Creates a binding used to get a member, such as {@code a.b.c}. The value 791 * of the binding will be {@code c}, or {@code ""} if {@code c} could not 792 * be reached (due to {@code b} not having a {@code c} property, 793 * {@code b} being {@code null}, or {@code c} not being a {@code String} etc.). 794 * <p> 795 * All classes and properties used in a select-binding have to be 796 * declared public. 797 * Additionally, if any class is in a named module, then it must be 798 * reflectively accessible to the {@code javafx.base} module (see 799 * <a href="#DeployAppAsModule">Deploying an Application as a Module</a>). 800 * </p> 801 * 802 * <p> 803 * If root has JavaFX properties, this call is equivalent to {@link #selectString(javafx.beans.value.ObservableValue, java.lang.String[])}, 804 * with the {@code root} and {@code step[0]} being substituted with the relevant property object. 805 * </p> 806 * 807 * @param root 808 * The root bean. 809 * @param steps 810 * The property names to reach the final property. The first step 811 * must be specified as it marks the property of the root bean. 812 * @return the created {@link ObjectBinding} 813 * @since JavaFX 8.0 814 */ 815 public static StringBinding selectString(Object root, String... steps) { 816 return new SelectBinding.AsString(root, steps); 817 } 818 819 /** 820 * Creates a binding that calculates the result of a ternary expression. See 821 * the description of class {@link When} for details. 822 * 823 * @see When 824 * 825 * @param condition 826 * the condition of the ternary expression 827 * @return an intermediate class to build the complete binding 828 */ 829 public static When when(final ObservableBooleanValue condition) { 830 return new When(condition); 831 } 832 833 // ================================================================================================================= 834 // Bidirectional Bindings 835 836 /** 837 * Generates a bidirectional binding (or "bind with inverse") between two 838 * instances of {@link javafx.beans.property.Property}. 839 * <p> 840 * A bidirectional binding is a binding that works in both directions. If 841 * two properties {@code a} and {@code b} are linked with a bidirectional 842 * binding and the value of {@code a} changes, {@code b} is set to the same 843 * value automatically. And vice versa, if {@code b} changes, {@code a} is 844 * set to the same value. 845 * <p> 846 * A bidirectional binding can be removed with 847 * {@link #unbindBidirectional(Property, Property)}. 848 * <p> 849 * Note: this implementation of a bidirectional binding behaves differently 850 * from all other bindings here in two important aspects. A property that is 851 * linked to another property with a bidirectional binding can still be set 852 * (usually bindings would throw an exception). Secondly bidirectional 853 * bindings are calculated eagerly, i.e. a bound property is updated 854 * immediately. 855 * 856 * @param <T> 857 * the types of the properties 858 * @param property1 859 * the first {@code Property<T>} 860 * @param property2 861 * the second {@code Property<T>} 862 * @throws NullPointerException 863 * if one of the properties is {@code null} 864 * @throws IllegalArgumentException 865 * if both properties are equal 866 */ 867 public static <T> void bindBidirectional(Property<T> property1, Property<T> property2) { 868 BidirectionalBinding.bind(property1, property2); 869 } 870 871 /** 872 * Delete a bidirectional binding that was previously defined with 873 * {@link #bindBidirectional(Property, Property)}. 874 * 875 * @param <T> 876 * the types of the properties 877 * @param property1 878 * the first {@code Property<T>} 879 * @param property2 880 * the second {@code Property<T>} 881 * @throws NullPointerException 882 * if one of the properties is {@code null} 883 * @throws IllegalArgumentException 884 * if both properties are equal 885 */ 886 public static <T> void unbindBidirectional(Property<T> property1, Property<T> property2) { 887 BidirectionalBinding.unbind(property1, property2); 888 } 889 890 /** 891 * Delete a bidirectional binding that was previously defined with 892 * {@link #bindBidirectional(Property, Property)} or 893 * {@link #bindBidirectional(javafx.beans.property.Property, javafx.beans.property.Property, java.text.Format)}. 894 * 895 * @param property1 896 * the first {@code Property<T>} 897 * @param property2 898 * the second {@code Property<T>} 899 * @throws NullPointerException 900 * if one of the properties is {@code null} 901 * @throws IllegalArgumentException 902 * if both properties are equal 903 * @since JavaFX 2.1 904 */ 905 public static void unbindBidirectional(Object property1, Object property2) { 906 BidirectionalBinding.unbind(property1, property2); 907 } 908 909 /** 910 * Generates a bidirectional binding (or "bind with inverse") between a 911 * {@code String}-{@link javafx.beans.property.Property} and another {@code Property} 912 * using the specified {@code Format} for conversion. 913 * <p> 914 * A bidirectional binding is a binding that works in both directions. If 915 * two properties {@code a} and {@code b} are linked with a bidirectional 916 * binding and the value of {@code a} changes, {@code b} is set to the same 917 * value automatically. And vice versa, if {@code b} changes, {@code a} is 918 * set to the same value. 919 * <p> 920 * A bidirectional binding can be removed with 921 * {@link #unbindBidirectional(Object, Object)}. 922 * <p> 923 * Note: this implementation of a bidirectional binding behaves differently 924 * from all other bindings here in two important aspects. A property that is 925 * linked to another property with a bidirectional binding can still be set 926 * (usually bindings would throw an exception). Secondly bidirectional 927 * bindings are calculated eagerly, i.e. a bound property is updated 928 * immediately. 929 * 930 * @param stringProperty 931 * the {@code String} {@code Property} 932 * @param otherProperty 933 * the other (non-{@code String}) {@code Property} 934 * @param format 935 * the {@code Format} used to convert between the properties 936 * @throws NullPointerException 937 * if one of the properties or the {@code format} is {@code null} 938 * @throws IllegalArgumentException 939 * if both properties are equal 940 * @since JavaFX 2.1 941 */ 942 public static void bindBidirectional(Property<String> stringProperty, Property<?> otherProperty, Format format) { 943 BidirectionalBinding.bind(stringProperty, otherProperty, format); 944 } 945 946 /** 947 * Generates a bidirectional binding (or "bind with inverse") between a 948 * {@code String}-{@link javafx.beans.property.Property} and another {@code Property} 949 * using the specified {@link javafx.util.StringConverter} for conversion. 950 * <p> 951 * A bidirectional binding is a binding that works in both directions. If 952 * two properties {@code a} and {@code b} are linked with a bidirectional 953 * binding and the value of {@code a} changes, {@code b} is set to the same 954 * value automatically. And vice versa, if {@code b} changes, {@code a} is 955 * set to the same value. 956 * <p> 957 * A bidirectional binding can be removed with 958 * {@link #unbindBidirectional(Object, Object)}. 959 * <p> 960 * Note: this implementation of a bidirectional binding behaves differently 961 * from all other bindings here in two important aspects. A property that is 962 * linked to another property with a bidirectional binding can still be set 963 * (usually bindings would throw an exception). Secondly bidirectional 964 * bindings are calculated eagerly, i.e. a bound property is updated 965 * immediately. 966 * 967 * @param <T> the type of the wrapped {@code Object} 968 * @param stringProperty 969 * the {@code String} {@code Property} 970 * @param otherProperty 971 * the other (non-{@code String}) {@code Property} 972 * @param converter 973 * the {@code StringConverter} used to convert between the properties 974 * @throws NullPointerException 975 * if one of the properties or the {@code converter} is {@code null} 976 * @throws IllegalArgumentException 977 * if both properties are equal 978 * @since JavaFX 2.1 979 */ 980 public static <T> void bindBidirectional(Property<String> stringProperty, Property<T> otherProperty, StringConverter<T> converter) { 981 BidirectionalBinding.bind(stringProperty, otherProperty, converter); 982 } 983 984 /** 985 * Generates a bidirectional binding (or "bind with inverse") between two 986 * instances of {@link javafx.collections.ObservableList}. 987 * <p> 988 * A bidirectional binding is a binding that works in both directions. If 989 * two properties {@code a} and {@code b} are linked with a bidirectional 990 * binding and the value of {@code a} changes, {@code b} is set to the same 991 * value automatically. And vice versa, if {@code b} changes, {@code a} is 992 * set to the same value. 993 * <p> 994 * Only the content of the two lists is synchronized, which means that 995 * both lists are different, but they contain the same elements. 996 * <p> 997 * A bidirectional content-binding can be removed with 998 * {@link #unbindContentBidirectional(Object, Object)}. 999 * <p> 1000 * Note: this implementation of a bidirectional binding behaves differently 1001 * from all other bindings here in two important aspects. A property that is 1002 * linked to another property with a bidirectional binding can still be set 1003 * (usually bindings would throw an exception). Secondly bidirectional 1004 * bindings are calculated eagerly, i.e. a bound property is updated 1005 * immediately. 1006 * 1007 * @param <E> 1008 * the type of the list elements 1009 * @param list1 1010 * the first {@code ObservableList<E>} 1011 * @param list2 1012 * the second {@code ObservableList<E>} 1013 * @throws NullPointerException 1014 * if one of the lists is {@code null} 1015 * @throws IllegalArgumentException 1016 * if {@code list1} == {@code list2} 1017 * @since JavaFX 2.1 1018 */ 1019 public static <E> void bindContentBidirectional(ObservableList<E> list1, ObservableList<E> list2) { 1020 BidirectionalContentBinding.bind(list1, list2); 1021 } 1022 1023 /** 1024 * Generates a bidirectional binding (or "bind with inverse") between two 1025 * instances of {@link javafx.collections.ObservableSet}. 1026 * <p> 1027 * A bidirectional binding is a binding that works in both directions. If 1028 * two properties {@code a} and {@code b} are linked with a bidirectional 1029 * binding and the value of {@code a} changes, {@code b} is set to the same 1030 * value automatically. And vice versa, if {@code b} changes, {@code a} is 1031 * set to the same value. 1032 * <p> 1033 * Only the content of the two sets is synchronized, which means that 1034 * both sets are different, but they contain the same elements. 1035 * <p> 1036 * A bidirectional content-binding can be removed with 1037 * {@link #unbindContentBidirectional(Object, Object)}. 1038 * <p> 1039 * Note: this implementation of a bidirectional binding behaves differently 1040 * from all other bindings here in two important aspects. A property that is 1041 * linked to another property with a bidirectional binding can still be set 1042 * (usually bindings would throw an exception). Secondly bidirectional 1043 * bindings are calculated eagerly, i.e. a bound property is updated 1044 * immediately. 1045 * 1046 * @param <E> 1047 * the type of the set elements 1048 * @param set1 1049 * the first {@code ObservableSet<E>} 1050 * @param set2 1051 * the second {@code ObservableSet<E>} 1052 * @throws NullPointerException 1053 * if one of the sets is {@code null} 1054 * @throws IllegalArgumentException 1055 * if {@code set1} == {@code set2} 1056 * @since JavaFX 2.1 1057 */ 1058 public static <E> void bindContentBidirectional(ObservableSet<E> set1, ObservableSet<E> set2) { 1059 BidirectionalContentBinding.bind(set1, set2); 1060 } 1061 1062 /** 1063 * Generates a bidirectional binding (or "bind with inverse") between two 1064 * instances of {@link javafx.collections.ObservableMap}. 1065 * <p> 1066 * A bidirectional binding is a binding that works in both directions. If 1067 * two properties {@code a} and {@code b} are linked with a bidirectional 1068 * binding and the value of {@code a} changes, {@code b} is set to the same 1069 * value automatically. And vice versa, if {@code b} changes, {@code a} is 1070 * set to the same value. 1071 * <p> 1072 * Only the content of the two maps is synchronized, which means that 1073 * both maps are different, but they contain the same elements. 1074 * <p> 1075 * A bidirectional content-binding can be removed with 1076 * {@link #unbindContentBidirectional(Object, Object)}. 1077 * <p> 1078 * Note: this implementation of a bidirectional binding behaves differently 1079 * from all other bindings here in two important aspects. A property that is 1080 * linked to another property with a bidirectional binding can still be set 1081 * (usually bindings would throw an exception). Secondly bidirectional 1082 * bindings are calculated eagerly, i.e. a bound property is updated 1083 * immediately. 1084 * 1085 * @param <K> 1086 * the type of the key elements 1087 * @param <V> 1088 * the type of the value elements 1089 * @param map1 1090 * the first {@code ObservableMap<K, V>} 1091 * @param map2 1092 * the second {@code ObservableMap<K, V>} 1093 * @since JavaFX 2.1 1094 */ 1095 public static <K, V> void bindContentBidirectional(ObservableMap<K, V> map1, ObservableMap<K, V> map2) { 1096 BidirectionalContentBinding.bind(map1, map2); 1097 } 1098 1099 /** 1100 * Remove a bidirectional content binding. 1101 * 1102 * @param obj1 1103 * the first {@code Object} 1104 * @param obj2 1105 * the second {@code Object} 1106 * @since JavaFX 2.1 1107 */ 1108 public static void unbindContentBidirectional(Object obj1, Object obj2) { 1109 BidirectionalContentBinding.unbind(obj1, obj2); 1110 } 1111 1112 /** 1113 * Generates a content binding between an {@link javafx.collections.ObservableList} and a {@link java.util.List}. 1114 * <p> 1115 * A content binding ensures that the {@code List} contains the same elements as the {@code ObservableList}. 1116 * If the content of the {@code ObservableList} changes, the {@code List} will be updated automatically. 1117 * <p> 1118 * Once a {@code List} is bound to an {@code ObservableList}, the {@code List} must not be changed directly 1119 * anymore. Doing so would lead to unexpected results. 1120 * <p> 1121 * A content-binding can be removed with {@link #unbindContent(Object, Object)}. 1122 * 1123 * @param <E> 1124 * the type of the {@code List} elements 1125 * @param list1 1126 * the {@code List} 1127 * @param list2 1128 * the {@code ObservableList} 1129 * @since JavaFX 2.1 1130 */ 1131 public static <E> void bindContent(List<E> list1, ObservableList<? extends E> list2) { 1132 ContentBinding.bind(list1, list2); 1133 } 1134 1135 /** 1136 * Generates a content binding between an {@link javafx.collections.ObservableSet} and a {@link java.util.Set}. 1137 * <p> 1138 * A content binding ensures that the {@code Set} contains the same elements as the {@code ObservableSet}. 1139 * If the content of the {@code ObservableSet} changes, the {@code Set} will be updated automatically. 1140 * <p> 1141 * Once a {@code Set} is bound to an {@code ObservableSet}, the {@code Set} must not be changed directly 1142 * anymore. Doing so would lead to unexpected results. 1143 * <p> 1144 * A content-binding can be removed with {@link #unbindContent(Object, Object)}. 1145 * 1146 * @param <E> 1147 * the type of the {@code Set} elements 1148 * @param set1 1149 * the {@code Set} 1150 * @param set2 1151 * the {@code ObservableSet} 1152 * @throws NullPointerException 1153 * if one of the sets is {@code null} 1154 * @throws IllegalArgumentException 1155 * if {@code set1} == {@code set2} 1156 * @since JavaFX 2.1 1157 */ 1158 public static <E> void bindContent(Set<E> set1, ObservableSet<? extends E> set2) { 1159 ContentBinding.bind(set1, set2); 1160 } 1161 1162 /** 1163 * Generates a content binding between an {@link javafx.collections.ObservableMap} and a {@link java.util.Map}. 1164 * <p> 1165 * A content binding ensures that the {@code Map} contains the same elements as the {@code ObservableMap}. 1166 * If the content of the {@code ObservableMap} changes, the {@code Map} will be updated automatically. 1167 * <p> 1168 * Once a {@code Map} is bound to an {@code ObservableMap}, the {@code Map} must not be changed directly 1169 * anymore. Doing so would lead to unexpected results. 1170 * <p> 1171 * A content-binding can be removed with {@link #unbindContent(Object, Object)}. 1172 * 1173 * @param <K> 1174 * the type of the key elements of the {@code Map} 1175 * @param <V> 1176 * the type of the value elements of the {@code Map} 1177 * @param map1 1178 * the {@code Map} 1179 * @param map2 1180 * the {@code ObservableMap} 1181 * @throws NullPointerException 1182 * if one of the maps is {@code null} 1183 * @throws IllegalArgumentException 1184 * if {@code map1} == {@code map2} 1185 * @since JavaFX 2.1 1186 */ 1187 public static <K, V> void bindContent(Map<K, V> map1, ObservableMap<? extends K, ? extends V> map2) { 1188 ContentBinding.bind(map1, map2); 1189 } 1190 1191 /** 1192 * Remove a content binding. 1193 * 1194 * @param obj1 1195 * the first {@code Object} 1196 * @param obj2 1197 * the second {@code Object} 1198 * @throws NullPointerException 1199 * if one of the {@code Objects} is {@code null} 1200 * @throws IllegalArgumentException 1201 * if {@code obj1} == {@code obj2} 1202 * @since JavaFX 2.1 1203 */ 1204 public static void unbindContent(Object obj1, Object obj2) { 1205 ContentBinding.unbind(obj1, obj2); 1206 } 1207 1208 1209 1210 // ================================================================================================================= 1211 // Negation 1212 1213 /** 1214 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 1215 * the negation of a {@link javafx.beans.value.ObservableNumberValue}. 1216 * 1217 * @param value 1218 * the operand 1219 * @return the new {@code NumberBinding} 1220 * @throws NullPointerException 1221 * if the value is {@code null} 1222 */ 1223 public static NumberBinding negate(final ObservableNumberValue value) { 1224 if (value == null) { 1225 throw new NullPointerException("Operand cannot be null."); 1226 } 1227 1228 if (value instanceof ObservableDoubleValue) { 1229 return new DoubleBinding() { 1230 { 1231 super.bind(value); 1232 } 1233 1234 @Override 1235 public void dispose() { 1236 super.unbind(value); 1237 } 1238 1239 @Override 1240 protected double computeValue() { 1241 return -value.doubleValue(); 1242 } 1243 1244 @Override 1245 public ObservableList<?> getDependencies() { 1246 return FXCollections.singletonObservableList(value); 1247 } 1248 }; 1249 } else if (value instanceof ObservableFloatValue) { 1250 return new FloatBinding() { 1251 { 1252 super.bind(value); 1253 } 1254 1255 @Override 1256 public void dispose() { 1257 super.unbind(value); 1258 } 1259 1260 @Override 1261 protected float computeValue() { 1262 return -value.floatValue(); 1263 } 1264 1265 @Override 1266 public ObservableList<?> getDependencies() { 1267 return FXCollections.singletonObservableList(value); 1268 } 1269 }; 1270 } else if (value instanceof ObservableLongValue) { 1271 return new LongBinding() { 1272 { 1273 super.bind(value); 1274 } 1275 1276 @Override 1277 public void dispose() { 1278 super.unbind(value); 1279 } 1280 1281 @Override 1282 protected long computeValue() { 1283 return -value.longValue(); 1284 } 1285 1286 @Override 1287 public ObservableList<?> getDependencies() { 1288 return FXCollections.singletonObservableList(value); 1289 } 1290 }; 1291 } else { 1292 return new IntegerBinding() { 1293 { 1294 super.bind(value); 1295 } 1296 1297 @Override 1298 public void dispose() { 1299 super.unbind(value); 1300 } 1301 1302 @Override 1303 protected int computeValue() { 1304 return -value.intValue(); 1305 } 1306 1307 @Override 1308 public ObservableList<?> getDependencies() { 1309 return FXCollections.singletonObservableList(value); 1310 } 1311 }; 1312 } 1313 } 1314 1315 // ================================================================================================================= 1316 // Sum 1317 1318 private static NumberBinding add(final ObservableNumberValue op1, final ObservableNumberValue op2, final Observable... dependencies) { 1319 if ((op1 == null) || (op2 == null)) { 1320 throw new NullPointerException("Operands cannot be null."); 1321 } 1322 assert (dependencies != null) && (dependencies.length > 0); 1323 1324 if ((op1 instanceof ObservableDoubleValue) || (op2 instanceof ObservableDoubleValue)) { 1325 return new DoubleBinding() { 1326 { 1327 super.bind(dependencies); 1328 } 1329 1330 @Override 1331 public void dispose() { 1332 super.unbind(dependencies); 1333 } 1334 1335 @Override 1336 protected double computeValue() { 1337 return op1.doubleValue() + op2.doubleValue(); 1338 } 1339 1340 @Override 1341 public ObservableList<?> getDependencies() { 1342 return (dependencies.length == 1)? 1343 FXCollections.singletonObservableList(dependencies[0]) 1344 : new ImmutableObservableList<Observable>(dependencies); 1345 } 1346 }; 1347 } else if ((op1 instanceof ObservableFloatValue) || (op2 instanceof ObservableFloatValue)) { 1348 return new FloatBinding() { 1349 { 1350 super.bind(dependencies); 1351 } 1352 1353 @Override 1354 public void dispose() { 1355 super.unbind(dependencies); 1356 } 1357 1358 @Override 1359 protected float computeValue() { 1360 return op1.floatValue() + op2.floatValue(); 1361 } 1362 1363 @Override 1364 public ObservableList<?> getDependencies() { 1365 return (dependencies.length == 1)? 1366 FXCollections.singletonObservableList(dependencies[0]) 1367 : new ImmutableObservableList<Observable>(dependencies); 1368 } 1369 }; 1370 } else if ((op1 instanceof ObservableLongValue) || (op2 instanceof ObservableLongValue)) { 1371 return new LongBinding() { 1372 { 1373 super.bind(dependencies); 1374 } 1375 1376 @Override 1377 public void dispose() { 1378 super.unbind(dependencies); 1379 } 1380 1381 @Override 1382 protected long computeValue() { 1383 return op1.longValue() + op2.longValue(); 1384 } 1385 1386 @Override 1387 public ObservableList<?> getDependencies() { 1388 return (dependencies.length == 1)? 1389 FXCollections.singletonObservableList(dependencies[0]) 1390 : new ImmutableObservableList<Observable>(dependencies); 1391 } 1392 }; 1393 } else { 1394 return new IntegerBinding() { 1395 { 1396 super.bind(dependencies); 1397 } 1398 1399 @Override 1400 public void dispose() { 1401 super.unbind(dependencies); 1402 } 1403 1404 @Override 1405 protected int computeValue() { 1406 return op1.intValue() + op2.intValue(); 1407 } 1408 1409 @Override 1410 public ObservableList<?> getDependencies() { 1411 return (dependencies.length == 1)? 1412 FXCollections.singletonObservableList(dependencies[0]) 1413 : new ImmutableObservableList<Observable>(dependencies); 1414 } 1415 }; 1416 } 1417 } 1418 1419 /** 1420 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 1421 * the sum of the values of two instances of 1422 * {@link javafx.beans.value.ObservableNumberValue}. 1423 * 1424 * @param op1 1425 * the first operand 1426 * @param op2 1427 * the second operand 1428 * @return the new {@code NumberBinding} 1429 * @throws NullPointerException 1430 * if one of the operands is {@code null} 1431 */ 1432 public static NumberBinding add(final ObservableNumberValue op1, final ObservableNumberValue op2) { 1433 return Bindings.add(op1, op2, op1, op2); 1434 } 1435 1436 /** 1437 * Creates a new {@link javafx.beans.binding.DoubleBinding} that calculates 1438 * the sum of the value of a 1439 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 1440 * 1441 * @param op1 1442 * the {@code ObservableNumberValue} 1443 * @param op2 1444 * the constant value 1445 * @return the new {@code DoubleBinding} 1446 * @throws NullPointerException 1447 * if the {@code ObservableNumberValue} is {@code null} 1448 */ 1449 public static DoubleBinding add(final ObservableNumberValue op1, double op2) { 1450 return (DoubleBinding) Bindings.add(op1, DoubleConstant.valueOf(op2), op1); 1451 } 1452 1453 /** 1454 * Creates a new {@link javafx.beans.binding.DoubleBinding} that calculates 1455 * the sum of the value of a 1456 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 1457 * 1458 * @param op1 1459 * the constant value 1460 * @param op2 1461 * the {@code ObservableNumberValue} 1462 * @return the new {@code DoubleBinding} 1463 * @throws NullPointerException 1464 * if the {@code ObservableNumberValue} is {@code null} 1465 */ 1466 public static DoubleBinding add(double op1, final ObservableNumberValue op2) { 1467 return (DoubleBinding) Bindings.add(DoubleConstant.valueOf(op1), op2, op2); 1468 } 1469 1470 /** 1471 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 1472 * the sum of the value of a 1473 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 1474 * 1475 * @param op1 1476 * the {@code ObservableNumberValue} 1477 * @param op2 1478 * the constant value 1479 * @return the new {@code NumberBinding} 1480 * @throws NullPointerException 1481 * if the {@code ObservableNumberValue} is {@code null} 1482 */ 1483 public static NumberBinding add(final ObservableNumberValue op1, float op2) { 1484 return Bindings.add(op1, FloatConstant.valueOf(op2), op1); 1485 } 1486 1487 /** 1488 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 1489 * the sum of the value of a 1490 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 1491 * 1492 * @param op1 1493 * the constant value 1494 * @param op2 1495 * the {@code ObservableNumberValue} 1496 * @return the new {@code NumberBinding} 1497 * @throws NullPointerException 1498 * if the {@code ObservableNumberValue} is {@code null} 1499 */ 1500 public static NumberBinding add(float op1, final ObservableNumberValue op2) { 1501 return Bindings.add(FloatConstant.valueOf(op1), op2, op2); 1502 } 1503 1504 /** 1505 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 1506 * the sum of the value of a 1507 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 1508 * 1509 * @param op1 1510 * the {@code ObservableNumberValue} 1511 * @param op2 1512 * the constant value 1513 * @return the new {@code NumberBinding} 1514 * @throws NullPointerException 1515 * if the {@code ObservableNumberValue} is {@code null} 1516 */ 1517 public static NumberBinding add(final ObservableNumberValue op1, long op2) { 1518 return Bindings.add(op1, LongConstant.valueOf(op2), op1); 1519 } 1520 1521 /** 1522 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 1523 * the sum of the value of a 1524 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 1525 * 1526 * @param op1 1527 * the constant value 1528 * @param op2 1529 * the {@code ObservableNumberValue} 1530 * @return the new {@code NumberBinding} 1531 * @throws NullPointerException 1532 * if the {@code ObservableNumberValue} is {@code null} 1533 */ 1534 public static NumberBinding add(long op1, final ObservableNumberValue op2) { 1535 return Bindings.add(LongConstant.valueOf(op1), op2, op2); 1536 } 1537 1538 /** 1539 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 1540 * the sum of the value of a 1541 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 1542 * 1543 * @param op1 1544 * the {@code ObservableNumberValue} 1545 * @param op2 1546 * the constant value 1547 * @return the new {@code NumberBinding} 1548 * @throws NullPointerException 1549 * if the {@code ObservableNumberValue} is {@code null} 1550 */ 1551 public static NumberBinding add(final ObservableNumberValue op1, int op2) { 1552 return Bindings.add(op1, IntegerConstant.valueOf(op2), op1); 1553 } 1554 1555 /** 1556 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 1557 * the sum of the value of a 1558 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 1559 * 1560 * @param op1 1561 * the constant value 1562 * @param op2 1563 * the {@code ObservableNumberValue} 1564 * @return the new {@code NumberBinding} 1565 * @throws NullPointerException 1566 * if the {@code ObservableNumberValue} is {@code null} 1567 */ 1568 public static NumberBinding add(int op1, final ObservableNumberValue op2) { 1569 return Bindings.add(IntegerConstant.valueOf(op1), op2, op2); 1570 } 1571 1572 // ================================================================================================================= 1573 // Diff 1574 1575 private static NumberBinding subtract(final ObservableNumberValue op1, final ObservableNumberValue op2, final Observable... dependencies) { 1576 if ((op1 == null) || (op2 == null)) { 1577 throw new NullPointerException("Operands cannot be null."); 1578 } 1579 assert (dependencies != null) && (dependencies.length > 0); 1580 1581 if ((op1 instanceof ObservableDoubleValue) || (op2 instanceof ObservableDoubleValue)) { 1582 return new DoubleBinding() { 1583 { 1584 super.bind(dependencies); 1585 } 1586 1587 @Override 1588 public void dispose() { 1589 super.unbind(dependencies); 1590 } 1591 1592 @Override 1593 protected double computeValue() { 1594 return op1.doubleValue() - op2.doubleValue(); 1595 } 1596 1597 @Override 1598 public ObservableList<?> getDependencies() { 1599 return (dependencies.length == 1)? 1600 FXCollections.singletonObservableList(dependencies[0]) 1601 : new ImmutableObservableList<Observable>(dependencies); 1602 } 1603 }; 1604 } else if ((op1 instanceof ObservableFloatValue) || (op2 instanceof ObservableFloatValue)) { 1605 return new FloatBinding() { 1606 { 1607 super.bind(dependencies); 1608 } 1609 1610 @Override 1611 public void dispose() { 1612 super.unbind(dependencies); 1613 } 1614 1615 @Override 1616 protected float computeValue() { 1617 return op1.floatValue() - op2.floatValue(); 1618 } 1619 1620 @Override 1621 public ObservableList<?> getDependencies() { 1622 return (dependencies.length == 1)? 1623 FXCollections.singletonObservableList(dependencies[0]) 1624 : new ImmutableObservableList<Observable>(dependencies); 1625 } 1626 }; 1627 } else if ((op1 instanceof ObservableLongValue) || (op2 instanceof ObservableLongValue)) { 1628 return new LongBinding() { 1629 { 1630 super.bind(dependencies); 1631 } 1632 1633 @Override 1634 public void dispose() { 1635 super.unbind(dependencies); 1636 } 1637 1638 @Override 1639 protected long computeValue() { 1640 return op1.longValue() - op2.longValue(); 1641 } 1642 1643 @Override 1644 public ObservableList<?> getDependencies() { 1645 return (dependencies.length == 1)? 1646 FXCollections.singletonObservableList(dependencies[0]) 1647 : new ImmutableObservableList<Observable>(dependencies); 1648 } 1649 }; 1650 } else { 1651 return new IntegerBinding() { 1652 { 1653 super.bind(dependencies); 1654 } 1655 1656 @Override 1657 public void dispose() { 1658 super.unbind(dependencies); 1659 } 1660 1661 @Override 1662 protected int computeValue() { 1663 return op1.intValue() - op2.intValue(); 1664 } 1665 1666 @Override 1667 public ObservableList<?> getDependencies() { 1668 return (dependencies.length == 1)? 1669 FXCollections.singletonObservableList(dependencies[0]) 1670 : new ImmutableObservableList<Observable>(dependencies); 1671 } 1672 }; 1673 } 1674 } 1675 1676 /** 1677 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 1678 * the difference of the values of two instances of 1679 * {@link javafx.beans.value.ObservableNumberValue}. 1680 * 1681 * @param op1 1682 * the first operand 1683 * @param op2 1684 * the second operand 1685 * @return the new {@code NumberBinding} 1686 * @throws NullPointerException 1687 * if one of the operands is {@code null} 1688 */ 1689 public static NumberBinding subtract(final ObservableNumberValue op1, final ObservableNumberValue op2) { 1690 return Bindings.subtract(op1, op2, op1, op2); 1691 } 1692 1693 /** 1694 * Creates a new {@link javafx.beans.binding.DoubleBinding} that calculates 1695 * the difference of the value of a 1696 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 1697 * 1698 * @param op1 1699 * the {@code ObservableNumberValue} 1700 * @param op2 1701 * the constant value 1702 * @return the new {@code DoubleBinding} 1703 * @throws NullPointerException 1704 * if the {@code ObservableNumberValue} is {@code null} 1705 */ 1706 public static DoubleBinding subtract(final ObservableNumberValue op1, double op2) { 1707 return (DoubleBinding) Bindings.subtract(op1, DoubleConstant.valueOf(op2), op1); 1708 } 1709 1710 /** 1711 * Creates a new {@link javafx.beans.binding.DoubleBinding} that calculates 1712 * the difference of a constant value and the value of a 1713 * {@link javafx.beans.value.ObservableNumberValue}. 1714 * 1715 * @param op1 1716 * the constant value 1717 * @param op2 1718 * the {@code ObservableNumberValue} 1719 * @return the new {@code DoubleBinding} 1720 * @throws NullPointerException 1721 * if the {@code ObservableNumberValue} is {@code null} 1722 */ 1723 public static DoubleBinding subtract(double op1, final ObservableNumberValue op2) { 1724 return (DoubleBinding) Bindings.subtract(DoubleConstant.valueOf(op1), op2, op2); 1725 } 1726 1727 /** 1728 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 1729 * the difference of the value of a 1730 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 1731 * 1732 * @param op1 1733 * the constant value 1734 * @param op2 1735 * the {@code ObservableNumberValue} 1736 * @return the new {@code NumberBinding} 1737 * @throws NullPointerException 1738 * if the {@code ObservableNumberValue} is {@code null} 1739 */ 1740 public static NumberBinding subtract(final ObservableNumberValue op1, float op2) { 1741 return Bindings.subtract(op1, FloatConstant.valueOf(op2), op1); 1742 } 1743 1744 /** 1745 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 1746 * the difference of a constant value and the value of a 1747 * {@link javafx.beans.value.ObservableNumberValue}. 1748 * 1749 * @param op1 1750 * the {@code ObservableNumberValue} 1751 * @param op2 1752 * the constant value 1753 * @return the new {@code NumberBinding} 1754 * @throws NullPointerException 1755 * if the {@code ObservableNumberValue} is {@code null} 1756 */ 1757 public static NumberBinding subtract(float op1, final ObservableNumberValue op2) { 1758 return Bindings.subtract(FloatConstant.valueOf(op1), op2, op2); 1759 } 1760 1761 /** 1762 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 1763 * the difference of the value of a 1764 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 1765 * 1766 * @param op1 1767 * the constant value 1768 * @param op2 1769 * the {@code ObservableNumberValue} 1770 * @return the new {@code NumberBinding} 1771 * @throws NullPointerException 1772 * if the {@code ObservableNumberValue} is {@code null} 1773 */ 1774 public static NumberBinding subtract(final ObservableNumberValue op1, long op2) { 1775 return Bindings.subtract(op1, LongConstant.valueOf(op2), op1); 1776 } 1777 1778 /** 1779 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 1780 * the difference of a constant value and the value of a 1781 * {@link javafx.beans.value.ObservableNumberValue}. 1782 * 1783 * @param op1 1784 * the {@code ObservableNumberValue} 1785 * @param op2 1786 * the constant value 1787 * @return the new {@code NumberBinding} 1788 * @throws NullPointerException 1789 * if the {@code ObservableNumberValue} is {@code null} 1790 */ 1791 public static NumberBinding subtract(long op1, final ObservableNumberValue op2) { 1792 return Bindings.subtract(LongConstant.valueOf(op1), op2, op2); 1793 } 1794 1795 /** 1796 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 1797 * the difference of the value of a 1798 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 1799 * 1800 * @param op1 1801 * the constant value 1802 * @param op2 1803 * the {@code ObservableNumberValue} 1804 * @return the new {@code NumberBinding} 1805 * @throws NullPointerException 1806 * if the {@code ObservableNumberValue} is {@code null} 1807 */ 1808 public static NumberBinding subtract(final ObservableNumberValue op1, int op2) { 1809 return Bindings.subtract(op1, IntegerConstant.valueOf(op2), op1); 1810 } 1811 1812 /** 1813 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 1814 * the difference of a constant value and the value of a 1815 * {@link javafx.beans.value.ObservableNumberValue}. 1816 * 1817 * @param op1 1818 * the {@code ObservableNumberValue} 1819 * @param op2 1820 * the constant value 1821 * @return the new {@code NumberBinding} 1822 * @throws NullPointerException 1823 * if the {@code ObservableNumberValue} is {@code null} 1824 */ 1825 public static NumberBinding subtract(int op1, final ObservableNumberValue op2) { 1826 return Bindings.subtract(IntegerConstant.valueOf(op1), op2, op2); 1827 } 1828 1829 // ================================================================================================================= 1830 // Multiply 1831 1832 private static NumberBinding multiply(final ObservableNumberValue op1, final ObservableNumberValue op2, final Observable... dependencies) { 1833 if ((op1 == null) || (op2 == null)) { 1834 throw new NullPointerException("Operands cannot be null."); 1835 } 1836 assert (dependencies != null) && (dependencies.length > 0); 1837 1838 if ((op1 instanceof ObservableDoubleValue) || (op2 instanceof ObservableDoubleValue)) { 1839 return new DoubleBinding() { 1840 { 1841 super.bind(dependencies); 1842 } 1843 1844 @Override 1845 public void dispose() { 1846 super.unbind(dependencies); 1847 } 1848 1849 @Override 1850 protected double computeValue() { 1851 return op1.doubleValue() * op2.doubleValue(); 1852 } 1853 1854 @Override 1855 public ObservableList<?> getDependencies() { 1856 return (dependencies.length == 1)? 1857 FXCollections.singletonObservableList(dependencies[0]) 1858 : new ImmutableObservableList<Observable>(dependencies); 1859 } 1860 }; 1861 } else if ((op1 instanceof ObservableFloatValue) || (op2 instanceof ObservableFloatValue)) { 1862 return new FloatBinding() { 1863 { 1864 super.bind(dependencies); 1865 } 1866 1867 @Override 1868 public void dispose() { 1869 super.unbind(dependencies); 1870 } 1871 1872 @Override 1873 protected float computeValue() { 1874 return op1.floatValue() * op2.floatValue(); 1875 } 1876 1877 @Override 1878 public ObservableList<?> getDependencies() { 1879 return (dependencies.length == 1)? 1880 FXCollections.singletonObservableList(dependencies[0]) 1881 : new ImmutableObservableList<Observable>(dependencies); 1882 } 1883 }; 1884 } else if ((op1 instanceof ObservableLongValue) || (op2 instanceof ObservableLongValue)) { 1885 return new LongBinding() { 1886 { 1887 super.bind(dependencies); 1888 } 1889 1890 @Override 1891 public void dispose() { 1892 super.unbind(dependencies); 1893 } 1894 1895 @Override 1896 protected long computeValue() { 1897 return op1.longValue() * op2.longValue(); 1898 } 1899 1900 @Override 1901 public ObservableList<?> getDependencies() { 1902 return (dependencies.length == 1)? 1903 FXCollections.singletonObservableList(dependencies[0]) 1904 : new ImmutableObservableList<Observable>(dependencies); 1905 } 1906 }; 1907 } else { 1908 return new IntegerBinding() { 1909 { 1910 super.bind(dependencies); 1911 } 1912 1913 @Override 1914 public void dispose() { 1915 super.unbind(dependencies); 1916 } 1917 1918 @Override 1919 protected int computeValue() { 1920 return op1.intValue() * op2.intValue(); 1921 } 1922 1923 @Override 1924 public ObservableList<?> getDependencies() { 1925 return (dependencies.length == 1)? 1926 FXCollections.singletonObservableList(dependencies[0]) 1927 : new ImmutableObservableList<Observable>(dependencies); 1928 } 1929 }; 1930 } 1931 } 1932 1933 /** 1934 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 1935 * the product of the values of two instances of 1936 * {@link javafx.beans.value.ObservableNumberValue}. 1937 * 1938 * @param op1 1939 * the first operand 1940 * @param op2 1941 * the second operand 1942 * @return the new {@code NumberBinding} 1943 * @throws NullPointerException 1944 * if one of the operands is {@code null} 1945 */ 1946 public static NumberBinding multiply(final ObservableNumberValue op1, final ObservableNumberValue op2) { 1947 return Bindings.multiply(op1, op2, op1, op2); 1948 } 1949 1950 /** 1951 * Creates a new {@link javafx.beans.binding.DoubleBinding} that calculates 1952 * the product of the value of a 1953 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 1954 * 1955 * @param op1 1956 * the {@code ObservableNumberValue} 1957 * @param op2 1958 * the constant value 1959 * @return the new {@code DoubleBinding} 1960 * @throws NullPointerException 1961 * if the {@code ObservableNumberValue} is {@code null} 1962 */ 1963 public static DoubleBinding multiply(final ObservableNumberValue op1, double op2) { 1964 return (DoubleBinding) Bindings.multiply(op1, DoubleConstant.valueOf(op2), op1); 1965 } 1966 1967 /** 1968 * Creates a new {@link javafx.beans.binding.DoubleBinding} that calculates 1969 * the product of the value of a 1970 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 1971 * 1972 * @param op1 1973 * the constant value 1974 * @param op2 1975 * the {@code ObservableNumberValue} 1976 * @return the new {@code DoubleBinding} 1977 * @throws NullPointerException 1978 * if the {@code ObservableNumberValue} is {@code null} 1979 */ 1980 public static DoubleBinding multiply(double op1, final ObservableNumberValue op2) { 1981 return (DoubleBinding) Bindings.multiply(DoubleConstant.valueOf(op1), op2, op2); 1982 } 1983 1984 /** 1985 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 1986 * the product of the value of a 1987 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 1988 * 1989 * @param op1 1990 * the constant value 1991 * @param op2 1992 * the {@code ObservableNumberValue} 1993 * @return the new {@code NumberBinding} 1994 * @throws NullPointerException 1995 * if the {@code ObservableNumberValue} is {@code null} 1996 */ 1997 public static NumberBinding multiply(final ObservableNumberValue op1, float op2) { 1998 return Bindings.multiply(op1, FloatConstant.valueOf(op2), op1); 1999 } 2000 2001 /** 2002 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 2003 * the product of the value of a 2004 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 2005 * 2006 * @param op1 2007 * the constant value 2008 * @param op2 2009 * the {@code ObservableNumberValue} 2010 * @return the new {@code NumberBinding} 2011 * @throws NullPointerException 2012 * if the {@code ObservableNumberValue} is {@code null} 2013 */ 2014 public static NumberBinding multiply(float op1, final ObservableNumberValue op2) { 2015 return Bindings.multiply(FloatConstant.valueOf(op1), op2, op2); 2016 } 2017 2018 /** 2019 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 2020 * the product of the value of a 2021 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 2022 * 2023 * @param op1 2024 * the constant value 2025 * @param op2 2026 * the {@code ObservableNumberValue} 2027 * @return the new {@code NumberBinding} 2028 * @throws NullPointerException 2029 * if the {@code ObservableNumberValue} is {@code null} 2030 */ 2031 public static NumberBinding multiply(final ObservableNumberValue op1, long op2) { 2032 return Bindings.multiply(op1, LongConstant.valueOf(op2), op1); 2033 } 2034 2035 /** 2036 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 2037 * the product of the value of a 2038 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 2039 * 2040 * @param op1 2041 * the constant value 2042 * @param op2 2043 * the {@code ObservableNumberValue} 2044 * @return the new {@code NumberBinding} 2045 * @throws NullPointerException 2046 * if the {@code ObservableNumberValue} is {@code null} 2047 */ 2048 public static NumberBinding multiply(long op1, final ObservableNumberValue op2) { 2049 return Bindings.multiply(LongConstant.valueOf(op1), op2, op2); 2050 } 2051 2052 /** 2053 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 2054 * the product of the value of a 2055 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 2056 * 2057 * @param op1 2058 * the constant value 2059 * @param op2 2060 * the {@code ObservableNumberValue} 2061 * @return the new {@code NumberBinding} 2062 * @throws NullPointerException 2063 * if the {@code ObservableNumberValue} is {@code null} 2064 */ 2065 public static NumberBinding multiply(final ObservableNumberValue op1, int op2) { 2066 return Bindings.multiply(op1, IntegerConstant.valueOf(op2), op1); 2067 } 2068 2069 /** 2070 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 2071 * the product of the value of a 2072 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 2073 * 2074 * @param op1 2075 * the constant value 2076 * @param op2 2077 * the {@code ObservableNumberValue} 2078 * @return the new {@code NumberBinding} 2079 * @throws NullPointerException 2080 * if the {@code ObservableNumberValue} is {@code null} 2081 */ 2082 public static NumberBinding multiply(int op1, final ObservableNumberValue op2) { 2083 return Bindings.multiply(IntegerConstant.valueOf(op1), op2, op2); 2084 } 2085 2086 // ================================================================================================================= 2087 // Divide 2088 2089 private static NumberBinding divide(final ObservableNumberValue op1, final ObservableNumberValue op2, final Observable... dependencies) { 2090 if ((op1 == null) || (op2 == null)) { 2091 throw new NullPointerException("Operands cannot be null."); 2092 } 2093 assert (dependencies != null) && (dependencies.length > 0); 2094 2095 if ((op1 instanceof ObservableDoubleValue) || (op2 instanceof ObservableDoubleValue)) { 2096 return new DoubleBinding() { 2097 { 2098 super.bind(dependencies); 2099 } 2100 2101 @Override 2102 public void dispose() { 2103 super.unbind(dependencies); 2104 } 2105 2106 @Override 2107 protected double computeValue() { 2108 return op1.doubleValue() / op2.doubleValue(); 2109 } 2110 2111 @Override 2112 public ObservableList<?> getDependencies() { 2113 return (dependencies.length == 1)? 2114 FXCollections.singletonObservableList(dependencies[0]) 2115 : new ImmutableObservableList<Observable>(dependencies); 2116 } 2117 }; 2118 } else if ((op1 instanceof ObservableFloatValue) || (op2 instanceof ObservableFloatValue)) { 2119 return new FloatBinding() { 2120 { 2121 super.bind(dependencies); 2122 } 2123 2124 @Override 2125 public void dispose() { 2126 super.unbind(dependencies); 2127 } 2128 2129 @Override 2130 protected float computeValue() { 2131 return op1.floatValue() / op2.floatValue(); 2132 } 2133 2134 @Override 2135 public ObservableList<?> getDependencies() { 2136 return (dependencies.length == 1)? 2137 FXCollections.singletonObservableList(dependencies[0]) 2138 : new ImmutableObservableList<Observable>(dependencies); 2139 } 2140 }; 2141 } else if ((op1 instanceof ObservableLongValue) || (op2 instanceof ObservableLongValue)) { 2142 return new LongBinding() { 2143 { 2144 super.bind(dependencies); 2145 } 2146 2147 @Override 2148 public void dispose() { 2149 super.unbind(dependencies); 2150 } 2151 2152 @Override 2153 protected long computeValue() { 2154 return op1.longValue() / op2.longValue(); 2155 } 2156 2157 @Override 2158 public ObservableList<?> getDependencies() { 2159 return (dependencies.length == 1)? 2160 FXCollections.singletonObservableList(dependencies[0]) 2161 : new ImmutableObservableList<Observable>(dependencies); 2162 } 2163 }; 2164 } else { 2165 return new IntegerBinding() { 2166 { 2167 super.bind(dependencies); 2168 } 2169 2170 @Override 2171 public void dispose() { 2172 super.unbind(dependencies); 2173 } 2174 2175 @Override 2176 protected int computeValue() { 2177 return op1.intValue() / op2.intValue(); 2178 } 2179 2180 @Override 2181 public ObservableList<?> getDependencies() { 2182 return (dependencies.length == 1)? 2183 FXCollections.singletonObservableList(dependencies[0]) 2184 : new ImmutableObservableList<Observable>(dependencies); 2185 } 2186 }; 2187 } 2188 } 2189 2190 /** 2191 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 2192 * the division of the values of two instances of 2193 * {@link javafx.beans.value.ObservableNumberValue}. 2194 * 2195 * @param op1 2196 * the first operand 2197 * @param op2 2198 * the second operand 2199 * @return the new {@code NumberBinding} 2200 * @throws NullPointerException 2201 * if one of the operands is {@code null} 2202 */ 2203 public static NumberBinding divide(final ObservableNumberValue op1, final ObservableNumberValue op2) { 2204 return Bindings.divide(op1, op2, op1, op2); 2205 } 2206 2207 /** 2208 * Creates a new {@link javafx.beans.binding.DoubleBinding} that calculates 2209 * the division of the value of a 2210 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 2211 * 2212 * @param op1 2213 * the {@code ObservableNumberValue} 2214 * @param op2 2215 * the constant value 2216 * @return the new {@code DoubleBinding} 2217 * @throws NullPointerException 2218 * if the {@code ObservableNumberValue} is {@code null} 2219 */ 2220 public static DoubleBinding divide(final ObservableNumberValue op1, double op2) { 2221 return (DoubleBinding) Bindings.divide(op1, DoubleConstant.valueOf(op2), op1); 2222 } 2223 2224 /** 2225 * Creates a new {@link javafx.beans.binding.DoubleBinding} that calculates 2226 * the division of a constant value and the value of a 2227 * {@link javafx.beans.value.ObservableNumberValue}. 2228 * 2229 * @param op1 2230 * the constant value 2231 * @param op2 2232 * the {@code ObservableNumberValue} 2233 * @return the new {@code DoubleBinding} 2234 * @throws NullPointerException 2235 * if the {@code ObservableNumberValue} is {@code null} 2236 */ 2237 public static DoubleBinding divide(double op1, final ObservableNumberValue op2) { 2238 return (DoubleBinding) Bindings.divide(DoubleConstant.valueOf(op1), op2, op2); 2239 } 2240 2241 /** 2242 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 2243 * the division of the value of a 2244 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 2245 * 2246 * @param op1 2247 * the constant value 2248 * @param op2 2249 * the {@code ObservableNumberValue} 2250 * @return the new {@code NumberBinding} 2251 * @throws NullPointerException 2252 * if the {@code ObservableNumberValue} is {@code null} 2253 */ 2254 public static NumberBinding divide(final ObservableNumberValue op1, float op2) { 2255 return Bindings.divide(op1, FloatConstant.valueOf(op2), op1); 2256 } 2257 2258 /** 2259 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 2260 * the division of a constant value and the value of a 2261 * {@link javafx.beans.value.ObservableNumberValue}. 2262 * 2263 * @param op1 2264 * the {@code ObservableNumberValue} 2265 * @param op2 2266 * the constant value 2267 * @return the new {@code NumberBinding} 2268 * @throws NullPointerException 2269 * if the {@code ObservableNumberValue} is {@code null} 2270 */ 2271 public static NumberBinding divide(float op1, final ObservableNumberValue op2) { 2272 return Bindings.divide(FloatConstant.valueOf(op1), op2, op2); 2273 } 2274 2275 /** 2276 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 2277 * the division of the value of a 2278 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 2279 * 2280 * @param op1 2281 * the constant value 2282 * @param op2 2283 * the {@code ObservableNumberValue} 2284 * @return the new {@code NumberBinding} 2285 * @throws NullPointerException 2286 * if the {@code ObservableNumberValue} is {@code null} 2287 */ 2288 public static NumberBinding divide(final ObservableNumberValue op1, long op2) { 2289 return Bindings.divide(op1, LongConstant.valueOf(op2), op1); 2290 } 2291 2292 /** 2293 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 2294 * the division of a constant value and the value of a 2295 * {@link javafx.beans.value.ObservableNumberValue}. 2296 * 2297 * @param op1 2298 * the {@code ObservableNumberValue} 2299 * @param op2 2300 * the constant value 2301 * @return the new {@code NumberBinding} 2302 * @throws NullPointerException 2303 * if the {@code ObservableNumberValue} is {@code null} 2304 */ 2305 public static NumberBinding divide(long op1, final ObservableNumberValue op2) { 2306 return Bindings.divide(LongConstant.valueOf(op1), op2, op2); 2307 } 2308 2309 /** 2310 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 2311 * the division of the value of a 2312 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 2313 * 2314 * @param op1 2315 * the constant value 2316 * @param op2 2317 * the {@code ObservableNumberValue} 2318 * @return the new {@code NumberBinding} 2319 * @throws NullPointerException 2320 * if the {@code ObservableNumberValue} is {@code null} 2321 */ 2322 public static NumberBinding divide(final ObservableNumberValue op1, int op2) { 2323 return Bindings.divide(op1, IntegerConstant.valueOf(op2), op1); 2324 } 2325 2326 /** 2327 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 2328 * the division of a constant value and the value of a 2329 * {@link javafx.beans.value.ObservableNumberValue}. 2330 * 2331 * @param op1 2332 * the {@code ObservableNumberValue} 2333 * @param op2 2334 * the constant value 2335 * @return the new {@code NumberBinding} 2336 * @throws NullPointerException 2337 * if the {@code ObservableNumberValue} is {@code null} 2338 */ 2339 public static NumberBinding divide(int op1, final ObservableNumberValue op2) { 2340 return Bindings.divide(IntegerConstant.valueOf(op1), op2, op2); 2341 } 2342 2343 // ================================================================================================================= 2344 // Equals 2345 2346 private static BooleanBinding equal(final ObservableNumberValue op1, final ObservableNumberValue op2, final double epsilon, final Observable... dependencies) { 2347 if ((op1 == null) || (op2 == null)) { 2348 throw new NullPointerException("Operands cannot be null."); 2349 } 2350 assert (dependencies != null) && (dependencies.length > 0); 2351 2352 if ((op1 instanceof ObservableDoubleValue) || (op2 instanceof ObservableDoubleValue)) { 2353 return new BooleanBinding() { 2354 { 2355 super.bind(dependencies); 2356 } 2357 2358 @Override 2359 public void dispose() { 2360 super.unbind(dependencies); 2361 } 2362 2363 @Override 2364 protected boolean computeValue() { 2365 return Math.abs(op1.doubleValue() - op2.doubleValue()) <= epsilon; 2366 } 2367 2368 @Override 2369 public ObservableList<?> getDependencies() { 2370 return (dependencies.length == 1)? 2371 FXCollections.singletonObservableList(dependencies[0]) 2372 : new ImmutableObservableList<Observable>(dependencies); 2373 } 2374 }; 2375 } else if ((op1 instanceof ObservableFloatValue) || (op2 instanceof ObservableFloatValue)) { 2376 return new BooleanBinding() { 2377 { 2378 super.bind(dependencies); 2379 } 2380 2381 @Override 2382 public void dispose() { 2383 super.unbind(dependencies); 2384 } 2385 2386 @Override 2387 protected boolean computeValue() { 2388 return Math.abs(op1.floatValue() - op2.floatValue()) <= epsilon; 2389 } 2390 2391 @Override 2392 public ObservableList<?> getDependencies() { 2393 return (dependencies.length == 1)? 2394 FXCollections.singletonObservableList(dependencies[0]) 2395 : new ImmutableObservableList<Observable>(dependencies); 2396 } 2397 }; 2398 } else if ((op1 instanceof ObservableLongValue) || (op2 instanceof ObservableLongValue)) { 2399 return new BooleanBinding() { 2400 { 2401 super.bind(dependencies); 2402 } 2403 2404 @Override 2405 public void dispose() { 2406 super.unbind(dependencies); 2407 } 2408 2409 @Override 2410 protected boolean computeValue() { 2411 return Math.abs(op1.longValue() - op2.longValue()) <= epsilon; 2412 } 2413 2414 @Override 2415 public ObservableList<?> getDependencies() { 2416 return (dependencies.length == 1)? 2417 FXCollections.singletonObservableList(dependencies[0]) 2418 : new ImmutableObservableList<Observable>(dependencies); 2419 } 2420 }; 2421 } else { 2422 return new BooleanBinding() { 2423 { 2424 super.bind(dependencies); 2425 } 2426 2427 @Override 2428 public void dispose() { 2429 super.unbind(dependencies); 2430 } 2431 2432 @Override 2433 protected boolean computeValue() { 2434 return Math.abs(op1.intValue() - op2.intValue()) <= epsilon; 2435 } 2436 2437 @Override 2438 public ObservableList<?> getDependencies() { 2439 return (dependencies.length == 1)? 2440 FXCollections.singletonObservableList(dependencies[0]) 2441 : new ImmutableObservableList<Observable>(dependencies); 2442 } 2443 }; 2444 } 2445 } 2446 2447 /** 2448 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 2449 * if the values of two instances of 2450 * {@link javafx.beans.value.ObservableNumberValue} are equal (with a 2451 * tolerance). 2452 * <p> 2453 * Two operands {@code a} and {@code b} are considered equal if 2454 * {@code Math.abs(a-b) <= epsilon}. 2455 * <p> 2456 * Allowing a small tolerance is recommended when comparing floating-point 2457 * numbers because of rounding-errors. 2458 * 2459 * @param op1 2460 * the first operand 2461 * @param op2 2462 * the second operand 2463 * @param epsilon 2464 * the permitted tolerance 2465 * @return the new {@code BooleanBinding} 2466 * @throws NullPointerException 2467 * if one of the operands is {@code null} 2468 */ 2469 public static BooleanBinding equal(final ObservableNumberValue op1, final ObservableNumberValue op2, final double epsilon) { 2470 return Bindings.equal(op1, op2, epsilon, op1, op2); 2471 } 2472 2473 /** 2474 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 2475 * if the values of two instances of 2476 * {@link javafx.beans.value.ObservableNumberValue} are equal. 2477 * <p> 2478 * When comparing floating-point numbers it is recommended to use the 2479 * {@link #equal(ObservableNumberValue, ObservableNumberValue, double) 2480 * equal()} method that allows a small tolerance. 2481 * 2482 * @param op1 2483 * the first operand 2484 * @param op2 2485 * the second operand 2486 * @return the new {@code BooleanBinding} 2487 * @throws NullPointerException 2488 * if one of the operands is {@code null} 2489 */ 2490 public static BooleanBinding equal(final ObservableNumberValue op1, final ObservableNumberValue op2) { 2491 return equal(op1, op2, 0.0, op1, op2); 2492 } 2493 2494 /** 2495 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 2496 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 2497 * equal to a constant value (with a tolerance). 2498 * <p> 2499 * Two operands {@code a} and {@code b} are considered equal if 2500 * {@code Math.abs(a-b) <= epsilon}. 2501 * <p> 2502 * Allowing a small tolerance is recommended when comparing floating-point 2503 * numbers because of rounding-errors. 2504 * 2505 * @param op1 2506 * the {@code ObservableNumberValue} 2507 * @param op2 2508 * the constant value 2509 * @param epsilon 2510 * the permitted tolerance 2511 * @return the new {@code BooleanBinding} 2512 * @throws NullPointerException 2513 * if the {@code ObservableNumberValue} is {@code null} 2514 */ 2515 public static BooleanBinding equal(final ObservableNumberValue op1, final double op2, final double epsilon) { 2516 return equal(op1, DoubleConstant.valueOf(op2), epsilon, op1); 2517 } 2518 2519 /** 2520 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 2521 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 2522 * equal to a constant value (with a tolerance). 2523 * <p> 2524 * Two operands {@code a} and {@code b} are considered equal if 2525 * {@code Math.abs(a-b) <= epsilon}. 2526 * <p> 2527 * Allowing a small tolerance is recommended when comparing floating-point 2528 * numbers because of rounding-errors. 2529 * 2530 * @param op1 2531 * the constant value 2532 * @param op2 2533 * the {@code ObservableNumberValue} 2534 * @param epsilon 2535 * the permitted tolerance 2536 * @return the new {@code BooleanBinding} 2537 * @throws NullPointerException 2538 * if the {@code ObservableNumberValue} is {@code null} 2539 */ 2540 public static BooleanBinding equal(final double op1, final ObservableNumberValue op2, final double epsilon) { 2541 return equal(DoubleConstant.valueOf(op1), op2, epsilon, op2); 2542 } 2543 2544 /** 2545 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 2546 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 2547 * equal to a constant value (with a tolerance). 2548 * <p> 2549 * Two operands {@code a} and {@code b} are considered equal if 2550 * {@code Math.abs(a-b) <= epsilon}. 2551 * <p> 2552 * Allowing a small tolerance is recommended when comparing floating-point 2553 * numbers because of rounding-errors. 2554 * 2555 * @param op1 2556 * the {@code ObservableNumberValue} 2557 * @param op2 2558 * the constant value 2559 * @param epsilon 2560 * the permitted tolerance 2561 * @return the new {@code BooleanBinding} 2562 * @throws NullPointerException 2563 * if the {@code ObservableNumberValue} is {@code null} 2564 */ 2565 public static BooleanBinding equal(final ObservableNumberValue op1, final float op2, final double epsilon) { 2566 return equal(op1, FloatConstant.valueOf(op2), epsilon, op1); 2567 } 2568 2569 /** 2570 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 2571 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 2572 * equal to a constant value (with a tolerance). 2573 * <p> 2574 * Two operands {@code a} and {@code b} are considered equal if 2575 * {@code Math.abs(a-b) <= epsilon}. 2576 * <p> 2577 * Allowing a small tolerance is recommended when comparing floating-point 2578 * numbers because of rounding-errors. 2579 * 2580 * @param op1 2581 * the constant value 2582 * @param op2 2583 * the {@code ObservableNumberValue} 2584 * @param epsilon 2585 * the permitted tolerance 2586 * @return the new {@code BooleanBinding} 2587 * @throws NullPointerException 2588 * if the {@code ObservableNumberValue} is {@code null} 2589 */ 2590 public static BooleanBinding equal(final float op1, final ObservableNumberValue op2, final double epsilon) { 2591 return equal(FloatConstant.valueOf(op1), op2, epsilon, op2); 2592 } 2593 2594 /** 2595 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 2596 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 2597 * equal to a constant value (with a tolerance). 2598 * <p> 2599 * Two operands {@code a} and {@code b} are considered equal if 2600 * {@code Math.abs(a-b) <= epsilon}. 2601 * <p> 2602 * Allowing a small tolerance is recommended when comparing floating-point 2603 * numbers because of rounding-errors. 2604 * 2605 * @param op1 2606 * the {@code ObservableNumberValue} 2607 * @param op2 2608 * the constant value 2609 * @param epsilon 2610 * the permitted tolerance 2611 * @return the new {@code BooleanBinding} 2612 * @throws NullPointerException 2613 * if the {@code ObservableNumberValue} is {@code null} 2614 */ 2615 public static BooleanBinding equal(final ObservableNumberValue op1, final long op2, final double epsilon) { 2616 return equal(op1, LongConstant.valueOf(op2), epsilon, op1); 2617 } 2618 2619 /** 2620 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 2621 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 2622 * equal to a constant value. 2623 * <p> 2624 * When comparing floating-point numbers it is recommended to use the 2625 * {@link #equal(ObservableNumberValue, long, double) equal()} method that 2626 * allows a small tolerance. 2627 * 2628 * @param op1 2629 * the {@code ObservableNumberValue} 2630 * @param op2 2631 * the constant value 2632 * @return the new {@code BooleanBinding} 2633 * @throws NullPointerException 2634 * if the {@code ObservableNumberValue} is {@code null} 2635 */ 2636 public static BooleanBinding equal(final ObservableNumberValue op1, final long op2) { 2637 return equal(op1, LongConstant.valueOf(op2), 0.0, op1); 2638 } 2639 2640 /** 2641 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 2642 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 2643 * equal to a constant value (with a tolerance). 2644 * <p> 2645 * Two operands {@code a} and {@code b} are considered equal if 2646 * {@code Math.abs(a-b) <= epsilon}. 2647 * <p> 2648 * Allowing a small tolerance is recommended when comparing floating-point 2649 * numbers because of rounding-errors. 2650 * 2651 * @param op1 2652 * the constant value 2653 * @param op2 2654 * the {@code ObservableNumberValue} 2655 * @param epsilon 2656 * the permitted tolerance 2657 * @return the new {@code BooleanBinding} 2658 * @throws NullPointerException 2659 * if the {@code ObservableNumberValue} is {@code null} 2660 */ 2661 public static BooleanBinding equal(final long op1, final ObservableNumberValue op2, final double epsilon) { 2662 return equal(LongConstant.valueOf(op1), op2, epsilon, op2); 2663 } 2664 2665 /** 2666 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 2667 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 2668 * equal to a constant value. 2669 * <p> 2670 * When comparing floating-point numbers it is recommended to use the 2671 * {@link #equal(long, ObservableNumberValue, double) equal()} method that 2672 * allows a small tolerance. 2673 * 2674 * @param op1 2675 * the constant value 2676 * @param op2 2677 * the {@code ObservableNumberValue} 2678 * @return the new {@code BooleanBinding} 2679 * @throws NullPointerException 2680 * if the {@code ObservableNumberValue} is {@code null} 2681 */ 2682 public static BooleanBinding equal(final long op1, final ObservableNumberValue op2) { 2683 return equal(LongConstant.valueOf(op1), op2, 0.0, op2); 2684 } 2685 2686 /** 2687 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 2688 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 2689 * equal to a constant value (with a tolerance). 2690 * <p> 2691 * Two operands {@code a} and {@code b} are considered equal if 2692 * {@code Math.abs(a-b) <= epsilon}. 2693 * <p> 2694 * Allowing a small tolerance is recommended when comparing floating-point 2695 * numbers because of rounding-errors. 2696 * 2697 * @param op1 2698 * the {@code ObservableNumberValue} 2699 * @param op2 2700 * the constant value 2701 * @param epsilon 2702 * the permitted tolerance 2703 * @return the new {@code BooleanBinding} 2704 * @throws NullPointerException 2705 * if the {@code ObservableNumberValue} is {@code null} 2706 */ 2707 public static BooleanBinding equal(final ObservableNumberValue op1, final int op2, final double epsilon) { 2708 return equal(op1, IntegerConstant.valueOf(op2), epsilon, op1); 2709 } 2710 2711 /** 2712 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 2713 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 2714 * equal to a constant value. 2715 * <p> 2716 * When comparing floating-point numbers it is recommended to use the 2717 * {@link #equal(ObservableNumberValue, int, double) equal()} method that 2718 * allows a small tolerance. 2719 * 2720 * @param op1 2721 * the {@code ObservableNumberValue} 2722 * @param op2 2723 * the constant value 2724 * @return the new {@code BooleanBinding} 2725 * @throws NullPointerException 2726 * if the {@code ObservableNumberValue} is {@code null} 2727 */ 2728 public static BooleanBinding equal(final ObservableNumberValue op1, final int op2) { 2729 return equal(op1, IntegerConstant.valueOf(op2), 0.0, op1); 2730 } 2731 2732 /** 2733 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 2734 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 2735 * equal to a constant value (with a tolerance). 2736 * <p> 2737 * Two operands {@code a} and {@code b} are considered equal if 2738 * {@code Math.abs(a-b) <= epsilon}. 2739 * <p> 2740 * Allowing a small tolerance is recommended when comparing floating-point 2741 * numbers because of rounding-errors. 2742 * 2743 * @param op1 2744 * the constant value 2745 * @param op2 2746 * the {@code ObservableNumberValue} 2747 * @param epsilon 2748 * the permitted tolerance 2749 * @return the new {@code BooleanBinding} 2750 * @throws NullPointerException 2751 * if the {@code ObservableNumberValue} is {@code null} 2752 */ 2753 public static BooleanBinding equal(final int op1, final ObservableNumberValue op2, final double epsilon) { 2754 return equal(IntegerConstant.valueOf(op1), op2, epsilon, op2); 2755 } 2756 2757 /** 2758 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 2759 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 2760 * equal to a constant value. 2761 * <p> 2762 * When comparing floating-point numbers it is recommended to use the 2763 * {@link #equal(int, ObservableNumberValue, double) equal()} method that 2764 * allows a small tolerance. 2765 * 2766 * @param op1 2767 * the constant value 2768 * @param op2 2769 * the {@code ObservableNumberValue} 2770 * @return the new {@code BooleanBinding} 2771 * @throws NullPointerException 2772 * if the {@code ObservableNumberValue} is {@code null} 2773 */ 2774 public static BooleanBinding equal(final int op1, final ObservableNumberValue op2) { 2775 return equal(IntegerConstant.valueOf(op1), op2, 0.0, op2); 2776 } 2777 2778 // ================================================================================================================= 2779 // Not Equal 2780 2781 private static BooleanBinding notEqual(final ObservableNumberValue op1, final ObservableNumberValue op2, final double epsilon, final Observable... dependencies) { 2782 if ((op1 == null) || (op2 == null)) { 2783 throw new NullPointerException("Operands cannot be null."); 2784 } 2785 assert (dependencies != null) && (dependencies.length > 0); 2786 2787 if ((op1 instanceof ObservableDoubleValue) || (op2 instanceof ObservableDoubleValue)) { 2788 return new BooleanBinding() { 2789 { 2790 super.bind(dependencies); 2791 } 2792 2793 @Override 2794 public void dispose() { 2795 super.unbind(dependencies); 2796 } 2797 2798 @Override 2799 protected boolean computeValue() { 2800 return Math.abs(op1.doubleValue() - op2.doubleValue()) > epsilon; 2801 } 2802 2803 @Override 2804 public ObservableList<?> getDependencies() { 2805 return (dependencies.length == 1)? 2806 FXCollections.singletonObservableList(dependencies[0]) 2807 : new ImmutableObservableList<Observable>(dependencies); 2808 } 2809 }; 2810 } else if ((op1 instanceof ObservableFloatValue) || (op2 instanceof ObservableFloatValue)) { 2811 return new BooleanBinding() { 2812 { 2813 super.bind(dependencies); 2814 } 2815 2816 @Override 2817 public void dispose() { 2818 super.unbind(dependencies); 2819 } 2820 2821 @Override 2822 protected boolean computeValue() { 2823 return Math.abs(op1.floatValue() - op2.floatValue()) > epsilon; 2824 } 2825 2826 @Override 2827 public ObservableList<?> getDependencies() { 2828 return (dependencies.length == 1)? 2829 FXCollections.singletonObservableList(dependencies[0]) 2830 : new ImmutableObservableList<Observable>(dependencies); 2831 } 2832 }; 2833 } else if ((op1 instanceof ObservableLongValue) || (op2 instanceof ObservableLongValue)) { 2834 return new BooleanBinding() { 2835 { 2836 super.bind(dependencies); 2837 } 2838 2839 @Override 2840 public void dispose() { 2841 super.unbind(dependencies); 2842 } 2843 2844 @Override 2845 protected boolean computeValue() { 2846 return Math.abs(op1.longValue() - op2.longValue()) > epsilon; 2847 } 2848 2849 @Override 2850 public ObservableList<?> getDependencies() { 2851 return (dependencies.length == 1)? 2852 FXCollections.singletonObservableList(dependencies[0]) 2853 : new ImmutableObservableList<Observable>(dependencies); 2854 } 2855 }; 2856 } else { 2857 return new BooleanBinding() { 2858 { 2859 super.bind(dependencies); 2860 } 2861 2862 @Override 2863 public void dispose() { 2864 super.unbind(dependencies); 2865 } 2866 2867 @Override 2868 protected boolean computeValue() { 2869 return Math.abs(op1.intValue() - op2.intValue()) > epsilon; 2870 } 2871 2872 @Override 2873 public ObservableList<?> getDependencies() { 2874 return (dependencies.length == 1)? 2875 FXCollections.singletonObservableList(dependencies[0]) 2876 : new ImmutableObservableList<Observable>(dependencies); 2877 } 2878 }; 2879 } 2880 } 2881 2882 /** 2883 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 2884 * if the values of two instances of 2885 * {@link javafx.beans.value.ObservableNumberValue} are not equal (with a 2886 * tolerance). 2887 * <p> 2888 * Two operands {@code a} and {@code b} are considered equal if 2889 * {@code Math.abs(a-b) <= epsilon}. 2890 * <p> 2891 * Allowing a small tolerance is recommended when comparing floating-point 2892 * numbers because of rounding-errors. 2893 * 2894 * @param op1 2895 * the first operand 2896 * @param op2 2897 * the second operand 2898 * @param epsilon 2899 * the permitted tolerance 2900 * @return the new {@code BooleanBinding} 2901 * @throws NullPointerException 2902 * if one of the operands is {@code null} 2903 */ 2904 public static BooleanBinding notEqual(final ObservableNumberValue op1, final ObservableNumberValue op2, final double epsilon) { 2905 return Bindings.notEqual(op1, op2, epsilon, op1, op2); 2906 } 2907 2908 /** 2909 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 2910 * if the values of two instances of 2911 * {@link javafx.beans.value.ObservableNumberValue} are not equal. 2912 * <p> 2913 * When comparing floating-point numbers it is recommended to use the 2914 * {@link #notEqual(ObservableNumberValue, ObservableNumberValue, double) 2915 * notEqual()} method that allows a small tolerance. 2916 * 2917 * @param op1 2918 * the first operand 2919 * @param op2 2920 * the second operand 2921 * @return the new {@code BooleanBinding} 2922 * @throws NullPointerException 2923 * if one of the operands is {@code null} 2924 */ 2925 public static BooleanBinding notEqual(final ObservableNumberValue op1, final ObservableNumberValue op2) { 2926 return notEqual(op1, op2, 0.0, op1, op2); 2927 } 2928 2929 /** 2930 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 2931 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is not 2932 * equal to a constant value (with a tolerance). 2933 * <p> 2934 * Two operands {@code a} and {@code b} are considered equal if 2935 * {@code Math.abs(a-b) <= epsilon}. 2936 * <p> 2937 * Allowing a small tolerance is recommended when comparing floating-point 2938 * numbers because of rounding-errors. 2939 * 2940 * @param op1 2941 * the {@code ObservableNumberValue} 2942 * @param op2 2943 * the constant value 2944 * @param epsilon 2945 * the permitted tolerance 2946 * @return the new {@code BooleanBinding} 2947 * @throws NullPointerException 2948 * if the {@code ObservableNumberValue} is {@code null} 2949 */ 2950 public static BooleanBinding notEqual(final ObservableNumberValue op1, final double op2, final double epsilon) { 2951 return notEqual(op1, DoubleConstant.valueOf(op2), epsilon, op1); 2952 } 2953 2954 /** 2955 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 2956 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is not 2957 * equal to a constant value (with a tolerance). 2958 * <p> 2959 * Two operands {@code a} and {@code b} are considered equal if 2960 * {@code Math.abs(a-b) <= epsilon}. 2961 * <p> 2962 * Allowing a small tolerance is recommended when comparing floating-point 2963 * numbers because of rounding-errors. 2964 * 2965 * @param op1 2966 * the constant value 2967 * @param op2 2968 * the {@code ObservableNumberValue} 2969 * @param epsilon 2970 * the permitted tolerance 2971 * @return the new {@code BooleanBinding} 2972 * @throws NullPointerException 2973 * if the {@code ObservableNumberValue} is {@code null} 2974 */ 2975 public static BooleanBinding notEqual(final double op1, final ObservableNumberValue op2, final double epsilon) { 2976 return notEqual(DoubleConstant.valueOf(op1), op2, epsilon, op2); 2977 } 2978 2979 /** 2980 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 2981 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is not 2982 * equal to a constant value (with a tolerance). 2983 * <p> 2984 * Two operands {@code a} and {@code b} are considered equal if 2985 * {@code Math.abs(a-b) <= epsilon}. 2986 * <p> 2987 * Allowing a small tolerance is recommended when comparing floating-point 2988 * numbers because of rounding-errors. 2989 * 2990 * @param op1 2991 * the {@code ObservableNumberValue} 2992 * @param op2 2993 * the constant value 2994 * @param epsilon 2995 * the permitted tolerance 2996 * @return the new {@code BooleanBinding} 2997 * @throws NullPointerException 2998 * if the {@code ObservableNumberValue} is {@code null} 2999 */ 3000 public static BooleanBinding notEqual(final ObservableNumberValue op1, final float op2, final double epsilon) { 3001 return notEqual(op1, FloatConstant.valueOf(op2), epsilon, op1); 3002 } 3003 3004 /** 3005 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3006 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is not 3007 * equal to a constant value (with a tolerance). 3008 * <p> 3009 * Two operands {@code a} and {@code b} are considered equal if 3010 * {@code Math.abs(a-b) <= epsilon}. 3011 * <p> 3012 * Allowing a small tolerance is recommended when comparing floating-point 3013 * numbers because of rounding-errors. 3014 * 3015 * @param op1 3016 * the constant value 3017 * @param op2 3018 * the {@code ObservableNumberValue} 3019 * @param epsilon 3020 * the permitted tolerance 3021 * @return the new {@code BooleanBinding} 3022 * @throws NullPointerException 3023 * if the {@code ObservableNumberValue} is {@code null} 3024 */ 3025 public static BooleanBinding notEqual(final float op1, final ObservableNumberValue op2, final double epsilon) { 3026 return notEqual(FloatConstant.valueOf(op1), op2, epsilon, op2); 3027 } 3028 3029 /** 3030 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3031 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is not 3032 * equal to a constant value (with a tolerance). 3033 * <p> 3034 * Two operands {@code a} and {@code b} are considered equal if 3035 * {@code Math.abs(a-b) <= epsilon}. 3036 * <p> 3037 * Allowing a small tolerance is recommended when comparing floating-point 3038 * numbers because of rounding-errors. 3039 * 3040 * @param op1 3041 * the {@code ObservableNumberValue} 3042 * @param op2 3043 * the constant value 3044 * @param epsilon 3045 * the permitted tolerance 3046 * @return the new {@code BooleanBinding} 3047 * @throws NullPointerException 3048 * if the {@code ObservableNumberValue} is {@code null} 3049 */ 3050 public static BooleanBinding notEqual(final ObservableNumberValue op1, final long op2, final double epsilon) { 3051 return notEqual(op1, LongConstant.valueOf(op2), epsilon, op1); 3052 } 3053 3054 /** 3055 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3056 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is not 3057 * equal to a constant value. 3058 * <p> 3059 * When comparing floating-point numbers it is recommended to use the 3060 * {@link #notEqual(ObservableNumberValue, long, double) notEqual()} method 3061 * that allows a small tolerance. 3062 * 3063 * @param op1 3064 * the {@code ObservableNumberValue} 3065 * @param op2 3066 * the constant value 3067 * @return the new {@code BooleanBinding} 3068 * @throws NullPointerException 3069 * if the {@code ObservableNumberValue} is {@code null} 3070 */ 3071 public static BooleanBinding notEqual(final ObservableNumberValue op1, final long op2) { 3072 return notEqual(op1, LongConstant.valueOf(op2), 0.0, op1); 3073 } 3074 3075 /** 3076 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3077 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is not 3078 * equal to a constant value (with a tolerance). 3079 * <p> 3080 * Two operands {@code a} and {@code b} are considered equal if 3081 * {@code Math.abs(a-b) <= epsilon}. 3082 * <p> 3083 * Allowing a small tolerance is recommended when comparing floating-point 3084 * numbers because of rounding-errors. 3085 * 3086 * @param op1 3087 * the constant value 3088 * @param op2 3089 * the {@code ObservableNumberValue} 3090 * @param epsilon 3091 * the permitted tolerance 3092 * @return the new {@code BooleanBinding} 3093 * @throws NullPointerException 3094 * if the {@code ObservableNumberValue} is {@code null} 3095 */ 3096 public static BooleanBinding notEqual(final long op1, final ObservableNumberValue op2, final double epsilon) { 3097 return notEqual(LongConstant.valueOf(op1), op2, epsilon, op2); 3098 } 3099 3100 /** 3101 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3102 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is not 3103 * equal to a constant value. 3104 * <p> 3105 * When comparing floating-point numbers it is recommended to use the 3106 * {@link #notEqual(long, ObservableNumberValue, double) notEqual()} method 3107 * that allows a small tolerance. 3108 * 3109 * @param op1 3110 * the constant value 3111 * @param op2 3112 * the {@code ObservableNumberValue} 3113 * @return the new {@code BooleanBinding} 3114 * @throws NullPointerException 3115 * if the {@code ObservableNumberValue} is {@code null} 3116 */ 3117 public static BooleanBinding notEqual(final long op1, final ObservableNumberValue op2) { 3118 return notEqual(LongConstant.valueOf(op1), op2, 0.0, op2); 3119 } 3120 3121 /** 3122 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3123 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is not 3124 * equal to a constant value (with a tolerance). 3125 * <p> 3126 * Two operands {@code a} and {@code b} are considered equal if 3127 * {@code Math.abs(a-b) <= epsilon}. 3128 * <p> 3129 * Allowing a small tolerance is recommended when comparing floating-point 3130 * numbers because of rounding-errors. 3131 * 3132 * @param op1 3133 * the {@code ObservableNumberValue} 3134 * @param op2 3135 * the constant value 3136 * @param epsilon 3137 * the permitted tolerance 3138 * @return the new {@code BooleanBinding} 3139 * @throws NullPointerException 3140 * if the {@code ObservableNumberValue} is {@code null} 3141 */ 3142 public static BooleanBinding notEqual(final ObservableNumberValue op1, final int op2, final double epsilon) { 3143 return notEqual(op1, IntegerConstant.valueOf(op2), epsilon, op1); 3144 } 3145 3146 /** 3147 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3148 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is not 3149 * equal to a constant value. 3150 * <p> 3151 * When comparing floating-point numbers it is recommended to use the 3152 * {@link #notEqual(ObservableNumberValue, int, double) notEqual()} method 3153 * that allows a small tolerance. 3154 * 3155 * @param op1 3156 * the {@code ObservableNumberValue} 3157 * @param op2 3158 * the constant value 3159 * @return the new {@code BooleanBinding} 3160 * @throws NullPointerException 3161 * if the {@code ObservableNumberValue} is {@code null} 3162 */ 3163 public static BooleanBinding notEqual(final ObservableNumberValue op1, final int op2) { 3164 return notEqual(op1, IntegerConstant.valueOf(op2), 0.0, op1); 3165 } 3166 3167 /** 3168 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3169 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is not 3170 * equal to a constant value (with a tolerance). 3171 * <p> 3172 * Two operands {@code a} and {@code b} are considered equal if 3173 * {@code Math.abs(a-b) <= epsilon}. 3174 * <p> 3175 * Allowing a small tolerance is recommended when comparing floating-point 3176 * numbers because of rounding-errors. 3177 * 3178 * @param op1 3179 * the constant value 3180 * @param op2 3181 * the {@code ObservableNumberValue} 3182 * @param epsilon 3183 * the permitted tolerance 3184 * @return the new {@code BooleanBinding} 3185 * @throws NullPointerException 3186 * if the {@code ObservableNumberValue} is {@code null} 3187 */ 3188 public static BooleanBinding notEqual(final int op1, final ObservableNumberValue op2, final double epsilon) { 3189 return notEqual(IntegerConstant.valueOf(op1), op2, epsilon, op2); 3190 } 3191 3192 /** 3193 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3194 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is not 3195 * equal to a constant value. 3196 * <p> 3197 * When comparing floating-point numbers it is recommended to use the 3198 * {@link #notEqual(int, ObservableNumberValue, double) notEqual()} method 3199 * that allows a small tolerance. 3200 * 3201 * @param op1 3202 * the constant value 3203 * @param op2 3204 * the {@code ObservableNumberValue} 3205 * @return the new {@code BooleanBinding} 3206 * @throws NullPointerException 3207 * if the {@code ObservableNumberValue} is {@code null} 3208 */ 3209 public static BooleanBinding notEqual(final int op1, final ObservableNumberValue op2) { 3210 return notEqual(IntegerConstant.valueOf(op1), op2, 0.0, op2); 3211 } 3212 3213 // ================================================================================================================= 3214 // Greater Than 3215 3216 private static BooleanBinding greaterThan(final ObservableNumberValue op1, final ObservableNumberValue op2, final Observable... dependencies) { 3217 if ((op1 == null) || (op2 == null)) { 3218 throw new NullPointerException("Operands cannot be null."); 3219 } 3220 assert (dependencies != null) && (dependencies.length > 0); 3221 3222 if ((op1 instanceof ObservableDoubleValue) || (op2 instanceof ObservableDoubleValue)) { 3223 return new BooleanBinding() { 3224 { 3225 super.bind(dependencies); 3226 } 3227 3228 @Override 3229 public void dispose() { 3230 super.unbind(dependencies); 3231 } 3232 3233 @Override 3234 protected boolean computeValue() { 3235 return op1.doubleValue() > op2.doubleValue(); 3236 } 3237 3238 @Override 3239 public ObservableList<?> getDependencies() { 3240 return (dependencies.length == 1)? 3241 FXCollections.singletonObservableList(dependencies[0]) 3242 : new ImmutableObservableList<Observable>(dependencies); 3243 } 3244 }; 3245 } else if ((op1 instanceof ObservableFloatValue) || (op2 instanceof ObservableFloatValue)) { 3246 return new BooleanBinding() { 3247 { 3248 super.bind(dependencies); 3249 } 3250 3251 @Override 3252 public void dispose() { 3253 super.unbind(dependencies); 3254 } 3255 3256 @Override 3257 protected boolean computeValue() { 3258 return op1.floatValue() > op2.floatValue(); 3259 } 3260 3261 @Override 3262 public ObservableList<?> getDependencies() { 3263 return (dependencies.length == 1)? 3264 FXCollections.singletonObservableList(dependencies[0]) 3265 : new ImmutableObservableList<Observable>(dependencies); 3266 } 3267 }; 3268 } else if ((op1 instanceof ObservableLongValue) || (op2 instanceof ObservableLongValue)) { 3269 return new BooleanBinding() { 3270 { 3271 super.bind(dependencies); 3272 } 3273 3274 @Override 3275 public void dispose() { 3276 super.unbind(dependencies); 3277 } 3278 3279 @Override 3280 protected boolean computeValue() { 3281 return op1.longValue() > op2.longValue(); 3282 } 3283 3284 @Override 3285 public ObservableList<?> getDependencies() { 3286 return (dependencies.length == 1)? 3287 FXCollections.singletonObservableList(dependencies[0]) 3288 : new ImmutableObservableList<Observable>(dependencies); 3289 } 3290 }; 3291 } else { 3292 return new BooleanBinding() { 3293 { 3294 super.bind(dependencies); 3295 } 3296 3297 @Override 3298 public void dispose() { 3299 super.unbind(dependencies); 3300 } 3301 3302 @Override 3303 protected boolean computeValue() { 3304 return op1.intValue() > op2.intValue(); 3305 } 3306 3307 @Override 3308 public ObservableList<?> getDependencies() { 3309 return (dependencies.length == 1)? 3310 FXCollections.singletonObservableList(dependencies[0]) 3311 : new ImmutableObservableList<Observable>(dependencies); 3312 } 3313 }; 3314 } 3315 } 3316 3317 /** 3318 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3319 * if the value of the first 3320 * {@link javafx.beans.value.ObservableNumberValue} is greater than the 3321 * value of the second. 3322 * 3323 * @param op1 3324 * the first operand 3325 * @param op2 3326 * the second operand 3327 * @return the new {@code BooleanBinding} 3328 * @throws NullPointerException 3329 * if one of the operands is {@code null} 3330 */ 3331 public static BooleanBinding greaterThan(final ObservableNumberValue op1, final ObservableNumberValue op2) { 3332 return Bindings.greaterThan(op1, op2, op1, op2); 3333 } 3334 3335 /** 3336 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3337 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 3338 * greater than a constant value. 3339 * 3340 * @param op1 3341 * the {@code ObservableNumberValue} 3342 * @param op2 3343 * the constant value 3344 * @return the new {@code BooleanBinding} 3345 * @throws NullPointerException 3346 * if the {@code ObservableNumberValue} is {@code null} 3347 */ 3348 public static BooleanBinding greaterThan(final ObservableNumberValue op1, final double op2) { 3349 return greaterThan(op1, DoubleConstant.valueOf(op2), op1); 3350 } 3351 3352 /** 3353 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3354 * if a constant value is greater than the value of a 3355 * {@link javafx.beans.value.ObservableNumberValue}. 3356 * 3357 * @param op1 3358 * the constant value 3359 * @param op2 3360 * the {@code ObservableNumberValue} 3361 * @return the new {@code BooleanBinding} 3362 * @throws NullPointerException 3363 * if the {@code ObservableNumberValue} is {@code null} 3364 */ 3365 public static BooleanBinding greaterThan(final double op1, final ObservableNumberValue op2) { 3366 return greaterThan(DoubleConstant.valueOf(op1), op2, op2); 3367 } 3368 3369 /** 3370 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3371 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 3372 * greater than a constant value. 3373 * 3374 * @param op1 3375 * the {@code ObservableNumberValue} 3376 * @param op2 3377 * the constant value 3378 * @return the new {@code BooleanBinding} 3379 * @throws NullPointerException 3380 * if the {@code ObservableNumberValue} is {@code null} 3381 */ 3382 public static BooleanBinding greaterThan(final ObservableNumberValue op1, final float op2) { 3383 return greaterThan(op1, FloatConstant.valueOf(op2), op1); 3384 } 3385 3386 /** 3387 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3388 * if a constant value is greater than the value of a 3389 * {@link javafx.beans.value.ObservableNumberValue}. 3390 * 3391 * @param op1 3392 * the constant value 3393 * @param op2 3394 * the {@code ObservableNumberValue} 3395 * @return the new {@code BooleanBinding} 3396 * @throws NullPointerException 3397 * if the {@code ObservableNumberValue} is {@code null} 3398 */ 3399 public static BooleanBinding greaterThan(final float op1, final ObservableNumberValue op2) { 3400 return greaterThan(FloatConstant.valueOf(op1), op2, op2); 3401 } 3402 3403 /** 3404 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3405 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 3406 * greater than a constant value. 3407 * 3408 * @param op1 3409 * the {@code ObservableNumberValue} 3410 * @param op2 3411 * the constant value 3412 * @return the new {@code BooleanBinding} 3413 * @throws NullPointerException 3414 * if the {@code ObservableNumberValue} is {@code null} 3415 */ 3416 public static BooleanBinding greaterThan(final ObservableNumberValue op1, final long op2) { 3417 return greaterThan(op1, LongConstant.valueOf(op2), op1); 3418 } 3419 3420 /** 3421 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3422 * if a constant value is greater than the value of a 3423 * {@link javafx.beans.value.ObservableNumberValue}. 3424 * 3425 * @param op1 3426 * the constant value 3427 * @param op2 3428 * the {@code ObservableNumberValue} 3429 * @return the new {@code BooleanBinding} 3430 * @throws NullPointerException 3431 * if the {@code ObservableNumberValue} is {@code null} 3432 */ 3433 public static BooleanBinding greaterThan(final long op1, final ObservableNumberValue op2) { 3434 return greaterThan(LongConstant.valueOf(op1), op2, op2); 3435 } 3436 3437 /** 3438 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3439 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 3440 * greater than a constant value. 3441 * 3442 * @param op1 3443 * the {@code ObservableNumberValue} 3444 * @param op2 3445 * the constant value 3446 * @return the new {@code BooleanBinding} 3447 * @throws NullPointerException 3448 * if the {@code ObservableNumberValue} is {@code null} 3449 */ 3450 public static BooleanBinding greaterThan(final ObservableNumberValue op1, final int op2) { 3451 return greaterThan(op1, IntegerConstant.valueOf(op2), op1); 3452 } 3453 3454 /** 3455 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3456 * if a constant value is greater than the value of a 3457 * {@link javafx.beans.value.ObservableNumberValue}. 3458 * 3459 * @param op1 3460 * the constant value 3461 * @param op2 3462 * the {@code ObservableNumberValue} 3463 * @return the new {@code BooleanBinding} 3464 * @throws NullPointerException 3465 * if the {@code ObservableNumberValue} is {@code null} 3466 */ 3467 public static BooleanBinding greaterThan(final int op1, final ObservableNumberValue op2) { 3468 return greaterThan(IntegerConstant.valueOf(op1), op2, op2); 3469 } 3470 3471 // ================================================================================================================= 3472 // Less Than 3473 3474 private static BooleanBinding lessThan(final ObservableNumberValue op1, final ObservableNumberValue op2, final Observable... dependencies) { 3475 return greaterThan(op2, op1, dependencies); 3476 } 3477 3478 /** 3479 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3480 * if the value of the first 3481 * {@link javafx.beans.value.ObservableNumberValue} is less than the value 3482 * of the second. 3483 * 3484 * @param op1 3485 * the first operand 3486 * @param op2 3487 * the second operand 3488 * @return the new {@code BooleanBinding} 3489 * @throws NullPointerException 3490 * if one of the operands is {@code null} 3491 */ 3492 public static BooleanBinding lessThan(final ObservableNumberValue op1, final ObservableNumberValue op2) { 3493 return lessThan(op1, op2, op1, op2); 3494 } 3495 3496 /** 3497 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3498 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 3499 * less than a constant value. 3500 * 3501 * @param op1 3502 * the {@code ObservableNumberValue} 3503 * @param op2 3504 * the constant value 3505 * @return the new {@code BooleanBinding} 3506 * @throws NullPointerException 3507 * if the {@code ObservableNumberValue} is {@code null} 3508 */ 3509 public static BooleanBinding lessThan(final ObservableNumberValue op1, final double op2) { 3510 return lessThan(op1, DoubleConstant.valueOf(op2), op1); 3511 } 3512 3513 /** 3514 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3515 * if a constant value is less than the value of a 3516 * {@link javafx.beans.value.ObservableNumberValue}. 3517 * 3518 * @param op1 3519 * the constant value 3520 * @param op2 3521 * the {@code ObservableNumberValue} 3522 * @return the new {@code BooleanBinding} 3523 * @throws NullPointerException 3524 * if the {@code ObservableNumberValue} is {@code null} 3525 */ 3526 public static BooleanBinding lessThan(final double op1, final ObservableNumberValue op2) { 3527 return lessThan(DoubleConstant.valueOf(op1), op2, op2); 3528 } 3529 3530 /** 3531 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3532 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 3533 * less than a constant value. 3534 * 3535 * @param op1 3536 * the {@code ObservableNumberValue} 3537 * @param op2 3538 * the constant value 3539 * @return the new {@code BooleanBinding} 3540 * @throws NullPointerException 3541 * if the {@code ObservableNumberValue} is {@code null} 3542 */ 3543 public static BooleanBinding lessThan(final ObservableNumberValue op1, final float op2) { 3544 return lessThan(op1, FloatConstant.valueOf(op2), op1); 3545 } 3546 3547 /** 3548 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3549 * if a constant value is less than the value of a 3550 * {@link javafx.beans.value.ObservableNumberValue}. 3551 * 3552 * @param op1 3553 * the constant value 3554 * @param op2 3555 * the {@code ObservableNumberValue} 3556 * @return the new {@code BooleanBinding} 3557 * @throws NullPointerException 3558 * if the {@code ObservableNumberValue} is {@code null} 3559 */ 3560 public static BooleanBinding lessThan(final float op1, final ObservableNumberValue op2) { 3561 return lessThan(FloatConstant.valueOf(op1), op2, op2); 3562 } 3563 3564 /** 3565 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3566 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 3567 * less than a constant value. 3568 * 3569 * @param op1 3570 * the {@code ObservableNumberValue} 3571 * @param op2 3572 * the constant value 3573 * @return the new {@code BooleanBinding} 3574 * @throws NullPointerException 3575 * if the {@code ObservableNumberValue} is {@code null} 3576 */ 3577 public static BooleanBinding lessThan(final ObservableNumberValue op1, final long op2) { 3578 return lessThan(op1, LongConstant.valueOf(op2), op1); 3579 } 3580 3581 /** 3582 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3583 * if a constant value is less than the value of a 3584 * {@link javafx.beans.value.ObservableNumberValue}. 3585 * 3586 * @param op1 3587 * the constant value 3588 * @param op2 3589 * the {@code ObservableNumberValue} 3590 * @return the new {@code BooleanBinding} 3591 * @throws NullPointerException 3592 * if the {@code ObservableNumberValue} is {@code null} 3593 */ 3594 public static BooleanBinding lessThan(final long op1, final ObservableNumberValue op2) { 3595 return lessThan(LongConstant.valueOf(op1), op2, op2); 3596 } 3597 3598 /** 3599 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3600 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 3601 * less than a constant value. 3602 * 3603 * @param op1 3604 * the {@code ObservableNumberValue} 3605 * @param op2 3606 * the constant value 3607 * @return the new {@code BooleanBinding} 3608 * @throws NullPointerException 3609 * if the {@code ObservableNumberValue} is {@code null} 3610 */ 3611 public static BooleanBinding lessThan(final ObservableNumberValue op1, final int op2) { 3612 return lessThan(op1, IntegerConstant.valueOf(op2), op1); 3613 } 3614 3615 /** 3616 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3617 * if a constant value is less than the value of a 3618 * {@link javafx.beans.value.ObservableNumberValue}. 3619 * 3620 * @param op1 3621 * the constant value 3622 * @param op2 3623 * the {@code ObservableNumberValue} 3624 * @return the new {@code BooleanBinding} 3625 * @throws NullPointerException 3626 * if the {@code ObservableNumberValue} is {@code null} 3627 */ 3628 public static BooleanBinding lessThan(final int op1, final ObservableNumberValue op2) { 3629 return lessThan(IntegerConstant.valueOf(op1), op2, op2); 3630 } 3631 3632 // ================================================================================================================= 3633 // Greater Than or Equal 3634 3635 private static BooleanBinding greaterThanOrEqual(final ObservableNumberValue op1, final ObservableNumberValue op2, final Observable... dependencies) { 3636 if ((op1 == null) || (op2 == null)) { 3637 throw new NullPointerException("Operands cannot be null."); 3638 } 3639 assert (dependencies != null) && (dependencies.length > 0); 3640 3641 if ((op1 instanceof ObservableDoubleValue) || (op2 instanceof ObservableDoubleValue)) { 3642 return new BooleanBinding() { 3643 { 3644 super.bind(dependencies); 3645 } 3646 3647 @Override 3648 public void dispose() { 3649 super.unbind(dependencies); 3650 } 3651 3652 @Override 3653 protected boolean computeValue() { 3654 return op1.doubleValue() >= op2.doubleValue(); 3655 } 3656 3657 @Override 3658 public ObservableList<?> getDependencies() { 3659 return (dependencies.length == 1)? 3660 FXCollections.singletonObservableList(dependencies[0]) 3661 : new ImmutableObservableList<Observable>(dependencies); 3662 } 3663 }; 3664 } else if ((op1 instanceof ObservableFloatValue) || (op2 instanceof ObservableFloatValue)) { 3665 return new BooleanBinding() { 3666 { 3667 super.bind(dependencies); 3668 } 3669 3670 @Override 3671 public void dispose() { 3672 super.unbind(dependencies); 3673 } 3674 3675 @Override 3676 protected boolean computeValue() { 3677 return op1.floatValue() >= op2.floatValue(); 3678 } 3679 3680 @Override 3681 public ObservableList<?> getDependencies() { 3682 return (dependencies.length == 1)? 3683 FXCollections.singletonObservableList(dependencies[0]) 3684 : new ImmutableObservableList<Observable>(dependencies); 3685 } 3686 }; 3687 } else if ((op1 instanceof ObservableLongValue) || (op2 instanceof ObservableLongValue)) { 3688 return new BooleanBinding() { 3689 { 3690 super.bind(dependencies); 3691 } 3692 3693 @Override 3694 public void dispose() { 3695 super.unbind(dependencies); 3696 } 3697 3698 @Override 3699 protected boolean computeValue() { 3700 return op1.longValue() >= op2.longValue(); 3701 } 3702 3703 @Override 3704 public ObservableList<?> getDependencies() { 3705 return (dependencies.length == 1)? 3706 FXCollections.singletonObservableList(dependencies[0]) 3707 : new ImmutableObservableList<Observable>(dependencies); 3708 } 3709 }; 3710 } else { 3711 return new BooleanBinding() { 3712 { 3713 super.bind(dependencies); 3714 } 3715 3716 @Override 3717 public void dispose() { 3718 super.unbind(dependencies); 3719 } 3720 3721 @Override 3722 protected boolean computeValue() { 3723 return op1.intValue() >= op2.intValue(); 3724 } 3725 3726 @Override 3727 public ObservableList<?> getDependencies() { 3728 return (dependencies.length == 1)? 3729 FXCollections.singletonObservableList(dependencies[0]) 3730 : new ImmutableObservableList<Observable>(dependencies); 3731 } 3732 }; 3733 } 3734 } 3735 3736 /** 3737 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3738 * if the value of the first 3739 * {@link javafx.beans.value.ObservableNumberValue} is greater than or equal 3740 * to the value of the second. 3741 * 3742 * @param op1 3743 * the first operand 3744 * @param op2 3745 * the second operand 3746 * @return the new {@code BooleanBinding} 3747 * @throws NullPointerException 3748 * if one of the operands is {@code null} 3749 */ 3750 public static BooleanBinding greaterThanOrEqual(final ObservableNumberValue op1, final ObservableNumberValue op2) { 3751 return greaterThanOrEqual(op1, op2, op1, op2); 3752 } 3753 3754 /** 3755 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3756 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 3757 * greater than or equal to a constant value. 3758 * 3759 * @param op1 3760 * the {@code ObservableNumberValue} 3761 * @param op2 3762 * the constant value 3763 * @return the new {@code BooleanBinding} 3764 * @throws NullPointerException 3765 * if the {@code ObservableNumberValue} is {@code null} 3766 */ 3767 public static BooleanBinding greaterThanOrEqual(final ObservableNumberValue op1, final double op2) { 3768 return greaterThanOrEqual(op1, DoubleConstant.valueOf(op2), op1); 3769 } 3770 3771 /** 3772 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3773 * if a constant value is greater than or equal to the value of a 3774 * {@link javafx.beans.value.ObservableNumberValue}. 3775 * 3776 * @param op1 3777 * the constant value 3778 * @param op2 3779 * the {@code ObservableNumberValue} 3780 * @return the new {@code BooleanBinding} 3781 * @throws NullPointerException 3782 * if the {@code ObservableNumberValue} is {@code null} 3783 */ 3784 public static BooleanBinding greaterThanOrEqual(final double op1, final ObservableNumberValue op2) { 3785 return greaterThanOrEqual(DoubleConstant.valueOf(op1), op2, op2); 3786 } 3787 3788 /** 3789 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3790 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 3791 * greater than or equal to a constant value. 3792 * 3793 * @param op1 3794 * the {@code ObservableNumberValue} 3795 * @param op2 3796 * the constant value 3797 * @return the new {@code BooleanBinding} 3798 * @throws NullPointerException 3799 * if the {@code ObservableNumberValue} is {@code null} 3800 */ 3801 public static BooleanBinding greaterThanOrEqual(final ObservableNumberValue op1, final float op2) { 3802 return greaterThanOrEqual(op1, FloatConstant.valueOf(op2), op1); 3803 } 3804 3805 /** 3806 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3807 * if a constant value is greater than or equal to the value of a 3808 * {@link javafx.beans.value.ObservableNumberValue}. 3809 * 3810 * @param op1 3811 * the constant value 3812 * @param op2 3813 * the {@code ObservableNumberValue} 3814 * @return the new {@code BooleanBinding} 3815 * @throws NullPointerException 3816 * if the {@code ObservableNumberValue} is {@code null} 3817 */ 3818 public static BooleanBinding greaterThanOrEqual(final float op1, final ObservableNumberValue op2) { 3819 return greaterThanOrEqual(FloatConstant.valueOf(op1), op2, op2); 3820 } 3821 3822 /** 3823 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3824 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 3825 * greater than or equal to a constant value. 3826 * 3827 * @param op1 3828 * the {@code ObservableNumberValue} 3829 * @param op2 3830 * the constant value 3831 * @return the new {@code BooleanBinding} 3832 * @throws NullPointerException 3833 * if the {@code ObservableNumberValue} is {@code null} 3834 */ 3835 public static BooleanBinding greaterThanOrEqual(final ObservableNumberValue op1, final long op2) { 3836 return greaterThanOrEqual(op1, LongConstant.valueOf(op2), op1); 3837 } 3838 3839 /** 3840 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3841 * if a constant value is greater than or equal to the value of a 3842 * {@link javafx.beans.value.ObservableNumberValue}. 3843 * 3844 * @param op1 3845 * the constant value 3846 * @param op2 3847 * the {@code ObservableNumberValue} 3848 * @return the new {@code BooleanBinding} 3849 * @throws NullPointerException 3850 * if the {@code ObservableNumberValue} is {@code null} 3851 */ 3852 public static BooleanBinding greaterThanOrEqual(final long op1, final ObservableNumberValue op2) { 3853 return greaterThanOrEqual(LongConstant.valueOf(op1), op2, op2); 3854 } 3855 3856 /** 3857 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3858 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 3859 * greater than or equal to a constant value. 3860 * 3861 * @param op1 3862 * the {@code ObservableNumberValue} 3863 * @param op2 3864 * the constant value 3865 * @return the new {@code BooleanBinding} 3866 * @throws NullPointerException 3867 * if the {@code ObservableNumberValue} is {@code null} 3868 */ 3869 public static BooleanBinding greaterThanOrEqual(final ObservableNumberValue op1, final int op2) { 3870 return greaterThanOrEqual(op1, IntegerConstant.valueOf(op2), op1); 3871 } 3872 3873 /** 3874 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3875 * if a constant value is greater than or equal to the value of a 3876 * {@link javafx.beans.value.ObservableNumberValue}. 3877 * 3878 * @param op1 3879 * the constant value 3880 * @param op2 3881 * the {@code ObservableNumberValue} 3882 * @return the new {@code BooleanBinding} 3883 * @throws NullPointerException 3884 * if the {@code ObservableNumberValue} is {@code null} 3885 */ 3886 public static BooleanBinding greaterThanOrEqual(final int op1, final ObservableNumberValue op2) { 3887 return greaterThanOrEqual(IntegerConstant.valueOf(op1), op2, op2); 3888 } 3889 3890 // ================================================================================================================= 3891 // Less Than or Equal 3892 3893 private static BooleanBinding lessThanOrEqual(final ObservableNumberValue op1, final ObservableNumberValue op2, Observable... dependencies) { 3894 return greaterThanOrEqual(op2, op1, dependencies); 3895 } 3896 3897 3898 /** 3899 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3900 * if the value of the first 3901 * {@link javafx.beans.value.ObservableNumberValue} is less than or equal to 3902 * the value of the second. 3903 * 3904 * @param op1 3905 * the first operand 3906 * @param op2 3907 * the second operand 3908 * @return the new {@code BooleanBinding} 3909 * @throws NullPointerException 3910 * if one of the operands is {@code null} 3911 */ 3912 public static BooleanBinding lessThanOrEqual(final ObservableNumberValue op1, final ObservableNumberValue op2) { 3913 return lessThanOrEqual(op1, op2, op1, op2); 3914 } 3915 3916 /** 3917 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3918 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 3919 * less than or equal to a constant value. 3920 * 3921 * @param op1 3922 * the {@code ObservableNumberValue} 3923 * @param op2 3924 * the constant value 3925 * @return the new {@code BooleanBinding} 3926 * @throws NullPointerException 3927 * if the {@code ObservableNumberValue} is {@code null} 3928 */ 3929 public static BooleanBinding lessThanOrEqual(final ObservableNumberValue op1, final double op2) { 3930 return lessThanOrEqual(op1, DoubleConstant.valueOf(op2), op1); 3931 } 3932 3933 /** 3934 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3935 * if a constant value is less than or equal to the value of a 3936 * {@link javafx.beans.value.ObservableNumberValue}. 3937 * 3938 * @param op1 3939 * the constant value 3940 * @param op2 3941 * the {@code ObservableNumberValue} 3942 * @return the new {@code BooleanBinding} 3943 * @throws NullPointerException 3944 * if the {@code ObservableNumberValue} is {@code null} 3945 */ 3946 public static BooleanBinding lessThanOrEqual(final double op1, final ObservableNumberValue op2) { 3947 return lessThanOrEqual(DoubleConstant.valueOf(op1), op2, op2); 3948 } 3949 3950 /** 3951 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3952 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 3953 * less than or equal to a constant value. 3954 * 3955 * @param op1 3956 * the {@code ObservableNumberValue} 3957 * @param op2 3958 * the constant value 3959 * @return the new {@code BooleanBinding} 3960 * @throws NullPointerException 3961 * if the {@code ObservableNumberValue} is {@code null} 3962 */ 3963 public static BooleanBinding lessThanOrEqual(final ObservableNumberValue op1, final float op2) { 3964 return lessThanOrEqual(op1, FloatConstant.valueOf(op2), op1); 3965 } 3966 3967 /** 3968 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3969 * if a constant value is less than or equal to the value of a 3970 * {@link javafx.beans.value.ObservableNumberValue}. 3971 * 3972 * @param op1 3973 * the constant value 3974 * @param op2 3975 * the {@code ObservableNumberValue} 3976 * @return the new {@code BooleanBinding} 3977 * @throws NullPointerException 3978 * if the {@code ObservableNumberValue} is {@code null} 3979 */ 3980 public static BooleanBinding lessThanOrEqual(final float op1, final ObservableNumberValue op2) { 3981 return lessThanOrEqual(FloatConstant.valueOf(op1), op2, op2); 3982 } 3983 3984 /** 3985 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 3986 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 3987 * less than or equal to a constant value. 3988 * 3989 * @param op1 3990 * the {@code ObservableNumberValue} 3991 * @param op2 3992 * the constant value 3993 * @return the new {@code BooleanBinding} 3994 * @throws NullPointerException 3995 * if the {@code ObservableNumberValue} is {@code null} 3996 */ 3997 public static BooleanBinding lessThanOrEqual(final ObservableNumberValue op1, final long op2) { 3998 return lessThanOrEqual(op1, LongConstant.valueOf(op2), op1); 3999 } 4000 4001 /** 4002 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 4003 * if a constant value is less than or equal to the value of a 4004 * {@link javafx.beans.value.ObservableNumberValue}. 4005 * 4006 * @param op1 4007 * the constant value 4008 * @param op2 4009 * the {@code ObservableNumberValue} 4010 * @return the new {@code BooleanBinding} 4011 * @throws NullPointerException 4012 * if the {@code ObservableNumberValue} is {@code null} 4013 */ 4014 public static BooleanBinding lessThanOrEqual(final long op1, final ObservableNumberValue op2) { 4015 return lessThanOrEqual(LongConstant.valueOf(op1), op2, op2); 4016 } 4017 4018 /** 4019 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 4020 * if the value of a {@link javafx.beans.value.ObservableNumberValue} is 4021 * less than or equal to a constant value. 4022 * 4023 * @param op1 4024 * the {@code ObservableNumberValue} 4025 * @param op2 4026 * the constant value 4027 * @return the new {@code BooleanBinding} 4028 * @throws NullPointerException 4029 * if the {@code ObservableNumberValue} is {@code null} 4030 */ 4031 public static BooleanBinding lessThanOrEqual(final ObservableNumberValue op1, final int op2) { 4032 return lessThanOrEqual(op1, IntegerConstant.valueOf(op2), op1); 4033 } 4034 4035 /** 4036 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 4037 * if a constant value is less than or equal to the value of a 4038 * {@link javafx.beans.value.ObservableNumberValue}. 4039 * 4040 * @param op1 4041 * the constant value 4042 * @param op2 4043 * the {@code ObservableNumberValue} 4044 * @return the new {@code BooleanBinding} 4045 * @throws NullPointerException 4046 * if the {@code ObservableNumberValue} is {@code null} 4047 */ 4048 public static BooleanBinding lessThanOrEqual(final int op1, final ObservableNumberValue op2) { 4049 return lessThanOrEqual(IntegerConstant.valueOf(op1), op2, op2); 4050 } 4051 4052 // ================================================================================================================= 4053 // Minimum 4054 4055 private static NumberBinding min(final ObservableNumberValue op1, final ObservableNumberValue op2, final Observable... dependencies) { 4056 if ((op1 == null) || (op2 == null)) { 4057 throw new NullPointerException("Operands cannot be null."); 4058 } 4059 assert (dependencies != null) && (dependencies.length > 0); 4060 4061 if ((op1 instanceof ObservableDoubleValue) || (op2 instanceof ObservableDoubleValue)) { 4062 return new DoubleBinding() { 4063 { 4064 super.bind(dependencies); 4065 } 4066 4067 @Override 4068 public void dispose() { 4069 super.unbind(dependencies); 4070 } 4071 4072 @Override 4073 protected double computeValue() { 4074 return Math.min(op1.doubleValue(), op2.doubleValue()); 4075 } 4076 4077 @Override 4078 public ObservableList<?> getDependencies() { 4079 return (dependencies.length == 1)? 4080 FXCollections.singletonObservableList(dependencies[0]) 4081 : new ImmutableObservableList<Observable>(dependencies); 4082 } 4083 }; 4084 } else if ((op1 instanceof ObservableFloatValue) || (op2 instanceof ObservableFloatValue)) { 4085 return new FloatBinding() { 4086 { 4087 super.bind(dependencies); 4088 } 4089 4090 @Override 4091 public void dispose() { 4092 super.unbind(dependencies); 4093 } 4094 4095 @Override 4096 protected float computeValue() { 4097 return Math.min(op1.floatValue(), op2.floatValue()); 4098 } 4099 4100 @Override 4101 public ObservableList<?> getDependencies() { 4102 return (dependencies.length == 1)? 4103 FXCollections.singletonObservableList(dependencies[0]) 4104 : new ImmutableObservableList<Observable>(dependencies); 4105 } 4106 }; 4107 } else if ((op1 instanceof ObservableLongValue) || (op2 instanceof ObservableLongValue)) { 4108 return new LongBinding() { 4109 { 4110 super.bind(dependencies); 4111 } 4112 4113 @Override 4114 public void dispose() { 4115 super.unbind(dependencies); 4116 } 4117 4118 @Override 4119 protected long computeValue() { 4120 return Math.min(op1.longValue(), op2.longValue()); 4121 } 4122 4123 @Override 4124 public ObservableList<?> getDependencies() { 4125 return (dependencies.length == 1)? 4126 FXCollections.singletonObservableList(dependencies[0]) 4127 : new ImmutableObservableList<Observable>(dependencies); 4128 } 4129 }; 4130 } else { 4131 return new IntegerBinding() { 4132 { 4133 super.bind(dependencies); 4134 } 4135 4136 @Override 4137 public void dispose() { 4138 super.unbind(dependencies); 4139 } 4140 4141 @Override 4142 protected int computeValue() { 4143 return Math.min(op1.intValue(), op2.intValue()); 4144 } 4145 4146 @Override 4147 public ObservableList<?> getDependencies() { 4148 return (dependencies.length == 1)? 4149 FXCollections.singletonObservableList(dependencies[0]) 4150 : new ImmutableObservableList<Observable>(dependencies); 4151 } 4152 }; 4153 } 4154 } 4155 4156 /** 4157 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 4158 * the minimum of the values of two instances of 4159 * {@link javafx.beans.value.ObservableNumberValue}. 4160 * 4161 * @param op1 4162 * the first operand 4163 * @param op2 4164 * the second operand 4165 * @return the new {@code NumberBinding} 4166 * @throws NullPointerException 4167 * if one of the operands is {@code null} 4168 */ 4169 public static NumberBinding min(final ObservableNumberValue op1, final ObservableNumberValue op2) { 4170 return min(op1, op2, op1, op2); 4171 } 4172 4173 /** 4174 * Creates a new {@link javafx.beans.binding.DoubleBinding} that calculates 4175 * the minimum of the value of a 4176 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 4177 * 4178 * @param op1 4179 * the {@code ObservableNumberValue} 4180 * @param op2 4181 * the constant value 4182 * @return the new {@code DoubleBinding} 4183 * @throws NullPointerException 4184 * if the {@code ObservableNumberValue} is {@code null} 4185 */ 4186 public static DoubleBinding min(final ObservableNumberValue op1, final double op2) { 4187 return (DoubleBinding) min(op1, DoubleConstant.valueOf(op2), op1); 4188 } 4189 4190 /** 4191 * Creates a new {@link javafx.beans.binding.DoubleBinding} that calculates 4192 * the minimum of the value of a 4193 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 4194 * 4195 * @param op1 4196 * the constant value 4197 * @param op2 4198 * the {@code ObservableNumberValue} 4199 * @return the new {@code DoubleBinding} 4200 * @throws NullPointerException 4201 * if the {@code ObservableNumberValue} is {@code null} 4202 */ 4203 public static DoubleBinding min(final double op1, final ObservableNumberValue op2) { 4204 return (DoubleBinding) min(DoubleConstant.valueOf(op1), op2, op2); 4205 } 4206 4207 /** 4208 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 4209 * the minimum of the value of a 4210 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 4211 * 4212 * @param op1 4213 * the {@code ObservableNumberValue} 4214 * @param op2 4215 * the constant value 4216 * @return the new {@code NumberBinding} 4217 * @throws NullPointerException 4218 * if the {@code ObservableNumberValue} is {@code null} 4219 */ 4220 public static NumberBinding min(final ObservableNumberValue op1, final float op2) { 4221 return min(op1, FloatConstant.valueOf(op2), op1); 4222 } 4223 4224 /** 4225 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 4226 * the minimum of the value of a 4227 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 4228 * 4229 * @param op1 4230 * the constant value 4231 * @param op2 4232 * the {@code ObservableNumberValue} 4233 * @return the new {@code NumberBinding} 4234 * @throws NullPointerException 4235 * if the {@code ObservableNumberValue} is {@code null} 4236 */ 4237 public static NumberBinding min(final float op1, final ObservableNumberValue op2) { 4238 return min(FloatConstant.valueOf(op1), op2, op2); 4239 } 4240 4241 /** 4242 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 4243 * the minimum of the value of a 4244 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 4245 * 4246 * @param op1 4247 * the {@code ObservableNumberValue} 4248 * @param op2 4249 * the constant value 4250 * @return the new {@code NumberBinding} 4251 * @throws NullPointerException 4252 * if the {@code ObservableNumberValue} is {@code null} 4253 */ 4254 public static NumberBinding min(final ObservableNumberValue op1, final long op2) { 4255 return min(op1, LongConstant.valueOf(op2), op1); 4256 } 4257 4258 /** 4259 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 4260 * the minimum of the value of a 4261 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 4262 * 4263 * @param op1 4264 * the constant value 4265 * @param op2 4266 * the {@code ObservableNumberValue} 4267 * @return the new {@code NumberBinding} 4268 * @throws NullPointerException 4269 * if the {@code ObservableNumberValue} is {@code null} 4270 */ 4271 public static NumberBinding min(final long op1, final ObservableNumberValue op2) { 4272 return min(LongConstant.valueOf(op1), op2, op2); 4273 } 4274 4275 /** 4276 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 4277 * the minimum of the value of a 4278 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 4279 * 4280 * @param op1 4281 * the {@code ObservableNumberValue} 4282 * @param op2 4283 * the constant value 4284 * @return the new {@code NumberBinding} 4285 * @throws NullPointerException 4286 * if the {@code ObservableNumberValue} is {@code null} 4287 */ 4288 public static NumberBinding min(final ObservableNumberValue op1, final int op2) { 4289 return min(op1, IntegerConstant.valueOf(op2), op1); 4290 } 4291 4292 /** 4293 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 4294 * the minimum of the value of a 4295 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 4296 * 4297 * @param op1 4298 * the constant value 4299 * @param op2 4300 * the {@code ObservableNumberValue} 4301 * @return the new {@code NumberBinding} 4302 * @throws NullPointerException 4303 * if the {@code ObservableNumberValue} is {@code null} 4304 */ 4305 public static NumberBinding min(final int op1, final ObservableNumberValue op2) { 4306 return min(IntegerConstant.valueOf(op1), op2, op2); 4307 } 4308 4309 // ================================================================================================================= 4310 // Maximum 4311 4312 private static NumberBinding max(final ObservableNumberValue op1, final ObservableNumberValue op2, final Observable... dependencies) { 4313 if ((op1 == null) || (op2 == null)) { 4314 throw new NullPointerException("Operands cannot be null."); 4315 } 4316 assert (dependencies != null) && (dependencies.length > 0); 4317 4318 if ((op1 instanceof ObservableDoubleValue) || (op2 instanceof ObservableDoubleValue)) { 4319 return new DoubleBinding() { 4320 { 4321 super.bind(dependencies); 4322 } 4323 4324 @Override 4325 public void dispose() { 4326 super.unbind(dependencies); 4327 } 4328 4329 @Override 4330 protected double computeValue() { 4331 return Math.max(op1.doubleValue(), op2.doubleValue()); 4332 } 4333 4334 @Override 4335 public ObservableList<?> getDependencies() { 4336 return (dependencies.length == 1)? 4337 FXCollections.singletonObservableList(dependencies[0]) 4338 : new ImmutableObservableList<Observable>(dependencies); 4339 } 4340 }; 4341 } else if ((op1 instanceof ObservableFloatValue) || (op2 instanceof ObservableFloatValue)) { 4342 return new FloatBinding() { 4343 { 4344 super.bind(dependencies); 4345 } 4346 4347 @Override 4348 public void dispose() { 4349 super.unbind(dependencies); 4350 } 4351 4352 @Override 4353 protected float computeValue() { 4354 return Math.max(op1.floatValue(), op2.floatValue()); 4355 } 4356 4357 @Override 4358 public ObservableList<?> getDependencies() { 4359 return (dependencies.length == 1)? 4360 FXCollections.singletonObservableList(dependencies[0]) 4361 : new ImmutableObservableList<Observable>(dependencies); 4362 } 4363 }; 4364 } else if ((op1 instanceof ObservableLongValue) || (op2 instanceof ObservableLongValue)) { 4365 return new LongBinding() { 4366 { 4367 super.bind(dependencies); 4368 } 4369 4370 @Override 4371 public void dispose() { 4372 super.unbind(dependencies); 4373 } 4374 4375 @Override 4376 protected long computeValue() { 4377 return Math.max(op1.longValue(), op2.longValue()); 4378 } 4379 4380 @Override 4381 public ObservableList<?> getDependencies() { 4382 return (dependencies.length == 1)? 4383 FXCollections.singletonObservableList(dependencies[0]) 4384 : new ImmutableObservableList<Observable>(dependencies); 4385 } 4386 }; 4387 } else { 4388 return new IntegerBinding() { 4389 { 4390 super.bind(dependencies); 4391 } 4392 4393 @Override 4394 public void dispose() { 4395 super.unbind(dependencies); 4396 } 4397 4398 @Override 4399 protected int computeValue() { 4400 return Math.max(op1.intValue(), op2.intValue()); 4401 } 4402 4403 @Override 4404 public ObservableList<?> getDependencies() { 4405 return (dependencies.length == 1)? 4406 FXCollections.singletonObservableList(dependencies[0]) 4407 : new ImmutableObservableList<Observable>(dependencies); 4408 } 4409 }; 4410 } 4411 } 4412 4413 /** 4414 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 4415 * the maximum of the values of two instances of 4416 * {@link javafx.beans.value.ObservableNumberValue}. 4417 * 4418 * @param op1 4419 * the first operand 4420 * @param op2 4421 * the second operand 4422 * @return the new {@code NumberBinding} 4423 * @throws NullPointerException 4424 * if one of the operands is {@code null} 4425 */ 4426 public static NumberBinding max(final ObservableNumberValue op1, final ObservableNumberValue op2) { 4427 return max(op1, op2, op1, op2); 4428 } 4429 4430 /** 4431 * Creates a new {@link javafx.beans.binding.DoubleBinding} that calculates 4432 * the maximum of the value of a 4433 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 4434 * 4435 * @param op1 4436 * the {@code ObservableNumberValue} 4437 * @param op2 4438 * the constant value 4439 * @return the new {@code DoubleBinding} 4440 * @throws NullPointerException 4441 * if the {@code ObservableNumberValue} is {@code null} 4442 */ 4443 public static DoubleBinding max(final ObservableNumberValue op1, final double op2) { 4444 return (DoubleBinding) max(op1, DoubleConstant.valueOf(op2), op1); 4445 } 4446 4447 /** 4448 * Creates a new {@link javafx.beans.binding.DoubleBinding} that calculates 4449 * the maximum of the value of a 4450 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 4451 * 4452 * @param op1 4453 * the constant value 4454 * @param op2 4455 * the {@code ObservableNumberValue} 4456 * @return the new {@code DoubleBinding} 4457 * @throws NullPointerException 4458 * if the {@code ObservableNumberValue} is {@code null} 4459 */ 4460 public static DoubleBinding max(final double op1, final ObservableNumberValue op2) { 4461 return (DoubleBinding) max(DoubleConstant.valueOf(op1), op2, op2); 4462 } 4463 4464 /** 4465 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 4466 * the maximum of the value of a 4467 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 4468 * 4469 * @param op1 4470 * the {@code ObservableNumberValue} 4471 * @param op2 4472 * the constant value 4473 * @return the new {@code NumberBinding} 4474 * @throws NullPointerException 4475 * if the {@code ObservableNumberValue} is {@code null} 4476 */ 4477 public static NumberBinding max(final ObservableNumberValue op1, final float op2) { 4478 return max(op1, FloatConstant.valueOf(op2), op1); 4479 } 4480 4481 /** 4482 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 4483 * the maximum of the value of a 4484 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 4485 * 4486 * @param op1 4487 * the constant value 4488 * @param op2 4489 * the {@code ObservableNumberValue} 4490 * @return the new {@code NumberBinding} 4491 * @throws NullPointerException 4492 * if the {@code ObservableNumberValue} is {@code null} 4493 */ 4494 public static NumberBinding max(final float op1, final ObservableNumberValue op2) { 4495 return max(FloatConstant.valueOf(op1), op2, op2); 4496 } 4497 4498 /** 4499 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 4500 * the maximum of the value of a 4501 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 4502 * 4503 * @param op1 4504 * the {@code ObservableNumberValue} 4505 * @param op2 4506 * the constant value 4507 * @return the new {@code NumberBinding} 4508 * @throws NullPointerException 4509 * if the {@code ObservableNumberValue} is {@code null} 4510 */ 4511 public static NumberBinding max(final ObservableNumberValue op1, final long op2) { 4512 return max(op1, LongConstant.valueOf(op2), op1); 4513 } 4514 4515 /** 4516 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 4517 * the maximum of the value of a 4518 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 4519 * 4520 * @param op1 4521 * the constant value 4522 * @param op2 4523 * the {@code ObservableNumberValue} 4524 * @return the new {@code NumberBinding} 4525 * @throws NullPointerException 4526 * if the {@code ObservableNumberValue} is {@code null} 4527 */ 4528 public static NumberBinding max(final long op1, final ObservableNumberValue op2) { 4529 return max(LongConstant.valueOf(op1), op2, op2); 4530 } 4531 4532 /** 4533 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 4534 * the maximum of the value of a 4535 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 4536 * 4537 * @param op1 4538 * the {@code ObservableNumberValue} 4539 * @param op2 4540 * the constant value 4541 * @return the new {@code NumberBinding} 4542 * @throws NullPointerException 4543 * if the {@code ObservableNumberValue} is {@code null} 4544 */ 4545 public static NumberBinding max(final ObservableNumberValue op1, final int op2) { 4546 return max(op1, IntegerConstant.valueOf(op2), op1); 4547 } 4548 4549 /** 4550 * Creates a new {@link javafx.beans.binding.NumberBinding} that calculates 4551 * the maximum of the value of a 4552 * {@link javafx.beans.value.ObservableNumberValue} and a constant value. 4553 * 4554 * @param op1 4555 * the constant value 4556 * @param op2 4557 * the {@code ObservableNumberValue} 4558 * @return the new {@code NumberBinding} 4559 * @throws NullPointerException 4560 * if the {@code ObservableNumberValue} is {@code null} 4561 */ 4562 public static NumberBinding max(final int op1, final ObservableNumberValue op2) { 4563 return max(IntegerConstant.valueOf(op1), op2, op2); 4564 } 4565 4566 // boolean 4567 // ================================================================================================================= 4568 4569 private static class BooleanAndBinding extends BooleanBinding { 4570 4571 private final ObservableBooleanValue op1; 4572 private final ObservableBooleanValue op2; 4573 private final InvalidationListener observer; 4574 4575 public BooleanAndBinding(ObservableBooleanValue op1, ObservableBooleanValue op2) { 4576 this.op1 = op1; 4577 this.op2 = op2; 4578 4579 observer = new ShortCircuitAndInvalidator(this); 4580 4581 op1.addListener(observer); 4582 op2.addListener(observer); 4583 } 4584 4585 4586 @Override 4587 public void dispose() { 4588 op1.removeListener(observer); 4589 op2.removeListener(observer); 4590 } 4591 4592 @Override 4593 protected boolean computeValue() { 4594 return op1.get() && op2.get(); 4595 } 4596 4597 @Override 4598 public ObservableList<?> getDependencies() { 4599 return new ImmutableObservableList<>(op1, op2); 4600 } 4601 } 4602 4603 private static class ShortCircuitAndInvalidator implements InvalidationListener { 4604 4605 private final WeakReference<BooleanAndBinding> ref; 4606 4607 private ShortCircuitAndInvalidator(BooleanAndBinding binding) { 4608 assert binding != null; 4609 ref = new WeakReference<>(binding); 4610 } 4611 4612 @Override 4613 public void invalidated(Observable observable) { 4614 final BooleanAndBinding binding = ref.get(); 4615 if (binding == null) { 4616 observable.removeListener(this); 4617 } else { 4618 // short-circuit invalidation. This BooleanBinding becomes 4619 // only invalid if the first operator changes or the 4620 // first parameter is true. 4621 if ((binding.op1.equals(observable) || (binding.isValid() && binding.op1.get()))) { 4622 binding.invalidate(); 4623 } 4624 } 4625 } 4626 4627 } 4628 4629 /** 4630 * Creates a {@link BooleanBinding} that calculates the conditional-AND 4631 * operation on the value of two instance of 4632 * {@link javafx.beans.value.ObservableBooleanValue}. 4633 * 4634 * @param op1 4635 * first {@code ObservableBooleanValue} 4636 * @param op2 4637 * second {@code ObservableBooleanValue} 4638 * @return the new {@code BooleanBinding} 4639 * @throws NullPointerException 4640 * if one of the operands is {@code null} 4641 */ 4642 public static BooleanBinding and(final ObservableBooleanValue op1, final ObservableBooleanValue op2) { 4643 if ((op1 == null) || (op2 == null)) { 4644 throw new NullPointerException("Operands cannot be null."); 4645 } 4646 4647 return new BooleanAndBinding(op1, op2); 4648 } 4649 4650 private static class BooleanOrBinding extends BooleanBinding { 4651 4652 private final ObservableBooleanValue op1; 4653 private final ObservableBooleanValue op2; 4654 private final InvalidationListener observer; 4655 4656 public BooleanOrBinding(ObservableBooleanValue op1, ObservableBooleanValue op2) { 4657 this.op1 = op1; 4658 this.op2 = op2; 4659 observer = new ShortCircuitOrInvalidator(this); 4660 op1.addListener(observer); 4661 op2.addListener(observer); 4662 } 4663 4664 4665 @Override 4666 public void dispose() { 4667 op1.removeListener(observer); 4668 op2.removeListener(observer); 4669 } 4670 4671 @Override 4672 protected boolean computeValue() { 4673 return op1.get() || op2.get(); 4674 } 4675 4676 @Override 4677 public ObservableList<?> getDependencies() { 4678 return new ImmutableObservableList<>(op1, op2); 4679 } 4680 } 4681 4682 4683 private static class ShortCircuitOrInvalidator implements InvalidationListener { 4684 4685 private final WeakReference<BooleanOrBinding> ref; 4686 4687 private ShortCircuitOrInvalidator(BooleanOrBinding binding) { 4688 assert binding != null; 4689 ref = new WeakReference<>(binding); 4690 } 4691 4692 @Override 4693 public void invalidated(Observable observable) { 4694 final BooleanOrBinding binding = ref.get(); 4695 if (binding == null) { 4696 observable.removeListener(this); 4697 } else { 4698 // short circuit invalidation. This BooleanBinding becomes 4699 // only invalid if the first operator changes or the 4700 // first parameter is false. 4701 if ((binding.op1.equals(observable) || (binding.isValid() && !binding.op1.get()))) { 4702 binding.invalidate(); 4703 } 4704 } 4705 } 4706 4707 } 4708 4709 /** 4710 * Creates a {@link BooleanBinding} that calculates the conditional-OR 4711 * operation on the value of two instance of 4712 * {@link javafx.beans.value.ObservableBooleanValue}. 4713 * 4714 * @param op1 4715 * first {@code ObservableBooleanValue} 4716 * @param op2 4717 * second {@code ObservableBooleanValue} 4718 * @return the new {@code BooleanBinding} 4719 * @throws NullPointerException 4720 * if one of the operands is {@code null} 4721 */ 4722 public static BooleanBinding or(final ObservableBooleanValue op1, final ObservableBooleanValue op2) { 4723 if ((op1 == null) || (op2 == null)) { 4724 throw new NullPointerException("Operands cannot be null."); 4725 } 4726 4727 return new BooleanOrBinding(op1, op2); 4728 } 4729 4730 /** 4731 * Creates a {@link BooleanBinding} that calculates the inverse of the value 4732 * of a {@link javafx.beans.value.ObservableBooleanValue}. 4733 * 4734 * @param op 4735 * the {@code ObservableBooleanValue} 4736 * @return the new {@code BooleanBinding} 4737 * @throws NullPointerException 4738 * if the operand is {@code null} 4739 */ 4740 public static BooleanBinding not(final ObservableBooleanValue op) { 4741 if (op == null) { 4742 throw new NullPointerException("Operand cannot be null."); 4743 } 4744 4745 return new BooleanBinding() { 4746 { 4747 super.bind(op); 4748 } 4749 4750 @Override 4751 public void dispose() { 4752 super.unbind(op); 4753 } 4754 4755 @Override 4756 protected boolean computeValue() { 4757 return !op.get(); 4758 } 4759 4760 @Override 4761 public ObservableList<?> getDependencies() { 4762 return FXCollections.singletonObservableList(op); 4763 } 4764 }; 4765 } 4766 4767 /** 4768 * Creates a new {@link BooleanBinding} that holds {@code true} if the values of two 4769 * instances of {@link javafx.beans.value.ObservableBooleanValue} are equal. 4770 * 4771 * @param op1 4772 * the first operand 4773 * @param op2 4774 * the second operand 4775 * @return the new {@code BooleanBinding} 4776 * @throws NullPointerException 4777 * if one of the operands is {@code null} 4778 */ 4779 public static BooleanBinding equal(final ObservableBooleanValue op1, final ObservableBooleanValue op2) { 4780 if ((op1 == null) || (op2 == null)) { 4781 throw new NullPointerException("Operands cannot be null."); 4782 } 4783 4784 return new BooleanBinding() { 4785 { 4786 super.bind(op1, op2); 4787 } 4788 4789 @Override 4790 public void dispose() { 4791 super.unbind(op1, op2); 4792 } 4793 4794 @Override 4795 protected boolean computeValue() { 4796 return op1.get() == op2.get(); 4797 } 4798 4799 @Override 4800 public ObservableList<?> getDependencies() { 4801 return new ImmutableObservableList<ObservableBooleanValue>(op1, op2); 4802 } 4803 }; 4804 } 4805 4806 /** 4807 * Creates a new {@link BooleanBinding} that holds {@code true} if the values of two 4808 * instances of {@link javafx.beans.value.ObservableBooleanValue} are not 4809 * equal. 4810 * 4811 * @param op1 4812 * the first operand 4813 * @param op2 4814 * the second operand 4815 * @return the new {@code BooleanBinding} 4816 * @throws NullPointerException 4817 * if one of the operands is {@code null} 4818 */ 4819 public static BooleanBinding notEqual(final ObservableBooleanValue op1, final ObservableBooleanValue op2) { 4820 if ((op1 == null) || (op2 == null)) { 4821 throw new NullPointerException("Operands cannot be null."); 4822 } 4823 4824 return new BooleanBinding() { 4825 { 4826 super.bind(op1, op2); 4827 } 4828 4829 @Override 4830 public void dispose() { 4831 super.unbind(op1, op2); 4832 } 4833 4834 @Override 4835 protected boolean computeValue() { 4836 return op1.get() != op2.get(); 4837 } 4838 4839 @Override 4840 public ObservableList<?> getDependencies() { 4841 return new ImmutableObservableList<ObservableBooleanValue>(op1, op2); 4842 } 4843 }; 4844 } 4845 4846 // String 4847 // ================================================================================================================= 4848 4849 /** 4850 * Returns a {@link javafx.beans.binding.StringExpression} that wraps a 4851 * {@link javafx.beans.value.ObservableValue}. If the 4852 * {@code ObservableValue} is already a {@code StringExpression}, it will be 4853 * returned. Otherwise a new {@link javafx.beans.binding.StringBinding} is 4854 * created that holds the value of the {@code ObservableValue} converted to 4855 * a {@code String}. 4856 * 4857 * @param observableValue 4858 * The source {@code ObservableValue} 4859 * @return A {@code StringExpression} that wraps the {@code ObservableValue} 4860 * if necessary 4861 * @throws NullPointerException 4862 * if {@code observableValue} is {@code null} 4863 */ 4864 public static StringExpression convert(ObservableValue<?> observableValue) { 4865 return StringFormatter.convert(observableValue); 4866 } 4867 4868 /** 4869 * Returns a {@link javafx.beans.binding.StringExpression} that holds the 4870 * value of the concatenation of multiple {@code Objects}. 4871 * <p> 4872 * If one of the arguments implements 4873 * {@link javafx.beans.value.ObservableValue} and the value of this 4874 * {@code ObservableValue} changes, the change is automatically reflected in 4875 * the {@code StringExpression}. 4876 * <p> 4877 * If {@code null} or an empty array is passed to this method, a 4878 * {@code StringExpression} that contains an empty {@code String} is 4879 * returned 4880 * 4881 * @param args 4882 * the {@code Objects} that should be concatenated 4883 * @return the new {@code StringExpression} 4884 */ 4885 public static StringExpression concat(Object... args) { 4886 return StringFormatter.concat(args); 4887 } 4888 4889 /** 4890 * Creates a {@link javafx.beans.binding.StringExpression} that holds the 4891 * value of multiple {@code Objects} formatted according to a format 4892 * {@code String}. 4893 * <p> 4894 * If one of the arguments implements 4895 * {@link javafx.beans.value.ObservableValue} and the value of this 4896 * {@code ObservableValue} changes, the change is automatically reflected in 4897 * the {@code StringExpression}. 4898 * <p> 4899 * See {@code java.util.Formatter} for formatting rules. 4900 * 4901 * @param format 4902 * the formatting {@code String} 4903 * @param args 4904 * the {@code Objects} that should be inserted in the formatting 4905 * {@code String} 4906 * @return the new {@code StringExpression} 4907 */ 4908 public static StringExpression format(String format, Object... args) { 4909 return StringFormatter.format(format, args); 4910 } 4911 4912 /** 4913 * Creates a {@link javafx.beans.binding.StringExpression} that holds the 4914 * value of multiple {@code Objects} formatted according to a format 4915 * {@code String} and a specified {@code Locale} 4916 * <p> 4917 * If one of the arguments implements 4918 * {@link javafx.beans.value.ObservableValue} and the value of this 4919 * {@code ObservableValue} changes, the change is automatically reflected in 4920 * the {@code StringExpression}. 4921 * <p> 4922 * See {@code java.util.Formatter} for formatting rules. See 4923 * {@code java.util.Locale} for details on {@code Locale}. 4924 * 4925 * @param locale 4926 * the {@code Locale} to use during formatting 4927 * @param format 4928 * the formatting {@code String} 4929 * @param args 4930 * the {@code Objects} that should be inserted in the formatting 4931 * {@code String} 4932 * @return the new {@code StringExpression} 4933 */ 4934 public static StringExpression format(Locale locale, String format, 4935 Object... args) { 4936 return StringFormatter.format(locale, format, args); 4937 } 4938 4939 private static String getStringSafe(String value) { 4940 return value == null ? "" : value; 4941 } 4942 4943 private static BooleanBinding equal(final ObservableStringValue op1, final ObservableStringValue op2, final Observable... dependencies) { 4944 if ((op1 == null) || (op2 == null)) { 4945 throw new NullPointerException("Operands cannot be null."); 4946 } 4947 assert (dependencies != null) && (dependencies.length > 0); 4948 4949 return new BooleanBinding() { 4950 { 4951 super.bind(dependencies); 4952 } 4953 4954 @Override 4955 public void dispose() { 4956 super.unbind(dependencies); 4957 } 4958 4959 @Override 4960 protected boolean computeValue() { 4961 final String s1 = getStringSafe(op1.get()); 4962 final String s2 = getStringSafe(op2.get()); 4963 return s1.equals(s2); 4964 } 4965 4966 @Override 4967 public ObservableList<?> getDependencies() { 4968 return (dependencies.length == 1)? 4969 FXCollections.singletonObservableList(dependencies[0]) 4970 : new ImmutableObservableList<Observable>(dependencies); 4971 } 4972 }; 4973 } 4974 4975 /** 4976 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 4977 * if the values of two instances of 4978 * {@link javafx.beans.value.ObservableStringValue} are equal. 4979 * <p> 4980 * Note: In this comparison a {@code String} that is {@code null} is 4981 * considered equal to an empty {@code String}. 4982 * 4983 * @param op1 4984 * the first operand 4985 * @param op2 4986 * the second operand 4987 * @return the new {@code BooleanBinding} 4988 * @throws NullPointerException 4989 * if one of the operands is {@code null} 4990 */ 4991 public static BooleanBinding equal(final ObservableStringValue op1, final ObservableStringValue op2) { 4992 return equal(op1, op2, op1, op2); 4993 } 4994 4995 /** 4996 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 4997 * if the value of a {@link javafx.beans.value.ObservableStringValue} is 4998 * equal to a constant value. 4999 * <p> 5000 * Note: In this comparison a {@code String} that is {@code null} is 5001 * considered equal to an empty {@code String}. 5002 * 5003 * @param op1 5004 * the {@code ObservableStringValue} 5005 * @param op2 5006 * the constant value 5007 * @return the new {@code BooleanBinding} 5008 * @throws NullPointerException 5009 * if the {@code ObservableStringValue} is {@code null} 5010 */ 5011 public static BooleanBinding equal(final ObservableStringValue op1, String op2) { 5012 return equal(op1, StringConstant.valueOf(op2), op1); 5013 } 5014 5015 /** 5016 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5017 * if the value of a {@link javafx.beans.value.ObservableStringValue} is 5018 * equal to a constant value. 5019 * <p> 5020 * Note: In this comparison a {@code String} that is {@code null} is 5021 * considered equal to an empty {@code String}. 5022 * 5023 * @param op1 5024 * the constant value 5025 * @param op2 5026 * the {@code ObservableStringValue} 5027 * @return the new {@code BooleanBinding} 5028 * @throws NullPointerException 5029 * if the {@code ObservableStringValue} is {@code null} 5030 */ 5031 public static BooleanBinding equal(String op1, final ObservableStringValue op2) { 5032 return equal(StringConstant.valueOf(op1), op2, op2); 5033 } 5034 5035 private static BooleanBinding notEqual(final ObservableStringValue op1, final ObservableStringValue op2, final Observable... dependencies) { 5036 if ((op1 == null) || (op2 == null)) { 5037 throw new NullPointerException("Operands cannot be null."); 5038 } 5039 assert (dependencies != null) && (dependencies.length > 0); 5040 5041 return new BooleanBinding() { 5042 { 5043 super.bind(dependencies); 5044 } 5045 5046 @Override 5047 public void dispose() { 5048 super.unbind(dependencies); 5049 } 5050 5051 @Override 5052 protected boolean computeValue() { 5053 final String s1 = getStringSafe(op1.get()); 5054 final String s2 = getStringSafe(op2.get()); 5055 return ! s1.equals(s2); 5056 } 5057 5058 @Override 5059 public ObservableList<?> getDependencies() { 5060 return (dependencies.length == 1)? 5061 FXCollections.singletonObservableList(dependencies[0]) 5062 : new ImmutableObservableList<Observable>(dependencies); 5063 } 5064 }; 5065 } 5066 5067 /** 5068 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5069 * if the values of two instances of 5070 * {@link javafx.beans.value.ObservableStringValue} are not equal. 5071 * <p> 5072 * Note: In this comparison a {@code String} that is {@code null} is 5073 * considered equal to an empty {@code String}. 5074 * 5075 * @param op1 5076 * the first operand 5077 * @param op2 5078 * the second operand 5079 * @return the new {@code BooleanBinding} 5080 * @throws NullPointerException 5081 * if one of the operands is {@code null} 5082 */ 5083 public static BooleanBinding notEqual(final ObservableStringValue op1, final ObservableStringValue op2) { 5084 return notEqual(op1, op2, op1, op2); 5085 } 5086 5087 /** 5088 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5089 * if the value of a {@link javafx.beans.value.ObservableStringValue} is not 5090 * equal to a constant value. 5091 * <p> 5092 * Note: In this comparison a {@code String} that is {@code null} is 5093 * considered equal to an empty {@code String}. 5094 * 5095 * @param op1 5096 * the {@code ObservableStringValue} 5097 * @param op2 5098 * the constant value 5099 * @return the new {@code BooleanBinding} 5100 * @throws NullPointerException 5101 * if the {@code ObservableStringValue} is {@code null} 5102 */ 5103 public static BooleanBinding notEqual(final ObservableStringValue op1, String op2) { 5104 return notEqual(op1, StringConstant.valueOf(op2), op1); 5105 } 5106 5107 /** 5108 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5109 * if the value of a {@link javafx.beans.value.ObservableStringValue} is not 5110 * equal to a constant value. 5111 * <p> 5112 * Note: In this comparison a {@code String} that is {@code null} is 5113 * considered equal to an empty {@code String}. 5114 * 5115 * @param op1 5116 * the constant value 5117 * @param op2 5118 * the {@code ObservableStringValue} 5119 * @return the new {@code BooleanBinding} 5120 * @throws NullPointerException 5121 * if the {@code ObservableStringValue} is {@code null} 5122 */ 5123 public static BooleanBinding notEqual(String op1, final ObservableStringValue op2) { 5124 return notEqual(StringConstant.valueOf(op1), op2, op2); 5125 } 5126 5127 private static BooleanBinding equalIgnoreCase(final ObservableStringValue op1, final ObservableStringValue op2, final Observable... dependencies) { 5128 if ((op1 == null) || (op2 == null)) { 5129 throw new NullPointerException("Operands cannot be null."); 5130 } 5131 assert (dependencies != null) && (dependencies.length > 0); 5132 5133 return new BooleanBinding() { 5134 { 5135 super.bind(dependencies); 5136 } 5137 5138 @Override 5139 public void dispose() { 5140 super.unbind(dependencies); 5141 } 5142 5143 @Override 5144 protected boolean computeValue() { 5145 final String s1 = getStringSafe(op1.get()); 5146 final String s2 = getStringSafe(op2.get()); 5147 return s1.equalsIgnoreCase(s2); 5148 } 5149 5150 @Override 5151 public ObservableList<?> getDependencies() { 5152 return (dependencies.length == 1)? 5153 FXCollections.singletonObservableList(dependencies[0]) 5154 : new ImmutableObservableList<Observable>(dependencies); 5155 } 5156 }; 5157 } 5158 5159 /** 5160 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5161 * if the values of two instances of 5162 * {@link javafx.beans.value.ObservableStringValue} are equal ignoring case. 5163 * <p> 5164 * Note: In this comparison a {@code String} that is {@code null} is 5165 * considered equal to an empty {@code String}. 5166 * 5167 * @param op1 5168 * the first operand 5169 * @param op2 5170 * the second operand 5171 * @return the new {@code BooleanBinding} 5172 * @throws NullPointerException 5173 * if one of the operands is {@code null} 5174 */ 5175 public static BooleanBinding equalIgnoreCase(final ObservableStringValue op1, final ObservableStringValue op2) { 5176 return equalIgnoreCase(op1, op2, op1, op2); 5177 } 5178 5179 /** 5180 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5181 * if the value of a {@link javafx.beans.value.ObservableStringValue} is 5182 * equal to a constant value ignoring case. 5183 * <p> 5184 * Note: In this comparison a {@code String} that is {@code null} is 5185 * considered equal to an empty {@code String}. 5186 * 5187 * @param op1 5188 * the {@code ObservableStringValue} 5189 * @param op2 5190 * the constant value 5191 * @return the new {@code BooleanBinding} 5192 * @throws NullPointerException 5193 * if the {@code ObservableStringValue} is {@code null} 5194 */ 5195 public static BooleanBinding equalIgnoreCase(final ObservableStringValue op1, String op2) { 5196 return equalIgnoreCase(op1, StringConstant.valueOf(op2), op1); 5197 } 5198 5199 /** 5200 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5201 * if the value of a {@link javafx.beans.value.ObservableStringValue} is 5202 * equal to a constant value ignoring case. 5203 * <p> 5204 * Note: In this comparison a {@code String} that is {@code null} is 5205 * considered equal to an empty {@code String}. 5206 * 5207 * @param op1 5208 * the constant value 5209 * @param op2 5210 * the {@code ObservableStringValue} 5211 * @return the new {@code BooleanBinding} 5212 * @throws NullPointerException 5213 * if the {@code ObservableStringValue} is {@code null} 5214 */ 5215 public static BooleanBinding equalIgnoreCase(String op1, final ObservableStringValue op2) { 5216 return equalIgnoreCase(StringConstant.valueOf(op1), op2, op2); 5217 } 5218 5219 private static BooleanBinding notEqualIgnoreCase(final ObservableStringValue op1, final ObservableStringValue op2, final Observable... dependencies) { 5220 if ((op1 == null) || (op2 == null)) { 5221 throw new NullPointerException("Operands cannot be null."); 5222 } 5223 assert (dependencies != null) && (dependencies.length > 0); 5224 5225 return new BooleanBinding() { 5226 { 5227 super.bind(dependencies); 5228 } 5229 5230 @Override 5231 public void dispose() { 5232 super.unbind(dependencies); 5233 } 5234 5235 @Override 5236 protected boolean computeValue() { 5237 final String s1 = getStringSafe(op1.get()); 5238 final String s2 = getStringSafe(op2.get()); 5239 return ! s1.equalsIgnoreCase(s2); 5240 } 5241 5242 @Override 5243 public ObservableList<?> getDependencies() { 5244 return (dependencies.length == 1)? 5245 FXCollections.singletonObservableList(dependencies[0]) 5246 : new ImmutableObservableList<Observable>(dependencies); 5247 } 5248 }; 5249 } 5250 5251 /** 5252 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5253 * if the values of two instances of 5254 * {@link javafx.beans.value.ObservableStringValue} are not equal ignoring 5255 * case. 5256 * <p> 5257 * Note: In this comparison a {@code String} that is {@code null} is 5258 * considered equal to an empty {@code String}. 5259 * 5260 * @param op1 5261 * the first operand 5262 * @param op2 5263 * the second operand 5264 * @return the new {@code BooleanBinding} 5265 * @throws NullPointerException 5266 * if one of the operands is {@code null} 5267 */ 5268 public static BooleanBinding notEqualIgnoreCase(final ObservableStringValue op1, final ObservableStringValue op2) { 5269 return notEqualIgnoreCase(op1, op2, op1, op2); 5270 } 5271 5272 /** 5273 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5274 * if the value of a {@link javafx.beans.value.ObservableStringValue} is not 5275 * equal to a constant value ignoring case. 5276 * <p> 5277 * Note: In this comparison a {@code String} that is {@code null} is 5278 * considered equal to an empty {@code String}. 5279 * 5280 * @param op1 5281 * the {@code ObservableStringValue} 5282 * @param op2 5283 * the constant value 5284 * @return the new {@code BooleanBinding} 5285 * @throws NullPointerException 5286 * if the {@code ObservableStringValue} is {@code null} 5287 */ 5288 public static BooleanBinding notEqualIgnoreCase(final ObservableStringValue op1, String op2) { 5289 return notEqualIgnoreCase(op1, StringConstant.valueOf(op2), op1); 5290 } 5291 5292 /** 5293 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5294 * if the value of a {@link javafx.beans.value.ObservableStringValue} is not 5295 * equal to a constant value ignoring case. 5296 * <p> 5297 * Note: In this comparison a {@code String} that is {@code null} is 5298 * considered equal to an empty {@code String}. 5299 * 5300 * @param op1 5301 * the constant value 5302 * @param op2 5303 * the {@code ObservableStringValue} 5304 * @return the new {@code BooleanBinding} 5305 * @throws NullPointerException 5306 * if the {@code ObservableStringValue} is {@code null} 5307 */ 5308 public static BooleanBinding notEqualIgnoreCase(String op1, final ObservableStringValue op2) { 5309 return notEqualIgnoreCase(StringConstant.valueOf(op1), op2, op2); 5310 } 5311 5312 private static BooleanBinding greaterThan(final ObservableStringValue op1, final ObservableStringValue op2, final Observable... dependencies) { 5313 if ((op1 == null) || (op2 == null)) { 5314 throw new NullPointerException("Operands cannot be null."); 5315 } 5316 assert (dependencies != null) && (dependencies.length > 0); 5317 5318 return new BooleanBinding() { 5319 { 5320 super.bind(dependencies); 5321 } 5322 5323 @Override 5324 public void dispose() { 5325 super.unbind(dependencies); 5326 } 5327 5328 @Override 5329 protected boolean computeValue() { 5330 final String s1 = getStringSafe(op1.get()); 5331 final String s2 = getStringSafe(op2.get()); 5332 return s1.compareTo(s2) > 0; 5333 } 5334 5335 @Override 5336 public ObservableList<?> getDependencies() { 5337 return (dependencies.length == 1)? 5338 FXCollections.singletonObservableList(dependencies[0]) 5339 : new ImmutableObservableList<Observable>(dependencies); 5340 } 5341 }; 5342 } 5343 5344 /** 5345 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5346 * if the value of the first 5347 * {@link javafx.beans.value.ObservableStringValue} is greater than the 5348 * value of the second. 5349 * <p> 5350 * Note: In this comparison a {@code String} that is {@code null} is 5351 * considered equal to an empty {@code String}. 5352 * 5353 * @param op1 5354 * the first operand 5355 * @param op2 5356 * the second operand 5357 * @return the new {@code BooleanBinding} 5358 * @throws NullPointerException 5359 * if one of the operands is {@code null} 5360 */ 5361 public static BooleanBinding greaterThan(final ObservableStringValue op1, final ObservableStringValue op2) { 5362 return greaterThan(op1, op2, op1, op2); 5363 } 5364 5365 /** 5366 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5367 * if the value of a {@link javafx.beans.value.ObservableStringValue} is 5368 * greater than a constant value. 5369 * <p> 5370 * Note: In this comparison a {@code String} that is {@code null} is 5371 * considered equal to an empty {@code String}. 5372 * 5373 * @param op1 5374 * the {@code ObservableStringValue} 5375 * @param op2 5376 * the constant value 5377 * @return the new {@code BooleanBinding} 5378 * @throws NullPointerException 5379 * if the {@code ObservableStringValue} is {@code null} 5380 */ 5381 public static BooleanBinding greaterThan(final ObservableStringValue op1, String op2) { 5382 return greaterThan(op1, StringConstant.valueOf(op2), op1); 5383 } 5384 5385 /** 5386 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5387 * if the value of a constant value is greater than the value of a 5388 * {@link javafx.beans.value.ObservableStringValue}. 5389 * <p> 5390 * Note: In this comparison a {@code String} that is {@code null} is 5391 * considered equal to an empty {@code String}. 5392 * 5393 * @param op1 5394 * the constant value 5395 * @param op2 5396 * the {@code ObservableStringValue} 5397 * @return the new {@code BooleanBinding} 5398 * @throws NullPointerException 5399 * if the {@code ObservableStringValue} is {@code null} 5400 */ 5401 public static BooleanBinding greaterThan(String op1, final ObservableStringValue op2) { 5402 return greaterThan(StringConstant.valueOf(op1), op2, op2); 5403 } 5404 5405 private static BooleanBinding lessThan(final ObservableStringValue op1, final ObservableStringValue op2, final Observable... dependencies) { 5406 return greaterThan(op2, op1, dependencies); 5407 } 5408 5409 /** 5410 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5411 * if the value of the first 5412 * {@link javafx.beans.value.ObservableStringValue} is less than the value 5413 * of the second. 5414 * <p> 5415 * Note: In this comparison a {@code String} that is {@code null} is 5416 * considered equal to an empty {@code String}. 5417 * 5418 * @param op1 5419 * the first operand 5420 * @param op2 5421 * the second operand 5422 * @return the new {@code BooleanBinding} 5423 * @throws NullPointerException 5424 * if one of the operands is {@code null} 5425 */ 5426 public static BooleanBinding lessThan(final ObservableStringValue op1, final ObservableStringValue op2) { 5427 return lessThan(op1, op2, op1, op2); 5428 } 5429 5430 /** 5431 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5432 * if the value of a {@link javafx.beans.value.ObservableStringValue} is 5433 * less than a constant value. 5434 * <p> 5435 * Note: In this comparison a {@code String} that is {@code null} is 5436 * considered equal to an empty {@code String}. 5437 * 5438 * @param op1 5439 * the {@code ObservableStringValue} 5440 * @param op2 5441 * the constant value 5442 * @return the new {@code BooleanBinding} 5443 * @throws NullPointerException 5444 * if the {@code ObservableStringValue} is {@code null} 5445 */ 5446 public static BooleanBinding lessThan(final ObservableStringValue op1, String op2) { 5447 return lessThan(op1, StringConstant.valueOf(op2), op1); 5448 } 5449 5450 /** 5451 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5452 * if a constant value is less than the value of a 5453 * {@link javafx.beans.value.ObservableStringValue}. 5454 * <p> 5455 * Note: In this comparison a {@code String} that is {@code null} is 5456 * considered equal to an empty {@code String}. 5457 * 5458 * @param op1 5459 * the constant value 5460 * @param op2 5461 * the {@code ObservableStringValue} 5462 * @return the new {@code BooleanBinding} 5463 * @throws NullPointerException 5464 * if the {@code ObservableStringValue} is {@code null} 5465 */ 5466 public static BooleanBinding lessThan(String op1, final ObservableStringValue op2) { 5467 return lessThan(StringConstant.valueOf(op1), op2, op2); 5468 } 5469 5470 private static BooleanBinding greaterThanOrEqual(final ObservableStringValue op1, final ObservableStringValue op2, final Observable... dependencies) { 5471 if ((op1 == null) || (op2 == null)) { 5472 throw new NullPointerException("Operands cannot be null."); 5473 } 5474 assert (dependencies != null) && (dependencies.length > 0); 5475 5476 return new BooleanBinding() { 5477 { 5478 super.bind(dependencies); 5479 } 5480 5481 @Override 5482 public void dispose() { 5483 super.unbind(dependencies); 5484 } 5485 5486 @Override 5487 protected boolean computeValue() { 5488 final String s1 = getStringSafe(op1.get()); 5489 final String s2 = getStringSafe(op2.get()); 5490 return s1.compareTo(s2) >= 0; 5491 } 5492 5493 @Override 5494 public ObservableList<?> getDependencies() { 5495 return (dependencies.length == 1)? 5496 FXCollections.singletonObservableList(dependencies[0]) 5497 : new ImmutableObservableList<Observable>(dependencies); 5498 } 5499 }; 5500 } 5501 5502 /** 5503 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5504 * if the value of the first 5505 * {@link javafx.beans.value.ObservableStringValue} is greater than or equal 5506 * to the value of the second. 5507 * <p> 5508 * Note: In this comparison a {@code String} that is {@code null} is 5509 * considered equal to an empty {@code String}. 5510 * 5511 * @param op1 5512 * the first operand 5513 * @param op2 5514 * the second operand 5515 * @return the new {@code BooleanBinding} 5516 * @throws NullPointerException 5517 * if one of the operands is {@code null} 5518 */ 5519 public static BooleanBinding greaterThanOrEqual(final ObservableStringValue op1, final ObservableStringValue op2) { 5520 return greaterThanOrEqual(op1, op2, op1, op2); 5521 } 5522 5523 /** 5524 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5525 * if the value of a {@link javafx.beans.value.ObservableStringValue} is 5526 * greater than or equal to a constant value. 5527 * <p> 5528 * Note: In this comparison a {@code String} that is {@code null} is 5529 * considered equal to an empty {@code String}. 5530 * 5531 * @param op1 5532 * the {@code ObservableStringValue} 5533 * @param op2 5534 * the constant value 5535 * @return the new {@code BooleanBinding} 5536 * @throws NullPointerException 5537 * if the {@code ObservableStringValue} is {@code null} 5538 */ 5539 public static BooleanBinding greaterThanOrEqual(final ObservableStringValue op1, String op2) { 5540 return greaterThanOrEqual(op1, StringConstant.valueOf(op2), op1); 5541 } 5542 5543 /** 5544 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5545 * if a constant value is greater than or equal to the value of a 5546 * {@link javafx.beans.value.ObservableStringValue}. 5547 * <p> 5548 * Note: In this comparison a {@code String} that is {@code null} is 5549 * considered equal to an empty {@code String}. 5550 * 5551 * @param op1 5552 * the constant value 5553 * @param op2 5554 * the {@code ObservableStringValue} 5555 * @return the new {@code BooleanBinding} 5556 * @throws NullPointerException 5557 * if the {@code ObservableStringValue} is {@code null} 5558 */ 5559 public static BooleanBinding greaterThanOrEqual(String op1, final ObservableStringValue op2) { 5560 return greaterThanOrEqual(StringConstant.valueOf(op1), op2, op2); 5561 } 5562 5563 private static BooleanBinding lessThanOrEqual(final ObservableStringValue op1, final ObservableStringValue op2, final Observable... dependencies) { 5564 return greaterThanOrEqual(op2, op1, dependencies); 5565 } 5566 5567 /** 5568 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5569 * if the value of the first 5570 * {@link javafx.beans.value.ObservableStringValue} is less than or equal to 5571 * the value of the second. 5572 * <p> 5573 * Note: In this comparison a {@code String} that is {@code null} is 5574 * considered equal to an empty {@code String}. 5575 * 5576 * @param op1 5577 * the first operand 5578 * @param op2 5579 * the second operand 5580 * @return the new {@code BooleanBinding} 5581 * @throws NullPointerException 5582 * if one of the operands is {@code null} 5583 */ 5584 public static BooleanBinding lessThanOrEqual(final ObservableStringValue op1, final ObservableStringValue op2) { 5585 return lessThanOrEqual(op1, op2, op1, op2); 5586 } 5587 5588 /** 5589 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5590 * if the value of a {@link javafx.beans.value.ObservableStringValue} is 5591 * less than or equal to a constant value. 5592 * <p> 5593 * Note: In this comparison a {@code String} that is {@code null} is 5594 * considered equal to an empty {@code String}. 5595 * 5596 * @param op1 5597 * the {@code ObservableStringValue} 5598 * @param op2 5599 * the constant value 5600 * @return the new {@code BooleanBinding} 5601 * @throws NullPointerException 5602 * if the {@code ObservableStringValue} is {@code null} 5603 */ 5604 public static BooleanBinding lessThanOrEqual(final ObservableStringValue op1, String op2) { 5605 return lessThanOrEqual(op1, StringConstant.valueOf(op2), op1); 5606 } 5607 5608 /** 5609 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5610 * if a constant value is less than or equal to the value of a 5611 * {@link javafx.beans.value.ObservableStringValue}. 5612 * <p> 5613 * Note: In this comparison a {@code String} that is {@code null} is 5614 * considered equal to an empty {@code String}. 5615 * 5616 * @param op1 5617 * the constant value 5618 * @param op2 5619 * the {@code ObservableStringValue} 5620 * @return the new {@code BooleanBinding} 5621 * @throws NullPointerException 5622 * if the {@code ObservableStringValue} is {@code null} 5623 */ 5624 public static BooleanBinding lessThanOrEqual(String op1, final ObservableStringValue op2) { 5625 return lessThanOrEqual(StringConstant.valueOf(op1), op2, op2); 5626 } 5627 5628 /** 5629 * Creates a new {@link javafx.beans.binding.IntegerBinding} that holds the length of a 5630 * {@link javafx.beans.value.ObservableStringValue}. 5631 * <p> 5632 * Note: In this comparison a {@code String} that is {@code null} is 5633 * considered to have a length of {@code 0}. 5634 * 5635 * @param op 5636 * the {@code ObservableStringValue} 5637 * @return the new {@code IntegerBinding} 5638 * @throws NullPointerException 5639 * if the {@code ObservableStringValue} is {@code null} 5640 * @since JavaFX 8.0 5641 */ 5642 public static IntegerBinding length(final ObservableStringValue op) { 5643 if (op == null) { 5644 throw new NullPointerException("Operand cannot be null"); 5645 } 5646 5647 return new IntegerBinding() { 5648 { 5649 super.bind(op); 5650 } 5651 5652 @Override 5653 public void dispose() { 5654 super.unbind(op); 5655 } 5656 5657 @Override 5658 protected int computeValue() { 5659 return getStringSafe(op.get()).length(); 5660 } 5661 5662 @Override 5663 public ObservableList<?> getDependencies() { 5664 return FXCollections.singletonObservableList(op); 5665 } 5666 }; 5667 } 5668 5669 /** 5670 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5671 * if the value of a {@link javafx.beans.value.ObservableStringValue} is empty. 5672 * <p> 5673 * Note: In this comparison a {@code String} that is {@code null} is 5674 * considered to be empty. 5675 * 5676 * @param op 5677 * the {@code ObservableStringValue} 5678 * @return the new {@code BooleanBinding} 5679 * @throws NullPointerException 5680 * if the {@code ObservableStringValue} is {@code null} 5681 * @since JavaFX 8.0 5682 */ 5683 public static BooleanBinding isEmpty(final ObservableStringValue op) { 5684 if (op == null) { 5685 throw new NullPointerException("Operand cannot be null"); 5686 } 5687 5688 return new BooleanBinding() { 5689 { 5690 super.bind(op); 5691 } 5692 5693 @Override 5694 public void dispose() { 5695 super.unbind(op); 5696 } 5697 5698 @Override 5699 protected boolean computeValue() { 5700 return getStringSafe(op.get()).isEmpty(); 5701 } 5702 5703 @Override 5704 public ObservableList<?> getDependencies() { 5705 return FXCollections.singletonObservableList(op); 5706 } 5707 }; 5708 } 5709 5710 /** 5711 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5712 * if the value of a {@link javafx.beans.value.ObservableStringValue} is not empty. 5713 * <p> 5714 * Note: In this comparison a {@code String} that is {@code null} is 5715 * considered to be empty. 5716 * 5717 * @param op 5718 * the {@code ObservableStringValue} 5719 * @return the new {@code BooleanBinding} 5720 * @throws NullPointerException 5721 * if the {@code ObservableStringValue} is {@code null} 5722 * @since JavaFX 8.0 5723 */ 5724 public static BooleanBinding isNotEmpty(final ObservableStringValue op) { 5725 if (op == null) { 5726 throw new NullPointerException("Operand cannot be null"); 5727 } 5728 5729 return new BooleanBinding() { 5730 { 5731 super.bind(op); 5732 } 5733 5734 @Override 5735 public void dispose() { 5736 super.unbind(op); 5737 } 5738 5739 @Override 5740 protected boolean computeValue() { 5741 return !getStringSafe(op.get()).isEmpty(); 5742 } 5743 5744 @Override 5745 public ObservableList<?> getDependencies() { 5746 return FXCollections.singletonObservableList(op); 5747 } 5748 }; 5749 } 5750 5751 // Object 5752 // ================================================================================================================= 5753 5754 private static BooleanBinding equal(final ObservableObjectValue<?> op1, final ObservableObjectValue<?> op2, final Observable... dependencies) { 5755 if ((op1 == null) || (op2 == null)) { 5756 throw new NullPointerException("Operands cannot be null."); 5757 } 5758 assert (dependencies != null) && (dependencies.length > 0); 5759 5760 return new BooleanBinding() { 5761 { 5762 super.bind(dependencies); 5763 } 5764 5765 @Override 5766 public void dispose() { 5767 super.unbind(dependencies); 5768 } 5769 5770 @Override 5771 protected boolean computeValue() { 5772 final Object obj1 = op1.get(); 5773 final Object obj2 = op2.get(); 5774 return obj1 == null ? obj2 == null : obj1.equals(obj2); 5775 } 5776 5777 @Override 5778 public ObservableList<?> getDependencies() { 5779 return (dependencies.length == 1)? 5780 FXCollections.singletonObservableList(dependencies[0]) 5781 : new ImmutableObservableList<Observable>(dependencies); 5782 } 5783 }; 5784 } 5785 5786 /** 5787 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5788 * if the values of two instances of 5789 * {@link javafx.beans.value.ObservableObjectValue} are equal. 5790 * 5791 * @param op1 5792 * the first operand 5793 * @param op2 5794 * the second operand 5795 * @return the new {@code BooleanBinding} 5796 * @throws NullPointerException 5797 * if one of the operands is {@code null} 5798 */ 5799 public static BooleanBinding equal(final ObservableObjectValue<?> op1, final ObservableObjectValue<?> op2) { 5800 return equal(op1, op2, op1, op2); 5801 } 5802 5803 /** 5804 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5805 * if the value of an {@link javafx.beans.value.ObservableObjectValue} is 5806 * equal to a constant value. 5807 * 5808 * @param op1 5809 * the {@code ObservableCharacterValue} 5810 * @param op2 5811 * the constant value 5812 * @return the new {@code BooleanBinding} 5813 * @throws NullPointerException 5814 * if the {@code ObservableCharacterValue} is {@code null} 5815 */ 5816 public static BooleanBinding equal(final ObservableObjectValue<?> op1, Object op2) { 5817 return equal(op1, ObjectConstant.valueOf(op2), op1); 5818 } 5819 5820 /** 5821 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5822 * if the value of an {@link javafx.beans.value.ObservableObjectValue} is 5823 * equal to a constant value. 5824 * 5825 * @param op1 5826 * the constant value 5827 * @param op2 5828 * the {@code ObservableCharacterValue} 5829 * @return the new {@code BooleanBinding} 5830 * @throws NullPointerException 5831 * if the {@code ObservableCharacterValue} is {@code null} 5832 */ 5833 public static BooleanBinding equal(Object op1, final ObservableObjectValue<?> op2) { 5834 return equal(ObjectConstant.valueOf(op1), op2, op2); 5835 } 5836 5837 private static BooleanBinding notEqual(final ObservableObjectValue<?> op1, final ObservableObjectValue<?> op2, final Observable... dependencies) { 5838 if ((op1 == null) || (op2 == null)) { 5839 throw new NullPointerException("Operands cannot be null."); 5840 } 5841 assert (dependencies != null) && (dependencies.length > 0); 5842 5843 return new BooleanBinding() { 5844 { 5845 super.bind(dependencies); 5846 } 5847 5848 @Override 5849 public void dispose() { 5850 super.unbind(dependencies); 5851 } 5852 5853 @Override 5854 protected boolean computeValue() { 5855 final Object obj1 = op1.get(); 5856 final Object obj2 = op2.get(); 5857 return obj1 == null ? obj2 != null : ! obj1.equals(obj2); 5858 } 5859 5860 @Override 5861 public ObservableList<?> getDependencies() { 5862 return (dependencies.length == 1)? 5863 FXCollections.singletonObservableList(dependencies[0]) 5864 : new ImmutableObservableList<Observable>(dependencies); 5865 } 5866 }; 5867 } 5868 5869 /** 5870 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5871 * if the values of two instances of 5872 * {@link javafx.beans.value.ObservableObjectValue} are not equal. 5873 * 5874 * @param op1 5875 * the first operand 5876 * @param op2 5877 * the second operand 5878 * @return the new {@code BooleanBinding} 5879 * @throws NullPointerException 5880 * if one of the operands is {@code null} 5881 */ 5882 public static BooleanBinding notEqual(final ObservableObjectValue<?> op1, final ObservableObjectValue<?> op2) { 5883 return notEqual(op1, op2, op1, op2); 5884 } 5885 5886 /** 5887 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5888 * if the value of an {@link javafx.beans.value.ObservableObjectValue} is 5889 * not equal to a constant value. 5890 * 5891 * @param op1 5892 * the {@code ObservableObjectValue} 5893 * @param op2 5894 * the constant value 5895 * @return the new {@code BooleanBinding} 5896 * @throws NullPointerException 5897 * if the {@code ObservableObjectValue} is {@code null} 5898 */ 5899 public static BooleanBinding notEqual(final ObservableObjectValue<?> op1, Object op2) { 5900 return notEqual(op1, ObjectConstant.valueOf(op2), op1); 5901 } 5902 5903 /** 5904 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5905 * if the value of an {@link javafx.beans.value.ObservableObjectValue} is 5906 * not equal to a constant value. 5907 * 5908 * @param op1 5909 * the constant value 5910 * @param op2 5911 * the {@code ObservableObjectValue} 5912 * @return the new {@code BooleanBinding} 5913 * @throws NullPointerException 5914 * if the {@code ObservableObjectValue} is {@code null} 5915 */ 5916 public static BooleanBinding notEqual(Object op1, final ObservableObjectValue<?> op2) { 5917 return notEqual(ObjectConstant.valueOf(op1), op2, op2); 5918 } 5919 5920 /** 5921 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5922 * if the value of an {@link javafx.beans.value.ObservableObjectValue} is 5923 * {@code null}. 5924 * 5925 * @param op 5926 * the {@code ObservableObjectValue} 5927 * @return the new {@code BooleanBinding} 5928 * @throws NullPointerException 5929 * if the {@code ObservableObjectValue} is {@code null} 5930 */ 5931 public static BooleanBinding isNull(final ObservableObjectValue<?> op) { 5932 if (op == null) { 5933 throw new NullPointerException("Operand cannot be null."); 5934 } 5935 5936 return new BooleanBinding() { 5937 { 5938 super.bind(op); 5939 } 5940 5941 @Override 5942 public void dispose() { 5943 super.unbind(op); 5944 } 5945 5946 @Override 5947 protected boolean computeValue() { 5948 return op.get() == null; 5949 } 5950 5951 @Override 5952 public ObservableList<?> getDependencies() { 5953 return FXCollections.singletonObservableList(op); 5954 } 5955 }; 5956 } 5957 5958 /** 5959 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 5960 * if the value of an {@link javafx.beans.value.ObservableObjectValue} is 5961 * not {@code null}. 5962 * 5963 * @param op 5964 * the {@code ObservableObjectValue} 5965 * @return the new {@code BooleanBinding} 5966 * @throws NullPointerException 5967 * if the {@code ObservableObjectValue} is {@code null} 5968 */ 5969 public static BooleanBinding isNotNull(final ObservableObjectValue<?> op) { 5970 if (op == null) { 5971 throw new NullPointerException("Operand cannot be null."); 5972 } 5973 5974 return new BooleanBinding() { 5975 { 5976 super.bind(op); 5977 } 5978 5979 @Override 5980 public void dispose() { 5981 super.unbind(op); 5982 } 5983 5984 @Override 5985 protected boolean computeValue() { 5986 return op.get() != null; 5987 } 5988 5989 @Override 5990 public ObservableList<?> getDependencies() { 5991 return FXCollections.singletonObservableList(op); 5992 } 5993 }; 5994 } 5995 5996 // List 5997 // ================================================================================================================= 5998 5999 /** 6000 * Creates a new {@link javafx.beans.binding.IntegerBinding} that contains the size 6001 * of an {@link javafx.collections.ObservableList}. 6002 * 6003 * @param op 6004 * the {@code ObservableList} 6005 * @param <E> type of the {@code List} elements 6006 * @return the new {@code IntegerBinding} 6007 * @throws NullPointerException 6008 * if the {@code ObservableList} is {@code null} 6009 * @since JavaFX 2.1 6010 */ 6011 public static <E> IntegerBinding size(final ObservableList<E> op) { 6012 if (op == null) { 6013 throw new NullPointerException("List cannot be null."); 6014 } 6015 6016 return new IntegerBinding() { 6017 { 6018 super.bind(op); 6019 } 6020 6021 @Override 6022 public void dispose() { 6023 super.unbind(op); 6024 } 6025 6026 @Override 6027 protected int computeValue() { 6028 return op.size(); 6029 } 6030 6031 @Override 6032 public ObservableList<?> getDependencies() { 6033 return FXCollections.singletonObservableList(op); 6034 } 6035 }; 6036 } 6037 6038 /** 6039 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 6040 * if a given {@link javafx.collections.ObservableList} is empty. 6041 * 6042 * @param op 6043 * the {@code ObservableList} 6044 * @param <E> type of the {@code List} elements 6045 * @return the new {@code BooleanBinding} 6046 * @throws NullPointerException 6047 * if the {@code ObservableList} is {@code null} 6048 * @since JavaFX 2.1 6049 */ 6050 public static <E> BooleanBinding isEmpty(final ObservableList<E> op) { 6051 if (op == null) { 6052 throw new NullPointerException("List cannot be null."); 6053 } 6054 6055 return new BooleanBinding() { 6056 { 6057 super.bind(op); 6058 } 6059 6060 @Override 6061 public void dispose() { 6062 super.unbind(op); 6063 } 6064 6065 @Override 6066 protected boolean computeValue() { 6067 return op.isEmpty(); 6068 } 6069 6070 @Override 6071 public ObservableList<?> getDependencies() { 6072 return FXCollections.singletonObservableList(op); 6073 } 6074 }; 6075 } 6076 6077 /** 6078 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 6079 * if a given {@link javafx.collections.ObservableList} is not empty. 6080 * 6081 * @param op 6082 * the {@code ObservableList} 6083 * @param <E> type of the {@code List} elements 6084 * @return the new {@code BooleanBinding} 6085 * @throws NullPointerException 6086 * if the {@code ObservableList} is {@code null} 6087 * @since JavaFX 8.0 6088 */ 6089 public static <E> BooleanBinding isNotEmpty(final ObservableList<E> op) { 6090 if (op == null) { 6091 throw new NullPointerException("List cannot be null."); 6092 } 6093 6094 return new BooleanBinding() { 6095 { 6096 super.bind(op); 6097 } 6098 6099 @Override 6100 public void dispose() { 6101 super.unbind(op); 6102 } 6103 6104 @Override 6105 protected boolean computeValue() { 6106 return !op.isEmpty(); 6107 } 6108 6109 @Override 6110 public ObservableList<?> getDependencies() { 6111 return FXCollections.singletonObservableList(op); 6112 } 6113 }; 6114 } 6115 6116 /** 6117 * Creates a new {@link javafx.beans.binding.ObjectBinding} that contains the element 6118 * of an {@link javafx.collections.ObservableList} at the specified position. The {@code ObjectBinding} 6119 * will contain {@code null}, if the {@code index} points behind the {@code ObservableList}. 6120 * 6121 * @param op the {@code ObservableList} 6122 * @param index the position in the {@code List} 6123 * @param <E> the type of the {@code List} elements 6124 * @return the new {@code ObjectBinding} 6125 * @throws NullPointerException if the {@code ObservableList} is {@code null} 6126 * @throws IllegalArgumentException if (@code index < 0) 6127 * @since JavaFX 2.1 6128 */ 6129 public static <E> ObjectBinding<E> valueAt(final ObservableList<E> op, final int index) { 6130 if (op == null) { 6131 throw new NullPointerException("List cannot be null."); 6132 } 6133 if (index < 0) { 6134 throw new IllegalArgumentException("Index cannot be negative"); 6135 } 6136 6137 return new ObjectBinding<E>() { 6138 { 6139 super.bind(op); 6140 } 6141 6142 @Override 6143 public void dispose() { 6144 super.unbind(op); 6145 } 6146 6147 @Override 6148 protected E computeValue() { 6149 try { 6150 return op.get(index); 6151 } catch (IndexOutOfBoundsException ex) { 6152 Logging.getLogger().fine("Exception while evaluating binding", ex); 6153 } 6154 return null; 6155 } 6156 6157 @Override 6158 public ObservableList<?> getDependencies() { 6159 return FXCollections.singletonObservableList(op); 6160 } 6161 }; 6162 } 6163 6164 /** 6165 * Creates a new {@link javafx.beans.binding.ObjectBinding} that contains the element 6166 * of an {@link javafx.collections.ObservableList} at the specified position. The {@code ObjectBinding} 6167 * will contain {@code null}, if the {@code index} is outside of the {@code ObservableList}. 6168 * 6169 * @param op the {@code ObservableList} 6170 * @param index the position in the {@code List} 6171 * @param <E> the type of the {@code List} elements 6172 * @return the new {@code ObjectBinding} 6173 * @throws NullPointerException if the {@code ObservableList} or {@code index} is {@code null} 6174 * @since JavaFX 2.1 6175 */ 6176 public static <E> ObjectBinding<E> valueAt(final ObservableList<E> op, final ObservableIntegerValue index) { 6177 return valueAt(op, (ObservableNumberValue)index); 6178 } 6179 6180 /** 6181 * Creates a new {@link javafx.beans.binding.ObjectBinding} that contains the element 6182 * of an {@link javafx.collections.ObservableList} at the specified position. The {@code ObjectBinding} 6183 * will contain {@code null}, if the {@code index} is outside of the {@code ObservableList}. 6184 * 6185 * @param op the {@code ObservableList} 6186 * @param index the position in the {@code List}, converted to int 6187 * @param <E> the type of the {@code List} elements 6188 * @return the new {@code ObjectBinding} 6189 * @throws NullPointerException if the {@code ObservableList} or {@code index} is {@code null} 6190 * @since JavaFX 8.0 6191 */ 6192 public static <E> ObjectBinding<E> valueAt(final ObservableList<E> op, final ObservableNumberValue index) { 6193 if ((op == null) || (index == null)) { 6194 throw new NullPointerException("Operands cannot be null."); 6195 } 6196 6197 return new ObjectBinding<E>() { 6198 { 6199 super.bind(op, index); 6200 } 6201 6202 @Override 6203 public void dispose() { 6204 super.unbind(op, index); 6205 } 6206 6207 @Override 6208 protected E computeValue() { 6209 try { 6210 return op.get(index.intValue()); 6211 } catch (IndexOutOfBoundsException ex) { 6212 Logging.getLogger().fine("Exception while evaluating binding", ex); 6213 } 6214 return null; 6215 } 6216 6217 @Override 6218 public ObservableList<?> getDependencies() { 6219 return new ImmutableObservableList<Observable>(op, index); 6220 } 6221 }; 6222 } 6223 6224 /** 6225 * Creates a new {@link javafx.beans.binding.BooleanBinding} that contains the element 6226 * of an {@link javafx.collections.ObservableList} at the specified position. The {@code BooleanBinding} 6227 * will hold {@code false}, if the {@code index} points behind the {@code ObservableList}. 6228 * 6229 * @param op the {@code ObservableList} 6230 * @param index the position in the {@code List} 6231 * @return the new {@code BooleanBinding} 6232 * @throws NullPointerException if the {@code ObservableList} is {@code null} 6233 * @throws IllegalArgumentException if (@code index < 0) 6234 * @since JavaFX 2.1 6235 */ 6236 public static BooleanBinding booleanValueAt(final ObservableList<Boolean> op, final int index) { 6237 if (op == null) { 6238 throw new NullPointerException("List cannot be null."); 6239 } 6240 if (index < 0) { 6241 throw new IllegalArgumentException("Index cannot be negative"); 6242 } 6243 6244 return new BooleanBinding() { 6245 { 6246 super.bind(op); 6247 } 6248 6249 @Override 6250 public void dispose() { 6251 super.unbind(op); 6252 } 6253 6254 @Override 6255 protected boolean computeValue() { 6256 try { 6257 final Boolean value = op.get(index); 6258 if (value == null) { 6259 Logging.getLogger().fine("List element is null, returning default value instead.", new NullPointerException()); 6260 } else { 6261 return value; 6262 } 6263 } catch (IndexOutOfBoundsException ex) { 6264 Logging.getLogger().fine("Exception while evaluating binding", ex); 6265 } 6266 return false; 6267 } 6268 6269 @Override 6270 public ObservableList<?> getDependencies() { 6271 return FXCollections.singletonObservableList(op); 6272 } 6273 }; 6274 } 6275 6276 /** 6277 * Creates a new {@link javafx.beans.binding.BooleanBinding} that contains the element 6278 * of an {@link javafx.collections.ObservableList} at the specified position. The {@code BooleanBinding} 6279 * will hold {@code false}, if the {@code index} is outside of the {@code ObservableList}. 6280 * 6281 * @param op the {@code ObservableList} 6282 * @param index the position in the {@code List} 6283 * @return the new {@code BooleanBinding} 6284 * @throws NullPointerException if the {@code ObservableList} or {@code index} is {@code null} 6285 * @since JavaFX 2.1 6286 */ 6287 public static BooleanBinding booleanValueAt(final ObservableList<Boolean> op, final ObservableIntegerValue index) { 6288 return booleanValueAt(op, (ObservableNumberValue)index); 6289 } 6290 6291 /** 6292 * Creates a new {@link javafx.beans.binding.BooleanBinding} that contains the element 6293 * of an {@link javafx.collections.ObservableList} at the specified position. The {@code BooleanBinding} 6294 * will hold {@code false}, if the {@code index} is outside of the {@code ObservableList}. 6295 * 6296 * @param op the {@code ObservableList} 6297 * @param index the position in the {@code List}, converted to int 6298 * @return the new {@code BooleanBinding} 6299 * @throws NullPointerException if the {@code ObservableList} or {@code index} is {@code null} 6300 * @since JavaFX 8.0 6301 */ 6302 public static BooleanBinding booleanValueAt(final ObservableList<Boolean> op, final ObservableNumberValue index) { 6303 if ((op == null) || (index == null)) { 6304 throw new NullPointerException("Operands cannot be null."); 6305 } 6306 6307 return new BooleanBinding() { 6308 { 6309 super.bind(op, index); 6310 } 6311 6312 @Override 6313 public void dispose() { 6314 super.unbind(op, index); 6315 } 6316 6317 @Override 6318 protected boolean computeValue() { 6319 try { 6320 final Boolean value = op.get(index.intValue()); 6321 if (value == null) { 6322 Logging.getLogger().fine("List element is null, returning default value instead.", new NullPointerException()); 6323 } else { 6324 return value; 6325 } 6326 } catch (IndexOutOfBoundsException ex) { 6327 Logging.getLogger().fine("Exception while evaluating binding", ex); 6328 } 6329 return false; 6330 } 6331 6332 @Override 6333 public ObservableList<?> getDependencies() { 6334 return new ImmutableObservableList<Observable>(op, index); 6335 } 6336 }; 6337 } 6338 6339 /** 6340 * Creates a new {@link javafx.beans.binding.DoubleBinding} that contains the element 6341 * of an {@link javafx.collections.ObservableList} at the specified position. The {@code DoubleBinding} 6342 * will hold {@code 0.0}, if the {@code index} points behind the {@code ObservableList}. 6343 * 6344 * @param op the {@code ObservableList} 6345 * @param index the position in the {@code List} 6346 * @return the new {@code DoubleBinding} 6347 * @throws NullPointerException if the {@code ObservableList} is {@code null} 6348 * @throws IllegalArgumentException if (@code index < 0) 6349 * @since JavaFX 2.1 6350 */ 6351 public static DoubleBinding doubleValueAt(final ObservableList<? extends Number> op, final int index) { 6352 if (op == null) { 6353 throw new NullPointerException("List cannot be null."); 6354 } 6355 if (index < 0) { 6356 throw new IllegalArgumentException("Index cannot be negative"); 6357 } 6358 6359 return new DoubleBinding() { 6360 { 6361 super.bind(op); 6362 } 6363 6364 @Override 6365 public void dispose() { 6366 super.unbind(op); 6367 } 6368 6369 @Override 6370 protected double computeValue() { 6371 try { 6372 final Number value = op.get(index); 6373 if (value == null) { 6374 Logging.getLogger().fine("List element is null, returning default value instead.", new NullPointerException()); 6375 } else { 6376 return value.doubleValue(); 6377 } 6378 } catch (IndexOutOfBoundsException ex) { 6379 Logging.getLogger().fine("Exception while evaluating binding", ex); 6380 } 6381 return 0.0; 6382 } 6383 6384 @Override 6385 public ObservableList<?> getDependencies() { 6386 return FXCollections.singletonObservableList(op); 6387 } 6388 }; 6389 } 6390 6391 /** 6392 * Creates a new {@link javafx.beans.binding.DoubleBinding} that contains the element 6393 * of an {@link javafx.collections.ObservableList} at the specified position. The {@code DoubleBinding} 6394 * will hold {@code 0.0}, if the {@code index} is outside of the {@code ObservableList}. 6395 * 6396 * @param op the {@code ObservableList} 6397 * @param index the position in the {@code List} 6398 * @return the new {@code DoubleBinding} 6399 * @throws NullPointerException if the {@code ObservableList} or {@code index} is {@code null} 6400 * @since JavaFX 2.1 6401 */ 6402 public static DoubleBinding doubleValueAt(final ObservableList<? extends Number> op, final ObservableIntegerValue index) { 6403 return doubleValueAt(op, (ObservableNumberValue)index); 6404 } 6405 6406 /** 6407 * Creates a new {@link javafx.beans.binding.DoubleBinding} that contains the element 6408 * of an {@link javafx.collections.ObservableList} at the specified position. The {@code DoubleBinding} 6409 * will hold {@code 0.0}, if the {@code index} is outside of the {@code ObservableList}. 6410 * 6411 * @param op the {@code ObservableList} 6412 * @param index the position in the {@code List}, converted to int 6413 * @return the new {@code DoubleBinding} 6414 * @throws NullPointerException if the {@code ObservableList} or {@code index} is {@code null} 6415 * @since JavaFX 8.0 6416 */ 6417 public static DoubleBinding doubleValueAt(final ObservableList<? extends Number> op, final ObservableNumberValue index) { 6418 if ((op == null) || (index == null)) { 6419 throw new NullPointerException("Operands cannot be null."); 6420 } 6421 6422 return new DoubleBinding() { 6423 { 6424 super.bind(op, index); 6425 } 6426 6427 @Override 6428 public void dispose() { 6429 super.unbind(op, index); 6430 } 6431 6432 @Override 6433 protected double computeValue() { 6434 try { 6435 final Number value = op.get(index.intValue()); 6436 if (value == null) { 6437 Logging.getLogger().fine("List element is null, returning default value instead.", new NullPointerException()); 6438 } else { 6439 return value.doubleValue(); 6440 } 6441 } catch (IndexOutOfBoundsException ex) { 6442 Logging.getLogger().fine("Exception while evaluating binding", ex); 6443 } 6444 return 0.0; 6445 } 6446 6447 @Override 6448 public ObservableList<?> getDependencies() { 6449 return new ImmutableObservableList<Observable>(op, index); 6450 } 6451 }; 6452 } 6453 6454 /** 6455 * Creates a new {@link javafx.beans.binding.FloatBinding} that contains the element 6456 * of an {@link javafx.collections.ObservableList} at the specified position. The {@code FloatBinding} 6457 * will hold {@code 0.0f}, if the {@code index} points behind the {@code ObservableList}. 6458 * 6459 * @param op the {@code ObservableList} 6460 * @param index the position in the {@code List} 6461 * @return the new {@code FloatBinding} 6462 * @throws NullPointerException if the {@code ObservableList} is {@code null} 6463 * @throws IllegalArgumentException if (@code index < 0) 6464 * @since JavaFX 2.1 6465 */ 6466 public static FloatBinding floatValueAt(final ObservableList<? extends Number> op, final int index) { 6467 if (op == null) { 6468 throw new NullPointerException("List cannot be null."); 6469 } 6470 if (index < 0) { 6471 throw new IllegalArgumentException("Index cannot be negative"); 6472 } 6473 6474 return new FloatBinding() { 6475 { 6476 super.bind(op); 6477 } 6478 6479 @Override 6480 public void dispose() { 6481 super.unbind(op); 6482 } 6483 6484 @Override 6485 protected float computeValue() { 6486 try { 6487 final Number value = op.get(index); 6488 if (value == null) { 6489 Logging.getLogger().fine("List element is null, returning default value instead.", new NullPointerException()); 6490 } else { 6491 return value.floatValue(); 6492 } 6493 } catch (IndexOutOfBoundsException ex) { 6494 Logging.getLogger().fine("Exception while evaluating binding", ex); 6495 } 6496 return 0.0f; 6497 } 6498 6499 @Override 6500 public ObservableList<?> getDependencies() { 6501 return FXCollections.singletonObservableList(op); 6502 } 6503 }; 6504 } 6505 6506 /** 6507 * Creates a new {@link javafx.beans.binding.FloatBinding} that contains the element 6508 * of an {@link javafx.collections.ObservableList} at the specified position. The {@code FloatBinding} 6509 * will hold {@code 0.0f}, if the {@code index} is outside of the {@code ObservableList}. 6510 * 6511 * @param op the {@code ObservableList} 6512 * @param index the position in the {@code List} 6513 * @return the new {@code FloatBinding} 6514 * @throws NullPointerException if the {@code ObservableList} or {@code index} is {@code null} 6515 * @since JavaFX 2.1 6516 */ 6517 public static FloatBinding floatValueAt(final ObservableList<? extends Number> op, final ObservableIntegerValue index) { 6518 return floatValueAt(op, (ObservableNumberValue)index); 6519 } 6520 6521 /** 6522 * Creates a new {@link javafx.beans.binding.FloatBinding} that contains the element 6523 * of an {@link javafx.collections.ObservableList} at the specified position. The {@code FloatBinding} 6524 * will hold {@code 0.0f}, if the {@code index} is outside of the {@code ObservableList}. 6525 * 6526 * @param op the {@code ObservableList} 6527 * @param index the position in the {@code List}, converted to int 6528 * @return the new {@code FloatBinding} 6529 * @throws NullPointerException if the {@code ObservableList} or {@code index} is {@code null} 6530 * @since JavaFX 8.0 6531 */ 6532 public static FloatBinding floatValueAt(final ObservableList<? extends Number> op, final ObservableNumberValue index) { 6533 if ((op == null) || (index == null)) { 6534 throw new NullPointerException("Operands cannot be null."); 6535 } 6536 6537 return new FloatBinding() { 6538 { 6539 super.bind(op, index); 6540 } 6541 6542 @Override 6543 public void dispose() { 6544 super.unbind(op, index); 6545 } 6546 6547 @Override 6548 protected float computeValue() { 6549 try { 6550 final Number value = op.get(index.intValue()); 6551 if (value == null) { 6552 Logging.getLogger().fine("List element is null, returning default value instead.", new NullPointerException()); 6553 } else { 6554 return value.floatValue(); 6555 } 6556 } catch (IndexOutOfBoundsException ex) { 6557 Logging.getLogger().fine("Exception while evaluating binding", ex); 6558 } 6559 return 0.0f; 6560 } 6561 6562 @Override 6563 public ObservableList<?> getDependencies() { 6564 return new ImmutableObservableList<Observable>(op, index); 6565 } 6566 }; 6567 } 6568 6569 /** 6570 * Creates a new {@link javafx.beans.binding.IntegerBinding} that contains the element 6571 * of an {@link javafx.collections.ObservableList} at the specified position. The {@code IntegerBinding} 6572 * will hold {@code 0}, if the {@code index} points behind the {@code ObservableList}. 6573 * 6574 * @param op the {@code ObservableList} 6575 * @param index the position in the {@code List} 6576 * @return the new {@code IntegerBinding} 6577 * @throws NullPointerException if the {@code ObservableList} is {@code null} 6578 * @throws IllegalArgumentException if (@code index < 0) 6579 * @since JavaFX 2.1 6580 */ 6581 public static IntegerBinding integerValueAt(final ObservableList<? extends Number> op, final int index) { 6582 if (op == null) { 6583 throw new NullPointerException("List cannot be null."); 6584 } 6585 if (index < 0) { 6586 throw new IllegalArgumentException("Index cannot be negative"); 6587 } 6588 6589 return new IntegerBinding() { 6590 { 6591 super.bind(op); 6592 } 6593 6594 @Override 6595 public void dispose() { 6596 super.unbind(op); 6597 } 6598 6599 @Override 6600 protected int computeValue() { 6601 try { 6602 final Number value = op.get(index); 6603 if (value == null) { 6604 Logging.getLogger().fine("List element is null, returning default value instead.", new NullPointerException()); 6605 } else { 6606 return value.intValue(); 6607 } 6608 } catch (IndexOutOfBoundsException ex) { 6609 Logging.getLogger().fine("Exception while evaluating binding", ex); 6610 } 6611 return 0; 6612 } 6613 6614 @Override 6615 public ObservableList<?> getDependencies() { 6616 return FXCollections.singletonObservableList(op); 6617 } 6618 }; 6619 } 6620 6621 /** 6622 * Creates a new {@link javafx.beans.binding.IntegerBinding} that contains the element 6623 * of an {@link javafx.collections.ObservableList} at the specified position. The {@code IntegerBinding} 6624 * will hold {@code 0}, if the {@code index} is outside of the {@code ObservableList}. 6625 * 6626 * @param op the {@code ObservableList} 6627 * @param index the position in the {@code List} 6628 * @return the new {@code IntegerBinding} 6629 * @throws NullPointerException if the {@code ObservableList} or {@code index} is {@code null} 6630 * @since JavaFX 2.1 6631 */ 6632 public static IntegerBinding integerValueAt(final ObservableList<? extends Number> op, final ObservableIntegerValue index) { 6633 return integerValueAt(op, (ObservableNumberValue)index); 6634 } 6635 6636 /** 6637 * Creates a new {@link javafx.beans.binding.IntegerBinding} that contains the element 6638 * of an {@link javafx.collections.ObservableList} at the specified position. The {@code IntegerBinding} 6639 * will hold {@code 0}, if the {@code index} is outside of the {@code ObservableList}. 6640 * 6641 * @param op the {@code ObservableList} 6642 * @param index the position in the {@code List}, converted to int 6643 * @return the new {@code IntegerBinding} 6644 * @throws NullPointerException if the {@code ObservableList} or {@code index} is {@code null} 6645 * @since JavaFX 8.0 6646 */ 6647 public static IntegerBinding integerValueAt(final ObservableList<? extends Number> op, final ObservableNumberValue index) { 6648 if ((op == null) || (index == null)) { 6649 throw new NullPointerException("Operands cannot be null."); 6650 } 6651 6652 return new IntegerBinding() { 6653 { 6654 super.bind(op, index); 6655 } 6656 6657 @Override 6658 public void dispose() { 6659 super.unbind(op, index); 6660 } 6661 6662 @Override 6663 protected int computeValue() { 6664 try { 6665 final Number value = op.get(index.intValue()); 6666 if (value == null) { 6667 Logging.getLogger().fine("List element is null, returning default value instead.", new NullPointerException()); 6668 } else { 6669 return value.intValue(); 6670 } 6671 } catch (IndexOutOfBoundsException ex) { 6672 Logging.getLogger().fine("Exception while evaluating binding", ex); 6673 } 6674 return 0; 6675 } 6676 6677 @Override 6678 public ObservableList<?> getDependencies() { 6679 return new ImmutableObservableList<Observable>(op, index); 6680 } 6681 }; 6682 } 6683 6684 /** 6685 * Creates a new {@link javafx.beans.binding.LongBinding} that contains the element 6686 * of an {@link javafx.collections.ObservableList} at the specified position. The {@code LongBinding} 6687 * will hold {@code 0L}, if the {@code index} points behind the {@code ObservableList}. 6688 * 6689 * @param op the {@code ObservableList} 6690 * @param index the position in the {@code List} 6691 * @return the new {@code LongBinding} 6692 * @throws NullPointerException if the {@code ObservableList} is {@code null} 6693 * @throws IllegalArgumentException if (@code index < 0) 6694 * @since JavaFX 2.1 6695 */ 6696 public static LongBinding longValueAt(final ObservableList<? extends Number> op, final int index) { 6697 if (op == null) { 6698 throw new NullPointerException("List cannot be null."); 6699 } 6700 if (index < 0) { 6701 throw new IllegalArgumentException("Index cannot be negative"); 6702 } 6703 6704 return new LongBinding() { 6705 { 6706 super.bind(op); 6707 } 6708 6709 @Override 6710 public void dispose() { 6711 super.unbind(op); 6712 } 6713 6714 @Override 6715 protected long computeValue() { 6716 try { 6717 final Number value = op.get(index); 6718 if (value == null) { 6719 Logging.getLogger().fine("List element is null, returning default value instead.", new NullPointerException()); 6720 } else { 6721 return value.longValue(); 6722 } 6723 } catch (IndexOutOfBoundsException ex) { 6724 Logging.getLogger().fine("Exception while evaluating binding", ex); 6725 } 6726 return 0L; 6727 } 6728 6729 @Override 6730 public ObservableList<?> getDependencies() { 6731 return FXCollections.singletonObservableList(op); 6732 } 6733 }; 6734 } 6735 6736 /** 6737 * Creates a new {@link javafx.beans.binding.LongBinding} that contains the element 6738 * of an {@link javafx.collections.ObservableList} at the specified position. The {@code LongBinding} 6739 * will hold {@code 0L}, if the {@code index} is outside of the {@code ObservableList}. 6740 * 6741 * @param op the {@code ObservableList} 6742 * @param index the position in the {@code List} 6743 * @return the new {@code LongBinding} 6744 * @throws NullPointerException if the {@code ObservableList} or {@code index} is {@code null} 6745 * @since JavaFX 2.1 6746 */ 6747 public static LongBinding longValueAt(final ObservableList<? extends Number> op, final ObservableIntegerValue index) { 6748 return longValueAt(op, (ObservableNumberValue)index); 6749 } 6750 6751 /** 6752 * Creates a new {@link javafx.beans.binding.LongBinding} that contains the element 6753 * of an {@link javafx.collections.ObservableList} at the specified position. The {@code LongBinding} 6754 * will hold {@code 0L}, if the {@code index} is outside of the {@code ObservableList}. 6755 * 6756 * @param op the {@code ObservableList} 6757 * @param index the position in the {@code List}, converted to int 6758 * @return the new {@code LongBinding} 6759 * @throws NullPointerException if the {@code ObservableList} or {@code index} is {@code null} 6760 * @since JavaFX 8.0 6761 */ 6762 public static LongBinding longValueAt(final ObservableList<? extends Number> op, final ObservableNumberValue index) { 6763 if ((op == null) || (index == null)) { 6764 throw new NullPointerException("Operands cannot be null."); 6765 } 6766 6767 return new LongBinding() { 6768 { 6769 super.bind(op, index); 6770 } 6771 6772 @Override 6773 public void dispose() { 6774 super.unbind(op, index); 6775 } 6776 6777 @Override 6778 protected long computeValue() { 6779 try { 6780 final Number value = op.get(index.intValue()); 6781 if (value == null) { 6782 Logging.getLogger().fine("List element is null, returning default value instead.", new NullPointerException()); 6783 } else { 6784 return value.longValue(); 6785 } 6786 } catch (IndexOutOfBoundsException ex) { 6787 Logging.getLogger().fine("Exception while evaluating binding", ex); 6788 } 6789 return 0L; 6790 } 6791 6792 @Override 6793 public ObservableList<?> getDependencies() { 6794 return new ImmutableObservableList<Observable>(op, index); 6795 } 6796 }; 6797 } 6798 6799 /** 6800 * Creates a new {@link javafx.beans.binding.StringBinding} that contains the element 6801 * of an {@link javafx.collections.ObservableList} at the specified position. The {@code StringBinding} 6802 * will hold {@code null}, if the {@code index} points behind the {@code ObservableList}. 6803 * 6804 * @param op the {@code ObservableList} 6805 * @param index the position in the {@code List} 6806 * @return the new {@code StringBinding} 6807 * @throws NullPointerException if the {@code ObservableList} is {@code null} 6808 * @throws IllegalArgumentException if (@code index < 0) 6809 * @since JavaFX 2.1 6810 */ 6811 public static StringBinding stringValueAt(final ObservableList<String> op, final int index) { 6812 if (op == null) { 6813 throw new NullPointerException("List cannot be null."); 6814 } 6815 if (index < 0) { 6816 throw new IllegalArgumentException("Index cannot be negative"); 6817 } 6818 6819 return new StringBinding() { 6820 { 6821 super.bind(op); 6822 } 6823 6824 @Override 6825 public void dispose() { 6826 super.unbind(op); 6827 } 6828 6829 @Override 6830 protected String computeValue() { 6831 try { 6832 return op.get(index); 6833 } catch (IndexOutOfBoundsException ex) { 6834 Logging.getLogger().fine("Exception while evaluating binding", ex); 6835 } 6836 return null; 6837 } 6838 6839 @Override 6840 public ObservableList<?> getDependencies() { 6841 return FXCollections.singletonObservableList(op); 6842 } 6843 }; 6844 } 6845 6846 /** 6847 * Creates a new {@link javafx.beans.binding.StringBinding} that contains the element 6848 * of an {@link javafx.collections.ObservableList} at the specified position. The {@code StringBinding} 6849 * will hold {@code ""}, if the {@code index} is outside of the {@code ObservableList}. 6850 * 6851 * @param op the {@code ObservableList} 6852 * @param index the position in the {@code List} 6853 * @return the new {@code StringBinding} 6854 * @throws NullPointerException if the {@code ObservableList} or {@code index} is {@code null} 6855 * @since JavaFX 2.1 6856 */ 6857 public static StringBinding stringValueAt(final ObservableList<String> op, final ObservableIntegerValue index) { 6858 return stringValueAt(op, (ObservableNumberValue)index); 6859 } 6860 6861 /** 6862 * Creates a new {@link javafx.beans.binding.StringBinding} that contains the element 6863 * of an {@link javafx.collections.ObservableList} at the specified position. The {@code StringBinding} 6864 * will hold {@code ""}, if the {@code index} is outside of the {@code ObservableList}. 6865 * 6866 * @param op the {@code ObservableList} 6867 * @param index the position in the {@code List}, converted to int 6868 * @return the new {@code StringBinding} 6869 * @throws NullPointerException if the {@code ObservableList} or {@code index} is {@code null} 6870 * @since JavaFX 8.0 6871 */ 6872 public static StringBinding stringValueAt(final ObservableList<String> op, final ObservableNumberValue index) { 6873 if ((op == null) || (index == null)) { 6874 throw new NullPointerException("Operands cannot be null."); 6875 } 6876 6877 return new StringBinding() { 6878 { 6879 super.bind(op, index); 6880 } 6881 6882 @Override 6883 public void dispose() { 6884 super.unbind(op, index); 6885 } 6886 6887 @Override 6888 protected String computeValue() { 6889 try { 6890 return op.get(index.intValue()); 6891 } catch (IndexOutOfBoundsException ex) { 6892 Logging.getLogger().fine("Exception while evaluating binding", ex); 6893 } 6894 return null; 6895 } 6896 6897 @Override 6898 public ObservableList<?> getDependencies() { 6899 return new ImmutableObservableList<Observable>(op, index); 6900 } 6901 }; 6902 } 6903 6904 // Set 6905 // ================================================================================================================= 6906 6907 /** 6908 * Creates a new {@link javafx.beans.binding.IntegerBinding} that contains the size 6909 * of an {@link javafx.collections.ObservableSet}. 6910 * 6911 * @param op 6912 * the {@code ObservableSet} 6913 * @param <E> the type of the {@code Set} elements 6914 * @return the new {@code IntegerBinding} 6915 * @throws NullPointerException 6916 * if the {@code ObservableSet} is {@code null} 6917 * @since JavaFX 2.1 6918 */ 6919 public static <E> IntegerBinding size(final ObservableSet<E> op) { 6920 if (op == null) { 6921 throw new NullPointerException("Set cannot be null."); 6922 } 6923 6924 return new IntegerBinding() { 6925 { 6926 super.bind(op); 6927 } 6928 6929 @Override 6930 public void dispose() { 6931 super.unbind(op); 6932 } 6933 6934 @Override 6935 protected int computeValue() { 6936 return op.size(); 6937 } 6938 6939 @Override 6940 public ObservableList<?> getDependencies() { 6941 return FXCollections.singletonObservableList(op); 6942 } 6943 }; 6944 } 6945 6946 /** 6947 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 6948 * if a given {@link javafx.collections.ObservableSet} is empty. 6949 * 6950 * @param op 6951 * the {@code ObservableSet} 6952 * @param <E> the type of the {@code Set} elements 6953 * @return the new {@code BooleanBinding} 6954 * @throws NullPointerException 6955 * if the {@code ObservableSet} is {@code null} 6956 * @since JavaFX 2.1 6957 */ 6958 public static <E> BooleanBinding isEmpty(final ObservableSet<E> op) { 6959 if (op == null) { 6960 throw new NullPointerException("Set cannot be null."); 6961 } 6962 6963 return new BooleanBinding() { 6964 { 6965 super.bind(op); 6966 } 6967 6968 @Override 6969 public void dispose() { 6970 super.unbind(op); 6971 } 6972 6973 @Override 6974 protected boolean computeValue() { 6975 return op.isEmpty(); 6976 } 6977 6978 @Override 6979 public ObservableList<?> getDependencies() { 6980 return FXCollections.singletonObservableList(op); 6981 } 6982 }; 6983 } 6984 6985 /** 6986 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 6987 * if a given {@link javafx.collections.ObservableSet} is not empty. 6988 * 6989 * @param op 6990 * the {@code ObservableSet} 6991 * @param <E> the type of the {@code Set} elements 6992 * @return the new {@code BooleanBinding} 6993 * @throws NullPointerException 6994 * if the {@code ObservableSet} is {@code null} 6995 * @since JavaFX 8.0 6996 */ 6997 public static <E> BooleanBinding isNotEmpty(final ObservableSet<E> op) { 6998 if (op == null) { 6999 throw new NullPointerException("List cannot be null."); 7000 } 7001 7002 return new BooleanBinding() { 7003 { 7004 super.bind(op); 7005 } 7006 7007 @Override 7008 public void dispose() { 7009 super.unbind(op); 7010 } 7011 7012 @Override 7013 protected boolean computeValue() { 7014 return !op.isEmpty(); 7015 } 7016 7017 @Override 7018 public ObservableList<?> getDependencies() { 7019 return FXCollections.singletonObservableList(op); 7020 } 7021 }; 7022 } 7023 7024 // Array 7025 // ================================================================================================================= 7026 7027 /** 7028 * Creates a new {@link javafx.beans.binding.IntegerBinding} that contains the size 7029 * of an {@link javafx.collections.ObservableArray}. 7030 * 7031 * @param op the {@code ObservableArray} 7032 * @return the new {@code IntegerBinding} 7033 * @throws NullPointerException 7034 * if the {@code ObservableArray} is {@code null} 7035 * @since JavaFX 8.0 7036 */ 7037 public static IntegerBinding size(final ObservableArray op) { 7038 if (op == null) { 7039 throw new NullPointerException("Array cannot be null."); 7040 } 7041 7042 return new IntegerBinding() { 7043 { 7044 super.bind(op); 7045 } 7046 7047 @Override 7048 public void dispose() { 7049 super.unbind(op); 7050 } 7051 7052 @Override 7053 protected int computeValue() { 7054 return op.size(); 7055 } 7056 7057 @Override 7058 public ObservableList<?> getDependencies() { 7059 return FXCollections.singletonObservableList(op); 7060 } 7061 }; 7062 } 7063 7064 /** 7065 * Creates a new {@link javafx.beans.binding.FloatBinding} that contains the element 7066 * of an {@link javafx.collections.ObservableArray} at the specified position. The {@code FloatBinding} 7067 * will hold {@code 0.0f}, if the {@code index} points behind the {@code ObservableArray}. 7068 * 7069 * @param op the {@code ObservableArray} 7070 * @param index the position in the {@code ObservableArray} 7071 * @return the new {@code FloatBinding} 7072 * @throws NullPointerException if the {@code ObservableArray} is {@code null} 7073 * @throws IllegalArgumentException if (@code index < 0) 7074 * @since JavaFX 8.0 7075 */ 7076 public static FloatBinding floatValueAt(final ObservableFloatArray op, final int index) { 7077 if (op == null) { 7078 throw new NullPointerException("Array cannot be null."); 7079 } 7080 if (index < 0) { 7081 throw new IllegalArgumentException("Index cannot be negative"); 7082 } 7083 7084 return new FloatBinding() { 7085 { 7086 super.bind(op); 7087 } 7088 7089 @Override 7090 public void dispose() { 7091 super.unbind(op); 7092 } 7093 7094 @Override 7095 protected float computeValue() { 7096 try { 7097 return op.get(index); 7098 } catch (IndexOutOfBoundsException ex) { 7099 Logging.getLogger().fine("Exception while evaluating binding", ex); 7100 } 7101 return 0.0f; 7102 } 7103 7104 @Override 7105 public ObservableList<?> getDependencies() { 7106 return FXCollections.singletonObservableList(op); 7107 } 7108 }; 7109 } 7110 7111 /** 7112 * Creates a new {@link javafx.beans.binding.FloatBinding} that contains the element 7113 * of an {@link javafx.collections.ObservableArray} at the specified position. The {@code FloatBinding} 7114 * will hold {@code 0.0f}, if the {@code index} is outside of the {@code ObservableArray}. 7115 * 7116 * @param op the {@code ObservableArray} 7117 * @param index the position in the {@code ObservableArray} 7118 * @return the new {@code FloatBinding} 7119 * @throws NullPointerException if the {@code ObservableArray} or {@code index} is {@code null} 7120 * @since JavaFX 8.0 7121 */ 7122 public static FloatBinding floatValueAt(final ObservableFloatArray op, final ObservableIntegerValue index) { 7123 return floatValueAt(op, (ObservableNumberValue)index); 7124 } 7125 7126 /** 7127 * Creates a new {@link javafx.beans.binding.FloatBinding} that contains the element 7128 * of an {@link javafx.collections.ObservableArray} at the specified position. The {@code FloatBinding} 7129 * will hold {@code 0.0f}, if the {@code index} is outside of the {@code ObservableArray}. 7130 * 7131 * @param op the {@code ObservableArray} 7132 * @param index the position in the {@code ObservableArray}, converted to int 7133 * @return the new {@code FloatBinding} 7134 * @throws NullPointerException if the {@code ObservableArray} or {@code index} is {@code null} 7135 * @since JavaFX 8.0 7136 */ 7137 public static FloatBinding floatValueAt(final ObservableFloatArray op, final ObservableNumberValue index) { 7138 if ((op == null) || (index == null)) { 7139 throw new NullPointerException("Operands cannot be null."); 7140 } 7141 7142 return new FloatBinding() { 7143 { 7144 super.bind(op, index); 7145 } 7146 7147 @Override 7148 public void dispose() { 7149 super.unbind(op, index); 7150 } 7151 7152 @Override 7153 protected float computeValue() { 7154 try { 7155 return op.get(index.intValue()); 7156 } catch (IndexOutOfBoundsException ex) { 7157 Logging.getLogger().fine("Exception while evaluating binding", ex); 7158 } 7159 return 0.0f; 7160 } 7161 7162 @Override 7163 public ObservableList<?> getDependencies() { 7164 return new ImmutableObservableList<>(op, index); 7165 } 7166 }; 7167 } 7168 7169 /** 7170 * Creates a new {@link javafx.beans.binding.IntegerBinding} that contains the element 7171 * of an {@link javafx.collections.ObservableArray} at the specified position. The {@code IntegerBinding} 7172 * will hold {@code 0}, if the {@code index} points behind the {@code ObservableArray}. 7173 * 7174 * @param op the {@code ObservableArray} 7175 * @param index the position in the {@code ObservableArray} 7176 * @return the new {@code IntegerBinding} 7177 * @throws NullPointerException if the {@code ObservableArray} is {@code null} 7178 * @throws IllegalArgumentException if (@code index < 0) 7179 * @since JavaFX 8.0 7180 */ 7181 public static IntegerBinding integerValueAt(final ObservableIntegerArray op, final int index) { 7182 if (op == null) { 7183 throw new NullPointerException("Array cannot be null."); 7184 } 7185 if (index < 0) { 7186 throw new IllegalArgumentException("Index cannot be negative"); 7187 } 7188 7189 return new IntegerBinding() { 7190 { 7191 super.bind(op); 7192 } 7193 7194 @Override 7195 public void dispose() { 7196 super.unbind(op); 7197 } 7198 7199 @Override 7200 protected int computeValue() { 7201 try { 7202 return op.get(index); 7203 } catch (IndexOutOfBoundsException ex) { 7204 Logging.getLogger().fine("Exception while evaluating binding", ex); 7205 } 7206 return 0; 7207 } 7208 7209 @Override 7210 public ObservableList<?> getDependencies() { 7211 return FXCollections.singletonObservableList(op); 7212 } 7213 }; 7214 } 7215 7216 /** 7217 * Creates a new {@link javafx.beans.binding.IntegerBinding} that contains the element 7218 * of an {@link javafx.collections.ObservableArray} at the specified position. The {@code IntegerBinding} 7219 * will hold {@code 0}, if the {@code index} is outside of the {@code ObservableArray}. 7220 * 7221 * @param op the {@code ObservableArray} 7222 * @param index the position in the {@code ObservableArray} 7223 * @return the new {@code IntegerBinding} 7224 * @throws NullPointerException if the {@code ObservableArray} or {@code index} is {@code null} 7225 * @since JavaFX 8.0 7226 */ 7227 public static IntegerBinding integerValueAt(final ObservableIntegerArray op, final ObservableIntegerValue index) { 7228 return integerValueAt(op, (ObservableNumberValue)index); 7229 } 7230 7231 /** 7232 * Creates a new {@link javafx.beans.binding.IntegerBinding} that contains the element 7233 * of an {@link javafx.collections.ObservableArray} at the specified position. The {@code IntegerBinding} 7234 * will hold {@code 0}, if the {@code index} is outside of the {@code ObservableArray}. 7235 * 7236 * @param op the {@code ObservableArray} 7237 * @param index the position in the {@code ObservableArray}, converted to int 7238 * @return the new {@code IntegerBinding} 7239 * @throws NullPointerException if the {@code ObservableArray} or {@code index} is {@code null} 7240 * @since JavaFX 8.0 7241 */ 7242 public static IntegerBinding integerValueAt(final ObservableIntegerArray op, final ObservableNumberValue index) { 7243 if ((op == null) || (index == null)) { 7244 throw new NullPointerException("Operands cannot be null."); 7245 } 7246 7247 return new IntegerBinding() { 7248 { 7249 super.bind(op, index); 7250 } 7251 7252 @Override 7253 public void dispose() { 7254 super.unbind(op, index); 7255 } 7256 7257 @Override 7258 protected int computeValue() { 7259 try { 7260 return op.get(index.intValue()); 7261 } catch (IndexOutOfBoundsException ex) { 7262 Logging.getLogger().fine("Exception while evaluating binding", ex); 7263 } 7264 return 0; 7265 } 7266 7267 @Override 7268 public ObservableList<?> getDependencies() { 7269 return new ImmutableObservableList<>(op, index); 7270 } 7271 }; 7272 } 7273 7274 // Map 7275 // ================================================================================================================= 7276 7277 /** 7278 * Creates a new {@link javafx.beans.binding.IntegerBinding} that contains the size 7279 * of an {@link javafx.collections.ObservableMap}. 7280 * 7281 * @param op 7282 * the {@code ObservableMap} 7283 * @param <K> type of the key elements of the {@code Map} 7284 * @param <V> type of the value elements of the {@code Map} 7285 * @return the new {@code IntegerBinding} 7286 * @throws NullPointerException 7287 * if the {@code ObservableMap} is {@code null} 7288 * 7289 * @since JavaFX 2.1 7290 */ 7291 public static <K, V> IntegerBinding size(final ObservableMap<K, V> op) { 7292 if (op == null) { 7293 throw new NullPointerException("Map cannot be null."); 7294 } 7295 7296 return new IntegerBinding() { 7297 { 7298 super.bind(op); 7299 } 7300 7301 @Override 7302 public void dispose() { 7303 super.unbind(op); 7304 } 7305 7306 @Override 7307 protected int computeValue() { 7308 return op.size(); 7309 } 7310 7311 @Override 7312 public ObservableList<?> getDependencies() { 7313 return FXCollections.singletonObservableList(op); 7314 } 7315 }; 7316 } 7317 7318 /** 7319 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 7320 * if a given {@link javafx.collections.ObservableMap} is empty. 7321 * 7322 * @param op 7323 * the {@code ObservableMap} 7324 * @param <K> type of the key elements of the {@code Map} 7325 * @param <V> type of the value elements of the {@code Map} 7326 * @return the new {@code BooleanBinding} 7327 * @throws NullPointerException 7328 * if the {@code ObservableMap} is {@code null} 7329 * @since JavaFX 2.1 7330 */ 7331 public static <K, V> BooleanBinding isEmpty(final ObservableMap<K, V> op) { 7332 if (op == null) { 7333 throw new NullPointerException("Map cannot be null."); 7334 } 7335 7336 return new BooleanBinding() { 7337 { 7338 super.bind(op); 7339 } 7340 7341 @Override 7342 public void dispose() { 7343 super.unbind(op); 7344 } 7345 7346 @Override 7347 protected boolean computeValue() { 7348 return op.isEmpty(); 7349 } 7350 7351 @Override 7352 public ObservableList<?> getDependencies() { 7353 return FXCollections.singletonObservableList(op); 7354 } 7355 }; 7356 } 7357 7358 /** 7359 * Creates a new {@link javafx.beans.binding.BooleanBinding} that holds {@code true} 7360 * if a given {@link javafx.collections.ObservableMap} is not empty. 7361 * 7362 * @param op 7363 * the {@code ObservableMap} 7364 * @param <K> type of the key elements of the {@code Map} 7365 * @param <V> type of the value elements of the {@code Map} 7366 * @return the new {@code BooleanBinding} 7367 * @throws NullPointerException 7368 * if the {@code ObservableMap} is {@code null} 7369 * @since JavaFX 8.0 7370 */ 7371 public static <K, V> BooleanBinding isNotEmpty(final ObservableMap<K, V> op) { 7372 if (op == null) { 7373 throw new NullPointerException("List cannot be null."); 7374 } 7375 7376 return new BooleanBinding() { 7377 { 7378 super.bind(op); 7379 } 7380 7381 @Override 7382 public void dispose() { 7383 super.unbind(op); 7384 } 7385 7386 @Override 7387 protected boolean computeValue() { 7388 return !op.isEmpty(); 7389 } 7390 7391 @Override 7392 public ObservableList<?> getDependencies() { 7393 return FXCollections.singletonObservableList(op); 7394 } 7395 }; 7396 } 7397 7398 /** 7399 * Creates a new {@link javafx.beans.binding.ObjectBinding} that contains the mapping of a specific key 7400 * in an {@link javafx.collections.ObservableMap}. 7401 * 7402 * @param op the {@code ObservableMap} 7403 * @param key the key in the {@code Map} 7404 * @param <K> type of the key elements of the {@code Map} 7405 * @param <V> type of the value elements of the {@code Map} 7406 * @return the new {@code ObjectBinding} 7407 * @throws NullPointerException if the {@code ObservableMap} is {@code null} 7408 * @since JavaFX 2.1 7409 */ 7410 public static <K, V> ObjectBinding<V> valueAt(final ObservableMap<K, V> op, final K key) { 7411 if (op == null) { 7412 throw new NullPointerException("Map cannot be null."); 7413 } 7414 7415 return new ObjectBinding<V>() { 7416 { 7417 super.bind(op); 7418 } 7419 7420 @Override 7421 public void dispose() { 7422 super.unbind(op); 7423 } 7424 7425 @Override 7426 protected V computeValue() { 7427 try { 7428 return op.get(key); 7429 } catch (ClassCastException ex) { 7430 Logging.getLogger().warning("Exception while evaluating binding", ex); 7431 // ignore 7432 } catch (NullPointerException ex) { 7433 Logging.getLogger().warning("Exception while evaluating binding", ex); 7434 // ignore 7435 } 7436 return null; 7437 } 7438 7439 @Override 7440 public ObservableList<?> getDependencies() { 7441 return FXCollections.singletonObservableList(op); 7442 } 7443 }; 7444 } 7445 7446 /** 7447 * Creates a new {@link javafx.beans.binding.ObjectBinding} that contains the mapping of a specific key 7448 * in an {@link javafx.collections.ObservableMap}. 7449 * 7450 * @param op the {@code ObservableMap} 7451 * @param key the key in the {@code Map} 7452 * @param <K> type of the key elements of the {@code Map} 7453 * @param <V> type of the value elements of the {@code Map} 7454 * @return the new {@code ObjectBinding} 7455 * @throws NullPointerException if the {@code ObservableMap} or {@code key} is {@code null} 7456 * @since JavaFX 2.1 7457 */ 7458 public static <K, V> ObjectBinding<V> valueAt(final ObservableMap<K, V> op, final ObservableValue<? extends K> key) { 7459 if ((op == null) || (key == null)) { 7460 throw new NullPointerException("Operands cannot be null."); 7461 } 7462 7463 return new ObjectBinding<V>() { 7464 { 7465 super.bind(op, key); 7466 } 7467 7468 @Override 7469 public void dispose() { 7470 super.unbind(op); 7471 } 7472 7473 @Override 7474 protected V computeValue() { 7475 try { 7476 return op.get(key.getValue()); 7477 } catch (ClassCastException ex) { 7478 Logging.getLogger().warning("Exception while evaluating binding", ex); 7479 // ignore 7480 } catch (NullPointerException ex) { 7481 Logging.getLogger().warning("Exception while evaluating binding", ex); 7482 // ignore 7483 } 7484 return null; 7485 } 7486 7487 @Override 7488 public ObservableList<?> getDependencies() { 7489 return new ImmutableObservableList<Observable>(op, key); 7490 } 7491 }; 7492 } 7493 7494 /** 7495 * Creates a new {@link javafx.beans.binding.BooleanBinding} that contains the mapping of a specific key 7496 * in an {@link javafx.collections.ObservableMap}. The {@code BooleanBinding} 7497 * will hold {@code false}, if the {@code key} cannot be found in the {@code ObservableMap}. 7498 * 7499 * @param op the {@code ObservableMap} 7500 * @param key the key in the {@code Map} 7501 * @param <K> type of the key elements of the {@code Map} 7502 * @return the new {@code BooleanBinding} 7503 * @throws NullPointerException if the {@code ObservableMap} is {@code null} 7504 * @since JavaFX 2.1 7505 */ 7506 public static <K> BooleanBinding booleanValueAt(final ObservableMap<K, Boolean> op, final K key) { 7507 if (op == null) { 7508 throw new NullPointerException("Map cannot be null."); 7509 } 7510 7511 return new BooleanBinding() { 7512 { 7513 super.bind(op); 7514 } 7515 7516 @Override 7517 public void dispose() { 7518 super.unbind(op); 7519 } 7520 7521 @Override 7522 protected boolean computeValue() { 7523 try { 7524 final Boolean value = op.get(key); 7525 if (value == null) { 7526 Logging.getLogger().fine("Element not found in map, returning default value instead.", new NullPointerException()); 7527 } else { 7528 return value; 7529 } 7530 } catch (ClassCastException ex) { 7531 Logging.getLogger().warning("Exception while evaluating binding", ex); 7532 // ignore 7533 } catch (NullPointerException ex) { 7534 Logging.getLogger().warning("Exception while evaluating binding", ex); 7535 // ignore 7536 } 7537 return false; 7538 } 7539 7540 @Override 7541 public ObservableList<?> getDependencies() { 7542 return FXCollections.singletonObservableList(op); 7543 } 7544 }; 7545 } 7546 7547 /** 7548 * Creates a new {@link javafx.beans.binding.BooleanBinding} that contains the mapping of a specific key 7549 * in an {@link javafx.collections.ObservableMap}. The {@code BooleanBinding} 7550 * will hold {@code false}, if the {@code key} cannot be found in the {@code ObservableMap}. 7551 * 7552 * @param op the {@code ObservableMap} 7553 * @param key the key in the {@code Map} 7554 * @param <K> type of the key elements of the {@code Map} 7555 * @return the new {@code BooleanBinding} 7556 * @throws NullPointerException if the {@code ObservableMap} or {@code key} is {@code null} 7557 * @since JavaFX 2.1 7558 */ 7559 public static <K> BooleanBinding booleanValueAt(final ObservableMap<K, Boolean> op, final ObservableValue<? extends K> key) { 7560 if ((op == null) || (key == null)) { 7561 throw new NullPointerException("Operands cannot be null."); 7562 } 7563 7564 return new BooleanBinding() { 7565 { 7566 super.bind(op, key); 7567 } 7568 7569 @Override 7570 public void dispose() { 7571 super.unbind(op, key); 7572 } 7573 7574 @Override 7575 protected boolean computeValue() { 7576 try { 7577 final Boolean value = op.get(key.getValue()); 7578 if (value == null) { 7579 Logging.getLogger().fine("Element not found in map, returning default value instead.", new NullPointerException()); 7580 } else { 7581 return value; 7582 } 7583 } catch (ClassCastException ex) { 7584 Logging.getLogger().warning("Exception while evaluating binding", ex); 7585 // ignore 7586 } catch (NullPointerException ex) { 7587 Logging.getLogger().warning("Exception while evaluating binding", ex); 7588 // ignore 7589 } 7590 return false; 7591 } 7592 7593 @Override 7594 public ObservableList<?> getDependencies() { 7595 return new ImmutableObservableList<Observable>(op, key); 7596 } 7597 }; 7598 } 7599 7600 /** 7601 * Creates a new {@link javafx.beans.binding.DoubleBinding} that contains the mapping of a specific key 7602 * in an {@link javafx.collections.ObservableMap}. The {@code DoubleBinding} 7603 * will hold {@code 0.0}, if the {@code key} cannot be found in the {@code ObservableMap}. 7604 * 7605 * @param op the {@code ObservableMap} 7606 * @param key the key in the {@code Map} 7607 * @param <K> type of the key elements of the {@code Map} 7608 * @return the new {@code DoubleBinding} 7609 * @throws NullPointerException if the {@code ObservableMap} is {@code null} 7610 * @since JavaFX 2.1 7611 */ 7612 public static <K> DoubleBinding doubleValueAt(final ObservableMap<K, ? extends Number> op, final K key) { 7613 if (op == null) { 7614 throw new NullPointerException("Map cannot be null."); 7615 } 7616 7617 return new DoubleBinding() { 7618 { 7619 super.bind(op); 7620 } 7621 7622 @Override 7623 public void dispose() { 7624 super.unbind(op); 7625 } 7626 7627 @Override 7628 protected double computeValue() { 7629 try { 7630 final Number value = op.get(key); 7631 if (value == null) { 7632 Logging.getLogger().fine("Element not found in map, returning default value instead.", new NullPointerException()); 7633 } else { 7634 return value.doubleValue(); 7635 } 7636 } catch (ClassCastException ex) { 7637 Logging.getLogger().warning("Exception while evaluating binding", ex); 7638 // ignore 7639 } catch (NullPointerException ex) { 7640 Logging.getLogger().warning("Exception while evaluating binding", ex); 7641 // ignore 7642 } 7643 return 0.0; 7644 } 7645 7646 @Override 7647 public ObservableList<?> getDependencies() { 7648 return FXCollections.singletonObservableList(op); 7649 } 7650 }; 7651 } 7652 7653 /** 7654 * Creates a new {@link javafx.beans.binding.DoubleBinding} that contains the mapping of a specific key 7655 * in an {@link javafx.collections.ObservableMap}. The {@code DoubleBinding} 7656 * will hold {@code 0.0}, if the {@code key} cannot be found in the {@code ObservableMap}. 7657 * 7658 * @param op the {@code ObservableMap} 7659 * @param key the key in the {@code Map} 7660 * @param <K> type of the key elements of the {@code Map} 7661 * @return the new {@code DoubleBinding} 7662 * @throws NullPointerException if the {@code ObservableMap} or {@code key} is {@code null} 7663 * @since JavaFX 2.1 7664 */ 7665 public static <K> DoubleBinding doubleValueAt(final ObservableMap<K, ? extends Number> op, final ObservableValue<? extends K> key) { 7666 if ((op == null) || (key == null)) { 7667 throw new NullPointerException("Operands cannot be null."); 7668 } 7669 7670 return new DoubleBinding() { 7671 { 7672 super.bind(op, key); 7673 } 7674 7675 @Override 7676 public void dispose() { 7677 super.unbind(op, key); 7678 } 7679 7680 @Override 7681 protected double computeValue() { 7682 try { 7683 final Number value = op.get(key.getValue()); 7684 if (value == null) { 7685 Logging.getLogger().fine("Element not found in map, returning default value instead.", new NullPointerException()); 7686 } else { 7687 return value.doubleValue(); 7688 } 7689 } catch (ClassCastException ex) { 7690 Logging.getLogger().warning("Exception while evaluating binding", ex); 7691 // ignore 7692 } catch (NullPointerException ex) { 7693 Logging.getLogger().warning("Exception while evaluating binding", ex); 7694 // ignore 7695 } 7696 return 0.0; 7697 } 7698 7699 @Override 7700 public ObservableList<?> getDependencies() { 7701 return new ImmutableObservableList<Observable>(op, key); 7702 } 7703 }; 7704 } 7705 7706 /** 7707 * Creates a new {@link javafx.beans.binding.FloatBinding} that contains the mapping of a specific key 7708 * in an {@link javafx.collections.ObservableMap}. The {@code FloatBinding} 7709 * will hold {@code 0.0f}, if the {@code key} cannot be found in the {@code ObservableMap}. 7710 * 7711 * @param op the {@code ObservableMap} 7712 * @param key the key in the {@code Map} 7713 * @param <K> type of the key elements of the {@code Map} 7714 * @return the new {@code FloatBinding} 7715 * @throws NullPointerException if the {@code ObservableMap} is {@code null} 7716 * @since JavaFX 2.1 7717 */ 7718 public static <K> FloatBinding floatValueAt(final ObservableMap<K, ? extends Number> op, final K key) { 7719 if (op == null) { 7720 throw new NullPointerException("Map cannot be null."); 7721 } 7722 7723 return new FloatBinding() { 7724 { 7725 super.bind(op); 7726 } 7727 7728 @Override 7729 public void dispose() { 7730 super.unbind(op); 7731 } 7732 7733 @Override 7734 protected float computeValue() { 7735 try { 7736 final Number value = op.get(key); 7737 if (value == null) { 7738 Logging.getLogger().fine("Element not found in map, returning default value instead.", new NullPointerException()); 7739 } else { 7740 return value.floatValue(); 7741 } 7742 } catch (ClassCastException ex) { 7743 Logging.getLogger().warning("Exception while evaluating binding", ex); 7744 // ignore 7745 } catch (NullPointerException ex) { 7746 Logging.getLogger().warning("Exception while evaluating binding", ex); 7747 // ignore 7748 } 7749 return 0.0f; 7750 } 7751 7752 @Override 7753 public ObservableList<?> getDependencies() { 7754 return FXCollections.singletonObservableList(op); 7755 } 7756 }; 7757 } 7758 7759 /** 7760 * Creates a new {@link javafx.beans.binding.FloatBinding} that contains the mapping of a specific key 7761 * in an {@link javafx.collections.ObservableMap}. The {@code FloatBinding} 7762 * will hold {@code 0.0f}, if the {@code key} cannot be found in the {@code ObservableMap}. 7763 * 7764 * @param op the {@code ObservableMap} 7765 * @param key the key in the {@code Map} 7766 * @param <K> type of the key elements of the {@code Map} 7767 * @return the new {@code FloatBinding} 7768 * @throws NullPointerException if the {@code ObservableMap} or {@code key} is {@code null} 7769 * @since JavaFX 2.1 7770 */ 7771 public static <K> FloatBinding floatValueAt(final ObservableMap<K, ? extends Number> op, final ObservableValue<? extends K> key) { 7772 if ((op == null) || (key == null)) { 7773 throw new NullPointerException("Operands cannot be null."); 7774 } 7775 7776 return new FloatBinding() { 7777 { 7778 super.bind(op, key); 7779 } 7780 7781 @Override 7782 public void dispose() { 7783 super.unbind(op, key); 7784 } 7785 7786 @Override 7787 protected float computeValue() { 7788 try { 7789 final Number value = op.get(key.getValue()); 7790 if (value == null) { 7791 Logging.getLogger().fine("Element not found in map, returning default value instead.", new NullPointerException()); 7792 } else { 7793 return value.floatValue(); 7794 } 7795 } catch (ClassCastException ex) { 7796 Logging.getLogger().warning("Exception while evaluating binding", ex); 7797 // ignore 7798 } catch (NullPointerException ex) { 7799 Logging.getLogger().warning("Exception while evaluating binding", ex); 7800 // ignore 7801 } 7802 return 0.0f; 7803 } 7804 7805 @Override 7806 public ObservableList<?> getDependencies() { 7807 return new ImmutableObservableList<Observable>(op, key); 7808 } 7809 }; 7810 } 7811 7812 /** 7813 * Creates a new {@link javafx.beans.binding.IntegerBinding} that contains the mapping of a specific key 7814 * in an {@link javafx.collections.ObservableMap}. The {@code IntegerBinding} 7815 * will hold {@code 0}, if the {@code key} cannot be found in the {@code ObservableMap}. 7816 * 7817 * @param op the {@code ObservableMap} 7818 * @param key the key in the {@code Map} 7819 * @param <K> type of the key elements of the {@code Map} 7820 * @return the new {@code IntegerBinding} 7821 * @throws NullPointerException if the {@code ObservableMap} is {@code null} 7822 * @since JavaFX 2.1 7823 */ 7824 public static <K> IntegerBinding integerValueAt(final ObservableMap<K, ? extends Number> op, final K key) { 7825 if (op == null) { 7826 throw new NullPointerException("Map cannot be null."); 7827 } 7828 7829 return new IntegerBinding() { 7830 { 7831 super.bind(op); 7832 } 7833 7834 @Override 7835 public void dispose() { 7836 super.unbind(op); 7837 } 7838 7839 @Override 7840 protected int computeValue() { 7841 try { 7842 final Number value = op.get(key); 7843 if (value == null) { 7844 Logging.getLogger().fine("Element not found in map, returning default value instead.", new NullPointerException()); 7845 } else { 7846 return value.intValue(); 7847 } 7848 } catch (ClassCastException ex) { 7849 Logging.getLogger().warning("Exception while evaluating binding", ex); 7850 // ignore 7851 } catch (NullPointerException ex) { 7852 Logging.getLogger().warning("Exception while evaluating binding", ex); 7853 // ignore 7854 } 7855 return 0; 7856 } 7857 7858 @Override 7859 public ObservableList<?> getDependencies() { 7860 return FXCollections.singletonObservableList(op); 7861 } 7862 }; 7863 } 7864 7865 /** 7866 * Creates a new {@link javafx.beans.binding.IntegerBinding} that contains the mapping of a specific key 7867 * in an {@link javafx.collections.ObservableMap}. The {@code IntegerBinding} 7868 * will hold {@code 0}, if the {@code key} cannot be found in the {@code ObservableMap}. 7869 * 7870 * @param op the {@code ObservableMap} 7871 * @param key the key in the {@code Map} 7872 * @param <K> type of the key elements of the {@code Map} 7873 * @return the new {@code IntegerBinding} 7874 * @throws NullPointerException if the {@code ObservableMap} or {@code key} is {@code null} 7875 * @since JavaFX 2.1 7876 */ 7877 public static <K> IntegerBinding integerValueAt(final ObservableMap<K, ? extends Number> op, final ObservableValue<? extends K> key) { 7878 if ((op == null) || (key == null)) { 7879 throw new NullPointerException("Operands cannot be null."); 7880 } 7881 7882 return new IntegerBinding() { 7883 { 7884 super.bind(op, key); 7885 } 7886 7887 @Override 7888 public void dispose() { 7889 super.unbind(op, key); 7890 } 7891 7892 @Override 7893 protected int computeValue() { 7894 try { 7895 final Number value = op.get(key.getValue()); 7896 if (value == null) { 7897 Logging.getLogger().fine("Element not found in map, returning default value instead.", new NullPointerException()); 7898 } else { 7899 return value.intValue(); 7900 } 7901 } catch (ClassCastException ex) { 7902 Logging.getLogger().warning("Exception while evaluating binding", ex); 7903 // ignore 7904 } catch (NullPointerException ex) { 7905 Logging.getLogger().warning("Exception while evaluating binding", ex); 7906 // ignore 7907 } 7908 return 0; 7909 } 7910 7911 @Override 7912 public ObservableList<?> getDependencies() { 7913 return new ImmutableObservableList<Observable>(op, key); 7914 } 7915 }; 7916 } 7917 7918 /** 7919 * Creates a new {@link javafx.beans.binding.LongBinding} that contains the mapping of a specific key 7920 * in an {@link javafx.collections.ObservableMap}. The {@code LongBinding} 7921 * will hold {@code 0L}, if the {@code key} cannot be found in the {@code ObservableMap}. 7922 * 7923 * @param op the {@code ObservableMap} 7924 * @param key the key in the {@code Map} 7925 * @param <K> type of the key elements of the {@code Map} 7926 * @return the new {@code LongBinding} 7927 * @throws NullPointerException if the {@code ObservableMap} is {@code null} 7928 * @since JavaFX 2.1 7929 */ 7930 public static <K> LongBinding longValueAt(final ObservableMap<K, ? extends Number> op, final K key) { 7931 if (op == null) { 7932 throw new NullPointerException("Map cannot be null."); 7933 } 7934 7935 return new LongBinding() { 7936 { 7937 super.bind(op); 7938 } 7939 7940 @Override 7941 public void dispose() { 7942 super.unbind(op); 7943 } 7944 7945 @Override 7946 protected long computeValue() { 7947 try { 7948 final Number value = op.get(key); 7949 if (value == null) { 7950 Logging.getLogger().fine("Element not found in map, returning default value instead.", new NullPointerException()); 7951 } else { 7952 return value.longValue(); 7953 } 7954 } catch (ClassCastException ex) { 7955 Logging.getLogger().warning("Exception while evaluating binding", ex); 7956 // ignore 7957 } catch (NullPointerException ex) { 7958 Logging.getLogger().warning("Exception while evaluating binding", ex); 7959 // ignore 7960 } 7961 return 0L; 7962 } 7963 7964 @Override 7965 public ObservableList<?> getDependencies() { 7966 return FXCollections.singletonObservableList(op); 7967 } 7968 }; 7969 } 7970 7971 /** 7972 * Creates a new {@link javafx.beans.binding.LongBinding} that contains the mapping of a specific key 7973 * in an {@link javafx.collections.ObservableMap}. The {@code LongBinding} 7974 * will hold {@code 0L}, if the {@code key} cannot be found in the {@code ObservableMap}. 7975 * 7976 * @param op the {@code ObservableMap} 7977 * @param key the key in the {@code Map} 7978 * @param <K> type of the key elements of the {@code Map} 7979 * @return the new {@code LongBinding} 7980 * @throws NullPointerException if the {@code ObservableMap} or {@code key} is {@code null} 7981 * @since JavaFX 2.1 7982 */ 7983 public static <K> LongBinding longValueAt(final ObservableMap<K, ? extends Number> op, final ObservableValue<? extends K> key) { 7984 if ((op == null) || (key == null)) { 7985 throw new NullPointerException("Operands cannot be null."); 7986 } 7987 7988 return new LongBinding() { 7989 { 7990 super.bind(op, key); 7991 } 7992 7993 @Override 7994 public void dispose() { 7995 super.unbind(op, key); 7996 } 7997 7998 @Override 7999 protected long computeValue() { 8000 try { 8001 final Number value = op.get(key.getValue()); 8002 if (value == null) { 8003 Logging.getLogger().fine("Element not found in map, returning default value instead.", new NullPointerException()); 8004 } else { 8005 return value.longValue(); 8006 } 8007 } catch (ClassCastException ex) { 8008 Logging.getLogger().warning("Exception while evaluating binding", ex); 8009 // ignore 8010 } catch (NullPointerException ex) { 8011 Logging.getLogger().warning("Exception while evaluating binding", ex); 8012 // ignore 8013 } 8014 return 0L; 8015 } 8016 8017 @Override 8018 public ObservableList<?> getDependencies() { 8019 return new ImmutableObservableList<Observable>(op, key); 8020 } 8021 }; 8022 } 8023 8024 /** 8025 * Creates a new {@link javafx.beans.binding.StringBinding} that contains the mapping of a specific key 8026 * in an {@link javafx.collections.ObservableMap}. The {@code StringBinding} 8027 * will hold {@code null}, if the {@code key} cannot be found in the {@code ObservableMap}. 8028 * 8029 * @param op the {@code ObservableMap} 8030 * @param key the key in the {@code Map} 8031 * @param <K> type of the key elements of the {@code Map} 8032 * @return the new {@code StringBinding} 8033 * @throws NullPointerException if the {@code ObservableMap} is {@code null} 8034 * @since JavaFX 2.1 8035 */ 8036 public static <K> StringBinding stringValueAt(final ObservableMap<K, String> op, final K key) { 8037 if (op == null) { 8038 throw new NullPointerException("Map cannot be null."); 8039 } 8040 8041 return new StringBinding() { 8042 { 8043 super.bind(op); 8044 } 8045 8046 @Override 8047 public void dispose() { 8048 super.unbind(op); 8049 } 8050 8051 @Override 8052 protected String computeValue() { 8053 try { 8054 return op.get(key); 8055 } catch (ClassCastException ex) { 8056 Logging.getLogger().warning("Exception while evaluating binding", ex); 8057 // ignore 8058 } catch (NullPointerException ex) { 8059 Logging.getLogger().warning("Exception while evaluating binding", ex); 8060 // ignore 8061 } 8062 return null; 8063 } 8064 8065 @Override 8066 public ObservableList<?> getDependencies() { 8067 return FXCollections.singletonObservableList(op); 8068 } 8069 }; 8070 } 8071 8072 /** 8073 * Creates a new {@link javafx.beans.binding.StringBinding} that contains the mapping of a specific key 8074 * in an {@link javafx.collections.ObservableMap}. The {@code StringBinding} 8075 * will hold {@code ""}, if the {@code key} cannot be found in the {@code ObservableMap}. 8076 * 8077 * @param op the {@code ObservableMap} 8078 * @param key the key in the {@code Map} 8079 * @param <K> type of the key elements of the {@code Map} 8080 * @return the new {@code StringBinding} 8081 * @throws NullPointerException if the {@code ObservableMap} or {@code key} is {@code null} 8082 * @since JavaFX 2.1 8083 */ 8084 public static <K> StringBinding stringValueAt(final ObservableMap<K, String> op, final ObservableValue<? extends K> key) { 8085 if ((op == null) || (key == null)) { 8086 throw new NullPointerException("Operands cannot be null."); 8087 } 8088 8089 return new StringBinding() { 8090 { 8091 super.bind(op, key); 8092 } 8093 8094 @Override 8095 public void dispose() { 8096 super.unbind(op, key); 8097 } 8098 8099 @Override 8100 protected String computeValue() { 8101 try { 8102 return op.get(key.getValue()); 8103 } catch (ClassCastException ex) { 8104 Logging.getLogger().warning("Exception while evaluating binding", ex); 8105 // ignore 8106 } catch (NullPointerException ex) { 8107 Logging.getLogger().warning("Exception while evaluating binding", ex); 8108 // ignore 8109 } 8110 return null; 8111 } 8112 8113 @Override 8114 public ObservableList<?> getDependencies() { 8115 return new ImmutableObservableList<Observable>(op, key); 8116 } 8117 }; 8118 } 8119 8120 8121 }