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