如何在用FXML构建的JavaFx中重新启动应用程序?

如何在用FXML构建的JavaFx中重新启动应用程序?,java,swing,javafx,fxml,Java,Swing,Javafx,Fxml,假设我有一个带按钮的窗口。每次按下该按钮,我都希望当前窗口被释放,并显示一个新窗口 在Swing中,这很容易,但我在JavaFx中找不到它的语法? 那么在本例中,使用我的示例代码,我如何做到这一点 public class Main extends Application { Parent root; Scene scene; @Override public void start(Stage primaryStage) throws Exception {

假设我有一个带按钮的窗口。每次按下该按钮,我都希望当前窗口被释放,并显示一个新窗口

在Swing中,这很容易,但我在JavaFx中找不到它的语法? 那么在本例中,使用我的示例代码,我如何做到这一点

public class Main extends Application {

    Parent root;
    Scene scene;

    @Override
    public void start(Stage primaryStage) throws Exception {
        root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));

        scene = new Scene(root);

        primaryStage.setScene(scene);

        primaryStage.sizeToScene();
        primaryStage.setResizable(false);

        primaryStage.show();


        root.setOnMouseClicked((MouseEvent mouseEvent) -> {
            if (mouseEvent.getButton().equals(MouseButton.PRIMARY)) {
                if (mouseEvent.getClickCount() == 2) {



                        Stage stage = new Stage();
                        stage.setScene(primaryStage.getScene());
                        stage.show();
                        primaryStage.close();


                }
            }
        });
    }


    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }
     }
正在尝试创建新窗口:

FXML:


您可以通过调用hide或close来隐藏窗口,即处理窗口。 您只需显示一个新窗口,其代码与您以前使用的代码完全相同:

                primaryStage.close();

                Stage stage = new Stage();

                root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));

scene = new Scene(root);

stage.setScene(scene);

stage.sizeToScene();
stage.setResizable(false);

stage.show();
但这对于你想要实现的目标来说似乎太过分了。为什么不替换现有场景的根,并使用现有舞台

try {
    scene.setRoot(FXMLLoader.load(getClass().getResource("FXMLDocument.fxml")));
} catch (Exception exc) {
    exc.printStackTrace();
    throw new RuntimeException(exc);
}
请注意,无论采用哪种方式,现在都已替换了场景的根;新根目录没有与之关联的相同鼠标处理程序。如果使用第二种方法,则可以将处理程序放在场景中,而场景不会改变。或者,更好的方法是,您可以在FXML和控制器中定义侦听器:

<VBox prefHeight="430.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="blackjack.FXMLDocumentController"
fx:id="root"
onMouseClicked="reload">
<!-- ... -->
</VBox>
package blackjack ;

public class FXMLDocumentController {

    // ...

    @FXML
    private VBox root ;

    // ...

    @FXML
    private void reload() throws Exception {

        // Really, it would be way better here to reset the whole UI to its initial
        // state, instead of reloading it from scratch. This should work as a 
        // quick hack though.
        Scene scene = root.getScene();
        scene.setRoot(FXMLLoader.load(Main.class.getResource("FXMLDocument.fmxl")));
    }

    // ...
}

您需要处理窗口还是仅处理当前fxml也适用于您?。每次按下该按钮时,我都希望处理当前窗口并显示新窗口。在秋千上,那很容易,。。可能很简单,但不推荐。看看Java FX是否将开发人员限制在一个对其有利的“框架”内。@AndrewThompson谢谢你Andrew,我需要在我的Java FX应用程序中使用这个重新启动按钮,这对我的应用程序非常必要。这可能吗?您在Swing中使用了什么来重新启动应用程序?@ItachiUchiha this.dispose要处理当前窗口,请选择new window.setVisibletrue。。如果我没记错语法,效果很好。当我双击时,当前窗口被释放并显示一个新窗口。伟大的但是,当我在新窗口中再次尝试此操作时,该函数不起作用。你知道为什么它只在第一次起作用吗?难道不能用System.exit删除所有内容并加载一个新的UI吗?哦,是的,因为鼠标侦听器只添加到第一个根目录中,然后被替换。我会更新。是的,我同意重置整个UI更好。这很乱,不过还是谢谢你。如果我想重置整个UI,System.exit然后加载fxml是否足够?或者我该怎么做?我的意思是重置所有的UI组件。如果这太难编写代码,那么您可能需要学习一些设计策略,尽管这是一个更高级的主题。这样做的目的是减少对系统的影响,而不是更多。如果调用System.exit。。。;,您将完全退出应用程序,因此在此之后的任何代码都不会执行。我认为以我展示的方式重新加载控制器是一种合理的折衷。好的,谢谢。我对这么小的东西要花这么多功夫感到惊讶。荡秋千要容易得多。
package blackjack ;

public class FXMLDocumentController {

    // ...

    @FXML
    private VBox root ;

    // ...

    @FXML
    private void reload() throws Exception {

        // Really, it would be way better here to reset the whole UI to its initial
        // state, instead of reloading it from scratch. This should work as a 
        // quick hack though.
        Scene scene = root.getScene();
        scene.setRoot(FXMLLoader.load(Main.class.getResource("FXMLDocument.fmxl")));
    }

    // ...
}