场景变化与窗格变化

时间:2015-06-19 17:10:23

标签: javafx

我是Java的新手,特别是JavaFX。我正在尝试制作一个菜单,用于在buttonclick上切换显示的内容。我现在通过清除窗格并将新的fxml文件添加到其中来完成此操作。 这是我的Controller中的一种方法:

protected void CustomStart(ActionEvent event) {

        content.getChildren().clear();
        try {

            content.getChildren().add(
                    (Node) FXMLLoader.load(getClass().getResource(
                            "/view/CustomStartStructure.fxml")));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

到目前为止工作得很好,但我也喜欢通过改变场景来做到这一点。

我想在构造函数中启动fxml文件的场景。它适用于另一种方法。但是如果我尝试在构造函数中启动它,我会得到一个由StackOverflow错误导致的RuntimeException引起的InvocationTargetException。如果我在另一个方法中执行它,当我尝试更改场景时,我得到一个NullPointerException。

这是构造函数

public Game() throws IOException {

        this.MainMenu = new Scene((GridPane) FXMLLoader.load(getClass()
                .getResource("/view/MainMenuStructure.fxml")), 400, 400);
        this.stage = new Stage();
        this.stage.setScene(MainMenu);

    }

这是调用工作的方法:

public void run() throws Exception {
        /**
         * Set the Scenes for the different menus by using the panels from the
         * fxml-files
         */

        this.MainMenu = new Scene((GridPane) FXMLLoader.load(getClass()
                .getResource("/view/MainMenuStructure.fxml")), 400, 400);
        MainMenu.getStylesheets().add(
                getClass().getResource("/view/MainMenuDesign.css")
                        .toExternalForm());
        this.SingleRaceMenu = new Scene((GridPane) FXMLLoader.load(getClass()
                .getResource("/view/CustomStartStructure.fxml")), 400, 400);
        /** Giving the Stage a Scene */
        this.setStage(new Stage());
        this.stage.setScene(MainMenu);
        this.stage.show();
}

这是Buttoncontroller:

protected void CustomStart(ActionEvent event) {
        this.getStage().setScene(getSingleRaceMenu());

    }

我希望你能给我一个建议!

1 个答案:

答案 0 :(得分:0)

以下是一个包​​含two fxml个文件的简单示例,loaded into separate scenes和场景都设置为same Stage

仅为scene1.fxml定义控制器,因为这是如何使用控制器上的按钮事件更改场景的基本示例。

示例中的重要部分是看我如何使用按钮引用获取当前阶段引用,该引用已经是场景图的一部分:

((Stage)button.getScene().getWindow())

如果您想了解如何切换场景,并回到上一个场景,您可以通过在各自的场景中加载fxml来实现以下示例:

Loading new fxml in the same scene

实施例

<强> scene1.fxml

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>

<VBox alignment="CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" spacing="10.0" style="-fx-background-color: goldenrod;" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Controller">
    <children>
        <Label text="Scene 1" />
        <Button fx:id="button" mnemonicParsing="false" onAction="#changeScene" text="Change Scene" />
    </children>
</VBox>

<强> scene2.fxml

<?import javafx.scene.layout.VBox?>

<VBox alignment="CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" spacing="10.0" style="-fx-background-color: cyan;" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
    <children>
        <Label text="You have switched to Scene 2" />
    </children>
</VBox>

Scene1 Controller

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;

import java.io.IOException;

public class Controller {

    @FXML
    private Button button;

    @FXML
    public void initialize() {
    }

    @FXML
    private void changeScene(ActionEvent event) {
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("/scene2.fxml"));
            Parent parent = loader.load();
            ((Stage)button.getScene().getWindow()).setScene(new Scene(parent, 200, 200));
        } catch (IOException eox) {
            eox.printStackTrace();
        }
    }
}

主要

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) {
        try {
            FXMLLoader fxmlloader = new FXMLLoader(Main.class.getResource("/scene1.fxml"));
            VBox root = fxmlloader.load();
            Scene scene = new Scene(root, 200, 200);
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

输出

enter image description here

enter image description here