我有一个简单的scalafx应用程序,但我正在努力使简单的鼠标交互正常工作。
我有一个名为Square的自定义Canvas节点类:
case class Square(val index: Int) extends Canvas
然后我有了一个自定义的GridPane,它用正方形填充:
class BoardPane extends GridPane
{
val squares: Array[Square] = (0 to 63).toArray.map(index => Square(index))
(0 to 63).foreach(index => add(squares(index), index%8, 7-index/8))
}
[当我尝试从鼠标事件中获取选择结果时:
class PlayableBoardPane extends BoardPane
{
onMouseDragged = (event => {
val node: Option[Node] = event.pickResult.intersectedNode
...
})
}
相交的节点不是Square,而是“ scalafx.scene.LowerPriorityIncludes $$ anon $ 4”(具有隐式转换)
有没有一种方法可以将该节点映射回我的正方形?
没有,我什至看不到如何甚至对子类化的节点使用节点选择。
请记住,ScalaFX可帮助您构建JavaFX应用程序-基础结构是JavaFX。也就是说,在ScalaFX中构建场景图时,它由JavaFX对象组成。
因此,ScalaFX应用程序应该是通过槽构建而不是继承。当您仅从ScalaFX包装器继承时,例如您的示例:
case class Square(val index: Int) extends Canvas
它扩展了包装器,而不是实际的JavaFX类。当您构建场景图并通过挑选对其进行检查时,您将看到JavaFX对象而不是您创建的包装器。您可以通过多种方式处理。一种简单的方法是设置userData
,该参数将传递给基础JavaFX对象。我从您构成的片段中完成示例,就像这样:
import scalafx.Includes._
import scalafx.application.JFXApp
import scalafx.application.JFXApp.PrimaryStage
import scalafx.scene.Scene
import scalafx.scene.canvas.Canvas
import scalafx.scene.layout.GridPane
object PickResultWithSubclassedNodes extends JFXApp {
case class Square(index: Int) extends Canvas {
height = 25
width = 25
userData = index.toString
}
class BoardPane extends GridPane {
val squares: Array[Square] = (0 to 63).toArray.map(index => Square(index))
(0 to 63).foreach(index => add(squares(index), index % 8, 7 - index / 8))
}
class PlayableBoardPane extends BoardPane {
onMouseReleased = (event => {
val node = event.pickResult.intersectedNode
node match {
case Some(n) => println("Picked: " + n.userData)
case None =>
}
})
}
stage = new PrimaryStage {
title = "Blocking"
scene = new Scene {
root = new PlayableBoardPane()
}
}
}
单击窗口将产生如下输出:
Picked: 40
Picked: 42
Picked: 17
Picked: 36
Picked: 52
Picked: 38
Picked: 27
不寻常的隐式类没有问题。