Nifty GUI - Pure Java?

Is it possible (and if it is - how?) to create everything GUI related without even touching those ugly XML’s? What I’m struggling with are:

  • Setting fonts globally (by which I mean setting font for panel so all of it’s children share this font) OR setting fonts for interactive elements (buttons for example - so far I was able to change font only for label),
  • Setting how interactive elements look (background color is the only thing that works for me now),
  • Setting interaction effects (onHovers, onClicks, etc.) for interactive elements (buttons for example),
  • Setting WHOLE element transparency (not only background with alpha channel but the whole element: background, text and anything else) and setting button’s transparency (seems to have some pre-defined look and only RGB part of RGBA color seems to pull through - I easily set RGBA background color for label though).

Tutorials and Manual fail to cover those topics. Laying out static stuff is more-or-less explained but dealing with interactive stuff, not so much.

It is fessable i belive but then again if you realy want to go pure java I would recommand you to use tonegod instead. Here is a nice forum thread showing the difference between both, one of them been the use of XML vs no XML.

To give you a short answer: Yes, you can write everything in java. I do this in my own project have run into zero problems until now.

  • Setting fonts globally OR setting fonts for interactive elements: You can put the font for each element, like button, label etc. For the button you could use the ButtonBuilder b = new ButtonBuilder(…); b.label(…); To use a global font you could simply set a string which saves the font name, like “aurulent-sans-16.fnt”.
  • Setting how interactive elements look: What exactly do you want to set? You can use the builder of each element to set everything you need.
  • Setting interaction effects (onHovers, onClicks, etc.) for interactive elements (buttons for example): Sure, you can use the given interactions and binds them to specifics effects.
  • Setting WHOLE element transparency: For example for the panel you can use the PanelCreator. There you can set the method setStyle(""); which results into not showing the panel itself.

As far as I remember, Nifty doesn’t force you to use XMLs… You can build a GUi in code just as fine as you can in XML.
Just because something supports loading from XML doesn’t mean you HAVE to use xml files? It’s like saying because you have a fast food restaurant around the corner, you can never cook again your life. XML guis are fine if they fit your needs - But you don’t need to use them and can always go back to placing elements via code.
It kinda reminds me of Windows, when the metro design was made the default starting screen and everyone looked at it for 1 minute and was like “this new windows sucks, I liked the desktop more” and not realizing the metro-gui/xml-loader was just a bonus and the old desktop was just one click away.

Back to the topic: Of course it is possible to do all this in code. I mean… the xml loader is written in Java. So if the loader can generate commands to build the gui / set interactions, you can do it as well. The documentation is indeed missing a lot of information, but it is definitely possible.

Well, yes and no, I still believe that you should use the right tool for the right work. You can plant nails with a screwdriver if you want, but a hammer will always be more efficient, and you can also screw a frame with a hammer but really that will only make a mess.

I did not use nifty enough to claim I fully undethant all its potential, but from what I have seen and read its design in a way that you should use XML if you want to fully use its capacity. It’s not a bad thing, I just believe it’s not the right tool here.

Mordag:

a) I meant setting it ONCE for example:

screen(screen builder() {{
font("myfont.fnt");
}});

…and have it on every child of this screen. As for second part of this: You mean that I should create label that is a child of button and set font for those label and leave actual button text empty?

[EDIT] Nope, label child of button doesn’t seem to work either.

b) For example button have this default convex look and setting background color doesn’t change it. Also I’d like to get rid of this silly red border when I hover mouse over button and have something else instead (background color change for example). Also setting permanent border around elements would be nice.

c) Care to show me code for those “given interactions”? How do I create those from grounds up? There isn’t a single word in manual about this. So far I did something like this:

control(new ButtonBuilder("Show Mesh Grid", "Show Mesh Grid") {{
    // some other parameters here
    backgroundColor("#somecolor");
    onHoverEffect(new HoverEffectBuilder("MyEffect") {{
        backgroundColor("#someothercolor");
    }});
}});

…and it doesn’t work. It changes my color permanently to #someothercolor. When I added endHoverEffect in the same fashion it just took the “freshest” color in code.

d) Transparency != Invisibility. I don’t want my element to be invisible, I want it to be transparent with the alfa value set by me. Right now I can set transparency by setting background color in RGBA code. But it DOESN’T WORK for buttons, as they completely ignore A part, not to mension it changes only background. And I want text to be as transparent as background (which means I want WHOLE ELEMENT to be transparent - let’s say I have a button that has background color, text and small icon image in front of text - I want to set transparency to 20% somewhere, and have this whole button visible in 80%).

[EDIT] Small adjustment. It’s even worse in button case. It looks like RGBA in background color works but… It doesn’t really paint background. It just paints a rectangle over button default convex look. And I want to change this default look to pure color (or something else - but not paint over it, but change it).

Could You guys give me at least example syntax for doing some of the stuff I mentioned? Because without documentation I’m kinda unable to pull this off.

SimonBedard:
I’d agree with You if TonegodGUI was at least in as advanced state as NiftyGUI is (blast it, I even seen Tonegod him/her-self applauding NiftyGUI potential in several topics here). And to be honest it’s as far from it as NiftyGUI is from JavaFX (which should be a role model for all GUI’s in the world in my opinion).

Without documentation? You did find the link to the Nifty PDF manual, right?

Of course I did (I believe I mentioned both “tutorial” and “manual” in beginning of the topic). Did You?
Because I have it right in front of me and as far as controls, styles and effects sections begin, code syntax is presented only in xml way (90%) or not presented at all (10%).

a) I haven’t done this yet/haven’t need it. Maybe there’s a way to set the font globally. No, I meant you can use the actual button set a font. There are different builder in nifty. Each builder represent the specific control/element. Like the button is build by the ButtonBuilder class. This class includes settings for size, text and also for setting the font.

b) You have to use the method setStyle and give it a “”-parameter. This is what I did. I haven’t played with the border yet, but simply take a look at the style jars of nifty. For starters you could you setStyle(“nifty-panel-simple”) which includes a simple border for your panels.

c) Sure, here an example how I did the onHover effect (I only give you parts of my code to minimize the relevant code. I hope that’s ok for you):

(createButton is an instance of the ButtonBuilder class.)

createButton.backgroundColor(color);
createButton.onHoverEffect(effectController.createColorAction(hoverColor));

which leads to my own effect controller class:

public ControlEffectOnHoverAttributes createColorHover(String color) {

    controlEffectOnHoverAttributes = new ControlEffectOnHoverAttributes();
    controlEffectOnHoverAttributes.setName("colorBar");
    controlEffectOnHoverAttributes.setAttribute("color", color);
    controlEffectOnHoverAttributes.setPost("true");

    return controlEffectOnHoverAttributes;
}

d) You can use the “normal” html-color codes for that. For example: “#0d0c0cb2”.

Point A.

control(new ButtonBuilder("Show Mesh Grid", "Show Mesh Grid") {{
    font("Assets/Fonts/BlockishFont.fnt");
    // some other parameters
    backgroundColor("#0070A8B4");
}});

Doesn’t work. And the EXACTLY SAME code in my label builder works. Everything is 100% identical. It’s like Button Builder ignores the font parameter.

Point B.

Element button = nifty.getCurrentScreen().findElementByName("Show Mesh Grid");
button.findNiftyControl("Show Mesh Grid", Button.class).setStyle(""); // option 1
button.setStyle(""); // option 2

Doesn’t work either. Button still have this convex thingy underneath my color. And red border on hover is still there. On the other hand using code like this:

control(new ButtonBuilder("Show Mesh Grid", "Show Mesh Grid") {{
        font("Assets/Fonts/BlockishFont.fnt");
        // some other parameters
        style("");
        backgroundColor("#0070A8B4");
    }});

…just plain crashes my application.

Point D.
I do use them. But again such transparency obviously only applies to background (it’s value of background parameter). It doesn’t apply to other stuff like for example text or image. Example that I used is in point A. That’s normal html RGBA #colorcode.

About Point A/B: I am using the implementation of B to keep my code organize, but there shouldn’t be a big difference. At point A, you probably forget to call the method .create() or similar. I am not sure about this. About B, what are you trying to do? An example:

ButtonBuilder button = new ButtonBuilder(“awesomeID”);
button.height(“10%”);
button.width(“5%);
button.label(“Click me!”);
button.setStyle(”");
button.backgroundColor("#FFFFFF");
button.interactOnClick(“click()”);
button.build(nifty, screen, parentElement);

Now you can search for this button via Element button = nifty.getCurrentScreen().findElementByName(“AwesomeID”);
If you want to change something within the button, you should use the button control. Short explanation, each element on the screen is represented by a control class. The button uses the Button.class. You can access this via button.getNiftyControl(Button.class).[access to methods like button label text]. More general stuff like width or height, you can use the element itself like button.setConstraintWidth(new SizeValue(“10px”);

OkayWaitAMinuteHere!!!

I’m using entirely different way of building my GUI. The very one from the tutorials which looks like this:

//<SCREEN>
nifty.addScreen("Game Screen", new ScreenBuilder("Game Screen") {{
    controller(new DefaultScreenController());
    // <LAYER>
    layer(new LayerBuilder("Game Layer") {{
        childLayoutAbsolute();
        // <PANEL>
        panel(new PanelBuilder("Toolbar Panel") {{
            childLayoutVertical();
            // some b..it
            // <BUTTON>
            control(new ButtonBuilder("Show Mesh Grid", "Show Mesh Grid") {{
                // some b..it
            }});
            // </BUTTON>
            // <BUTTON>
            control(new ButtonBuilder("Quit Game", "Quit Game") {{
                // some b..it
            }});
            // </BUTTON>
        }});
        // </PANEL>
        // <PANEL>
        panel(new PanelBuilder("Tooltip Panel") {{
            childLayoutAbsolute();
            // <LABEL>
            control(new LabelBuilder("Tooltip", "Tooltip Text") {{
                // some b..it
            }});
            // </LABEL>
        }});
        // </PANEL>
    }});
    // </LAYER>
}}.build(nifty));
// </SCREEN>

So I can either set stuff as parameters inside that code or do the:

Element button = nifty.getCurrentScreen().findElementByName("Show Mesh Grid");
button.DOSOMETHINGHERE
or
button.findNiftyControl("ShowMeshGrid", Button.class).DOSOMETHINGHERE

In the end whatever I’m doing it works with labels but doesn’t work with buttons. Except for effects - I can’t split myself so I left this part for later, when I get a hang on button settings.

Well that’s one way to create elements. I am sure in the manual there’s also examples for this, but the usage of the builder classes is straightforward and “cleaner”.
No, you can set certain stuff via searching for the element, but not everything. You should set everything important while creating the element and if you really have to change the position, size, button text or anything else, you could use the control classes.
What do you want to do with your button? I mean the example above should give you a button with the color #FFFFF and the text Click me!.

I cut all the unimportant stuff so short version:

  • I managed to get rid of default styling completely with Your builder (and it also works in my tree-like syntax, after few changes). GOOD!
  • Text on the button is invisible or there is no text at all (tried both with label(“string”) and text(“string”). NOT GOOD!

My mistake, it’s of course style(""). That’s one problem with the builders. Each builder have slightly different names for their parameters. Like the ButtonBuilder uses style(…) and the PanelCreator uses setStyle(…).

Edit: You definitely should take a closer look what each element needs. For example the childrenLayout have to be set within each panel.

Edit 2: Which color is your background? I think you need to use the label(…) but I could be wrong.

WARNING: missing font in renderText! could it be that you're using <text> elements without a font or style attribute? in case you've replaced <label> with <text> you're probably missing style='nifty-label' :)

So that’s why I don’t see text. We cleaned the style on purpose and I added my font, so what could be missing now?

Forgot the code. It’s like this now:

ButtonBuilder button = new ButtonBuilder("MyButton");
button.style("");
button.childLayout(ElementBuilder.ChildLayoutType.Vertical);
button.height("10%");
button.width("90%");
button.font("Assets/Fonts/BlockishFont.fnt");
button.color("#FFFFFF"); // not sure if it's text color but just for the heck of it - doesn't work either way
button.textHAlignCenter();
button.textVAlignCenter();
button.label("Click me!");
button.backgroundColor("#0070A8B4");
button.interactOnClick("click()");
button.build(nifty, nifty.getScreen("Game Screen"), nifty.getScreen("Game Screen").findElementByName("Toolbar Panel"));

When I change label to text it stops screaming through my debugger but “Click me!” isn’t there still.

Sorry, probably it’s getting late of why I am doing mistakes like this. I mixed up my own solution with the “right” solution. :confused: So, yes the problem is because we have set our style to “”. By simply removing the method button.style("");, it should fixed this for now. The problem is now that the red border is still active.

Edit: Found the solution: You have to define this in the onHoverEffect(…) (that’s the xml part)–> < onHover name=“border” color="#822f" post=“true” /> To prober solve your button, you have to use different effects; like the onFocus and onHover.

Edit2: If you’re interested in my solution: I have created one button without a text and created a label as a child (another element) on top of it. Reason for this was that my button also could be an image, which means the button itself acts as a container for the event listener and the text.

Well but this was supposed to solve a lot more then red border.

  • font(“MyFont”) doesn’t work and I have default font,
  • convex looking background under my backgroundColor(“MyColor”) is there again.

Ehh… In the end it looks like xml is unavoidable? :frowning:
Or… Something is seriously screwed with some commands, because they just don’t work for buttons, even though they should? :expressionless:

No, you do not need to use xml. I just attached the xml style code which is written into the button style jar. What exactly isn’t working in case of the font? I few comments to your code:

ButtonBuilder button = new ButtonBuilder(“MyButton”);
button.style(""); //remove this
button.childLayout(ElementBuilder.ChildLayoutType.Vertical);
button.height(“10%”);
button.width(“90%”);
button.font(“Assets/Fonts/BlockishFont.fnt”); //is this also in the jme lib as default? If not, you have to attach this to the assetmanager or is it the right path? I think it should be “Fonts/BlockishFont.fnt”
button.color("#FFFFFF"); // also don’t know what this is; I think it’s for the text, but I am not sure
button.textHAlignCenter(); //text is always center, as far as I know
button.textVAlignCenter();
button.label(“Click me!”);
button.backgroundColor("#0070A8B4");
button.interactOnClick(“click()”);
button.build(nifty, nifty.getScreen(“Game Screen”), nifty.getScreen(“Game Screen”).findElementByName(“Toolbar Panel”));

So far this button should work without problems. Are you getting exception or something else or what exactly is not working?

Well code works.
But the font is default, not mine. And as for path it’s 100% correct, because I gave the same path to font for my label elsewhere and I got my font.
And default convex (background? image? whatever that is…) shape is visible on my button through the alfa of backgroundColor. Wasn’t visible with empty style though so there should be some kind of parameter to get rid of that.