Solved

Why are my objects un-initializing?

Posted on 2014-12-02
7
104 Views
Last Modified: 2014-12-02
So I have a fairly simple class (the "events" are just extensions off of the listeners on the parent window object):

package com.peculiarhabit.application;

import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent;

import com.peculiarhabit.debug.Debug;
import com.peculiarhabit.gui.Window;
import com.peculiarhabit.input.KeyWatcher;

public class MainWindow extends Window {
	public static class Builder extends Window.Builder 	{	
		@Override public MainWindow build() {
			return new MainWindow(this);	
		}	
	}


	protected MainWindow(Builder b)  {
		super(b);	
	}


	protected KeyWatcher kw = null;
	
	@Override protected void windowInitialized() {
		kw = new KeyWatcher();
		Debug.print("kw is null: " + (kw == null));
	}
	
	@Override protected void mouseClicked(MouseEvent e) 	{
		Debug.print("(click) kw is null: " + (kw ==  null));
	}
	
	@Override protected void windowClosing(WindowEvent e) {
		Debug.print("Closing");
		if (kw == null) Debug.print("Why is it null?");
	}
	
}

Open in new window



So what happens here is that when run, it pops up a window.  I click the window.  Then I click the close button in the upper right-hand corner.  This is the Debug output:

00:00:00.000.113		main	kw is null: false
00:00:01.597.709		AWT-EventQueue-0	(click) kw is null: true
00:00:06.287.066		AWT-EventQueue-0	Closing
00:00:06.287.235		AWT-EventQueue-0	Why is it null?

Open in new window


Why is the "KeyWatcher" object being dropped?  I feel like it has to be something obvious that I'm missing.
0
Comment
Question by:Javin007
  • 4
  • 3
7 Comments
 
LVL 4

Author Comment

by:Javin007
ID: 40476490
Seems to be related to the threading for some reason.  I suspect the "main" thread is closing, and thus uninitializing all of its objects.  

While setting the object to "Final" kind of works (the object is now NOT initialized in the "init" event, but is in the further events) it's also not what I'm trying to do.  I would prefer that I be able to create/destroy the object when I want to.  

"Hanging" the main thread open (with a while loop that keeps it open as long as an "IsRunning" variable is "true") seems to get the desired result, but is that the right way to do things?  Seems a wasted thread to me.
0
 
LVL 35

Accepted Solution

by:
mccarl earned 500 total points
ID: 40477466
Unfortunately, the answer won't lie in the code that you have posted. Can you post the rest of your code that is applicable to this? ie. I would probably need your "Window" and "KeyWatcher" classes as well as whatever class contains you "main()" method.

My guess is that somewhere/somehow you have (at least) 2 different instances of your MainWindow class because there should be no other way to affect the "kw" field. So also, if you could using the following code for MainWindow (it has some extra debug output), and post the results it would help a lot...
package com.peculiarhabit.application;

import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent;

import com.peculiarhabit.debug.Debug;
import com.peculiarhabit.gui.Window;
import com.peculiarhabit.input.KeyWatcher;

public class MainWindow extends Window {
	public static class Builder extends Window.Builder 	{	
		@Override public MainWindow build() {
			return new MainWindow(this);	
		}	
	}


	protected MainWindow(Builder b)  {
		super(b);	
	}


	protected KeyWatcher kw = null;
	
	@Override protected void windowInitialized() {
		kw = new KeyWatcher();
		Debug.print("kw is null: " + (kw == null));
		Debug.print("'this' from windowInitialized" + Integer.toHexString(this.hashCode()));
	}
	
	@Override protected void mouseClicked(MouseEvent e) 	{
		Debug.print("(click) kw is null: " + (kw ==  null));
		Debug.print("'this' from mouseClicked" + Integer.toHexString(this.hashCode()));
	}
	
	@Override protected void windowClosing(WindowEvent e) {
		Debug.print("Closing");
		if (kw == null) Debug.print("Why is it null?");
		Debug.print("'this' from windowClosing" + Integer.toHexString(this.hashCode()));
	}
	
}

Open in new window

0
 
LVL 4

Author Comment

by:Javin007
ID: 40477511
Indeed, it appears that the problem was in the "KeyWatcher" class itself.  The class was watching the thread that spawned it, and "cleaning up" itself when that thread closed.  It seems that the main thread "shuts down" when it's done creating the windows and other objects, and that was triggering the KeyWatcher to shut itself down.  I was under the assumption that for as long as the application was running, the "main" thread would have an "IsAlive" value of "true".  Doesn't seem to be the case.

So while I've tracked down the problems, what was your reason for using the hashcodes?  What does that tell you?  Looks interesting.
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 35

Expert Comment

by:mccarl
ID: 40477587
what was your reason for using the hashcodes?  What does that tell you?
"hashcode()" is like an ID of the object. Each different object instance will have a different hashcode. So the code above was printing out the hashcode/ID of "this" which is the MainWindow object (note, it's NOT the KeyWatcher object). What I was expecting to see is at least 2 different hashcodes being printed out in those debug statements.

The thing is, even though you may have got your app working, I still think that there may be other underlying issues. Why? Because it is unlikely that anything else can change/null out your kw variable, ie. Nothing the KeyWatcher does in normal processing or as it is "shutting down" can make your kw == null.

So yeah, as I said, I still think that there is something else going on, so if can post the output with those hashcode debug statements, it would be good to double check things.
0
 
LVL 4

Author Comment

by:Javin007
ID: 40477654
Ah, unfortunately I'm past that point in the code now (I don't even have the KeyWatcher class anymore).  But I'll definitely keep that nugget in mind and use the hashcodes in the future!  Thanks!
0
 
LVL 35

Expert Comment

by:mccarl
ID: 40477700
I don't even have the KeyWatcher class anymore
Yes, but do you still have MainWindow? As I aluded to above, the issues with KeyWatcher was just a symptom of a bigger problem.

Anyway, I'll leave it up to you to decide if you want to pursue further but just so that you know, in case you see some issues in the future or that after I describe below you DO think it might still apply... What I think was the problem is that one instance of MainWindow was being created and .windowInitialized() was being called on that one, and then somehow another, different instance of MainWindow was being created later and that was what the other two methods were being called upon. Hopefully, you can see that this will cause other problems in the future if not resolved. Maybe your changes since the above code have sorted this out, but it is just something to keep in mind!! I am happy to keep this discussion open if you DO now feel like the issue may be there, after I've described it further.
0
 
LVL 4

Author Comment

by:Javin007
ID: 40477703
Yes, MainWindow hasn't changed, nor has its parent, but neither dealt with the "KeyWatcher" object, but you might see something I don't.  I'll have to post again when I get back to work tomorrow. Thanks for your help!
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
splitOdd10 challenge 5 80
Printing to a specific printer tray (HP 806dn printer) 3 83
Java Server Faces parameter pass? 6 39
servlet doXXX methods 3 36
Introduction Java can be integrated with native programs using an interface called JNI(Java Native Interface). Native programs are programs which can directly run on the processor. JNI is simply a naming and calling convention so that the JVM (Java…
Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
This video teaches viewers about errors in exception handling.

910 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now