简体   繁体   English

从JTextField输入文本时触发的ActionListener

[英]ActionListener to trigger on text input from JTextField

I would like to ask the user a question through a JTextArea, and have the answer evaluated inside of an ActionListener. 我想通过JTextArea向用户提出问题,并在ActionListener中评估答案。 Here is my (example) code: 这是我的(示例)代码:

textField.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            final String text = textField.getText();
            textArea.setText("Is your favorite color Red?");
            if (text.replaceAll("'", "").toLowerCase().contains("yes")){
                textArea.setText("Cool!");
            }else if (text.replaceAll("'", "").toLowerCase().equals("no")){
                textArea.setText(":(");
            }
        }
    });

The problem is that because there are other questions, whenever the user types "yes", the response is "Cool!". 问题在于,因为还有其他问题,每当用户键入“是”时,响应都是“很酷!”。 I want it to only say "Cool!" 我只想说“酷!” when the answer is "yes" and the question is "Is your favorite color Red?". 当答案是“是”,而问题是“您最喜欢的颜色是红色吗?”时。

You're operating in an event driven environment, so you need to ask the question and wait for a response from the user. 您在事件驱动的环境中进行操作,因此您需要提出问题并等待用户的响应。

Think about it a little differently. 换个角度考虑一下。 You have a "question", which has prescribed output in response to user input. 您有一个“问题”,已根据用户输入指定了输出。

What you need is some way to associate the response from the question with the question, lucky for us, Java is a OO language... 您需要某种方式将问题的答案与问题相关联,这对我们来说是幸运的,Java是一种面向对象语言。

Start with some concept of question 从一些问题的概念开始

public interface Question {
    public String getPrompt();
    public String getResponse(String input);
}

public abstract class AbstractQuestion implements Question {

    private String prompt;

    public AbstractQuestion(String prompt) {
        this.prompt = prompt;
    }

    @Override
    public String getPrompt() {
        return prompt;
    }

}

Now, we need some way to apply the current question... 现在,我们需要某种方式来应用当前问题...

private JTextArea ta;
//...
private Question question;
//...
public void setQuestion(Question q) {
    if (question != q) {
        question = q;
        if (question != null) {
            ta.append(question.getPrompt() + "\n");
            ta.setCaretPosition(ta.getDocument().getLength());
        }
    }
}

Now, when the ActionListener , we need to ask the Question for the response to the input... 现在,当ActionListener ,我们需要询问Question对输入的响应...

@Override
public void actionPerformed(ActionEvent e) {
    if (question != null) {
        String response = question.getResponse(tf.getText().trim());
        ta.append(response + "\n");
        ta.setCaretPosition(ta.getDocument().getLength());
    }
}

This way, you can control the response based on the current Question 这样,您可以根据当前Question控制响应

For example... 例如...

题

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JTextArea ta;
        private JTextField tf;

        private Question question;

        public TestPane() {
            setLayout(new BorderLayout());
            ta = new JTextArea(10, 30);
            ta.setEditable(false);
            add(new JScrollPane(ta));

            tf = new JTextField(10);
            add(tf, BorderLayout.SOUTH);

            tf.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (question != null) {
                        String response = question.getResponse(tf.getText().trim());
                        ta.append(response + "\n");
                        ta.setCaretPosition(ta.getDocument().getLength());
                    }
                }
            });

            setQuestion(new AbstractQuestion("Is your favorite color Red?") {
                @Override
                public String getResponse(String input) {
                    String response = "To bad, mine is";
                    if ("yes".equalsIgnoreCase(input)) {
                        response = "Cool!";
                    }
                    return response;
                }
            });
        }

        public void setQuestion(Question q) {
            if (question != q) {
                question = q;
                if (question != null) {
                    ta.append(question.getPrompt() + "\n");
                    ta.setCaretPosition(ta.getDocument().getLength());
                }
            }
        }

    }

    public interface Question {

        public String getPrompt();

        public String getResponse(String input);
    }

    public abstract class AbstractQuestion implements Question {

        private String prompt;

        public AbstractQuestion(String prompt) {
            this.prompt = prompt;
        }

        @Override
        public String getPrompt() {
            return prompt;
        }

    }

}

This kind of approach decouples the UI/user input from the logic of the question and allows you to isolate the responsibility for generating the response to the instance of the question, allowing you to make a potentially unlimited number of questions with out the need to generate a very long list of if-else statements 这种方法使UI /用户输入与问题的逻辑脱钩,并允许您隔离生成对问题实例的响应的责任,从而使您可以生成无限数量的问题而无需生成很长的if-else语句列表

Try something like 尝试类似

String question = "Is your favorite color Red?";
textArea.setText(question);
if(textArea.getText().equals(question))
{
        if (text.replaceAll("'", "").toLowerCase().contains("yes")){
            textArea.setText("Cool!");
        }else if (text.replaceAll("'", "").toLowerCase().equals("no")){
            textArea.setText(":(");
        }
}

You are setting the text area to "Is your favorite color Red?", but then later replacing that with "Cool!". 您将文本区域设置为“您喜欢的颜色是红色吗?”,但随后将其替换为“酷!”。 Instead, you should use something like the following so that you only set the text of the JTextArea once with everything you need. 相反,您应该使用类似以下的内容,以便只对JTextArea的文本进行一次设置即可。

textField.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
         final String text = textField.getText();

         StringBuilder sb = new StringBuilder();
         sb.append("Is your favorite color Red?\n");
         if (text.replaceAll("'", "").toLowerCase().contains("yes")){
             sb.append("yes\nCool!");
         } else if (text.replaceAll("'", "").toLowerCase().equals("no")){
             sb.append("no\n:(");
         }
         textArea.setText(sb.toString());
    }
});

My code inserts the "yes" and "no" answers into a specific place in the JTextArea, so you may have to change it around and figure out how exactly you want it. 我的代码将“是”和“否”的答案插入到JTextArea中的特定位置,因此您可能不得不更改它并弄清楚您想要的程度。

Note, however, that if I were programming this with Swing, I would use JLabel's for the questions and responses, and JRadioButton's for the multiple choice answers. 但是请注意,如果我使用Swing进行编程,则将JLabel用于问题和响应,而JRadioButton用于多项选择答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM