JavaFX 在仅获取一个字母数字字符后停止 KeyEvent

JavaFX stop KeyEvent after getting only one alpha numeric character

我是 Java 的新手,在让一些代码正常工作时遇到了问题。我有一个带有字母 A-Z 的 GUI。单击按钮后,我想请求一个 Keyevent 来做几件事:

  1. 只允许您select一封信。大写或小写。如果不等待正确的响应。
  2. 然后查看字母列表,看看之前是否按下过。如果它有然后要求另一个字母
  3. 如果输入了新字符,则在字母表中将其删除,然后运行遵循
  4. 的方法
  5. 禁止再按下任何键。 我试过以下代码:

    private static void spinGame(){
    
            switch (wheelResult)
    
            {
              case "1'
                ...
    
                break;
              case "2":
                ...
    
                break;
    
              default: 
                System.out.println("...");
    
                newPhrase.gameB();
    
                scene2.setOnKeyPressed((KeyEvent event) -> {
                    if (event.getText().isEmpty())
                        return;
    
                    char pressed = event.getText().toUpperCase().charAt(0);
                    userGuess=event.getText().charAt(0);
    
                    if ((pressed < 'A' || pressed > 'Z'))
                        return;
    
    
                        Text t = alphabet.get(pressed);
                     if (t.isStrikethrough())
                            return;
    
                        // mark the letter 'used'
                     else{t.setFill(Color.BLUE);
                        t.setStrikethrough(true);
    
                        System.out.println(userGuess);
                        }
                        int letterCount;
                        if ((userGuess == 'a') || (userGuess == 'e') || (userGuess == 'i') || (userGuess == 'o')    || (userGuess == 'u')){
    
                           playerScores[currentPlayer] -= 250;
                           System.out.println("£250 docked from score for vowel use");
                        }
    

从这里开始就出错了。我不想再次按下按键,我不希望下面的方法应该 运行:

                           letterCount = newPhrase.makeGuess(userGuess);

                            ...my method....;
                     })

我不知道如何修复它。我测试并记录了 User guess is being selected 但它不会在之后继续该方法并且输入中的键不会停止。我也觉得我对字母数字的编码是错误的。

您的解决方案已经可以满足您的要求,因为您可以检查有效字母以及它是否在您的字母表中被删除线。因此,在他们提供未使用的字母之前,除了每次检查的条件外,什么都不会发生

要停止按键输入,我建议使用 ToggleButton 或类似的东西,这样用户必须在他们想猜的时候指出。这意味着您可以使用其他基于文本的控件来降低意外删除字母表中字母的可能性。当他们猜出一个未使用的字母时,您可以重置按钮,否则继续检查他们输入的有效字母

您的评分系统相关方法仅在用户输入元音时调用。您可以通过创建一个方法并仅向其提供有效的未使用字母来分离分数和输入逻辑,并在那里处理游戏的 scoring/phrase 查找逻辑:

private void checkPhrase(char chosenLetter){
    //Handle the Hangman-like logic here
    boolean isVowel = vowels.indexOf(chosenLetter) >= 0;
    if (isVowel) {
        System.out.println("User provided a vowel");
    }
}

这将使您的代码更容易阅读和维护,因为一旦您确定该字母未被使用,您只需调用它一次。而之前你可能有重复,因为它看起来只针对元音执行


以下是我在测试时对您的代码所做的更改,以防它们被使用:

public class AlphabetGuess extends Application {
    private String vowels = "AEIOU";

    @Override
    public void start(Stage primaryStage) throws Exception {
        ObservableList<Text> alphabet = FXCollections.observableArrayList();

        for(char letter = 'A'; letter <= 'Z'; letter++){
            alphabet.add(new Text(String.valueOf(letter)));
        }

        HBox alphabetContainer = new HBox(5);
        alphabetContainer.setAlignment(Pos.CENTER);
        alphabetContainer.getChildren().addAll(alphabet);

        ToggleButton button = new ToggleButton("Listen for guess");
        button.setSelected(false);

        VBox root = new VBox(20, alphabetContainer, button);
        root.setAlignment(Pos.CENTER);

        Scene scene = new Scene(root, 500, 100);
        scene.setOnKeyPressed(event -> {
            //If the button isn't selected, don't process the input
            if (event.getText().isEmpty() || !button.isSelected()) {
                return;
            }

            char userGuess = event.getText().toUpperCase().charAt(0);
            if ((userGuess < 'A' || userGuess > 'Z')) {
                return;
            }

            //This will cause letters A-Z to become 0-25 allowing the list to be indexed
            Text text = alphabet.get(userGuess - 'A');
            if (text.isStrikethrough()) {
                System.out.println(userGuess + " has already been guessed");
                return;
            } else {
                text.setFill(Color.BLUE);
                text.setStrikethrough(true);
                checkPhrase(userGuess);
            }
            //Un-select button which will cause this event to reject incoming keys
            button.setSelected(false);
        });

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private void checkPhrase(char chosenLetter){
        //Handle the Hangman-like logic here
        boolean isVowel = vowels.indexOf(chosenLetter) >= 0;
        if (isVowel) {
            System.out.println("User provided a vowel");
        }
        //ToDo: Implement
    }
}