简体   繁体   English

JavaFX动作事件语句执行顺序

[英]JavaFX action event statement execution order

public class MainController {
@FXML
public Button browse_report;
@FXML
public Button browse_directory;
@FXML
public Button export;
@FXML
public Button close;
@FXML
public Label report;
@FXML
public Label directory;
@FXML
public Label processing;
@FXML
public TextField report_text;
@FXML
public TextField directory_text;
@FXML
public ProgressBar pg = new ProgressBar();



public void closeButton(ActionEvent e) {
    System.exit(0);
}

public void getReport(ActionEvent e) {
    FileChooser fc = new FileChooser();
    File file=fc.showOpenDialog(null);
    report_text.setText(file.getAbsolutePath());
}

public void getDirectory(ActionEvent e) {
    DirectoryChooser dc = new DirectoryChooser();
    File file =dc.showDialog(null);
    directory_text.setText(file.getAbsolutePath());

}

public void Export(ActionEvent e) {

    pg.setProgress(-1);
    foo();
    Alert alert = new Alert(AlertType.INFORMATION, "Spreadsheet Generated", ButtonType.CLOSE);
    alert.showAndWait();
    pg.setProgress(1);
}

The above Export() method, when executed on button click,appears to run the method statements out of order. 上面的Export()方法在单击按钮时执行时,似乎会乱序运行方法语句。 The progress bar animation does not display until after the alert window pops up. 直到弹出警报窗口后,进度条动画才会显示。 How can I correct this? 我该如何纠正?

Assuming your foo() method takes a long time to run, what is happening is that you are blocking the FX Application Thread, which prevents it from performing its usual duties, such as rendering the UI. 假设您的foo()方法需要花费很长时间才能运行,这是因为您正在阻止FX Application Thread,这阻止了它执行其通常的职责,例如呈现UI。 So while the statements are (of course) executed in the order you write them, ie the progressProperty of pg is set to -1 , then foo() is executed, then the Alert is shown, you won't actually see the results of those in the UI until the whole process completes (or, actually, in this case until you relinquish control of the FX Application Thread by calling showAndWait() ). 因此,尽管按照您编写语句的顺序(当然)执行了语句,即pgprogressProperty设置为-1 ,然后执行了foo() ,然后显示了Alert ,但实际上您不会看到的结果直到整个过程完成为止(或者实际上,在这种情况下,直到您通过调用showAndWait()放弃对FX Application Thread的控制为止),才可以在UI中showAndWait()

The basic way to solve this is to run foo() in a background thread. 解决此问题的基本方法是在后台线程中运行foo() If there is UI-related code you want to perform when that completes, the best way to do that is to use a Task and use its onSucceeded handler to perform the UI code at the end. 如果要在完成时执行与UI相关的代码,最好的方法是使用Task并使用其onSucceeded处理函数最后执行UI代码。 So in general you do something like this: 因此,通常您可以执行以下操作:

public void Export(ActionEvent e) {

    pg.setProgress(-1);
    Task<Void> task = new Task<Void>() {
        @Override
        protected Void call() throws Exception {
            foo();
            return null ;
        }
    };
    task.setOnSucceeded(evt -> {
        Alert alert = new Alert(AlertType.INFORMATION, "Spreadsheet Generated", ButtonType.CLOSE);
        alert.showAndWait();
        pg.setProgress(1);

    });
    new Thread(task).start();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM