< prev index next >

modules/javafx.controls/src/main/java/javafx/scene/control/SpinnerValueFactory.java

Print this page




  56 
  57 /**
  58  * The SpinnerValueFactory is the model behind the JavaFX
  59  * {@link Spinner Spinner control} - without a value factory installed a
  60  * Spinner is unusable. It is the role of the value factory to handle almost all
  61  * aspects of the Spinner, including:
  62  *
  63  * <ul>
  64  *     <li>Representing the current state of the {@link javafx.scene.control.SpinnerValueFactory#valueProperty() value},</li>
  65  *     <li>{@link SpinnerValueFactory#increment(int) Incrementing}
  66  *         and {@link SpinnerValueFactory#decrement(int) decrementing} the
  67  *         value, with one or more steps per call,</li>
  68  *     <li>{@link javafx.scene.control.SpinnerValueFactory#converterProperty() Converting} text input
  69  *         from the user (via the Spinner {@link Spinner#editorProperty() editor},</li>
  70  *     <li>Converting {@link javafx.scene.control.SpinnerValueFactory#converterProperty() objects to user-readable strings}
  71  *         for display on screen</li>
  72  * </ul>
  73  *
  74  * <p>SpinnerValueFactory classes for some common types are provided with JavaFX, including:
  75  *
  76  * <br/>
  77  *
  78  * <ul>
  79  *     <li>{@link SpinnerValueFactory.IntegerSpinnerValueFactory}</li>
  80  *     <li>{@link SpinnerValueFactory.DoubleSpinnerValueFactory}</li>
  81  *     <li>{@link SpinnerValueFactory.ListSpinnerValueFactory}</li>
  82  * </ul>
  83  *
  84  * @param <T> The type of the data this value factory deals with, which must
  85  *            coincide with the type of the Spinner that the value factory is set on.
  86  * @see Spinner
  87  * @see SpinnerValueFactory.IntegerSpinnerValueFactory
  88  * @see SpinnerValueFactory.DoubleSpinnerValueFactory
  89  * @see SpinnerValueFactory.ListSpinnerValueFactory
  90  * @since JavaFX 8u40
  91  */
  92 public abstract class SpinnerValueFactory<T> {
  93 
  94     /***************************************************************************
  95      *                                                                         *
  96      * Private fields                                                          *
  97      *                                                                         *


 280                     newIndex = items.indexOf(newValue);
 281                 }
 282                 currentIndex = newIndex;
 283             });
 284             setValue(_getValue(currentIndex));
 285         }
 286 
 287 
 288 
 289         /***********************************************************************
 290          *                                                                     *
 291          * Properties                                                          *
 292          *                                                                     *
 293          **********************************************************************/
 294         // --- Items
 295         private ObjectProperty<ObservableList<T>> items;
 296 
 297         /**
 298          * Sets the underlying data model for the ListSpinnerValueFactory. Note that it has a generic
 299          * type that must match the type of the Spinner itself.

 300          */
 301         public final void setItems(ObservableList<T> value) {
 302             itemsProperty().set(value);
 303         }
 304 
 305         /**
 306          * Returns an {@link javafx.collections.ObservableList} that contains the items currently able
 307          * to be iterated through by the user. This may be null if
 308          * {@link #setItems(javafx.collections.ObservableList)} has previously been
 309          * called, however, by default it is an empty ObservableList.
 310          *
 311          * @return An ObservableList containing the items to be shown to the user, or
 312          *      null if the items have previously been set to null.
 313          */
 314         public final ObservableList<T> getItems() {
 315             return items == null ? null : items.get();
 316         }
 317 
 318         /**
 319          * The underlying data model for the ListView. Note that it has a generic
 320          * type that must match the type of the ListView itself.

 321          */
 322         public final ObjectProperty<ObservableList<T>> itemsProperty() {
 323             if (items == null) {
 324                 items = new SimpleObjectProperty<ObservableList<T>>(this, "items") {
 325                     WeakReference<ObservableList<T>> oldItemsRef;
 326 
 327                     @Override protected void invalidated() {
 328                         ObservableList<T> oldItems = oldItemsRef == null ? null : oldItemsRef.get();
 329                         ObservableList<T> newItems = getItems();
 330 
 331                         // update listeners
 332                         if (oldItems != null) {
 333                             oldItems.removeListener(weakItemsContentObserver);
 334                         }
 335                         if (newItems != null) {
 336                             newItems.addListener(weakItemsContentObserver);
 337                         }
 338 
 339                         // update the current value based on the index
 340                         updateCurrentIndex();


 492                 int newMin = get();
 493                 if (newMin > getMax()) {
 494                     setMin(getMax());
 495                     return;
 496                 }
 497 
 498                 if (currentValue < newMin) {
 499                     IntegerSpinnerValueFactory.this.setValue(newMin);
 500                 }
 501             }
 502         };
 503 
 504         public final void setMin(int value) {
 505             min.set(value);
 506         }
 507         public final int getMin() {
 508             return min.get();
 509         }
 510         /**
 511          * Sets the minimum allowable value for this value factory

 512          */
 513         public final IntegerProperty minProperty() {
 514             return min;
 515         }
 516 
 517         // --- max
 518         private IntegerProperty max = new SimpleIntegerProperty(this, "max") {
 519             @Override protected void invalidated() {
 520                 Integer currentValue = IntegerSpinnerValueFactory.this.getValue();
 521                 if (currentValue == null) {
 522                     return;
 523                 }
 524 
 525                 int newMax = get();
 526                 if (newMax < getMin()) {
 527                     setMax(getMin());
 528                     return;
 529                 }
 530 
 531                 if (currentValue > newMax) {
 532                     IntegerSpinnerValueFactory.this.setValue(newMax);
 533                 }
 534             }
 535         };
 536 
 537         public final void setMax(int value) {
 538             max.set(value);
 539         }
 540         public final int getMax() {
 541             return max.get();
 542         }
 543         /**
 544          * Sets the maximum allowable value for this value factory

 545          */
 546         public final IntegerProperty maxProperty() {
 547             return max;
 548         }
 549 
 550         // --- amountToStepBy
 551         private IntegerProperty amountToStepBy = new SimpleIntegerProperty(this, "amountToStepBy");
 552         public final void setAmountToStepBy(int value) {
 553             amountToStepBy.set(value);
 554         }
 555         public final int getAmountToStepBy() {
 556             return amountToStepBy.get();
 557         }
 558         /**
 559          * Sets the amount to increment or decrement by, per step.

 560          */
 561         public final IntegerProperty amountToStepByProperty() {
 562             return amountToStepBy;
 563         }
 564 
 565 
 566 
 567         /***********************************************************************
 568          *                                                                     *
 569          * Overridden methods                                                  *
 570          *                                                                     *
 571          **********************************************************************/
 572 
 573         /** {@inheritDoc} */
 574         @Override public void decrement(int steps) {
 575             final int min = getMin();
 576             final int max = getMax();
 577             final int newIndex = getValue() - steps * getAmountToStepBy();
 578             setValue(newIndex >= min ? newIndex : (isWrapAround() ? Spinner.wrapValue(newIndex, min, max) + 1 : min));
 579         }


 752                 final double newMin = get();
 753                 if (newMin > getMax()) {
 754                     setMin(getMax());
 755                     return;
 756                 }
 757 
 758                 if (currentValue < newMin) {
 759                     DoubleSpinnerValueFactory.this.setValue(newMin);
 760                 }
 761             }
 762         };
 763 
 764         public final void setMin(double value) {
 765             min.set(value);
 766         }
 767         public final double getMin() {
 768             return min.get();
 769         }
 770         /**
 771          * Sets the minimum allowable value for this value factory

 772          */
 773         public final DoubleProperty minProperty() {
 774             return min;
 775         }
 776 
 777         // --- max
 778         private DoubleProperty max = new SimpleDoubleProperty(this, "max") {
 779             @Override protected void invalidated() {
 780                 Double currentValue = DoubleSpinnerValueFactory.this.getValue();
 781                 if (currentValue == null) {
 782                     return;
 783                 }
 784 
 785                 final double newMax = get();
 786                 if (newMax < getMin()) {
 787                     setMax(getMin());
 788                     return;
 789                 }
 790 
 791                 if (currentValue > newMax) {
 792                     DoubleSpinnerValueFactory.this.setValue(newMax);
 793                 }
 794             }
 795         };
 796 
 797         public final void setMax(double value) {
 798             max.set(value);
 799         }
 800         public final double getMax() {
 801             return max.get();
 802         }
 803         /**
 804          * Sets the maximum allowable value for this value factory

 805          */
 806         public final DoubleProperty maxProperty() {
 807             return max;
 808         }
 809 
 810         // --- amountToStepBy
 811         private DoubleProperty amountToStepBy = new SimpleDoubleProperty(this, "amountToStepBy");
 812         public final void setAmountToStepBy(double value) {
 813             amountToStepBy.set(value);
 814         }
 815         public final double getAmountToStepBy() {
 816             return amountToStepBy.get();
 817         }
 818         /**
 819          * Sets the amount to increment or decrement by, per step.

 820          */
 821         public final DoubleProperty amountToStepByProperty() {
 822             return amountToStepBy;
 823         }
 824 
 825 
 826 
 827         /** {@inheritDoc} */
 828         @Override public void decrement(int steps) {
 829             final BigDecimal currentValue = BigDecimal.valueOf(getValue());
 830             final BigDecimal minBigDecimal = BigDecimal.valueOf(getMin());
 831             final BigDecimal maxBigDecimal = BigDecimal.valueOf(getMax());
 832             final BigDecimal amountToStepByBigDecimal = BigDecimal.valueOf(getAmountToStepBy());
 833             BigDecimal newValue = currentValue.subtract(amountToStepByBigDecimal.multiply(BigDecimal.valueOf(steps)));
 834             setValue(newValue.compareTo(minBigDecimal) >= 0 ? newValue.doubleValue() :
 835                     (isWrapAround() ? Spinner.wrapValue(newValue, minBigDecimal, maxBigDecimal).doubleValue() : getMin()));
 836         }
 837 
 838         /** {@inheritDoc} */
 839         @Override public void increment(int steps) {




  56 
  57 /**
  58  * The SpinnerValueFactory is the model behind the JavaFX
  59  * {@link Spinner Spinner control} - without a value factory installed a
  60  * Spinner is unusable. It is the role of the value factory to handle almost all
  61  * aspects of the Spinner, including:
  62  *
  63  * <ul>
  64  *     <li>Representing the current state of the {@link javafx.scene.control.SpinnerValueFactory#valueProperty() value},</li>
  65  *     <li>{@link SpinnerValueFactory#increment(int) Incrementing}
  66  *         and {@link SpinnerValueFactory#decrement(int) decrementing} the
  67  *         value, with one or more steps per call,</li>
  68  *     <li>{@link javafx.scene.control.SpinnerValueFactory#converterProperty() Converting} text input
  69  *         from the user (via the Spinner {@link Spinner#editorProperty() editor},</li>
  70  *     <li>Converting {@link javafx.scene.control.SpinnerValueFactory#converterProperty() objects to user-readable strings}
  71  *         for display on screen</li>
  72  * </ul>
  73  *
  74  * <p>SpinnerValueFactory classes for some common types are provided with JavaFX, including:
  75  *


  76  * <ul>
  77  *     <li>{@link SpinnerValueFactory.IntegerSpinnerValueFactory}</li>
  78  *     <li>{@link SpinnerValueFactory.DoubleSpinnerValueFactory}</li>
  79  *     <li>{@link SpinnerValueFactory.ListSpinnerValueFactory}</li>
  80  * </ul>
  81  *
  82  * @param <T> The type of the data this value factory deals with, which must
  83  *            coincide with the type of the Spinner that the value factory is set on.
  84  * @see Spinner
  85  * @see SpinnerValueFactory.IntegerSpinnerValueFactory
  86  * @see SpinnerValueFactory.DoubleSpinnerValueFactory
  87  * @see SpinnerValueFactory.ListSpinnerValueFactory
  88  * @since JavaFX 8u40
  89  */
  90 public abstract class SpinnerValueFactory<T> {
  91 
  92     /***************************************************************************
  93      *                                                                         *
  94      * Private fields                                                          *
  95      *                                                                         *


 278                     newIndex = items.indexOf(newValue);
 279                 }
 280                 currentIndex = newIndex;
 281             });
 282             setValue(_getValue(currentIndex));
 283         }
 284 
 285 
 286 
 287         /***********************************************************************
 288          *                                                                     *
 289          * Properties                                                          *
 290          *                                                                     *
 291          **********************************************************************/
 292         // --- Items
 293         private ObjectProperty<ObservableList<T>> items;
 294 
 295         /**
 296          * Sets the underlying data model for the ListSpinnerValueFactory. Note that it has a generic
 297          * type that must match the type of the Spinner itself.
 298          * @param value the list of items
 299          */
 300         public final void setItems(ObservableList<T> value) {
 301             itemsProperty().set(value);
 302         }
 303 
 304         /**
 305          * Returns an {@link javafx.collections.ObservableList} that contains the items currently able
 306          * to be iterated through by the user. This may be null if
 307          * {@link #setItems(javafx.collections.ObservableList)} has previously been
 308          * called, however, by default it is an empty ObservableList.
 309          *
 310          * @return An ObservableList containing the items to be shown to the user, or
 311          *      null if the items have previously been set to null.
 312          */
 313         public final ObservableList<T> getItems() {
 314             return items == null ? null : items.get();
 315         }
 316 
 317         /**
 318          * The underlying data model for the ListView. Note that it has a generic
 319          * type that must match the type of the ListView itself.
 320          * @return the list of items
 321          */
 322         public final ObjectProperty<ObservableList<T>> itemsProperty() {
 323             if (items == null) {
 324                 items = new SimpleObjectProperty<ObservableList<T>>(this, "items") {
 325                     WeakReference<ObservableList<T>> oldItemsRef;
 326 
 327                     @Override protected void invalidated() {
 328                         ObservableList<T> oldItems = oldItemsRef == null ? null : oldItemsRef.get();
 329                         ObservableList<T> newItems = getItems();
 330 
 331                         // update listeners
 332                         if (oldItems != null) {
 333                             oldItems.removeListener(weakItemsContentObserver);
 334                         }
 335                         if (newItems != null) {
 336                             newItems.addListener(weakItemsContentObserver);
 337                         }
 338 
 339                         // update the current value based on the index
 340                         updateCurrentIndex();


 492                 int newMin = get();
 493                 if (newMin > getMax()) {
 494                     setMin(getMax());
 495                     return;
 496                 }
 497 
 498                 if (currentValue < newMin) {
 499                     IntegerSpinnerValueFactory.this.setValue(newMin);
 500                 }
 501             }
 502         };
 503 
 504         public final void setMin(int value) {
 505             min.set(value);
 506         }
 507         public final int getMin() {
 508             return min.get();
 509         }
 510         /**
 511          * Sets the minimum allowable value for this value factory
 512          * @return the minimum allowable value for this value factory
 513          */
 514         public final IntegerProperty minProperty() {
 515             return min;
 516         }
 517 
 518         // --- max
 519         private IntegerProperty max = new SimpleIntegerProperty(this, "max") {
 520             @Override protected void invalidated() {
 521                 Integer currentValue = IntegerSpinnerValueFactory.this.getValue();
 522                 if (currentValue == null) {
 523                     return;
 524                 }
 525 
 526                 int newMax = get();
 527                 if (newMax < getMin()) {
 528                     setMax(getMin());
 529                     return;
 530                 }
 531 
 532                 if (currentValue > newMax) {
 533                     IntegerSpinnerValueFactory.this.setValue(newMax);
 534                 }
 535             }
 536         };
 537 
 538         public final void setMax(int value) {
 539             max.set(value);
 540         }
 541         public final int getMax() {
 542             return max.get();
 543         }
 544         /**
 545          * Sets the maximum allowable value for this value factory
 546          * @return the maximum allowable value for this value factory
 547          */
 548         public final IntegerProperty maxProperty() {
 549             return max;
 550         }
 551 
 552         // --- amountToStepBy
 553         private IntegerProperty amountToStepBy = new SimpleIntegerProperty(this, "amountToStepBy");
 554         public final void setAmountToStepBy(int value) {
 555             amountToStepBy.set(value);
 556         }
 557         public final int getAmountToStepBy() {
 558             return amountToStepBy.get();
 559         }
 560         /**
 561          * Sets the amount to increment or decrement by, per step.
 562          * @return the amount to increment or decrement by, per step
 563          */
 564         public final IntegerProperty amountToStepByProperty() {
 565             return amountToStepBy;
 566         }
 567 
 568 
 569 
 570         /***********************************************************************
 571          *                                                                     *
 572          * Overridden methods                                                  *
 573          *                                                                     *
 574          **********************************************************************/
 575 
 576         /** {@inheritDoc} */
 577         @Override public void decrement(int steps) {
 578             final int min = getMin();
 579             final int max = getMax();
 580             final int newIndex = getValue() - steps * getAmountToStepBy();
 581             setValue(newIndex >= min ? newIndex : (isWrapAround() ? Spinner.wrapValue(newIndex, min, max) + 1 : min));
 582         }


 755                 final double newMin = get();
 756                 if (newMin > getMax()) {
 757                     setMin(getMax());
 758                     return;
 759                 }
 760 
 761                 if (currentValue < newMin) {
 762                     DoubleSpinnerValueFactory.this.setValue(newMin);
 763                 }
 764             }
 765         };
 766 
 767         public final void setMin(double value) {
 768             min.set(value);
 769         }
 770         public final double getMin() {
 771             return min.get();
 772         }
 773         /**
 774          * Sets the minimum allowable value for this value factory
 775          * @return the minimum allowable value for this value factory
 776          */
 777         public final DoubleProperty minProperty() {
 778             return min;
 779         }
 780 
 781         // --- max
 782         private DoubleProperty max = new SimpleDoubleProperty(this, "max") {
 783             @Override protected void invalidated() {
 784                 Double currentValue = DoubleSpinnerValueFactory.this.getValue();
 785                 if (currentValue == null) {
 786                     return;
 787                 }
 788 
 789                 final double newMax = get();
 790                 if (newMax < getMin()) {
 791                     setMax(getMin());
 792                     return;
 793                 }
 794 
 795                 if (currentValue > newMax) {
 796                     DoubleSpinnerValueFactory.this.setValue(newMax);
 797                 }
 798             }
 799         };
 800 
 801         public final void setMax(double value) {
 802             max.set(value);
 803         }
 804         public final double getMax() {
 805             return max.get();
 806         }
 807         /**
 808          * Sets the maximum allowable value for this value factory
 809          * @return the maximum allowable value for this value factory
 810          */
 811         public final DoubleProperty maxProperty() {
 812             return max;
 813         }
 814 
 815         // --- amountToStepBy
 816         private DoubleProperty amountToStepBy = new SimpleDoubleProperty(this, "amountToStepBy");
 817         public final void setAmountToStepBy(double value) {
 818             amountToStepBy.set(value);
 819         }
 820         public final double getAmountToStepBy() {
 821             return amountToStepBy.get();
 822         }
 823         /**
 824          * Sets the amount to increment or decrement by, per step.
 825          * @return the amount to increment or decrement by, per step
 826          */
 827         public final DoubleProperty amountToStepByProperty() {
 828             return amountToStepBy;
 829         }
 830 
 831 
 832 
 833         /** {@inheritDoc} */
 834         @Override public void decrement(int steps) {
 835             final BigDecimal currentValue = BigDecimal.valueOf(getValue());
 836             final BigDecimal minBigDecimal = BigDecimal.valueOf(getMin());
 837             final BigDecimal maxBigDecimal = BigDecimal.valueOf(getMax());
 838             final BigDecimal amountToStepByBigDecimal = BigDecimal.valueOf(getAmountToStepBy());
 839             BigDecimal newValue = currentValue.subtract(amountToStepByBigDecimal.multiply(BigDecimal.valueOf(steps)));
 840             setValue(newValue.compareTo(minBigDecimal) >= 0 ? newValue.doubleValue() :
 841                     (isWrapAround() ? Spinner.wrapValue(newValue, minBigDecimal, maxBigDecimal).doubleValue() : getMin()));
 842         }
 843 
 844         /** {@inheritDoc} */
 845         @Override public void increment(int steps) {


< prev index next >