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.
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 MySettingsScreen(MyGameData data ){ /** constructor */ } 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.
In most cases, you will want to pass game data in and out of the ScreenController. Note that you can pass any arguments into your ScreenController constructor. In the example above, the object with the necessary data is is MyGameData data
.
You can use any of the three following approaches to make Java classes interact with the GUI, and you can also combine them, depending on what you want to do.
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); } }
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.
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.getElementInteraction().getPrimary().setOnMouseOver(new NiftyMethodInvoker(nifty, "myCustomMethod()", this));
For this to work, there already needs to be an < interact > tag inside your xml element:
<interact onClick="doNothing()"/>
note: Nifty-gui 1.3 oriented.
Even though you create and populate the popup menu in Java you still need a "placeholder" in your XML file, below is an example extract:
<useControls filename="nifty-default-controls.xml"/> ... <popup id="niftyPopupMenu" childLayout="absolute-inside" controller="ControllerOfYourChoice" width="10%"> <interact onClick="closePopup()" onSecondaryClick="closePopup()" onTertiaryClick="closePopup()" /> <control id="#menu" name="niftyMenu" /> </popup> ...
A brief explanation of some the attributes above:
Java code within your defined ScreenController implementation:
private Element popup; ... public void createMyPopupMenu(){ popup = nifty.createPopup("niftyPopupMenu"); Menu.class); myMenu.setWidth(new SizeValue("100px")); //must be set myMenu.addMenuItem("Click me!", "menuItemIcon.png", new menuItem("menuItemid", "blah blah")); //menuItem is a custom class nifty.subscribe(nifty.getCurrentScreen(), myMenu.getId(), MenuItemActivatedEvent.class, new MenuItemActivatedEventSubscriber()); } public void showMenu(){ //the method to trigger the menu createMyPopupMenu() //you should call this in your constructor rather than here if it is a menu that is going to be used many times nifty.showPopup(nifty.getCurrentScreen(), popup.getId(), null); //call the popup to screen of your choice } private class menuItem{ public String id; public String name; public menuItem(String name){ this.id= id; this.name = name; } }
To handle menu item events (i.e. calling a method when you click on a menu item) you subscribe a EventTopicSubscriber<MenuItemActivatedEvent> class implementation to a nifty screen and element.
private class MenuItemActivatedEventSubscriber implements EventTopicSubscriber<MenuItemActivatedEvent> { @Override public void onEvent(final String id, final MenuItemActivatedEvent event) { menuItem item = (menuItem) event.getItem(); if ("menuItemid".equals(item.id)) { //do something !!! } } };
Nifty 1.3 controls Java Docs: http://nifty-gui.sourceforge.net/projects/1.3-SNAPSHOT/nifty-default-controls/apidocs/
Nifty 1.3 Java Docs: http://nifty-gui.sourceforge.net/projects/1.3-SNAPSHOT/nifty/apidocs/index.html
Examples of standard controls in Nifty 1.3: http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Nifty_Standard_Controls_%28Nifty_1.3%29
Learn more: Nifty Syntax