user4920910
user4920910

Reputation:

ActionListener acting wierd

I am having a problem with my ActionListener's not acting as (I think) they should. I have the below code:

textField.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
             final String text = textField.getText();
             if (text.toLowerCase().replaceAll("'", "").contains("whats new")){
                 textArea.setText("Oh, you know...work...college. I am a computer science major and software engineer.\nDo you program?");
                 if (text.toLowerCase().replaceAll("'", "").contains("yes")){
                     textArea.setText("Cool!");
                 }else{
                     textArea.setText(":(");
                 }
             }
          }
        });

The textField is where the user types the question, and the textArea is where the program answers. The problem is, when I type "whats new", then "yes", it gives me the default string I set for when it doesn't understand.

Upvotes: 1

Views: 46

Answers (2)

Paul Bilnoski
Paul Bilnoski

Reputation: 556

You're not thinking fourth-dimensionally! (kidding aside now)

You are attempting to handle the sequence of events at once in your listener but your listener will actually be called multiple times: once for an answer to the first question and a second time for a reply to your follow-up comment.

You need to make your listener handle both of these states independently. You probably need to capture the state of your last asked question in the class scope and check it in your listener to determine what question was asked so you will know how to evaluate the contents of text and give the proper reply.

You will probably not study finite automata or formal study of state machines for several more semesters, but it's a crucial step to have elementary understanding of. Without knowing the problem statement provided, I assume the assignment is trying to push you into that direction. Also, in any paradigm, though for Java we'll stick with OO, there are many ways to add some layers of beauty and fault-tolerance for a better solution, but my intent is to stick with what is simplest for you. For example, you could make a class that represents each state pending the user's response (question 1, question 2, etc.) and model the states and transitions within your application. Each state as modeled would know of the question asked, potential answers, and transitions to other states. In an OO system, each of these states would have an API and operate via some call like execute() which would evaluate the current state of the system and determine a transition. Do some more research on this on your own.

Back to your simpler example. Let's say you only have two cases, one for each question: "what's new" and "do you program". Store some representation in your class (named constants are good practice):

class Interrogator {
     String q1 = "what's new";
     String a1 = ...do you program?";
     String q2 = "yes";
     ...
}

Now in your actionPerformed, test the contents of both your question-text-area against known questions and your answer area against known responses: if (a1.equals(textArea.getText() && q2.equals(text.getText())) then you know you the answer to the initial (unprompted) question is displayed and an expected response was entered. Don't forget your formatting translation (to lower case, strip quotes).

Upvotes: 4

Stylishcoder
Stylishcoder

Reputation: 1222

It gives you the default because the second if statement is inside the first. When the first test is true, the second test which nested inside the first test will be false casing the else clause to override your textArea with default text. You should do something like this

if (text.toLowerCase().replaceAll("'", "").contains("whats new")){
   ...       
}
else if (text.toLowerCase().replaceAll("'", "").contains("yes")) {
   ...
}
else {
    ...
}

Upvotes: 0

Related Questions