[Nifty1.3] Listbox with custom items. (Solved)

Hi,



I’m trying different things with the new API.

And now, I try to add custom buttons inside a listbox.



I have my own control for the buttons : ItemButtonControl



With the wiki, I’ve found that I need to specify a viewConverterClass for managing object other that string

So I’ve created this class :

[java]

package com.didigame.acariaempire.gui.controls;



import com.didigame.acariaempire.data.character.CharacterItem;



import de.lessvoid.nifty.controls.ListBox.ListBoxViewConverter;

import de.lessvoid.nifty.elements.Element;



public class ListBoxViewConverterForItems implements ListBoxViewConverter<CharacterItem> {



@Override

public void display(final Element element, final CharacterItem item)

{

System.out.println( element.toString() );

Element btn = element.getElements().get( 0 );

ItemButtonControl control = btn.getControl( ItemButtonControl.class );

control.setItem( item );

}



@Override

public int getWidth(final Element element, final CharacterItem item)

{

return 300;

}

}

[/java]

(This is for test purpose. For now all my buttons have the same size : 300px )



After that, I’ve created my own control :

Copy-Paste from the ‘listBox’ control and changing 2 things :

  • Adding [java]viewConverterClass="com.didigame.acariaempire.gui.controls.ListBoxViewConverterForItems"[/java]
  • Changing the item definition :

    [java]



    <control type=“itemButton” style=“itemListBoxElt” controller=“de.lessvoid.nifty.controls.listbox.ListBoxItemController” inputMapping=“de.lessvoid.nifty.input.mapping.MenuInputMapping” />

    [/java]



    It gives something like that :

    [java]



    <controlDefinition name=“itemListBox” style=“ae-listbox” childRootId="#child-root" controller=“de.lessvoid.nifty.controls.listbox.ListBoxControl” viewConverterClass=“com.didigame.acariaempire.gui.controls.ListBoxViewConverterForItems” >

    <panel childLayout=“vertical”>

    <panel id="#scrollpanel" childLayout=“horizontal”>

    <panel id="#panel" childLayout=“absolute” childClip=“true” style="#scrollpanel" controller=“de.lessvoid.nifty.controls.listbox.ListBoxPanel” inputMapping=“de.lessvoid.nifty.input.mapping.MenuInputMapping”>

    <panel id="#child-root" width=“100%” childLayout=“vertical” visibleToMouse=“true”>



    <control type=“itemButton” style=“itemListBoxElt” controller=“de.lessvoid.nifty.controls.listbox.ListBoxItemController” inputMapping=“de.lessvoid.nifty.input.mapping.MenuInputMapping” />



    </panel>

    </panel>

    <control id="#vertical-scrollbar" name=“verticalScrollbar” style=“nifty-vertical-scrollbar”/>

    </panel>

    <panel id="#horizontal-scrollbar-parent" childLayout=“horizontal”>

    <control id="#horizontal-scrollbar" name=“horizontalScrollbar” style=“nifty-horizontal-scrollbar”/>

    <panel id="#bottom-right" style="#bottom-right" />

    </panel>

    </panel>

    </controlDefinition>

    [/java]



    The problem is :

    When I try to add an item, I can’t retrieve the ItemButtonControl.

    [java]

    @SuppressWarnings(“unchecked”)

    public void selectMiscPanel()

    {

    ListBox<CharacterItem> listBox = miscList.getNiftyControl( ListBox.class );

    listBox.clear();

    CharacterItem item = selectedCharacter.getEquipment().getCurrentWeapon();

    if( item != null )

    listBox.addItem( item );

    }

    [/java]

    [java]

    public class ListBoxViewConverterForItems implements ListBoxViewConverter<CharacterItem> {



    @Override

    public void display(final Element element, final CharacterItem item)

    {

    ItemButtonControl control = element.getControl( ItemButtonControl.class ); // PROBLEM HERE : control == null

    control.setItem( item );

    }

    […]

    [/java]



    So my questions are :
  • Is it possible to add something that is not a simple text as a list Item
  • If yes, what am I doing wrong ? ( Do I need to change the ListBoxItemController ? )



    Thanks in advance !



    Edit : The other way would be to use a ScrollPanel and populate it via code.

    If there is a small example that use the class ScrollPanelBuilder and involves the creation of multiples childs, I’m interested :slight_smile:

did you mean:



[xml]<control name="itemButton" style="itemListBoxElt" controller="de.lessvoid.nift[/xml]



instead of:



[xml]<control type="itemButton" style="itemListBoxElt" controller="de.lessvoid.nift[/xml]



?



btw: you can change the template for the elements like so too (no need to copy the whole controldefinition of the listbox if you only want to apply another template element):



[xml]<control name="listbox" …>

<text text="Template" style="nifty-listbox-item" controller="de.lessvoid.nifty.controls.listbox.ListBoxItemController" inputMapping="de.lessvoid.nifty.input.mapping.MenuInputMapping"/> <!-- could be any element you like … -->

</control>[/xml]

the very first child element of any control tag will be automatically transfered by nifty to the “childRootId” element in the controlDefinition …

Thanks, it solved my problem :

[java]

<control id=“miscList” name=“listBox” style=“ae-listbox” height="*" width=“100%” vertical=“true” horizontal=“optional” displayItems=“10” selection=“Single” viewConverterClass=“com.didigame.acariaempire.gui.controls.ListBoxViewConverterForItems” >

<control name=“itemButton” >

<interact onClick=“clickOnMiscItem()” />

</control>

</control>

[/java]



For the attributes ‘name’ instead of ‘type’. I didn’t really know wich one I have to use. ( The two seems to works for most of the cases )

So ‘name’ is the official one. Good to now.

[xml] <xs:complexType name=“controlType”>

<xs:complexContent>

<xs:extension base=“elementType”>

<xs:attribute name=“name” type=“xs:string”></xs:attribute>

<xs:anyAttribute processContents=“skip” namespace="##any" />

</xs:extension>

</xs:complexContent>

</xs:complexType>[/xml]



The “name” attribute is mandatory for the control tag. You could either have Nifty validate your XML-Files (nifty.validateXml() I think) or setup your editor for XSD validation to help detect that kind of errors :slight_smile:



(Note: You won’t get a XML/XSD validation error if you use other attributes that are unknown to Nifty tho :confused: The problem is that Nifty allows you to define your own control attributes, like <control name=“button” label=“Hello World”> In this example “label” is a parameter that is specific to the button control! (Inside the controlDefinition it is used like: text="$label" and Nifty will replace that with the value of “label” when the control is being created) This is usually a Nifty feature but you won’t get an error if you use attributes like “type” that are not supported by the control. I just wanted to clarify this :slight_smile:

Yep.



But what I found strange is that those two works :

[java]

<control id=“btnStory” type=“battleObj” align=“center” valign=“center” firstEffect=“story” />

<control id=“btnStory” name=“battleObj” align=“center” valign=“center” firstEffect=“story” />

[/java]

For some reason, Nifty read the attribute type and use it as if it was the attribute ‘name’.



I think I just copied an example somwhere with the ‘type’ attribute and kept it until now.

I will change my XML to delete all of them :slight_smile:



Edit : I’ve made the xml viewable :slight_smile:

Heh, SyntaxHighlighter fail ^^

http://imgur.com/qoUDE.png

HAH! :smiley:



[java] private String getType() {

String type = getAttributes().get(“type”);

if (type != null) {

return type;

}



return getAttributes().get(“name”);

}[/java]



Seems like you can use both names xD … but you really should forget about the “type” :slight_smile: it’s not in the XSD and it was probably called “type” in older versions of Nifty… “name” is the correct one :slight_smile: