Hello Nifty 1.3 [New Tutorial]

The demo project downloadable here, https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:nifty_gui_java_layout, doesn’t run.



It shows some error.


  1. import de.lessvoid.nifty.renderer.lwjgl.render.LwjglRenderDevice; Doesn’t exists.
  2. import de.lessvoid.nifty.sound.openal.OpenALSoundDevice; Doesn’t exists.

    3, import de.lessvoid.nifty.renderer.lwjgl.input.LwjglInputSystem; Doesn’t exists.

Hold on, I’ll go check…



PS: I now replaced it with a zip file that works for me, try again.

Now it runs without any error.



But when I click the ? button at the right most, it crashes and shows the following error,



com.jme3.asset.AssetNotFoundException: Interface/sound/Loveshadow_-_Almost_Given_Up.ogg (Stream)

at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:239)

at com.jme3.audio.AudioNode.(AudioNode.java:178)

at com.jme3.audio.AudioNode.(AudioNode.java:205)

at com.jme3.niftygui.SoundHandleJme.play(SoundHandleJme.java:78)

at de.lessvoid.nifty.effects.impl.PlaySound.playSound(PlaySound.java:51)

at de.lessvoid.nifty.effects.impl.PlaySound.execute(PlaySound.java:36)

at de.lessvoid.nifty.effects.Effect.execute(Effect.java:120)

at de.lessvoid.nifty.effects.EffectProcessor.renderActive(EffectProcessor.java:79)

at de.lessvoid.nifty.effects.EffectProcessor.renderPre(EffectProcessor.java:57)

at de.lessvoid.nifty.effects.EffectManager$RenderPhasePre.render(EffectManager.java:318)

at de.lessvoid.nifty.effects.EffectManager.render(EffectManager.java:122)

at de.lessvoid.nifty.effects.EffectManager.renderPre(EffectManager.java:135)

at de.lessvoid.nifty.elements.Element.render(Element.java:583)

at de.lessvoid.nifty.elements.Element.renderInternalChildElements(Element.java:616)

at de.lessvoid.nifty.elements.Element.renderChildren(Element.java:609)

at de.lessvoid.nifty.elements.Element.render(Element.java:578)

at de.lessvoid.nifty.screen.Screen.renderLayers(Screen.java:313)

at de.lessvoid.nifty.Nifty.render(Nifty.java:259)

at com.jme3.niftygui.NiftyJmeDisplay.postQueue(NiftyJmeDisplay.java:170)

at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:1121)

at com.jme3.renderer.RenderManager.render(RenderManager.java:1173)

at com.jme3.app.SimpleApplication.update(SimpleApplication.java:263)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:149)

at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:185)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:223)

at java.lang.Thread.run(Thread.java:662)

Oct 5, 2011 2:23:45 AM com.jme3.renderer.lwjgl.LwjglRenderer cleanup

INFO: Deleting objects and invalidating state

Oct 5, 2011 2:23:46 AM com.jme3.input.lwjgl.LwjglMouseInput destroy

INFO: Mouse destroyed.

Oct 5, 2011 2:23:46 AM com.jme3.input.lwjgl.LwjglKeyInput destroy

INFO: Keyboard destroyed.

Oct 5, 2011 2:23:46 AM com.jme3.system.lwjgl.LwjglAbstractDisplay deinitInThread

INFO: Display destroyed.

Oh wow, I never tried that button. It is supposed to play music and I forgot to include the OGG file. I updated the zip again… :slight_smile:



PS: LOL… What kind of song did you put into the credits, @void256? Love shadow? :smiley:

The song is called “Almost given up” by someone called “love shadow” :stuck_out_tongue: Here is the original link to the ccMixter site: http://ccmixter.org/files/Loveshadow/26756



And yes, that [?] button kinda hides the credits for the controls demo and was supposed to be discovered (and not supposed to crash xD) :slight_smile:

@void256 what ‘way’ do you prefer and/or suggest for those who are ‘new nifty users’ with jMonkey Engine. the XML way or the Java way?

Both XML and Java are fairly easy to learn. It all depends on how you intend to use it. If you have a lot of dynamically build screens, Java would be the way to go. If most of your screens are static, XML would be the way to go.

In the end though, it would most likely turn out to be a mix of both.

Your basic UI layout should be built using XML and then you dynamically change the content using java code. This way you can for example easily switch a phone vs a desktop UI, by simply changing the base XML file.

1 Like

@zathras @void256 its still very hard to decipher what’s in the example code. A simple Basic most “Hello Button” would have get me/anyone started. But, this 17MB example pack is literally driving me crazy! :cry:

I know, I’m in the same situation. :frowning: I’ve been trying to come up with a simple example, but I have to understand it myself first. But you’re lucky – my coffee was too strong this morning and I have this feeling today like… I could solve all Portal levels AND learn Nifty during the load screens, you know what I mean? :wink: Maybe I get a good Hello Nifty done, let’s see…

@zathras Hey good news!!! I have almost completed a Hello Nifty. Just need a little more cleanup. Oh, its a relief!



The bad thing is, it would take several tutorials to make a new comer to grab the whole concept of Control, Builder and yeda yeda yeda…a simple Hello Nifty is not going to help much. Maybe @void256 can give us a basic concept on the fundamentals of Nifty 1.3(java only) :slight_smile:



Have you solved all the portal puzzles? I loved P1 and hated P2. Only 3 of P2 was good enough for the yeeeee!

Maybe we should also add nifty file templates for the most used nifty functions to the SDK. If anyone cares to come up with those that’d be cool.

Maybe @void256 can give us a basic concept on the fundamentals of Nifty 1.3(java only)


Well, using Java only mode is not really that different from using a XML file. The basics are the same and I'd suggest finding the 1.2 interactive tutorial to learn the basics as well as all the other wiki entries that exists (both the jme wiki as well as niftys own wiki).

The next step is basically find the the element you want to create, let's say a "screen" and then just add "Builder" to it to get the "ScreenBuilder" class ;) Every attribute that you can set on the element is available as a method that you simply call in a static initialisation block.

Example:

[java] ScreenBuilder screenBuilder = new ScreenBuilder("start")
{
{
controller(new DefaultScreenController() { // controller Attribute of the <screen> tag
@Override
public void onStartScreen() {
nifty.gotoScreen("demo");
}
});
layer(new LayerBuilder("layer") // this corresponds to the <layer> child element of the <screen> tag
{
{
childLayoutCenter(); // this is a short cut to the childLayout="center" attribute
... // I hope you get the idea
}
}
}
};

// actually build the screen
Screen screen = screenBuilder.build(nifty);[/java]

So you can nest these Builder classes to actually build the same element hierachy as with XML. The only thing that's a bit odd in the beginning is the double {{ and }} but you can get used to it.

And on a second note, I've not created this Builder stuff :) It was arielsan of http://blog.gemserk.com/ that send a patch that added that to Nifty so all credit (and complains :P) belong to him :D
normen said:
Maybe we should also add nifty file templates for the most used nifty functions to the SDK.

@normen What's that? CommonBuilder classes for avoiding long nested class description?

No, just some “New File” templates of Nifty XML, maybe also one with a ScreenController and XML file.

@zathras @void256

Finally, Hello Nifty, using Java.



Code :

[java]package mygame;



import com.jme3.app.SimpleApplication;

import com.jme3.niftygui.NiftyJmeDisplay;

import de.lessvoid.nifty.Nifty;

import de.lessvoid.nifty.builder.ScreenBuilder;

import de.lessvoid.nifty.builder.LayerBuilder;

import de.lessvoid.nifty.builder.PanelBuilder;

import de.lessvoid.nifty.controls.button.builder.ButtonBuilder;

import de.lessvoid.nifty.screen.DefaultScreenController;



public class Main extends SimpleApplication {



public static void main(String[] args) {

Main app = new Main();

app.start();

}



@Override

public void simpleInitApp() {

NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(

assetManager, inputManager, audioRenderer, guiViewPort);

Nifty nifty = niftyDisplay.getNifty();

guiViewPort.addProcessor(niftyDisplay);

flyCam.setDragToRotate(true);



nifty.loadStyleFile(“nifty-default-styles.xml”);

nifty.loadControlFile(“nifty-default-controls.xml”);



// <screen>

nifty.addScreen(“Screen_ID”, new ScreenBuilder(“Hello Nifty Screen”){{

controller(new DefaultScreenController()); // Screen properties



// <layer>

layer(new LayerBuilder(“Layer_ID”) {{

childLayoutVertical(); // layer properties, add more…



// <panel>

panel(new PanelBuilder(“Panel_ID”) {{

childLayoutCenter(); // panel properties, add more…



// GUI elements

control(new ButtonBuilder(“Button_ID”, “Hello Nifty”){{

alignCenter();

valignCenter();

height(“5%”);

width(“15%”);

}});



//… add more GUI elements here



}});

// </panel>

}});

// </layer>

}}.build(nifty));

// </screen>



nifty.gotoScreen(“Screen_ID”); // start the screen

}

}

[/java]



Output:





One this looks a little confusing to me is that, I can start the screen using both

[java] nifty.gotoScreen(“Screen_ID”);

nifty.gotoScreen(“Hello Nifty Screen”);[/java] lines. But, shouldn’t one of them would be wrong?



another thing is, is it possible to setup this two files using Java?

[java] nifty.loadStyleFile(“nifty-default-styles.xml”);

nifty.loadControlFile(“nifty-default-controls.xml”);[/java]



& also Please suggest improvements of any kind. I might end up writing some Nifty 1.3 tutorials. So, guideline would help in the long run. :slight_smile:

1 Like

Cool, thanks, I added that prominently to https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:nifty_gui_java_layout for now. I’ll get back to it after updating my XML example. I’ll continue writing https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:nifty_gui_xml_layout today. So don’t be surprised if the images and details on that page suddenly change in the next few hours.



The most important part is https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:nifty_gui_java_interaction – I have some ideas, including a nice example how to combine a ScreenController and an AbstractAppState. (tentatively tomorrow)



To prevent these intro page from becoming too long I moved some examples to https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:nifty_gui_scenarios



We’re getting, there, slowly :wink:

1 Like

@zathras okey, Then I will start writing the Java counter parts of the xml example. :slight_smile:





I am having a hard time working with the java parts, like changing font and receiving /sending messages. I don’t understand how to work with EventBus system, clearly. It would be great if @void256 step up and modify, “Hello Nifty[java][/java] code” slightly so it sends a message to the game and receives something.

This post is a translation of XML to Java from tutorial, https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:nifty_gui_xml_layout



1. XML

[xml]<?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”>

<screen id=“start”>

<!-- … →

</screen>

<screen id=“hud”>

<!-- … →

</screen>

</nifty>[/xml]



JAVA :



[java] nifty.addScreen(“start”, new ScreenBuilder(“start”){{

controller(new DefaultScreenController());

// <!-- … →

}}.build(nifty));



nifty.addScreen(“hud”, new ScreenBuilder(“hud”){{

controller(new DefaultScreenController());

// <!-- … →

}}.build(nifty));[/java]



2. XML [xml]<nifty>

<screen id=“start”>

<layer id=“background” backgroundColor="#000f">

<!-- … →

</layer>

<layer id=“foreground” backgroundColor="#0000" childLayout=“vertical”>

<!-- … →

</layer>

</screen>

<screen id=“hud”>

<layer id=“background” backgroundColor="#000f">

<!-- … →

</layer>

<layer id=“foreground” backgroundColor="#0000" childLayout=“vertical”>

<!-- … →

</layer>

</screen>

</nifty>[/xml]



[java]nifty.addScreen(“start”, new ScreenBuilder(“start”){{

controller(new DefaultScreenController());



// layer added

layer(new LayerBuilder(“background”) {{

childLayoutVertical();

backgroundColor("#000f");



// <!-- … →

}});



layer(new LayerBuilder(“foreground”) {{

childLayoutVertical();

backgroundColor("#0000");



// <!-- … →

}});

// layer added



}}.build(nifty));[/java]



3. XML

[xml]<panel id=“panel_top” height=“25%” width=“75%” align=“center” childLayout=“center”

backgroundColor="#f008">

</panel>

<panel id=“panel_mid” height=“50%” width=“75%” align=“center” childLayout=“center”

backgroundColor="#0f08">

</panel>

<panel id=“panel_bottom” height=“25%” width=“75%” align=“center” childLayout=“horizontal”

backgroundColor="#00f8">

<panel id=“panel_bottom_left” height=“50%” width=“50%” valign=“center” childLayout=“center”

backgroundColor="#44f8">

</panel>

<panel id=“panel_bottom_right” height=“50%” width=“50%” valign=“center” childLayout=“center”

backgroundColor="#88f8">

</panel>

</panel>[/xml]



JAVA :

[java]nifty.addScreen(“start”, new ScreenBuilder(“start”){{

controller(new DefaultScreenController());



layer(new LayerBuilder(“background”) {{

childLayoutVertical();

backgroundColor("#000f");

// <!-- … →

}});



layer(new LayerBuilder(“foreground”) {{

childLayoutVertical();

backgroundColor("#0000");



height(“25%”);

width(“75%”);



// panel added

panel(new PanelBuilder(“panel_top”) {{

childLayoutCenter();

alignCenter();

backgroundColor("#f008");



height(“25%”);

width(“75%”);

}});



panel(new PanelBuilder(“panel_mid”) {{

childLayoutCenter();

alignCenter();

backgroundColor("#f008");



height(“50%”);

width(“75%”);

}});



panel(new PanelBuilder(“panel_bottom”) {{

childLayoutHorizontal();

alignCenter();

backgroundColor("#f008");



panel(new PanelBuilder(“panel_bottom_left”) {{

childLayoutCenter();

valignCenter();

backgroundColor("#44f8");



height(“50%”);

width(“50%”);

}});



panel(new PanelBuilder(“panel_bottom_right”) {{

childLayoutCenter();

valignCenter();

backgroundColor("#88f8");



height(“50%”);

width(“50%”);

}});

}});

// panel added



}});

}}.build(nifty));[/java]



4. XML : This part of code might contains error. a quick check and found the panels are messed up.

[xml]<panel id=“panel_left” width=“80%” height=“100%” childLayout=“vertical”

backgroundColor="#0f08">

<!-- spacer →

</panel>

<panel id=“panel_right” width=“20%” height=“100%” childLayout=“vertical”

backgroundColor="#00f8" >

<panel id=“panel_top_right1” width=“100%” height=“15%” childLayout=“center”

backgroundColor="#00f8">

</panel>

<panel id=“panel_top_right2” width=“100%” height=“15%” childLayout=“center”

backgroundColor="#44f8">

</panel>

<panel id=“panel_bot_right” width=“100%” height=“70%” valign=“center”

backgroundColor="#88f8">

</panel>

</panel>[/xml]

JAVA

[java]nifty.addScreen(“hud”, new ScreenBuilder(“hud”){{

controller(new DefaultScreenController()); // Screen properties



layer(new LayerBuilder(“background”) {{

childLayoutVertical();

backgroundColor("#000f");

// <!-- … →

}});



layer(new LayerBuilder(“foreground”) {{

childLayoutVertical();

backgroundColor("#000f");



// panel added

panel(new PanelBuilder(“panel_left”) {{

childLayoutVertical();

backgroundColor("#0f08");



height(“100%”);

width(“80%”);



// <!-- spacer →

}});



panel(new PanelBuilder(“panel_right”) {{

childLayoutVertical();

backgroundColor("#00f8");



height(“100%”);

width(“20%”);



panel(new PanelBuilder(“panel_top_right1”) {{

childLayoutCenter();

backgroundColor("#00f8");



height(“15%”);

width(“100%”);

}});



panel(new PanelBuilder(“panel_top_right2”) {{

childLayoutCenter();

backgroundColor("#44f8");



height(“15%”);

width(“100%”);

}});



panel(new PanelBuilder(“panel_bot_right”) {{

childLayoutCenter();

valignCenter();

backgroundColor("#88f8");



height(“70%”);

width(“100%”);

}});

}});

// panel added

}});

}}.build(nifty));[/java]



I will do the rest of the tutorial some other day. Let me know if there is any problem. :slight_smile:



@zathras you might want to attach the completed XML file at the documentation page.

1 Like

@iamcreasy: Nice, thanks!



I’ll post again when I got the next part ready (interaction). But that is Java only anyway. (XML is static)