scalafx自定义绑定竞争条件

时间:2018-08-07 16:45:38

标签: scala javafx scalafx

我正在尝试使用Amazon Rekognition在图像中检测到的文本周围绘制框。

这是一个精简的JavaFX应用程序,可以做到这一点:

object TextRekognizeGui extends JFXApp {
  lazy val rekognition: Option[AmazonRekognition] =
    RekogClient.get(config.AwsConfig.rekogEndpoint, config.AwsConfig.region)
  private val config = MainConfig.loadConfig()

  stage = new PrimaryStage {
    scene = new Scene {
      var imgFile: Option[File] = None

      content = new HBox {
        val imgFile: ObjectProperty[Option[File]] = ObjectProperty(None)
        val img: ObjectProperty[Option[Image]] = ObjectProperty(None)
        val lines: ObjectProperty[Seq[TextDetection]] = ObjectProperty(Seq.empty)
        // These two print statements are always executed when we press the appropriate button.
        img.onChange((_, _, newValue) => println("New image"))
        lines.onChange((_, _, newValue) => println(s"${newValue.length} new text detections"))
        children = Seq(
          new VBox {
            children = Seq(
              new OpenButton(img, imgFile, lines, stage),
              new RekogButton(img, imgFile, lines, rekognition)
            )
          },
          new ResultPane(675, 425, img, lines))
      }
    }
  }

  stage.show
}

class ResultPane(width: Double, height: Double, img: ObjectProperty[Option[Image]],
                 textDetections: ObjectProperty[Seq[TextDetection]]) extends AnchorPane { private val emptyPane: Node = Rectangle(0, 0, width, height)

  // This print statement, and the one below, are often not executed even when their dependencies change.
  private val backdrop = Bindings.createObjectBinding[Node](
    () => {println("new backdrop"); img.value.map(new MainImageView(_)).getOrElse(emptyPane)},
    img
  )

  private val outlines = Bindings.createObjectBinding[Seq[Node]](
    () => {println("new outlines"); textDetections.value map getTextOutline},
    textDetections
  )

在我看来,这就像我遵循ScalaFX文档的directions创建自定义绑定一样。当我单击“ RekogButton”时,我希望看到“新文本检测”消息以及“新轮廓”消息,但是更多的时候我只会看到“新文本检测”消息。

在程序的整个生命周期中,行为似乎是相同的,但仅在某些运行中才表现出来。 img-> background绑定也会发生相同的问题,但这种情况很少出现。

为什么属性更改时有时无法调用绑定?

修改1 JavaFX将与绑定关联的侦听器存储为weak reference,这意味着它们仍然可以被垃圾回收,除非另一个对象持有对它们的强引用或软引用。因此,如果垃圾收集器恰好在应用初始化和绘制轮廓之间运行,看来我的应用失败了。

这很奇怪,因为我似乎对绑定有很强的引用-结果窗格中值“ outlines”的“ delegate”字段。进一步研究。

0 个答案:

没有答案