Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 事件驱动输入与基于回合的输入_Java_Swing_Jtextfield - Fatal编程技术网

Java 事件驱动输入与基于回合的输入

Java 事件驱动输入与基于回合的输入,java,swing,jtextfield,Java,Swing,Jtextfield,我试图用JTextArea作为控制台/输出,JTextField作为用户输入来重新创建控制台游戏。由于GUI是事件驱动的,我不明白如何停止代码的执行,在继续执行之前等待用户输入。我能想到的唯一解决方案是While(userTurn)和userTurn将在actionlistener上更改为false有更好的方法吗 我的控制台解决方案 String getInput(String prompt){ String inputLine = null; console.se

我试图用JTextArea作为控制台/输出,JTextField作为用户输入来重新创建控制台游戏。由于GUI是事件驱动的,我不明白如何停止代码的执行,在继续执行之前等待用户输入。我能想到的唯一解决方案是While(userTurn)和userTurn将在actionlistener上更改为false有更好的方法吗

我的控制台解决方案

 String getInput(String prompt){
        String inputLine = null;
      console.setTextConsole(prompt + " ");
        try{
            BufferedReader is = new BufferedReader(new InputStreamReader(System.in));
            inputLine = is.readLine();
            if(inputLine.length() == 0) return null;

        }catch(IOException e){
            console.setTextConsole("IOException "+e);
        }
        return inputLine;
    }
我刚刚调用了这个getInput方法,然后开始了下一轮

我想完成的是:

  • 对手转向
  • 游戏等待用户
  • 用户在JtextField中键入文本,然后按enter键
  • 游戏执行玩家的命令
  • 对手再次转身
  • 那么我觉得这个,

    比赛的规则是谁拥有回合。只要统治者开始行动,其他统治者就必须等待。如何实现这一点

  • 如果用户拥有回合,他/她可以在JText字段中输入文本

  • 当他/她按ENTER键时,必须验证该命令。如果正常,回合必须转移到程序,同时,用户甚至不能在JText字段中输入文本。例如,禁用它:

  • 为了增强用户体验,启用/禁用按钮和文本字段可能会很有用。在这种情况下,您只需修改两种方法
    switchturntheprogram
    switchturntheuser
    ,我认为:

    比赛的规则是谁拥有回合。只要统治者开始行动,其他统治者就必须等待。如何实现这一点

  • 如果用户拥有回合,他/她可以在JText字段中输入文本

  • 当他/她按ENTER键时,必须验证该命令。如果正常,回合必须转移到程序,同时,用户甚至不能在JText字段中输入文本。例如,禁用它:


  • 为了增强用户体验,启用/禁用按钮和文本字段可能会很有用。在这种情况下,您只需修改两种方法
    switchturntheprogram
    switchturntheuser

    ,我已经编写了一个示例游戏,这样您就可以观察到它们之间的差异。计算机和用户尝试猜测0-2(含0-2)之间的随机数。谁做对了就赢。如果双方都做对了或都做错了,那就是平局

    编辑:更新的GUI版本

    以下是控制台程序:

    import java.util.Random;
    import java.util.Scanner;
    
    public class ConsoleGame {
        public static void main(String[] args) {
            Scanner console = new Scanner(System.in);
            Random rand = new Random();
            boolean playAgain = false;
            int wins = 0, losses = 0, draw = 0;
            do {
                int num = rand.nextInt(3); // 0-2 inclusive
                System.out.println("Guess the number [0-2]: ");
                int guess = Integer.parseInt(console.nextLine());
                int computerGuess = rand.nextInt(3);
                System.out.println("You: " + guess + "\tComputer: " + computerGuess + "\tNumber: " + num);
                if (guess == num && computerGuess == num || guess != num && computerGuess != num) {
                    draw++;
                    System.out.println("Draw!");
                } else if (guess == num) {
                    wins++;
                    System.out.println("You win!");
                } else if (computerGuess == num) {
                    losses++;
                    System.out.println("Computer wins :(");
                }
                System.out.println("Play again [y/n]? ");
                playAgain = console.nextLine().startsWith("y");
            } while (playAgain);
            System.out.println("Wins: " + wins + "\nLosses: " + losses + "\nDraw: " + draw);
            console.close();
        }
    }
    
    以下是GUI程序:

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.EventQueue;
    import java.awt.Font;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.Random;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.JTextField;
    
    public class GUIGame extends JFrame {
        private JPanel contentPane;
        private JTextField textField;
        private JTextArea textArea;
        private boolean textReceived;
    
         /**
         * Launch the application.
         */
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        GUIGame frame = new GUIGame();
                        frame.setVisible(true);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    
        /**
         * Create the frame.
         */
        public GUIGame() {
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setBounds(100, 100, 450, 300);
            contentPane = new JPanel();
            contentPane.setLayout(new BorderLayout());
            setContentPane(contentPane);
    
            textField = new JTextField();
            textField.addActionListener(new ActionListener() {
                @Override
                // user pressed 'enter' key,
                public void actionPerformed(ActionEvent e) {
                    textReceived = true;
                    synchronized (textField) {
                        // notify game loop thread which is waiting on this event
                        textField.notifyAll();
                    }
                }
            });
            contentPane.add(textField, BorderLayout.SOUTH);
    
            JScrollPane scrollPane = new JScrollPane();
            contentPane.add(scrollPane, BorderLayout.CENTER);
    
            textArea = new JTextArea();
            textArea.setFont(new Font("Consolas", Font.PLAIN, 12));
            textArea.setLineWrap(true);
            textArea.setWrapStyleWord(true);
            textArea.setForeground(Color.LIGHT_GRAY);
            textArea.setBackground(Color.BLACK);
            textArea.setEditable(false);
            scrollPane.setViewportView(textArea);
    
            // Start game loop in new thread since we block the thread when
            // waiting for input and we don't want to block the UI thread
            new Thread(new Runnable() {
                @Override
                public void run() {
                    playGame();
                }
            }).start();
        }
    
        private void playGame() {
            Random rand = new Random();
            boolean playAgain = false;
            int wins = 0, losses = 0, draw = 0;
            do {
                int num = rand.nextInt(3); // 0-2 inclusive
                textArea.append("Guess the number [0-2]: \n");
                int guess = Integer.parseInt(requestInput());
                int computerGuess = rand.nextInt(3);
                textArea.append("You: " + guess + "\tComputer: " + computerGuess + "\tNumber: " + num + "\n");
                if (guess == num && computerGuess == num || guess != num && computerGuess != num) {
                    draw++;
                    textArea.append("Draw!\n");
                } else if (guess == num) {
                    wins++;
                    textArea.append("You win!\n");
                } else if (computerGuess == num) {
                    losses++;
                    textArea.append("Computer wins :(\n");
                }
                textArea.append("Play again [y/n]? \n");
                playAgain = requestInput().startsWith("y");
            } while (playAgain);
            textArea.append("Wins: " + wins + "\nLosses: " + losses + "\nDraw: " + draw + "\n");
        }
    
        private String requestInput() {
            textField.setEnabled(true);
            textField.requestFocus();
            // wait on text field till UI thread signals a user input event
            synchronized (textField) {
                while (!textReceived) {
                    try {
                        textField.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            String input = textField.getText();
            textField.setText("");
            textField.setEnabled(false);
            textReceived = false;
            return input;
        }
    }
    

    我已经编写了一个示例游戏,这样你就可以观察到其中的差异。计算机和用户尝试猜测0-2(含0-2)之间的随机数。谁做对了就赢。如果双方都做对了或都做错了,那就是平局

    编辑:更新的GUI版本

    以下是控制台程序:

    import java.util.Random;
    import java.util.Scanner;
    
    public class ConsoleGame {
        public static void main(String[] args) {
            Scanner console = new Scanner(System.in);
            Random rand = new Random();
            boolean playAgain = false;
            int wins = 0, losses = 0, draw = 0;
            do {
                int num = rand.nextInt(3); // 0-2 inclusive
                System.out.println("Guess the number [0-2]: ");
                int guess = Integer.parseInt(console.nextLine());
                int computerGuess = rand.nextInt(3);
                System.out.println("You: " + guess + "\tComputer: " + computerGuess + "\tNumber: " + num);
                if (guess == num && computerGuess == num || guess != num && computerGuess != num) {
                    draw++;
                    System.out.println("Draw!");
                } else if (guess == num) {
                    wins++;
                    System.out.println("You win!");
                } else if (computerGuess == num) {
                    losses++;
                    System.out.println("Computer wins :(");
                }
                System.out.println("Play again [y/n]? ");
                playAgain = console.nextLine().startsWith("y");
            } while (playAgain);
            System.out.println("Wins: " + wins + "\nLosses: " + losses + "\nDraw: " + draw);
            console.close();
        }
    }
    
    以下是GUI程序:

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.EventQueue;
    import java.awt.Font;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.Random;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.JTextField;
    
    public class GUIGame extends JFrame {
        private JPanel contentPane;
        private JTextField textField;
        private JTextArea textArea;
        private boolean textReceived;
    
         /**
         * Launch the application.
         */
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        GUIGame frame = new GUIGame();
                        frame.setVisible(true);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    
        /**
         * Create the frame.
         */
        public GUIGame() {
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setBounds(100, 100, 450, 300);
            contentPane = new JPanel();
            contentPane.setLayout(new BorderLayout());
            setContentPane(contentPane);
    
            textField = new JTextField();
            textField.addActionListener(new ActionListener() {
                @Override
                // user pressed 'enter' key,
                public void actionPerformed(ActionEvent e) {
                    textReceived = true;
                    synchronized (textField) {
                        // notify game loop thread which is waiting on this event
                        textField.notifyAll();
                    }
                }
            });
            contentPane.add(textField, BorderLayout.SOUTH);
    
            JScrollPane scrollPane = new JScrollPane();
            contentPane.add(scrollPane, BorderLayout.CENTER);
    
            textArea = new JTextArea();
            textArea.setFont(new Font("Consolas", Font.PLAIN, 12));
            textArea.setLineWrap(true);
            textArea.setWrapStyleWord(true);
            textArea.setForeground(Color.LIGHT_GRAY);
            textArea.setBackground(Color.BLACK);
            textArea.setEditable(false);
            scrollPane.setViewportView(textArea);
    
            // Start game loop in new thread since we block the thread when
            // waiting for input and we don't want to block the UI thread
            new Thread(new Runnable() {
                @Override
                public void run() {
                    playGame();
                }
            }).start();
        }
    
        private void playGame() {
            Random rand = new Random();
            boolean playAgain = false;
            int wins = 0, losses = 0, draw = 0;
            do {
                int num = rand.nextInt(3); // 0-2 inclusive
                textArea.append("Guess the number [0-2]: \n");
                int guess = Integer.parseInt(requestInput());
                int computerGuess = rand.nextInt(3);
                textArea.append("You: " + guess + "\tComputer: " + computerGuess + "\tNumber: " + num + "\n");
                if (guess == num && computerGuess == num || guess != num && computerGuess != num) {
                    draw++;
                    textArea.append("Draw!\n");
                } else if (guess == num) {
                    wins++;
                    textArea.append("You win!\n");
                } else if (computerGuess == num) {
                    losses++;
                    textArea.append("Computer wins :(\n");
                }
                textArea.append("Play again [y/n]? \n");
                playAgain = requestInput().startsWith("y");
            } while (playAgain);
            textArea.append("Wins: " + wins + "\nLosses: " + losses + "\nDraw: " + draw + "\n");
        }
    
        private String requestInput() {
            textField.setEnabled(true);
            textField.requestFocus();
            // wait on text field till UI thread signals a user input event
            synchronized (textField) {
                while (!textReceived) {
                    try {
                        textField.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            String input = textField.getText();
            textField.setText("");
            textField.setEnabled(false);
            textReceived = false;
            return input;
        }
    }
    

    为什么你问了10个问题,却只接受了一个答案?是两个对手的游戏还是一个对手对电脑的游戏?事件驱动代码的意思是,作为事件结果执行的代码。当用户按下Enter键时,您只执行执行播放器命令的代码。你可以为对手的回合设置另一个按钮,该按钮将执行对手的回合代码。为什么你问了10个问题,却只接受了一个答案?是两个对手的游戏,还是一个对手对计算机的游戏?事件驱动代码的意思是,作为事件结果执行的代码。当用户按下Enter键时,您只执行执行播放器命令的代码。你可以为对手的回合设置另一个按钮,该按钮将执行对手的回合代码。我要寻找的部分是等待用户按enter键,而无需继续执行Java swing中立即出现的代码:你只需打开并绘制JPanel,添加侦听器,然后结束。面板将保持打开状态,并且有一个后台线程监听用户事件,该线程将调用连接到按钮的actionListener。我要查找的部分是等待用户按enter键,而不继续执行Java swing中立即出现的代码:您只需打开并绘制JPanel,添加侦听器,然后结束。面板将保持打开状态,并且有一个后台线程正在监听用户事件,该线程将调用连接到按钮的actionListener。干杯,我想我开始明白了。如果你能向我解释的话,还有一件事是,如果我期望不同的输入,例如,在游戏开始时,我希望用户输入他的名字,然后期望他按F键,然后按A/g键,等等。你可以通过传递提示来实现这一点,但这似乎不是最普遍的方式。有不同的方式吗?比回读文本区好吗?@Higeath是的,事实上有一种更好、更直观的方法。虽然它与您在问题中提到的建议解决方案类似,但这种称为忙等待的技术会占用CPU资源。阻塞via是一个更好的选择,请参阅更新的答案。干杯,我想我开始明白了。如果你能向我解释的话,还有一件事是,如果我期望不同的输入,例如,在游戏开始时,我希望用户输入他的名字,然后期望他按F键,然后按A/g键,等等。你可以通过传递提示来实现这一点,但这似乎不是最普遍的方式。有不同的方式吗?比回读文本区好吗?@Higeath是的,事实上有一种更好、更直观的方法。虽然它与您在问题中提到的建议解决方案类似,但这种称为忙等待的技术会占用CPU资源。阻塞via是更好的选择,请参阅更新的答案。
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.EventQueue;
    import java.awt.Font;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.Random;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.JTextField;
    
    public class GUIGame extends JFrame {
        private JPanel contentPane;
        private JTextField textField;
        private JTextArea textArea;
        private boolean textReceived;
    
         /**
         * Launch the application.
         */
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        GUIGame frame = new GUIGame();
                        frame.setVisible(true);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    
        /**
         * Create the frame.
         */
        public GUIGame() {
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setBounds(100, 100, 450, 300);
            contentPane = new JPanel();
            contentPane.setLayout(new BorderLayout());
            setContentPane(contentPane);
    
            textField = new JTextField();
            textField.addActionListener(new ActionListener() {
                @Override
                // user pressed 'enter' key,
                public void actionPerformed(ActionEvent e) {
                    textReceived = true;
                    synchronized (textField) {
                        // notify game loop thread which is waiting on this event
                        textField.notifyAll();
                    }
                }
            });
            contentPane.add(textField, BorderLayout.SOUTH);
    
            JScrollPane scrollPane = new JScrollPane();
            contentPane.add(scrollPane, BorderLayout.CENTER);
    
            textArea = new JTextArea();
            textArea.setFont(new Font("Consolas", Font.PLAIN, 12));
            textArea.setLineWrap(true);
            textArea.setWrapStyleWord(true);
            textArea.setForeground(Color.LIGHT_GRAY);
            textArea.setBackground(Color.BLACK);
            textArea.setEditable(false);
            scrollPane.setViewportView(textArea);
    
            // Start game loop in new thread since we block the thread when
            // waiting for input and we don't want to block the UI thread
            new Thread(new Runnable() {
                @Override
                public void run() {
                    playGame();
                }
            }).start();
        }
    
        private void playGame() {
            Random rand = new Random();
            boolean playAgain = false;
            int wins = 0, losses = 0, draw = 0;
            do {
                int num = rand.nextInt(3); // 0-2 inclusive
                textArea.append("Guess the number [0-2]: \n");
                int guess = Integer.parseInt(requestInput());
                int computerGuess = rand.nextInt(3);
                textArea.append("You: " + guess + "\tComputer: " + computerGuess + "\tNumber: " + num + "\n");
                if (guess == num && computerGuess == num || guess != num && computerGuess != num) {
                    draw++;
                    textArea.append("Draw!\n");
                } else if (guess == num) {
                    wins++;
                    textArea.append("You win!\n");
                } else if (computerGuess == num) {
                    losses++;
                    textArea.append("Computer wins :(\n");
                }
                textArea.append("Play again [y/n]? \n");
                playAgain = requestInput().startsWith("y");
            } while (playAgain);
            textArea.append("Wins: " + wins + "\nLosses: " + losses + "\nDraw: " + draw + "\n");
        }
    
        private String requestInput() {
            textField.setEnabled(true);
            textField.requestFocus();
            // wait on text field till UI thread signals a user input event
            synchronized (textField) {
                while (!textReceived) {
                    try {
                        textField.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            String input = textField.getText();
            textField.setText("");
            textField.setEnabled(false);
            textReceived = false;
            return input;
        }
    }