ActionListener acting wierd - java

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.

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

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

Related

Is there an elegant way to check many conditions and call corresponding functions?

So, say I've got lots of values and flags passed into my program from the command line, all stored as variables in some configuration object, config. These variables default to null if they are not provided by the user.
I've then got some other object, say an instance of Dog, which has lots of methods. Depending on the value of a specific command line argument, I may or may not want to call a specific method, possibly passing the argument value to the method.
At the moment I'm doing that like this:
Dog dog = new Dog();
if (config.argumentA != null) {
dog.methodA(config.argumentA);
}
if (config.argumentB != null) {
dog.methodB(config.argumentB);
}
if (config.boolArgument) {
dog.methodC();
}
// ... ... ...
if (config.argumentZ != null) {
dog.methodZ(config.argumentZ);
}
Now I've tried to look for a more elegant way of doing this, since this feels very dirty, but Google and Java jargon have me stumped.
I'm imagining making a map from the arguments' names to the function names, then looping through, checking each argument's value and calling the corresponding method. Does such a mapping exist in Java? Is there any way to do this nicely, or am I going about the problem completely wrong?
P.S.: I'm a bit of a beginner with both Java and problems like this, so pls be gentle :)
Actually this question relates to the programming practices. So like Alan Kay said OOP is basically message passing. Thus your code should not be making these decisions but rather passing this info to some other method of some other class, till the time it's actually needed. Now if you couple this concept with different Design patterns you'll get an elegant piece of code.
Also it's difficult to suggest a particular solution to a problem as abstract as your's.

Is there a name for the difference of these two code styles?

When i see code from others, i mainly see two types of method-styling.
One looks like this, having many nested ifs:
void doSomething(Thing thing) {
if (thing.hasOwner()) {
Entity owner = thing.getOwner();
if (owner instanceof Human) {
Human humanOwner = (Human) owner;
if (humanOwner.getAge() > 20) {
//...
}
}
}
}
And the other style, looks like this:
void doSomething(Thing thing) {
if (!thing.hasOwner()) {
return;
}
Entity owner = thing.getOwner();
if (!(owner instanceof Human)) {
return;
}
Human humanOwner = (Human) owner;
if (humanOwner.getAge() <= 20) {
return;
}
//...
}
My question is, are there names for these two code styles? And if, what are they called.
The early-returns in the second example are known as guard clauses.
Prior to the actual thing the method is going to do, some preconditions are checked, and if they fail, the method immediately returns. It is a kind of fail-fast mechanism.
There's a lot of debate around those return statements. Some think that it's bad to have multiple return statements within a method. Others think that it avoids wrapping your code in a bunch of if statements, like in the first example.
My own humble option is in line with this post: minimize the number of returns, but use them if they enhance readability.
Related:
Should a function have only one return statement?
Better Java syntax: return early or late?
Guard clauses may be all you need
I don't know if there is a recognized name for the two styles, but in structured programming terms, they can be described as "single exit" versus "multiple exit" control structures. (This also includes continue and break statements in loop constructs.)
The classical structured programming paradigm advocated single exit over multiple exit, but most programmers these days are happy with either style, depending on the context. Even classically, relaxation of the "single exit" rule was acceptable when the resulting code was more readable.
(One needs to remember that structured programming was a viewed as the antidote to "spaghetti" programming, particularly in assembly language, where the sole control constructs were conditional and non-conditional branches.)
i would say it's about readability. The 2nd style which i prefer, gives you the opportunity to send for example messages to the user/program for any check that should stop the program.
One could call it "multiple returns" and "single return". But I wouldn't call it a style, you may want to use both approaches, depending on readability in any particular case.
Single return is considered a better practice in general, since it allows you to write more readable code with the least surprise for the reader. In a complex method, it may be quite complicated to understand at which point the program will exit for any particular arguments, and what side effects may occur.
But if in any particular case you feel multiple returns improve readability of your code, there's nothing wrong with using them.

Referencing not-yet-defined variables - Java [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Because I'm tired of solving math problems, I decided to try something more engaging with my very rusty (and even without the rust, very basic) Java skills. I landed on a super-simple people simulator, and thus far have been having a grand time working through the various steps of getting it to function. Currently, it generates an array of people-class objects and runs a for loop to cycle through a set of actions that alter the relationships between them, which I have stored in a 2d integer array. When it ends, I go look at how much they all hate each other. Fun stuff.
Trouble has arisen, however, because I would like the program to clearly print what action is happening when it happens. I thought the best way to do this would be to add a string, description, to my "action" class (which stores variables for the actor, reactor, and the amount the relationship changes). This works to a degree, in that I can print a generic message ("A fight has occurred!") with no problem. However, ideally I would like it to be a little more specific ("Person A has thrown a rock at Person B's head!"). This latter goal is proving more difficult: attempting to construct an action with a description string that references actor and reactor gets me a big old error, "Cannot reference field before it is defined." Which makes perfect sense.
I believe I'm not quite in programmer mode, because the only other way I can think to do this is an unwieldy switch statement that negates the need for each action to have its own nicely-packaged description. And there must be a neater way. I am not looking for examples of code, only a push in the direction of the right concept to handle this.
Wow. Quite a large wall of text. Hence:
Breakdown
Your setup
Currently, it generates an array of people-class objects and runs a for loop to cycle through a set of actions that alter the relationships between them, which I have stored in a 2d integer array.
I would like the program to clearly print what action is happening when it happens.
I thought the best way to do this would be to add a string description to my "action" class (which stores variables for the actor, reactor, and the amount the relationship changes).
It sounds like your Action class so far looks something like this:
public class Action {
private String reactor;
private String actor;
private double hateMeasure;
/* Obligatory constructor method, getters, and setters go here */
}
Your trouble
I would like it to be a little more specific ("Person A has thrown a rock at Person B's head!").
... attempting to construct an action with a description string that references actor and reactor gets me ... "Cannot reference field before it is defined."
At this point I'm not quite sure how you're setting up your reference fields, and exactly how you're running into this error.
I know you weren't looking for code, but you must appreciate the difficulty of getting somebody into "programmer mode" without showing them some skeletal principle-illustrating code.
Perhaps create a method that takes two parameters of the actor and reactor, and then call that method after each action happens?
public void reportAction(String reactor, String actor) {
// do stuff
}
/* if you're confused by how "reactor" and "actor" have the same names as
the instance variables, look into the "this" keyword */
Alternatively (if your setup was different from what I inferred from your description, add in those instance variables and then) you can simply write a new method in your Action class that takes no parameters and simply references your instance variables:
public void reportAction() {
System.out.println(actor + " with " + reactor);
}
Now it occurs to me that you may wish to specify what happened between the reactor and actor instead of simply stating that something happened between two specific simulated people. In that case...
public void reportAction() {
System.out.print(actor);
// you're going to have to define the change in hateMeasure here
if( deltaHateMeasure > 0 ) {
System.out.print(" had a fight with " + reactor);
} else { /* print other stuff */ }
}
Another fun thing for you to look at would be ternary operators, if you'd like to code this succinctly.
Have fun!
EDIT:
Even better!
Add in a String descriptor; instance variable to your class!
Then it all comes down to...:
public void reportAction() {
System.out.println(actor + descriptor + reactor);
}
I am not exactly sure how you wrote your classes. Am I correct in assuming that at the time that you want to print your string, you do know the names of the actor and reactor?
If so, you should be able to do something along these lines:
System.out.printf(action.description, actor.name, reactor.name);
In which case action.description (or wherever you store your description string) looks something like:
"%s has thrown a rock at %s's head!";
I hope this helps!

Comparison Method violates its general contract. Simple comparison

I'm doing a card game in swing (java)
The user has to wait his turn, take a card, and press confirm. When it's not his turn, he can't take any card.
It starts this way:
this.cardTaken = false;
board.canTakeCards(!cardTaken);
Then in board class it comes the next action:
public void canTakeCards(boolean can) {
if (can) {
this.btnConfirm.setEnabled(false);
this.pnlCards.setCanTake(true);
} else {
this.btnConfirm.setEnabled(true);
this.pnlCards.setCanTake(false);
}
(the else happens when the user takes a card).
So. I got the Comparison method violates its general contract at line board.canTakeCards(!cardTaken);
That only happened one time and I "tested" my game for about 8 times. I'm really confused and afraid about this.
One of my theories is that I call this function from 2 differents parts of the code at the same execution time, and it receives a true and false at the same time. But I revised my code and i think that's imposible.
Any advice? Thanks
This message text is included in an exception thrown from Java 7 sorted collections, indicating that the object in question has an inconsistent implementation of compareTo, which basically means it is not imposing a total ordering on the objects. Prior to Java 7 this was silently ignored. Revise your Comparable classes.

When to use an exception instead of a boolean

Let say you have a method that checks if the argument (Answer) is correct and check if the question already have answers in the list that is also correct:
public void addAnswer(Answer answer) {
if (answer.isCorrect()) {
...
}
}
However, I only want one answer to be correct in the list. I have multiple options. I could throw an exception, I could ignore it, I could return some boolean value from the addAnswer that tells me if the operation was ok or not. How are you supposed to think in such scenarios?
The rule is pretty simple: Use exceptions on exceptional, erroneous, unpredicted failures. Don't use exceptions when you expect something to happen or when something happens really often.
In your case it's not an error or something truly rare that an answer is not correct. It's part of your business logic. You can throw an exception, but only as part of some validation (assertion) if you expect an answer at given point to always be correct and suddenly it's not (precondition failure).
And of course if some failure occurs while checking correctness (database connection lost, wrong array index) exception are desired.
This entirely depends on what you want to achieve. Should the caller of your method already have made sure that it doesn't add two correct answers? Is it a sign of a programming error if that happens? Then throw an exception, but definitely an unchecked exception.
If your method's purpose is to relieve the caller from enforcing the one-true-answer invariant (I doubt that, though), then you can just arrange to signal via a boolean return value, which makes it only an optional information channel for the caller.
If there is no way to know in advance whether there are other correct answers—for example, the answers are added concurrently from several threads or even processes (via a database)—then it would be meaningful to throw a checked exception.
Bottom line: there is no one-size-fits-all best practice, but there is a best practice for every scenario you want to accomplish.
The exception police will be down on you like a ton of bricks, and me for this answer, with statements like "don't use exceptions for flow control" and "don't use exceptions for normal conditions".
The trouble with the first statement is that exceptions are a form of flow control. This makes the argument self-contradictory, and therefore invalid.
The trouble with the second statement is that it seems to inevitably go along with endlessly redefining exceptional conditions as normal. You will find examples in this very site: for example, a lively discussion where the police insisted that EOF was 'normal' and therefore that EOFException shouldn't be caught, despite the existence of dozens of Java APIs that don't give you any choice in the matter. Travel far enough down this path and you can end up with nothing that is exceptional whatsoever, and therefore no occasion to use them at all.
These are not logical arguments. These are unexamined dogmas.
The original and real point, back in about 1989 when it was first formulated, was that you shouldn't throw exceptions to yourself, to be handled in the same method: in other words, don't treat it as a GOTO. This principle continues to have validity.
The point about checked exceptions is that you force the caller to do something about handling them. If you believe, on your own analysis, that this is what you want, use an exception. Or, if you are using an API that forces you to catch them, catch them, at the appropriate level (whatever that is: left as an exercise for the reader).
In other words, like most things in the real world, it is up to your discretion and judgment. The feature is there to be used, or abused, like anything else.
#Exception police: you will find me in the telephone book. But be prepared for an argument.
An exception thrown from a method enforces the callers to take some action in the anticipation of the exception occurring for some inputs. A return value doesn't enforce the same and so it is up to the caller to capture it and take some action.
If you want the callers to handle the scenario to take some corrective action, then you should throw a checked exception (sub class of java.lang.Exception).
The problem here is that your API is error prone. I'd use the following scheme instead:
public class Question {
private List<Answer> answers;
private int mCorrect;
// you may want a List implementation without duplicates
public void setAnswers(List<Answer> answers, int correct) {
this.answers = answers;
// check if int is between bounds
mCorrect = correct;
}
public boolean isCorrect(Answer answer) {
return answers.indexOf(answer) == mCorrect;
}
}
because an Answer by itself is simply a statement, and usually cannot be true of false without being associated to a Question. This API makes it impossible to have zero or more than one correct answers, and forces the user to supply the correct one when he adds answers, so your program is always in a consistent state and simply can't fail.
Before deciding how to signal errors, it's always better to design the API so that errors are less common as possible. With your current implementation, you have to make checks on your side, and the client programmer must check on his side as well. With the suggested design no check is needed, and you'll have correct, concise and fluent code on both sides.
Regarding when to use a boolean and when to use Exceptions, I often see boolean used to mirror the underlying API (mostly low level C-code).
I agree with Tomasz Nurkiewicz's response. I cant comment on it because I'm a new user. I would also recommend that if the addAnswer() method is not always going to add the answer (because they already exists a correct one), name it to suggest this behaviour. "add" is suggest normal collections behaviour.
public boolean submitAnswer(Answer answer); // returns true is answer accepted
Your exact solution may depend on the bigger picture about your application that we dont know about. Maybe you do want to throw an Exception but also make it the responsibility of the caller to check if adding the Answer is valid.
It's all a rich tapestry.
I would implement it in this way:
public class Question {
private int questionId;
private final Set<Answer> options = new HashSet<Answer>();
private final Set<Answer> correctAnswers = new HashSet<Answer>();
public boolean addAnswer(Answer answer) throws WrongAnswerForThisQuestionException {
if(!answer.isValid(questionId)) {
throw new WrongAnswerForThisQuestionException(answer, this);
}
if (answer.isCorrect(questionId)) {
correctAnswers.add(answer);
}
return options.add(answer);
}
}

Categories

Resources