我正在构建一个简单的JavaFX应用程序,它要求我在主应用程序窗口前面启动一个模态窗口。使用下面的代码,我能够启动模态窗口1次并关闭它。如果我再次尝试启动它,我会收到:
java.lang.IllegalArgumentException: BorderPane[id=root, styleClass=root]is already set as root of another scene
我正在使用这里描述的Spring Controller / FXML View依赖注入方法: http://www.zenjava.com/2012/02/20/porting-first-contact-to-spring/
我能够以编程方式创建场景并隐藏/显示简单的对话框,而无需使用FXML / Spring Controller注入。这很好。
我无法解释'已设置为root'异常,因为每次单击startButton时我都会创建一个新的Scene()。第一次关闭模态窗口时,第一个场景应该被销毁。
相关文件如下。
MainTabPanel.java - 我的应用程序的主视图。这包含单击以启动模态窗口的'startButton'。
ActivePresentation Controller / View注入:
@Inject private ActivePresentation activePresentation;
下面是在点击startButton时尝试启动模态的initialize()方法。
@FXML
public void initialize()
{
availableReceiversIdColumn.setCellValueFactory(new PropertyValueFactory("id"));
availableReceiversFirmwareVersionColumn.setCellValueFactory(new PropertyValueFactory("firmwareVersion"));
availableReceiversModelColumn.setCellValueFactory(new PropertyValueFactory("model"));
availableReceiversChannelColumn.setCellValueFactory(new PropertyValueFactory("channel"));
ObservableList<String> responseTypes = FXCollections.observableArrayList();
responseTypes.add("Single Response Alpha");
responseTypes.add("Single Response Numeric");
responseTypeChoiceBox.setItems(responseTypes);
startButton.setOnAction(new EventHandler<ActionEvent>()
{
@Override
public void handle(ActionEvent e)
{
Stage stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);
presentationResponseService.startPresentation();
activePresentation.populateResponses(null);
activePresentation.populateResults(null);
Scene activePresentationScene = new Scene(activePresentation.getView());
activePresentationScene.getStylesheets().add("styles.css");
stage.setScene(activePresentationScene);
stage.setTitle("Active Presentation");
stage.showAndWait();
}
});
}
closeButton在模态对话框中定义如下。
closeButton.setOnAction(new EventHandler<ActionEvent>()
{
@Override
public void handle(ActionEvent e)
{
presentationResponseService.closePresentation();
Stage stage = (Stage) root.getScene().getWindow();
stage.close();
}
});
ActivePresentation bean和FXML加载器的基于Java的Spring配置如下。
@Bean
public ActivePresentation activePresentation()
{
return loadPresenter("/fxml/ActivePresentation.fxml");
}
FXML Loader
private <T> T loadPresenter(String fxmlFile)
{
try
{
FXMLLoader loader = new FXMLLoader();
loader.load(getClass().getResourceAsStream(fxmlFile));
return (T) loader.getController();
} catch (IOException e)
{
throw new RuntimeException(String.format("Unable to load FXML file '%s'", fxmlFile), e);
}
}
答案 0 :(得分:0)
你每次创建一个舞台,而前一个仍然活着,所以,你可以尝试在stage.close()附近添加stage.setScene(null)。
或者每次都使用相同的场景或同一个舞台?
我在JFX的这一部分没有看到任何错误:节点是相同的,阶段(和其中的场景)是不同的。所以有两种方法:只使用1个阶段+场景,或者每次都创建不同的边框窗格实例。
答案 1 :(得分:0)
当我有一个自动装配的弹出窗口时,我遇到了问题。它是第一次工作,但是当我第二次关闭弹出窗口时,我收到了这个错误 我通过检查弹出窗口是否已有场景来管理,请参阅以下代码:
if (window.getScene() == null) {
Scene scene = new Scene(window);
stage.setScene(scene);
} else {
stage.setScene(window.getScene());
}