vigoo / scalafxml

Bridging the gap between scalafx and FXML with generated proxies
94 stars 11 forks source link

Access FXMLLoader controller instance #17

Closed kammoh closed 8 years ago

kammoh commented 8 years ago

I'm trying to access the controller instance of a loaded FXML in scala but haven't found a way to do it. My code is sth like this:

@sfxml
class MyappController(var main: VBox) {
  def handleAbout() = {
    val loader = new FXMLLoader(getClass.getResource("/myapp/about.fxml"), NoDependencyResolver)
    val pane = loader.load[jfxsl.GridPane]
    val controller = loader.getController[AboutDialogController] // <<< ???? [Exception Line]
    val dialogStage = new Stage {
      scene = new Scene(pane)
    }
    ...
  }
}
@sfxml
class AboutDialogController(var pane: GridPane ) {
  ....

  def handleOk() = {
    println("Ok clicked")
  }
}

in the fxml file I have:

<GridPane  ... xmlns="http://javafx.com/javafx/8.0.60"
          xmlns:fx="http://javafx.com/fxml/1" fx:controller="sfxml.AboutDialogController"> ... </GridPane>

I get the following exception:

Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException ... Caused by: java.lang.ClassCastException: sfxml.AboutDialogController$Controller cannot be cast to sfxml.AboutDialogController at sfxml.MyappController$Controller.handleAbout(... [Exception Line]... ) at sfxml.MyappController.handleAbout(...)

vigoo commented 8 years ago

You can't refer to the original class because it is transformed. What you can do is to extract the interface you'd like to use to a trait, and use getController with that, like in the example: https://github.com/vigoo/scalafxml/blob/master/demo/src/main/scala/scalafxml/demo/getcontroller/GetControllerDemo.scala

kammoh commented 8 years ago

Thank's Daniel! I totally overlooked the macro magic which was going on there! Great work by the way!