JavaFx 改变场景

JavaFx change scene

我是 javaFX 的新手,对 java 有初级水平的了解。我正在尝试构建一个最终会生成表单的简单应用程序。我想在选择按钮时改变场景,但我不知道如何做到这一点,我所阅读的所有内容都超出了我的水平。`

@Override
public void start(Stage primaryStage) {

         primaryStage.setTitle("Welcome to the Log Book Generator");
         /*Defining Options on Home screen*/

         Button btnR = new Button("Repair");
         Button btnM = new Button("Maintenance");
         Button btnW = new Button("Weather");
         Button btnO = new Button ("Other");
         Button btnU = new Button ("Filter Pickup");
         Button btnVC = new Button ("Verification/Calibration");
         Button btnE = new Button ("Exit");



    /*Actions upon button selection*/    
    btnR.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            System.out.println("Repair");
        }
    });
    btnM.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            System.out.println("Maintenance");
        }
    });
    btnW.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            System.out.println("Weather");
        }
    });
    btnO.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            System.out.println("Other");
        }
    });
    btnU.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            System.out.println("Filter Pickup");
        }
    });
    btnVC.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            System.out.println("Verification/Calibration");
        }
    });
    btnE.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            System.exit(0);
        }
    });
    Pane root = new Pane();
    /*StackPane root = new StackPane();
    /* Setting Button Layout*/
    btnM.setLayoutX(150);btnM.setLayoutY(150);
    btnR.setLayoutX(150);btnR.setLayoutY(250);
    btnW.setLayoutX(150);btnW.setLayoutY(350);
    btnO.setLayoutX(150);btnO.setLayoutY(150);
    btnU.setLayoutX(150);btnU.setLayoutY(450);
    btnVC.setLayoutX(150);btnVC.setLayoutY(550);
    btnE.setLayoutX(350);btnE.setLayoutY(650);
    /*Ask user for Selection*/
    Label label;
    label = new Label("Please select a task.");
    label.setFont(Font.font("Arial", 32));            
    root.getChildren().add(label);
    root.getChildren().add(btnE);
    root.getChildren().add(btnVC);
    root.getChildren().add(btnU);
    root.getChildren().add(btnO);
    root.getChildren().add(btnW);
    root.getChildren().add(btnM);
    root.getChildren().add(btnR);
    primaryStage.setScene(new Scene(root, 500, 750));
    primaryStage.show();
}

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    launch(args);
}

} ` 我计划在同一阶段将不同的部分制作成自己的场景。任何帮助,将不胜感激。我正在使用 NetBeans8.2.

您可以创建您的场景,初始化它们,并将它们设置为事件处理程序中的主要阶段,请注意,如果您尝试将 children 垂直添加到彼此之上,您应该考虑使用 VBox,如果您想将多个 children 添加到同一个 parent 中,您可以使用 addAll 而不是 add

这就是您将拥有的代码(我只做了前 3 个场景来向您展示它是如何工作的,您应该能够相应地完成其他场景)

// having a fixed size for the stage
double width = 500, height = 600;

// Creating scenes
Scene sceneR, sceneM, sceneW, sceneO, sceneU, sceneVC, mainMenu;

// saving the primaryStage to have access to it from other methods
Stage ps;

@Override
public void start(Stage primaryStage) {
    ps = primaryStage;

    //calling the initializing method
    initializeScenes();

    primaryStage.setTitle("Welcome to the Log Book Generator");
    /* Defining Options on Home screen */

    Button btnR = new Button("Repair");
    Button btnM = new Button("Maintenance");
    Button btnW = new Button("Weather");
    Button btnO = new Button("Other");
    Button btnU = new Button("Filter Pickup");
    Button btnVC = new Button("Verification/Calibration");
    Button btnE = new Button("Exit");

    /* Actions upon button selection */
    btnR.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            ps.setScene(sceneR);
        }
    });
    btnM.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            ps.setScene(sceneM);
        }
    });
    btnW.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            ps.setScene(sceneW);
        }
    });
    btnO.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            System.out.println("Other");
        }
    });
    btnU.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            System.out.println("Filter Pickup");
        }
    });
    btnVC.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            System.out.println("Verification/Calibration");
        }
    });
    btnE.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            System.exit(0);
        }
    });

    // 20 will be the spacing
    VBox root = new VBox(40);
    root.setAlignment(Pos.CENTER);

    Label label;
    label = new Label("Please select a task.");
    label.setFont(Font.font("Arial", 32));

    // Adding buttons to the root
    root.getChildren().addAll(label, btnR, btnM, btnW, btnO, btnU, btnVC, btnE);

    btnE.setTranslateX(100);

    mainMenu = new Scene(root, width, height);
    primaryStage.setScene(mainMenu);
    primaryStage.show();
}

public void initializeScenes() {
    // You Can Here Add Whatever you want into your scenes

    // initializing the Repair Scene :

    VBox rootR = new VBox(10);
    rootR.setAlignment(Pos.CENTER);
    Label descR = new Label("Repair Scene");
    Button backR = new Button("back");
    rootR.getChildren().addAll(descR, backR);
    // the back button takes you back to the main menu scene
    backR.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            ps.setScene(mainMenu);
        }
    });
    sceneR = new Scene(rootR, width, height);

    // initializing the Maintenance Scene :

    VBox rootM = new VBox(10);
    rootM.setAlignment(Pos.CENTER);
    Label descM = new Label("Maintenance Scene");
    Button backM = new Button("back");
    rootM.getChildren().addAll(descM, backM);
    // the back button takes you back to the main menu scene
    backM.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            ps.setScene(mainMenu);
        }
    });
    sceneM = new Scene(rootM, width, height);

    // initializing the Weather Scene :

    VBox rootW = new VBox(10);
    rootW.setAlignment(Pos.CENTER);
    Label descW = new Label("Weather Scene");
    Button backW = new Button("back");
    rootW.getChildren().addAll(descW, backW);
    // the back button takes you back to the main menu scene
    backW.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            ps.setScene(mainMenu);
        }
    });
    sceneW = new Scene(rootW, width, height);



    // you should be able to do the other scenes
}

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    launch(args);
}

您似乎只想更新部分屏幕,而不是尝试更改 Scene

下面是一个简单的示例,它使用 BorderPane 作为根布局,然后在单击按钮时更改 CENTER 窗格的内容。

下面的示例只是为不同的标签切换内容,但您可以轻松地使用 root.setCenter() 来传递整个 VBoxHBox 或任何其他填充的容器。

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Main extends Application {

    private BorderPane root;

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

    @Override
    public void start(Stage primaryStage) {

        primaryStage.setWidth(500);

        // Simple interface. The buttons will be on the left and the contents of the center section will change
        // when buttons are clicked.
        root = new BorderPane();
        root.setPadding(new Insets(10));

        // Create the left pane, containing buttons to switch the CENTER content
        VBox paneButtonBox = new VBox(5);
        paneButtonBox.setAlignment(Pos.TOP_CENTER);
        paneButtonBox.setPadding(new Insets(10));

        // Create 3 buttons to change the contents of the CENTER
        Button btnView1 = new Button("View 1");
        btnView1.setOnAction(e -> switchContent(1));
        Button btnView2 = new Button("View 2");
        btnView2.setOnAction(e -> switchContent(2));
        Button btnView3 = new Button("View 3");
        btnView3.setOnAction(e -> switchContent(3));

        // Add the Buttons to the button box
        paneButtonBox.getChildren().addAll(btnView1, btnView2, btnView3);

        // Add the button box to the LEFT of root pane
        root.setLeft(paneButtonBox);

        primaryStage.setScene(new Scene(root));

        primaryStage.show();
    }

    /**
     * @param view is the # of the content we want to display. For this sample, just to demonstrate.
     */
    private void switchContent(int view) {

        // Change the content of the CENTER node based on button clicked
        switch (view) {
            case 1:
                root.setCenter(new Label("THIS IS VIEW 1"));
                break;
            case 2:
                root.setCenter(new Label("THIS IS VIEW 2"));
                break;
            case 3:
                root.setCenter(new Label("THIS IS VIEW 3"));
                break;

        }

    }
}

以上代码生成以下布局:

右边的Label随着每个按钮的点击而变化。希望这有助于引导您朝着正确的方向前进。

基本概念是创建布局的一部分,您可以更改其中的内容。 BorderPane 为您提供了这些部分,但您也可以自己创建一个单独的 VBox 并调用 VBox.getChildren().addAll() 并在需要更改时传入您想要的任何 Node 对象内容。

Another Option

实现类似界面功能的另一种方法是使用 TabPane。您添加到 TabPane 的每个 Tab 都有一个 content 属性,您可以使用它来设置您选择的任何节点,类似于上面 BorderPane 的工作方式:

@Override
public void start(Stage primaryStage) {

    primaryStage.setHeight(300);
    primaryStage.setWidth(500);

    TabPane root = new TabPane();

    // Create Separate Tabs
    Tab tab1 = new Tab("Section 1");
    tab1.setContent(new Label("This is Section 1!"));
    Tab tab2 = new Tab("Section 2");
    tab2.setContent(new Label("This is Section 2!"));
    Tab tab3 = new Tab("Section 3");
    tab3.setContent(new Label("This is Section 3!"));

    root.getTabs().addAll(tab1, tab2, tab3);

    primaryStage.setScene(new Scene(root));
    primaryStage.show();

}

结果是:

package principal;

public class Start extends Application {

    private static Stage stage;

    private static Scene parametrizacao;
    private static Scene monitorar;
    private static Scene relatorio;

    @Override
    public void start(Stage primaryStage) throws Exception {
        stage = primaryStage;

        primaryStage.setTitle("Java FX");

        Parent fxmlInicio = FXMLLoader.load(getClass().getResource("/fxml/inicio.fxml"));
        parametrizacao = new Scene(fxmlInicio);

        Parent fxmlMonitorar = FXMLLoader.load(getClass().getResource("/fxml/monitora.fxml"));
        monitorar = new Scene(fxmlMonitorar);

        Parent fxmlRelatorio = FXMLLoader.load(getClass().getResource("/fxml/relatorio.fxml"));
        relatorio = new Scene(fxmlRelatorio);

        primaryStage.setResizable(false);
        //stage.initStyle(StageStyle.UNDECORATED);
        //stage.getIcons().add(new Image(getClass().getResourceAsStream("/icone.jpg")));
        primaryStage.setScene(inicio);
        primaryStage.show();
    }

    //Metodo que faz a navegação entre as telas
    public static void changeScreen(String scr, Object userData) {
        switch (scr) {
            case "inicio":
                stage.setScene(inicio);
                break;
            case "monitorar":
                stage.setScene(monitorar);
                notifyAllListeners("monitorar", scr);
                break;
            case "relatorio":
                stage.setScene(relatorio);
                notifyAllListeners("relatorio", scr);
                break;
        }
    }

    public static void changeScreen(String scr) {
        changeScreen(scr, null);
    }

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

    public static ArrayList<OnChangeScreen> listeners = new ArrayList<>();

    public static interface OnChangeScreen {

        void onChangeScreen(String newScreen, Object userData);
    }

    public static void addOnChangeScreenListener(OnChangeScreen newListener) {
        listeners.add(newListener);
    }

    public static void notifyAllListeners(String newScreen, Object userData) {
        for (OnChangeScreen l : listeners) {
            l.onChangeScreen(newScreen, userData);
        }
    }

}