JavaFx卡在while循环中

JavaFx卡在while循环中,java,intellij-idea,while-loop,javafx-8,scenebuilder,Java,Intellij Idea,While Loop,Javafx 8,Scenebuilder,我是JavaFx新手,正在尝试编写我的刽子手游戏。我必须检查保存我词典的文件是否在那里。如果没有,请要求用户输入其位置。我试图在一个弹出窗口中执行此操作,该窗口要求用户输入位置并点击一个按钮,该按钮将导致textbox.getText()被保存并加载。如果位置不好,请重复。为了让这个弹出窗口运行,我故意拼错了位置,但它被卡在了一个while循环中,迫使我结束应用程序。我把它当作一个新的场景来运行,但是我被接下来该做什么所困扰。这是我的Controller.java 仅供参考:虽然这是大学的家庭作

我是JavaFx新手,正在尝试编写我的刽子手游戏。我必须检查保存我词典的文件是否在那里。如果没有,请要求用户输入其位置。我试图在一个弹出窗口中执行此操作,该窗口要求用户输入位置并点击一个按钮,该按钮将导致textbox.getText()被保存并加载。如果位置不好,请重复。为了让这个弹出窗口运行,我故意拼错了位置,但它被卡在了一个while循环中,迫使我结束应用程序。我把它当作一个新的场景来运行,但是我被接下来该做什么所困扰。这是我的Controller.java

仅供参考:虽然这是大学的家庭作业,但我没有被录取。我是残疾学生,我的朋友正在上课。我试着通过玩弄他的作业来保持忙碌。我喜欢编写代码,这让我忙个不停,不断更新,我开始学习新东西

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循环只是重复创建控件,向其中一个(按钮)注册侦听器,将控件放置在新窗口中,然后显示窗口。循环不会等待按钮按下后再继续下一次迭代。所以你会有很多窗户

您希望在显示阶段时阻止代码,直到输入有效文件。Stage定义了一个方法,该方法将显示窗口,然后阻止执行,直到窗口被取消。(请注意,这实际上是您应该在FX应用程序线程上调用的唯一阻塞方法。它发挥了一些魔力,确保UI在代码执行被阻塞时保持响应。)因此,一种方法是在循环中调用
showAndWait
,因为这将阻止循环进入下一个迭代,直到窗口关闭:

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

}
如果文件存在,只需关闭窗口,就可以使这一点变得更好:

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();
});
如果文件不存在,则可以禁用该按钮,使其更加友好:

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();
});
最后,除非文件有效,否则禁用“确定”按钮,您可以取消装饰窗口(没有最小化、最大化按钮,或者关键是关闭按钮)。然后,除非输入有效的文件,否则无法关闭窗口,并且可以完全消除循环。注意:如果用户无法找到有效的文件(没有转义路径),这可能会让用户感到恼火:


<>和最后一个评论:为了允许用户选择一个文件,您可以考虑在GUI编程中使用()./P>< P>,在考虑基于循环的方法之前,始终考虑事件驱动的方法。while循环只是重复创建控件,向其中一个(按钮)注册侦听器,将控件放置在新窗口中,然后显示窗口。循环不会等待按钮按下后再继续下一次迭代。所以你会有很多窗户

您希望在显示阶段时阻止代码,直到输入有效文件。Stage定义了一个方法,该方法将显示窗口,然后阻止执行,直到窗口被取消。(请注意,这实际上是您应该在FX应用程序线程上调用的唯一阻塞方法。它发挥了一些魔力,确保UI在代码执行被阻塞时保持响应。)因此,一种方法是在循环中调用
showAndWait
,因为这将阻止循环进入下一个迭代,直到窗口关闭:

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

}
如果文件存在,只需关闭窗口,就可以使这一点变得更好:

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();
});
如果文件不存在,则可以禁用该按钮,使其更加友好:

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();
});
最后,除非文件有效,否则禁用“确定”按钮,您可以取消装饰窗口(没有最小化、最大化按钮,或者关键是关闭按钮)。然后,除非输入有效的文件,否则无法关闭窗口,并且可以完全消除循环。注意:如果用户无法找到有效的文件(没有转义路径),这可能会让用户感到恼火:

最后一个注释:为了允许用户选择文件,您可以考虑使用().< /P>