JavaFx 陷入 while 循环
JavaFx Stuck in while loop
我是 JavaFx 的新手,正在尝试编写我的刽子手游戏代码。我现在必须检查保存我的词典的文件是否存在。如果没有要求用户输入其位置。我正在尝试在要求用户输入位置并点击按钮的弹出窗口 windows 中执行此操作,此按钮反过来将导致 textbox.getText() 被保存并加载。如果它是一个糟糕的位置,重复。我故意拼错了位置以将此弹出窗口设置为 运行,但它陷入了 while 循环并迫使我结束应用程序。我 运行 将它作为一个新场景,但我不知道下一步该怎么做。这是我的 Controller.java
仅供参考:虽然这是大学的家庭作业,但我没有注册。我有残疾,我的朋友正在经历 class。我试图通过玩他的作业来保持忙碌。热爱编码,这让我很忙,了解最新情况,并且我开始学习新事物。
package sample;
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.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Controller {
public Label welcomeLabel, guessesLettersLabel, GuessesRemainingLabel, currentStateLAbel, endGameMessageLabel;
public Button newGameButton, exitButton, enterTextButton;
public TextField enterTextBox;
public boolean ynAnswer;
public String textAnswer;
Stage window;
File inputFile;
public void newGame() throws FileNotFoundException {
Scanner input = new Scanner(System.in);
inputFile = new File("src\sample\HangmanLexcon.txt");
while(!inputFile.exists()) {
window = new Stage();
window.initModality(Modality.APPLICATION_MODAL);
window.setTitle("File was not found.");
window.setMinWidth(250);
window.setMaxHeight(100);
//form
TextField fileInput = new TextField();
Button inputButton = new Button("Upload File");
inputButton.setOnAction(e -> {
inputFile = new File(fileInput.getText());
window.close();
});
//Layout
VBox layout = new VBox(10);
layout.setPadding(new Insets(20, 20, 20, 20));
layout.getChildren().addAll(fileInput, inputButton);
//Set scene and show in window.
Scene scene = new Scene(layout, 300, 100);
window.setScene(scene);
window.show();
}
Hangman newGame = new Hangman(inputFile.toString());
welcomeLabel.setText("A word has been selected. Good luck, and may the odds ever be in your favor.");
guessesLettersLabel.setText("Guessed Letters: " + newGame.getGuessedLetters());
GuessesRemainingLabel.setText("Guesses remaining: " + newGame.getIncorrectGuessesRemaining());
currentStateLAbel.setText("Current State: " + newGame.getCurrentState());
}
public void enterTextButton(){
System.out.println("You pressed enter...");
}
public void enterText(){
enterTextButton();
}
/**
* If the player closed to exit the game or hit the X button this method will ask if they are
* sure they wish to exit before quiting the game.
*/
public void exitGame(){
Boolean answer = desplayYesNoMessgae("Exit", "Are you sure you want to exit?");
if(answer)
System.exit(0);
}
public boolean desplayYesNoMessgae(String title, String message){
Stage window = new Stage();
window.initModality(Modality.APPLICATION_MODAL);
window.setTitle(title);
window.setMinWidth(250);
Label label1 = new Label();
label1.setText(message);
//Create two buttons, yes and no
Button yesButton = new Button("Yes");
Button noButton = new Button("No");
//If yes ic clucked, set answer to true.
yesButton.setOnAction(e -> {
ynAnswer = true;
window.close();
});
//if no is clicked, set answer to false.
noButton.setOnAction(e -> {
ynAnswer = false;
window.close();
});
VBox layout = new VBox(10);
layout.getChildren().addAll(label1, yesButton, noButton);
layout.setAlignment(Pos.CENTER);
Scene scene = new Scene(layout);
window.setScene(scene);
window.showAndWait();
return ynAnswer;
}
public String desplayTextMessgae(String title, String message){
Stage window = new Stage();
window.initModality(Modality.APPLICATION_MODAL);
window.setTitle(title);
window.setMinWidth(250);
Label label1 = new Label();
label1.setText(message);
//form
TextField nameInput = new TextField();
Button loadBbutton = new Button("Upload");
loadBbutton.setOnAction(e -> {
textAnswer = nameInput.getText();
window.close();
});
//Layout
VBox layout = new VBox(10);
layout.setPadding(new Insets(20, 20, 20, 20));
layout.getChildren().addAll(nameInput, loadBbutton);
//Set scene and show in window.
Scene scene = new Scene(layout, 300, 100);
window.setScene(scene);
window.show();
return textAnswer;
}
}
在 GUI 编程中,在考虑基于循环的方法之前总是考虑事件驱动的方法。您的 while 循环只是简单地重复创建控件,向其中一个控件(按钮)注册一个侦听器,将控件放在一个新的 window 中,然后显示 window。在继续下一次迭代之前,循环不会等待按下按钮。所以你最终得到很多 windows...
您希望代码在显示阶段时阻塞,直到输入有效文件。 Stage 定义了一个 showAndWait
方法,它将显示 window 然后阻止执行直到 window 被关闭。 (请注意,这本质上是您应该在 FX 应用程序线程上调用的 only 阻塞方法。它做了一些神奇的事情来确保 UI 在代码执行被阻塞时保持响应。)因此,一种方法是在循环中调用 showAndWait
,因为这将阻止循环进行到下一次迭代,直到 window 被关闭:
while(!inputFile.exists()) {
window = new Stage();
window.initModality(Modality.APPLICATION_MODAL);
window.setTitle("File was not found.");
window.setMinWidth(250);
window.setMaxHeight(100);
//form
TextField fileInput = new TextField();
Button inputButton = new Button("Upload File");
inputButton.setOnAction(e -> {
inputFile = new File(fileInput.getText());
window.close();
});
//Layout
VBox layout = new VBox(10);
layout.setPadding(new Insets(20, 20, 20, 20));
layout.getChildren().addAll(fileInput, inputButton);
//Set scene and show in window.
Scene scene = new Scene(layout, 300, 100);
window.setScene(scene);
window.showAndWait();
}
如果文件存在,您可以通过仅关闭 window 来使它更好一些:
inputButton.setOnAction(e -> {
inputFile = new File(fileInput.getText());
if (inputFile.exists()) {
window.close();
}
});
除非文件存在,否则您可以通过禁用该按钮使它变得更好:
TextField fileInput = new TextField();
Button inputButton = new Button("Upload File");
inputButton.setDisable(true);
fileInput.textProperty().addListener((obs, oldText, newText) ->
inputButton.setDisable( ! new File(newText).exists() ) );
inputButton.setOnAction(e -> {
inputFile = new File(fileInput.getText());
window.close();
});
或绑定:
TextField fileInput = new TextField();
Button inputButton = new Button("Upload File");
inputButton.disableProperty().bind(Bindings.createBooleanBinding(
() -> ! new File(fileInput.getText()).exists(),
fileInput.textProperty()));
inputButton.setOnAction(e -> {
inputFile = new File(fileInput.getText());
window.close();
});
最后,除非文件有效,否则禁用“确定”按钮,您可以使 window 未修饰(没有最小化、最大化或最重要的是关闭按钮)。除非输入有效文件,否则无法关闭 window,并且您可以完全摆脱循环。请注意,如果用户无法找出有效文件(没有转义路径),这可能会让用户感到厌烦:
if (! inputFile.exists()) {
window = new Stage();
window.initModality(Modality.APPLICATION_MODAL);
window.initStyle(StageStyle.UNDECORATED);
window.setTitle("File was not found.");
window.setMinWidth(250);
window.setMaxHeight(100);
//form
TextField fileInput = new TextField();
Button inputButton = new Button("Upload File");
inputButton.disableProperty().bind(Bindings.createBooleanBinding(
() -> ! new File(fileInput.getText()).exists(),
fileInput.textProperty()));
inputButton.setOnAction(e -> {
inputFile = new File(fileInput.getText());
window.close();
});
//Layout
VBox layout = new VBox(10);
layout.setPadding(new Insets(20, 20, 20, 20));
layout.getChildren().addAll(fileInput, inputButton);
//Set scene and show in window.
Scene scene = new Scene(layout, 300, 100);
window.setScene(scene);
window.showAndWait();
}
最后一条评论:要允许用户选择文件,您可以考虑使用 FileChooser
(tutorial)。
我是 JavaFx 的新手,正在尝试编写我的刽子手游戏代码。我现在必须检查保存我的词典的文件是否存在。如果没有要求用户输入其位置。我正在尝试在要求用户输入位置并点击按钮的弹出窗口 windows 中执行此操作,此按钮反过来将导致 textbox.getText() 被保存并加载。如果它是一个糟糕的位置,重复。我故意拼错了位置以将此弹出窗口设置为 运行,但它陷入了 while 循环并迫使我结束应用程序。我 运行 将它作为一个新场景,但我不知道下一步该怎么做。这是我的 Controller.java
仅供参考:虽然这是大学的家庭作业,但我没有注册。我有残疾,我的朋友正在经历 class。我试图通过玩他的作业来保持忙碌。热爱编码,这让我很忙,了解最新情况,并且我开始学习新事物。
package sample;
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.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Controller {
public Label welcomeLabel, guessesLettersLabel, GuessesRemainingLabel, currentStateLAbel, endGameMessageLabel;
public Button newGameButton, exitButton, enterTextButton;
public TextField enterTextBox;
public boolean ynAnswer;
public String textAnswer;
Stage window;
File inputFile;
public void newGame() throws FileNotFoundException {
Scanner input = new Scanner(System.in);
inputFile = new File("src\sample\HangmanLexcon.txt");
while(!inputFile.exists()) {
window = new Stage();
window.initModality(Modality.APPLICATION_MODAL);
window.setTitle("File was not found.");
window.setMinWidth(250);
window.setMaxHeight(100);
//form
TextField fileInput = new TextField();
Button inputButton = new Button("Upload File");
inputButton.setOnAction(e -> {
inputFile = new File(fileInput.getText());
window.close();
});
//Layout
VBox layout = new VBox(10);
layout.setPadding(new Insets(20, 20, 20, 20));
layout.getChildren().addAll(fileInput, inputButton);
//Set scene and show in window.
Scene scene = new Scene(layout, 300, 100);
window.setScene(scene);
window.show();
}
Hangman newGame = new Hangman(inputFile.toString());
welcomeLabel.setText("A word has been selected. Good luck, and may the odds ever be in your favor.");
guessesLettersLabel.setText("Guessed Letters: " + newGame.getGuessedLetters());
GuessesRemainingLabel.setText("Guesses remaining: " + newGame.getIncorrectGuessesRemaining());
currentStateLAbel.setText("Current State: " + newGame.getCurrentState());
}
public void enterTextButton(){
System.out.println("You pressed enter...");
}
public void enterText(){
enterTextButton();
}
/**
* If the player closed to exit the game or hit the X button this method will ask if they are
* sure they wish to exit before quiting the game.
*/
public void exitGame(){
Boolean answer = desplayYesNoMessgae("Exit", "Are you sure you want to exit?");
if(answer)
System.exit(0);
}
public boolean desplayYesNoMessgae(String title, String message){
Stage window = new Stage();
window.initModality(Modality.APPLICATION_MODAL);
window.setTitle(title);
window.setMinWidth(250);
Label label1 = new Label();
label1.setText(message);
//Create two buttons, yes and no
Button yesButton = new Button("Yes");
Button noButton = new Button("No");
//If yes ic clucked, set answer to true.
yesButton.setOnAction(e -> {
ynAnswer = true;
window.close();
});
//if no is clicked, set answer to false.
noButton.setOnAction(e -> {
ynAnswer = false;
window.close();
});
VBox layout = new VBox(10);
layout.getChildren().addAll(label1, yesButton, noButton);
layout.setAlignment(Pos.CENTER);
Scene scene = new Scene(layout);
window.setScene(scene);
window.showAndWait();
return ynAnswer;
}
public String desplayTextMessgae(String title, String message){
Stage window = new Stage();
window.initModality(Modality.APPLICATION_MODAL);
window.setTitle(title);
window.setMinWidth(250);
Label label1 = new Label();
label1.setText(message);
//form
TextField nameInput = new TextField();
Button loadBbutton = new Button("Upload");
loadBbutton.setOnAction(e -> {
textAnswer = nameInput.getText();
window.close();
});
//Layout
VBox layout = new VBox(10);
layout.setPadding(new Insets(20, 20, 20, 20));
layout.getChildren().addAll(nameInput, loadBbutton);
//Set scene and show in window.
Scene scene = new Scene(layout, 300, 100);
window.setScene(scene);
window.show();
return textAnswer;
}
}
在 GUI 编程中,在考虑基于循环的方法之前总是考虑事件驱动的方法。您的 while 循环只是简单地重复创建控件,向其中一个控件(按钮)注册一个侦听器,将控件放在一个新的 window 中,然后显示 window。在继续下一次迭代之前,循环不会等待按下按钮。所以你最终得到很多 windows...
您希望代码在显示阶段时阻塞,直到输入有效文件。 Stage 定义了一个 showAndWait
方法,它将显示 window 然后阻止执行直到 window 被关闭。 (请注意,这本质上是您应该在 FX 应用程序线程上调用的 only 阻塞方法。它做了一些神奇的事情来确保 UI 在代码执行被阻塞时保持响应。)因此,一种方法是在循环中调用 showAndWait
,因为这将阻止循环进行到下一次迭代,直到 window 被关闭:
while(!inputFile.exists()) {
window = new Stage();
window.initModality(Modality.APPLICATION_MODAL);
window.setTitle("File was not found.");
window.setMinWidth(250);
window.setMaxHeight(100);
//form
TextField fileInput = new TextField();
Button inputButton = new Button("Upload File");
inputButton.setOnAction(e -> {
inputFile = new File(fileInput.getText());
window.close();
});
//Layout
VBox layout = new VBox(10);
layout.setPadding(new Insets(20, 20, 20, 20));
layout.getChildren().addAll(fileInput, inputButton);
//Set scene and show in window.
Scene scene = new Scene(layout, 300, 100);
window.setScene(scene);
window.showAndWait();
}
如果文件存在,您可以通过仅关闭 window 来使它更好一些:
inputButton.setOnAction(e -> {
inputFile = new File(fileInput.getText());
if (inputFile.exists()) {
window.close();
}
});
除非文件存在,否则您可以通过禁用该按钮使它变得更好:
TextField fileInput = new TextField();
Button inputButton = new Button("Upload File");
inputButton.setDisable(true);
fileInput.textProperty().addListener((obs, oldText, newText) ->
inputButton.setDisable( ! new File(newText).exists() ) );
inputButton.setOnAction(e -> {
inputFile = new File(fileInput.getText());
window.close();
});
或绑定:
TextField fileInput = new TextField();
Button inputButton = new Button("Upload File");
inputButton.disableProperty().bind(Bindings.createBooleanBinding(
() -> ! new File(fileInput.getText()).exists(),
fileInput.textProperty()));
inputButton.setOnAction(e -> {
inputFile = new File(fileInput.getText());
window.close();
});
最后,除非文件有效,否则禁用“确定”按钮,您可以使 window 未修饰(没有最小化、最大化或最重要的是关闭按钮)。除非输入有效文件,否则无法关闭 window,并且您可以完全摆脱循环。请注意,如果用户无法找出有效文件(没有转义路径),这可能会让用户感到厌烦:
if (! inputFile.exists()) {
window = new Stage();
window.initModality(Modality.APPLICATION_MODAL);
window.initStyle(StageStyle.UNDECORATED);
window.setTitle("File was not found.");
window.setMinWidth(250);
window.setMaxHeight(100);
//form
TextField fileInput = new TextField();
Button inputButton = new Button("Upload File");
inputButton.disableProperty().bind(Bindings.createBooleanBinding(
() -> ! new File(fileInput.getText()).exists(),
fileInput.textProperty()));
inputButton.setOnAction(e -> {
inputFile = new File(fileInput.getText());
window.close();
});
//Layout
VBox layout = new VBox(10);
layout.setPadding(new Insets(20, 20, 20, 20));
layout.getChildren().addAll(fileInput, inputButton);
//Set scene and show in window.
Scene scene = new Scene(layout, 300, 100);
window.setScene(scene);
window.showAndWait();
}
最后一条评论:要允许用户选择文件,您可以考虑使用 FileChooser
(tutorial)。