指定第二个 javafx 后的场景返回前一个场景

时间:2021-05-12 14:55:27

标签: javafx

我有场景 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) {
    }
        
    }    

    
    
}
    

1 个答案:

答案 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>
相关问题