JavaFX - кнопки переключаются на неправильные сцены - PullRequest
2 голосов
/ 06 января 2020

В этой программе я использую только одну сцену, но меняю ее root узлы.

Изначально программа отображает экран «Добро пожаловать» (welcome Root). Но когда я нажимаю там кнопку «Войти», экран меняется на экран «Выбор режима игры», хотя в моем коде четко указано «logIn Root».

Это определенно не что логин Root инициализируется так, как должно быть gmode Root.

Вот выдержка из кода, сокращенная для ясности.

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene; 
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class WhatsWrong extends Application { 
    public void start(Stage theStage) throws Exception {

        // Fields
        VBox welcomeRoot = new VBox(20);
        VBox logInRoot = new VBox(20);
        VBox signUpRoot = new VBox(20);
        VBox gmodeRoot = new VBox(20);
        VBox singleplayerRoot = new VBox(20);
        VBox multiplayerRoot = new VBox(20);
        VBox statsRoot = new VBox(20);
        String currentUser = "";


        // Welcome screen
        Label theWelcomeMessage = new Label("Welcome to the Morse code learning program");
        Label welcomeLabel = new Label("Welcome screen");
        Button logInBtn = new Button("Log in");
        logInBtn.setOnAction(e -> theStage.getScene().setRoot(logInRoot));    // correct link...
        Button signUpBtn = new Button("Sign in");
        logInBtn.setOnAction(e -> theStage.getScene().setRoot(signUpRoot));
        Button unloggedBtn = new Button("Continue unlogged");
        logInBtn.setOnAction(e -> theStage.getScene().setRoot(gmodeRoot));  
            // This button links directly to choosing the game mode.

        welcomeRoot.getChildren().addAll(theWelcomeMessage, welcomeLabel, logInBtn, signUpBtn, unloggedBtn);


        // Log in screen
        Button logInGoBackBtn = new Button(/*back arrow drawing here*/);
        logInGoBackBtn.setOnAction(e -> theStage.getScene().setRoot(welcomeRoot));
        Label logInLabel = new Label("Log in");
        TextArea logInUsernameInput = new TextArea();
        logInUsernameInput.setPromptText("Username - only letters and numbers, max length 15");
        logInUsernameInput.setId("username");
        TextArea logInPasswordInput = new TextArea();
        logInPasswordInput.setPromptText("Password - at least one letter, number and special character");
        logInPasswordInput.setId("password");
        logInPasswordInput.getText();
        Button logInConfirmBtn = new Button("Continue");
        logInConfirmBtn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                // verify, display error message if correct, save username to currentUsername if correct.
            }
        });
        Label logInUsernameError = new Label(/*x symbol here*/"Error - username taken or invalid");
        Label logInPasswordError = new Label(/*x symbol here*/"Error - password invalid");    
            // input these into the root and delete if need be

        logInRoot.getChildren().addAll(logInGoBackBtn, logInLabel, logInUsernameInput, logInPasswordInput, logInConfirmBtn);


        // Sign up screen
        // code and some pseudocode here - deleted to save space


        // Choose game mode screen
        Button gmodeGoBackBtn = new Button(/*back arrow drawing here*/);
        gmodeGoBackBtn.setOnAction(/*If logged in, display a pop-up about logging-off*/e -> theStage.getScene().setRoot(welcomeRoot));
        Label gmodeLabel = new Label("Choose the game mode");
        Button gmodeTo1PlayerBtn = new Button("Singleplayer");
        gmodeTo1PlayerBtn.setOnAction(e -> theStage.getScene().setRoot(singleplayerRoot));
        Button gmodeToMultiBtn = new Button("Multiplayer");
        gmodeToMultiBtn.setOnAction(e -> theStage.getScene().setRoot(multiplayerRoot));
        Button gmodeToStatsBtn = new Button("Statistics");
        gmodeToStatsBtn.setOnAction(e -> theStage.getScene().setRoot(statsRoot));

        gmodeRoot.getChildren().addAll(gmodeGoBackBtn, gmodeLabel, gmodeTo1PlayerBtn, gmodeToMultiBtn, gmodeToStatsBtn);


        // etc.


        // Dealing with stage
        theStage.setTitle("Morse code - educational program");
        Scene theScene = new Scene(welcomeRoot);    // Replace with logInRoot, and login screen shows up, as expected.
        theStage.setScene(theScene);
        theStage.show();
    }

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

PS «выдержка»; надеюсь я рассмешил тебя;)

1 Ответ

4 голосов
/ 06 января 2020

Здесь вы создаете 3 кнопки, но вы только настраиваете слушателей действия на logInBtn:

Button logInBtn = new Button("Log in");
logInBtn.setOnAction(e -> theStage.getScene().setRoot(logInRoot));
Button signUpBtn = new Button("Sign in");
logInBtn.setOnAction(e -> theStage.getScene().setRoot(signUpRoot));
Button unloggedBtn = new Button("Continue unlogged");
logInBtn.setOnAction(e -> theStage.getScene().setRoot(gmodeRoot));

Добавление другого слушателя к той же кнопке переопределит любой ранее установленный слушатель, и поэтому ваш root имеет значение gmodeRoot и почему вы видите неправильное сообщение.

Я предполагаю, что вы хотите изменить его на:

Button logInBtn = new Button("Log in");
logInBtn.setOnAction(e -> theStage.getScene().setRoot(logInRoot));
Button signUpBtn = new Button("Sign in");
signUpBtn.setOnAction(e -> theStage.getScene().setRoot(signUpRoot));
Button unloggedBtn = new Button("Continue unlogged");
unloggedBtn.setOnAction(e -> theStage.getScene().setRoot(gmodeRoot));
...