wood burning stoves 2.0*
The moose likes Beginning Java and the fly likes NullPointerException help.... Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCA/OCP Java SE 7 Programmer I & II Study Guide this week in the OCPJP forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "NullPointerException help...." Watch "NullPointerException help...." New topic
Author

NullPointerException help....

Jeff Pollet
Ranch Hand

Joined: Jul 20, 2005
Posts: 49
This is my first posting to javaranch, though I have been learning a lot over the past few weeks just from reading the responses to various questions--so thanks to everybody for asking and answering questions!

I'm working with the Head First Java book. I've taken one of the code examples given there and have been slightly tweaking it (helps me learn stuff),and I've run into a problem that I think shows that I don't understand something fairly fundamental.

Here's the code. Basically, it just creates a panel, a text box within the panel, and a button to press. Originally, the code was such that when the button was pressed,the text box printed 'button clicked' for every time it was pressed. I thought I'd just see if I could change it a bit so that after 5 times of pressing, it would print 'Knock it off' and after 10 times it would print 'That's it, I quit' and then close the panel (or make it invisible).


It compiles just fine, and runs fine until I press the button 10 times, at which time it prints out "That's it, I quit!"...and then I get a series of exception errors:


Obviously there is an unknown source problem. Heh. I'm guessing my problem involves the code in bold.

My guess is that I'm doing something wrong regarding using 'frame', but I'm not sure what...and I'm still not the clearest on public/private variables just yet.

I'm almost certain that I'm missing something simple and basic (and therefore important) here, so I'd appreciate a nudge in the right direction.

I realize that this is a 'homework-ish' type problem, but it would help me to understand better in general, so thanks in advance.

ps--oh, and could somebody tell me if Java is a TRUE object-oriented language? Just kidding...


newbie, please be gentle.
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

Hi Jeff,

Welcome to JavaRanch!

Thanks for the laugh about "true OO languages."

Let's see. In your event handler, you've got a line commented out "int x = 0;" Now, I think that means you did declare "x" as a local variable at first, found that didn't work, and then moved it to be a member variable, and it worked. Right?

I bring this up because your problem is due to something similar. There are two frame variables here: one a member, and one local to the method "go", which contains the line

JFrame frame = new JFrame();

that means the member stays "null", always, and so when the action listener tries to use it, it will be null, and you get this exception. What you want to do is have "go" use the member variable, not a local. Change that one line to

frame = new JFrame();

and your problem will go away!

So, the question is: do you understand why?


[Jess in Action][AskingGoodQuestions]
fred rosenberger
lowercase baba
Bartender

Joined: Oct 02, 2003
Posts: 11441
    
  16

Dang it Ernest...

i was about to make my post to help jeff, but you managed to beat me to it.

don't you have a JOB or something?

Of course, your answer is better than mine would have been. i'll just have to get faster...

fbr


There are only two hard things in computer science: cache invalidation, naming things, and off-by-one errors
Jeff Pollet
Ranch Hand

Joined: Jul 20, 2005
Posts: 49
Thanks for your help (both of you!).

The answer to your question about whether or not I understand why is: Yes and No. Heh.

I have an intuition about it--for instance, my event handler DOES use 'text' just fine, so I figured that the way text was set in go() (text = new JText) is fundamentally different from the way frame was set in go() (JFrame frame = new JFrame).

But I really don't understand the purposes/reasons for declaring variables in the two different ways.

First of all, why, in the original code given in the book, would one want to declare frame with 'JFrame frame = new JFrame'? That is, what reason would you want to declare it that way, rather than 'frame = new JFrame'?

Secondly, 'JFrame frame = new JFrame' is setting frame as a member variable, right? And 'frame = new JFrame' is setting frame as a local variable, right? Or do I have that backwards? It's still a bit confusing, obviously.

Thanks again for the help. I recognize that some of this is just conceptual stuff that I may have to just sort out on my own, but your help is most appreciated.
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

Your "secondly" is indeed backwards.

When you say

Foo aFoo ...;

you're declaring a variable. Where this code appears is important, as it determines the scope of the variable. If this is in the body of the class, then you make a member variable. If it's in the body of a method, then you've made a member variable. Most important for you: if it's in both, then you declare two variables, one of each; the local will be used in the method where it's declared, and the member will be used everywhere else. The local is said to "hide" or "shadow" the member -- and this is almost always an accident and a bug.

Now, what the "..." is determines what initial value, if any, gets assigned to the variable; and where it happens determines when the assignment gets done. Although you can write

Foo foo = new Foo();

all on one line, you can also write

Foo foo;
foo = new Foo();

(in some places, anyway) and it's really perfectly equivalent. The tricky part, perhaps, is when you declare a variable in one place, and initialize it -- assign a value to it -- later, like this:



One simple rule of thumb is that variables used only in one invocation of one method should be local, and variables shared by multiple methods or invocations should be members. In your program, "x" is shared by multiple method invocations, and "frame" is shared by multiple methods, so both ought to be members. But, for example "button" and "scroller" in go() should be locals, as they're never used outside of their defining method.

Make sense?
Jeff Pollet
Ranch Hand

Joined: Jul 20, 2005
Posts: 49
Thanks again Ernest for your help. It is definitely getting clearer. I see now that in the original program, 'frame' was declared and initialized within go(), making it a local variable--and this was done because originally, 'frame' was only to be used within go(). It was my meddling with things, and trying to use 'frame' from within another method that led to the trouble. Because I wanted to use 'frame' in a method outside of go(), I need to make sure that frame is declared as a memeber--that is, I have to declare it in the body of the class, rather than only in the body of the go() method.

Now my question is: Why not declare everything as a member? I'm guessing the answer is that it can create possible problems later on, make for messy code and the like, but is there a more specific reason not to?

Also, just to be clear, you wrote:

If this is in the body of the class, then you make a member variable. If it's in the body of a method, then you've made a member variable.


I'm hoping/guessing that there is a slight typo here, and you meant to say:

If this is in the body of the class, then you make a member variable. If it's in the body of a method, then you've made a local variable.

...otherwise I'm still not getting something important!

Thanks once again for your help. And so quickly, too. Hopefully someday I can help somebody out in a similar way.
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

Yes, a typo. Sorry.

Why not make everything a member? Well, lots of reasons. A few off the top of my head:

- There are plenty of variables (loop counters, pointers to open files) which are meaningful only during the method where they're used. Sharing them between methods simply wouldn't work -- or would be terribly confusing. Saving something in a member implies that it will be useful after the method returns; if it's not, that makes it harder to understand your rationale.

- If methods communicate via members rather than, say, via method parameters, then that communication is "hidden". It's harder to understand the code. Worse, one method can change a member variable and inadvertently change the operation of some other method that uses it. Therefore, it's best to limit use of member variables to a few well-understood cases.

- If you have a class Person, and you have, say, 100,000 Person objects in your program (it's a payroll program, say) then every 4-byte member variable adds a half a megabyte to your memory requirements.

There are more!
Jeff Pollet
Ranch Hand

Joined: Jul 20, 2005
Posts: 49
That all makes sense.

Thanks again for all of your help; I understand all of this a lot better than I did at the beginning of the day!

Maybe someday I'll understand enough to even grasp what your book is about, Ernest!
 
wood burning stoves
 
subject: NullPointerException help....