【问题标题】:JavaFX stop KeyEvent after getting only one alpha numeric characterJavaFX 在仅获得一个字母数字字符后停止 KeyEvent
【发布时间】:2016-06-09 22:44:48
【问题描述】:

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

  1. 只允许您选择一个字母。大写或小写。如果不是,请等待正确的响应。
  2. 然后检查字母列表,看看它之前是否被按下过。如果它已经要求另一封信
  3. 如果输入了新字符,则在字母表上将其删除并运行以下方法
  4. 禁用任何其他正在按下的键。 我试过以下代码:

    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....;
                     })

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

【问题讨论】:

  • 您提供的内容看起来不错,尽管您可以做一些小的更改来压缩它。除非您遇到的问题不在您提供的代码中?例如初始化“字母表”,我在测试时猜到了
  • 字母表设置完毕。它取消并且工作正常。问题是我想停止关键事件,直到调用它的方法再次运行。
  • 你的意思是你想在字母表中的每个字母都猜对后停止检查字母吗?
  • 我将如何压缩它?
  • userGuess 并按住相同的值,你可以只用一个来压缩它

标签: java javafx keyevent onkeypress


【解决方案1】:

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

要停止按键输入,我建议使用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
    }
}

【讨论】:

  • 因此,由于程序其余部分的设置方式,我不确定切换按钮会有多大帮助。所以发生的情况如下:按下 GUI 上的按钮 -> 运行切换方法 -> 在某些情况下,上述方法应该运行一次。这将是新的字母值。听众需要停下来。我认为这里的问题是返回语句。我需要一种只接受一个之前未选择的字母的按键。
  • 问题是scene.setOnKeyPress 位于一个方法中。
  • 您的 switch 语句是否能够确定何时再次收听?如果可以,则可以删除基于按钮的逻辑并在那里模仿
  • 您可以在输入 switch 语句之前根据滚轮结果的一些常见特征设置一个布尔值,并检查是否选择了一个按钮。例如。如果轮子有数字 1-5 并且您只需要检查输入是否大于 4
  • 如果轮询变量成为性能问题,您可以考虑通过添加/删除事件处理程序来替换/组合它,以便仅在需要时使用它:docs.oracle.com/javafx/2/events/filters.htm
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-26
  • 2021-01-22
相关资源
最近更新 更多