JavaFX-任务中的新阶段
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaFX-任务中的新阶段相关的知识,希望对你有一定的参考价值。
我想从任务中打开一个新窗口但由于某种原因,在行Stage stage = new Stage
之后代码停止执行,但没有错误。
Task<Void> task = new Task<Void>() {
@Override protected Void call() throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("sample2.fxml"));
Stage stage = new Stage();
System.out.println("Print");
stage.setTitle("My New Stage Title");
stage.setScene(new Scene(root, 100, 100));
stage.show();
return null;
}
};
它从不打印出“打印”消息。
答案
Answer to Question
你的Task
失败的原因是因为你在JavaFX应用程序线程以外的线程上创建了一个Stage
。 Stage
的Javadoc声明:
必须在JavaFX Application Thread上构造和修改Stage对象。
这意味着当您尝试在运行Stage
的后台线程上创建Task
时,将生成一个IllegalStateException
,并显示一条消息,告知您不在JavaFX应用程序线程上。要解决此问题,请在Stage
调用中包装所有创建和/或修改Platform.runLater(Runnable)
的代码。
旁注:最好不要在Stage
中创建Task
。相反,在你的情况下,只需返回FXMLLoader.load(URL)
的结果并在处理Stage
的成功时创建Task
。
Task<Parent> task = new Task<Parent>() {
@Override
protected Parent call() throws Exception {
return FXMLLoader.load(getClass().getResource("sample2.fxml"));
}
};
task.setOnSucceeded(event -> {
Parent root = task.getValue();
Stage stage = new Stage();
stage.setScene(new Scene(root));
stage.show();
};
Why No Error Shown?
你说没有错误,但你也没有显示任何代码,如果确实发生错误将显示错误。当Task
失败时,它确定了exception
财产失败的原因。要处理Task
失败的情况,您可以:
- 听听
exception
的财产 - 添加一个
EventHandler
来处理WorkerStateEvent.WORKER_STATE_FAILED
事件并查询exception
属性 使用task.setOnFailed(EventHandler)
或task.addEventXXX(EventType, EventHandler)
,其中XXX
是Filter
或Handler
- 覆盖
protected void failed()
实现中的Task
方法并查询exception
属性 始终在JavaFX应用程序线程上调用failed()
方法 - 在重新抛出它之前,在
call()
方法中捕获并处理异常 - 可能是我目前没想到的其他方式
另一答案
您需要一个Executor来启动该线程
Executor exec = Executors.newCachedThreadPool(runnable -> {
Thread t = new Thread(runnable);
t.setDaemon(true);
return t;
});
exec.execute(task);
以上是关于JavaFX-任务中的新阶段的主要内容,如果未能解决你的问题,请参考以下文章