1

I want to make JavaFX spinner with 3 decimal places as a double value, so I just made Spinner like this:

Spinner<Double> spinner = new Spinner<Double>();
SpinnerValueFactory<Double> valueFactory =
    new SpinnerValueFactory.DoubleSpinnerValueFactory(0, 512, 51.197, 1);
spinner.setValueFactory(valueFactory);
spinner.setEditable(true);

I just made spinner with initial value as 51.197, but when I run this code, initial value is 51.2; and when I edit spinner as 52.666, I can't use this value. I think that the decimal place is problem. I want to use value form as ###.###. How can I handle JavaFX Spinner decimal place?

fabian
  • 80,457
  • 12
  • 86
  • 114
HyungjinJeon
  • 143
  • 11
  • 1
    Try setting the [`converter`](https://openjfx.io/javadoc/12/javafx.controls/javafx/scene/control/SpinnerValueFactory.html#converterProperty) to a [`NumberStringConverter`](https://openjfx.io/javadoc/12/javafx.base/javafx/util/converter/NumberStringConverter.html) with the appropriate pattern. – Slaw May 07 '19 at 19:34
  • @Slaw Thank you. I did what i want using StringConverter :) – HyungjinJeon May 07 '19 at 20:35
  • The documentation says that the default double factory is ##. ##. So you'll need to add your own as slaw mentioned. I think you also need the constructor to be (0, 512, 51.197, 0.001) – kendavidson May 07 '19 at 20:35
  • @HyungjinJeon if you solved your question you should post it as an answer and accept it so if others find this post they know how to fix their problem – Matt May 07 '19 at 20:43

1 Answers1

3

I solved this problem with StringConverter.

StringConverter<Double> doubleConverter = new StringConverter<Double>() {
private final DecimalFormat df = new DecimalFormat("###.###");
@Override
public String toString(Double object) {
    if (object == null) {return "";}
    return df.format(object);}
@Override
public Double fromString(String string) {
    try {
        if (string == null) {return null;}
        string = string.trim();
        if (string.length() < 1) {return null;}     
        return df.parse(string).doubleValue();
    } catch (ParseException ex) {throw new RuntimeException(ex);}
    }
};

Spinner<Double> spinner = new Spinner<Double>();
SpinnerValueFactory<Double> valueFactory = new SpinnerValueFactory.DoubleSpinnerValueFactory(0, 512, 51.197, 1);
spinner.setValueFactory(valueFactory);
spinner.setEditable(true);

SpinnerValueFactory.setConverter(doubleConverter);

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
HyungjinJeon
  • 143
  • 11
  • A related example is examined [here](https://stackoverflow.com/q/55427306/230513). – trashgod May 08 '19 at 00:43
  • 3
    Note you could use `new NumberStringConverter("###.###")` instead of implementing your own. – Slaw May 08 '19 at 05:26
  • 1
    @Slaw might be being stupid, but this throws a compilation error for me, `incompatible types: javafx.util.converter.NumberStringConverter cannot be converted to javafx.util.StringConverter`. Does this work with `SpinnerValueFactory`? – Dan Sep 03 '20 at 09:52
  • 1
    @Dan Ah, you're right. Sometimes I really dislike how they designed the generics in JavaFX. You might be able to create a workaround with `ListSpinnerValueFactory` but it honestly may be easier to just do what HyungjinJeon does in their answer and ignore my comment. – Slaw Sep 03 '20 at 13:45
  • @Slaw Thanks for the quick response :) Shame you can't use it like that – Dan Sep 03 '20 at 14:06