私はFXMLを初めて使用し、switch
を使用してすべてのボタンクリックのハンドラーを作成しようとしています。ただし、そのためには、idを使用して要素を取得する必要があります。私は以下を試しましたが、何らかの理由で(メインではなくコントローラークラスで実行しているためか)、スタックオーバーフロー例外が発生します。
public class ViewController {
public Button exitBtn;
public ViewController() throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("mainWindow.fxml"));
Scene scene = new Scene(root);
exitBtn = (Button) scene.lookup("#exitBtn");
}
}
それで、IDを参照として使用して要素(ボタンなど)を取得するにはどうすればよいですか?
ボタンのfxmlブロックは次のとおりです。
<Button fx:id="exitBtn" contentDisplay="CENTER" mnemonicParsing="false"
onAction="#handleButtonClick" text="Exit" HBox.hgrow="NEVER" HBox.margin="$x1"/>
ルックアップを使用する必要がないように、コントローラークラスを使用します。 FXMLLoader
は、フィールドをコントローラーに挿入します。インジェクションは、initialize()
メソッド(ある場合)が呼び出される前に発生することが保証されています
public class ViewController {
@FXML
private Button exitBtn ;
@FXML
private Button openBtn ;
public void initialize() {
// initialization here, if needed...
}
@FXML
private void handleButtonClick(ActionEvent event) {
// I really don't recommend using a single handler like this,
// but it will work
if (event.getSource() == exitBtn) {
exitBtn.getScene().getWindow().hide();
} else if (event.getSource() == openBtn) {
// do open action...
}
// etc...
}
}
FXMLのルート要素でコントローラークラスを指定します。
<!-- imports etc... -->
<SomePane xmlns="..." fx:controller="my.package.ViewController">
<!-- ... -->
<Button fx:id="exitBtn" contentDisplay="CENTER" mnemonicParsing="false" onAction="#handleButtonClick" text="Exit" HBox.hgrow="NEVER" HBox.margin="$x1" />
<Button fx:id="openBtn" contentDisplay="CENTER" mnemonicParsing="false" onAction="#handleButtonClick" text="Open" HBox.hgrow="NEVER" HBox.margin="$x1" />
</SomePane>
最後に、コントローラークラス以外のクラス(Application
クラスの場合もありますが、必ずしもそうではありません)からFXMLをロードします。
Parent root = FXMLLoader.load(getClass().getResource("path/to/fxml"));
Scene scene = new Scene(root);
// etc...