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()に任せたのだけれど、そうするにはStringPropertyをObservableNumberValueに、NumberBindingをObservableValue<? extends String>にそれぞれ変換する必要がある。後者はNumberBinding#asString()でできるけど、前者の変換方法が分からなかった。仕方ないのでDoubleBindingを拡張したStringDoubleBindingクラスを自前で用意した。
- handleKey()は不要だけれど、以前のFXMLを使いまわしているので残している。
以前とは違い、テキストフィールドの値が数値でないときに結果が0と表示されてしまう。
まさしく、これがやりたくて探し回っていました。<br>もっと簡単に型変換できるAPIがあると思っていたのですが、見つからず自作の仕方を教えてもらえて助かりました。<br>ありがとうございました。