I cant get my start button to call the “startGame()” function.
I can display everything but I can’t interact with any buttons.
[java]package mygame;
import com.jme3.app.Application;
import com.jme3.app.SimpleApplication;
import com.jme3.app.state.AppStateManager;
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;
import de.lessvoid.nifty.screen.Screen;
import de.lessvoid.nifty.screen.ScreenController;
class Screens extends SimpleApplication implements ScreenController {
Nifty nifty;
private Screen screen;
private SimpleApplication app;
public static void main(String[] args) {
Screens app = new Screens();
app.start();
}
public void bind(Nifty nifty, Screen screen) {
this.nifty = nifty;
this.screen = screen;
}
@Override
public void simpleInitApp() {
NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(
assetManager, inputManager, audioRenderer, guiViewPort);
nifty = niftyDisplay.getNifty();
guiViewPort.addProcessor(niftyDisplay);
flyCam.setDragToRotate(true);
nifty.loadStyleFile(“nifty-default-styles.xml”);
nifty.loadControlFile(“nifty-default-controls.xml”);
nifty.gotoScreen(“start”);
// <screen>
nifty.addScreen(“start”, new ScreenBuilder(“start”) {{
controller(new DefaultScreenController());
layer(new LayerBuilder(“background”) {{
childLayoutCenter();
backgroundColor("#000f");
}});
layer(new LayerBuilder(“foreground”) {{
childLayoutVertical();
backgroundColor("#0000");
// panel added
panel(new PanelBuilder(“panel_top”) {{
childLayoutCenter();
alignCenter();
backgroundColor("#f008");
height(“25%”);
width(“75%”);
}});
panel(new PanelBuilder(“panel_mid”) {{
childLayoutCenter();
alignCenter();
backgroundColor("#0f08");
height(“50%”);
width(“75%”);
}});
panel(new PanelBuilder(“panel_bottom”) {{
childLayoutHorizontal();
alignCenter();
backgroundColor("#00f8");
height(“25%”);
width(“75%”);
control(new ButtonBuilder(“QuitButton”, “Quit”) {{
alignCenter();
valignCenter();
height(“50%”);
width(“50%”);
visibleToMouse(true);
interactOnClick(“quitGame()”);
}});
control(new ButtonBuilder(“StartButton”, “Start”) {{
alignCenter();
valignCenter();
height(“50%”);
width(“50%”);
visibleToMouse(true);
interactOnClick(“startGame()”);
}});
panel(new PanelBuilder(“panel_bottom_right”) {{
childLayoutCenter();
valignCenter();
backgroundColor("#88f8");
height(“50%”);
width(“50%”);
}});
}}); // panel added
}});
}}.build(nifty));
// </screen>
nifty.gotoScreen(“start”); // start the screen
}
public void startGame() {
//HelloTerrainCollision n = new HelloTerrainCollision();
System.out.println(“Start game”);
//n.start();
}
public void quitGame() {
System.out.println(“quit”);
}
public void initialize(AppStateManager stateManager, Application app) {
this.initialize(stateManager, app);
this.app=(SimpleApplication)app;
}
public void onStartScreen() {
throw new UnsupportedOperationException(“Not supported yet.”);
}
public void onEndScreen() {
throw new UnsupportedOperationException(“Not supported yet.”);
}
public void update(float tpf) {
}
}[/java]
Is there a working example of a nifty GUI user interaction code?
If I’m not reading it wrong, you seem to have three elements with width=“50%” in your “panel_bottom” panel, which adds up to 150%.
Perhaps that last panel (“panel_bottom_right”) is covering your start button?
Try setting their widths so that they add up to 100% in total.
I can see my buttons and I’ve removed “panel_bottom_right”. But it’s not having any effect. : (
I’ve also set the main panels to 100% width.
I just noticed you’re giving the screen a new DefaultScreenController.
As you have no other controllers set below it, the calls would go to that one.
Try using “controller(this);” instead of “controller(new DefaultScreenController());” in your ScreenBuilder.
I replaced it with this : “controller(this);” and it game me an error pointing out that it needed a screen controller and not a screenBuilder.
I’ve no idea where to go from here.
Hi, your problem is that in the
controller( this ), THIS will refer to the new ScreenBuilder Object and NOT the SimpleApplication Object which implements ScreenController.
Try to store a reference to your ScreenController outside the builder like this:
ScreenController controller_ref = this;
and then use controller( controller_ref ) inside the Builder.
Hope this solves your problem.
Also… You have two calls to goToScreen( “start” ), the first of which is called before “start” is defined. Just letting you know.
Oh, I missed that! As @nihal pointed out, “this” refers to the ScreenBuilder if inside that code part.
You can use an outside reference like @nihal suggests, or use “Screens.this” instead of just “this”, so it will point to your outer class.
Sorry for replying late but it’s still not working.
I’m looking over the tutorials but i can’t find my problem.
Here’s the latest code.
import com.jme3.app.Application;
import com.jme3.app.SimpleApplication;
import com.jme3.app.state.AppStateManager;
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;
import de.lessvoid.nifty.screen.Screen;
import de.lessvoid.nifty.screen.ScreenController;
/**
-
@author iamcreasy
*/
class Screens extends SimpleApplication implements ScreenController {
Nifty nifty;
private Screen screen;
private SimpleApplication app;
public static void main(String[] args) {
Screens app = new Screens();
app.start();
}
public void bind(Nifty nifty, Screen screen) {
this.nifty = nifty;
this.screen = screen;
}
@Override
public void simpleInitApp() {
NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(
assetManager, inputManager, audioRenderer, guiViewPort);
nifty = niftyDisplay.getNifty();
guiViewPort.addProcessor(niftyDisplay);
flyCam.setDragToRotate(true);
nifty.loadStyleFile("nifty-default-styles.xml");
nifty.loadControlFile("nifty-default-controls.xml");
// <screen>
final ScreenController controller_ref = this;
nifty.addScreen("start", new ScreenBuilder("start") {{controller(controller_ref); layer(new LayerBuilder("background") {{ childLayoutCenter(); backgroundColor("#000f"); // <!-- ... --> }}); layer(new LayerBuilder("foreground") {{ childLayoutVertical(); backgroundColor("#0000"); // panel added panel(new PanelBuilder("panel_top") {{ childLayoutCenter(); alignCenter(); backgroundColor("#f008"); height("25%"); width("100%"); }}); panel(new PanelBuilder("panel_mid") {{ childLayoutCenter(); alignCenter(); backgroundColor("#0f08"); height("50%"); width("100%"); }}); panel(new PanelBuilder("panel_bottom") {{ childLayoutHorizontal(); alignCenter(); backgroundColor("#00f8"); height("25%"); width("100%"); control(new ButtonBuilder("QuitButton", "Quit") {{ alignCenter(); valignCenter(); height("50%"); width("50%"); visibleToMouse(true); interactOnClick("quitGame()"); }}); control(new ButtonBuilder("StartButton", "Start") {{ alignCenter(); valignCenter(); height("50%"); width("50%"); visibleToMouse(true); interactOnClick("startGame()"); }}); }}); // panel added }});
}
}.build(nifty));
// </screen>
nifty.gotoScreen("start"); // start the screen
}
public void startGame() {
//HelloTerrainCollision n = new HelloTerrainCollision();
System.out.println("Start game");
//n.start();
}
public void quitGame() {
System.out.println("quit");
}
public void initialize(AppStateManager stateManager, Application app) {
this.initialize(stateManager, app);
this.app=(SimpleApplication)app;
}
public void onStartScreen() {
//throw new UnsupportedOperationException("Not supported yet.");
}
public void onEndScreen() {
throw new UnsupportedOperationException("Not supported yet.");
}
public void update(float tpf) {
/** jME update loop! */
}
}
Do you know where there is a working example of a nifty GUI user interaction code?
:)
Oh, wait a second!
Are you overriding the Application’s update method?
I’m pretty sure that nifty’s viewport won’t be updated unless you call super.update(tpf) in there (or rather, don’t override the update method and use simpleUpdate instead, as you’re using SimpleApplication).
Still not working. Did it work in yours?
I tried:
no suitable method found for update(float)
method com.jme3.app.SimpleApplication.update() is not applicable
(actual and formal argument lists differ in length)
Sorry, that’s not quite what I meant.
Anyway, I tested your code and that update loop isn’t actually overriding anything (it isn’t being used at all).
simpleUpdate(float tpf) is called from SimpleApplication automatically, and it’s recommended you use that to do your updates if you use SimpleApplication. You don’t need to do and “super” calls.
Your code works fine when I test it as it is in your post above (the last one with full code), with one important edit: Your outer class declaration should be public, or Nifty won’t be allowed to access it through reflection. If I run your code with an anonymous class declaration (as in your code above) I get an IllegalAccessException that explains the problem.
With the class public, the methods are called and the System.out.println is printed, hover effects are done, everything seems to work fine.
So, the solution to your problem is: “public class Screens” (you should generally always make your top class declaration public).
Everything’s working now. Thanks for all your help.