Lemur Listbox with Buttons?

I’d like to fill a Listbox with clickable items, so I tried to directly put Buttons inside it, but I discovered that Listbox wants Strings…

import com.jme3.app.Application;
import com.jme3.app.SimpleApplication;
import com.jme3.app.state.BaseAppState;
import com.jme3.math.Vector3f;
import com.jme3.scene.Node;
import com.simsilica.lemur.*;

import java.util.ArrayList;

public class HelloJME3_3 extends SimpleApplication{

    public static void main(String[] args) {
        HelloJME3_3 app=new HelloJME3_3();
        app.start(); // start the game
    }

    @Override
    public void simpleInitApp() {
        GuiGlobals.initialize(this);
        GuiGlobals globals = GuiGlobals.getInstance();
        stateManager.attach(new WikiAppstate());
    }

    class WikiAppstate extends BaseAppState {

        Node stateGuiNode = new Node();

        String pages[] = {
                "page1",
                "page2",
                "page3",
                "page4",
                "page5",
                "page6",
                "page7",
                "page8",
                "page9",
        };

        ArrayList<String> unlocked = new ArrayList<>();
        ListBox listBox;

        @Override
        protected void initialize(Application app) {

            listBox = new ListBox();
            //listBox.setVisibleItems(5);
            listBox.setPreferredSize(new Vector3f(800, 500, 0));
            listBox.setLocalTranslation((800) , 680, 0);
            for (String page : pages) {
                unlocked.add(page);
                ActionButton b = new ActionButton(new Action() {
                    @Override
                    public void execute(Button source) {
                        WikiAppstate.this.wiki(page);
                    }

                    @Override
                    public String getName() {
                        return page;
                    }

                });
                listBox.getModel().add(b);
                b.setPreferredSize(new Vector3f(500, 68, 0));
            }
            stateGuiNode.attachChild(listBox);
        }

        public void wiki(String page) {
            System.out.println("goto " + page);
        }

        @Override
        protected void cleanup(Application app) {

        }

        @Override
        protected void onEnable() {
            ((SimpleApplication)getApplication()).getGuiNode().attachChild(stateGuiNode);
        }

        @Override
        protected void onDisable() {
            stateGuiNode.removeFromParent();
        }
    }

}
1 Like

A ListBox<T> wants elements of type T. By default it renders .toString(), but if you override the CellRenderer it will render it however you wish.

2 Likes

As Jay says, a List is backed by a model. That model can contain anything. The default cell renderer slaps that into the string of a button (maybe a label but pretty sure a button).

In your case, it doesn’t make a lot of sense to use action buttons in the model if you are already going to be putting them into a list. You could have filled your list with strings and then added a click handler to open the wiki page.

Even if you wanted to do actions with a custom renderer then it would be better to have the list be of actions List<Action> and have your cell renderer just create buttons from the actions. There still isn’t much point, though… when in this case the strings would be enough.

1 Like