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