场景切换问题(从一个场景过渡到另一个场景)
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
加载完成后,我enable
Button
。如果单击 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>
我正在编写一个包含 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
加载完成后,我enable
Button
。如果单击 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>