Scalafx。通过定时器启动警报

Scalafx。通过定时器启动警报,scala,timer,alert,scalafx,Scala,Timer,Alert,Scalafx,我有一个主窗口,里面有一些信息。我不能用定时器启动警报。我需要每10秒显示一次警报(主窗口正常工作),并通过警报按钮更改主窗口中标签的文本。 我有这个代码,但它不起作用: object main extends JFXApp { stage = new JFXApp.PrimaryStage() { scene = new Scene { val MyLabel = new Label("SomeText") root = new VBox { child

我有一个主窗口,里面有一些信息。我不能用定时器启动警报。我需要每10秒显示一次警报(主窗口正常工作),并通过警报按钮更改主窗口中标签的文本。 我有这个代码,但它不起作用:

object main extends JFXApp {
 stage = new JFXApp.PrimaryStage() {
   scene = new Scene {
    val MyLabel = new Label("SomeText")
    root = new VBox {
        children = MyLabel
     }
   }
 val ButtonTypeOne = new ButtonType("Change the text")
 val ButtonTypeTwo = new ButtonType("No")

  val alert1 = new Alert(AlertType.Warning) {
        initOwner(stage)
        title = "Warning!!!"
        headerText = "Header"
        contentText = "Do you need to change the text?"
        buttonTypes = Seq(ButtonTypeOne, ButtonTypeTwo, ButtonType.Cancel)
      }
    val result = alert1.showAndWait()
    val timerA = new PauseTransition(Duration(5000))
              timerA.onFinished = { _ =>
                result match {
                  case Some(ButtonTypeOne) => /*Here I need to change text in MyLabel */
                  case Some(ButtonTypeTwo) => None
                  case _ => None
                 }
               timerA.playFromStart()
              }
    timerA.play
 }
}

代码中有几个不同的问题:

  • 无论计时器发生了什么,您只会显示一次警报
  • 对计时器中的警报结果作出反应的代码始终查看相同的初始结果
  • 不幸的是,即使在计时器的动画更新事件中移动
    val result=alert1.showAndWait
    ,JavaFX也会使在这样的例程中调用
    showAndWait
    非法
  • 解决方案是为
    alert1
    创建一个
    onHidden
    事件处理程序,该处理程序对其关闭作出反应。用于关闭对话框的按钮类型随后存储在
    alert1.result
    中,因此您可以使用它来确定要采取的操作

    我添加了一个
    StringProperty
    ,以帮助更改标签值。下面的例子应该是你想要实现的一个很好的起点。。。

    导入scalafx.Includes_
    导入scalafx.animation.PauseTransition
    导入scalafx.application.JFXApp
    导入scalafx.application.JFXApp.PrimaryStage
    导入scalafx.beans.property.StringProperty
    导入scalafx.scene.scene
    导入scalafx.scene.layout.VBox
    导入scalafx.scene.control.{Alert,ButtonType,Label}
    导入scalafx.scene.control.Alert.AlertType
    导入scalafx.util.Duration
    对象main扩展了JFXApp{
    //myLabel中文本的字符串属性。
    val strProp=StringProperty(“某些文本”)
    //声明此项,以便可以从timerA.onFinished访问它。
    val myLabel=新标签{
    //将text属性绑定到strProp的值。
    //当strProp的值更改时,标签的文本也会更改。
    正文
    alert1.result.value匹配{
    //如果按钮类型为1,请更改属性值。
    //注意:alert1.result.value是一个JavaFXButtonType,因此使用.delegate进行匹配。
    case button typaone.delegate=>strProp.value=“已更改!”
    //否则,什么也不做。
    案例=>
    }
    //再次启动计时器。
    //这将是一个非常烦人的应用程序!;-)
    timerA.playFromStart()
    }
    //当计时器熄灭时,显示警报。
    timerA.onFinished={\u=>
    警报1.show()
    }
    //第一次启动计时器。
    蒂梅拉。玩
    }
    
    import scalafx.Includes._
    import scalafx.animation.PauseTransition
    import scalafx.application.JFXApp
    import scalafx.application.JFXApp.PrimaryStage
    import scalafx.beans.property.StringProperty
    import scalafx.scene.Scene
    import scalafx.scene.layout.VBox
    import scalafx.scene.control.{Alert, ButtonType, Label}
    import scalafx.scene.control.Alert.AlertType
    import scalafx.util.Duration
    
    object main extends JFXApp {
    
      // String property for the text in myLabel.
      val strProp = StringProperty("Some Text")
    
      // Declare this so that it's accessible from timerA.onFinished.
      val myLabel = new Label {
    
        // Bind the text property to the value of strProp.
        // When strProp's value changes, so does the label's text.
        text <== strProp
      }
    
      stage = new PrimaryStage() {
        scene = new Scene {
          root = new VBox {
            children = myLabel
          }
        }
      }
    
      // Custom buttons.
      val ButtonTypeOne = new ButtonType("Change the text")
      val ButtonTypeTwo = new ButtonType("No")
    
      // Create the timer. This goes off after 5,000ms (5 seconds) - after play is called.
      val timerA = new PauseTransition(Duration(5000))
    
      // Alert dialog.
      // Note: JavaFX forbids use of showAndWait within animation processing, so we must use
      // an onHidden event instead.
      val alert1 = new Alert(AlertType.Warning) {
        initOwner(stage)
        title = "Warning!!!"
        headerText = "Header"
        contentText = "Do you need to change the text?"
        buttonTypes = Seq(ButtonTypeOne, ButtonTypeTwo, ButtonType.Cancel)
      }
    
      // React to the dialog being closed.
      alert1.onHidden = {_ =>
        alert1.result.value match {
    
          // If button type one, change the property value.
          // Note alert1.result.value is a JavaFX ButtonType, so use .delegate for the match.
          case ButtonTypeOne.delegate => strProp.value = "Changed!"
    
          // Otherwise, do nothing.
          case _ =>
        }
    
        // Start the timer once more.
        // This is going to be a very annoying app! ;-)
        timerA.playFromStart()
      }
    
      // When the timer goes off, show the alert.
      timerA.onFinished = {_ =>
        alert1.show()
      }
    
      // Start the timer for the first time.
      timerA.play
    }