メモの日々


2014年02月08日(土) [長年日記]

  • ソチオリンピックが開幕した。
  • 関東地方は雪。20年ぶりの大雪とのこと。

[java] JavaFXのバインドを試す

JavaFX 2で始めるGUI開発 第6回 プロパティとバインドを読んだ。バインドは便利そう。

この前作った掛算画面がイベントハンドラではなくバインドを使っても実現できそうなので試してみた。コントローラクラスだけを書き換えて次のようにした。

package hello;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.DoubleBinding;
import javafx.beans.value.ObservableStringValue;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyEvent;

public class HelloController implements Initializable {
    @FXML
    private TextField leftField;

    @FXML
    private TextField rightField;

    @FXML
    private Label resultLabel;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        resultLabel.textProperty().bind(Bindings.multiply(
            new StringDoubleBinding(leftField.textProperty()),
            new StringDoubleBinding(rightField.textProperty())).asString());
    }

    @FXML
    public void handleKey(KeyEvent event) {}

    static class StringDoubleBinding extends DoubleBinding {
        private final ObservableStringValue source;

        public StringDoubleBinding(ObservableStringValue s) {
            super.bind(s);
            source = s;
        }

        @Override
        protected double computeValue() {
            try {
                return Double.parseDouble(source.getValue());
            } catch (NumberFormatException ex) {
                return 0;
            }
        }
    }
}
  • initialize()にてresultLabelにleftFieldとrightFieldの積をバインドしている。
  • 掛算をBindings.multiply()に任せたのだけれど、そうするにはStringPropertyObservableNumberValueに、NumberBindingObservableValue<? extends String>にそれぞれ変換する必要がある。後者はNumberBinding#asString()でできるけど、前者の変換方法が分からなかった。仕方ないのでDoubleBindingを拡張したStringDoubleBindingクラスを自前で用意した。
  • handleKey()は不要だけれど、以前のFXMLを使いまわしているので残している。

以前とは違い、テキストフィールドの値が数値でないときに結果が0と表示されてしまう。

本日のツッコミ(全1件) [ツッコミを入れる]
FX初心者 (2019年07月22日(月) 13:53)

まさしく、これがやりたくて探し回っていました。<br>もっと簡単に型変換できるAPIがあると思っていたのですが、見つからず自作の仕方を教えてもらえて助かりました。<br>ありがとうございました。