【问题标题】:How to swtich to new scene in the same stage JavaFX同阶段JavaFX如何切换到新场景
【发布时间】:2015-02-12 04:10:02
【问题描述】:

我尝试在同一阶段的场景之间切换。我是 JavaFX 的初学者,所以我不知道如何在没有意大利面条代码的情况下轻松做到这一点。当我开始下面的代码时,我在 showCarChoosePage 方法(第二个场景)中的 rootLayout.setCenter(content) 处获得了空指针。我知道 rootLayout 是空的,我正在尝试创建新场景并将其加载到 primaryStage 但后来我也得到了空指针。 showCarChoosePage 方法是从 LoginController 调用的。感谢您的帮助

public class MC extends Application {
    public Scene scene;
    private GridPane grid;
    public AnchorPane content;
    public BorderPane rootLayout;
    public Stage primaryStage;

@Override
public void start(Stage primaryStage) {

    this.primaryStage = primaryStage;
    this.primaryStage.setTitle("VMHT v0.1");

    try {
        FXMLLoader loader = new FXMLLoader(MC.class.getResource("view/RootLayout.fxml"));
        rootLayout = (BorderPane) loader.load();
        Scene scene = new Scene(rootLayout);
        primaryStage.setScene(scene);
        primaryStage.show();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    showLoginPage();
    //showCarChoosePage();

}
public void showLoginPage(){

    try {
        FXMLLoader loader = new FXMLLoader(MC.class.getResource("view/LoginView.fxml"));
        content = (AnchorPane) loader.load();
        rootLayout.setCenter(content);

        LoginController controller = loader.getController();
        controller.setMC(this);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }  
}

public void showCarChoosePage(){

    try {
        FXMLLoader loader = new FXMLLoader(MC.class.getResource("view/CarChooseView.fxml"));
        AnchorPane content = (AnchorPane) loader.load();
        rootLayout.setCenter(content);

        CarChooseController controller = loader.getController();
        controller.setMC(this); 
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }  

}

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

}

【问题讨论】:

    标签: java javafx-2


    【解决方案1】:

    这是您可以尝试的一种简单方法

    import javafx.stage.Stage;
    
    public class ManyScenes extends Application {
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Application.launch(args);
    }
    
    @Override
    public void start(final Stage primaryStage) {
        primaryStage.setTitle("Hello World");
    
        Group root1 = new Group();
        Group root2 = new Group();
        Group root3 = new Group();
    
        final Scene scene1 = new Scene(root1, 300, 250);
        final Scene scene2 = new Scene(root2, 300, 250);
        final Scene scene3 = new Scene(root3, 300, 250);
    
        Button go1 = new Button();
        go1.setLayoutX(100);
        go1.setLayoutY(80);
        go1.setText("Go  to scene2");
        go1.setOnAction(new EventHandler<ActionEvent>() {
    
            public void handle(ActionEvent event) {
                primaryStage.setScene(scene2);
            }
        });
        root1.getChildren().addAll(new Label("Scene 1"), go1);
    
        Button go2 = new Button();
        go2.setLayoutX(100);
        go2.setLayoutY(80);
        go2.setText("Go to scene3");
        go2.setOnAction(new EventHandler<ActionEvent>() {
    
            public void handle(ActionEvent event) {
                primaryStage.setScene(scene3);
            }
        });
    
        root2.getChildren().addAll(new TextField(), go2);
    
        Button go3 = new Button();
        go3.setLayoutX(100);
        go3.setLayoutY(80);
        go3.setText("Back to scene1");
        go3.setOnAction(new EventHandler<ActionEvent>() {
    
            public void handle(ActionEvent event) {
                primaryStage.setScene(scene1);
            }
        });
    
        root3.getChildren().addAll(new TextArea(), go3);
    
        primaryStage.setScene(scene1);
        primaryStage.show();
        }
    }
    

    【讨论】:

      【解决方案2】:

      这是处理多个场景的另一种方法。它为每个场景使用控制器。您必须将在 Main 中创建的初始阶段传递给每个新 Controller。您还必须将想要从控制器共享的任何数据传递给控制器​​。这一切都是通过添加到控制器中的方法完成的。

      在这个简单的例子中,创建了一个 Person 对象,其中包含 name、sex 和 age 类变量以及这些对象的 setter 和 getter。

      然后我创建了 3 个显示姓名、性别和年龄值的 fxml 文件(使用 SceneBuilder)。当然,我还创建了 3 个控制器,每个 fxml 文件一个。

      允许用户编辑这些值。一个场景允许输入姓名,另一个允许输入性别,最后一个允许输入年龄。这模拟了一个复杂的应用程序,其中数据输入和处理分为 3 个不同的场景。

      三个 fxml 文件和三个控制器看起来非常相似。这是名称控制器。它首先具有 Stage 和 Person 对象的设置器。它还具有按钮事件处理程序,以允许用户导航到其他阶段。

      package multiscene;
      
      import javafx.event.ActionEvent;
      import javafx.fxml.FXML;
      import javafx.fxml.FXMLLoader;
      import javafx.fxml.Initializable;
      import javafx.scene.Scene;
      import javafx.scene.control.TextField;
      import javafx.scene.layout.AnchorPane;
      import javafx.stage.Stage;
      
      import java.net.URL;
      import java.util.ResourceBundle;
      
      public class NameController implements Initializable {
      
          @FXML private TextField lblSex;
          @FXML private TextField lblAge;
          @FXML private TextField txtName;
          private Stage myStage;
          private Person person;
      
          public void setStage(Stage myStage) {
              this.myStage = myStage;
          }
      
          public void setPerson(Person person) {
              this.person = person;
              lblAge.setText(person.getAge());
              txtName.setText(person.getName());
              lblSex.setText(person.getSex());
          }
      
          @FXML
          private void ageClicked(ActionEvent event) throws Exception{
              FXMLLoader loader = new FXMLLoader();
              loader.setLocation(NameController.class.getResource("Age.fxml"));
              AnchorPane page = (AnchorPane) loader.load();
              Stage dialogStage = new Stage();
              dialogStage.setTitle("Person Editor");
              // dialogStage.initModality(Modality.WINDOW_MODAL);
              //dialogStage.initOwner(primaryStage);
              Scene scene = new Scene(page);
              dialogStage.setScene(scene);
      
              // Set the person into the controller
              person.setName(txtName.getText());
              AgeController newController = loader.getController();
              newController.setStage(dialogStage);
              newController.setPerson(person);
              dialogStage.show();
              myStage.close();
          }
      
          @FXML
          private void sexClicked(ActionEvent event) throws Exception {
              FXMLLoader loader = new FXMLLoader();
              loader.setLocation(AgeController.class.getResource("Sex.fxml"));
              AnchorPane page = (AnchorPane) loader.load();
              Stage dialogStage = new Stage();
              dialogStage.setTitle("Person Editor");
              // dialogStage.initModality(Modality.WINDOW_MODAL);
              //dialogStage.initOwner(primaryStage);
              Scene scene = new Scene(page);
              dialogStage.setScene(scene);
      
              // Set the person into the controller
              person.setName(txtName.getText());
              SexController newController = loader.getController();
              newController.setStage(dialogStage);
              newController.setPerson(person);
              dialogStage.show();
              myStage.close();
          }
      
          @Override
          public void initialize(URL url, ResourceBundle rb) {
              // TODO
          }
      
      }  
      

      Main.java 必须按如下方式初始化 Stage 和共享数据。加载时,Stage 和共享数据都会传递给第一个 Scene。

      package multiscene;
      
      import javafx.application.Application;
      import javafx.fxml.FXMLLoader;
      import javafx.scene.Scene;
      import javafx.scene.layout.AnchorPane;
      import javafx.stage.Stage;
      
      public class Main extends Application {
      
          @Override
          public void start(Stage primaryStage) throws Exception{
              Person person = new Person();
              FXMLLoader loader = new FXMLLoader();
              loader.setLocation(Main.class.getResource("Name.fxml"));
              AnchorPane page = (AnchorPane) loader.load();
              Stage dialogStage = new Stage();
              dialogStage.setTitle("Person Editor");
              Scene scene = new Scene(page);
              dialogStage.setScene(scene);
              NameController nameController = loader.getController();
              nameController.setStage(dialogStage);
              nameController.setPerson(person);
              dialogStage.show();
          }
      
          public static void main(String[] args) {
              launch(args);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-09-09
        • 2020-03-23
        • 2021-05-29
        • 1970-01-01
        • 1970-01-01
        • 2016-04-13
        • 1970-01-01
        相关资源
        最近更新 更多