rootNode doesn't work with Nifty

i have button , has this code

control(new ButtonBuilder("Button_ID", "START"){{
                    alignCenter();
                    valignCenter();
                    height("10%");
                    width("30%");
                    interactOnClick("next()");
                }});

when i clicked in button … next() function will implement

  public void next() {
             rootNode.attachChild(geom);
    }

but it doesn’t work with rootNode … any help ?

thanks in advance

1 Like

First of all,

Second: What does not work? Please be a bit more precise about your problem otherwise it’s diffuclt for everybody to help, really!

Third: Is next() even called, did you try to put some debug output (System.out.println()) in it?

1 Like

when i clicked to button nothing happened

and it said "May 16, 2017 11:27:00 PM de.lessvoid.nifty.NiftyMethodInvoker callMethod
WARNING: Exception in callMethod(public void mygame.GUI.MainMenuController.next()) for [mygame.GUI.MainMenuController@6181c927]
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at de.lessvoid.nifty.NiftyMethodInvoker.callMethod(NiftyMethodInvoker.java:157)
at de.lessvoid.nifty.NiftyMethodInvoker.performInvoke(NiftyMethodInvoker.java:115)
at de.lessvoid.nifty.Nifty$DelayedMethodInvoke.perform(Nifty.java:1465)
at de.lessvoid.nifty.Nifty.invokeMethods(Nifty.java:1441)
at de.lessvoid.nifty.Nifty.handleDynamicElements(Nifty.java:434)
at de.lessvoid.nifty.Nifty.access$1600(Nifty.java:85)
at de.lessvoid.nifty.Nifty$NiftyInputConsumerImpl.processEvent(Nifty.java:1711)
at de.lessvoid.nifty.Nifty$NiftyInputConsumerImpl.processMouseEvent(Nifty.java:1649)
at com.jme3.niftygui.InputSystemJme.handleMouseEvent(InputSystemJme.java:123)
at com.jme3.niftygui.InputSystemJme.onMouseButtonEventQueued(InputSystemJme.java:231)
at com.jme3.niftygui.InputSystemJme.forwardEvents(InputSystemJme.java:295)
at de.lessvoid.nifty.Nifty.update(Nifty.java:363) "

yes it’s called , i tried to print and it worked

thank you

1 Like

i have two classes one called MainMenuController and other is Main … with different packages

MainMenuController Class

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package mygame.GUI;

import com.jme3.app.Application;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.controls.button.builder.ButtonBuilder;
import de.lessvoid.nifty.elements.Element;
import de.lessvoid.nifty.input.NiftyMouseInputEvent;
import de.lessvoid.nifty.screen.Screen;
import de.lessvoid.nifty.screen.ScreenController;
import mygame.Main;

public class MainMenuController extends Main implements ScreenController {

  private Application app;
  private AppStateManager stateManager;
  private Nifty nifty;
  private Screen screen;
   
  public MainMenuController() {
  
  }
  
  @Override
  public void bind(Nifty nifty, Screen screen) {
        this.nifty = nifty;
        this.screen = screen;
  }
  
  @Override
    public void onStartScreen() {
        
  }

  @Override
    public void onEndScreen() {
  }
    public void next() {
              rootNode.attachChild(geom);
    }
    public void nextWithCoords(int x, int y) {
        System.out.println("next() clicked at: " + x + ", " + y);
 }
    public void tete(Element element , NiftyMouseInputEvent event)
    {
        System.out.println("ay ay ay ay ay ay ay ay ay ay ya yay");
    }
    public void constructBuilding()
    {
        
    }

}

main class

package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.niftygui.NiftyJmeDisplay;
import de.lessvoid.nifty.Nifty;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import de.lessvoid.nifty.builder.ControlDefinitionBuilder;
import de.lessvoid.nifty.builder.ImageBuilder;
import de.lessvoid.nifty.builder.LayerBuilder;
import de.lessvoid.nifty.builder.PanelBuilder;
import de.lessvoid.nifty.builder.ScreenBuilder;
import de.lessvoid.nifty.builder.TextBuilder;
import de.lessvoid.nifty.controls.Button;
import de.lessvoid.nifty.controls.button.builder.ButtonBuilder;
import de.lessvoid.nifty.controls.textfield.builder.TextFieldBuilder;
import de.lessvoid.nifty.screen.DefaultScreenController;
import de.lessvoid.nifty.screen.Screen;
import mygame.GUI.MainMenuController;

/**
 * This is the Main Class of your Game. You should only do initialization here.
 * Move your Logic into AppStates or Controls
 * @author normenhansen
 */
public class Main extends SimpleApplication {

    public static void main(String[] args) {
        Main app = new Main();
        app.start();
    }
    protected Box b ; 
    protected Geometry geom ; 
    protected boolean flag = false  ; 
    @Override
    public void simpleInitApp() {
        b = new Box(1, 1, 1);
        geom = new Geometry("Box", b);

        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        mat.setColor("Color", ColorRGBA.Blue);
        geom.setMaterial(mat);

        //rootNode.attachChild(geom);
        Spatial scene =  assetManager.loadModel("Models/terrain/untitled.j3o");
        DirectionalLight light = new DirectionalLight();
        DirectionalLight sun = new DirectionalLight();
        sun.setDirection(new Vector3f(-5f, .5f, -.5f ));
        sun.setColor(ColorRGBA.Yellow);
        rootNode.addLight(sun);
        rootNode.attachChild(scene);
        rootNode.addLight(light);
        viewPort.setBackgroundColor(ColorRGBA.White);
        flyCam.setDragToRotate(true);
        flyCam.setMoveSpeed(180);
        cam.setLocation(new Vector3f(0f, 175f, 140f));
        cam.setAxes(new Vector3f(-0.99998283f, -4.332047E-6f, -0.005864509f), new Vector3f(0.0048147123f, 0.5703341f, -0.82139874f), new Vector3f(0.0033482877f, -0.8214128f, -0.5703243f));
       
        
        
        NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager, inputManager, audioRenderer, guiViewPort);
        Nifty nifty = niftyDisplay.getNifty();
        guiViewPort.addProcessor(niftyDisplay);
       // nifty.setDebugOptionPanelColors(true);
        flyCam.setDragToRotate(true);
        
        nifty.loadStyleFile("nifty-default-styles.xml");

        nifty.loadControlFile("nifty-default-controls.xml");
        
         nifty.addScreen("Screen_ID", new ScreenBuilder("Hello Nifty Screen"){{
        controller(new MainMenuController()); // 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", "START"){{
                    alignCenter();
                    valignCenter();
                    height("10%");
                    width("30%");
                    interactOnClick("next()");
              
                }});
                
               

                //.. add more GUI elements here

            }});
            // </panel>
          }});
        // </layer>
      }}.build(nifty));
    // </screen>

    nifty.gotoScreen("Screen_ID"); // start the screen

    
    
    
    
    }

    @Override
    public void simpleUpdate(float tpf) {
        //TODO: add update code
    }

    @Override
    public void simpleRender(RenderManager rm) {
        //TODO: add render code
    }
}
1 Like

How many applications do you want in your application?

Hint: this is totally wrong.

Nifty is very hard to use and requires a really experienced Java developer to develop with it. Extending a class just to get some fields instead of passing those fields is a sign of someone who will really struggle with nifty.

1 Like

i just wanna know how to use rootNode in class mainMenuController if it isn’t extends my Main Class

1 Like

You pass the object via the constructor or method input variables. This is a basic java question, not really jmonkey specific. You should really learn the basics before you venture into game development. It will make your life a lot easier.

1 Like

Hey @khaledawaled Nifty is actually not that hard to use but you really should make yourself familiar with the basic programming patterns and practices. You don’t need JME for that. So please, do learn basic Java object orientation (OO) and so on…

However, sometimes it’s easier to see the “right” code. Note: the following is just to give you a hint on how you could do it.

public class MainMenuController implements ScreenController {
    
    private Node rootNode;
    private Geometry geom;
    
    public MainMenuController(Node rootNode, Geometry geom) {
        this.rootNode = rootNode;
        this.geom = geom;
    }
    
    
    public void onButtonClick() {
        this.rootNode.attachChild(geom);
    }
    

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

    @Override
    public void onStartScreen() {}

    @Override
    public void onEndScreen() {}
    
}

When you create your MainScreenController object you have to give the constructor two parameters: A reference to a Node object and a reference to a Geometry object.

In the following line you create a new Geometry object and the geom variable is a reference to that created object.

Geometry geom = new Geometry("Box", b);

When you create your MainScreenController object you have to provide those two parameters which are references to the real objects:

new MainMenuController(rootNode, geom);

Try this and I hope it does make click in your brain and you got it.

Nevertheless, you really have to gain some basic programming experience before going on with JME. We all recommend that, so please take our advice seriously.

3 Likes

Hey Domenic ,

First , thanks for your time

sec , Nifty not very hard yes it’s true

but it’s first time i use Nifty and Jmonkey , i do have very good basics Knowledge about java

but i don’t have any knowledge about game development

anyway thank you :smiley:

1 Like

And yet, your first response to “My class needs the this value” was “Extend this other random unrelated class and hope for the best” rather than “pass the value on a constructor”.

The SimpleApplication class is your main application. It goes through a whole life cycle of creating a window, being initialized, etc… extending it multiple times just to access some protected variables (that won’t even be properly initialized because your application should only have one application) is kind of a noob-Java-developer approach.

I’m not trying to be mean but to get proper help in the future you should be self-aware of your relative skill level.

1 Like

okay thanks :slight_smile:

1 Like