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

时间:2016-06-09 22:44:48

标签: java javafx keyevent onkeypress

我是Java的新手,在使用某些代码时遇到了麻烦。我有一个带字母A-Z的GUI。点击一下按钮后,我想请Keyevent做几件事:

  1. 只允许您选择一个字母。大小写。如果不等待正确的回复。
  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");
                        }
    
  6. 从这里出错了。我不希望再次按下键,我不会运行以下方法:

                               letterCount = newPhrase.makeGuess(userGuess);
    
                                ...my method....;
                         })
    

    我不知道如何修复它。我测试并记录了用户猜测正在被选中但是之后没有继续该方法并且输入中的键没有停止。我也觉得我对字母数字的编码是错误的。

1 个答案:

答案 0 :(得分:0)

您的解决方案已经满足您的要求,因为您检查了有效的信件以及它是否是您的字母表中的删除信件。因此,除非他们提供未使用的信件,否则每次检查的条件都不会发生任何事情

要停止键输入,我建议使用ToggleButton或类似的东西,以便用户必须指出他们想要猜测的时间。这意味着您可以使用其他基于文本的控件,减少意外触发字母表中字母的概率。当他们猜出一个未使用的字母时,你可以重置按钮,否则继续检查他们的输入是否有效的字母

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

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
    }
}