JavaFX - 按钮切换到错误的场景
JavaFX - Buttons switch to the wrong scenes
在这个程序中,我只使用了一个场景,但是改变了它的根节点。
最初,程序显示 "Welcome" 屏幕 (welcomeRoot)。但是当我按下那里的 "Log in" 按钮时,屏幕会变为 "Choose game mode" 屏幕,即使在我的代码中它清楚地表明 "logInRoot".
肯定不是像gmodeRoot那样初始化了logInRoot。
这里是代码的摘录,为清楚起见,进行了缩减。
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);
}
}
P.S。 "excerpt";希望我能让你发笑 ;)
这里您创建了 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));
向同一个按钮添加另一个侦听器将覆盖之前设置的任何侦听器,这就是为什么您的根设置为 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));
在这个程序中,我只使用了一个场景,但是改变了它的根节点。
最初,程序显示 "Welcome" 屏幕 (welcomeRoot)。但是当我按下那里的 "Log in" 按钮时,屏幕会变为 "Choose game mode" 屏幕,即使在我的代码中它清楚地表明 "logInRoot".
肯定不是像gmodeRoot那样初始化了logInRoot。
这里是代码的摘录,为清楚起见,进行了缩减。
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);
}
}
P.S。 "excerpt";希望我能让你发笑 ;)
这里您创建了 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));
向同一个按钮添加另一个侦听器将覆盖之前设置的任何侦听器,这就是为什么您的根设置为 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));