1

I have a ScalaFX App which contains a Stage with a Scene and a SubScene. All I want to achieve is to obtain a reference to the SubScene in another scope (a method to be precise) in order to change the content of the SubScene later on. My minimal working example (which isn't working...) looks like this:

object GuiTest extends JFXApp {

  def onClickByUser = {
    val subScene = stage.scene().lookup("sub").asInstanceOf[SubScene]
    println(subScene) // always null
  }

  stage = new PrimaryStage {
    scene = new Scene(900, 900, true, SceneAntialiasing.Balanced) {
      root = new BorderPane {
        center = createView
      }
    }
  }

  def createView = {
    new BorderPane {
      center = new SubScene(800, 800, true, SceneAntialiasing.Balanced) {
        id = "sub"
      }
    }
  }

}

In this simple case, I added the onClickByUser method which gets executed whenever the user clicks a button (button definition not shown above for simplicity) - but I always get null instead of the SubScene. Why is that? Any help is appreciated, thanks.

edit:

Okay, I forgot the pound sign ('#'):

val subScene = stage.scene().lookup("#sub").asInstanceOf[SubScene]

But now I'm getting this:

Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: javafx.scene.SubScene cannot be cast to scalafx.scene.SubScene

If I omit the asInstanceOf[SubScene], then it works, but then of course the returned value has the type Nodeinstead of SubScene.

edit2: It works like this:

val javaSubScene = stage.scene().lookup("#sub").asInstanceOf[javafx.scene.SubScene]
val subScene = new SubScene(javaSubScene)

But that is a bit ugly in my opinion, having to use the java classes and create new scala wrapper objects instead of just getting references to existing objects... any improvements are appreciated.

ceran
  • 1,392
  • 1
  • 17
  • 43

1 Answers1

1

Just use

 val subScene: scalafx.scene.SubSecne = 
             stage.scene().lookup("#sub").asInstanceOf[javafx.scene.SubScene]

You don't need to manually convert the java sub scene to the scalafx version because scala has implicits. To use the implicits defined in scalafx, you need to use the import import scalafx.Includes._

BTW This is how scalafx wrappers convert their properties. Example width

def width: scalafx.beans.property.ReadOnlyDoubleProperty = delegate.widthProperty
J Atkin
  • 3,080
  • 2
  • 19
  • 33