我想从外部线程(而不是主线程)在javafx中打开一个新窗口(Stage)。我的代码吼叫不起作用,请帮助我。
这是我的java代码:
public void login(ActionEvent event)
{
Task task = new javafx.concurrent.Task<Void>()
{
@Override
protected Void call() throws Exception
{
loader.setVisible(true);
if(Compte.login(username.getText(), password.getText()))
{
Parent root = FXMLLoader.load(getClass().getResource("/views/PrincipalFram.fxml"));
Scene scene = new Scene(root);
Stage stage = new Stage();
stage.setScene(scene);
stage.setTitle("My Title");
stage.show();
}
else
{
//TODO
}
return null;
}
@Override
protected void succeeded()
{
loader.setVisible(false);
}
@Override
protected void failed()
{
loader.setVisible(false);
}
};
Thread thread = new Thread(task);
thread.setDaemon(true);
thread.start();
}
答案 0 :(得分:0)
仅对后台线程执行 耗时的工作。所有UI工作必须在FX应用程序线程上完成。 (documentation for Stage
明确声明“必须在FX应用程序线程上构造和修改舞台对象”。)所以你应该这样做:
public void login(ActionEvent event) {
Task<Boolean> loginTask = new Task<Boolean>() {
@Override
protected Boolean call() throws Exception {
return Compte.login(username.getText(), password.getText());
}
};
loginTask.setOnSucceeded(e -> {
if (loginTask.getValue()) {
Parent root = FXMLLoader.load(getClass().getResource("/views/PrincipalFram.fxml"));
Scene scene = new Scene(root);
Stage stage = new Stage();
stage.setScene(scene);
stage.setTitle("My Title");
stage.show();
} else {
//TODO
}
loader.setVisible(false);
});
loginTask.setOnFailed(e -> {
loader.setVisible(false);
});
Thread thread = new Thread(task);
thread.setDaemon(true);
loader.setVisible(true);
thread.start();
}