Nifty GUI, console with history for commands, xml or javabuilder, something premade?

Hi!



[blabering]

I like Nifty GUI a lot, but I cant get used to it :frowning:

I tried the javabuilder but for some reason it dont work.

All examples I find never lead me to a usefull and simple console with history, and commands retrieve history.

Its some months I am trying to find something simple.

I tried to get the example console, that one with F1 (that I would rather use TAB or “~”) but all efforts I put on trying to isolate that code and xmls etc, always lead to disaster (scrambled code everywhere…), I tried also to mix the xml with javabuilder, to no avail.

[/blabering]



So my goal is simple:

Usable console, with custom activation key, preferably transparent (mandatory? :D); with history, and comands retrieve history (press key up); simple like that.

Does anyone have any idea how to achieve that? Can be xml, anything, just need it usable to send more complex commands as my keyboard keys for binds are almost ending :stuck_out_tongue:

Such a thing could be an example in the nifty tests? please! :smiley: It could be TestNiftyConsole.java or something like that!

hi @phate666,



I saw that, it does not work, there is something missing…

someone used to it may know, but I am completely puzzled :frowning:

everyway I try to use that code leads to nothing, crashes/exceptions and even not found classes…

I am using latest JME SVN, could be because of that?

I tried also to get latest nifty lib, or older ones, but I cant find info on what version i should use…



If there was a complete class doing everything, and not the isolated pieces of code like:

[patch]

// this creates a simple console with 25 lines that is 80% width (of the parent element) and for demonstration purpose there is an effect added

control(new ConsoleBuilder(“console”) {{

width(“80%”);

lines(25);

alignCenter();

valignCenter();

onStartScreenEffect(new EffectBuilder(“move”) {{

length(150);

inherit();

neverStopRendering(true);

effectParameter(“mode”, “in”);

effectParameter(“direction”, “top”);

}});

}});[/patch]

this is for ppl that knows a lot of nifty, I am noob on it, and have been for a long time…

The above code needs something from “Screen” to work, also it needs to be on some panel or something and needs some more stuff, some controls etc… it is not a working source :frowning:



I am looking for a working simple console, that works, as for starters. Something you can begin with and improve later. The examples in xml, I cant understand that, I tried to follow it, but I couldnt even find where the F1 key is bound!! It took me some hours of research, after that I gave up D:



Any more tips? :smiley:

The tip is this project: https://nifty-gui.svn.sourceforge.net/svnroot/nifty-gui/nifty-default-controls-examples/trunk Try to get that to build. It contains a working console and lots of Java Builder stuff.



The Nifty version out of date, missing documentation problem will soon be resolved. It’s hard to maintain everything at the same time and actually coding / improving / extending it >_< … since 1.3 is now really very near this will soon be settled.



Noob compatible documentation will be next :stuck_out_tongue:

Hi @void256!

.

I got the whole SVN, I was trying to join all sources, but I couldnt find a good way to do that on eclipse. I thought on creating one project for each module of that SVN, but I couldnt find how to supply some lwjgl dependencies, I couldnt find the libs, I tried to reuse the jme3-svn ones to no avail…

.

Btw, I thought again, on all my old tries, and I thought on this:

The example console is cool enough, I just couldnt find a way to call only that, instead of the full presentation.

.

So, I thought on doing this:

At TestNiftyExamples.java instead of this line

// nifty.fromXml(“all/intro.xml”, “start”);

I would put this code:

[patch] nifty.fromXmlWithoutStartScreen(“all/intro.xml”);

final Element cp = nifty.findPopupByName(“consolePopup”);

Screen mainScreen = new ScreenBuilder(“main”) {{

controller(new DefaultScreenController());

//cp ??

}}.build(nifty);

nifty.gotoScreen(“main”);

[/patch]

.

From this point on, I dont know what to do, as every name I got from console.xml as “consolePopup”, “nifty-console”, “console”; or even “ConsoleDemoStartScreen” (when I was trying to reuse the controller with findScreenController() to use instead of DefaultScreenController())… all of these tries returned “null”.

.

I would like to reuse that console that is ready and is cool, but I dont know how to collect it. If I am thinking right (use xml stuff on java builder).

And finally, receive and use the consolePopup commands!

.

Btw, the new release is much awaited! :smiley:

.

thx!!

I’m doing something like

[java]

nifty.fromXml(“net/virtualmat/nifty/console.xml”, “start”);

popup = nifty.createPopupWithId(“consolePopup”, “consolePopup”);

Console control = popup.findNiftyControl(“console”, Console.class);

[/java]

and then attach ConsoleCommands to control variable.

My console.xml is slightly modified, but I think same thing should still work.

I’m then showing console (as I handle that event myself) with

[java]

Element consoleElement = popup.findElementByName(“console”);

nifty.showPopup(screen, “consolePopup”, consoleElement);

[/java]

Btw, the new release is much awaited! :D


What do you want more:

a) Support on the Forum
b) new Nifty Release

It's hard to do both at the same time :P

Some explanation:

The console is just a control like all the others. So there is basically no difference if you would add a button or a console to a screen. You can add the console control to any element you like, a simple panel would be enough. The only parameter that is required is the lines attribute (to specify how many lines the console should show) and probably the width of the console.

Makes sense so far?

If you want to open the console only at certain times (by a keypress or something) then you'll need to learn about popup layers which is currently a bit difficult because it's not yet documented in the wiki, I think :P

There is a more simple console example in the old nifty-examples project available (Java Code: http://nifty-gui.svn.sourceforge.net/viewvc/nifty-gui/nifty-examples/trunk/src/main/java/de/lessvoid/nifty/examples/console/, XML Resources: http://nifty-gui.svn.sourceforge.net/viewvc/nifty-gui/nifty-examples/trunk/src/main/resources/console/)

XML Popup Layer definition with a console (Most of this makes the console fade in and stuff):

[xml] <!-- +++++++++++++++++++++++++++++++++++++++ -->
<!-- the console popup -->
<!-- +++++++++++++++++++++++++++++++++++++++ -->
<popup id="consolePopup" childLayout="center" backgroundColor="#000a">
<effect>
<onStartScreen name="fade" start="#0" end="#a" length="200" inherit="true" />
<onEndScreen name="fade" start="#a" end="#0" length="200" startDelay="100" inherit="true" />
</effect>
<panel childLayout="center" width="95%" align="center" valign="center">
<control id="console" name="nifty-console" lines="25" align="center" valign="center">
<effect>
<onStartScreen name="move" direction="top" mode="in" length="200" startDelay="100" inherit="true" />
<onEndScreen name="move" direction="top" mode="out" length="200" startDelay="0" inherit="true" />
</effect>
</control>
</panel>
</popup>[/xml]

To show the popup layer (this works for all popup layers) you'll need to first create the popup layer (you can create multiple popups if you want/need to):

[java]Element consolePopup = nifty.createPopup("consolePopup");[/java]

and then make it active which shows it (the third parameters makes sure the textfield inside of the console gets the keyboard focus - I think you could skip that parameter and it would still work):

[java]nifty.showPopup(screen, consolePopup.getId(), consolePopup.findElementByName("console#textInput"));[/java]

This is all not really console related but popup layer stuff.

To access the Console class from Java (to register commands or output stuff) you'll need to get the Console API:

[java]Console console = screen.findNiftyControl("console", Console.class);[/java]

Done!

The only thing that might be a bit difficult (and where I actually would accept your bitching :P) is the popup layer stuff which is not yet documented well enough for people to grasp. You could consider donating for Nifty via the sf.net project page tho :)

PS: The best way to build Nifty is learning and using Maven for this. Everything else would be odd.
1 Like

@abies

thx! I collected the console from xml w/o changes with this:

[patch]

nifty.fromXml(“console/console.xml”, “start”);

screen = nifty.getScreen(“start”);

screen.removeLayerElement(“layer”);

screen.removeLayerElement(“layer2”);

[/patch]

(I removed the layers to have only the console, it is looking good!)

.

@void256

thx on the explanation, it is helping me to implement the console!

I can show the console, and hide it, and type working commands!

EDIT:

I tried to release the keyboard with these commands (all at once):

[patch]

niftyDisplay.cleanup();

screen.endScreen(null);

nifty.exit();

[/patch]

I was able to reactivate niftygui by reinitializing it (as being loaded again!), but that makes me loose the history etc…

.

I will still look at the code links you showed above, I couldnt read it all today…; I am working on this all night, I will try to read that tomorrow, for a more gracefull solution!

.

thx!!

.

EDIT: I tested the code from sf.net, it works, but I still cant release the keyboard back to jme.

Hey!!

.

finally! it is fully working, it is fast and looks cool! yey!!

thx a lot!

.

below is the code, I created it for a few reasons:

  • to demonstrate a world we can go back interacting from console
  • to be easy to attach to your application and expand with your console commands
  • to allow you to have your xml stuff (look for myCustomStuff variable)

    (not fully tested btw…)

    EDIT: the default bound key to console is F2 !!!, I couldnt find a way to release/rebind the F1 key…

    .

    the remaining problem is I cant make the help commands work, the idea is:
  • help: this command should list all commands
  • Help CloseConsole: should show help info on specific command

    .

    btw,

    it would be interesting to have help info when binding a command, as a nifty-gui functionality :slight_smile:

    also, it would be cool if commands completion could be case insensitive! so commands would read nice, and also be found easly! :smiley: ( type “c” TAB and you get all “C…” commands!, key up and down could select a command also :smiley: )

    .

    EDIT: is there a way to disable smiles in the patch (below)? I had to remove them…

    EDIT: updated, now F1 keypress is ignored, you can use F1 key release for your commands like show help; it now disables the flybycam and reenable if it was enabled.

    [patch]package jme3test.niftygui;



    import java.util.Vector;



    import com.jme3.app.SimpleApplication;

    import com.jme3.asset.TextureKey;

    import com.jme3.input.KeyInput;

    import com.jme3.input.RawInputListener;

    import com.jme3.input.controls.ActionListener;

    import com.jme3.input.controls.KeyTrigger;

    import com.jme3.input.event.JoyAxisEvent;

    import com.jme3.input.event.JoyButtonEvent;

    import com.jme3.input.event.KeyInputEvent;

    import com.jme3.input.event.MouseButtonEvent;

    import com.jme3.input.event.MouseMotionEvent;

    import com.jme3.input.event.TouchEvent;

    import com.jme3.material.Material;

    import com.jme3.math.Vector3f;

    import com.jme3.niftygui.NiftyJmeDisplay;

    import com.jme3.scene.Geometry;

    import com.jme3.scene.shape.Box;

    import com.jme3.texture.Texture;



    import de.lessvoid.nifty.Nifty;

    import de.lessvoid.nifty.controls.Console;

    import de.lessvoid.nifty.controls.ConsoleCommands;

    import de.lessvoid.nifty.controls.ConsoleCommands.ConsoleCommand;

    import de.lessvoid.nifty.elements.Element;

    import de.lessvoid.nifty.screen.Screen;



    /**
  • @author teique
  • many thanks to void256, abies and pspeed

    */



    public class TestNiftyConsole {

    public static interface INiftyConsole {

    public abstract void initNiftyConsoleCommands(TestNiftyConsole nc);

    }



    private static class TestSimpleApplication extends SimpleApplication implements INiftyConsole {

    @Override

    public void initNiftyConsoleCommands(TestNiftyConsole nc) {

    }



    @Override

    public void simpleInitApp() {

    // show some stuff, your world

    Material mat = new Material(getAssetManager(), "Common/MatDefs/Misc/SimpleTextured.j3md");

    TextureKey key = new TextureKey("Textures/Terrain/splat/road.jpg");

    key.setGenerateMips(true);

    Texture tex = getAssetManager().loadTexture(key);

    mat.setTexture("ColorMap", tex);



    Box floor = new Box(Vector3f.ZERO, 3, 0.1f, 3);

    Geometry floorGeom = new Geometry("Floor", floor);

    floorGeom.setMaterial(mat);

    floorGeom.setLocalTranslation(0,-1f,0);

    rootNode.attachChild(floorGeom);



    guiNode.detachAllChildren(); //comment to not remove info above console view



    // ===>>> use these two lines below on your application! <<<===

    final TestNiftyConsole nc = new TestNiftyConsole();//TODO not working ,"/","&quot;);

    nc.init(this);



    inputManager.addMapping(ENiftyConsoleCommands.showConsole.toString(), new KeyTrigger(KeyInput.KEY_F2));

    inputManager.addListener(new ActionListener() {

    public void onAction(String name, boolean isPressed, float tpf) {

    switch(ENiftyConsoleCommands.valueOf(name)){

    case showConsole:

    if(isPressed) {

    nc.toggle();

    }

    break;

    }

    }

    },ENiftyConsoleCommands.showConsole.toString());

    }



    }



    public enum ENiftyConsoleCommands{

    consoleCommandParametersExample,

    showConsole,

    clearConsole,

    helpListAllCommands,

    help, //to show specific info on command

    closeConsole,

    quit,

    exit,

    }



    private SimpleApplication app;

    private Nifty nifty;

    private Console console;

    private Element consoleElement;

    private ConsoleCommands consoleCommands;

    private String[] commandsPrefixes = null;

    private Screen screen;

    private Element popup;

    private NiftyJmeDisplay niftyDisplay;

    private boolean enabled = false;

    private boolean flyByCamWasEnabled;



    public static void main(String[] args){

    SimpleApplication sp = new TestSimpleApplication ();

    sp.start();

    }



    /**

    *
  • @return if enabled

    */

    public boolean toggle() {

    enable(!enabled);

    return enabled;

    }



    public String[] getCommandsPrefixes(){

    if(commandsPrefixes == null)

    return null;

    return commandsPrefixes.clone();

    }



    public void enable(boolean enable){

    if(enable){

    initWork(app,false);



    popup.enable();

    nifty.showPopup(screen, "consolePopup", consoleElement);



    flyByCamWasEnabled = app.getFlyByCamera().isEnabled();

    app.getFlyByCamera().setEnabled(false);

    }else{

    nifty.closePopup("consolePopup");

    popup.disable();



    // not need these 3 below I think…

    //niftyDisplay.cleanup();

    //screen.endScreen(null);

    //nifty.exit();



    app.getGuiViewPort().removeProcessor(niftyDisplay);



    if(flyByCamWasEnabled)

    app.getFlyByCamera().setEnabled(true);

    }



    app.getInputManager().setCursorVisible(enable);

    //org.lwjgl.input.Mouse.setGrabbed(!enabled);



    this.enabled = enable;

    }



    public void init(SimpleApplication app) {

    this.app = app;

    this.app.getInputManager().addRawInputListener(new RawInputListener() {

    @Override public void onTouchEvent(TouchEvent evt) {}

    @Override public void onMouseMotionEvent(MouseMotionEvent evt) {}

    @Override public void onMouseButtonEvent(MouseButtonEvent evt) {}

    @Override public void onKeyEvent(KeyInputEvent evt) {

    if(evt.getKeyCode() == KeyInput.KEY_F1){

    if(evt.isPressed()){

    evt.setConsumed(); //consume the keypress event preventing it from being used by console

    }

    }

    }

    @Override public void onJoyButtonEvent(JoyButtonEvent evt) {}

    @Override public void onJoyAxisEvent(JoyAxisEvent evt) {}

    @Override public void endInput() {}

    @Override public void beginInput() {}

    });



    toggle();

    toggle();

    }



    /**
  • keep this method private, use init() above!
  • @param app
  • @param commandsPrefixes

    */

    private void initWork(SimpleApplication app, boolean myCustomStuff, String… commandsPrefixes) {

    boolean firstTime = false;

    if(this.app == null)

    throw new NullPointerException("call init(app) first!");



    this.app = app;

    if(commandsPrefixes.length > 0)

    this.commandsPrefixes = commandsPrefixes;



    if(niftyDisplay == null)

    niftyDisplay = new NiftyJmeDisplay(

    app.getAssetManager(), app.getInputManager(),

    app.getAudioRenderer(), app.getGuiViewPort());

    if(nifty == null){

    nifty = niftyDisplay.getNifty();



    if(myCustomStuff){ //not tested… but may work…

    // to create your own file outside any zip, in this case in the path "data" at root of your project path

    app.getAssetManager().registerLocator("data", "com.jme3.asset.plugins.FileLocator");

    // to load your custom console.xml at "data" path

    nifty.fromXml("console.xml", "start");

    }else{

    //load from nifty examples

    nifty.fromXml("console/console.xml", "start");

    }

    }



    if(screen == null){

    screen = nifty.getScreen("start");

    //remove some elements from the background, that come at console.xml

    screen.removeLayerElement("layer");

    screen.removeLayerElement("layer2");

    }



    if(popup == null){

    popup = nifty.createPopupWithId("consolePopup", "consolePopup");

    }



    if(console == null)

    console = popup.findNiftyControl("console", Console.class);



    if(consoleCommands == null){

    consoleCommands = new ConsoleCommands(nifty, console);



    // finally enable command completion

    consoleCommands.enableCommandCompletion(true);



    // init some basic commands

    addCommand(ENiftyConsoleCommands.exit .toString(), new BasicCommand(this), "Exit the application.");

    addCommand(ENiftyConsoleCommands.quit .toString(), new BasicCommand(this), "Quit the application (like Exit).");

    addCommand(ENiftyConsoleCommands.helpListAllCommands.toString(), new BasicCommand(this), "Show all commands.");

    addCommand(ENiftyConsoleCommands.clearConsole.toString(), new BasicCommand(this), "Clear console.");

    addCommand(ENiftyConsoleCommands.closeConsole.toString(), new BasicCommand(this), "Close console.");



    if(!(app instanceof INiftyConsole))

    throw new NullPointerException("your app must implement "+INiftyConsole.class.getName());

    ((INiftyConsole)app).initNiftyConsoleCommands(this);

    }



    if(consoleElement == null)

    consoleElement = popup.findElementByName("console");



    // attach the nifty display to the gui view port as a processor

    this.app.getGuiViewPort().addProcessor(niftyDisplay);

    }



    public void addCommand(String command, ConsoleCommand cc){

    addCommand(command, cc, null);

    }

    public void addCommand(String command, ConsoleCommand cc, String helpText){

    consoleCommands.registerCommand(command, cc);



    if(helpText!=null){

    HelpCommand hc = new HelpCommand(this,helpText);

    consoleCommands.registerCommand(ENiftyConsoleCommands.help.toString()+" "+command, hc);

    }

    }



    private class BasicCommand implements ConsoleCommand {

    private TestNiftyConsole nc;



    public BasicCommand(TestNiftyConsole nc) {

    this.nc = nc;

    }



    @Override

    public void execute(final String[] args) {

    String command = args[0];



    // force commands prefixes (usually "/" or "")

    if(nc.commandsPrefixes != null){

    for(String prefix : nc.commandsPrefixes){

    if(command.startsWith(prefix)){

    command = command.replaceFirst(prefix,"");

    break;

    }

    }

    return;

    }



    ENiftyConsoleCommands e = ENiftyConsoleCommands.valueOf(command);

    switch(e){

    case quit:

    case exit:

    nc.app.stop();

    break;

    case closeConsole:

    nc.enable(false);

    break;

    case consoleCommandParametersExample:

    nc.console.output("command: "+e);

    for(String str : TestNiftyConsole.getParameters(args)){

    nc.console.output("param: "+str);

    }

    break;

    case clearConsole:

    nc.console.clear();

    break;

    case helpListAllCommands:

    for(String cmd : nc.consoleCommands.getRegisteredCommands())

    if(!cmd.startsWith(ENiftyConsoleCommands.help.toString()+" "))

    nc.console.output(cmd);

    break;

    }

    }

    }



    private class HelpCommand implements ConsoleCommand {

    private TestNiftyConsole nc;

    private String helpText;



    public HelpCommand(TestNiftyConsole nc, String helpText) {

    this.nc = nc;

    this.helpText = helpText;

    }



    @Override

    public void execute(final String[] args) {

    nc.console.output(helpText);

    }

    }



    public static String[] getParameters(String… all){

    Vector<String> params = new Vector<String>();

    for(int i=0; i<all.length; i++){

    if(i==0)

    continue;

    params.add(all);

    }

    return params.toArray(new String[]{});

    }



    public Console getConsole() {

    return console;

    }



    }



    [/patch]

great work with the example! maybe add that to the jme wiki too for others to find?



there is also example code available that uses the console and when all else fails there is the sourcecode.

the command stuff is pretty new and it even has junit tests :slight_smile:



and it would be greatly appreciated if you could take a look at the source and maybe contribute a patch that adds the functionality you’re missing. Nifty is open source after all, you know? :slight_smile:

sure!



I am still playing with this code, I found some points that can be improved, and I am still working on it.

When it is working better I will look for the wiki :slight_smile:



I saw that when a command is sent to a ConsoleCommand extended class, it seems to not use the object related to the command, but use any object (or first or last on the array); so when I try to get HelpCommand for a specific command, I always get the same help text output. I think this is what you are talking about, I will take a look at the code and see what I can do. I already got the whole Nifty-gui repository SVN; I just couldnt setup compilable projects for it yet, but I guess if I bundle all files that compose an equivalent to “nifty-1.3-SNAPSHOT.jar” I will be able to compile it having jme3 svn as dependency! I will test that later… (do you seem to have an svn for that jar?)