ScalaFX。活页装订
我有一个简单的UI窗口,只有一个文本节点,显示当前时间并绑定到模型:ScalaFX。活页装订,scala,user-interface,binding,scalafx,Scala,User Interface,Binding,Scalafx,我有一个简单的UI窗口,只有一个文本节点,显示当前时间并绑定到模型: 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 scal
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
}
}
}
}
和一个模型:
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中的文本节点不会更改
我猜它在stratup上渲染过一次。如何使文本节点每次显示curTime的新值,curTime发生变化
对不起我的英语:(问题在于
时钟。curTime
只是一个变量,其值会定期更新-它不是一个可观察的属性,因此在更改时不会发生任何事情。特别是,该变量与文本
元素的内容之间没有链接
您所做的是使用该值初始化StringProperty
,但由于属性本身从未更新,标签也不会更新。我想您要做的是使curTime
成为StringProperty
,而不仅仅是String
。现在,每当您更改该属性的值时,Text
元素的值将相应更改
您应该注意,与JavaFX/ScalaFX的交互只能在JavaFX应用程序线程上发生,因此如果您尝试从另一个线程更新curTime
,您将遇到问题。实现这一点的一种方法是将实际更新curTime
的代码传递到平台。稍后运行
但是,更简单的方法是使用定时ScalaFX事件从JavaFX/ScalaFX中定期更新curTime
,如下所示:
这对我帮助很大。非常感谢!
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
}
}
}
}
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())
}