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

时间:2015-02-24 09:39:34

标签: java swing javafx fxml

假设我有一个带有按钮的窗口。每次按下该按钮时,我希望处理当前窗口并显示一个新窗口。

在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);
    }
     }

尝试创建新窗口:http://sv.tinypic.com/r/1jkq4w/8

FXML:

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.text.*?>

<VBox prefHeight="430.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="blackjack.FXMLDocumentController">
  <children>
    <AnchorPane maxHeight="-1.0" maxWidth="-1.0" prefHeight="-1.0" prefWidth="-1.0" VBox.vgrow="ALWAYS">
      <children>
            <Label fx:id="labelPlayerTotal" layoutX="510.0" layoutY="335.0" prefHeight="15.0" prefWidth="121.0" text="Playertotal:" />
            <Label fx:id="labelDealerTotal" layoutX="510.0" layoutY="359.0" prefHeight="15.0" prefWidth="112.0" text="Dealertotal:" />
            <TextArea fx:id="dealerArea" layoutY="29.0" prefHeight="159.0" prefWidth="503.0" />
            <TextArea fx:id="playerArea" layoutY="244.0" prefHeight="159.0" prefWidth="503.0" />
            <Button fx:id="stayButton" layoutX="512.0" layoutY="173.0" mnemonicParsing="false" onAction="#drawCardForDealer" prefHeight="25.0" prefWidth="72.0" text="STAY" />
            <Button fx:id="hitButton" layoutX="512.0" layoutY="130.0" mnemonicParsing="false" onAction="#drawCardForPlayer" prefHeight="25.0" prefWidth="72.0" text="HIT" />
            <Label fx:id="labelWinner" layoutX="104.0" layoutY="208.0" prefHeight="15.0" prefWidth="296.0" />
            <MenuBar fx:id="helpBar">
              <menus>
                <Menu mnemonicParsing="false" text="Help">
                  <items>
                    <MenuItem mnemonicParsing="false" onAction="#aboutApplication" text="About" />
                  </items>
                </Menu>
              </menus>
            </MenuBar>
      </children>
    </AnchorPane>
  </children>
</VBox>

1 个答案:

答案 0 :(得分:0)

您可以通过调用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")));
    }

    // ...
}