具有子类节点的 ScalaFX PickResult
ScalaFX PickResult with subclassed nodes
我有一个简单的 scalafx 应用程序,但我很难让简单的鼠标交互正常工作。
我有一个名为 Square 的自定义 Canvas 节点 class :
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
...
})
}
相交节点不是正方形而是"scalafx.scene.LowerPriorityIncludes$$anon"(带隐式转换)
有什么方法可以将这个节点映射回我的方块吗?
否则我根本看不出如何使用子classed 节点进行节点拾取。
请记住,ScalaFX 可帮助您构建 JavaFX 应用程序 - 底层结构是 JavaFX。也就是说,当您在 ScalaFX 中构建场景图时,它由 JavaFX 对象组成。
出于这个原因,ScalaFX 应用程序应该通过组合而不是继承来构建。当您简单地从 ScalaFX 包装器继承时,如您的示例所示:
case class Square(val index: Int) extends Canvas
它扩展了一个包装器,而不是实际的 JavaFX class。当您构建场景图然后通过拾取检查它时,您将看到 JavaFX 对象而不是您创建的包装器。您可以通过多种方式处理。一个简单的方法是设置传递给底层 JavaFX 对象的 userData
。我从你提出的片段中完成的例子是这样的:
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()
}
}
}
点击 window 将产生如下输出:
Picked: 40
Picked: 42
Picked: 17
Picked: 36
Picked: 52
Picked: 38
Picked: 27
不寻常的隐式 classes 没有问题。
我有一个简单的 scalafx 应用程序,但我很难让简单的鼠标交互正常工作。
我有一个名为 Square 的自定义 Canvas 节点 class :
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
...
})
}
相交节点不是正方形而是"scalafx.scene.LowerPriorityIncludes$$anon"(带隐式转换)
有什么方法可以将这个节点映射回我的方块吗?
否则我根本看不出如何使用子classed 节点进行节点拾取。
请记住,ScalaFX 可帮助您构建 JavaFX 应用程序 - 底层结构是 JavaFX。也就是说,当您在 ScalaFX 中构建场景图时,它由 JavaFX 对象组成。
出于这个原因,ScalaFX 应用程序应该通过组合而不是继承来构建。当您简单地从 ScalaFX 包装器继承时,如您的示例所示:
case class Square(val index: Int) extends Canvas
它扩展了一个包装器,而不是实际的 JavaFX class。当您构建场景图然后通过拾取检查它时,您将看到 JavaFX 对象而不是您创建的包装器。您可以通过多种方式处理。一个简单的方法是设置传递给底层 JavaFX 对象的 userData
。我从你提出的片段中完成的例子是这样的:
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()
}
}
}
点击 window 将产生如下输出:
Picked: 40
Picked: 42
Picked: 17
Picked: 36
Picked: 52
Picked: 38
Picked: 27
不寻常的隐式 classes 没有问题。