# Interacting with the GUI from Java

1. Nifty GUI XML Layout
2. Nifty GUI Overlay or Nifty GUI Projection
3. Nifty GUI Java Interaction

The main purpose of the GUI is to send events back to your Java class that indicate what the users clicked, which settings they chose, which values they entered into a field, etc. In the Java class, you want to respond with an appropriate action, or store the entered settings in a file, etc.

## Connect GUI to Java Controller

How does the XML file send a message back to your Java application? You register a ScreenController (a Java class) to every NiftyGUI screen.

Create a ScreenController by creating a Java class that implements the `de.lessvoid.nifty.screen.ScreenController` interface and its abtract methods.

    package my.game;
    import de.lessvoid.nifty.Nifty;
    import de.lessvoid.nifty.screen.Screen;
    import de.lessvoid.nifty.screen.ScreenController;

    public class MySettingsScreen implements ScreenController {

        public void bind(Nifty nifty, Screen screen) { }

        public void onStartScreen() { }

        public void onEndScreen() {  }
    }

The name and package of your custom ScreenController class (here `my.game.MySettingsScreen`) goes into the controller parameter of the respective screen it belongs to:

    <nifty>
      <screen id="settings" controller="my.game.MySettingsScreen">
          <!-- layer and panel code ... -->
      </screen>
    </nifty>

Now the Java class `my.game.MySettingsScreen` and this GUI screen (`settings`) are connected.

## Make GUI and Java Interact

You can use any of the three following approaches to interact, and you can also combine them, depending on what you want to do.

### GUI Calls a Void Java Method

To respond to an interaction, add the <interact /> element to a panel and specify the Java method you want to call. In this example, we want to call `sayHello()` when a panel on the screen is clicked.

    ...
    <panel id="panel" height="25%" width="35%" align="center" valign="center"
           backgroundColor="#f60f" childLayout="center" visibleToMouse="true">
        <text id="text" font="aurulent-sans-17.fnt" color="#000f"
              text="Hello World!" align="center" valign="center" />
        <interact onClick="sayHello(hi)"/>
    </panel>
    ...

Back in this screen's Java class, we specify what the `sayHello()` method does. As you see, you can include String arguments in the call.

    public class MySettingsScreen implements ScreenController {
      ...
      public void sayHello(String myarg) {
         System.out.println("Nifty says "+myarg);
      }
    }

### GUI Gets Return Value from Java Method

You can send a message from Java to Nifty. In this example, the Java class `callThis()` in MySettingsScreen defines the Text that is displayed in the textfield after the words `Hello World, …!`

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

    public class MySettingsScreen implements ScreenController {
      ...
      public String callThis() {
         return "my friend";
      }
    }

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

    ...
    <panel id="panel" height="25%" width="35%" align="center" valign="center"
           backgroundColor="#f60f" childLayout="center" visibleToMouse="true">
        <text id="text" font="aurulent-sans-17.fnt" color="#000f"
              text="Hello World, ${CALL.callThis()}!" align="center" valign="center" />
        <interact onClick="sayHello(hi)"/>
    </panel>
    ...

You can also use this for Strings and numeric values, e.g. when you read settings from a file, you read them like this.

### Java Modifies Nifty Elements and Events

You can also alter the appearance and functions of your nifty elements from Java.

Here's an example of how to change the image `myElement`:

    NiftyImage img = nifty.getRenderEngine().createImage("Interface/Images/image.png", false);
    Element niftyElement = nifty.getCurrentScreen().findElementByName("myElement");
    niftyElement.getRenderer(ImageRenderer.class).setImage(img);

The same is valid for other elements, for example text fields:

    niftyElement.getRenderer(TextRenderer.class).setText("New text");

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

    Element niftyElement = nifty.getCurrentScreen().findElementByName("myElement");
    niftyElement.setInteraction(new ElementInteraction(nifty) {

        @Override
        public void onClick() {
            // call java functions normally.
            niftyController.onElementClicked();
            super.onClick();
        }

        @Override
        public boolean onClick(MouseInputEvent inputEvent) {
            niftyController.onElementClicked();
            return super.onClick(inputEvent);
        }
    });

For this to work, there already needs to be an < interact > tag inside your xml element:

    <interact onClick="doNothing()"/>

Learn more:

gui, documentation, input, controller, controllers

view online version