【发布时间】:2022-07-07 13:25:45
【问题描述】:
我正在尝试在 java 中引发一个自定义加载对话框,然后执行一些需要几秒钟的同步函数。
只要函数执行,我希望对话框一直存在,一旦完成,我会关闭对话框。
我的对话框如下所示:
public abstract class LoaderControl extends Control implements SimpleDialogInfo {
private static final StyleablePropertyFactory<LoaderControl> FACTORY = new StyleablePropertyFactory<>(Control.getClassCssMetaData());
private LoaderDialogResponse response;
private final DialogInfo dialogInfo;
private final SimpleStringProperty text = new SimpleStringProperty("");
private final SimpleBooleanProperty spinnerVisible = new SimpleBooleanProperty(true);
private UpdaterStates state;
private CloseDialogFunction onClose;
@Override
public void closeDialog(){
onClose.closeDialog();
}
@Override
public void setCloseDialog(CloseDialogFunction onClose){
this.onClose = onClose;
}
}
这就是我创建它并展示它的方式:
public void createIndependentDialog(SimpleDialogInfo content, EventHandler<MouseEvent> onClose) {
Platform.runLater(() -> {
Stage stage = new Stage();
Parent p = new StackPane();
Scene s = new Scene(p);
stage.setScene(s);
MFXGenericDialog dialogContent = MFXGenericDialogBuilder.build()
.makeScrollable(true)
.setShowAlwaysOnTop(false)
.get();
MFXStageDialog dialog = MFXGenericDialogBuilder.build(dialogContent)
.toStageDialogBuilder()
.initModality(Modality.APPLICATION_MODAL)
.setDraggable(true)
.initOwner(stage)
.setTitle("Dialogs Preview")
.setOwnerNode(grid)
.setScrimPriority(ScrimPriority.WINDOW)
.setScrimOwner(true)
.get();
dialogContent.setMinSize(350, 200);
MFXFontIcon infoIcon = new MFXFontIcon(content.getDialogInfo().getIcon(), 18);
dialogContent.setHeaderIcon(infoIcon);
dialogContent.setHeaderText(content.getDialogInfo().getHeader());
dialogContent.setContent((Node) content);
MFXGenericDialog finalDialogContent = dialogContent;
MFXStageDialog finalDialog = dialog;
content.setCloseDialog(dialog::close);
convertDialogTo(String.format("mfx-%s-dialog", content.getDialogInfo().getDialogType()));
if(onClose != null)
dialogContent.setOnClose(onClose);
dialog.showAndWait();
});
}
这是它在调用类中的样子:
DialogLoaderControlImpl preloader = new DialogLoaderControlImpl(new LoaderDialogInfo("Searching For New Versions"));
DialogsController.getInstance().createIndependentDialog(preloader);
someSynchronousMethod();
preloader.closeDialog();
问题是当我到达“preloader.closeDialog()”行时,应该关闭对话框的 closeDialog 函数为空(onClose 字段为空)。
简而言之:
createIndependentDialog() 方法应该引发一个对话框,我想在对话框仍然显示时继续执行方法“someSynchronousMethod()”,并在方法完成后关闭它。
请注意,我在此处未显示的对话框中使用了皮肤,但如果我删除 Platform.runLater,它会起作用,但随后它会卡在 showAndWait() 中而没有按预期推进
是否有某种方式或已知设计有助于使用自定义对话框运行任务/方法?
【问题讨论】:
-
创建并发布minimal reproducible example;即一个完整的示例,我们可以复制、粘贴和运行,而无需引用其他类。使用
Thread.sleep()模拟后台长时间运行的任务。这里的代码太多了,我们不知道它是做什么的。 -
并且:“执行一些需要几秒钟的同步函数”。你的意思是这里的“异步”,确定吗?如果需要几秒钟,您将无法在 FX 应用程序线程上同步执行它,因为 UI 会冻结。
-
听起来你需要一个进度温度计,而不是一个对话框。对话框用于与用户进行交互,一个对话框。
-
ControlsFX 有一个ProgressDialog。使用它或研究它的implementation。也学习了解concurrency in JavaFX。
标签: java multithreading user-interface javafx