2015-11-02 58 views
0

我有一个登录窗口视图,我想显示一个进度条,当我点击/按Enter按钮,而光滑是查询密码。如果在按钮actionEvent处更改进度条的可见属性,则只有在查询完成后才会显示它。此外,我不希望进度栏在无形中占用空间。有人知道如何做这些事吗?查询加载时可以显示进度条。 ScalaFx

object SPM extends JFXApp { 

/* 
* Primary stage: Log in 
* */ 
stage = new PrimaryStage { 
// error message hidden label 
val errorLabel = new Label() 
errorLabel.textFill = Color.Red 
errorLabel.font = Font.font("Helvetica", FontWeight.ExtraLight, 12) 

val usernameField = new TextField { 
    promptText = "User" 
    maxWidth = 250 
    prefHeight = 35 
} 

val passwordField = new PasswordField() { 
    promptText = "Password" 
    maxWidth = 250 
    prefHeight = 35 
} 

val progressBar = new ProgressBar { 
    maxWidth = 300 
    visible = false 
} 
title = "Software Project Management" 
scene = new Scene(800, 600) { 
    root = new VBox { 
    spacing = 10 
    padding = Insets(20) 
    alignment = Pos.Center 
    children = List(
     new ImageView { 
     image = new Image(
      this.getClass.getResourceAsStream("/images/logo.png")) 
     margin = Insets(0, 0, 20, 0) 
     }, 
     new Label { 
     text = "Software Project Management" 
     font = Font.font("Helvetica", FontWeight.ExtraLight, 32) 
     }, 
     new Label { 
     text = "Sign in to get started" 
     font = Font.font("Helvetica", FontWeight.Thin, 18) 
     }, 
     errorLabel, 
     progressBar, 
     usernameField, 
     passwordField, 
     new Button { 
     text = "Enter" 
     defaultButton = true 
     prefHeight = 35 
     font = Font.font("Helvetica", FontWeight.Thin, 18) 
     maxWidth = 250 
     onAction = (ae: ActionEvent) => { 
      progressBar.visible = true 
      val password = Users.checkPassword(usernameField.text.value) 
      if (password != passwordField.text.value) 
      errorLabel.text = "Please re-enter your password" 
      else root = chooseProject 
     } 
     } 
    ) // children 
    } // root 
} // scene 

回答

0

您的Button.onAction处理程序正在JavaFX应用程序线程上运行。与用于更新UI的相同。当你运行长时间运行的任务时,你应该在一个单独的线程上运行它,这将有助于UI做出正确的反应。通常的做法是使用JavaFX Task。一般模式是这样的:

// Define your task 
val task = new javafx.concurrent.Task[T] { 
    override def call(): T = { 
    // Do your task and return result  
    // Executed off JavaFX Application thread  
    } 
    override def succeeded(): Unit = { 
    // Update UI to finish processing 
    // Executed on JavaFX Application thread  
    } 
    override def failed(): Unit = { 
    // Handle errors, if any 
    // Executed on JavaFX Application thread 
    } 
} 

// Run your task 
val t = new Thread(task, "My Task") 
t.setDaemon(true) 
t.start() 

```

这里是如何能看在你的代码:

root = new VBox { _root => 
    ... 

     onAction = (ae: ActionEvent) => { 
      progressBar.visible = true 
      _root.disable = true 
      //    progressBar.visible = true 
      val task = new javafx.concurrent.Task[Boolean] { 
      override def call(): Boolean = { 
       println("Checking password... ") 
       Thread.sleep(3000) 
       println("Password checked. ") 
       // Assume password is correct 
       true 
      } 
      override def succeeded(): Unit = { 
       progressBar.visible = false 
       _root.disable = false 
       val passwordOK = get() 
       if (passwordOK) { 
       new Alert(AlertType.Information) { 
        headerText = "Password OK" 
       }.showAndWait() 
       } else { 
       new Alert(AlertType.Warning) { 
        headerText = "Invalid Password" 
       }.showAndWait() 

       } 
      } 
      override def failed(): Unit = { 
       println("failed") 
       progressBar.visible = false 
       _root.disable = false 
      } 
      } 

      val t = new Thread(task, "Password Task") 
      t.setDaemon(true) 
      t.start() 
     } 
+0

感谢您的帮助 – mimo

+0

也很好的提示将根禁用,而完成任务,非常感谢。顺便说一句,现在我对线程有了更好的理解,你认为将查询放在并发性的scala未来会更好,还是javafx任务更适合? – mimo

+0

您也可以使用Scala功能,只需记住需要在JavaFX应用程序线程上完成对UI的更新。如果需要,JavaFX Task还可以轻松处理进度值更新和进度消息。 – Jarek