1

I'm coding a little test application that uses the Canvas class in Scala with scalafx. The problem is with:

gui.canvas.handleEvent(MouseEvent.MouseClicked){
     a: MouseEvent => {
          println("Mouse pos:" + a.sceneX+ "  " + a.sceneY)
     }      
}

Throwing the error:

[error] E:\dev\sg\src\main\scala\Test.scala:27: type mismatch;
[error]  found   : scalafx.scene.input.MouseEvent => Unit
[error]  required: _2.HandlerMagnet[javafx.scene.input.MouseEvent,?] 
where val _2: scalafx.scene.canvas.Canvas
[error]       a: MouseEvent => {
[error]                     ^

I don't get why this exact same snippet compiles when it appears in the method setupGraphics but NOT in when it's in the Main object's code.

BTW, having browsed quite a bit of ScalaFX code, I'm getting a bit dizzy because I've seen lots different ways to bind to an event, there's the one I'm using, setting the onMouseClicked variable (with and without a first class function), using filterEvent. Also, for each you can use an anonymous function or create an event handler object.

Of all those, this is the only one that worked in this example; trying to create an EventHandler[MouseEvent] and override handle() also fails in this case.

I'm using Scala 2.10.5

Full Source:

object Test {
  import scalafx.Includes._
  import scalafx.application.JFXApp
  import scalafx.application.JFXApp.PrimaryStage
  import scalafx.stage.Stage

  import scalafx.scene.Scene
  import scalafx.scene.canvas.Canvas
  import scalafx.scene.canvas.GraphicsContext

  import scalafx.scene.input.MouseEvent
  import scalafx.event.EventHandler



  class GUI(val canvas:Canvas
    ,val stage: Stage
    ,val gc: GraphicsContext){}

  object Main extends JFXApp {

    var gui=setupGraphics()

    gui.canvas.handleEvent(MouseEvent.MouseClicked){
      a: MouseEvent => {
        println("Mouse pos:" + a.sceneX+ "  " + a.sceneY)
      }
    }

    def setupGraphics():GUI={
      val canvas = new Canvas(400, 400)
      canvas.translateX=0
      canvas.translateY=0
      val gc = canvas.graphicsContext2D

      canvas.handleEvent(MouseEvent.MouseClicked){
        a: MouseEvent => {
          println("Mouse pos:" + a.sceneX+ "  " + a.sceneY)
        }
      }

      stage = new PrimaryStage {
        title = "asd"
        height = 600
        width = 800
        scene=new Scene{content=canvas}
      }

      return new GUI(canvas,stage,gc)
    }    
  }    
}
Community
  • 1
  • 1
Pepe Mandioca
  • 334
  • 2
  • 10

1 Answers1

1

This looks to me like a bug in Scala compiler, especially that you can correct this by using an intermediate variable for canvas without modifying anything else. Instead of calling gui.canvas.handleEvent, first assign canvas to a variable then call handleEvent on that:

var gui=setupGraphics()
val canvas = gui.canvas
canvas.handleEvent(MouseEvent.MouseClicked){
  a: MouseEvent => {
    println("Mouse pos:" + a.sceneX+ "  " + a.sceneY)
  }
}
Jarek
  • 1,513
  • 9
  • 16
  • That's great Jarek! Although I don't think it's a bug in the compiler. I guess I'm not grokking the type system enough and it's a subtle type-related bug. – Pepe Mandioca Sep 29 '15 at 15:37