[英]JavaFX- new Stage in a task
I want to open a new window from the task but for some reason after line Stage stage = new Stage
the code stops executing, but there is no error. 我想从任务中打开一个新窗口,但是由于某些原因,在
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;
}
};
It never prints out the message 'Print'. 它从不打印出“打印”消息。
The reason your Task
is failing is because you are creating a Stage
on a thread other than the JavaFX Application Thread. Task
失败的原因是因为您正在JavaFX Application Thread之外的其他线程上创建Stage
。 The Javadoc of Stage
states: Stage
的Javadoc指出:
Stage objects must be constructed and modified on the JavaFX Application Thread.
舞台对象必须在JavaFX Application Thread上构造和修改。
This means when you attempt to create a Stage
on the background thread that the Task
is running on it will result in an IllegalStateException
with a message telling you that you aren't on the JavaFX Application Thread. 这意味着,当您尝试在正在其上运行
Task
的后台线程上创建一个Stage
时,将导致IllegalStateException
并显示一条消息,告知您不在JavaFX Application Thread上。 To solve this issue wrap all code that creates and/or modifies a Stage
in a Platform.runLater(Runnable)
call. 要解决此问题,请在
Platform.runLater(Runnable)
调用中包装所有创建和/或修改Stage
代码。
Side Note: It would probably be better to not create the Stage
in the Task
at all. 旁注:最好根本不在
Task
中创建Stage
。 Rather, in your case, simply return the result of FXMLLoader.load(URL)
and create the Stage
when handling the success of the Task
. 相反,在您的情况下,仅在处理
Task
成功时返回FXMLLoader.load(URL)
的结果并创建Stage
。
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();
};
You say there is no error but you also don't show any code that would display an error if one does occurr. 您说没有错误,但是您也不会显示任何代码,如果发生的话会显示错误。 When a
Task
fails it sets the cause of failure in the exception
property. 当
Task
失败时,它将在exception
属性中设置失败的原因。 To handle the case when a Task
fails you can: 要处理
Task
失败时的情况,您可以:
exception
property exception
属性 EventHandler
to handle a WorkerStateEvent.WORKER_STATE_FAILED
event and query the exception
property EventHandler
来处理WorkerStateEvent.WORKER_STATE_FAILED
事件并查询exception
属性
task.setOnFailed(EventHandler)
or task.addEventXXX(EventType, EventHandler)
where XXX
is either Filter
or Handler
task.setOnFailed(EventHandler)
或task.addEventXXX(EventType, EventHandler)
,其中XXX
是Filter
或Handler
protected void failed()
method in your Task
implementation and query the exception
property Task
实现中protected void failed()
方法,并查询exception
属性
failed()
method will always be called on the JavaFX Application Thread failed()
方法将始终在JavaFX Application Thread上调用 call()
method before re-throwing it call()
方法中捕获并处理异常 You need an Executor to start the thread 您需要一个执行程序来启动线程
Executor exec = Executors.newCachedThreadPool(runnable -> {
Thread t = new Thread(runnable);
t.setDaemon(true);
return t;
});
exec.execute(task);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.