Slick2D and Nifty GUI

I am currently trying to combine both slick2d and nifty to work together. I've had some amount of success - I can now actually run my test and it won't crash. As far as I can tell, it will also receive input properly.

First, I'm having doubts I'm doing it right. I extend NiftyStateBasedGame in my outer game and then I extend two NiftyOverlayGameState to create the two states. However, I am getting an error that doesn't crash my application saying:

WARNING: An event service by the name NiftyEventBusalready exists.  Perhaps multiple threads tried to create a service about the same time?
org.bushe.swing.event.EventServiceExistsException: An event service by the name NiftyEventBusalready exists.  Perhaps multiple threads tried to create a service about the same time?
at org.bushe.swing.event.EventServiceLocator.setEventService(EventServiceLocator.java:123)


I could ignore it, since the application is running well enough (I think?) but I'm concerened that once I figure out how to actually implement some parts of the GUI they might not work.

Which leads me to my next question. I was trying to create a simple button on screen and I could not for the life of me figure out how to go about it. I have my nifty instance... But what do I do with it? Any pointers in the right direction would be greatly appriciated!

My three classes:

The outer class, TheGame (This is the StateBasedGame)

public class TheGame extends NiftyStateBasedGame
{

Nifty nifty;
GameOver go;

public TheGame(String name)
{
super(name);
go = new GameOver();

}

@Override
public void initStatesList(GameContainer arg0) throws SlickException
{

}

public static void main(String[] args) throws Exception
{
AppGameContainer game = new AppGameContainer(new TheGame("OMG, Super test!"));

game.setDisplayMode(800, 600, false);
game.setAlwaysRender(true);

game.start();

}


And the two dummy classes the are the states:

public class Menu extends NiftyOverlayGameState
{
@Override

protected void initGameAndGUI(GameContainer gc, StateBasedGame sbg) throws SlickException
{
initNifty(gc, sbg);
}

@Override
protected void renderGame(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException
{
g.drawString("Does it work?", 100, 100);

}

@Override
protected void updateGame(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException
{
Input input = gc.getInput();
if (input.isMouseButtonDown(Input.MOUSE_LEFT_BUTTON))
sbg.enterState(1);
}

public int getID()
{
return 0;
}

public class GameOver extends NiftyOverlayGameState
{

protected void initGameAndGUI(GameContainer gc, StateBasedGame sbg) throws SlickException
{
initNifty(gc, sbg);
}

@Override
protected void renderGame(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException
{
g.drawString("WORKS, OOOH-YEA!", 100, 100);
}

@Override
protected void updateGame(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException
{
Input input = gc.getInput();
if (input.isMouseButtonDown(Input.MOUSE_RIGHT_BUTTON))
sbg.enterState(0);
}

public int getID()
{
return 1;
}


Again, if compiled, this gets me the two screens I want with the warning/exception I mentioned above. What am I doing wrong? And how would I start actually adding GUI elements to this?

first off: You are doing it the right way. How ever something is wrong with your classes. There are abstract methods in the NiftyOverlayGameState you are not implementing in your samples.

/**
* Enter the game state. This function is called during the default {@link #enter(GameContainer, StateBasedGame)}
* function call.
*
* @param container the container that displays the game
* @param game the state based game this state is a part of
* @throws SlickException in case entering the state fails
*/
protected abstract void enterState(GameContainer container, StateBasedGame game) throws SlickException;

/**
* Leave the game state. This function is called during the default {@link #leave(GameContainer, StateBasedGame)}
* function call.
*
* @param container the container that displays the game
* @param game the state based game this state is a part of
* @throws SlickException in case entering the state fails
*/
protected abstract void leaveState(GameContainer container, StateBasedGame game) throws SlickException;

/**
* This function should be used to prepare the actual GUI and the controllers of the Nifty GUI. It is called right
* after the Nifty GUI got initialized.
*
* @param nifty the Nifty GUI that got initialized
* @param game the game this state is part of
*/
protected abstract void prepareNifty(Nifty nifty, StateBasedGame game);


While you might not need the enterState and leaveState functions right away, the prepareNifty function is very important. Inside this function you have to load the GUI itself.

Loading the GUI is done on two ways. Either using the builder classes or using the XML loader.

You find a sample on how to use the builder classes here in the Nifty-Examples. For example here: Nifty-Examples - Default Controls - Source

As for the XML loading. This is simply done using nifty.fromXML("gui.xml", "startScreen"). The XML Files look like this for example. You find more examples for these as well in the Nifty-GUI examples. Nifty-GUI fetches the XML files using the context classloader. So you need to apply the path to the file starting at the root resource or source path.

In addition I recommend a look at the manual of the Nifty-GUI. You find this one here.

I hope this helps you getting started with the Nifty-GUI. :)

Oh and the warning... this one usually appears if the initialization of the Nifty-GUI is called twice for any reason. In your code I fail to see any reason for that. The warning is not critical. But its a indication that the initialization process is flawed and most likely slower then it has to be.

• Thanks for your detailed answer! I'll give all this a proper reading and try to get it to work. – Eric Jul 19 '13 at 21:38