aspose file tools*
The moose likes Applets and the fly likes Text Field User Input into Array and last array element Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Applets
Bookmark "Text Field User Input into Array and last array element" Watch "Text Field User Input into Array and last array element" New topic
Author

Text Field User Input into Array and last array element

Roberta Fine
Greenhorn

Joined: Apr 23, 2013
Posts: 27
Hello CodeRanch,

Thanks for being here, I definitely can use your assistance. I have a program from my first Java class that I realize has a bug in it.
It turns out this same bug goes across similar programs, so it must be debugged!
The program is takes user's input of days of the week and stores them in a array of size 7 and then displays the array to the screen.

The problem is that in the actionPerformed method, I am gathering the days, storing them in the array, and when I display the array, the last day is showing up as "null."
I have tried changing every piece of this small program I can think of, and I know that the control should have n-1 for the array length.
So, please advise, here is the code, (I'm not sure how to attach the applet window with the output).




Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18882
    
    8

As you can see, your code is not filling in the last entry in your array of 7 strings. That's because line 43 of your posted code has the bug you are looking for.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18882
    
    8

And, welcome to the Ranch!
Roberta Fine
Greenhorn

Joined: Apr 23, 2013
Posts: 27
Hi Paul,

Thanks for the response! The thing is I have been adjusting that line over and over.
If I put "numDays < 7" , it takes all of the days, however, it prompts me an 8th time where I have input an Enter keystroke
for the process to close, and then the days to output to the console.

Is this correct to have to input an additional Enter keystroke? The thing that comes to mind is that the process needs
a null terminator to end. Also, isn't the control number supposed to be 1 less than the array size, i.e. "n-1"?

Please confirm, I spent a lot of time trying to figure this out! Thanks for the assist and the welcome pard'.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18882
    
    8

So if I understand that right (and I think I do), you should set done = true immediately after you fill in the last array entry. Right now you aren't doing it immediately, you're waiting for the next call of the action listener. (Which I guess is where the prompting happens, am I right?)
Roberta Fine
Greenhorn

Joined: Apr 23, 2013
Posts: 27
That's what I was thinking logically as well.
What happens exactly is:
1. It accepts a day
2. It clears the text field
3. It asks for 8 entries instead of 7 if I put "numDays < 7"
4. It asks for 7 entries if I put "numDays < 6" and outputs "null" in the seven element

What I thought it would do is:
1. Ask for entires up to 7 days,
2. After Sunday is entered, the post increment would increase numDays to 7
3. The condition would be tested, NOW numDays is 7, so
4. It should drop to the ELSE statement and exit.
5. And all of the days entered should be contained in array indices 0 to 6.

Yes?
Maneesh Godbole
Saloon Keeper

Joined: Jul 26, 2007
Posts: 10519
    
    9

What Paul meant was in your action performed, after numDays++, you do not check immediately if it has reached the limit. The limit check (else condition) is happening only on the next action performed.
To correct your logic, you need to make sure the limit check happens as soon as you increment numDays.

A couple of other things which might help
1) You are extending Applet. Applet is AWT which is like ancient. Unless your professor explicitly told you to do Applet (which he should not in my opinion), you should be extending JApplet which is Swing. Google for AWT/Swing difference. The one to use nowadays is Swing, i.e. JApplet. Usually it is a straight one to one replacement
Applet (AWT) -> JApplet (Swing)
Button (AWT) -> JButton (Swing)
Label (AWT) -> JLabel (Swing)
TextField (AWT) -> JTextField (Swing)
2) In swing, it is recommended you use paintComponent(Graphics g) instead of paint(Graphics g)


[How to ask questions] [Donate a pint, save a life!] [Onff-turn it on!]
Roberta Fine
Greenhorn

Joined: Apr 23, 2013
Posts: 27
Hi Maneesh,

I just saw your post after answering your message.
I'm working on it now, I'll post back soon, ; D
Roberta Fine
Greenhorn

Joined: Apr 23, 2013
Posts: 27
Maneesh Godbole wrote:What Paul meant was in your action performed, after numDays++, you do not check immediately if it has reached the limit. The limit check (else condition) is happening only on the next action performed.
To correct your logic, you need to make sure the limit check happens as soon as you increment numDays.


OK, I have learned more, however I am still stuck.
Yesterday and today when I run the debugger, what I see that the first condition checked is in paint,
"if (done == true)" , which should be the global variable "done," then a user input is accepted.

If I turn the "if (done == true)" condition off in paint, the debugger goes directly to the "displayDays" method and fills the array with nulls.
Then I can input the days which write over the "null" one by one. Which is still incorrect.

So, if I am supposed to check the condition immediately after incrementing "numDays++" before running the next action performed,
I would think I would move the variable attached to actionListener, which is "getInput" to run after the check is done.
However, I've tried that, and it doesn't stop the problem. Please advise!

Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18882
    
    8

Roberta Fine wrote:So, if I am supposed to check the condition immediately after incrementing "numDays++" before running the next action performed,


Yes, I think that would be the best thing to do.

I would think I would move the variable attached to actionListener, which is "getInput" to run after the check is done.


No, it's much simpler than that. Consider what "immediately" means. Your code "numDays++" is at line 46 of the original post. Where would you put code which you wanted to be run immediately after that?
Roberta Fine
Greenhorn

Joined: Apr 23, 2013
Posts: 27
The code I want to run immediately after that is to see if "numDays" is under the limit, over and over until it reaches the limit.

When I run the debugger, as soon as it executes "numDays++"it (bypasses the "else" condition),
moves to repaint(),
which in turn updates the screen.

I'm a little unclear about the difference between the "setText" method which clears the text field, and the "repaint()" method which
redraws the entire applet.
I think I only need to clear the text field over and over until the "done = true" condition is met.

However, it seems that repaint() has to be called after each iteration, so should it be moved above the "else" condition?

Am I on the right track?
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18882
    
    8

No, you aren't on the right track. Or actually, you are on the right track, you just keep on looking in the wrong place when you're deciding where to go.

You should be looking at that actionPerformed method. Nothing else. What it needs to do is only this:

1. Put the input number into the next array element.

2. If that was the last array element, set done = true.

Now, is there an "else" in that logic?

As for your question about repaint() versus setText(), I can't really answer that. That's because your logic for repeately getting input is rather strange, it isn't the usual way of writing GUI applications at all. But I don't want to fix that because it's a major project to throw it all away and write a new version. It's better to just try and make your code work.
Roberta Fine
Greenhorn

Joined: Apr 23, 2013
Posts: 27
I know it's hardly elegant code, it's from the first Java class I had.
The "else" statement is there to keep the "g.drawstring" in "paint" from writing to the screen until all input is in.
If I remove the "else", paint draws the output to the screen after the first day is input.
So it shows:

The days you entered are: Mondaynullnullnullnullnullnull
Maneesh Godbole
Saloon Keeper

Joined: Jul 26, 2007
Posts: 10519
    
    9

Hint:
Q. When should the 'done'* be set to true?
A. When you have populated all elements in the array.
Like Paul said, take out the else totally. You don't need it and its causing you grief

*Side note: Using if (done == true) is bad form and error prone. Use if(done)
Roberta Fine
Greenhorn

Joined: Apr 23, 2013
Posts: 27
I did take out the "else" and just have "done = true" after "numDays++"
If I do that paint outputs the days right after I input Monday.
I have done every manipulation I can think of, it just isn't working.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18882
    
    8

Roberta Fine wrote:I did take out the "else" and just have "done = true" after "numDays++"


And was that your implementation of this?

2. If that was the last array element, set done = true.
Roberta Fine
Greenhorn

Joined: Apr 23, 2013
Posts: 27
Ok, I'm going to go for plain logic.
The array is filled when the "if (numDays <= 6 )" has Monday through Sunday.
Then "numDays" becomes a 7 which is the trigger to go to the next statement
"done = true".
Is this not correct?

Normally I would have the function return a boolean and return true, however
actionPerformed is type void.

Roberta Fine
Greenhorn

Joined: Apr 23, 2013
Posts: 27
Hold up here pards, I think I have a breakthrough
It seems so elementary, I'm hesitant, however, here it goes:

{
if (numDays > 6)
done = true;
}

Isn't this spelling out what the "else" statement was supposed to be doing?
Maneesh Godbole
Saloon Keeper

Joined: Jul 26, 2007
Posts: 10519
    
    9

Nope.
In pseudo code

1) Identify user input
2) Check numDays
3) If numDays within acceptable limit (Hint: refer to the 6/7 conversation with Paul above)
3.a) Add user input to array
3.b) Increment numDays (because you did 3.a above)
4) Now check if you are done (check should be an exact (hint) check)
4.a) If done, call repaint
Roberta Fine
Greenhorn

Joined: Apr 23, 2013
Posts: 27
OK, I've adjusted the method block as follows, thanks for the pseudo code...
It works, thanks to our diligence...; ) However, why didn't the "else" work? Isn't the definition of it that when the preceding "if" condition isn't met,
the "else" condition is then executed?


Maneesh Godbole
Saloon Keeper

Joined: Jul 26, 2007
Posts: 10519
    
    9

Almost there
Are you sure your code follows 4.a to the letter? Hint: If done,...

Roberta Fine wrote:However, why didn't the "else" work? Isn't the definition of it that when the preceding "if" condition isn't met,

You have answered your own question already! "else" will be executed if the "if" condition isn't met. In other words, if the if condition is met, the else will be ignored. In light of this, can you see what was happening in your original code and what Paul meant when he said about the "next actionPerformed"?

PS. Another minor point.
Instead of if(numDays == 7) you can directly use this evaluation like done = (numDays == 7)

Roberta Fine
Greenhorn

Joined: Apr 23, 2013
Posts: 27
Please see next post....

Roberta Fine
Greenhorn

Joined: Apr 23, 2013
Posts: 27

I understand the condition of the "else" statement.
I could see in the debugger that actionPerformed tested the condition after "numDays" increased to 7,
rather than "numDays" increasing to 7 and then immediately dropping to the "else" condition.
However, no matter where else (ha ha) I put "else" statement, it would output the paint method to the screen after the first day was entered...??

Here is the corrected code:

Maneesh Godbole
Saloon Keeper

Joined: Jul 26, 2007
Posts: 10519
    
    9

Is this more exact?

No. Line 12 of your latest code can be done = (numDays == 7)

However, no matter where else (ha ha) I put "else" statement, it would output the paint method to the screen after the first day was entered...??

Your repaint is outside the if block and thus executed after every action performed. You will get output on the screen like
Sunday,null,null,....
Sunday,Monday,null,....

Come to think of it I might be confused with your requirement.
If you need to see the output like above, then your latest code is correct.
On the other hand, if you want to see the output only after the user has entered all the days, then just move the repaint call inside the if block. In other words, call repaint only if you are "done"
Sorry about the confusion on my part
Roberta Fine
Greenhorn

Joined: Apr 23, 2013
Posts: 27
We crossed paths when I corrected my last post....would you please look again?
And, you are really helping me, I do appreciate it!
Maneesh Godbole
Saloon Keeper

Joined: Jul 26, 2007
Posts: 10519
    
    9

Heh! You got it

What I meant was instead of

This would be more elegant


Notice how the evaluation of numDays == 7 is assigned directly to the 'done' boolean variable making the done = true redundant
Roberta Fine
Greenhorn

Joined: Apr 23, 2013
Posts: 27
Thank you for all of the assist and Paul too!
See how a little program can have so many different aspects?
I try to learn as much as I can from the small ones, so when the big ones come,
it will be easier.
Hmmmm....speaking of bigger programs, the next one I'm posting is a lot bigger.
It's an animation in an applet (from the same teacher and class) and it has some
very interesting points.
There's a bug in it too (at least one).
I'll post tomorrow, thanks again, have a great night!
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Text Field User Input into Array and last array element