Search code examples
scalascala-swing

Scala; Expression of type (X)=>X doesn't conform to type SupX


I'm a scala newbie who play with scala-swing. And want to translate a given scala.swing.Point on a scala.swing.event.MousEvent :

I would like to send mouse event to a class responsible to handle shapes selections. But because a shape has a location relative to his container (sheet) but MouseEvent.point is relative to the window I should translate/relativize it before.

So, I have a Selection class who receive MouseEvents :

case class Selection(sheet:Sheet) {

  def on(event:Event) = event match {
    case clicked:MouseClicked => {
      clicked.modifiers match {
        case scala.swing.event.Key.Modifier.Control => 
          sheet.getItemAt(clicked.point).map(addToSelection)
        case _ => 
          sheet.getItemAt(clicked.point).map(setSelection)
      }
    }
  }
}

And a Sheet who his the shapes container (and know how to translate points).

class Sheet extends Component {
  private val selection = Selection(this)

  listenTo(mouse.clicks, mouse.moves)
  reactions += {
    case e:MousePressed => selection.on(translate(e))
    case e:MouseClicked => selection.on(translate(e))
  }

  /** Here is my problem :
   * > Expression of type (MouseEvent) => MousePressed doesn't conform to expected type Event
   */
  def translate(original: MouseEvent): Event = original match {
    case pressed:MousePressed =>
      pressed.copy(point=relativize(pressed.point))
    case clicked:MouseClicked =>
      clicked.copy(point=relativize(pressed.point))
    case other:MouseEvent=>
      other
  }  
}

I can bypass this problem with an ugly cast :

case pressed:MousePressed =>
      pressed.copy(point=relativize(pressed.point)).asInstanceOf[MousePressed]

But then I have another more strange compiler problem :

Error:(32, 21) missing arguments for method copy in class MousePressed; follow this method with `_' if you want to treat it as a partially applied function

pressed.copy(point = relativize(pressed.point)).asInstanceOf[MousePressed]

And here, I'm lost and need your help to do this simple conversion.

Of course all methods use scala.swing._ types (and never mixes between scala.swing.andjava.awt.`)

Thanks a lot


Solution

  • Regarding the compiler problem, you can understand what's complaining about looking at the MouseEvent (and specifically MousePressed) documentation.

    The case class is defined with two parameter lists, with the following simplified signature

    MousePressed(source: Component, point: java.awt.Point, modifiers: Modifiers, clicks: Int, triggersPopup: Boolean)(peer: java.awt.event.MouseEvent) extends MouseButtonEvent 
    

    As you can see there's a second parameter list expecting the peer object, which is the underlying java swing object. You can access the peer instance using the attribute of the same name (e.g. pressed.peer)

    The copy method, generated by the case class definition, probably expects this second parameter, like this

    pressed.copy(point = relativize(pressed.point))(pressed.peer)
    

    With the second parameter list missing, the compiler is inferring that you want to partially apply the copy method, thus it suggests you to use the

    pressed.copy(point = relativize(pressed.point) _
    

    syntax for partially applying the curried function