JavaFX 操作事件语句执行顺序


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);
}

上面的 Export(( 方法在单击按钮时执行时,似乎不按顺序运行方法语句。进度条动画在弹出警报窗口之前不会显示。我该如何纠正此问题?

假设您的foo()方法需要很长时间才能运行,则发生的情况是您正在阻止 FX 应用程序线程,这会阻止它执行其常规职责,例如呈现 UI。因此,虽然语句(当然(按照您编写它们的顺序执行,即pgprogressProperty设置为-1,然后执行foo(),然后显示Alert,在整个过程完成之前,您实际上不会UI 中看到这些结果(或者,实际上,在这种情况下,直到您通过调用showAndWait()放弃对 FX 应用程序线程的控制权(。

解决此问题的基本方法是在后台线程中运行foo()。如果要在完成时执行与 UI 相关的代码,则执行此操作的最佳方法是使用Task并使用其onSucceeded处理程序在最后执行 UI 代码。所以一般来说,你会做这样的事情:

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();
}

最新更新