Nifty connection to Android appState

I have a jME3 program that starts a main SimpleApplication that sets up Nifty:

[java]
@Override
public void simpleInitApp() {
blankState = new BlankState(this);
graphicsState = new GraphicsState(this);

    loggerRunning = false;

    // Setup the GUI
    NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager,
            inputManager,
            audioRenderer,
            guiViewPort);
    nifty = niftyDisplay.getNifty();
    nifty.fromXml("Interface/settingsScreens.xml", "connection", this);
    nifty.addXml("Interface/graphicsScreen.xml");
    guiViewPort.addProcessor(niftyDisplay);
    inputManager.setCursorVisible(true);
    System.out.println("Initialized Main");
    stateManager.attach(blankState);

[/java]

BlankState and GraphicsState are classes that extend AbstractAppState. Using this method, everything works when I want to “print” values to labels in my GUI. What I am getting hung up on is how to correctly call functions when buttons are pressed in my GUI. I have tried to implement the ideas presented in the following wiki article:

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:nifty_gui_java_interaction

I have a class in my created Android project (the one located in the newly created mobile folder) called ReadLocationState:

[java]public class ReadLocationState extends AbstractAppState implements ScreenController { stuff }[/java]

This class implements bind, onStartScreen, and onEndScreen and then has a method checkConnections() to be called when the Check Connections button is pressed in the Nifty GUI. My problem is I don’t think I am correctly connecting my Nifty XML files to this class. I have tried both:

[java]
<screen id=“graphics” controller=“edu.pworm.mocap.ReadLocationState”>
[/java]

and

[java]
<screen id=“graphics” controller=“mobile.src.edu.pworm.mocap.ReadLocationState”>
[/java]

and neither one seems to register the button correctly. Am I going about this the wrong way? I can’t implement these buttons on the “jME3 program side” because when these buttons are pushed, I need to call Android specific functions. How is this normally done?

P-Worm

by doing this
[java]
nifty.fromXml(“Interface/settingsScreens.xml”, “connection”, this);
[/java]
you give nifty a controller (which seems to be your simpleApplication).
I guess this is your problem, just remove the last argument and try again.

Then about what you said at the end. If you want to call android specific functions from JME, you have to follows some rules.
First the android ui is running in its own thread so does JME.
So whatever you do, you have to enqueue the calls to the other thread.

for example to enqueue a call to JME you have to use app.enqueue(Callable);
to enqueue something to android you have to use activity.runOnUiThread(Runnable);

The other issue is that the JME part of your project doesn’t know android API. so you cant directly call runOnUIThread.
However, the android part of the project know JME API, and the main Activity has a reference to the JME application in the “app” protected attribute.
So you have to use some kind of communication layer.
Any pattern can work, observer, event bus, even queue.

There are plenty ways to do this but here is a simple one : Create a listener interface (Let’s say JMEWhateverListener) with an execute method for example. have the jme app hold a list of those listeners and public methods to add and remove listeners.
In the Android MainActivity override the onCreate and call super.onCreate() first. then add listeners to the JME app.
Of course those listeners execute method will call a runOnUIThread(runnable) that will finally call whatever android function you want.

Now all you have to do on the JME side is that somehow when you click on that button, the execute method of the listeners is called.