= Interacting with the GUI from Java
:author: 
:revnumber: 
:revdate: 2016/03/17 20:48
:keywords: gui, documentation, input, control, hud, nifty
:relfileprefix: ../../
:imagesdir: ../..
ifdef::env-github,env-browser[:outfilesuffix: .adoc]


.  <<jme3/advanced/nifty_gui#,Nifty GUI Concepts>>
.  <<jme3/advanced/nifty_gui_best_practices#,Nifty GUI Best Practices>>
.  <<jme3/advanced/nifty_gui_xml_layout#,Nifty GUI XML Layout>> or <<jme3/advanced/nifty_gui_java_layout#,Nifty GUI Java Layout>>
.  <<jme3/advanced/nifty_gui_overlay#,Nifty GUI Overlay>> or <<jme3/advanced/nifty_gui_projection#,Nifty GUI Projection>>
.  *Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ Java Interaction*

In the previous parts of the tutorial, you created a two-screen user interface. But it is still static, and when you click the buttons, nothing happens yet. The purpose of the +++<abbr title="Graphical User Interface">GUI</abbr>+++ is to communicate with your Java classes: Your game needs to know what the users clicked, which settings they chose, which values they entered into a field, etc. Similarly, the user needs to know what the currently game state is (score, health, etc). 


== Connect GUI to Java Controller

To let a Nifty screen communicate with the Java application, you register a `ScreenController` to every NiftyGUI screen. You create a ScreenController by creating a Java class that implements the `de.lessvoid.nifty.screen.ScreenController` interface and its abstract methods.

Create an AppState *MyStartScreen*.java file in your package. ( Rightclick on your package → New → Other… → JME3 Classes → New AppState)

*Pro Tip:* Since you are writing a jME3 application, you can additionally make the ScreenController class extend the <<jme3/advanced/application_states#,AbstractAppState>> class! This gives the ScreenController access to the application object and to the update loop!

Now add *implements ScreenController* to _public class MyStartScreen extends AbstractAppState{_ and add *import de.lessvoid.nifty.screen.ScreenController;*

Continue with adding:

[source,java]
----

import de.lessvoid.nifty.screen.Screen;
    
...
    
public void bind(Nifty nifty, Screen screen) {
    throw new UnsupportedOperationException("Not supported yet."); 
}

public void onStartScreen() {
    throw new UnsupportedOperationException("Not supported yet."); 
}

public void onEndScreen() {
    throw new UnsupportedOperationException("Not supported yet.");
}

----

[source,java]
----
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package mygame;

import com.jme3.app.Application;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.screen.Screen;
import de.lessvoid.nifty.screen.ScreenController;

public class MyStartScreen extends AbstractAppState implements ScreenController {
    
    @Override
    public void initialize(AppStateManager stateManager, Application app) {
        super.initialize(stateManager, app);
        //TODO: initialize your AppState, e.g. attach spatials to rootNode
        //this is called on the OpenGL thread after the AppState has been attached
    }
    
    @Override
    public void update(float tpf) {
        //TODO: implement behavior during runtime
    }
    
    @Override
    public void cleanup() {
        super.cleanup();
        //TODO: clean up what you initialized in the initialize method,
        //e.g. remove all spatials from rootNode
        //this is called on the OpenGL thread after the AppState has been detached
    }

    public void bind(Nifty nifty, Screen screen) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void onStartScreen() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void onEndScreen() {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}

----

The name and package of your custom ScreenController class (here `mygame.MyStartScreen`) goes into the controller parameter of the respective XML screen it belongs to. For example:

[source,xml]
----

<nifty>
  <screen id="start" controller="mygame.MyStartScreen">
      <!-- layer and panel code ... -->
  </screen>
</nifty>

----

Or the same in a Java syntax, respectively:

[source,java]
----

  nifty.addScreen("start", new ScreenBuilder("start") {{
      controller(new mygame.MyStartScreen())}});

----

Now the Java class `MyStartScreen` and this +++<abbr title="Graphical User Interface">GUI</abbr>+++ screen (`start`) are connected. For this example you can also connect the `hud` screen to MyStartScreen.


== Make GUI and Java Interact

In most cases, you will want to pass game data in and out of the ScreenController. Note that you can pass any custom arguments from your Java class into your ScreenController constructor (`public MyStartScreen(GameData data) {}`).

Use any combination of the three following approaches to make Java classes interact with the +++<abbr title="Graphical User Interface">GUI</abbr>+++.


=== GUI Calls a Void Java Method

This is how you respond to an +++<abbr title="Graphical User Interface">GUI</abbr>+++ interaction such as clicks in XML GUIs:

.  Add `visibleToMouse=“true` to the parent element!
.  Embed the `&lt;interact /&gt;` element into the parent element. 
.  Specify the Java methods that you want to call when the users performs certain actions, such as clicking. +Example: `&lt;interact onClick=“startGame(hud) /&gt;`

Or this is how you respond to an +++<abbr title="Graphical User Interface">GUI</abbr>+++ interaction such as clicks in Java GUIs:

.  Add `visibleToMouse(true);` to the parent element!
.  Embed one of the `interact…()` elements into the parent element
.  Specify the Java method that you want to call after the interaction. +Example: `interactOnClick(“startGame(hud));`

In the following example, we call the `startGame()` method when the player clicks the Start button, and `quitGame()` when the player clicks the Quit button.

[source,xml]
----

        <panel id="panel_bottom_left" height="50%" width="50%" valign="center" childLayout="center">  
          <control name="button" label="Start" id="StartButton" align="center" valign="center" 
          visibleToMouse="true" > 
            <interact onClick="startGame(hud)"/>
          </control>
        </panel>

        <panel id="panel_bottom_right" height="50%" width="50%" valign="center" childLayout="center">  
          <control name="button" label="Quit" id="QuitButton" align="center" valign="center" 
          visibleToMouse="true" > 
            <interact onClick="quitGame()"/>
          </control>
        </panel>

----

Or the same in a Java syntax, respectively:

[source,java]
----

control(new ButtonBuilder("StartButton", "Start") {{
  alignCenter();
  valignCenter();
  height("50%");
  width("50%");
  visibleToMouse(true);
  interactOnClick("startGame(hud)");
}});
...

control(new ButtonBuilder("QuitButton", "Quit") {{
  alignCenter();
  valignCenter();
  height("50%");
  width("50%");
  visibleToMouse(true);
  interactOnClick("quitGame()");
}});

----

Back in the MyStartScreen class, you specify what the `startGame()` and `quitGame()` methods do. As you see, you can pass String arguments (here `hud`) in the method call. You also see that you have access to the app object.

[source,java]
----

public class MyStartScreen implements ScreenController {
  ...

  /** custom methods */ 
  public void startGame(String nextScreen) {
    nifty.gotoScreen(nextScreen);  // switch to another screen
    // start the game and do some more stuff...
  }

  public void quitGame() {
    app.stop(); 
  }
  
  ...
}

----

The startGame() example simply switches the +++<abbr title="Graphical User Interface">GUI</abbr>+++ to the `hud` screen when the user clicks Start. Of course, in a real game, you would perform more steps here: Load the game level, switch to in-game input and navigation handling, set a custom `running` boolean to true, attach custom in-game AppStates – and lots more.

The quitGame() example shows that you have access to the application `app` object because you made the ScreenController extend AbstractAppState.  (If you're creating code from this example, note that you'll need to make sure `app` is initialized before you can successfully call its methods.)


=== GUI Gets Return Value from Java Method

When the Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ is initialized, you can get data from Java. In this example, the Java class `getPlayerName()` in `MyStartScreen` defines the Text that is displayed in the textfield before the words `'s Cool Game`. 

First define a Java method in the screen controller, in this example, `getPlayerName()`.

[source,java]
----

public class MySettingsScreen implements ScreenController {
  ...
  public String getPlayerName(){
    return System.getProperty("user.name");
  }
}

----

Nifty uses `${CALL.getPlayerName()}` to get the return value of the getPlayerName() method from your ScreenController Java class.

[source,xml]
----

<text text="${CALL.getPlayerName()}'s Cool Game" font="Interface/Fonts/Default.fnt" width="100%" height="100%" />

----

Or the same in a Java syntax, respectively:

[source,java]
----
text(new TextBuilder() {{
  text("${CALL.getPlayerName()}'s Cool Game");
  font("Interface/Fonts/Default.fnt");
  height("100%");
  width("100%");
}});

----

You can use this for Strings and numeric values (e.g. when you read settings from a file, you display the results in the +++<abbr title="Graphical User Interface">GUI</abbr>+++) and also for methods with side effects.


=== Java Modifies Nifty Elements and Events

You can also alter the appearance and functions of your nifty elements from Java. Make certain that the element that you want to alter has its `id=“name` attribute set, so you can identy and address it.

Here's an example of how to change an image called `playerhealth`:

[source,java]
----

// load or create new image
NiftyImage img = nifty.getRenderEngine().createImage("Interface/Images/face2.png", false);
// find old image
Element niftyElement = nifty.getCurrentScreen().findElementByName("playerhealth");
// swap old with new image
niftyElement.getRenderer(ImageRenderer.class).setImage(img);

----

The same is valid for other elements, for example a text label “score:

[source,java]
----

// find old text
Element niftyElement = nifty.getCurrentScreen().findElementByName("score");
// swap old with new text
niftyElement.getRenderer(TextRenderer.class).setText("124");

----

Similarly, to change the onClick() event of an element, create an `ElementInteraction` object:

[source,java]
----

Element niftyElement = nifty.getCurrentScreen().findElementByName("myElement");
niftyElement.getElementInteraction().getPrimary().setOnMouseOver(new NiftyMethodInvoker(nifty, "myCustomMethod()", this));

----

For this to work, there already needs to be a (possibly inactive) `&lt;interact /&gt;` tag inside your xml element:

[source,xml]
----
<interact onClick="doNothing()"/>
----


== Next Steps

You're done with the basic Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ for jME3 tutorial. You can proceed to advanced topics and learn how add controls and effects:

*  <<jme3/advanced/nifty_gui_scenarios#, Nifty GUI Scenarios>>
*  link:http://sourceforge.net/projects/nifty-gui/files/nifty-gui/nifty-gui-the-manual-v1.0.pdf/download[Nifty GUI - the Manual]
