我有场景 1 并且写了下面的代码到这个场景 1 转到另一个场景 2:
主类:
public class ProjectSeventh extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("/FXMLfiles/FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
sceneOne 受控代码:
public class FXMLDocumentController implements Initializable {
@FXML Label itemCouner;
public void frize(Event event) throws IOException {
FXMLLoader watingLoader = new FXMLLoader();
watingLoader.setLocation(getClass().getResource("/FXMLfiles/wating.fxml"));
Parent watingParent = watingLoader.load();
Scene watingScene = new Scene(watingParent);
Stage watingStage = (Stage) ((Node) event.getSource()).getScene().getWindow();
watingStage.setScene(watingScene);
watingStage.show();
}
@Override
public void initialize(URL url, ResourceBundle rb) {
Random myRand = new Random();
int holdingFrizes = myRand.nextInt(2);
}
}
我想当场景 2 出现时,6 秒后场景 2 自动回到场景 1,没有任何事件!但是我学习的这个切换场景协议需要在“(节点)event.getSource()”处有一个事件我该怎么办?
scene2 控制器代码:
public class WatingController implements Initializable {
public void getBackPreviousScene() throws IOException{
PauseTransition myPouse = new PauseTransition();
myPouse.setDuration(javafx.util.Duration.seconds(6));
myPouse.setOnFinished((event) -> {
try {
FXMLLoader shopingLoader = new FXMLLoader();
shopingLoader.setLocation(getClass().getResource("/FXMLfiles/FXMLDocument.fxml"));
Parent shopingParent = shopingLoader.load();
Scene shopingScene = new Scene(shopingParent);
Stage shopingStage = (Stage) ((Node) event.getSource()).getScene().getWindow();
shopingStage.setScene(shopingScene);
shopingStage.show();
} catch (IOException ex) {
}
});
myPouse.play();
}
@Override
public void initialize(URL url, ResourceBundle rb) {
try {
getBackPreviousScene();
} catch (IOException ex) {
}
}
}
答案 0 :(得分:1)
您的代码在 ClassCastException
中定义的 onFinished
处理程序中生成一个 getBackPreviousScene()
,因为事件源是 PauseTransition
,而不是 {{1} }.它没有 Node
或访问权限。
首先,一般来说,使用事件源并不是访问场景的好方法。相反,您可以简单地在控制器中的任何注入节点上调用 Scene
。例如:
getScene()
另请注意,如果您正在获取包含场景的窗口,该场景包含发生事件的节点,则该窗口必须已经显示,因此调用毫无意义
public class FXMLDocumentController implements Initializable {
@FXML Label itemCouner;
public void frize(Event event) throws IOException {
FXMLLoader watingLoader = new FXMLLoader();
watingLoader.setLocation(getClass().getResource("/FXMLfiles/wating.fxml"));
Parent watingParent = watingLoader.load();
Scene watingScene = new Scene(watingParent);
Stage watingStage = (Stage)itemCouner.getScene().getWindow();
watingStage.setScene(watingScene);
// watingStage.show();
}
@Override
public void initialize(URL url, ResourceBundle rb) {
Random myRand = new Random();
int holdingFrizes = myRand.nextInt(2);
}
}
在上面的代码中。您可以通过将某个节点注入控制器来在 watingStage.show();
中执行相同的操作。
其次,WatingController
似乎是控制 FXML 中声明的 UI 显示多长时间的错误位置。这应该是显示它的代码的责任,在本例中是 WatingController
类中的 frize()
方法。特别是,这使得无法提前加载 FXML 并在稍后显示它,因为在 6 秒后调用 FXMLDocumentController
会抛出空指针异常。
因此,例如,您可以这样做:
getScene().getWindow()
然后您的 public class FXMLDocumentController implements Initializable {
@FXML Label itemCouner;
public void frize(Event event) throws IOException {
FXMLLoader watingLoader = new FXMLLoader();
watingLoader.setLocation(getClass().getResource("/FXMLfiles/wating.fxml"));
Parent watingParent = watingLoader.load();
Scene watingScene = new Scene(watingParent);
Scene currentScene = itemCouner.getScene();
Stage stage = (Stage) currentScene.getWindow();
stage.setScene(watingScene);
PauseTransition pause = new PauseTransition(Duration.seconds(6));
pause.setOnFinished(e -> stage.setScene(currentScene));
pause.play();
}
@Override
public void initialize(URL url, ResourceBundle rb) {
}
}
中的代码都可以删除。
最后,请注意,在您的示例中,似乎根本不需要创建新场景。只需替换现有场景的根:
WatingController
primary.fxml
public class FXMLDocumentController implements Initializable {
@FXML Label itemCouner;
public void frize(Event event) throws IOException {
FXMLLoader watingLoader = new FXMLLoader();
watingLoader.setLocation(getClass().getResource("/FXMLfiles/wating.fxml"));
Parent watingParent = watingLoader.load();
Scene currentScene = itemCouner.getScene();
Parent currentRoot = currentScene.getRoot();
currentScene.setRoot(watingParent);
PauseTransition pause = new PauseTransition(Duration.seconds(6));
pause.setOnFinished(e -> currentScene.setRoot(currentRoot));
pause.play();
}
@Override
public void initialize(URL url, ResourceBundle rb) {
}
}
PrimaryController.java:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Button?>
<?import javafx.geometry.Insets?>
<VBox alignment="CENTER" spacing="20.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.jamesd.examples.tempscene.PrimaryController">
<children>
<Button fx:id="showTempButton" text="Show Temporary View" onAction="#showTemp"/>
</children>
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding>
</VBox>
temp.fxml:
package org.jamesd.examples.tempscene;
import java.io.IOException;
import javafx.animation.PauseTransition;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.util.Duration;
public class PrimaryController {
@FXML
private Button showTempButton ;
@FXML
private void showTemp() throws IOException {
Scene currentScene = showTempButton.getScene();
Parent currentRoot = currentScene.getRoot();
FXMLLoader loader = new FXMLLoader(getClass().getResource("temp.fxml"));
Parent tempRoot = loader.load();
currentScene.setRoot(tempRoot);
PauseTransition pause = new PauseTransition(Duration.seconds(2));
pause.setOnFinished(e -> currentScene.setRoot(currentRoot));
pause.play();
}
}
App.java:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Button?>
<?import javafx.geometry.Insets?>
<VBox alignment="CENTER" spacing="20.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" >
<children>
<Label text="Temporary View" />
</children>
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding>
</VBox>