Working niftygui code for android

I am trying to make niftygui work with android and am having very little luck. Things seem to be worse since beta came out. Does anyone have some known working android code with xml definition file that I could have. It really needs to do something like respond to effects, touches and utilize controls like buttons. Anything that I could run on my tablet would be greatly appreciated.



Thanks



Morris

@morrisford

Here is a working example. It works on both the PC and my Droid Bionic. The first screen takes about 7 sec to load. I think most of that time is Nifty initializing and loading the screens. After that switching screens is pretty instantaneous. The first screen is just an intro screen with a Start button and a Quit button (although the quit button has no functionality yet). When you touch Start, it switches to a second screen that has a progress bar that I delay by 100 frames for each increment.



[EDIT] Forgot to mention, the framerate with the nifty screen up is about 30fps. When the nifty screens go away and just the game running afterwards, the framerate is about 60fps (according to the stats on the screen).



I took the examples from https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:nifty_gui_xml_layout and the one for the progress bar https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:loading_screen.



My end results is a little different from the example to get it to work on Android, but I haven’t gone back and did a comparison to the original examples yet.



However, I had to modify the engine to get the touch events to fire the nifty events. See my last post in http://hub.jmonkeyengine.org/groups/android/forum/topic/error-with-nifty-and-awt/?topic_page=2&num=15 for what I changed to get it to work. I don’t know if anyone reviewed this change to see if it made sense.



I don’t have any screen shots yet, still trying to figure out how to get screen shots without taking an actual picture of the phone :slight_smile:



Hope this helps.



Here is the XML:

[java]



<?xml version=“1.0” encoding=“UTF-8”?>

<nifty

xmlns=“http://nifty-gui.sourceforge.net/nifty.xsd

xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance

xsi:schemaLocation=“http://nifty-gui.sourceforge.net/nifty.xsd http://nifty-gui.sourceforge.net/nifty.xsd

>

<useStyles filename=“nifty-default-styles.xml” />

<useControls filename=“nifty-default-controls.xml” />



<controlDefinition name = “loadingbar” controller = “mygame.LoadingScreen”>

<image filename=“Interface/nifty/border.png” childLayout=“absolute”

imageMode=“resize:15,2,15,15,15,2,15,2,15,2,15,15”>

<image id=“progressbar” x=“0” y=“0” filename=“Interface/nifty/inner.png” width=“32px” height=“100%”

imageMode=“resize:15,2,15,15,15,2,15,2,15,2,15,15” />

</image>

</controlDefinition>



<screen id=“start” controller = “mygame.Main”>

<layer

id=“background”

childLayout=“center”

>

<!-- … →

</layer>

<layer

id=“foreground”

backgroundColor="#0000"

childLayout=“vertical”

>

<panel

id=“panel_top”

height=“25%”

width=“75%”

align=“center”

childLayout=“center”

>

<text

text=“My Cool Game”

font=“Interface/Fonts/Default.fnt”

width=“100%”

height=“100%”

/>

</panel>

<panel

id=“panel_mid”

height=“50%”

width=“75%”

align=“center”

childLayout=“center”

>

<text text=“Here goes some text describing the game and the

rules and stuff. Incidentally, the text is quite long and needs

to wrap at the end of lines. …”

font=“Interface/Fonts/Default.fnt”

width=“100%”

height=“100%”

wrap=“true”

/>

</panel>

<panel

id=“panel_bottom”

height=“25%”

width=“75%”

align=“center”

childLayout=“horizontal”

backgroundColor="#0000"

>

<panel

id=“panel_bottom_left”

height=“50%”

width=“50%”

valign=“center”

childLayout=“center”

>

<control

width=“100%”

height=“100%”

name=“button”

label=“Start”

id=“StartButton”

align=“center”

valign=“center”

visibleToMouse=“true”

>

<interact onClick=“showLoadingMenu()”/>

</control>

</panel>

<panel

id=“panel_bottom_right”

height=“50%”

width=“50%”

valign=“center”

childLayout=“center”

>

<control

width=“100%”

height=“100%”

name=“button”

label=“Quit”

id=“QuitButton”

align=“center”

valign=“center”

visibleToMouse=“true”

>

<interact onClick=“quitGame()”/>

</control>

</panel>

</panel>

</layer>



</screen>



<screen id=“loadlevel” controller = “mygame.Main”>

<layer id=“loadinglayer” childLayout=“center” backgroundColor="#000000">

<panel id = “loadingpanel” childLayout=“vertical” align=“center” valign=“center” height=“32px” width=“70%”>

<control name=“loadingbar” align=“center” valign=“center” width=“100%” height=“100%” />

<control id=“loadingtext” name=“label” align=“center”

text=" “/>

</panel>

</layer>

</screen>



<screen id=“end” controller = “mygame.Main”>

</screen>



</nifty>

[/java]



And here is my main class

[java]

package mygame;



import com.jme3.input.event.TouchEvent;

import com.jme3.niftygui.NiftyJmeDisplay;

import de.lessvoid.nifty.Nifty;

import de.lessvoid.nifty.elements.Element;

import de.lessvoid.nifty.input.NiftyInputEvent;

import de.lessvoid.nifty.screen.Screen;

import de.lessvoid.nifty.screen.ScreenController;

import de.lessvoid.nifty.tools.SizeValue;

import com.jme3.app.SimpleApplication;

import com.jme3.input.TouchInput;

import com.jme3.input.controls.TouchListener;

import com.jme3.input.controls.TouchTrigger;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Vector3f;

import com.jme3.scene.Geometry;

import com.jme3.scene.Node;

import com.jme3.scene.shape.Box;

import com.jme3.terrain.geomipmap.TerrainQuad;

import de.lessvoid.nifty.controls.Controller;

import de.lessvoid.nifty.elements.render.TextRenderer;

import de.lessvoid.xml.xpp3.Attributes;

import java.util.Properties;

import java.util.concurrent.Future;

import java.util.concurrent.ScheduledThreadPoolExecutor;

import java.util.logging.Level;

import java.util.logging.Logger;



public class Main extends SimpleApplication implements ScreenController, Controller, TouchListener {



private Logger logger = Logger.getLogger(this.getClass().getName());



private NiftyJmeDisplay niftyDisplay;

private Nifty nifty;

private Element progressBarElement;

private TerrainQuad terrain;

private Material mat_terrain;

private boolean load = false;

private ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(2);

private Future loadFuture = null;

private TextRenderer textRenderer;

private Node sceneNode = new Node(“sceneNode”);

private int frames = 0;

final private String ESCAPE_EVENT = “TouchEscape”;

final private String MENU_EVENT = “TouchMenu”;



public static void main(String[] args) {

Main app = new Main();

app.start();

}



@Override

public void simpleInitApp() {



Logger.getLogger(”").setLevel(Level.SEVERE);



if (getInputManager() != null)

{

getInputManager().addMapping(ESCAPE_EVENT, new TouchTrigger(TouchInput.KEYCODE_BACK));

getInputManager().addListener(this, new String[]{ESCAPE_EVENT});

getInputManager().addMapping(MENU_EVENT, new TouchTrigger(TouchInput.KEYCODE_MENU));

getInputManager().addListener(this, new String[]{MENU_EVENT});

}





flyCam.setEnabled(false);

niftyDisplay = new NiftyJmeDisplay(assetManager,

inputManager,

audioRenderer,

guiViewPort);

nifty = niftyDisplay.getNifty();



nifty.fromXml(“Interface/nifty/niftyLoadingScreen.xml”, “start”, this);



guiViewPort.addProcessor(niftyDisplay);

}



@Override

public void simpleUpdate(float tpf) {

if (load) {



Element element = nifty.getScreen(“loadlevel”).findElementByName(“loadingtext”);

textRenderer = element.getRenderer(TextRenderer.class);



if (frames == 0) {

//setProgress is thread safe (see below)

setProgress(0f, “Loading Box1”);

Box b = new Box(Vector3f.ZERO, 1, 1, 1);

Geometry geom = new Geometry(“Box1”, b);

Material mat = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

mat.setColor(“Color”, ColorRGBA.Blue);

geom.setMaterial(mat);

geom.setLocalTranslation(-6, 0, 0);

sceneNode.attachChild(geom);

}



if (frames == 100) {

//setProgress is thread safe (see below)

setProgress(0.2f, “Loading Box2”);

Box b = new Box(Vector3f.ZERO, 1, 1, 1);

Geometry geom = new Geometry(“Box2”, b);

Material mat = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

mat.setColor(“Color”, ColorRGBA.Blue);

geom.setMaterial(mat);

geom.setLocalTranslation(-3, 0, 0);

sceneNode.attachChild(geom);

}



if (frames == 200) {

//setProgress is thread safe (see below)

setProgress(0.4f, “Loading Box3”);

Box b = new Box(Vector3f.ZERO, 1, 1, 1);

Geometry geom = new Geometry(“Box3”, b);

Material mat = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

mat.setColor(“Color”, ColorRGBA.Blue);

geom.setMaterial(mat);

geom.setLocalTranslation(0, 0, 0);

sceneNode.attachChild(geom);

}



if (frames == 300) {

//setProgress is thread safe (see below)

setProgress(0.6f, “Loading Box4”);

Box b = new Box(Vector3f.ZERO, 1, 1, 1);

Geometry geom = new Geometry(“Box4”, b);

Material mat = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

mat.setColor(“Color”, ColorRGBA.Blue);

geom.setMaterial(mat);

geom.setLocalTranslation(3, 0, 0);

sceneNode.attachChild(geom);

}



if (frames == 400) {

//setProgress is thread safe (see below)

setProgress(0.8f, “Loading Box5”);

Box b = new Box(Vector3f.ZERO, 1, 1, 1);

Geometry geom = new Geometry(“Box5”, b);

Material mat = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

mat.setColor(“Color”, ColorRGBA.Blue);

geom.setMaterial(mat);

geom.setLocalTranslation(6, 0, 0);

sceneNode.attachChild(geom);

}



if (frames == 500) {

setProgress(1f, “Loading complete”);

}







if (frames == 600) {

nifty.gotoScreen(“end”);

nifty.exit();

guiViewPort.removeProcessor(niftyDisplay);

flyCam.setEnabled(true);

flyCam.setDragToRotate(true);

flyCam.setMoveSpeed(50);

rootNode.attachChild(sceneNode);

load = false;

}



frames++;

}

}



public void setProgress(final float progress, final String loadingText) {

final int MIN_WIDTH = 32;

int pixelWidth = (int) (MIN_WIDTH + (progressBarElement.getParent().getWidth() - MIN_WIDTH) * progress);

progressBarElement.setConstraintWidth(new SizeValue(pixelWidth + “px”));

progressBarElement.getParent().layoutElements();

textRenderer.setText(loadingText);

}



public void showLoadingMenu() {

nifty.gotoScreen(“loadlevel”);

load = true;

}



@Override

public void onStartScreen() {

}



@Override

public void onEndScreen() {

}



@Override

public void bind(Nifty nifty, Screen screen) {

progressBarElement = nifty.getScreen(“loadlevel”).findElementByName(“progressbar”);

}



// methods for Controller

@Override

public boolean inputEvent(final NiftyInputEvent inputEvent) {

return false;

}



@Override

public void bind(Nifty nifty, Screen screen, Element elmnt, Properties prprts, Attributes atrbts) {

progressBarElement = elmnt.findElementByName(“progressbar”);

}



@Override

public void init(Properties prprts, Attributes atrbts) {

}



public void onFocus(boolean getFocus) {

}





public void onTouch(String name, TouchEvent event, float tpf) {

if (name.equals(ESCAPE_EVENT)) {

switch (event.getType()) {

case KEY_UP:

logger.log(Level.SEVERE, “onTouch: {0}”, event.getType());

event.setConsumed();

break;

default:

break;

}

} else if (name.equals(MENU_EVENT)) {

switch (event.getType()) {

case KEY_UP:

logger.log(Level.SEVERE, “onTouch: {0}”, event.getType());

event.setConsumed();

break;

default:

break;

}

}

}

}



[/java]

Screen shots











http://www.youtube.com/watch?v=7lNd2BjN3cEhttp://www.youtube.com/watch?v=7lNd2BjN3cE

It is a bit an older post but I got also the problem that nifty doesn’t react on on-click events.

I believe you have already found out how to make screen-shots. But to be sure:

  1. You can make screenshots with push and hold (Powerbutton + Volumebutton) until u hear a click signal.
  2. Or use MyPhoneExplorer, connect the device and go into the Menu Extras to Control Mobile. Works fine with Windows7 Snipping tool.