第二次启动模式对话框时,JavaFX“已设置为另一个场景的根”异常

时间:2013-05-01 16:13:09

标签: javafx-2

我正在构建一个简单的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);
      }
 }

2 个答案:

答案 0 :(得分:0)

似乎,舞台仍在JFX的控制之下(逻辑:你可以尝试再次打开它)。

你每次创建一个舞台,而前一个仍然活着,所以,你可以尝试在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());
}