I wrote this little app state for one of my games and decided to share it I think it would make a great addition to the com.jme3.niftygui package.
public class NiftyAppState implements AppState {
private AppStateManager stateManager;
private ViewPort viewPort;
private NiftyJmeDisplay display;
private Nifty nifty;
private Screen screen;
private String startFilePath;
private String startScreenId;
private void enabled;
public void NiftyAppState() { }
public void NiftyAppState(String filePath) {
this(filePath, null);
}
public void NiftyAppState(String filePath, String screenId) {
startFilePath = filePath;
startScreenId = screenId;
}
public Nifty getNifty() {
return nifty;
}
public NiftyJmeDisplay getDisplay() {
return display;
}
@Override
public boolean isEnabled() {
return enabled;
}
@Override
public boolean setEnabled(boolean enabled) {
if(this.enabled == enabled) {
return;
}
if(enabled) {
attachDisplay();
} else {
detachDisplay();
}
setControlEnabled(enabled);
this.enabled = enabled;
}
@Override
public boolean isInitialized() {
if(display == null) {
return false;
}
return display.isInitialized();
}
@Override
public void initialize(AppStateManager stateManager, Application app) {
this.stateManager = stateManager;
this.viewPort = app.getGuiViewPort();
AssetManager assetManager = app.getAssetManager();
InputManager inputManager = app.getInputManager();
AudioRenderer audioRenderer = app.getAudioRenderer();
display = new NiftyJmeDisplay(assetManager, inputManager, audioRenderer, viewPort);
nifty = display.getNifty();
if(startFilePath != null) {
nifty.addXML(startFilePath);
if(startScreenId != null) {
nifty.gotoScreen(startScreenId);
}
}
if(enabled) {
attachDisplay();
}
}
@Override
public void update(float tpf) {
Screen screen = nifty.getCurrentScreen();
if(this.screen != screen) {
detachController();
this.screen = screen;
attachController();
}
}
@Override
public void render(RenderManager rm) { }
@Override
public void postRender() { }
@Override
public void stateAttached(AppStateManager stateManager) { }
@Override
public void stateDetached(AppStateManager stateManager) { }
@Override
public void cleanup() {
detachController();
detachDisplay();
}
private void attachDisplay() {
if(viewPort == null || display == null) {
return;
}
if(viewPort.getProcessors().contains(display)) {
viewPort.addProcessor(display);
}
}
private void detachDisplay() {
if(viewPort == null || display == null) {
return;
}
if(viewPort.getProcessors().contains(display)) {
viewPort.removeProcessor(display);
}
}
private void attachController() {
if(screen == null || stateManager == null) {
return;
}
ScreenController controller screen.getScreenController();
if(controller != null) {
if(controller instanceof AppState) {
AppState appState = (AppState)controller;
if(!stateManager.hasState(appState)) {
stateManager.attach(appState);
}
}
}
}
private void detachController() {
if(screen == null || stateManager == null) {
return;
}
ScreenController controller screen.getScreenController();
if(controller != null) {
if(controller instanceof AppState) {
AppState appState = (AppState)controller;
if(stateManager.hasState(appState)) {
stateManager.detach(appState);
}
}
}
}
public void setControllerEnabled(boolean enabled) {
if(screen == null) {
return;
}
ScreenController controller screen.getScreenController();
if(controller != null) {
if(controller instanceof AppState) {
((AppState)controller).setEnabled(enabled);
}
}
}
}
It is actually very simple to use attach the state in your application.
public class MyGame extends SimpleApplication {
@Override
public void sipleinitApp() {
stateManager.attach(new NiftyAppState("Interface/nifty.xml", "start");
}
}
Create a screen with a controller Nifty GUI Java Interaction
the state will automatically load your AppState ScreenController and start updating it if the NiftyAppState is disabled or destroyed it will do the same to your Controller. this means if your game is screen driven like mos where GUI elements allow the user to navigate between states you only need to call nifty.gotoScreen(“newScreenId”) from your controller and let the NifyAppState handle attaching the state for you.
so in short your main application could consist of only the code above and your UI could be done only in xml with AppState Controllers. It really cleaned up some of my code I hope this helps others.