Scalafx.通过计时器启动警报



我有一个带有一些信息的主窗口。我无法通过计时器启动警报。我需要每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
 }
}

您的代码中有一些不同的问题:

  1. 您只显示一次警报,无论计时器发生了什么。
  2. 对计时器中警报结果的反应的代码始终查看相同的初始结果。
  3. 不幸的是,即使您将val result = alert1.showAndWait移入计时器动画更新事件的内部, javafx 使在此例程中致电showAndWait是非法的。

解决方案是为alert1创建一个onHidden事件处理程序,该处理程序对其进行了反应。然后将用于关闭对话框的按钮类型存储在alert1.result中,因此您可以使用它来确定要采取的措施。

我添加了StringProperty来协助更改标签值。以下示例应该是您想要实现的好起点...

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
}

最新更新