JavaFX Advent Calendar9日目の記事です。
8日目はHASUNUMA KenjiさんのJavaFX 8u40 のダイアログを探るでした。

  • StringConverterとは

Objectから文字列へ、文字列からObjectへ変換するためのものです。
javafx.util.converterパッケージにStringConverterのサブクラスが用意されています。

  • StringConverterって何に使うの

例えばスライダーの値をLabelのtextPropertyとバインドしたいとき、スライダーの値(double)からLabelのテキスト(String)に変換したい。
そんな時にStringConverterを使うと便利なんです!

  • 使ってみる

StringConverterを使ってバインドするためにはBindings#bindBidirectionalを使用します。
まずは基本的な使用方法として、第一引数にtextProperty、第二引数にバインドしたいProperty、第三引数に第二引数の型と同じStringConverterを使ってバインドしてみます。

//NumberStringConverterを使ってStringにConvertしてバインド
Bindings.bindBidirectional(sliderLabel.textProperty(), slider.valueProperty(), new NumberStringConverter());
//BooleanStringConverterで真偽値をStringにConvertしてバインド
Bindings.bindBidirectional(toggleButtonLabel.textProperty(), toggleButton.selectedProperty(), new BooleanStringConverter());

DatePickerのように、valueがLocalDateのようなjavafx.util.converterに用意されていない場合もあります。
一部のコントロールにはgetConverterメソッドでConverterを返してくれる場合があります。

//DatePickerが返すConverterを使ってバインド
Bindings.bindBidirectional(datePickerLabel.textProperty(), datePicker.valueProperty(), datePicker.getConverter());

上記2つに当てはまらない場合はStringConverterを自分で作成します。
textPropertyとColorPickerのvaluePropertyをバインドさせてみます。
StringConveerterの仮引数にはbindBidirectionalのvalueの型を指定します。
toString(T)ではTをどのような文字列で表示するかを処理します。
fromString(String)では文字列からTに変換する処理をします。

//独自にStringConverterを作る
        Bindings.bindBidirectional(colorPickerLabel.textProperty(), colorPicker.valueProperty(), new StringConverter<Color>() {
            //文字列への変換
            @Override
            public String toString(Color object) {
                double[] rgba = new double[]{object.getRed(), object.getGreen(), object.getBlue(), object.getOpacity()};
                return Arrays.stream(rgba)
                        .mapToObj(String::valueOf)
                        .collect(Collectors.joining(", "));
            }

            //Colorへの変換
            @Override
            public Color fromString(String string) {
                double[] color = Arrays.stream(string.split(", "))
                        .mapToDouble(Integer::parseInt)
                        .toArray();
                return new Color(color[0], color[1], color[2], color[3]);
            }
        });

無題

明日はtoruwestさんが面白い記事書いてくれると思います。