首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ScalaFX。活绑定

ScalaFX。活绑定
EN

Stack Overflow用户
提问于 2017-11-21 13:03:22
回答 1查看 574关注 0票数 2

我有一个简单的UI窗口,只有一个文本节点,它显示当前时间并绑定到模型:

代码语言:javascript
复制
import model.Clock

import scalafx.application.JFXApp
import scalafx.application.JFXApp.PrimaryStage
import scalafx.beans.property.StringProperty
import scalafx.geometry.Insets
import scalafx.scene.Scene
import scalafx.scene.layout.HBox
import scalafx.scene.text.Text
import scalafx.Includes._

object Main extends JFXApp {
    val clock = new Text()
    clock.textProperty().bind( new StringProperty(Clock.curTime) )

    stage = new PrimaryStage {
        onShowing = handle { Clock.startClock }
        title = "ScalaFX clock"
        scene = new Scene {
            content = new HBox {
                padding = Insets(50, 80, 50, 80)
                children = clock
            }
        }
    }
}

还有一个模型:

代码语言:javascript
复制
import java.util.Date
import java.text.SimpleDateFormat

object Clock {
    var curTime = ""
    private lazy val dateFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss")

    def startClock = {
        /*A code, witch runs in another Thread and 
          changes curTime every 1 second skipped here.
          Only one change of curTime for simplicity.
        */

        curTime = dateFormat format new Date
    }
}

我的问题是:当curTime变量发生变化时,UI中的文本节点不会改变。

我想它只出现过一次。如何使文本节点每次显示curTime的新值时,curTime发生变化?

对不起我的英语:

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-22 03:05:40

问题是,Clock.curTime只是一个变量,其值会定期更新--它不是一个可观察的属性,因此当它被更改时什么都不会发生。特别是,该变量与Text元素的内容之间没有任何联系。

您所做的就是用这个值初始化一个StringProperty --但是由于属性本身从未更新过,标签也是如此。我认为您想要做的是使curTime成为一个StringProperty,而不仅仅是一个String。现在,每当您更改该属性的值时,Text元素的值就会相应地发生变化。

您应该注意到,与JavaFX/ScalaFX的交互只能发生在JavaFX应用程序线程上,因此如果尝试从另一个线程更新curTime,就会遇到问题。实现这一目标的一种方法是将实际更新curTime的代码传递给Platform.runLater

然而,一种更简单的方法是使用一个定时的ScalaFX事件来定期更新JavaFX/ScalaFX中的curTime,如下所示:

代码语言:javascript
复制
import model.Clock
import scalafx.application.JFXApp
import scalafx.application.JFXApp.PrimaryStage
import scalafx.geometry.Insets
import scalafx.scene.Scene
import scalafx.scene.layout.HBox
import scalafx.scene.text.Text
import scalafx.Includes._

object Main
extends JFXApp {

  val clock = new Text()

  // Clock.curTime is now a StringProperty, which we bind to clock's text.  Since clock is
  // created lazily, it starts the timer event, so we do not need startClock either.
  clock.text <== Clock.curTime

  // Create the stage & scene.
  stage = new PrimaryStage {
    title = "ScalaFX clock"
    scene = new Scene {
      content = new HBox {
        padding = Insets(50, 80, 50, 80)
        children = clock
      }
    }
  }
}

Clock.scala

代码语言:javascript
复制
import java.util.Date
import java.text.SimpleDateFormat
import scalafx.animation.PauseTransition
import scalafx.application.Platform
import scalafx.beans.property.StringProperty
import scalafx.util.Duration
import scalafx.Includes._

// Object should be constructed lazily on the JFX App Thread. Verify that...
object Clock {
  assert(Platform.isFxApplicationThread)

  private val dateFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss")

  val curTime = new StringProperty(getDate())

  // Update the curTime property every second, using a timer.
  // Note: 1,000 ms = 1 sec
  val timer = new PauseTransition(Duration(1000))
  timer.onFinished = {_ =>
    curTime.value = getDate()
    timer.playFromStart() // Wait another second, or you can opt to finish instead.
  }

  // Start the timer.
  timer.play()

  private def getDate() = dateFormat.format(new Date())
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47413814

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档