Multithreading 从ScalaFX中的后台线程更新UI

Multithreading 从ScalaFX中的后台线程更新UI,multithreading,scala,scalafx,Multithreading,Scala,Scalafx,代码如下: import javafx.event import javafx.event.EventHandler import scalafx.application.{Platform, JFXApp} import scalafx.application.JFXApp.PrimaryStage import scalafx.event.ActionEvent import scalafx.scene.Scene import scalafx.scene.control.{Button,

代码如下:

import javafx.event
import javafx.event.EventHandler

import scalafx.application.{Platform, JFXApp}
import scalafx.application.JFXApp.PrimaryStage
import scalafx.event.ActionEvent
import scalafx.scene.Scene
import scalafx.scene.control.{Button, Label}
import scalafx.Includes._
import scalafx.scene.layout.{VBox, HBox}

object Blocking extends JFXApp {
  val statusLbl = new Label("Not started...")
  val startBtn = new Button("Start") {
    onAction = (e: ActionEvent) => startTask
  }
  val exitBtn = new Button("Exit") {
    onAction = (e: ActionEvent) => stage.close()
  }
  val buttonBox = new HBox(5, startBtn, exitBtn)
  val vBox = new VBox(10, statusLbl, buttonBox)

  def startTask = {
    val backgroundThread = new Thread {
      setDaemon(true)
      override def run = {
        runTask
      }
    }
    backgroundThread.start()
  }

  def runTask = {
    for(i <- 1 to 10) {
      try {
        val status =  "Processing " + i + " of " + 10
        Platform.runLater(() => {
          statusLbl.text = status
        })
        println(status)
        Thread.sleep(1000)
      } catch {
        case e: InterruptedException => e.printStackTrace()
      }
    }
  }

  stage = new PrimaryStage {
    title = "Blocking"
    scene = new Scene {
      root = vBox
    }
  }
}
import javafx.event
导入javafx.event.EventHandler
导入scalafx.application.{Platform,JFXApp}
导入scalafx.application.JFXApp.PrimaryStage
导入scalafx.event.ActionEvent
导入scalafx.scene.scene
导入scalafx.scene.control.{按钮,标签}
导入scalafx.Includes_
导入scalafx.scene.layout.{VBox,HBox}
对象阻塞扩展了JFXApp{
val statusLbl=新标签(“未启动…”)
val startBtn=新按钮(“开始”){
onAction=(e:ActionEvent)=>startTask
}
val exitBtn=新按钮(“退出”){
onAction=(e:ActionEvent)=>stage.close()
}
val按钮盒=新的HBox(5,开始,退出)
val vBox=新vBox(10,状态LBL,按钮框)
def startTask={
val backgroundThread=新线程{
setDaemon(true)
覆盖def运行={
运行任务
}
}
backgroundThread.start()
}
def runTask={
为了{
statusLbl.text=状态
})
println(状态)
线程。睡眠(1000)
}抓住{
案例e:InterruptedException=>e.printStackTrace()
}
}
}
阶段=新的初级阶段{
title=“阻止”
场景=新场景{
root=vBox
}
}
}

按下“开始”按钮时,状态标签应更新10次,但未更新。从控制台可以看到后台线程实际上正在更新状态,但这些状态不会反映在UI中。为什么?

问题在于调用
Platform.runLater
。要使其工作,请将其更改为:

Platform.runLater {
  statusLbl.text = status
}
runLater[R](op:=>R)
将返回
R
类型值的代码块作为参数。您正在传递一个定义匿名函数的代码块
runLater
正在创建函数,而不是执行它