如何在同一阶段JavaFX中切换到新场景

时间:2014-12-13 15:55:49

标签: java javafx-2

我尝试在同一阶段的场景之间切换。我是JavaFX的初学者,所以我不知道如何在没有意大利面条代码的情况下轻松完成。当我开始下面的代码时,我在showCarChoosePage方法(第二个场景)的rootLayout.setCenter(内容)中得到空指针。我知道rootLayout为null我正在尝试创建新场景并将其加载到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);
}

}

2 个答案:

答案 0 :(得分:0)

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

在这个简单的例子中,Person对象是使用名称,性别和年龄类变量以及这些对象的setter和getter创建的。

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

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

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

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必须按如下方式初始化舞台和共享数据。舞台和共享数据在加载时都会传递给第一个场景。

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);
    }
}

答案 1 :(得分:-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();
    }
}