JavaFXでコントローラー同士を参照する

やってみればなんてことはないんですが。
Controllerから別のControllerの処理を呼びたいのだけどどうすればいいかわからなかった。
自分的な答えは、コントローラー自身を他のコントローラーに渡しておく、ということでした。

ただ、コントローラーが他のコントローラーを持っておくには、ルールがあるようです。

http://stackoverflow.com/questions/14790785/subcontroller-not-being-injected-into-main-controller

ここによると、FXMLで、includeタグのfx:idに付けた値 + Controllerという名前のコントローラーじゃないとクラスが初期化時に保持してくれないです。
ここが重要のようなので、ミスしないようにしましょう。

<?xml version="1.0" encoding="UTF-8"?>
<VBox xmlns:fx="http://javafx.com/fxml"
      fx:controller="com.example.Controller">
  <children>
    <fx:include fx:id="menuBar" source="menu_bar.fxml"/>
    <TableView fx:id="table">
      <columns>
        <TableColumn text="No." fx:id="idColumn" />
        <TableColumn text="名前" fx:id="nameColumn" />
        <TableColumn text="E-mail" fx:id="emailColumn" />
      </columns>
    </TableView>
    <!-- 略 -->
  </children>
</VBox>

次に、includeするmenu_bar.fxml。
MenuBarControllerのhogeメソッドに紐づいてます。

<?xml version="1.0" encoding="UTF-8"?>
<MenuBar
    xmlns:fx="http://javafx.com/fxml"
    fx:controller="com.example.MenuBarController">
    <menus>
        <Menu mnemonicParsing="false" text="ファイル">
            <items>
                <MenuItem onAction="#hoge" mnemonicParsing="false" text="hoge" />
            </items>
        </Menu>
    </menus>
</MenuBar>

次に、プロパティ(Javaのメンバ変数)にMenuBarControllerを持つControllerのコード。
ただし、コードはKotlinです。

class Controller : Initializable {
  // FXMLはJavaのアノテーション@FXMLと同じ意味
  FXML private var menuBarController : MenuBarController? = null
  val hoge = "hoge"

  public override fun initialize(p0: URL?, p1: ResourceBundle?) {
    // 初期化の際に自身を渡しておく
    menuBarController!!.controller = this
  }
}

最後に、MenuBarController。Controllerクラスのプロパティhogeにアクセスさせてます。

class MenuBarController(){
  var controller : Controller by Delegates.notNull()
  FXML fun hoge(event: ActionEvent) {
    println(controller.hoge)
  }
}

相互にコントローラーを参照しているので、お互いのメソッドを呼び合うことができます。
あまりにコントローラーで参照しあうと複雑になりそうですが、2階層程度ならなんとかなりそうですね。


カテゴリー Java, Kotlin | タグ   | パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です