场景切换问题(从一个场景过渡到另一个场景)

Problems switching scenes (transitioning from one to another)

我正在编写一个包含 2 个场景的 GUI,第一个是连接到服务器的场景(已经编写并且运行良好),第二个是游戏本身。

我已经查阅了教程,但到目前为止我还没有看到可以加载 FXML 的教程。我试过自己做,但没有成功。我已经实现了 2 个单独的控制器和 2 个单独的 FXML,但我无法在 Main.java 中实现上述所有内容,并且无法使用按钮切换场景,我的代码目前看起来像这样.

Main.java

public class Main extends Application {
Stage window;
Scene scene1, scene2;

@Override
public void start(Stage primaryStage) throws Exception {
    window = primaryStage;

    Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
    primaryStage.setTitle("GUI v3.0");
    primaryStage.setScene(new Scene(root, 700, 700));
    primaryStage.getIcons().add(new Image("/sample/R_enormousRing.png"));
    primaryStage.show();

    //Stage 2
    //secondaryStage.setScene(new Scene(root, 700, 700));
    Parent secondary = FXMLLoader.load(getClass().getResource("sample2.fxml"));


    String hostName = "localhost"; // hard coded at the moment, but I'm trying to get the values from the "login" scene and use those 
    int portNumber = 2123; //idem
    Socket serverSocket = new Socket(hostName, portNumber);

Controller.java

public class Controller {


@FXML
private GridPane grid;

public void initialize() {
// useless code for now
}

Controller2.java

public class Controller2 {

//empty for now 



}

我希望现在不需要 FXML。

更新代码

public class Main extends Application {
@FXML
public Button button;

@Override
public void start(Stage primaryStage) throws Exception {
    FXMLLoader loader = new FXMLLoader(getClass().getResource("SceneOneController.fxml"));
    Parent root = loader.load();
    primaryStage.setTitle("GUI v3.0");
    primaryStage.setScene(new Scene(root, 700, 700));
    primaryStage.getIcons().add(new Image("/sample/R_enormousRing.png"));
    primaryStage.show();

    //Stage 2
    //secondaryStage.setScene(new Scene(root, 700, 700));

    button.setOnMouseClicked((MouseEvent event) -> {
        FXMLLoader innerLoader = new FXMLLoader(getClass().getResource("MainController.fxml"));
        try
        {
            Stage stage = new Stage();
            Parent innerRoot = innerLoader.load();
            stage.setTitle("Scene One");
            stage.setScene(new Scene(innerRoot, 700, 700));
            stage.show();
            primaryStage.close();
        } catch (IOException e)
        {
            e.printStackTrace();
        }

    });

和错误

Exception in Application start method
java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:473)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:372)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:945)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:973)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication(LauncherImpl.java:198)
    at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: java.lang.NullPointerException
    at sample.Main.start(Main.java:35)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1(LauncherImpl.java:919)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait(PlatformImpl.java:449)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater(PlatformImpl.java:418)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater(PlatformImpl.java:417)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop(WinApplication.java:175)
    ... 1 more
Exception running application sample.Main

在此示例应用程序中,我添加了一个 Button。我将 Button 设置为 disabled。我加载 Splash Screen。当Splash Screen加载完成后,我enableButton。如果单击 Button,它会加载第一个 Scene

Main

import java.io.IOException;
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.event.Event;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;

public class JavaFXApplication104 extends Application
{

    @Override
    public void start(Stage primaryStage) throws Exception
    {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLDocument.fxml"));
        Parent root = loader.load();
        FXMLDocumentController mainController = loader.getController();

        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();

        Button button = mainController.getButton();
        button.setOnAction(event -> {
            FXMLLoader innerLoader = new FXMLLoader(getClass().getResource("SceneOne.fxml"));
            try {

                Stage stage = new Stage();
                Parent innerRoot = innerLoader.load();
                stage.setTitle("Scene One");
                stage.setScene(new Scene(innerRoot, 500, 500));
                stage.show();
                primaryStage.close();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        });
        button.setDisable(true);

        final Task task = new Task<Void>()
        {
            @Override
            protected Void call() throws Exception
            {
                for (int i = 1; i < 100000000; i++) {
                    updateProgress(i, 100000000);
                }

                return null;
            }
        };

        task.setOnSucceeded((Event event) -> {
            button.setDisable(false);
        });

        mainController.getPBSplashValue().progressProperty().bind(task.progressProperty());
        mainController.getPISplash().progressProperty().bind(task.progressProperty());

        new Thread(task).start();

    }

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

1st Controller

import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.ProgressIndicator;

/**
 *
 * @author blj0011
 */
public class FXMLDocumentController implements Initializable
{

    @FXML
    ProgressBar pbSplash;
    @FXML
    ProgressIndicator piSplash;

    @FXML
    Button button;

    public ProgressBar getPBSplashValue()
    {
        return pbSplash;
    }

    public ProgressIndicator getPISplash()
    {
        return piSplash;
    }

    public Button getButton()
    {
        return button;
    }

    @Override
    public void initialize(URL location, ResourceBundle resources)
    {

    }
}

1st FXML

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ProgressBar?>
<?import javafx.scene.control.ProgressIndicator?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>

<StackPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication104.FXMLDocumentController">
    <children>
      <VBox alignment="CENTER" prefHeight="200.0" prefWidth="100.0">
         <children>
              <VBox maxHeight="-Infinity" maxWidth="-Infinity">
                  <children>
                      <ProgressBar fx:id="pbSplash" prefWidth="200.0" progress="0.0" />
                      <ProgressIndicator fx:id="piSplash" progress="0.0" />
                  </children>
              </VBox>
            <Button fx:id="button" mnemonicParsing="false" text="Button" />
         </children>
      </VBox>
    </children>
</StackPane>

2nd Controller

import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.Initializable;

/**
 * FXML Controller class
 *
 * @author blj0011
 */
public class SceneOneController implements Initializable
{

    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb)
    {
        // TODO
    }

}

2nd 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.*?>

<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication104.SceneOneController">

</AnchorPane>