Nifty TextField

Hi,
I have textField control on screen, it’s visible and reacting on mouse moving over it, but pressing any key does not do anyting.

    TextFieldBuilder tf = new TextFieldBuilder("text");
    tf.childLayoutCenter();
    tf.alignCenter();
    tf.backgroundColor("#0000");
    tf.height("100px");
    tf.width("400px");
    tf.inputMapping("de.lessvoid.nifty.controls.textfield.TextFieldInputMapping");
    tf.controller("de.lessvoid.nifty.controls.textfield.TextFieldControl");
    tf.maxLength(20);
    pan.control(tf);

Did I missed something? Uncle Google cant help me…

You don’t need to set the input mapping or controller. What happens when you click on it? It doesn’t have focus by default…

I was trying with and without the mapping or controller. Nothing happens when I click on it.

I’m not sure how much I can say without seeing more code or how the gui item is setup. I have plenty of text fields and have never had this issue.

I’m surprised too, it’s just a basic Nifty control. Tomorrow I’ll paste all the code.

Here is the whole code:

public class TextFieldScreen extends ScreenBuilder
{
    private static TextFieldScreen _instance;
    
    public static TextFieldScreen getInstance()
    {
        if (_instance == null) _instance = new TextFieldScreen();
        return _instance;
    }
    
    public static String ID = "TextField";
    
    private Screen _screen;
    //private NiftyRenderEngine _render;
    
    private TextFieldScreen() 
    {
        super(ID);
        
        ImageBuilder img = null;
        PanelBuilder pan = null;
        
        controller(new DefaultScreenController());
        
        LayerBuilder lay = new LayerBuilder("background");
        lay.childLayoutCenter();
        lay.backgroundColor("#0000");
        
        layer(lay);

        lay = new LayerBuilder("foreground");
        lay.childLayoutVertical();
        lay.backgroundColor("#0000");
        
        pan = new PanelBuilder("panel_top");
        pan.childLayoutCenter();
        pan.alignCenter();
        pan.backgroundColor("#0000");
        pan.height("50%");
        pan.width("100%");
        lay.panel(pan);
        
        pan = new PanelBuilder("panel_bottom");
        pan.childLayoutCenter();
        pan.alignCenter();
        pan.backgroundColor("#0000");
        //pan.y("100px"); //childLayoutAbsolute()
        pan.height("100px");
        pan.width("1000px");
        lay.panel(pan);
        
        TextFieldBuilder tf = new TextFieldBuilder("text");
        tf.childLayoutCenter();
        tf.alignCenter();
        tf.backgroundColor("#0000");
        tf.height("100px");
        tf.width("400px");
        tf.inputMapping("de.lessvoid.nifty.controls.textfield.TextFieldInputMapping");
        tf.controller("de.lessvoid.nifty.controls.textfield.TextFieldControl");
        tf.maxLength(20);
        pan.control(tf);
        
        layer(lay);
    }
    
    @Override
    public Screen build(Nifty ni) 
    {
        //_render = ni.getRenderEngine();
        
        _screen = super.build(ni);

    
        return _screen;
    }
    
}

and …

@Override
public void simpleInitApp() 
{
   . . . .
   _nifty.addScreen(TextFieldScreen.ID, TextFieldScreen.getInstance().build(_nifty));

Up,

I’m trying to understand the problem. First of all, I can’t see if the ThextField is even registered in InputManager. onKeyEventQueued → invokeActions and there is nothing from TextField, only engine’s and my own mappings.

EDIT: traced it already to this point:

    if (nic.processKeyboardEvent(keyEvt)) {
        evt.setConsumed();

The function returns true, so Nifty consumes the event. Why there is nothing on TextField?

EDIT2:

Ekhm, whats going on?

I mean the small red field filled with text… You can see my source in previous post.

EDIT3: SOLVED!

Another question:

Why TextFieldBuilder don’t want to use custom fonts?

    TextFieldBuilder tf = new TextFieldBuilder("text");
    tf.font("fonts/MorrisRoman.fnt");

Used SDK to convert ttf into fnt format. Inside JAR, in subfolder fonts I have both, fnt and png files.
I know that spending more and more time in google/docs/source files I’ll solve it on my own, like before, but this way i’ll configure that damn text field after a week…

Did you move the font to /font ? By default I think its Interface/Fonts. I do the exact same thing so I assume it could be a path issue.

Yes, the files are inside main JAR file, in fonts subfolder. I was trying to move them into asset but without success.
All the time I have some default fonts printed inside TextField, there is no exception during execution.

EDIT: and how to change its color (to transparent), how to get rid of the default red frame shown when mouse is over it? I’m not using xml so I don’t have any style to set. Seems that backgroundColor and color does not have any effect.

If they aren’t in the asset pack then I don’t think it will be able to find the font by default. As far as the box goes… you need to change or override the style. I’m not sure how to edit the styles in java or if you even can. You may need to keep an xml style sheet around to override those.

I found that I can use StyleBuilder.

    id(NAME);
    backgroundColor("#0000");

Ofc I used build(nifty).

TextFieldBuilder tf = new TextFieldBuilder("textfield");
tf.style(TextFieldStyle.NAME);

But when I want to build the screen that contains above lines, the error appears:

java.lang.RuntimeException: missing childLayout attribute for an element with [1] child elements. Attributes of error element [id => textfield#field, style => #field]
    at de.lessvoid.nifty.loaderv2.types.ElementType.enforceChildLayout(ElementType.java:187)
    at de.lessvoid.nifty.loaderv2.types.ElementType.applyStandard(ElementType.java:176)
    at de.lessvoid.nifty.loaderv2.types.ElementType.create(ElementType.java:144)
    at de.lessvoid.nifty.loaderv2.types.ElementType.applyChildren(ElementType.java:251)
    at de.lessvoid.nifty.loaderv2.types.ElementType.applyStandard(ElementType.java:175)
    at de.lessvoid.nifty.loaderv2.types.ElementType.create(ElementType.java:144)
    at de.lessvoid.nifty.loaderv2.types.ElementType.applyChildren(ElementType.java:251)
    at de.lessvoid.nifty.loaderv2.types.ElementType.applyStandard(ElementType.java:175)
    at de.lessvoid.nifty.loaderv2.types.ElementType.create(ElementType.java:144)
    at de.lessvoid.nifty.loaderv2.types.ElementType.applyChildren(ElementType.java:251)
    at de.lessvoid.nifty.loaderv2.types.ElementType.applyStandard(ElementType.java:175)
    at de.lessvoid.nifty.loaderv2.types.ElementType.create(ElementType.java:144)
    at de.lessvoid.nifty.Nifty.createElementFromTypeInternal(Nifty.java:1439)
    at de.lessvoid.nifty.Nifty.createElementFromType(Nifty.java:1430)
    at de.lessvoid.nifty.builder.ElementBuilder.build(ElementBuilder.java:448)
    at de.lessvoid.nifty.builder.LayerBuilder.build(LayerBuilder.java:22)
    at de.lessvoid.nifty.builder.ScreenBuilder.build(ScreenBuilder.java:52)
    at com.dungeongame.gameclient.scene3d.gui.nifty.TextFieldScreen.build(TextFieldScreen.java:128)
    at com.dungeongame.gameclient.scene3d.Scene3D.simpleInitApp(Scene3D.java:661)
    at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:226)
    at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:130)
    at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:207)
    at java.lang.Thread.run(Thread.java:722)

EDIT: ok, this is not fair, in documents there was nothing about that I must define childLayout…

    id(NAME);
    backgroundColor("#0000");
    padding("0px,2px");
    childClip(true);
    childLayout(ChildLayoutType.Center);

Btw, overriding the default styles works at least…

That error is because you didn’t set the chilldLayout attribute (aka ‘horizontal’, ‘vertical’, etc. etc.) on the element given in the error. You have to set some sort of child layout for every element.

Yes, I found that, check the EDIT to the prev post.

Seems that I have some progress:

The entire GUI I made on my own, just a textures on GuiNode and playing with screen coordinates when the mouse clicks. Nifty is huge and I don’t want huge and complex things in my code, the text field was an exception, I was too lazy to make something more ‘interactive’ than a button :wink:
Anyway… Now I only need to get rid of the red border that appears when mouse is over control.

Another problem, maybe someone can help me…

    TextField tf = _screen.findNiftyControl("textfield", TextField.class); 
    tf.setText(text);

The above code works well, but only if the textfield was shown before.
Calling setText for the first time produces NullPointerException.

I know that I can set any initial text during creation, but I’m calling build() at the begining of the program, initializing Nifty’s screens like all other resources, and the text field is ofc blank.

I need to set that text later, how to do that?

EDIT: at the first time, before the screen was shown, calling tf.isBound() gives me false. I found that I need to check isBound, and only if it is true I can use setText() withount NullPointerException. But I really really really need to set the text even if isBound() returns false.