メモの日々


2014年01月05日(日) [長年日記]

[java] JavaFXでイベントハンドリング

JavaFX 2で始めるGUI開発 第2回 シーングラフとFXMLを読んだ。コントローラクラスでGUIからのイベントを受け取る方法が説明されていたので試す。

FXML

掛算を行う画面を作ってみた。画面とそのFXMLは次の通り。

画面イメージ

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>

<AnchorPane id="AnchorPane" prefHeight="200.0" prefWidth="300.0"
	    xmlns:fx="http://javafx.com/fxml/1"
	    xmlns="http://javafx.com/javafx/2.2"
	    fx:controller="hello.HelloController">
  <children>
    <HBox alignment="CENTER" spacing="10.0"
	  AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
	  AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
      <children>
        <TextField fx:id="leftField" onKeyReleased="#handleKey" prefWidth="50.0" />
        <Label text="×" />
        <TextField fx:id="rightField" onKeyReleased="#handleKey" prefWidth="50.0" />
        <Label text="=" />
        <Label fx:id="resultLabel" text="" />
      </children>
    </HBox>
  </children>
</AnchorPane>
  • xmlnsのURLが前回と違うのは、Scene Builderがこう書き換えてしまうから。
  • ルート要素のAnchorPaneタグのfx:controller属性でコントローラとするクラスの名前を指定している。
  • コントロールを横一列に並べるのにHBoxを使ってみた。
  • 入力を受け付けるTextFieldタグと結果出力用のLabelタグのfx:id属性でそれぞれのフィールドに名前を付けている。
  • TextFiledタグのonKeyReleased属性で、キーボードのキーが離されたイベントを処理するコントローラクラスのメソッド名を指定している。

コントローラクラス

FXMLで指定したコントローラクラスのコードは次の通り。

package hello;

import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyEvent;

public class HelloController {
    @FXML
    private TextField leftField;

    @FXML
    private TextField rightField;

    @FXML
    private Label resultLabel;

    @FXML
    public void handleKey(KeyEvent event) {
        try {
            double left = Double.parseDouble(leftField.getText());
            double right = Double.parseDouble(rightField.getText());
            resultLabel.setText(String.valueOf(left * right));
        } catch (NumberFormatException | NullPointerException ex) {
            resultLabel.setText("");
        }
    }
}
  • FXMLで名前を付けた要素それぞれに対し、同名のメンバ変数を用意している。@FXMLアノテーションを付けることで、FXMLで定義した要素のオブジェクトを自動的に参照するようになるみたい。
  • FXMLで指定したキーreleaseイベントのハンドラメソッドを用意している。これにも@FXMLアノテーションを付ける。メソッドの引数がKeyEventになるということはNode#onKeyReleasedの型から分かるのだと思う。

メインクラス

メインクラスは前回と同じでよい。以上で掛算画面が動作するようになった。