Variables referencing screen elements are set to 'null' after bind()

I can’t tell if this is a problem with me or Nifty. I’ve got a class that’s in charge of controlling the label and scroll panel portions of a chat program. I’ve got methods for retrieving and setting the text, but whenever I call them I get a NullPointerException.

I’ve got an Element variable that I initialize in the bind() method. I’ve tried getting it from the screen through both the Screen and Element parameters that get passed with bind(). Here’s an example of something I have:

[java]public void bind(Nifty arg0, Screen arg1, Element arg2, Properties arg3, Attributes arg4) {
screen = arg1;
textArea = screen.findElementByName(“output_area”);
scrollPanel = screen.findNiftyControl(“scroll_panel”, ScrollPanel.class);
}[/java]

Now, when I add code to this to add text to the label (textArea), it works fine. But as soon as I try to use it in a different function from an external call it crashes. How am I supposed to dynamically update the text if I can’t use it past the initialization?

“external call”… what kind of external call? Maybe it is not using the same instance.

I’ve got a ScreenController object that has as a member this controller object for dealing with outputting text. I’m realizing now that the problem might be that the controller that the ScreenController references isn’t the same as the one that’s initialized, but I’m not sure how I’m supposed to connect the two.

The line of code I’m using that I think is supposed to connect the two is the following:
[java]output = arg1.findControl(“chatArea”, ChatOutputController.class);[/java]

I’m not sure what else I can do. :cry:

@Jake-Steel said: Now, when I add code to this to add text to the label (textArea), it works fine. But as soon as I try to use it in a different function from an external call it crashes. How am I supposed to dynamically update the text if I can't use it past the initialization?

One way it works fine. The other way “from an EXTERNAL CALL” it does not.

This implies that the EXTERNAL CALL is somehow not using the same instance of the SCREEN CONTROLLER. Please describe how you are making this EXTERNAL CALL on the SCREEN CONTROLLER.

Because that’s probably where the problem is.

Edit: Or element or whatever. I find nifty really confusing sometimes so you will have to forgive me if I get the terms wrong. At any rate, print the value of what you are calling the method on with the “External call” and print the value of “this” in the bind.

I might have used the term “external call” incorrectly here, if it means something and I don’t realize it. Essentially what’s happening is that our game communicates with a server (to get messages from everyone online and the server itself). The ScreenController handles chat packets from the server. When it receives a packet, it checks the controller for the output area for its current contents and adds to it, which is where the problem arises.

I’ve followed the flow of control to make sure that things aren’t being initialized/set in the wrong order, and everything is flowing fine. The output controller is initialized before the screen, and the screen “saves” the controller before it registers the chat handler.

Again, I suspect that the screen controller that your networking code is calling is not the actual one bound to the real screen.

Some simple debugging will prove or disprove this… but if it were the same instance then there would be no problem… so I’m pretty sure it can’t be.

So since I may be speaking in confusing terms…

System.out.println( this );
…inside the bind() method.

System.out.println( screenControllerThatImUsing );
…inside your network chat handling code

Then report back here what they say.

That seems to be the problem. The output from the bind() method gave me this:

com.<secret>.<secret>.ui.NiftyHUDAppState@52c0152d

While the chat handler gave me this:

com.<secret>.<secret>.ui.NiftyHUDAppState$3@1edc5c8b

Unfortunately I’ve got no idea to to make sure to make the handler reference the right screen controller.

@Jake-Steel said: That seems to be the problem. The output from the bind() method gave me this:

com.<secret>.<secret>.ui.NiftyHUDAppState@52c0152d

While the chat handler gave me this:

com.<secret>.<secret>.ui.NiftyHUDAppState$3@1edc5c8b

Unfortunately I’ve got no idea to to make sure to make the handler reference the right screen controller.

Create the screen controller. Give it to nifty. Give it to the handler.

How does the handler get the screen controller now?

It doesn’t, actually. The code for creating the handler is part of the screen controller’s code, so I thought that would make the handler a part of it. I realize now that isn’t the case. I haven’t done a whole lot of work with handlers like this, or Nifty (this is my first time using it). Honestly I’m not sure how I can give the controller to nifty and then pass that along to the handler.

I would have to see the code to comment further on how you managed this. Are you letting nifty create the screen controller now or do you create it yourself? How is the network handler initialized and how does it find the network connection and stuff?

More code please. :slight_smile:

I’m creating the screen controller myself and having nifty connect it to the screen.

Here’s some code that’ll hopefully help you understand my position. This is the initialize method for the screen controller:

[java]@Override
public void initialize(AppStateManager stateManager, Application app) {
// TODO Auto-generated method stub
super.initialize(stateManager, app);
this.app = (SimpleApplication) app;
guiViewPort = this.app.getGuiViewPort();

	// Load the screen from the XML file.
	NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(this.app.getAssetManager(), this.app.getInputManager(), 
			this.app.getAudioRenderer(), this.app.getGuiViewPort());
	nifty = niftyDisplay.getNifty();
	nifty.fromXml("interface/gamehud.xml", "hud", this);
	guiViewPort.addProcessor(niftyDisplay);
	
	initHealthPanel();
}[/java]

This is the code for registering the handler. It’s not exactly my code as I’m working on this with a team, and someone else is handling most of the server code:

[java]// Register chat handler.
PacketID.CHAT.registerHandler(new PacketHandler() {
@Override
public void onReceive(Packet packet) throws IOException {
/* if (output.getText().isEmpty())
output.setText(message);
else
output.append("\n" + message); */
}
});[/java]

The handler is being set in the onStartScreen() method. The commented out code is the code that communicates with the output controller to display information.

Well, ok… “this” is going to be the PacketHandler subclass and not the outer screen controller when inside the packet handler. Did you edit this to remove the debug printlns? Those were critical to my understanding of what is going on and now I only see them in my e-mail of the reply.

What is “output” in that handler? …like print that too.

Really, you could just post the whole screen controller warts and all and it would be faster than two or three lines here and there.

This document may help:
http://hub.jmonkeyengine.org/2013/04/the-herodex-gui-working-in-jme3/