タツノオトシゴのブログ

主にJavaに関するものです。

JavaFXのControllerの書式について

アノテーション「@FXML」とカプセル化について

アノテーション「@FXML」は、マッピング対象のクラス属性がpublic以外の場合に指定します。
そのため、publicにしておけば、アノテーションは必要ありませんが、カプセル化の観点からお勧めしません。
また、FXMLと関連付いているかどうか明示的に示すためにもアノテーションを用いた方が可読性が上がると思います。

  • 継承をしないControllerであれば、属性/メソッドも含めてprivateで定義すべきです。
  • 継承をする可能性のある、自身がコンポ―ネント(Paneなどを継承して作成した場合)は、protectedで定義した方が良いともいます。
public class CustomControl extends VBox {
    @FXML
    private TextField textField;

    public CustomControl() {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(
"custom_control.fxml"));
        fxmlLoader.setRoot(this);
        fxmlLoader.setController(this);

        try {
            fxmlLoader.load();
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }
    }

    public String getText() {
        return textProperty().get();
    }

    public void setText(String value) {
        textProperty().set(value);
    }
	
	// Observableが実装されているそれぞれのControlのプロパティを取得できるようにする
    public StringProperty textProperty() {
        return textField.textProperty();
    }

    @FXML
    protected void doSomething() {
        System.out.println("The button was clicked!");
    }
}

初期化について

初期化メソッドは、2通りの方法があります。

方法(1)インタフェース「javafx.fxml.Initializable」を実装する。
  • resourceBundleは、FXMLLoader#setResource();で設定した値が渡される。
    • テキストの国際化に使用できる。
import javafx.fxml.Initializable;

public class SampleController implements Initializable {
    
    @Override
    public void initialize(final URL location, final ResourceBundle resources) {
        System.out.println("init");
    }
}
方法(2)メソッド「@FXML initialize()」を設定する
  • メソッド「initialize()」を作成し、アノテーション@FXMLを付与する。
  • ResourceBundleなどが必要ならば、フィールドResourceBundleに対して、アノテーション@FXMLを付与する。
public class SampleController {
    
    @FXML
    private ResourceBundle resources;

    @FXML
    private URL location;

    @FXML
    void initialize() {
        System.out.println("init");

    }
}

関連付けられたNodeのインスタンスについて

Controllerの中で、自身に関連付いているSceneやPaneなどのインスタンスが必要な場合がある。
そのようなときは、FXMLのルート要素を「fx:id=""」を指定し、@FXMLで自身をインジェクションすればよい。

<AnchorPane id="samplePane" fx:id="samplePane" xmlns:fx="http://javafx.com/fxml" fx:controller="sample.gui.SamplePaneController">
・・・(省略)・・・
</AnchorPane>
public class SampleController {
    @FXML
    private AnchorPane samplePane;
}

Scene BuilderからのControllerのスケルトン作成について

Scene BuilderでFXMLを作成後に、Controllerを作成すると思うが、属性の変数名などを間違えると不良のもととなる。
そのため、Controllerのスケルトンのソースを生成してくれる機能がある。

  1. FMXLをScene Builderで開く。
  2. メニュー「表示」-「サンプル・コントローラ・スケルトンの表示」をクリックする。
  3. ダイアログが表示されその中にソースコードが表示される。
    • fx:idを記述している場合、フィールドが自動生成される。