multithreading - 如何从 ScalaFX 线程中获取值?

标签 multithreading scala javafx-2 future scalafx

我有一个 myNode: scalafx.scene.Node我想把它变成一个位图,以便我可以将它保存到磁盘,将它与其他位图进行比较等。我认为正确的代码将它变成 scalafx.scene.image.WritableImage

val writableImg = new Scene { root = new Group(myNode) }.snapshot(null)

然后我应该可以把它变成 java.awt.image.RenderedImage
val renderedImg = SwingFXUtils.fromFXImage(writableImg, null)

您可能已经意识到,问题是我必须运行代码才能获得 wrImg在 ScalaFX 线程上。有问题here这解释了如何返回一个值,但我没有任何运气将它翻译成 Scala。我试过这个:
lazy val writableImg: WritableImage = {
  val wrImg = new FutureTask(new Callable[WritableImage]() {
    override def call(): WritableImage = {
      new Scene { root = new Group(myNode) }.snapshot(null)
    }
  })
  Platform.runLater(wrImg)
  wrImg.get()
}

但代码只是挂起并且永远不会完成。谁能提供一个惯用的 Scala 版本和/或告诉我为什么代码永远不会返回?

最佳答案

如果您只想将图像保存到磁盘,您可以简单地在同一个线程上执行,避免传递图像的复杂性。像这样的东西会起作用:

Platform.runLater {
  val node = new Circle {
    centerX = 200
    centerY = 200
    radius = 50
    stroke = Color.BROWN
    strokeWidth = 2
    fill = Color.DARKKHAKI
  }
  val jfxImage = node.snapshot(new SnapshotParameters(), null)
  val bufferedImage = SwingFXUtils.fromFXImage(jfxImage, null)
  val file = new File("./snapshot.png")
  println("Writing snapshot to: " + file.getAbsolutePath)
  javax.imageio.ImageIO.write(bufferedImage, "png", file)
  ()
}

()有闭包返回单元,所以 ScalaFX Platform.runLater很高兴。

更新 :

如果您想获得 Platform.runLater 中的值您在问题中建议的方法通常应该没问题。但是,您要确保不阻塞 FX 应用程序线程。如果您调用Platform.runLater在 FX 应用程序线程上你将被锁定,所以你可能想要这样的东西
def makeSnapshot() = myNode.snapshot(new SnapshotParameters(), null)

val writableImg = if (Platform.isFxApplicationThread) {
  makeSnapshot()
} else {
  val futureTask = new FutureTask(new Callable[WritableImage]() {
    override def call(): WritableImage = makeSnapshot()
  })
  Platform.runLater(futureTask)
  futureTask.get()
}

关于multithreading - 如何从 ScalaFX 线程中获取值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22599552/

相关文章:

java - 将 fxml 与 jruby 一起使用

swing - 如何在 swing 中运行 javaFX MediaPlayer?

java - 生产者-消费者线程死锁

scala - scala 中的 Tuple_2 按键排序

css - 如何在 CSS 中设置 JavaFX SplitMenuButton 的样式

arrays - Scala Array.apply 的魔力是什么

scala:映射元组的 future

node.js - 在管理器/ worker 模式中使用子进程以确保线程安全时,Node.js 中是否需要锁定?

python - 在 wxPython 中使用多线程

java - 非同步读取(与同步写入结合)最终是否一致