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