我正在使用JavaFX8和e(fx)clipse实现文档编辑器,并希望用户在导出(写入光盘)时正在通知。我正在使用主(GUI)线程,因为我想在此操作期间阻止gui(需要2-3秒)。在此操作过程中,我想显示一个小弹出窗口,通知用户导出正在进行,没什么特别的。
@FXML
public void export() {
Dialog dialog = new Dialog();
dialog.setContentText("exporting ...");
dialog.show();
// some lenghty methods come here, ~equivalent to Thread.sleep(3000);
dialog.hide();
}
当我按下调用导出方法的相应Button时,我得到两个对话框,其中一个不关闭,并在方法完成后保持打开状态。
有人知道这里发生了什么吗?我真的对一个简单的解决方案感兴趣,我不需要进度条等。
另一种可能性是在操作开始之前显示等待光标并在此之后切换回默认光标。不幸的是,这似乎也没有用。我知道UI在“冗长”操作期间被阻止,但我不知道为什么我不能在该操作之前和之后更改UI ....
答案 0 :(得分:0)
您的示例并非完整 - 但我建议您使用以下两种方法之一。但是,您不会将长时间的过程放在后台线程上,这将使您的应用程序冻结。你想卸载这个过程。
1)使用具有Progess Alert的ControlsFX对话框。将您的工作与任务或服务联系起来,并将其提供给警报。这将在线程处于活动状态时弹出警报,并在完成后自动关闭它。如果您有中间进度值,则可以使用它来更新进度条。
或者,如果您不想使用此对话框,您可以执行以下操作:
Alert progressAlert = displayProgressDialog(message, stage);
Executors.newSingleThreadExecutor().execute(() -> {
try {
//Do you work here....
Platform.runLater(() ->forcefullyHideDialog(progressAlert));
} catch (Exception e) {
//Do what ever handling you need here....
Platform.runLater(() ->forcefullyHideDialog(progressAlert));
}
});
private Alert displayProgressDialog(String message, Stage stage) {
Alert progressAlert = new Alert(AlertType.NONE);
final ProgressBar progressBar = new ProgressBar();
progressBar.setMaxWidth(Double.MAX_VALUE);
progressBar.setPrefHeight(30);
final Label progressLabel = new Label(message);
progressAlert.setTitle("Please wait....");
progressAlert.setGraphic(progressBar);
progressAlert.setHeaderText("This will take a moment...");
VBox vbox = new VBox(20, progressLabel, progressBar);
vbox.setMaxWidth(Double.MAX_VALUE);
vbox.setPrefSize(300, 100);
progressAlert.getDialogPane().setContent(vbox);
progressAlert.initModality(Modality.WINDOW_MODAL);
progressAlert.initOwner(stage);
progressAlert.show();
return progressAlert;
}
private void forcefullyHideDialog(javafx.scene.control.Dialog<?> dialog) {
// for the dialog to be able to hide, we need a cancel button,
// so lets put one in now and then immediately call hide, and then
// remove the button again (if necessary).
DialogPane dialogPane = dialog.getDialogPane();
dialogPane.getButtonTypes().add(ButtonType.CANCEL);
dialog.hide();
dialogPane.getButtonTypes().remove(ButtonType.CANCEL);
}