具有子类节点的 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 没有问题。